Implemented HTTPS support

This commit is contained in:
Zaid Abdulla committed 2013-02-18 14:48:21 +03:00
1 parent 85fc5edc8d
commit 20fa79c0a3
4 files changed
+133 -89

No files matched your search

+99 -89
View File
@@ -2,12 +2,14 @@ config = require './config'
common = require './common' common = require './common'
util = require 'util' util = require 'util'
http = require 'http' http = require 'http'
https = require 'https'
tr069 = require './tr-069' tr069 = require './tr-069'
tasks = require './tasks' tasks = require './tasks'
sanitize = require('./sanitize').sanitize sanitize = require('./sanitize').sanitize
db = require './db' db = require './db'
presets = require './presets' presets = require './presets'
mongodb = require 'mongodb' mongodb = require 'mongodb'
fs = require 'fs'
applyConfigurations = (currentRequest, taskList) -> applyConfigurations = (currentRequest, taskList) ->
@@ -106,7 +108,7 @@ runTask = (currentRequest, task, methodResponse) ->
nextTask(currentRequest) nextTask(currentRequest)
) )
when tasks.STATUS_FAULT when tasks.STATUS_FAULT
util.log("#{currentRequest.deviceId}: Fault response for task #{taskId}") util.log("#{currentRequest.deviceId}: Fault response for task #{task._id}")
db.saveTask(task, (err) -> db.saveTask(task, (err) ->
# Faulty task. No more work to do until task is deleted. # Faulty task. No more work to do until task is deleted.
res = tr069.response(null, cwmpResponse) res = tr069.response(null, cwmpResponse)
@@ -166,6 +168,94 @@ nextTask = (currentRequest) ->
runTask(currentRequest, task, {}) runTask(currentRequest, task, {})
) )
listener = (httpRequest, httpResponse) ->
if httpRequest.method != 'POST'
#console.log '>>> 405 Method Not Allowed'
httpResponse.writeHead 405, {'Allow': 'POST'}
httpResponse.end('405 Method Not Allowed')
return
chunks = []
bytes = 0
cookies = {}
httpRequest.addListener 'data', (chunk) ->
chunks.push(chunk)
bytes += chunk.length
httpRequest.getBody = (encoding) ->
# Write all chunks into a Buffer
body = new Buffer(bytes)
offset = 0
chunks.forEach((chunk) ->
chunk.copy(body, offset, 0, chunk.length)
offset += chunk.length
)
#Return encoded (default to UTF8) string
return body.toString(encoding || 'utf8', 0, body.byteLength)
httpRequest.addListener 'end', () ->
currentRequest = {}
currentRequest.httpRequest = httpRequest
currentRequest.httpResponse = httpResponse
cwmpResponse = {}
cwmpRequest = tr069.request(httpRequest)
# get deviceId either from inform xml or cookie
if cwmpRequest.methodRequest? and cwmpRequest.methodRequest.type is 'Inform'
cookies.deviceId = currentRequest.deviceId = common.getDeviceId(cwmpRequest.methodRequest.deviceId)
else
currentRequest.deviceId = cwmpRequest.cookies.deviceId
if config.DEBUG_DEVICES[currentRequest.deviceId]
dump = "# REQUEST #{new Date(Date.now())}\n" + JSON.stringify(httpRequest.headers) + "\n#{httpRequest.getBody()}\n\n"
require('fs').appendFile("debug/#{currentRequest.deviceId}.dump", dump, (err) ->
throw new Error(err) if err
)
if cwmpRequest.methodRequest?
if cwmpRequest.methodRequest.type is 'Inform'
cwmpResponse.methodResponse = {type : 'InformResponse'}
if config.LOG_INFORMS
util.log("#{currentRequest.deviceId}: Inform (#{cwmpRequest.methodRequest.event}); retry count #{cwmpRequest.methodRequest.retryCount}")
updateDevice(currentRequest, {'inform' : true, 'parameterValues' : cwmpRequest.methodRequest.parameterList}, (err) ->
res = tr069.response(cwmpRequest.id, cwmpResponse, cookies)
writeResponse(currentRequest, res)
)
else if cwmpRequest.methodRequest.type is 'TransferComplete'
# do nothing
util.log("#{currentRequest.deviceId}: Transfer complete")
cwmpResponse.methodResponse = {type : 'TransferCompleteResponse'}
res = tr069.response(cwmpRequest.id, cwmpResponse, cookies)
writeResponse(currentRequest, res)
else
throw Error('ACS method not supported')
else if cwmpRequest.methodResponse?
taskId = cwmpRequest.id
db.getTask(taskId, (task) ->
if not task
nextTask(currentRequest)
else
runTask(currentRequest, task, cwmpRequest.methodResponse)
)
else if cwmpRequest.fault?
taskId = cwmpRequest.id
db.getTask(taskId, (task) ->
if not task
nextTask(currentRequest)
else
runTask(currentRequest, task, cwmpRequest.fault)
)
else
# cpe sent empty response. start sending acs requests
nextTask(currentRequest)
cluster = require 'cluster' cluster = require 'cluster'
numCPUs = require('os').cpus().length numCPUs = require('os').cpus().length
@@ -185,94 +275,14 @@ if cluster.isMaster
for i in [1 .. numCPUs] for i in [1 .. numCPUs]
cluster.fork() cluster.fork()
else else
server = http.createServer (httpRequest, httpResponse) -> options = {
if httpRequest.method != 'POST' key: fs.readFileSync('httpscert.key'),
#console.log '>>> 405 Method Not Allowed' cert: fs.readFileSync('httpscert.crt')
httpResponse.writeHead 405, {'Allow': 'POST'} }
httpResponse.end('405 Method Not Allowed')
return
chunks = [] httpServer = http.createServer(listener)
bytes = 0 httpsServer = https.createServer(options, listener)
cookies = {}
httpRequest.addListener 'data', (chunk) -> httpServer.listen(config.ACS_PORT, config.ACS_INTERFACE)
chunks.push(chunk) httpsServer.listen(config.ACS_HTTPS_PORT, config.ACS_HTTPS_INTERFACE)
bytes += chunk.length
httpRequest.getBody = (encoding) ->
# Write all chunks into a Buffer
body = new Buffer(bytes)
offset = 0
chunks.forEach((chunk) ->
chunk.copy(body, offset, 0, chunk.length)
offset += chunk.length
)
#Return encoded (default to UTF8) string
return body.toString(encoding || 'utf8', 0, body.byteLength)
httpRequest.addListener 'end', () ->
currentRequest = {}
currentRequest.httpRequest = httpRequest
currentRequest.httpResponse = httpResponse
cwmpResponse = {}
cwmpRequest = tr069.request(httpRequest)
# get deviceId either from inform xml or cookie
if cwmpRequest.methodRequest? and cwmpRequest.methodRequest.type is 'Inform'
cookies.deviceId = currentRequest.deviceId = common.getDeviceId(cwmpRequest.methodRequest.deviceId)
else
currentRequest.deviceId = cwmpRequest.cookies.deviceId
if config.DEBUG_DEVICES[currentRequest.deviceId]
dump = "# REQUEST #{new Date(Date.now())}\n" + JSON.stringify(httpRequest.headers) + "\n#{httpRequest.getBody()}\n\n"
require('fs').appendFile("debug/#{currentRequest.deviceId}.dump", dump, (err) ->
throw new Error(err) if err
)
if cwmpRequest.methodRequest?
if cwmpRequest.methodRequest.type is 'Inform'
cwmpResponse.methodResponse = {type : 'InformResponse'}
if config.LOG_INFORMS
util.log("#{currentRequest.deviceId}: Inform (#{cwmpRequest.methodRequest.event}); retry count #{cwmpRequest.methodRequest.retryCount}")
updateDevice(currentRequest, {'inform' : true, 'parameterValues' : cwmpRequest.methodRequest.parameterList}, (err) ->
res = tr069.response(cwmpRequest.id, cwmpResponse, cookies)
writeResponse(currentRequest, res)
)
else if cwmpRequest.methodRequest.type is 'TransferComplete'
# do nothing
util.log("#{currentRequest.deviceId}: Transfer complete")
cwmpResponse.methodResponse = {type : 'TransferCompleteResponse'}
res = tr069.response(cwmpRequest.id, cwmpResponse, cookies)
writeResponse(currentRequest, res)
else
throw Error('ACS method not supported')
else if cwmpRequest.methodResponse?
taskId = cwmpRequest.id
db.getTask(taskId, (task) ->
if not task
nextTask(currentRequest)
else
runTask(currentRequest, task, cwmpRequest.methodResponse)
)
else if cwmpRequest.fault?
taskId = cwmpRequest.id
db.getTask(taskId, (task) ->
if not task
nextTask(currentRequest)
else
runTask(currentRequest, task, cwmpRequest.fault)
)
else
# cpe sent empty response. start sending acs requests
nextTask(currentRequest)
server.listen config.ACS_PORT, config.ACS_INTERFACE
#console.log "Server listening on port #{config.ACS_PORT}" #console.log "Server listening on port #{config.ACS_PORT}"
+2
View File
@@ -1,6 +1,8 @@
exports.DATABASE_NAME = 'genie' exports.DATABASE_NAME = 'genie'
exports.ACS_PORT = 7547 # CWMP port as assigned by IANA exports.ACS_PORT = 7547 # CWMP port as assigned by IANA
exports.ACS_HTTPS_PORT = 7548
exports.ACS_INTERFACE = '0.0.0.0' exports.ACS_INTERFACE = '0.0.0.0'
exports.ACS_HTTPS_INTERFACE = '0.0.0.0'
exports.API_PORT = 7557 exports.API_PORT = 7557
exports.API_INTERFACE = '0.0.0.0' exports.API_INTERFACE = '0.0.0.0'
exports.FILES_PORT = 7567 exports.FILES_PORT = 7567
+17
View File
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICqTCCAhICCQDSrolRw1qPBzANBgkqhkiG9w0BAQUFADCBmDELMAkGA1UEBhMC
SVExFTATBgNVBAgMDFN1bGF5bWFuaXlhaDEVMBMGA1UEBwwMU3VsYXltYW5peWFo
MQ8wDQYDVQQKDAZGYW5vb3MxEzARBgNVBAsMClRlY2hub2xvZ3kxDjAMBgNVBAMM
BWdlbmllMSUwIwYJKoZIhvcNAQkBFhZ6YWlkLmFiZHVsbGFAZmFub29zLmlxMB4X
DTEzMDIxNzEyNTYzN1oXDTE0MDIxNzEyNTYzN1owgZgxCzAJBgNVBAYTAklRMRUw
EwYDVQQIDAxTdWxheW1hbml5YWgxFTATBgNVBAcMDFN1bGF5bWFuaXlhaDEPMA0G
A1UECgwGRmFub29zMRMwEQYDVQQLDApUZWNobm9sb2d5MQ4wDAYDVQQDDAVnZW5p
ZTElMCMGCSqGSIb3DQEJARYWemFpZC5hYmR1bGxhQGZhbm9vcy5pcTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAxtHC3jlOoVsZQ9I8Wgd+8NkEaRfc01lRIAzj
eWuUO/xNY54EUDHecRxwolHtoGkkZAp4kKR3uUVdAo9uXmNT2CeeZ5lfRoa8WmgG
Yd6PExsdc4ZeKcw20XrKtQICqmU6rGlLERMFX97ejQh3eUmqwbzNaXiURxcKGdeK
2C/NxoUCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAYFw6dy/z74ahnA5QpuJOjjTrt
AJaL9iuL1xS6TFfzne9UMIT+fFJsgSy6xx3TGkvbZJTnCzJN7I2uqmAhMoGFy7Ea
svCCkj8U5qkjqgwwi7IbwQ7fXxTVdPqUlkIdNB2YLDELksxCX+ZzGQPiFB8WrSoO
OBvB+hhPFpgp3aO2AQ==
-----END CERTIFICATE-----
+15
View File
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDG0cLeOU6hWxlD0jxaB37w2QRpF9zTWVEgDON5a5Q7/E1jngRQ
Md5xHHCiUe2gaSRkCniQpHe5RV0Cj25eY1PYJ55nmV9GhrxaaAZh3o8TGx1zhl4p
zDbResq1AgKqZTqsaUsREwVf3t6NCHd5SarBvM1peJRHFwoZ14rYL83GhQIDAQAB
AoGAR4NpuW8ZhlZzNv7m8Gcj1NPqjzajGm5VDNc19xWoAw+UcpGC8amOXlcheHFJ
rNpE2asehMBzw/NcKjCXPWIy5LnGmttJMN2EbT2h/+uxBIM5IUc+joF744xF4C0t
5zrtqQYJxC7sBLX2vf7nY6iuovUM7fHEwACyV3Rpw3zdZf0CQQDiqW+ugLKcfS/c
6hkGTxeYWF4gUJTf3ke3au8nyMmUhyBwOuP4kpO72mK8bMLtjZRk3g6YChA4qH41
nfXUXIh7AkEA4I2/zj4GDjjspDR+/tX0iUHQk1Rm2CRmRXXFJV1f688OLODCcOFK
Ms/+qnbe41wXo1NUxCqVrnPwEh3MVl88/wJBANUTpXqtX7s+8ETECTxmE+9Se0Hz
ntCJXG/v5d1Ho0Cueu8mXXMrEBiTpygtMl4xL2RXX+7L3w30T5lF4nh9eIsCQQDY
DmsbdL/81TaTc9MxPQlxOzsFVrMxiixA7uTGY8ZULD/2XDeZxprOsyPUPlWMquIv
ipFHwbWNSg4WUEd4X2BfAkEAytze+0mCd0WCsKbKwfTQnmJ3bK7JQywtC03llWyA
Om3Vl61Syaa7M2hl5rLvitZMvU1Wd0s8raOXN8RUuRXZBw==
-----END RSA PRIVATE KEY-----