Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switchable secure mode #97

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
.cert/*
.projectile
node_modules
*.log
Expand Down
16 changes: 16 additions & 0 deletions bosh.conf.example.js
Expand Up @@ -6,6 +6,22 @@ exports.config = {
path: /^\/http-bind(\/+)?$/,
logging: 'INFO',

// Https serving option
secure: true,

// Https server settings
secure_parameters: {
// Classic cert files structure
// key: './cert/server.key',
// cert: './cert/server.crt',
// Pfx cert container
pfx: './cert/server.pfx',
ciphers: 'RSA:DH:SSLv2:!MD5:!aNULL'
// More security parameters on
// http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
// For `key`, `cert`, `pfx` and `ca` you can use links to files here.
},

// The maximum number of bytes that the BOSH server will
// "hold" from the client
max_data_held: 100000,
Expand Down
28 changes: 23 additions & 5 deletions run-server.js
Expand Up @@ -76,6 +76,10 @@ function main() {
note: "The host on which to the BOSH server should listen for connections (default: 0.0.0.0)",
value: -1
},
secure: {
note: 'Is BOSH service endpoint secured by ssl (https) (default: no)',
value: false
},
version: {
note: "Display version info and exit",
value: false
Expand Down Expand Up @@ -136,6 +140,15 @@ function main() {
server_options.host = opts.host;
}

if (opts.secure === false) {
if (typeof server_options.secure == 'undefined') {
server_options.secure = false;
}
}
else {
server_options.secure = opts.secure;
}

if (opts.path === -1) {
if (!server_options.path) {
server_options.path = '/http-bind/';
Expand All @@ -162,15 +175,20 @@ function main() {
dutil.TRIM_DEFAULT_LENGTH = server_options.trim_default_length;
}

print_boxed_message(nxb.dutil.sprintf("Starting BOSH server 'v%s' on 'http://%s:%s%s' at '%s'",
get_version(), server_options.host, server_options.port,
server_options.path, new Date())
print_boxed_message(nxb.dutil.sprintf("Starting BOSH server 'v%s' on '%s://%s:%s%s' at '%s'",
get_version(),
server_options.secure?'https':'http',
server_options.host,
server_options.port,
server_options.path,
new Date())
);

var bosh_server = nxb.start_bosh(server_options);

print_boxed_message(nxb.dutil.sprintf("Starting WEBSOCKET server 'v%s' on ws://%s:%s' at '%s'",
get_version(),
print_boxed_message(nxb.dutil.sprintf("Starting WEBSOCKET server 'v%s' on %s://%s:%s' at '%s'",
get_version(),
server_options.secure?'wss':'ws',
server_options.host,
server_options.port,
new Date())
Expand Down
27 changes: 27 additions & 0 deletions scripts/generate_cert.sh
@@ -0,0 +1,27 @@
#!/bin/sh
printf "Generates sample certificate and puts it in <server>/cert directorry for easier testing."
printf "Requires openssl."
printf "Run '<this script> pfx' to generate 'pfx' package certificate."
scriptPath=${0%/*}

if [ ! -d "$scriptPath/../cert" ]; then mkdir "$scriptPath/../cert"; fi

openssl req \
-new \
-x509 \
-days 731 \
-sha1 \
-newkey rsa:2048 \
-nodes \
-keyout "$scriptPath/../cert/server.key" \
-out "$scriptPath/../cert/server.crt" \
-subj '/O=Snakeoil/OU=Snakeoil/CN=Snakeoil.sl'

if [ x"$1" = x"pfx" ]; then
openssl pkcs12 -export -in "$scriptPath/../cert/server.crt" \
-inkey "$scriptPath/../cert/server.key" \
-out "$scriptPath/../cert/server.pfx" \
-password pass:
rm "$scriptPath/../cert/server.crt"
rm "$scriptPath/../cert/server.key"
fi
2 changes: 1 addition & 1 deletion src/bosh.js
Expand Up @@ -290,7 +290,7 @@ exports.createServer = function (options) {
bosh_options = new opt.BOSH_Options(options);
server = new http.HTTPServer(options.port, options.host, get_statistics,
get_system_info, bosh_request_handler,
http_error_handler, bosh_options);
http_error_handler, bosh_options, options.secure, options.secure_parameters);
// The BOSH event emitter. People outside will subscribe to
// events from this guy. We return an instance of BoshEventPipe
// to the outside world when anyone calls createServer()
Expand Down
30 changes: 26 additions & 4 deletions src/http-server.js
Expand Up @@ -28,10 +28,10 @@
var dutil = require('./dutil.js');
var us = require('underscore');
var helper = require('./helper.js');
var http = require('http');
var url = require('url');
var path = require('path');
var EventPipe = require('eventpipe').EventPipe;
var fs = require('fs');

var filename = path.basename(path.normalize(__filename));
var log = require('./log.js').getLogger(filename);
Expand All @@ -40,7 +40,7 @@ var BoshRequestParser = require('./bosh-request-parser').BoshRequestParser;

function HTTPServer(port, host, stat_func, system_info_func,
bosh_request_handler, http_error_handler,
bosh_options) {
bosh_options, secureFlag, secureParams) {

var bosh_request_parser = new BoshRequestParser();
var req_list1 = [ ], req_list2 = [ ];
Expand Down Expand Up @@ -318,8 +318,30 @@ function HTTPServer(port, host, stat_func, system_info_func,
router.emit('request', req, res, u);
}

// Initialize
var server = http.createServer(http_request_handler);
var server = null;
if (secureFlag) {
// Transfer all options from config.
var httpsOptions = secureParams;
// Checking cert files
if (fs.existsSync(secureParams.key)) {
httpsOptions['key'] = fs.readFileSync(secureParams.key);
httpsOptions['cert'] = fs.readFileSync(secureParams.cert);
}
if (fs.existsSync(secureParams.pfx)) {
httpsOptions['pfx'] = fs.readFileSync(secureParams.pfx);
}
if (httpsOptions['ca']) {
httpsOptions['ca'] = [].concat(httpsOptions['ca']).map(function (ca) {
return fs.existsSync(ca)?fs.readFileSync(ca):ca;
});
}

// Initialize
server = require('https').createServer(httpsOptions, http_request_handler);
} else {
server = require('http').createServer(http_request_handler);
}

server.on('error', http_error_handler);
server.listen(port, host);

Expand Down
15 changes: 11 additions & 4 deletions tests/all.sh
Expand Up @@ -16,7 +16,14 @@ then
exit 1
fi

node run-server.js &
SECUREPARAM=''
if [ "x$1" = "x--secure" ]
then
# curl https request without certificate trust check
SECUREPARAM="--secure"
fi

node run-server.js $SECUREPARAM &

sleep 1
WAIT_SEC=3
Expand All @@ -39,7 +46,7 @@ else
echo -e "\e[00;32mSUCCESS: tests/test_GET.sh\e[00m" 1>&2
fi

node tests/basic.js --username="nonxbtest@jappix.com" --password="nonxbtest" &
node tests/basic.js --username="nonxbtest@jappix.com" --password="nonxbtest" $SECUREPARAM &
wait $!
if [ $? -eq 0 ]
then
Expand All @@ -49,7 +56,7 @@ else
echo -e "\e[00;32mSUCCESS: tests/basic.js\e[00m" 1>&2
fi

node tests/basic.js --username="nxbtest@jappix.com" --password="nonxbtest" &
node tests/basic.js --username="nxbtest@jappix.com" --password="nonxbtest" $SECUREPARAM &
wait $!
if [ $? -eq 0 ]
then
Expand All @@ -59,7 +66,7 @@ else
echo -e "\e[00;32mSUCCESS: tests/basic.js\e[00m" 1>&2
fi

node tests/basic.js --username="nxbtest@jappix.com" --password="nxbtest" &
node tests/basic.js --username="nxbtest@jappix.com" --password="nxbtest" $SECUREPARAM &
wait $!
if [ $? -ne 0 ]
then
Expand Down
13 changes: 11 additions & 2 deletions tests/basic.js
Expand Up @@ -81,16 +81,25 @@ function main() {
note: 'The password to use',
},
endpoint: {
note: 'The BOSH service endpoint (default: http://localhost:5280/http-bind/)',
value: 'http://localhost:5280/http-bind/'
note: 'The BOSH service endpoint (default: localhost:5280/http-bind/)',
value: 'localhost:5280/http-bind/'
},
secure: {
note: 'Is BOSH service endpoint secured by ssl (https) (default: no)',
value: false
},
route: {
note: 'The route attribute to use (default: <empty>)',
value: ''
}
});

options = opts;
if (options.secure) {
options.endpoint = 'https://'+options.endpoint;
} else {
options.endpoint = 'http://'+options.endpoint;
}
connect(options);
}

Expand Down
13 changes: 11 additions & 2 deletions tests/send_recv.js
Expand Up @@ -152,14 +152,23 @@ function main() {
'(check the comments in this file for the format of the file to pass here'
},
endpoint: {
note: 'The BOSH service endpoint (default: http://localhost:5280/http-bind/)',
value: 'http://localhost:5280/http-bind/'
note: 'The BOSH service endpoint (default: localhost:5280/http-bind/)',
value: 'localhost:5280/http-bind/'
},
secure: {
note: 'Is BOSH service endpoint secured by ssl (https) (default: no)',
value: false
}
});

opts.users = require("./" + opts.users).users;

options = opts;
if (options.secure) {
options.endpoint = 'https://'+options.endpoint;
} else {
options.endpoint = 'http://'+options.endpoint;
}
start_test(options);
}

Expand Down
13 changes: 11 additions & 2 deletions tests/stress.js
Expand Up @@ -172,9 +172,13 @@ function main() {
note: 'The XMPP server of \'domain\' shall be connected to'
},
endpoint: {
note: 'The BOSH service endpoint (default: http://localhost:5280/http-bind/)',
value: 'http://localhost:5280/http-bind/'
note: 'The BOSH service endpoint (default: localhost:5280/http-bind/)',
value: 'localhost:5280/http-bind/'
},
secure: {
note: 'Is BOSH service endpoint secured by ssl (https) (default: no)',
value: false
},
route: {
note: 'The route attribute to use (default: <empty>)',
value: ''
Expand All @@ -195,6 +199,11 @@ function main() {
});

options = opts;
if (options.secure) {
options.endpoint = 'https://'+options.endpoint;
} else {
options.endpoint = 'http://'+options.endpoint;
}
start_test(options);
}

Expand Down
14 changes: 11 additions & 3 deletions tests/test_GET.sh
@@ -1,7 +1,15 @@
#! /bin/bash

PROT="http"

if [ "x$1" = "x--secure" ]
then
# curl https request without certificate trust check
PROT="-k https"
fi

# XML Request: <body to="jabber.org" hold="1" rid="2241" wait="60" ver="1.6" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0" />
LINE=`curl 'http://localhost:5280/http-bind/?data=%3Cbody%20to%3D%22jabber.org%22%20hold%3D%221%22%20rid%3D%222241%22%20wait%3D%2260%22%20ver%3D%221.6%22%20xmlns%3Axmpp%3D%22urn%3Axmpp%3Axbosh%22%20xmpp%3Aversion%3D%221.0%22%20/%3E'`
LINE=`curl $PROT'://localhost:5280/http-bind/?data=%3Cbody%20to%3D%22jabber.org%22%20hold%3D%221%22%20rid%3D%222241%22%20wait%3D%2260%22%20ver%3D%221.6%22%20xmlns%3Axmpp%3D%22urn%3Axmpp%3Axbosh%22%20xmpp%3Aversion%3D%221.0%22%20/%3E'`

echo "[1] Got Response: $LINE"

Expand All @@ -15,7 +23,7 @@ fi


# XML Request: <body/>
LINE=`curl 'http://localhost:5280/http-bind/?data=%3Cbody/%3E'`
LINE=`curl $PROT'://localhost:5280/http-bind/?data=%3Cbody/%3E'`

echo "[2] Got Response: $LINE"

Expand All @@ -29,7 +37,7 @@ fi


# XML Request: <body to="jabber.org" hold="1" rid="2241" wait="60" ver="1.6" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0" />
LINE=`curl 'http://localhost:5280/http-bind/?data=%3Cbody%20to%3D%22jabber.org%22%20hold%3D%221%22%20rid%3D%222241%22%20wait%3D%2260%22%20ver%3D%221.6%22%20xmlns%3Axmpp%3D%22urn%3Axmpp%3Axbosh%22%20xmpp%3Aversion%3D%221.0%22%20/%3E&callback=myCB'`
LINE=`curl $PROT'://localhost:5280/http-bind/?data=%3Cbody%20to%3D%22jabber.org%22%20hold%3D%221%22%20rid%3D%222241%22%20wait%3D%2260%22%20ver%3D%221.6%22%20xmlns%3Axmpp%3D%22urn%3Axmpp%3Axbosh%22%20xmpp%3Aversion%3D%221.0%22%20/%3E&callback=myCB'`

echo "[3] Got Response: $LINE"

Expand Down