|
| 1 | +'use strict'; |
| 2 | +var createSoapEnv, device, env, files, methods, parse, ref, request, response, set, stage; |
| 3 | + |
| 4 | +ref = require('./xml'), parse = ref.parse, methods = ref.methods, createSoapEnv = ref.createSoapEnv; |
| 5 | + |
| 6 | +files = require('../files'); |
| 7 | + |
| 8 | +stage = null; |
| 9 | + |
| 10 | +device = {}; |
| 11 | + |
| 12 | +env = []; |
| 13 | + |
| 14 | +set = function(obj, key, value) { |
| 15 | + var attr, attrs, i, j, len; |
| 16 | + attrs = key.split('.'); |
| 17 | + for (i = j = 0, len = attrs.length; j < len; i = ++j) { |
| 18 | + attr = attrs[i]; |
| 19 | + if (i === attrs.length - 1) { |
| 20 | + obj[attr] = value; |
| 21 | + } else { |
| 22 | + obj = obj[attr] != null ? obj[attr] : obj[attr] = {}; |
| 23 | + } |
| 24 | + } |
| 25 | + return obj; |
| 26 | +}; |
| 27 | + |
| 28 | +request = function(ip, req, res) { |
| 29 | + var DeviceInfo, SoftwareVersion, body, cwmp, cwmpVersion, element, file, header, idElement, input, k, key, params, ref1, ref2, ref3, ref4, ref5, software, str, v, value, version, xml; |
| 30 | + if (req.body.length > 0) { |
| 31 | + console.log('>>> REQUEST'); |
| 32 | + console.dir([req.headers, req.body]); |
| 33 | + xml = parse(req.body); |
| 34 | + element = xml['soapenv:Envelope']; |
| 35 | + body = element['soapenv:Body']; |
| 36 | + header = element['soapenv:Header']; |
| 37 | + ref1 = element.attributes; |
| 38 | + for (k in ref1) { |
| 39 | + v = ref1[k]; |
| 40 | + if (!((k != null) && (v != null))) { |
| 41 | + return; |
| 42 | + } |
| 43 | + str = k.replace('soapenv', 'soap-env') + '=\'' + v + '\''; |
| 44 | + if (env.indexOf(str) === -1) { |
| 45 | + env.push(str); |
| 46 | + } |
| 47 | + } |
| 48 | + res.name = stage = Object.keys(body)[0]; |
| 49 | + cwmp = (ref2 = element.attributes) != null ? ref2['xmlns:cwmp'] : void 0; |
| 50 | + ref3 = /urn:dslforum-org:cwmp-(\d+-\d+)/.exec(cwmp) || [cwmp, '1-2'], input = ref3[0], cwmpVersion = ref3[1]; |
| 51 | + res.cwmpVersion = cwmpVersion.replace(/-/g, '.'); |
| 52 | + idElement = header['cwmp:ID']; |
| 53 | + if (idElement) { |
| 54 | + res.id = req.id = idElement; |
| 55 | + } |
| 56 | + ref4 = body[stage]; |
| 57 | + for (key in ref4) { |
| 58 | + value = ref4[key]; |
| 59 | + res[key] = value; |
| 60 | + } |
| 61 | + if (((ref5 = res.ParameterList) != null ? ref5.ParameterValueStruct : void 0) != null) { |
| 62 | + params = res.ParameterList.ParameterValueStruct; |
| 63 | + res.params = Object.keys(params).reduce(function(obj, k) { |
| 64 | + if (typeof params[k] === 'string') { |
| 65 | + set(obj, k, params[k]); |
| 66 | + } |
| 67 | + return obj; |
| 68 | + }, {}); |
| 69 | + device = res.params.Device || res.params.InternetGatewayDevice || {}; |
| 70 | + } |
| 71 | + res.name += 'Response'; |
| 72 | + } else if (stage === 'cwmp:Inform') { |
| 73 | + console.log('>>> EMPTY REQUEST'); |
| 74 | + console.dir([req.headers, req.body]); |
| 75 | + DeviceInfo = (device || {}).DeviceInfo; |
| 76 | + SoftwareVersion = (DeviceInfo || {}).SoftwareVersion; |
| 77 | + version = 17; |
| 78 | + software = parseInt(SoftwareVersion.substring(0, 2)); |
| 79 | + if (software < 17) { |
| 80 | + version = 16; |
| 81 | + } |
| 82 | + file = files[version]; |
| 83 | + res.name = 'cwmp:Download'; |
| 84 | + res.fileType = '3 Vendor Configuration File'; |
| 85 | + res.fileSize = file.length; |
| 86 | + res.url = "http://" + ip + "/" + version + ".sts"; |
| 87 | + } |
| 88 | + res.env = env.join(' '); |
| 89 | + return response(req, res); |
| 90 | +}; |
| 91 | + |
| 92 | +response = function(req, res) { |
| 93 | + var body, code, data, headers; |
| 94 | + headers = { |
| 95 | + 'Content-Type': 'text/xml; charset="utf-8"', |
| 96 | + 'Server': 'ACSServer', |
| 97 | + 'SOAPServer': 'ACSServer' |
| 98 | + }; |
| 99 | + if (res.name && (methods[res.name] != null)) { |
| 100 | + if (res.name === 'cwmp:InformResponse') { |
| 101 | + headers['Set-Cookie'] = "session=7b0fa33078153e5c"; |
| 102 | + } |
| 103 | + if (res.id == null) { |
| 104 | + res.id = req.id != null ? req.id : req.id = '1690d26c77f0000'; |
| 105 | + } |
| 106 | + if (methods[res.name] != null) { |
| 107 | + body = methods[res.name](res); |
| 108 | + } |
| 109 | + data = createSoapEnv(res.env, res.id, body); |
| 110 | + code = 200; |
| 111 | + headers['Content-Length'] = data.length; |
| 112 | + console.log('<<< RESPONSE'); |
| 113 | + console.dir([headers, data]); |
| 114 | + } else { |
| 115 | + code = 204; |
| 116 | + data = null; |
| 117 | + headers['Connection'] = "close"; |
| 118 | + headers['Content-Length'] = 0; |
| 119 | + console.log('<<< EMPTY RESPONSE'); |
| 120 | + console.dir([headers, data]); |
| 121 | + } |
| 122 | + res.writeHead(code, headers); |
| 123 | + res.end(data); |
| 124 | + if (res.name === 'cwmp:TransferCompleteResponse') { |
| 125 | + console.log("Please try a ssh connection now to " + req.connection.remoteAddress + " with username root and password root (change password immediately with passwd!)"); |
| 126 | + return setTimeout(function() { |
| 127 | + return process.exit(1); |
| 128 | + }, 20000); |
| 129 | + } |
| 130 | +}; |
| 131 | + |
| 132 | +module.exports = function(ip) { |
| 133 | + return function(req, res) { |
| 134 | + var COOKIE_REGEX, match; |
| 135 | + COOKIE_REGEX = /\s*([a-zA-Z0-9\-_]+?)\s*=\s*"?([a-zA-Z0-9\-_]*?)"?\s*(,|;|$)/g; |
| 136 | + while (match = COOKIE_REGEX.exec(req.headers.cookie)) { |
| 137 | + if (match[1] === 'session') { |
| 138 | + req.id = res.id = match[2]; |
| 139 | + } |
| 140 | + } |
| 141 | + req.body = ''; |
| 142 | + req.on('data', function(chunk) { |
| 143 | + return req.body += chunk; |
| 144 | + }); |
| 145 | + req.on('end', function() { |
| 146 | + return request(ip, req, res); |
| 147 | + }); |
| 148 | + }; |
| 149 | +}; |
0 commit comments