Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 prime256v1 -genkey; \
openssl ec -in ssl/ecprivate.key -pubout -out ssl/ecpub.key; \
fi
COPY . /usr/src/app

CMD [ "npm", "start" ]
Expand Down
166 changes: 162 additions & 4 deletions app/webrtc_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,145 @@ var inBoundRemoteStatsKeys;
var outBoundRemoteStatsKeys;
var pcKeys;

var room = 'foo';
var room = "'><img src='' onerror=alert('foo') />";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why such a room name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this to test an XSS attack vector?

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);

Expand Down Expand Up @@ -74,14 +208,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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ should be replaced with 'null'. According to the latest dependencies schema.


Expand Down Expand Up @@ -488,8 +621,33 @@ function csReportErrorCallback (err, msg){
var params = {
//disableBeforeUnloadHandler: false
};
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);

callStats.initialize(appId, appSecret, myUserId, csInitCallback,statsCallback);

document.getElementById("switchBtn").onclick = switchScreen;

Expand Down
42 changes: 41 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand All @@ -13,6 +16,9 @@ var ids = {};

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;
Expand All @@ -22,7 +28,7 @@ server.listen(8080);
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});
});

app.get('/dailystatstest', function (req, res) {
Expand Down Expand Up @@ -97,6 +103,40 @@ 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,
keyID: config.keyID
}, 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});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's happening with tokenid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In real system, for audit purposes you should log the generated tokens. As this is a sample implementation, we will just log the fact that the token was granted.

callback(null, token);
});
});

socket.on('disconnect', function () {
var room = socket.roomId;
console.log('User disconnected ',socket.username,room);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down