common.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * common.js
  3. *
  4. * (C) 2011, Charlie Robbins, Paolo Fragomeni, & the Contributors.
  5. */
  6. var fs = require('fs'),
  7. tls = require('tls'),
  8. net = require('net'),
  9. crypto = require('crypto');
  10. exports.createSocket = function (options) {
  11. options = options || {};
  12. options.type = options.type || 'tcp4';
  13. return options.type === 'tls'
  14. ? exports.createTlsSocket(options)
  15. : new net.Socket(options);
  16. };
  17. //
  18. // ### function createTlsSocket (options)
  19. // #### @options {Object} Tls options like in tls.js
  20. // #### Should behave like tls.connect, except it just creates the socket like net.Socket
  21. // #### Also has a function called 'connect' that will allow` it to connect to a remote host
  22. // this is a rip of tls.js's connect
  23. //
  24. exports.createTlsSocket = function(options) {
  25. var self = this;
  26. //
  27. // Setup the TLS connection over the existing TCP connection:
  28. //
  29. // 1. Create a new instance of `net.Socket`.
  30. // 2. Create a new set of credentials with `options`.
  31. // 3. Create the TLS pair
  32. // 4. Pipe the TLS pair to the TCP socket
  33. //
  34. var socket = new net.Stream({ type: 'tcp4' });
  35. function setupTlsPipe () {
  36. var sslcontext = crypto.createCredentials(options),
  37. pair = tls.createSecurePair(sslcontext, false),
  38. cleartext = pipe(pair, socket);
  39. pair.on('secure', function() {
  40. var verifyError = pair.ssl.verifyError();
  41. if (verifyError) {
  42. cleartext.authorized = false;
  43. cleartext.authorizationError = verifyError;
  44. }
  45. else {
  46. cleartext.authorized = true;
  47. }
  48. });
  49. //
  50. // Setup the cleartext stream to have a `.connect()` method
  51. // which passes through to the underlying TCP socket.
  52. //
  53. socket.cleartext = cleartext;
  54. cleartext._controlReleased = true;
  55. }
  56. socket.on('connect', setupTlsPipe);
  57. return socket;
  58. };
  59. //
  60. // helper function for createTlsSocket
  61. //
  62. function pipe(pair, socket) {
  63. pair.encrypted.pipe(socket);
  64. socket.pipe(pair.encrypted);
  65. pair.fd = socket.fd;
  66. var cleartext = pair.cleartext;
  67. cleartext.socket = socket;
  68. cleartext.encrypted = pair.encrypted;
  69. cleartext.authorized = false;
  70. function onerror(e) {
  71. if (cleartext._controlReleased) {
  72. cleartext.emit('error', e);
  73. }
  74. }
  75. function onclose() {
  76. socket.removeListener('error', onerror);
  77. socket.removeListener('close', onclose);
  78. socket.removeListener('timeout', ontimeout);
  79. }
  80. function ontimeout() {
  81. cleartext.emit('timeout');
  82. }
  83. socket.on('error', onerror);
  84. socket.on('close', onclose);
  85. socket.on('timeout', ontimeout);
  86. return cleartext;
  87. }