Split utils file
authorChocobozzz <florian.bigard@gmail.com>
Fri, 5 Feb 2016 17:03:20 +0000 (18:03 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Fri, 5 Feb 2016 17:03:20 +0000 (18:03 +0100)
controllers/api/v1/pods.js
helpers/peertubeCrypto.js [new file with mode: 0644]
helpers/requests.js [new file with mode: 0644]
helpers/utils.js
lib/friends.js
lib/poolRequests.js
middlewares/secure.js
server.js

index 3e457ec57d7859c044c94123e5692744c915efd2..29517ba8ecbe934aceb54a509cf9cc20d6a37b44 100644 (file)
@@ -8,11 +8,11 @@
   var friends = require('../../../lib/friends')
   var middleware = require('../../../middlewares')
   var cacheMiddleware = middleware.cache
+  var peertubeCrypto = require('../../../helpers/peertubeCrypto')
   var Pods = require('../../../models/pods')
   var reqValidator = middleware.reqValidators.pods
   var secureMiddleware = middleware.secure
   var secureRequest = middleware.reqValidators.remote.secureRequest
-  var utils = require('../../../helpers/utils')
   var Videos = require('../../../models/videos')
 
   var router = express.Router()
@@ -37,7 +37,7 @@
 
       Videos.addRemotes(informations.videos)
 
-      fs.readFile(utils.getCertDir() + 'peertube.pub', 'utf8', function (err, cert) {
+      fs.readFile(peertubeCrypto.getCertDir() + 'peertube.pub', 'utf8', function (err, cert) {
         if (err) {
           logger.error('Cannot read cert file.', { error: err })
           return next(err)
diff --git a/helpers/peertubeCrypto.js b/helpers/peertubeCrypto.js
new file mode 100644 (file)
index 0000000..3e75765
--- /dev/null
@@ -0,0 +1,152 @@
+;(function () {
+  'use strict'
+
+  var config = require('config')
+  var crypto = require('crypto')
+  var fs = require('fs')
+  var openssl = require('openssl-wrapper')
+  var ursa = require('ursa')
+
+  var logger = require('./logger')
+
+  var certDir = __dirname + '/../' + config.get('storage.certs')
+  var algorithm = 'aes-256-ctr'
+
+  var peertubeCrypto = {
+    checkSignature: checkSignature,
+    createCertsIfNotExist: createCertsIfNotExist,
+    decrypt: decrypt,
+    encrypt: encrypt,
+    getCertDir: getCertDir,
+    sign: sign
+  }
+
+  function checkSignature (public_key, raw_data, hex_signature) {
+    var crt = ursa.createPublicKey(public_key)
+    var is_valid = crt.hashAndVerify('sha256', new Buffer(raw_data).toString('hex'), hex_signature, 'hex')
+    return is_valid
+  }
+
+  function createCertsIfNotExist (callback) {
+    certsExist(function (exist) {
+      if (exist === true) {
+        return callback(null)
+      }
+
+      createCerts(function (err) {
+        return callback(err)
+      })
+    })
+  }
+
+  function decrypt (key, data, callback) {
+    fs.readFile(getCertDir() + 'peertube.key.pem', function (err, file) {
+      if (err) return callback(err)
+
+      var my_private_key = ursa.createPrivateKey(file)
+      var decrypted_key = my_private_key.decrypt(key, 'hex', 'utf8')
+      var decrypted_data = symetricDecrypt(data, decrypted_key)
+
+      return callback(null, decrypted_data)
+    })
+  }
+
+  function encrypt (public_key, data, callback) {
+    var crt = ursa.createPublicKey(public_key)
+
+    symetricEncrypt(data, function (err, dataEncrypted) {
+      if (err) return callback(err)
+
+      var key = crt.encrypt(dataEncrypted.password, 'utf8', 'hex')
+      var encrypted = {
+        data: dataEncrypted.crypted,
+        key: key
+      }
+
+      callback(null, encrypted)
+    })
+  }
+
+  function getCertDir () {
+    return certDir
+  }
+
+  function sign (data) {
+    var myKey = ursa.createPrivateKey(fs.readFileSync(certDir + 'peertube.key.pem'))
+    var signature = myKey.hashAndSign('sha256', data, 'utf8', 'hex')
+
+    return signature
+  }
+
+  // ---------------------------------------------------------------------------
+
+  module.exports = peertubeCrypto
+
+  // ---------------------------------------------------------------------------
+
+  function certsExist (callback) {
+    fs.exists(certDir + 'peertube.key.pem', function (exists) {
+      return callback(exists)
+    })
+  }
+
+  function createCerts (callback) {
+    certsExist(function (exist) {
+      if (exist === true) {
+        var string = 'Certs already exist.'
+        logger.warning(string)
+        return callback(new Error(string))
+      }
+
+      logger.info('Generating a RSA key...')
+      openssl.exec('genrsa', { 'out': certDir + 'peertube.key.pem', '2048': false }, function (err) {
+        if (err) {
+          logger.error('Cannot create private key on this pod.', { error: err })
+          return callback(err)
+        }
+        logger.info('RSA key generated.')
+
+        logger.info('Manage public key...')
+        openssl.exec('rsa', { 'in': certDir + 'peertube.key.pem', 'pubout': true, 'out': certDir + 'peertube.pub' }, function (err) {
+          if (err) {
+            logger.error('Cannot create public key on this pod .', { error: err })
+            return callback(err)
+          }
+
+          logger.info('Public key managed.')
+          return callback(null)
+        })
+      })
+    })
+  }
+
+  function generatePassword (callback) {
+    crypto.randomBytes(32, function (err, buf) {
+      if (err) {
+        return callback(err)
+      }
+
+      callback(null, buf.toString('utf8'))
+    })
+  }
+
+  function symetricDecrypt (text, password) {
+    var decipher = crypto.createDecipher(algorithm, password)
+    var dec = decipher.update(text, 'hex', 'utf8')
+    dec += decipher.final('utf8')
+    return dec
+  }
+
+  function symetricEncrypt (text, callback) {
+    generatePassword(function (err, password) {
+      if (err) {
+        return callback(err)
+      }
+
+      var cipher = crypto.createCipher(algorithm, password)
+      var crypted = cipher.update(text, 'utf8', 'hex')
+      crypted += cipher.final('hex')
+      callback(null, { crypted: crypted, password: password })
+    })
+  }
+})()
diff --git a/helpers/requests.js b/helpers/requests.js
new file mode 100644 (file)
index 0000000..0e301da
--- /dev/null
@@ -0,0 +1,111 @@
+;(function () {
+  'use strict'
+
+  var async = require('async')
+  var config = require('config')
+  var request = require('request')
+  var replay = require('request-replay')
+
+  var constants = require('../initializers/constants')
+  var logger = require('./logger')
+  var peertubeCrypto = require('./peertubeCrypto')
+
+  var http = config.get('webserver.https') ? 'https' : 'http'
+  var host = config.get('webserver.host')
+  var port = config.get('webserver.port')
+
+  var requests = {
+    makeMultipleRetryRequest: makeMultipleRetryRequest
+  }
+
+  function makeMultipleRetryRequest (all_data, pods, callbackEach, callback) {
+    if (!callback) {
+      callback = callbackEach
+      callbackEach = null
+    }
+
+    var url = http + '://' + host + ':' + port
+    var signature
+
+    // Add signature if it is specified in the params
+    if (all_data.method === 'POST' && all_data.data && all_data.sign === true) {
+      signature = peertubeCrypto.sign(url)
+    }
+
+    // Make a request for each pod
+    async.each(pods, function (pod, callback_each_async) {
+      function callbackEachRetryRequest (err, response, body, url, pod) {
+        if (callbackEach !== null) {
+          callbackEach(err, response, body, url, pod, function () {
+            callback_each_async()
+          })
+        } else {
+          callback_each_async()
+        }
+      }
+
+      var params = {
+        url: pod.url + all_data.path,
+        method: all_data.method
+      }
+
+      // Add data with POST requst ?
+      if (all_data.method === 'POST' && all_data.data) {
+        // Encrypt data ?
+        if (all_data.encrypt === true) {
+          // TODO: ES6 with let
+          ;(function (copy_params, copy_url, copy_pod, copy_signature) {
+            peertubeCrypto.encrypt(pod.publicKey, JSON.stringify(all_data.data), function (err, encrypted) {
+              if (err) return callback(err)
+
+              copy_params.json = {
+                data: encrypted.data,
+                key: encrypted.key
+              }
+
+              makeRetryRequest(copy_params, copy_url, copy_pod, copy_signature, callbackEachRetryRequest)
+            })
+          })(params, url, pod, signature)
+        } else {
+          params.json = { data: all_data.data }
+          makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest)
+        }
+      } else {
+        makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest)
+      }
+    }, callback)
+  }
+
+  // ---------------------------------------------------------------------------
+
+  module.exports = requests
+
+  // ---------------------------------------------------------------------------
+
+  function makeRetryRequest (params, from_url, to_pod, signature, callbackEach) {
+    // Append the signature
+    if (signature) {
+      params.json.signature = {
+        url: from_url,
+        signature: signature
+      }
+    }
+
+    logger.debug('Make retry requests to %s.', to_pod.url)
+
+    replay(
+      request.post(params, function (err, response, body) {
+        callbackEach(err, response, body, params.url, to_pod)
+      }),
+      {
+        retries: constants.REQUEST_RETRIES,
+        factor: 3,
+        maxTimeout: Infinity,
+        errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
+      }
+    ).on('replay', function (replay) {
+      logger.info('Replaying request to %s. Request failed: %d %s. Replay number: #%d. Will retry in: %d ms.',
+        params.url, replay.error.code, replay.error.message, replay.number, replay.delay)
+    })
+  }
+})()
index ec46631b13757998e8a8368d3d12bb4c5cb4a352..bd0557977548147fc93560a67deeeca3b2121ee0 100644 (file)
 ;(function () {
   'use strict'
 
-  var async = require('async')
-  var config = require('config')
-  var crypto = require('crypto')
-  var fs = require('fs')
-  var openssl = require('openssl-wrapper')
-  var request = require('request')
-  var replay = require('request-replay')
-  var ursa = require('ursa')
-
-  var constants = require('../initializers/constants')
   var logger = require('./logger')
 
-  var certDir = __dirname + '/../' + config.get('storage.certs')
-  var http = config.get('webserver.https') ? 'https' : 'http'
-  var host = config.get('webserver.host')
-  var port = config.get('webserver.port')
-  var algorithm = 'aes-256-ctr'
-
   var utils = {
-    getCertDir: getCertDir,
-    certsExist: certsExist,
-    cleanForExit: cleanForExit,
-    createCerts: createCerts,
-    createCertsIfNotExist: createCertsIfNotExist,
-    generatePassword: generatePassword,
-    makeMultipleRetryRequest: makeMultipleRetryRequest,
-    symetricEncrypt: symetricEncrypt,
-    symetricDecrypt: symetricDecrypt
-  }
-
-  function getCertDir () {
-    return certDir
-  }
-
-  function makeMultipleRetryRequest (all_data, pods, callbackEach, callback) {
-    if (!callback) {
-      callback = callbackEach
-      callbackEach = null
-    }
-
-    var url = http + '://' + host + ':' + port
-    var signature
-
-    // Add signature if it is specified in the params
-    if (all_data.method === 'POST' && all_data.data && all_data.sign === true) {
-      var myKey = ursa.createPrivateKey(fs.readFileSync(certDir + 'peertube.key.pem'))
-      signature = myKey.hashAndSign('sha256', url, 'utf8', 'hex')
-    }
-
-    // Make a request for each pod
-    async.each(pods, function (pod, callback_each_async) {
-      function callbackEachRetryRequest (err, response, body, url, pod) {
-        if (callbackEach !== null) {
-          callbackEach(err, response, body, url, pod, function () {
-            callback_each_async()
-          })
-        } else {
-          callback_each_async()
-        }
-      }
-
-      var params = {
-        url: pod.url + all_data.path,
-        method: all_data.method
-      }
-
-      // Add data with POST requst ?
-      if (all_data.method === 'POST' && all_data.data) {
-        // Encrypt data ?
-        if (all_data.encrypt === true) {
-          var crt = ursa.createPublicKey(pod.publicKey)
-
-          // TODO: ES6 with let
-          ;(function (crt_copy, copy_params, copy_url, copy_pod, copy_signature) {
-            symetricEncrypt(JSON.stringify(all_data.data), function (err, dataEncrypted) {
-              if (err) throw err
-
-              var passwordEncrypted = crt_copy.encrypt(dataEncrypted.password, 'utf8', 'hex')
-              copy_params.json = {
-                data: dataEncrypted.crypted,
-                key: passwordEncrypted
-              }
-
-              makeRetryRequest(copy_params, copy_url, copy_pod, copy_signature, callbackEachRetryRequest)
-            })
-          })(crt, params, url, pod, signature)
-        } else {
-          params.json = { data: all_data.data }
-          makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest)
-        }
-      } else {
-        makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest)
-      }
-    }, callback)
-  }
-
-  function certsExist (callback) {
-    fs.exists(certDir + 'peertube.key.pem', function (exists) {
-      return callback(exists)
-    })
-  }
-
-  function createCerts (callback) {
-    certsExist(function (exist) {
-      if (exist === true) {
-        var string = 'Certs already exist.'
-        logger.warning(string)
-        return callback(new Error(string))
-      }
-
-      logger.info('Generating a RSA key...')
-      openssl.exec('genrsa', { 'out': certDir + 'peertube.key.pem', '2048': false }, function (err) {
-        if (err) {
-          logger.error('Cannot create private key on this pod.', { error: err })
-          return callback(err)
-        }
-        logger.info('RSA key generated.')
-
-        logger.info('Manage public key...')
-        openssl.exec('rsa', { 'in': certDir + 'peertube.key.pem', 'pubout': true, 'out': certDir + 'peertube.pub' }, function (err) {
-          if (err) {
-            logger.error('Cannot create public key on this pod .', { error: err })
-            return callback(err)
-          }
-
-          logger.info('Public key managed.')
-          return callback(null)
-        })
-      })
-    })
-  }
-
-  function createCertsIfNotExist (callback) {
-    certsExist(function (exist) {
-      if (exist === true) {
-        return callback(null)
-      }
-
-      createCerts(function (err) {
-        return callback(err)
-      })
-    })
-  }
-
-  function generatePassword (callback) {
-    crypto.randomBytes(32, function (err, buf) {
-      if (err) {
-        return callback(err)
-      }
-
-      callback(null, buf.toString('utf8'))
-    })
-  }
-
-  function symetricEncrypt (text, callback) {
-    generatePassword(function (err, password) {
-      if (err) {
-        return callback(err)
-      }
-
-      var cipher = crypto.createCipher(algorithm, password)
-      var crypted = cipher.update(text, 'utf8', 'hex')
-      crypted += cipher.final('hex')
-      callback(null, { crypted: crypted, password: password })
-    })
-  }
-
-  function symetricDecrypt (text, password) {
-    var decipher = crypto.createDecipher(algorithm, password)
-    var dec = decipher.update(text, 'hex', 'utf8')
-    dec += decipher.final('utf8')
-    return dec
+    cleanForExit: cleanForExit
   }
 
   function cleanForExit (webtorrent_process) {
   // ---------------------------------------------------------------------------
 
   module.exports = utils
-
-  // ---------------------------------------------------------------------------
-
-  function makeRetryRequest (params, from_url, to_pod, signature, callbackEach) {
-    // Append the signature
-    if (signature) {
-      params.json.signature = {
-        url: from_url,
-        signature: signature
-      }
-    }
-
-    logger.debug('Make retry requests to %s.', to_pod.url)
-
-    replay(
-      request.post(params, function (err, response, body) {
-        callbackEach(err, response, body, params.url, to_pod)
-      }),
-      {
-        retries: constants.REQUEST_RETRIES,
-        factor: 3,
-        maxTimeout: Infinity,
-        errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
-      }
-    ).on('replay', function (replay) {
-      logger.info('Replaying request to %s. Request failed: %d %s. Replay number: #%d. Will retry in: %d ms.',
-        params.url, replay.error.code, replay.error.message, replay.number, replay.delay)
-    })
-  }
 })()
index e093c85c497b4580eb000939586e3dc1d77a0130..b0086a38b78e1fb2b1cc6e53139d0050afff7d05 100644 (file)
@@ -8,10 +8,11 @@
 
   var constants = require('../initializers/constants')
   var logger = require('../helpers/logger')
+  var peertubeCrypto = require('../helpers/peertubeCrypto')
   var Pods = require('../models/pods')
   var PoolRequests = require('../models/poolRequests')
   var poolRequests = require('../lib/poolRequests')
-  var utils = require('../helpers/utils')
+  var requests = require('../helpers/requests')
   var Videos = require('../models/videos')
 
   var http = config.get('webserver.https') ? 'https' : 'http'
@@ -48,7 +49,7 @@
     var pods_score = {}
 
     logger.info('Make friends!')
-    fs.readFile(utils.getCertDir() + 'peertube.pub', 'utf8', function (err, cert) {
+    fs.readFile(peertubeCrypto.getCertDir() + 'peertube.pub', 'utf8', function (err, cert) {
       if (err) {
         logger.error('Cannot read public cert.', { error: err })
         return callback(err)
           videos: videos_list
         }
 
-        utils.makeMultipleRetryRequest(
+        requests.makeMultipleRetryRequest(
           { method: 'POST', path: '/api/' + constants.API_VERSION + '/pods/', data: data },
 
           pods_list,
       }
 
       // Announce we quit them
-      utils.makeMultipleRetryRequest(request, pods, function () {
+      requests.makeMultipleRetryRequest(request, pods, function () {
         Pods.removeAll(function (err) {
           poolRequests.activate()
 
index 796f061491d746d49cb73511095aab749358ac42..f4ab434adcc86232c285e6a7d4421e06146e52d8 100644 (file)
@@ -8,7 +8,7 @@
   var logger = require('../helpers/logger')
   var Pods = require('../models/pods')
   var PoolRequests = require('../models/poolRequests')
-  var utils = require('../helpers/utils')
+  var requests = require('../helpers/requests')
   var Videos = require('../models/videos')
 
   var timer = null
@@ -40,7 +40,7 @@
 
   // ---------------------------------------------------------------------------
 
-  function makePoolRequest (type, requests, callback) {
+  function makePoolRequest (type, requests_to_make, callback) {
     if (!callback) callback = function () {}
 
     Pods.list(function (err, pods) {
@@ -51,7 +51,7 @@
         sign: true,
         method: 'POST',
         path: null,
-        data: requests
+        data: requests_to_make
       }
 
       if (type === 'add') {
@@ -65,7 +65,7 @@
       var bad_pods = []
       var good_pods = []
 
-      utils.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished)
+      requests.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished)
 
       function callbackEachPodFinished (err, response, body, url, pod, callback_each_pod_finished) {
         if (err || (response.statusCode !== 200 && response.statusCode !== 204)) {
@@ -95,7 +95,7 @@
 
       if (pool_requests.length === 0) return
 
-      var requests = {
+      var requests_to_make = {
         add: {
           ids: [],
           requests: []
 
       async.each(pool_requests, function (pool_request, callback_each) {
         if (pool_request.type === 'add') {
-          requests.add.requests.push(pool_request.request)
-          requests.add.ids.push(pool_request._id)
+          requests_to_make.add.requests.push(pool_request.request)
+          requests_to_make.add.ids.push(pool_request._id)
         } else if (pool_request.type === 'remove') {
-          requests.remove.requests.push(pool_request.request)
-          requests.remove.ids.push(pool_request._id)
+          requests_to_make.remove.requests.push(pool_request.request)
+          requests_to_make.remove.ids.push(pool_request._id)
         } else {
           throw new Error('Unkown pool request type.')
         }
         callback_each()
       }, function () {
         // Send the add requests
-        if (requests.add.requests.length !== 0) {
-          makePoolRequest('add', requests.add.requests, function (err) {
+        if (requests_to_make.add.requests.length !== 0) {
+          makePoolRequest('add', requests_to_make.add.requests, function (err) {
             if (err) logger.error('Errors when sent add pool requests.', { error: err })
 
-            PoolRequests.removeRequests(requests.add.ids)
+            PoolRequests.removeRequests(requests_to_make.add.ids)
           })
         }
 
         // Send the remove requests
-        if (requests.remove.requests.length !== 0) {
-          makePoolRequest('remove', requests.remove.requests, function (err) {
+        if (requests_to_make.remove.requests.length !== 0) {
+          makePoolRequest('remove', requests_to_make.remove.requests, function (err) {
             if (err) logger.error('Errors when sent remove pool requests.', { error: err })
 
-            PoolRequests.removeRequests(requests.remove.ids)
+            PoolRequests.removeRequests(requests_to_make.remove.ids)
           })
         }
       })
index 99ac9cdaeeed43e092ef85e422f240de8537e942..b7a18ad3e7500bdf761fe4fa27b049291beb683e 100644 (file)
@@ -1,12 +1,9 @@
 ;(function () {
   'use strict'
 
-  var fs = require('fs')
-  var ursa = require('ursa')
-
   var logger = require('../helpers/logger')
+  var peertubeCrypto = require('../helpers/peertubeCrypto')
   var Pods = require('../models/pods')
-  var utils = require('../helpers/utils')
 
   var secureMiddleware = {
     decryptBody: decryptBody
 
       logger.debug('Decrypting body from %s.', url)
 
-      var crt = ursa.createPublicKey(pod.publicKey)
-      var signature_ok = crt.hashAndVerify('sha256', new Buffer(req.body.signature.url).toString('hex'), req.body.signature.signature, 'hex')
+      var signature_ok = peertubeCrypto.checkSignature(pod.publicKey, url, req.body.signature.signature)
 
       if (signature_ok === true) {
-        var myKey = ursa.createPrivateKey(fs.readFileSync(utils.getCertDir() + 'peertube.key.pem'))
-        var decryptedKey = myKey.decrypt(req.body.key, 'hex', 'utf8')
-        req.body.data = JSON.parse(utils.symetricDecrypt(req.body.data, decryptedKey))
-        delete req.body.key
+        peertubeCrypto.decrypt(req.body.key, req.body.data, function (err, decrypted) {
+          if (err) {
+            logger.error('Cannot decrypt data.', { error: err })
+            return res.sendStatus(500)
+          }
+
+          req.body.data = JSON.parse(decrypted)
+          delete req.body.key
+
+          next()
+        })
       } else {
         logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url)
         return res.sendStatus(403)
       }
-
-      next()
     })
   }
 
index 1153c9ef6ba2c6792ab2a6402772cf2aa80688c6..b8674b0b52c80b6e30a7cac8722818ee2ca131c1 100644 (file)
--- a/server.js
+++ b/server.js
@@ -32,6 +32,7 @@
   var customValidators = require('./helpers/customValidators')
   var database = require('./initializers/database')
   var logger = require('./helpers/logger')
+  var peertubeCrypto = require('./helpers/peertubeCrypto')
   var poolRequests = require('./lib/poolRequests')
   var routes = require('./controllers')
   var utils = require('./helpers/utils')
   // Prod : no stacktraces leaked to user
   if (process.env.NODE_ENV === 'production') {
     app.use(function (err, req, res, next) {
-      logger.error('Error : ' + err.message, { error: err })
+      logger.error(err)
       res.status(err.status || 500)
       res.render('error', {
         message: err.message,
     })
   } else {
     app.use(function (err, req, res, next) {
-      logger.error('Error : ' + err.message, { error: err })
+      logger.error(err)
       res.status(err.status || 500)
       res.render('error', {
         message: err.message,
   }
 
   // ----------- Create the certificates if they don't already exist -----------
-  utils.createCertsIfNotExist(function (err) {
+  peertubeCrypto.createCertsIfNotExist(function (err) {
     if (err) throw err
     // Create/activate the webtorrent module
     webtorrent.create(function () {