Announcement
Collapse
No announcement yet.
Integrate Grandstream gds3710 video doorbell
Collapse
X
-
I found the problem, but not the solution (not yet).
The problem is that the API at step 2 doesn't use their own security code (a.k.a. challenge code) generated at step 1 but instead they use MD5 hash of this string
ChallengeCode : remote_pin : password
The user of GDS3710 knows all 3 and can submit them via Big5. The calculation of MD5 hash is a problem as neither Big5 nor HomeSeer supports this outdated and denounced by experts as vulnerable MD5 hash code generation.
Bottom line --- in order to solve the problem we need either (a) a volunteer to script MD5 hash generator in HomeSeer or (b) to find automated online tool for generating MD5 hash code by submitting the above string by Big5 and receiving the hash code back by Big5. Any ideas ????
Comment
-
O.K. This was resolved finally. HomeSeer HS4 with Big5 plug-in does open Door#1 and Door#2 now. Tested with HS4 but I don't see why it wouldn't work with HS3.
Thanks to rdc for providing the hardware and thanks to zwolfpack for drafting a script for MD5 hash generator. Solution wouldn't be possible without these components.
Please follow the instructions closely as this proved to be a tough nut to crack and is kind of sensitive.
Please note my Grandstream Device is at address 192.168.1.160 and is set to respond to http (not https). Substitute with your own IP address whereever you see this address in the examples below. Other necessary substitutions below are marked with xxxx, yyyy, zzzz, uuuu, vvvv pls make sure you do not forget to substitute per instructions.
1. Setup your Big5 HTTP profiles
1.1. GrandstreamGC - profile for getting the codes
Method - POST
URL - http://192.168.1.160/goform/apicmd?cmd=0&user=admin
Device name expression: "code1" && "code2"
Device value expression: substring(split(input,">")[7],0,32) && substring(split(input,">")[9],0,20)
1.2. GrandsreamA - profile for Action to open door by HTTP
Method - GET
URL - http://192.168.1.160/goform/apicmd?cmd=1&user=admin&authcode=${input}
2. HS4 event to get the codes
Action: Big5HTTP on GrandstreamGC profile
Action Box: blank
Result: Big5 will create two devices in Big5 floor and HTTP room
code1
code2
Please take a note of the reference numbers of these devices
3. HS4 event to generate the MD5 hash code
Action: run script
Here is the script (courtesy of zwolfpack )
Substitute xxxx with your code for opening door #1 and yyyyyyyy with your Admin password (both to be setup at GDS3710 menu)
Substitute zzzz with HS4 Device reverence number of the device "code1" see above
Substitute uuuu with HS4 Device reference number for a device "hash" that you create beforehand for holding the hash code.
*************************************************
Sub Main(ByVal p As String)
Const iRef = zzzz
Const oRef = uuuu
Dim iStr As String = hs.DeviceString(iRef)+":"+"xxxx"+":"+"yyyyyyyy"
Dim oStr = md5sum(iStr)
hs.SetDeviceString(oRef, oStr, True)
End Sub
Function md5sum(ByVal strToHash As String) As String
Dim md5Obj As New Security.Cryptography.MD5CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As String = ""
For Each b As Byte In bytesToHash
strResult += b.ToString("x2")
Next
Return strResult
End Function
************************************************************
4. HS4 event to send HTTP to open the door (not the actual door open event, see below).
Action: Big5 HTTP
Profile: GrandstreamA
Action box content: ${struuuu+"&idcode="+strvvvv+"&type=1"}
Substitute uuuu with Ref# of the device "hash" see above
Substitute vvvv with Ref# of the device "code2" see above
Do not lose the letters "str" during substitute it means string of the relevant device
5. Actual OPEN DOOR HS4 Event
Action: Run Event to get codes (see p.2 above. this will give you fresh security codes)
Action: Wait 1 sec.
Action; Run event to generate hash (see p.3 above)
Action: Wait 4 sec.
Action: Run event to send HTTP to open the door (see p.4 above)
The 4 sec. delay was determined by tests. It seem that GDS3710 needs some time to get ready to open the door after issuing fresh codes.
This will open Door#1 for you.
Everything is the same to open Door#2. Only difference is in the MD5 script you will put the code for Door#2 where xxxx is.
Enjoy.
- Likes 2
Comment
-
Hi All
I got some great help from this thread so thought i would feedback.
Here is one vb.net script that can be called as a Action from an Event to open the gate that doesnt use BigIP
Change sServer, sPin and sAdminPassword to your values
PHP Code:Sub Main(p AS object)
Dim sResCode AS String
Dim sRetMsg AS String
Dim sChallengeCode AS String
Dim sIDCode AS String
Dim GateXMLDoc As New System.XML.XmlDocument()
Dim sServer As String = "https://192.168.1.100"
Dim sPIN As String = "1234"
Dim sAdminPassword As String = "Password1234"
Dim sURL As String = ""
Try
'Parse XML Data First Layer
Dim sAuthQuery As String = "/goform/apicmd?cmd=0&user=admin"
sURL=sServer+sAuthQuery
'hs.writelog("Gate Auth: URL", sURL)
GateXMLDoc.Load(sURL)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Auth: Result", sResCode)
If sResCode=0 Then
sChallengeCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ChallengeCode").InnerText
'hs.writelog("Gate: Challenge Code", sChallengeCode)
sIDCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/IDCode").InnerText
'hs.writelog("Gate: ID Code", sIDCode)
Dim sAuthCode AS String = sChallengeCode + ":" + sPIN +":" + sAdminPassword
'hs.WriteLog("Gate: Auth Code", sAuthCode)
Dim sAuthCodeMD5 AS String = md5sum(sAuthCode)
'hs.WriteLog("Gate: Auth Code MD5", sAuthCodeMD5)
Dim sOpenQuery AS String = "/goform/apicmd?cmd=1&user=admin&authcode=" + sAuthCodeMD5 + "&idcode=" + sIDCode + "&type=1"
sURL=sServer+sOpenQuery
'hs.writelog("Gate Auth: URL", sURL)
GateXMLDoc.Load(sURL)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Open: Result", sResCode)
If sResCode=0 Then
hs.writelog("Gate Open: Success", sResCode)
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Open: Return Message", sRetMsg)
End If
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Auth: Falied", sRetMsg)
End If
Catch ex As Exception
hs.WriteLog ("Gate: XML Error", ex.Message)
End Try
End Sub
Function md5sum(ByVal strToHash As String) As String
Dim md5Obj As New Security.Cryptography.MD5CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As String = ""
For Each b As Byte In bytesToHash
strResult += b.ToString("x2")
Next
Return strResult
End Function
- Likes 1
Comment
-
This is very helpful. Any chance this could be modified to keep the gate in an open state?
Sometimes when we have a party it is nice to keep the gate locked open.
Thx
mike
Originally posted by slegs View PostHi All
I got some great help from this thread so thought i would feedback.
Here is one vb.net script that can be called as a Action from an Event to open the gate that doesnt use BigIP
Change sServer, sPin and sAdminPassword to your values
PHP Code:Sub Main(p AS object)
Dim sResCode AS String
Dim sRetMsg AS String
Dim sChallengeCode AS String
Dim sIDCode AS String
Dim GateXMLDoc As New System.XML.XmlDocument()
Dim sServer As String = "https://192.168.1.100"
Dim sPIN As String = "1234"
Dim sAdminPassword As String = "Password1234"
Dim sURL As String = ""
Try
'Parse XML Data First Layer
Dim sAuthQuery As String = "/goform/apicmd?cmd=0&user=admin"
sURL=sServer+sAuthQuery
'hs.writelog("Gate Auth: URL", sURL)
GateXMLDoc.Load(sURL)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Auth: Result", sResCode)
If sResCode=0 Then
sChallengeCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ChallengeCode").InnerText
'hs.writelog("Gate: Challenge Code", sChallengeCode)
sIDCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/IDCode").InnerText
'hs.writelog("Gate: ID Code", sIDCode)
Dim sAuthCode AS String = sChallengeCode + ":" + sPIN +":" + sAdminPassword
'hs.WriteLog("Gate: Auth Code", sAuthCode)
Dim sAuthCodeMD5 AS String = md5sum(sAuthCode)
'hs.WriteLog("Gate: Auth Code MD5", sAuthCodeMD5)
Dim sOpenQuery AS String = "/goform/apicmd?cmd=1&user=admin&authcode=" + sAuthCodeMD5 + "&idcode=" + sIDCode + "&type=1"
sURL=sServer+sOpenQuery
'hs.writelog("Gate Auth: URL", sURL)
GateXMLDoc.Load(sURL)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Open: Result", sResCode)
If sResCode=0 Then
hs.writelog("Gate Open: Success", sResCode)
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Open: Return Message", sRetMsg)
End If
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Auth: Falied", sRetMsg)
End If
Catch ex As Exception
hs.WriteLog ("Gate: XML Error", ex.Message)
End Try
End Sub
Function md5sum(ByVal strToHash As String) As String
Dim md5Obj As New Security.Cryptography.MD5CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As String = ""
For Each b As Byte In bytesToHash
strResult += b.ToString("x2")
Next
Return strResult
End Function
Comment
-
Yes, the Keep Open Door option works on a slightly different model in the API. Have coded it in bash and plan to do it shortly for Homseer vb.net too
Basically you can use api to program the Keep Open Door option from 5 minutes to 480 minutes assuming the GDS is wired properly to the door mechanism to allow this
Comment
-
Originally posted by slegs View PostYes, the Keep Open Door option works on a slightly different model in the API. Have coded it in bash and plan to do it shortly for Homseer vb.net too
Basically you can use api to program the Keep Open Door option from 5 minutes to 480 minutes assuming the GDS is wired properly to the door mechanism to allow this
The device is pretty nice, but the API is really complicated to deal with. Not sure why they went of of their way to make it so complicated.
thx
mike
Comment
-
Originally posted by fresnoboy View Post
That would be great. Being able to keep it open, and then being able to close it (which happens once the GDS opens the relay that drives it) would be great.
The device is pretty nice, but the API is really complicated to deal with. Not sure why they went of of their way to make it so complicated.
thx
mike
Comment
-
Originally posted by slegs View Post
The command actually schedules a timer on the GDS from 5 to 480 minutes so it closes automatically. If you want to close early you just send another similar command clearing the timer. Its different to the Open method above which sends the open pulse. To use the timer, you need to have your gate wired to the GDS in a way that the Keep Open option from the GDS menu works. This can be tested before applying the API as all the API does is program the same command. Hope to get some time later today to work on this.
I think mine is wired in a compatible way. Will check on that.
thanks again for the work here!
mike
Comment
-
OK got this complete and tested on my customer's Homseer. Script of the schedule command is a lot more complicated due to the need to interact with Cookies.
Note, you need to be able to interact with the .Net Http classes. To enable this you need to have the following line in the [Settings] block of your Homeseer settings.ini file
PHP Code:ScriptingReferences=System.Net.Http;System.Net.Http.dll
Homeseer will need to be restarted after changing this
Script is as before a one script file but it takes an event parameter which is the time to keep the gate open. Valid values are 0 or 5 to 480. 0 will disable any active timer and close the gate. A number between 5 and 480 will open the gate for that number of minutes. Once the timer elapses the gate will close automatically.
I suggest you save the script as something like gatetimer.vb in your scripts directory and then call it from multiple events with the parameter depending on your needs e.g a Disable Timer event sends 0, Open Gate 1 Hour sends 60
At top of script are the three values for you to change - Your GDS IP/Hostname in url format (use https if you GDS is enabled for https), your password for GDS GUI for the admin user and a value for which door to open (GDS can control 2 doors depending on wiring) - door 1 is "1", door 2 is "2" and for both doors set the value to "3"
Thanks
PHP Code:Sub Main(ByVal sTime As String)
'**********Your Custom Values************
' GDS3710 IP Address or Hostname e.g. https:/yourdyndns.org:1234
Dim sServer As String = "https://192.168.1.100"
' GDS3710 Password for Admin User
Dim sAdminPassword As String = "Password1234"
'Door 1 = 1, Door 2 = 2, Both Doors = 3
Dim sDoor As String = "3"
'**********Your Custom Values************
'Fixed Variables
Dim sResCode AS String
Dim sRetMsg AS String
Dim sChallengeCode AS String
Dim sIDCode AS String
Dim GateXMLDoc As New System.XML.XmlDocument()
Dim handler AS New System.Net.Http.HttpClientHandler()
Dim sGSKey As String = "GDS3710lZpRsFzCbM"
Dim sDoor1CodeEnable As String = "P15429"
Dim sDoor1CodeTime As String = "P15430"
Dim sDoor2CodeEnable As String = "P15455"
Dim sDoor2CodeTime As String = "P15456"
Dim sURL As String = ""
Dim sXML As String = ""
Dim sCookieUname As New System.Net.Cookie("uname", "admin")
Dim sCookieGDSKey As New System.Net.Cookie("gdsauthkey443", "643e985e113a50979fd245762be01a57")
Dim sEnable As String = "1"
'Parse Time Paramter - 0 disables timers
Dim iTime As Integer = CInt(sTime)
If iTime > 480 Then
sTime = "480"
ElseIf iTime > 0 and iTime < 5 Then
sTime = "5"
ElseIf iTime = 0 Then
sEnable = "0"
End If
hs.writelog("Gate Schedule: Params", "Door:" + sDoor + " Enable: " + sEnable + " Time: " + sTime)
Try
'First step of authorisation - Get Challenge Code
Dim sAuthStep1Query As String = "/goform/login?cmd=login&user=admin&type=0"
sURL=sServer+sAuthStep1Query
'hs.writelog("Gate Auth S1: URL", sURL)
GateXMLDoc.Load(sURL)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Auth S1: Result", sResCode)
If sResCode=0 Then
sChallengeCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ChallengeCode").InnerText
'hs.writelog("Gate: Challenge Code", sChallengeCode)
Dim sAuthCode AS String = sChallengeCode + ":" + sGSKey +":" + sAdminPassword
'hs.WriteLog("Gate: Auth Code", sAuthCode)
Dim sAuthCodeMD5 AS String = md5sum(sAuthCode)
'hs.WriteLog("Gate: Auth Code MD5", sAuthCodeMD5)
'Second step of authorisation - Authorise and set cookie with session code. Set Cookie Values as prescribed by Grandstream
Dim sAuthStep2Query AS String = "/goform/login?cmd=login&user=admin&authcode=" + sAuthCodeMD5
sURL=sServer+sAuthStep2Query
'hs.writelog("Gate Auth S2: URL", sURL)
Dim authuri As New System.Uri(sURL)
handler.CookieContainer = new System.Net.CookieContainer()
handler.CookieContainer.Add(authuri, sCookieUname)
handler.CookieContainer.Add(authuri, sCookieGDSKey)
Dim client As new System.Net.Http.HttpClient(handler)
sXML = client.GetStringAsync(authuri).Result
GateXMLDoc.LoadXml(sXML)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
'hs.writelog("Gate Auth S2: Result", sResCode)
If sResCode=0 Then
'hs.writelog("Gate Auth S2: Success", sResCode)
'Set Timer - Depending on sDoor value this can be either door or both
'0 Value for sEnable disables timer and closes door
Dim sOpenQuery AS String
If sDoor = "3" Then
sOpenQuery = "/goform/config?cmd=set&" + sDoor1CodeEnable + "=" + sEnable + "&" + sDoor1CodeTime + "=" + sTime + "&" + sDoor2CodeEnable + "=" + sEnable + "&" + sDoor2CodeTime + "=" + sTime
ElseIf sDoor = "2" Then
sOpenQuery = "/goform/config?cmd=set&" + sDoor2CodeEnable + "=" + sEnable + "&" + sDoor2CodeTime + "=" + sTime
Else
sOpenQuery = "/goform/config?cmd=set&" + sDoor1CodeEnable + "=" + sEnable + "&" + sDoor1CodeTime + "=" + sTime
End If
sURL=sServer+sOpenQuery
'hs.writelog("Gate Open: URL", sURL)
Dim openuri as New System.Uri(sURL)
sXML = client.GetStringAsync(openuri).Result
GateXMLDoc.LoadXml(sXML)
sResCode = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/ResCode").InnerText
If sResCode=0 Then
'SUCCESFUL Timer Set
hs.writelog("Gate Timer: Success", sResCode)
Else
'FAILED Timer Set
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Timer: Error", sRetMsg)
End If
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Auth S2: Error ", sRetMsg)
End If
Else
sRetMsg = GateXMLDoc.DocumentElement.SelectSingleNode("/Configuration/RetMsg").InnerText
hs.writelog("Gate Auth S1: Error", sRetMsg)
End If
Catch ex As Exception
hs.WriteLog ("Gate: Error", ex.Message)
End Try
End Sub
Function md5sum(ByVal strToHash As String) As String
Dim md5Obj As New Security.Cryptography.MD5CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As String = ""
For Each b As Byte In bytesToHash
strResult += b.ToString("x2")
Next
Return strResult
End Function
Comment
-
Slegs, I just tried your updated script, and after switching to http in the GDS for the web interface (I was getting an TLS error from homeseer when trying to use HTTPS) it works perfectly, at least with fimrware 1.0.7.14.
Thanks very much for this! I was going to kludge this up with a wifi controlled relay, but this is very clean and works well.
thanks again!
mike
- Likes 1
Comment
-
If you add this line
PHP Code:handler.ServerCertificateCustomValidationCallback = System.Net.Http.HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
PHP Code:Dim client As new System.Net.Http.HttpClient(handler)
Comment
Comment