Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't reach any endpoints with pyvizio, but can with curl #133

Open
whophil opened this issue Nov 11, 2022 · 3 comments
Open

Can't reach any endpoints with pyvizio, but can with curl #133

whophil opened this issue Nov 11, 2022 · 3 comments

Comments

@whophil
Copy link

whophil commented Nov 11, 2022

I have a Vizio E55-D0. I am able to reach endpoints and create an auth token via direct usage of curl, but cannot do so with pyvizio.

Below is an example (auth token redacted).

➜  pyvizio --ip=10.20.50.221 --device_type=tv --auth=XXXXXXXX power off
INFO:pyvizio.cli:Turning OFF
ERROR:pyvizio:Failed to execute command: Cannot connect to host 10.20.50.221:9000 ssl:False [None]
INFO:pyvizio.cli:ERROR

Any ideas from the devs? Is there any way to get more verbose output to understand what is happening?

@maxnl
Copy link

maxnl commented Dec 9, 2022

I am having the same issue with an E40-D0, same model year and series. I was able to pair manually to get an auth token using a CLI script, but can't seem to use that to connect with pyvizio or Home Assistant.

I'm wondering if it might be related to issue #114 that came up back with the 2020 models (also discussed on the Home Assistant community).

I was able to get this TV to work with Homebridge a few years back but I recall struggling with Home Assistant at the time as well. So I think it might just be something about the firmware on these old models that pyvizio isn't accounting for.

@whophil
Copy link
Author

whophil commented Dec 20, 2022

It seems that this issue is related to this model of TV using the very old TLS v1.0, as well as something called "unsafe legacy renegotiation."

What follows is a proof of concept to make a working API call to this model TV from Python via requests.

This requires:

  1. Forcing TLSv1
  2. Enabling "unsafe legacy renogiation" in OpenSSL (here it is done via a .cnf file which needs to be pointed to by the calling environment.)

Are there active devs here who could comment on how this might be implemented in this project?

The script vizio_request.py

from requests.adapters import HTTPAdapter
from urllib3 import PoolManager
import requests
import ssl


class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)


s = requests.session()
s.mount('https://', MyAdapter())

tv_ip = '10.20.50.221:9000'
r = s.put(url=f'https://{tv_ip}/pairing/start',
          json={"DEVICE_ID": "pyvizio",
                "DEVICE_NAME": "Python Vizio"},
          headers={'Content-Type': 'application/json'},
          verify=False)

print(r.content)

The OpenSSL conf file, openssl.cnf

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

Calling it

OPENSSL_CONF=/path/to/openssl.cnf python vizio_request.py

@ifeign
Copy link

ifeign commented Apr 30, 2023

It seems that this issue is related to this model of TV using the very old TLS v1.0, as well as something called "unsafe legacy renegotiation."

What follows is a proof of concept to make a working API call to this model TV from Python via requests.

This requires:

  1. Forcing TLSv1
  2. Enabling "unsafe legacy renogiation" in OpenSSL (here it is done via a .cnf file which needs to be pointed to by the calling environment.)

Are there active devs here who could comment on how this might be implemented in this project?

The script vizio_request.py

from requests.adapters import HTTPAdapter
from urllib3 import PoolManager
import requests
import ssl


class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)


s = requests.session()
s.mount('https://', MyAdapter())

tv_ip = '10.20.50.221:9000'
r = s.put(url=f'https://{tv_ip}/pairing/start',
          json={"DEVICE_ID": "pyvizio",
                "DEVICE_NAME": "Python Vizio"},
          headers={'Content-Type': 'application/json'},
          verify=False)

print(r.content)

The OpenSSL conf file, openssl.cnf

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

Calling it

OPENSSL_CONF=/path/to/openssl.cnf python vizio_request.py

Thanks for this, without this being implemented into pyvizio I won't be able to connect my E55-D0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants