-
Notifications
You must be signed in to change notification settings - Fork 60
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
Add provisioning methods #24
Comments
Understanding error codeCorrect call:
-40106 returned for both:
Following depau docsFollowing https://md.depau.eu/s/r1Ys_oWoP#All-command-types and above structure:
should work but it still returns -40106. I did test this on already provisioned camera though. Same happens with
But for example below works:
BUT, user_id no longer works and returns 40106.
|
@majkrzak Here's a bit of documentation that may help, it required quite a bit of reverse engineering of the Android App to fully understand that authentication is not required, but it's now possible (with a few unauthenticated API requests) to provision a camera without going through the Tapo app ! OnboardingIn this mode, the camera's LED will alternate between green and red. The camera creates an unsecured WiFi network such as Once connected to this WiFi network, the camera provides a dynamic IP in the Note: It is possible to log in without any parameters or using Scan WiFi networksRequest
{
"method": "scanApList",
"params": {
"onboarding": {
"scan": "null"
}
}
} Response{
"error_code": 0,
"result": {
"onboarding": {
"scan": {
"wpa3_supported": "false",
"ap_list": [
{
"ssid": "IOT-ROUTEUR-5246",
"bssid": "A5-6E-51-61-54-53",
"auth": 3,
"encryption": 2,
"rssi": 2
},
{
"ssid": "SFR WiFi Mobile",
"bssid": "72-CE-7D-D9-D8-8D",
"auth": 5,
"encryption": 2,
"rssi": 0
},
{
"ssid": "SFR WiFi FON",
"bssid": "72-CE-7D-D9-D8-8F",
"auth": 0,
"encryption": 0,
"rssi": 0
},
{
"ssid": "FreeWifi_secure",
"bssid": "00-24-D4-58-CB-45",
"auth": 5,
"encryption": 3,
"rssi": 0
}
]
}
}
}
}
Connect to a WiFi networkRequest
{
"method": "connectAp",
"params": {
"onboarding": {
"connect": {
"ssid": "IOT-ROUTEUR-5246",
"bssid": "A5-6E-51-61-54-53",
"auth": 3,
"encryption": 2,
"rssi": 2,
"password": "JfHLxfTdB+evKq5Pvlcuth2MgVlpw2Z++yEG/O0mk/Otcydno5ujFump0NNa+/dxOiN6D9m6JvpkRhqVY9VafrTkTIOFLesVwRbnzgczl90yS9gjjlyevkCrhIdM+x8OHERMB/NSeZUB6hLLY3IGwcAjVi3Ort13fxV/LovZ1qs="
}
}
}
} You may be wondering where that password comes from, it's encrypted with a 1024 bit RSA public key found in the decompiled Tapo APK (represented as Java RSAPublicKeySpec):
So using a free online tool (such as https://www.devglan.com/online-tools/rsa-encryption-decryption) you should be able to encrypt for example Response{
"error_code": 0,
"result": {
"onboarding": {
"connect": {
"connect_time": 60000,
"mac": "1c-61-b4-d5-87-d1",
"support_ap": "true"
}
}
}
} Get connect statusRequest
{
"method": "getConnectStatus",
"params": {
"onboarding": {
"get_connect_status": "null"
}
}
} Response{
"error_code": 0,
"result": {
"onboarding": {
"get_connect_status": {
"status": 0
}
}
}
} NoteOnce onboarding is performed and the camera is connected to the desired WiFi network, the onboarding methods will be unavailable and return the error code Once the camera is configured, the only way to change WiFi network appears to require a hard reset, returning the camera to factory settings and back into onboarding mode. |
I've been able to get the onboarding functions to work, and the cam connects to wifi. In this mode, you can also set the "third user" and admin/cloud passwords. There seems to be another message that gets sent to the camera that gets it out of "onboarding" mode, but I haven't been able to figure it out. Knowing this, we should be able to get these cameras provisioned without the app. |
Hi @ahoy Sorry, what do you mean by getting it out of onboarding mode? Does the device not exit onboarding once The following are the steps I have used to set up the device for RTSP streaming without requiring the app or internet, listing the
This is not the minimal set of steps (e.g. |
@jp-0 providing examples will be very useful. Currently, with commands from @liamjack I managed to force camera to connect my wifi, I'm able to connect to it with |
hey @majkrzak, see below some detail on the two requests you mentioned.
"changeAdminPassword"
"user_management": {
"change_admin_password": {
"secname": "root",
"passwd": password_md5, # uppercase of the md5 hash of your password
"old_passwd": password,
"ciphertext": password_rsa, # using the same public key extracted from the app, as mentioned in another comment
"username": "admin"
}
} "changeThirdAccount"
"user_management": {
"change_third_account": {
"secname": "third_account",
"passwd": new_third_account_password_md5, # uppercase of the md5 hash of your password
"old_passwd": "",
"ciphertext": new_third_account_password_rsa, # using the same public key extracted from the app, as mentioned in another comment
"username": new_username,
}
} "verifyThirdAccount"
"user_management": {
"verify_third_account": {
"secname": "third_account",
"passwd": current_third_account_password_md5, # uppercase of the md5 hash of your password
"old_passwd": "",
"ciphertext": current_third_account_password_rsa, # using the same public key extracted from the app, as mentioned in another comment
"username": current_username,
}
} It may be you need to go via the {"method": "multipleRequest", "params": {"requests": [{"method": method, "params": params}]}} |
@jp-0 @ahoy I've already successfully run
I am getting these response:
Is there something I am doing wrong? Also, is there also some reference for what the error codes |
How to set the IP if my AP doesn't have DHCP? I only see Also, where do I find info how to run the commands mentioned above? What is the respective payload? @jp-0 Edit: I'm also not sure how to set a username password. I'm also not sure what the current username/password is |
I have received my C220 now, but I'm not sure how to change the password. Because I don't know the current username/password, I can't use my camera at all, because I'm unable to access any video stream. I don't want to use the mobile app / bind my device to the cloud, so I'd prefer it someone can document what those different accounts are used for (how does the app use them / which account should be used for routine tasks). I also couldn't figure out how to do the steps in #24 (comment):
Regardless I went ahead with a firmware upgrade as documented in DrmnSamoLiu/Tapo_Camera_Firmware#9 |
Finally got it working
I've actually reverse-engineered this now. Some observations:
Excuse the poor following code style, I've been trying to figure this out for way too long and need some sleep now. import base64
from hashlib import md5
import json
from pytapo import Tapo
user = "admin"
password = "admin" # This password only works if you never used `changeAdminPassword` before
host = "192.168.191.1"
tapo = Tapo(host, user, password, printDebugInformation=True, redactConfidentialInformation=False)
def encryptPassphrase(passphrase):
public_pem_data = b"""-----BEGIN RSA PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4D6i0oD/Ga5qb//RfSe8MrPVI
rMIGecCxkcGWGj9kxxk74qQNq8XUuXoy2PczQ30BpiRHrlkbtBEPeWLpq85tfubT
UjhBz1NPNvWrC88uaYVGvzNpgzZOqDC35961uPTuvdUa8vztcUQjEZy16WbmetRj
URFIiWJgFCmemyYVbQIDAQAB
-----END RSA PUBLIC KEY-----"""
public_key = load_pem_public_key(public_pem_data)
ciphertext = public_key.encrypt(passphrase, padding.PKCS1v15())
return ciphertext
def multipleRequests(requests):
return {
"method": "multipleRequest",
"params": {
"requests": requests
}
}
# Work around login not working
def anonPerformRequest(req):
url = tapo.getHostURL()
res = tapo.request(
"POST",
url,
data=json.dumps(req),
headers=tapo.headers,
verify=False,
)
return res.json()
# Target values
third_account_username = "tapousername" # must be at least 6 symbols (!)
third_account_password = "tapopassword"
admin_password = "adminpassword"
# Change third user account
if True:
passwd = third_account_password
passwd_md5 = md5(passwd.encode('utf-8')).hexdigest().upper()
passwd_rsa = base64.b64encode(encryptPassphrase(passwd.encode('utf-8'))).decode('utf-8')
changeThirdAccount = {
"method": "changeThirdAccount",
"params": {
"user_management": {
"change_third_account": {
"secname": "third_account",
"passwd": passwd_md5, # uppercase of the md5 hash of your password
"old_passwd": "",
"ciphertext": passwd_rsa, # using the same public key extracted from the app, as mentioned in another comment
"username": third_account_username,
}
}
}
}
res = anonPerformRequest(multipleRequests([changeThirdAccount]))
print('changeThirdAccount', res)
verifyThirdAccount = {
"method": "verifyThirdAccount",
"params": {
"user_management": {
"verify_third_account": {
"secname": "third_account",
"passwd": passwd_md5, # uppercase of the md5 hash of your password
"old_passwd": "",
"ciphertext": passwd_rsa, # using the same public key extracted from the app, as mentioned in another comment
"username": third_account_username,
}
}
}
}
# Change admin password (the above must have ran before)
if False:
# Factory password (!)
passwd = admin_password
passwd_md5 = md5(passwd.encode('utf-8')).hexdigest().upper()
passwd_rsa = base64.b64encode(encryptPassphrase(passwd.encode('utf-8'))).decode('utf-8')
changeAdminPassword = {
"method": "changeAdminPassword",
"params": {
"user_management": {
"change_admin_password": {
"secname": "root",
"passwd": passwd_md5,
"old_passwd": md5(password.encode('utf-8')).hexdigest().upper(), # old password as md5 encoded
"ciphertext": passwd_rsa,
"username": "admin" # must be "admin" (?)
}
}
}
}
res = anonPerformRequest(multipleRequests([verifyThirdAccount, changeAdminPassword]))
print('changeAdminPassword', res) After that, I did the Following that, I did:
Connecting through The UDP rtsp was really unstable for me but that might also be related to my bridge which blocks the camera from the internet. I have a pretty good understanding about all involved tools (based on my RE of the C200 firmware, even though I own a C220):
I plan to document my findings as I've also found some potential security issues (I plan responsible disclosure here if tplink has that). There are also a bunch of yet-to-be-documented commands. I also made my own client for the tplink cloud API (device-facing, not user-facing like other projects) but it still has some issues. My plan is to discover firmware URLs. That way I should be able to get the camera completely cloudless, including the option to update. |
hi @JayFoxRox Below some hastily copied excerpts I have which may help you on the items you mentioned - although you have addressed some in later post. Unfortunately not much time at the moment for this project, but I have enumerated all the paths in the application (for my camera at least) so have a lot more traffic / request captures to review whenever I get some more time (e.g. setting the 'active zones' via
|
@JayFoxRox |
I'm currently struggling with process of provisioning the Tapo C100 camera.
When camera is in factory state it sets the unprotected AP named
Tapo_Camera_XXXX
whereXXXX
is some hex value. After connecting the dhcp server on camera assign the 192.168.191.100 ip address, while reporting the gateway to be 192.168.191.1.I assume it hosts the same API which is partially implemented in this library, as when querying the https server on this address it returns very similar responses.
Calling the
login
no matter the params, returns some stok result:I found out that there should be something like
onboarding
module, witchscan
,connect
andget_connect_status
.By comparing this to other methods implemented in this library, I assume it should be called somehow like:
Sadly this seems not to work.
Sadly I got stuck at this point, If you got any suggestions or question please ask.
I'll try to push it somehow forward and extend this library with provisioning methods.
The text was updated successfully, but these errors were encountered: