From bae60f29e61a0fdbfdcca96748c528288c1e2ad1 Mon Sep 17 00:00:00 2001 From: Eljas Alakulppi Date: Tue, 7 Jun 2016 10:24:14 +0300 Subject: [PATCH 1/4] JWT authentication --- Dockerfile | 9 ++++++++- app/webrtc_app.js | 32 ++++++++++++++++++++++++++++---- index.js | 41 ++++++++++++++++++++++++++++++++++++++++- package.json | 3 ++- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index b8ae10a..6a28bd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,14 @@ FROM node:4.3.1 WORKDIR /usr/src/app COPY package.json /usr/src/app/ -RUN npm install; mkdir ssl; openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ssl/server.key -out ssl/server.crt -passin pass:v2ZIZj2jKUap -subj '/CN=localhost/O=Local/C=FI'; cp ssl/server.crt ssl/ca.crt +RUN npm install; \ + mkdir ssl; \ + openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ssl/server.key -out ssl/server.crt -passin pass:v2ZIZj2jKUap -subj '/CN=localhost/O=Local/C=FI'; \ + cp ssl/server.crt ssl/ca.crt; \ + if [ ! -f ssl/ecprivate.key ]; \ + then openssl ecparam -out ssl/ecprivate.key -name secp256k1 -genkey; \ + openssl ec -in ssl/ecprivate.key -pubout -out ssl/ecpub.key; \ + fi COPY . /usr/src/app CMD [ "npm", "start" ] diff --git a/app/webrtc_app.js b/app/webrtc_app.js index 4053616..b52ee2a 100644 --- a/app/webrtc_app.js +++ b/app/webrtc_app.js @@ -9,7 +9,7 @@ var isScreenSharingOn = false; var isFirefox = false; var isChrome = false; -var room = 'foo'; +var room = "'>"; console.log("Room is " + room); var temp = Math.floor(Math.random()*10000); @@ -38,14 +38,13 @@ if (room !== ''){ //socket.emit('participant', room,myUserId); doGetUserMedia(function(status){ if (status === true) { - socket.emit('participant', room,myUserId); + socket.emit('participant', room, myUserId); } }); } var appConfig = AppConfiguration(); var appId = appConfig.appId; -var appSecret = appConfig.appSecret; var callStats = new callstats($,io,jsSHA); @@ -130,7 +129,32 @@ function csReportErrorCallback (err, msg){ console.log("CallStats error: err="+err+" msg="+msg); } -callStats.initialize(appId, appSecret, myUserId, csInitCallback,statsCallback); +var createTokenGeneratorTimer; + +var tokenGenerator = (function () { + var cached = null; + return function(forcenew, callback) { + if (!forcenew && cached !== null) { + return callback(null, cached); + } + socket.emit('generateToken', "foobar", function (err, token) { + if (err) { + console.log('Token generation failed'); + console.log("try again"); + return createTokenGeneratorTimer(forcenew, callback); + } + console.log("got token"); + callback(null, token); + }); + }; +})(); + +createTokenGeneratorTimer = function (forcenew, callback) { + return setTimeout(function () { console.log("calling tokenGenerator"); tokenGenerator(forcenew, callback);}, 100); +}; + + +callStats.initialize(appId, tokenGenerator, myUserId, csInitCallback,statsCallback); document.getElementById("switchBtn").onclick = switchScreen; diff --git a/index.js b/index.js index 6626b42..98682df 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,9 @@ var http = require('http'); var https = require('https'); var fs = require('fs'); var path = require('path'); +var jwt = require('jsonwebtoken'); +var crypto = require('crypto'); +var config = require('./config.js'); var numClients = 0; var usernames = []; @@ -17,6 +20,9 @@ var server = http.createServer(app); fs.exists = fs.exists || require('path').exists; +var privKey = null; + +privKey = fs.readFileSync('ssl/ecprivate.key'); //app.listen(8080); app.root = __dirname; @@ -27,7 +33,7 @@ app.use("/", express.static(__dirname + '/app')); app.get('/', function (req, res) { console.log("Req ",req); - res.sendFile('/app/index.html',{root: __dirname}) + res.sendFile('/app/index.html',{root: __dirname}); }); var io = null; @@ -99,6 +105,39 @@ io.sockets.on('connection', function (socket){ }); + socket.on('generateToken', function (data, callback) { + if (socket.username === undefined || socket.username === null) { + return callback('userNotJoined'); + } + // First generate the JWTID + crypto.randomBytes(48, function(err, buffer) { + if (err) { + return callback(err); + } + var tokenid = buffer.toString('hex'); + var token = null; + try { + // Try to sign teh token + token = jwt.sign( + { + userID: socket.username, + appID: config.appID + }, privKey, + { + algorithm: "ES256", + jwtid: tokenid, + expiresIn: 300, //5 minutes + notBefore: -300 //-5 minutes + }); + } catch (error) { + console.log(error); + return callback(error); + } + console.log({action: "GrantToken", user: socket.username, tokenid: tokenid}); + callback(null, token); + }); + }); + socket.on('disconnect', function () { var room = socket.roomId; console.log('User disconnected ',socket.username,room); diff --git a/package.json b/package.json index 579be7d..b83b049 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "license": "ISC", "dependencies": { "express": "^4.13.3", - "socket.io": "1.3.7" + "socket.io": "1.3.7", + "jsonwebtoken": "7.0.0" }, "private": true, "scripts": { From 67578990da8d608a0eecf14a38c8047ee7bb8629 Mon Sep 17 00:00:00 2001 From: Eljas Alakulppi Date: Wed, 8 Jun 2016 08:00:49 +0300 Subject: [PATCH 2/4] Merge conflict resolved --- app/webrtc_app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/webrtc_app.js b/app/webrtc_app.js index 68aa3ff..d806cc8 100644 --- a/app/webrtc_app.js +++ b/app/webrtc_app.js @@ -487,7 +487,6 @@ function csReportErrorCallback (err, msg){ var params = { //disableBeforeUnloadHandler: false }; - var createTokenGeneratorTimer; var tokenGenerator = (function () { @@ -512,8 +511,10 @@ createTokenGeneratorTimer = function (forcenew, callback) { return setTimeout(function () { console.log("calling tokenGenerator"); tokenGenerator(forcenew, callback);}, 100); }; + callStats.initialize(appId, tokenGenerator, myUserId, csInitCallback,statsCallback); + document.getElementById("switchBtn").onclick = switchScreen; var onPCInitialized = function(pc, receiver){ From 59654ee0cc675a9f61a0f1cfe3a1692a5045a3ab Mon Sep 17 00:00:00 2001 From: Eljas Alakulppi Date: Wed, 17 Aug 2016 13:04:11 +0300 Subject: [PATCH 3/4] Fix ECDSA authentication --- Dockerfile | 2 +- index.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6a28bd2..b1bcaa7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN npm install; \ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ssl/server.key -out ssl/server.crt -passin pass:v2ZIZj2jKUap -subj '/CN=localhost/O=Local/C=FI'; \ cp ssl/server.crt ssl/ca.crt; \ if [ ! -f ssl/ecprivate.key ]; \ - then openssl ecparam -out ssl/ecprivate.key -name secp256k1 -genkey; \ + then openssl ecparam -out ssl/ecprivate.key -name prime256v1 -genkey; \ openssl ec -in ssl/ecprivate.key -pubout -out ssl/ecpub.key; \ fi COPY . /usr/src/app diff --git a/index.js b/index.js index 8ec09d0..ce7b30f 100644 --- a/index.js +++ b/index.js @@ -119,7 +119,8 @@ io.sockets.on('connection', function (socket){ token = jwt.sign( { userID: socket.username, - appID: config.appID + appID: config.appID, + keyID: config.keyID }, privKey, { algorithm: "ES256", From 48d35e5ff5b940abf721910ce64019379efacbdb Mon Sep 17 00:00:00 2001 From: Lennart Schulte Date: Thu, 2 Mar 2017 15:09:42 +0200 Subject: [PATCH 4/4] add detectBrowserInfo function --- app/webrtc_app.js | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/app/webrtc_app.js b/app/webrtc_app.js index d806cc8..b226594 100644 --- a/app/webrtc_app.js +++ b/app/webrtc_app.js @@ -22,6 +22,140 @@ console.log("Room is " + room); var temp = Math.floor(Math.random()*10000); var myUserId = temp.toString(); + +/** + * Detect broswer os, name, version info + * @memberOf callstats + * @private + */ +var detectBrowserInfo = function() { + var nAgt = navigator.userAgent; + var browserName = navigator.appName; + var nVer = navigator.appVersion; + var fullVersion = '' + parseFloat(navigator.appVersion); + var verOffset; + var codeBase = { + goog: "Chrome", + moz: "Firefox", + plugin: "Plugin", + edge: "Edge" + }; + var codeBaseType; + // In Opera, the true version is after "Opera" or after "Version" + if ((verOffset = nAgt.indexOf("Opera")) !== -1) { + browserName = "Opera"; + fullVersion = nAgt.substring(verOffset + 6); + if ((verOffset = nAgt.indexOf("Version")) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + codeBaseType = codeBase.goog; + } else if ((verOffset = nAgt.indexOf("OPR")) !== -1) { + browserName = "Opera"; + fullVersion = nAgt.substring(verOffset + 4); + if ((verOffset = nAgt.indexOf("Version")) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + codeBaseType = codeBase.goog; + } else if ((verOffset = nAgt.indexOf("MSIE")) !== -1) { // In MSIE, the true version is after "MSIE" in userAgent + browserName = "Microsoft Internet Explorer"; + fullVersion = nAgt.substring(verOffset + 5); + codeBaseType = codeBase.goog; + } else if((verOffset = nAgt.indexOf("Edge")) !== -1) { + browserName = codeBase.edge; + fullVersion = nAgt.substring(verOffset + 5); + codeBaseType = codeBase.edge; + } else if ((verOffset = nAgt.indexOf("Chrome")) !== -1) { // In Chrome, the true version is after "Chrome" + browserName = codeBase.goog; + fullVersion = nAgt.substring(verOffset + 7); + codeBaseType = codeBase.goog; + } else if ((verOffset = nAgt.indexOf("Safari")) !== -1) { // In Safari, the true version is after "Safari" or after "Version" + browserName = "Safari"; + fullVersion = nAgt.substring(verOffset + 7); + if ((verOffset = nAgt.indexOf("Version")) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + codeBaseType = codeBase.goog; + } else if ((verOffset = nAgt.indexOf("Firefox")) !== -1) { // In Firefox, the true version is after "Firefox" + browserName = "Firefox"; + fullVersion = nAgt.substring(verOffset + 8); + codeBaseType = codeBase.moz; + } else if ((verOffset = nAgt.indexOf("Trident")) !== -1) { // IE 11 has no MSIE + browserName = "Microsoft Internet Explorer"; + verOffset = nAgt.indexOf("rv"); // In IE11, the true version is after "rv" + fullVersion = nAgt.substring(verOffset + 3, verOffset + 7); + codeBaseType = codeBase.goog; + } + + // system + // source: http://jsfiddle.net/ChristianL/AVyND/ + var osName = null; + var clientStrings = [ + {s: 'Windows 3.11', r: /Win16/}, + {s: 'Windows 95', r: /(Windows 95|Win95|Windows_95)/}, + {s: 'Windows ME', r: /(Win 9x 4.90|Windows ME)/}, + {s: 'Windows 98', r: /(Windows 98|Win98)/}, + {s: 'Windows CE', r: /Windows CE/}, + {s: 'Windows 2000', r: /(Windows NT 5.0|Windows 2000)/}, + {s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/}, + {s: 'Windows Server 2003', r: /Windows NT 5.2/}, + {s: 'Windows Vista', r: /Windows NT 6.0/}, + {s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/}, + {s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/}, + {s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/}, + {s: 'Windows 10', r: /(Windows 10|Windows NT 10.0)/}, + {s: 'Windows NT 4.0', r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/}, + {s: 'Windows ME', r: /Windows ME/}, + {s: 'Android', r: /Android/}, + {s: 'Open BSD', r: /OpenBSD/}, + {s: 'Sun OS', r: /SunOS/}, + {s: 'Linux', r: /(Linux|X11)/}, + {s: 'iOS', r: /(iPhone|iPad|iPod)/}, + {s: 'Mac OS X', r: /Mac OS X/}, + {s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/}, + {s: 'QNX', r: /QNX/}, + {s: 'UNIX', r: /UNIX/}, + {s: 'BeOS', r: /BeOS/}, + {s: 'OS/2', r: /OS\/2/}, + {s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/} + ]; + + var id, cs; + for (id in clientStrings) { + cs = clientStrings[id]; + if (cs.r.test(nAgt)) { + osName = cs.s; + break; + } + } + + var osVersion = null; + if (/Windows/.test(osName)) { + osVersion = /Windows (.*)/.exec(osName)[1]; + osName = 'Windows'; + } + + switch (osName) { + case 'Mac OS X': + osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1]; + break; + case 'Android': + osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1]; + break; + case 'iOS': + osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer); + osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0); + break; + } + return { + name: browserName, + ver: fullVersion.toString(), + os: osName, + osVersion: osVersion, + codebase: codeBaseType, + userAgent: nAgt, + }; +}; + var browserInfo = detectBrowserInfo(); console.log("Browser details ",browserInfo);