Support for UDP connection requests

This commit is contained in:
Zaid Abdulla committed 2017-01-02 04:59:01 -08:00
1 parent 4cb480dbd9
commit 7862117758
1 file changed
+40 -7
+40 -7
View File
@@ -38,6 +38,9 @@
# THE SOFTWARE. # THE SOFTWARE.
### ###
crypto = require 'crypto'
dgram = require 'dgram'
config = require './config' config = require './config'
db = require './db' db = require './db'
http = require 'http' http = require 'http'
@@ -46,6 +49,27 @@ util = require 'util'
URL = require 'url' URL = require 'url'
auth = require './auth' auth = require './auth'
udpConReq = (address, un, key, callback) ->
[host, port] = address.split(':', 2)
ts = Math.trunc(Date.now() / 1000)
id = Math.trunc(Math.random() * 4294967295)
cn = crypto.randomBytes(8).toString('hex')
sig = crypto.createHmac('sha1', key).update("#{ts}#{id}#{un}#{cn}").digest('hex')
uri = "http://#{address}?ts=#{ts}&id=#{id}&un=#{un}&cn=#{cn}&sig=#{sig}"
message = Buffer.from("GET #{uri} HTTP/1.1\r\nHost: #{host}:#{port}\r\n\r\n")
client = dgram.createSocket('udp4')
count = 3
client.send(message, 0, message.length, port, host, f = (err) ->
if err or -- count <= 0
client.close()
return callback(err)
client.send(message, 0, message.length, port, host, f)
)
connectionRequest = (deviceId, callback) -> connectionRequest = (deviceId, callback) ->
# ensure socket is reused in case of digest authentication # ensure socket is reused in case of digest authentication
@@ -92,11 +116,13 @@ connectionRequest = (deviceId, callback) ->
proj = { proj = {
'Device.ManagementServer.ConnectionRequestURL._value' : 1, 'Device.ManagementServer.ConnectionRequestURL._value' : 1,
'Device.ManagementServer.ConnectionRequestUsername._value', 'Device.ManagementServer.UDPConnectionRequestAddress._value' : 1,
'Device.ManagementServer.ConnectionRequestPassword._value', 'Device.ManagementServer.ConnectionRequestUsername._value' : 1,
'Device.ManagementServer.ConnectionRequestPassword._value' : 1,
'InternetGatewayDevice.ManagementServer.ConnectionRequestURL._value' : 1, 'InternetGatewayDevice.ManagementServer.ConnectionRequestURL._value' : 1,
'InternetGatewayDevice.ManagementServer.ConnectionRequestUsername._value', 'InternetGatewayDevice.ManagementServer.UDPConnectionRequestAddress._value' : 1,
'InternetGatewayDevice.ManagementServer.ConnectionRequestPassword._value' 'InternetGatewayDevice.ManagementServer.ConnectionRequestUsername._value' : 1,
'InternetGatewayDevice.ManagementServer.ConnectionRequestPassword._value' : 1
} }
db.devicesCollection.findOne({_id : deviceId}, proj, (err, device)-> db.devicesCollection.findOne({_id : deviceId}, proj, (err, device)->
@@ -106,20 +132,25 @@ connectionRequest = (deviceId, callback) ->
if device.Device? # TR-181 data model if device.Device? # TR-181 data model
connectionRequestUrl = device.Device.ManagementServer.ConnectionRequestURL._value connectionRequestUrl = device.Device.ManagementServer.ConnectionRequestURL._value
udpConnectionRequestAddress = device.Device.ManagementServer?.UDPConnectionRequestAddress?._value
username = device.Device.ManagementServer.ConnectionRequestUsername?._value username = device.Device.ManagementServer.ConnectionRequestUsername?._value
password = device.Device.ManagementServer.ConnectionRequestPassword?._value password = device.Device.ManagementServer.ConnectionRequestPassword?._value
else # TR-098 data model else # TR-098 data model
connectionRequestUrl = device.InternetGatewayDevice.ManagementServer.ConnectionRequestURL._value connectionRequestUrl = device.InternetGatewayDevice.ManagementServer.ConnectionRequestURL._value
udpConnectionRequestAddress = device.InternetGatewayDevice.ManagementServer?.UDPConnectionRequestAddress?._value
username = device.InternetGatewayDevice.ManagementServer.ConnectionRequestUsername?._value username = device.InternetGatewayDevice.ManagementServer.ConnectionRequestUsername?._value
password = device.InternetGatewayDevice.ManagementServer.ConnectionRequestPassword?._value password = device.InternetGatewayDevice.ManagementServer.ConnectionRequestPassword?._value
if not (username and password) and config.auth?.connectionRequest
[username, password] = config.auth.connectionRequest(deviceId)
if udpConnectionRequestAddress
udpConReq(udpConnectionRequestAddress, username, password, (err) -> throw err if err)
# for testing # for testing
#connectionRequestUrl = connectionRequestUrl.replace(/^(http:\/\/)([0-9\.]+)(\:[0-9]+\/[a-zA-Z0-9]+\/?$)/, '$110.1.1.254$3') #connectionRequestUrl = connectionRequestUrl.replace(/^(http:\/\/)([0-9\.]+)(\:[0-9]+\/[a-zA-Z0-9]+\/?$)/, '$110.1.1.254$3')
conReq(connectionRequestUrl, null, (statusCode, authHeader) -> conReq(connectionRequestUrl, null, (statusCode, authHeader) ->
if statusCode == 401 if statusCode == 401
if not (username and password) and config.auth?.connectionRequest
[username, password] = config.auth.connectionRequest(deviceId)
if authHeader.method is 'Basic' if authHeader.method is 'Basic'
authString = auth.basic(username, password) authString = auth.basic(username, password)
else if authHeader.method is 'Digest' else if authHeader.method is 'Digest'
@@ -132,6 +163,8 @@ connectionRequest = (deviceId, callback) ->
return conReq(connectionRequestUrl, authString, (statusCode) -> callback(statusToError(statusCode))) return conReq(connectionRequestUrl, authString, (statusCode) -> callback(statusToError(statusCode)))
callback(statusToError(statusCode)) callback(statusToError(statusCode))
) )
else if udpConnectionRequestAddress
return callback()
else else
callback(statusToError(statusCode)) callback(statusToError(statusCode))
) )