filcole / pycarwings2

Python library for interacting with the NissanConnect EV (aka CARWINGS) telematics service.
Apache License 2.0
33 stars 18 forks source link

Canada NCI login fails "INVALID PARAMS" from HTTP Response Body #21

Open fermulator opened 4 years ago

fermulator commented 4 years ago

Good day,

Initially tried this via https://www.home-assistant.io/integrations/nissan_leaf/, however it didn't work with:

Feb 08 16:45:44 hass hass[2545]: 2020-02-08 16:45:44 ERROR (SyncWorker_9) [pycarwings2.pycarwings2] carwings error INVALID PARAMS: -2010
Feb 08 16:45:44 hass hass[2545]: 2020-02-08 16:45:44 ERROR (SyncWorker_9) [homeassistant.components.nissan_leaf] An unknown error occurred while connecting to Nissan: <(snipped/lost)

Reproduced it with my account hitting Canada NCI portal using latest pycarwings2:

As per the README.md, did the basic install, and copied down some examples w/ my_config.ini.

$ python3 --version
Python 3.6.8

$ pip3 list | egrep "pycar|chardet|urllib3"
chardet                  3.0.4                 
pycarwings2              2.9                   
urllib3                  1.25.8                
~/.local/lib/python3.6/site-packages/pycarwings2/examples$ ll
total 44
drwxrwxr-x 2 fermulator fermulator 4096 Feb  8 20:05 ./
drwxrwxr-x 4 fermulator fermulator 4096 Feb  8 19:57 ../
-rw-rw-r-- 1 fermulator fermulator  129 Feb  8 19:57 config.ini
-rwxrwxr-x 1 fermulator fermulator 3167 Feb  8 20:03 get-leaf-info.py*
-rw-rw-r-- 1 fermulator fermulator  148 Feb  8 19:59 my_config.ini

Had to tweak get-leaf-info.py to hit my python3 directly (not env python), otherwise it is left unmodified.

After that, it ran, and repro'd the problem:

~/.local/lib/python3.6/site-packages/pycarwings2/examples$ ./get-leaf-info.py 
DEBUG:root:login = (SNIP), password = (snip), region = NCI
Prepare Session
Login...
DEBUG:pycarwings2.pycarwings2:invoking carwings API: https://gdcportalgw.its-mo.com/api_v190426_NE/gdc/InitialApp_v2.php
DEBUG:pycarwings2.pycarwings2:params: {
   "RegionCode": "NCI",
   "custom_sessionid": "",
   "initial_app_str": "9s5rfKVuMrT03RtzajWNcA",
   "lg": "en-US"
}
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): gdcportalgw.its-mo.com:443
DEBUG:requests.packages.urllib3.connectionpool:https://gdcportalgw.its-mo.com:443 "POST /api_v190426_NE/gdc/InitialApp_v2.php HTTP/1.1" 200 None
DEBUG:pycarwings2.pycarwings2:Response HTTP Status Code: 200
DEBUG:pycarwings2.pycarwings2:Response HTTP Response Body: b'{"status":200,"message":"success","baseprm":"88dSp7wWnV3bvv9Z88zEwg"}'
DEBUG:pycarwings2.pycarwings2:invoking carwings API: https://gdcportalgw.its-mo.com/api_v190426_NE/gdc/UserLoginRequest.php
DEBUG:pycarwings2.pycarwings2:params: {
   "Password": "(snip)",
   "RegionCode": "NCI",
   "UserId": "(SNIP)",
   "custom_sessionid": "",
   "initial_app_str": "9s5rfKVuMrT03RtzajWNcA"
}
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): gdcportalgw.its-mo.com:443
DEBUG:requests.packages.urllib3.connectionpool:https://gdcportalgw.its-mo.com:443 "POST /api_v190426_NE/gdc/UserLoginRequest.php HTTP/1.1" 200 None
DEBUG:pycarwings2.pycarwings2:Response HTTP Status Code: 200
DEBUG:pycarwings2.pycarwings2:Response HTTP Response Body: b'{"status":"-2010","message":"INVALID PARAMS","resultKey":""}'
ERROR:pycarwings2.pycarwings2:carwings error INVALID PARAMS: -2010
Traceback (most recent call last):
  File "./get-leaf-info.py", line 61, in <module>
    leaf = s.get_leaf()
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 212, in get_leaf
    self.connect()
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 186, in connect
    "Password": encodedPassword,
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 160, in _request
    raise CarwingsError("INVALID PARAMS")
pycarwings2.pycarwings2.CarwingsError: INVALID PARAMS
$ cat my_config.ini 
[get-leaf-info]
username = (SNIP)
password = (SNIP)
; NNA=USA, NE=Europe, NCI=Canada, NMA=Austrailia, NML=Japan
region = NCI

Open to working through/debugging (just filing the issue report for now). If anyone has guidance happy for it to get a jump start.

It may be worth noting (since I'm not sure if different regions have different account rules):

fermulator commented 4 years ago

Took a stab at things today ... I fear we're in another API backwards compatibility breakage.

The best thing to do atm is to get down into the POST ... I've tried varying permutations of posting to the API endpoint without success.

as a start:

$ cat params.json 
{
   "RegionCode": "NCI",
   "UserId": "someuser",
   "custom_sessionid": "",
   "initial_app_str": "9s5rfKVuMrT03RtzajWNcA"
}

and then try....

2$ curl -v --data "@params.json" --data-urlencode "Password=foobar" -X POST https://gdcportalgw.its-mo.com/api_v190426_NE/gdc/UserLoginRequest.php
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 54.199.141.237...
* Connected to gdcportalgw.its-mo.com (54.199.141.237) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 604 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*    server certificate verification OK
*    server certificate status verification SKIPPED
*    common name: *.its-mo.com (matched)
*    server certificate expiration date OK
*    server certificate activation date OK
*    certificate public key: RSA
*    certificate version: #3
*    subject: C=JP,ST=Tokyo,L=Minato-ku,O=ZENRIN DataCom Co.\,LTD.,OU=Engineering Section(1),CN=*.its-mo.com
*    start date: Wed, 25 Sep 2019 01:24:23 GMT
*    expire date: Wed, 23 Dec 2020 14:59:00 GMT
*    issuer: C=JP,O=Cybertrust Japan Co.\, Ltd.,CN=Cybertrust Japan Public CA G3
*    compression: NULL
* ALPN, server did not agree to a protocol
> POST /api_v190426_NE/gdc/UserLoginRequest.php HTTP/1.1
> Host: gdcportalgw.its-mo.com
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 137
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 137 out of 137 bytes
< HTTP/1.1 200 OK
< Date: Wed, 19 Feb 2020 01:30:13 GMT
< Server: Apache
< Strict-Transport-Security: max-age=15768000
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection 0
{"status":404,"message":"INVALID PARAMS"}

What's interesting though is that I'm not sure if the data should be binary or not .. either way nothing is working

$ curl --data-urlencode "@params.json" --data-urlencode "Password=foobar" -X POST https://gdcportalgw.its-mo.com/api_v190426_NE/gdc/UserLoginRequest.php
$ curl --data-binary "@params.json" --data-urlencode "Password=foobar" -X POST https://gdcportalgw.its-mo.com/api_v190426_NE/gdc/UserLoginRequest.php
.,..

all result in

{"status":404,"message":"INVALID PARAMS"}

Helper Refs:

fermulator commented 4 years ago

@linuscorin I don't suppose you have insight/guidance?

fermulator commented 4 years ago

I also hit up the php version of pycarwings2 it is called nissan-connect-php, and the same error there

https://github.com/gboudreau/nissan-connect-php/blob/master/README.md

php > require_once 'NissanConnect.class.php';
php > $nissanConnect = new NissanConnect('you@something.com', 'your_password_here', 'America/New_York', NissanConnect::COUNTRY_CANADA, NissanConnect::ENCRYPTION_OPTION_OPENSSL);

php > $nissanConnect->debug = TRUE                                                                                                                                      php > $nissanConnect->getStatus();                                                                                                                                      PHP Parse error:  syntax error, unexpected '$nissanConnect' (T_VARIABLE) in php shell code on line 2
php > $nissanConnect->getStatus();
    PHP Warning:  Uncaught Exception: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-2010","message":"INVALID PARAMS","resultKey":""} in /home/fermulator/projects/nissan-connect-php/NissanConnect.class.php:457
Stack trace:
(snip)
linuscorin commented 4 years ago

@linuscorin I don't suppose you have insight/guidance?

Sorry, no. There doesn't seem to have been any permanent API-breaking changes recently, at least not anything affecting Europe. Looking at my logs though, I can see that on the 3rd and 4th of February, I was getting a lot of "status: 404" responses, so if you're lucky it may be temporary. Note: I don't think the status number has anything to do with HTTP error codes. I've also in the past had status -2010, on a few occasions, but the last time I saw that was on the 27th of October.

fermulator commented 4 years ago

I wish there was a way to ask for "more verbose error details" "INVALID PARAMS" doesn't do it for me. Is it that I'm missing one? Provided one that is no longer supported? Does it actually mean "failed to authenticate"? ...

linuscorin commented 4 years ago

"INVALID PARAMS" seems to be the standard error message, and the status varies. On the 15th of Feb, I had a few hours of consistent "INVALID PARAMS" with status code 52 and -5256. Then it started working again by itself, without any changes to the supplied params.

I'm not aware of any way of getting more verbose errors from the API, and if the status codes are at all documented anywhere, it'll be for internal use only, as the API wasn't designed to be public, and has just been reverse engineered by people who wanted to use it.

niklasosth commented 4 years ago

Having the same problem today in Sweden: DEBUG:pycarwings2.pycarwings2:params: { "Password": "...", "RegionCode": "NE", "UserId": "niklas.osth@gmail.com", "custom_sessionid": "", "initial_app_str": "9s5rfKVuMrT03RtzajWNcA" } DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): gdcportalgw.its-mo.com:443 DEBUG:urllib3.connectionpool:https://gdcportalgw.its-mo.com:443 "POST /api_v190426_NE/gdc/UserLoginRequest.php HTTP/1.1" 200 None DEBUG:pycarwings2.pycarwings2:Response HTTP Status Code: 200 DEBUG:pycarwings2.pycarwings2:Response HTTP Response Body: b'{"status":"-2010","message":"INVALID PARAMS","resultKey":""}' ERROR:pycarwings2.pycarwings2:carwings error INVALID PARAMS: -2010

linuscorin commented 4 years ago

For what it's worth, it seems to be working consistently for me today, also from Sweden. So, it doesn't seem to be a system wide issue.

I get variations of "INVALID PARAMS" occasionally.

Has it been working for you previously, or are you just getting started?

2020-02-15 02:01:16 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 02:30:59 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-5256","message":"INVALID PARAMS","resultKey":""} 2020-02-15 03:00:46 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-5256","message":"INVALID PARAMS","resultKey":""} 2020-02-15 03:31:15 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 04:01:13 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 04:31:13 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:01:17 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:06:07 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-5256","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:11:16 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:16:17 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:21:15 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:26:16 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-15 05:31:22 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-20 02:01:00 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-5256","message":"INVALID PARAMS","resultKey":""} 2020-02-21 23:31:19 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-22 00:01:20 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-22 00:30:57 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"-5256","message":"INVALID PARAMS","resultKey":""} 2020-02-22 01:01:13 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-02-22 01:31:13 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""} 2020-03-30 03:31:21 Exception caught: Request for 'UserLoginRequest.php' failed. Response received: {"status":"52","message":"INVALID PARAMS","resultKey":""}

niklasosth commented 4 years ago

I got the Nissan Leaf yesterday so no - have no experience previously of getting it to work ;-)

linuscorin commented 4 years ago

Are you consistently getting the same error code, -2010? I haven't been seeing that code since October last year. At that point, it was a temporary error at the Nissan end which resolved itself after a day or so.

Unfortunately, I don't know much about the Python code (I'm using a PHP library), but what I can see from your debug output looks correct.

Grattis till bilen! :)

niklasosth commented 4 years ago

Thanks, tried with the php-lib but getting the same error there.

Question: Is it the password for https://youplus.nissan.se/ (I dont see Connected Services there) or the https://apps.apple.com/se/app/nissanconnect-services/id1451280347?

linuscorin commented 4 years ago

It should be the same password as you use in the app. I assume the app is able to connect to your car?

Which model / year is it? I've got a 2016 / 30kWh.

I've recently heard that newer cars use a different version of the app, so maybe they also use a different API or different API version? If so, that could also explain that what works for some people, doesn't work for others.

I did briefly play with sending traffic through a proxy server running on my laptop. to reverse engineer some of the features that weren't yet in the PHP library.

If the app works, but you can't get it to work using the API, then comparing requests between the app and your python code would be one way of figuring out what's wrong.

Here's some notes on reverse engineering: https://virantha.com/2016/01/12/reverse-engineering-nissan-connect-ev-protocol/

niklasosth commented 4 years ago

Yes, my problem seems to be that my car (MY2020) is only using the new NissanConnect Services API and because of that nissanyou+ based API is not enabled for my account and therefor the error code. Sadly, pycarwings and similar implementations will not work for newer cars. I will put my hope to projects like https://gitlab.com/tobiaswkjeldsen/dartnissanconnect/ and a future Python port.

Thanks for trying to help me out.

muldy commented 4 years ago

Same problem here, NE region too... This app works: https://play.google.com/store/apps/details?id=dk.kjeldsen.carwingsflutter https://gitlab.com/tobiaswkjeldsen/carwingsflutter <- source code here, if it helps

fermulator commented 3 years ago

Just tried after that MR, on 2.10 pycarwings.

$ pip3 list | egrep "pycar|chardet|urllib3"
chardet                  4.0.0
pycarwings2              2.10
urllib3                  1.26.2

Same issue. :x:

DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): gdcportalgw.its-mo.com:443
DEBUG:requests.packages.urllib3.connectionpool:https://gdcportalgw.its-mo.com:443 "POST /api_v190426_NE/gdc/UserLoginRequest.php HTTP/1.1" 200 None
DEBUG:pycarwings2.pycarwings2:Response HTTP Status Code: 200
DEBUG:pycarwings2.pycarwings2:Response HTTP Response Body: b'{"status":"-2010","message":"INVALID PARAMS","resultKey":""}'
ERROR:pycarwings2.pycarwings2:carwings error INVALID PARAMS: -2010
Traceback (most recent call last):
  File "./get-leaf-info.py", line 61, in <module>
    leaf = s.get_leaf()
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 217, in get_leaf
    self.connect()
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 191, in connect
    "Password": encodedPassword,
  File "/home/fermulator/.local/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 165, in _request
    raise CarwingsError("INVALID PARAMS")
pycarwings2.pycarwings2.CarwingsError: INVALID PARAMS
Kalkran commented 3 years ago

Maybe unrelated, but have you tried changing your username (if allowed) or password? These are the only parameters that would change between the initial InitialApp request and this one. The other issue related to something with the user-agent and broke all requests, yours seems to fulfill the baseprm request, but break on the second one.

Edit: Oh, and do other 3rd party apps work properly: such as the "My Leaf" app by Tobias Kjeldsen?

fermulator commented 3 years ago

@Kalkran - are you wondering/thinking that my password is "too complex" for the API and breaks it? (it has special characters etc) - the NissanConnect app works fine, and I'm using that (and logged out and logged back in w/ same credentials to verify those work);

I haven't tried other 3rd party apps (would prefer not to, but if I need to do so to debug....) - if others report that the fix in the PR for user agent has fixed their issue, then I guess I have a secondary problem here w/ credentials or something else.

Kalkran commented 3 years ago

I'm actually not sure about the password as it is encoded before being sent over, but something is definitely breaking things on the Nissan side and it doesn't seem related to the way the request are made (the first request goes through fine), and other users have no issues using identical versions.

Do you perhaps use a "+"-sign or other special character in your emailaddress?

fermulator commented 3 years ago

yup i have foo-bar@bat.xyz , and password has @ symbol

i tried just stripping all special chars, for a test (obviously the credentials are thus invalid), but still the same error -- i would EXPECT the API to give me a 403 ;/

avleen commented 3 years ago

FWIW, MyLeaf continues to function, and I don't see any related code changes on their side that could be related to this.

mzakharo commented 2 years ago

Hello, pycarwings2 used to work for me a few years back on my 2018 Leaf in Canada, but trying it now with 2.12 pycarwings2, I get INVALID PARAMS: -2010. My username/password have not changed. Nissan's App and website continue to work (I noticed over the NissanConnect API instead of carwings). Does anyone know what I can try to help resolve this error?

After some digging, looks like MyLeaf is using https://github.com/Tobiaswk/dartnissanconnectna to access Canadian Leaf status. Maybe 2018 leafs have no carwings support anymore? And it looks like there are some efforts on Nissan's part to try and ruin things for anyone not using the official app: https://tobis.dk/blog/open-letter-nissan-resistance-is-futile/ .