mirror of
				https://git.coolaj86.com/coolaj86/telebit.js.git
				synced 2025-11-04 02:32:47 +00:00 
			
		
		
		
	WIP: switch to authenticated requests
This commit is contained in:
		
							parent
							
								
									8b2e6e69d0
								
							
						
					
					
						commit
						1826ec8497
					
				@ -685,6 +685,7 @@ function parseConfig(err, text) {
 | 
				
			|||||||
      , protected: {
 | 
					      , protected: {
 | 
				
			||||||
          // alg will be filled out automatically
 | 
					          // alg will be filled out automatically
 | 
				
			||||||
          jwk: state.pub
 | 
					          jwk: state.pub
 | 
				
			||||||
 | 
					        , kid: false
 | 
				
			||||||
        , nonce: nonce
 | 
					        , nonce: nonce
 | 
				
			||||||
        , url: newAccountUrl
 | 
					        , url: newAccountUrl
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -590,9 +590,14 @@ function jwtEggspress(req, res, next) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // TODO verify if possible
 | 
					  // TODO verify if possible
 | 
				
			||||||
  console.warn("[warn] JWT is not verified yet");
 | 
					  console.warn("[warn] JWT is not verified yet");
 | 
				
			||||||
 | 
					  // A failed JWS should cause a failed JWT
 | 
				
			||||||
 | 
					  if (false !== req.trusted) {
 | 
				
			||||||
 | 
					    req.trusted = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  next();
 | 
					  next();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO switch to Keypairs.js / Keyfetch.js
 | 
				
			||||||
function verifyJws(jwk, jws) {
 | 
					function verifyJws(jwk, jws) {
 | 
				
			||||||
  return keypairs.export({ jwk: jwk }).then(function (pem) {
 | 
					  return keypairs.export({ jwk: jwk }).then(function (pem) {
 | 
				
			||||||
    var alg = 'SHA' + jws.header.alg.replace(/[^\d]+/i, '');
 | 
					    var alg = 'SHA' + jws.header.alg.replace(/[^\d]+/i, '');
 | 
				
			||||||
@ -632,9 +637,8 @@ function jwsEggspress(req, res, next) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  if (req.jws.header.jwk) {
 | 
					  if (req.jws.header.jwk) {
 | 
				
			||||||
    if (kid) {
 | 
					    if (kid) {
 | 
				
			||||||
      // TODO kid and jwk are mutually exclusive
 | 
					      res.send({ error: { message: "jws protected header must not include both 'kid' and 'jwk'" } });
 | 
				
			||||||
      //res.send({ error: { message: "jws protected header must not include both 'kid' and 'jwk'" } });
 | 
					      return;
 | 
				
			||||||
      //return;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    kid = req.jws.header.jwk.kid;
 | 
					    kid = req.jws.header.jwk.kid;
 | 
				
			||||||
    p = Keypairs.thumbprint({ jwk: req.jws.header.jwk }).then(function (thumb) {
 | 
					    p = Keypairs.thumbprint({ jwk: req.jws.header.jwk }).then(function (thumb) {
 | 
				
			||||||
@ -699,6 +703,10 @@ function jwsEggspress(req, res, next) {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }).then(function () {
 | 
					  }).then(function () {
 | 
				
			||||||
 | 
					    // a failed JWT should cause a failed JWS
 | 
				
			||||||
 | 
					    if (false !== req.trusted) {
 | 
				
			||||||
 | 
					      req.trusted = req.jws.trusted;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    next();
 | 
					    next();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1038,10 +1046,19 @@ function handleApi() {
 | 
				
			|||||||
  app.head('/acme/new-nonce', controllers.newNonce);
 | 
					  app.head('/acme/new-nonce', controllers.newNonce);
 | 
				
			||||||
  app.get('/acme/new-nonce', controllers.newNonce);
 | 
					  app.get('/acme/new-nonce', controllers.newNonce);
 | 
				
			||||||
  app.post('/acme/new-acct', controllers.newAccount);
 | 
					  app.post('/acme/new-acct', controllers.newAccount);
 | 
				
			||||||
  app.use(/\b(relay)\b/, controllers.relay);
 | 
					  function mustTrust(req, res, next) {
 | 
				
			||||||
  app.get(/\b(config)\b/, getConfigOnly);
 | 
					    // TODO public routes should be explicitly marked
 | 
				
			||||||
  app.use(/\b(init|config)\b/, initOrConfig);
 | 
					    // trusted should be the default
 | 
				
			||||||
  app.use(/\b(restart)\b/, restart);
 | 
					    if (req.trusted) { next(); }
 | 
				
			||||||
 | 
					    res.statusCode = 400;
 | 
				
			||||||
 | 
					    res.send({"error":{"message": "this type of requests must be encoded as a jws payload"
 | 
				
			||||||
 | 
					      + " and signed by a trusted account holder"}});
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  app.use(/\b(relay)\b/, mustTrust, controllers.relay);
 | 
				
			||||||
 | 
					  app.get(/\b(config)\b/, mustTrust, getConfigOnly);
 | 
				
			||||||
 | 
					  app.use(/\b(init|config)\b/, mustTrust, initOrConfig);
 | 
				
			||||||
 | 
					  app.use(/\b(restart)\b/, mustTrust, restart);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Position is important with eggspress
 | 
					  // Position is important with eggspress
 | 
				
			||||||
  // This should stay here, right before the other methods
 | 
					  // This should stay here, right before the other methods
 | 
				
			||||||
@ -1050,14 +1067,14 @@ function handleApi() {
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // With proper config
 | 
					  // With proper config
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
  app.use(/\b(http)\b/, controllers.http);
 | 
					  app.use(/\b(http)\b/, mustTrust, controllers.http);
 | 
				
			||||||
  app.use(/\b(tcp)\b/, controllers.tcp);
 | 
					  app.use(/\b(tcp)\b/, mustTrust, controllers.tcp);
 | 
				
			||||||
  app.use(/\b(save|commit)\b/, saveAndCommit);
 | 
					  app.use(/\b(save|commit)\b/, mustTrust, saveAndCommit);
 | 
				
			||||||
  app.use(/\b(ssh)\b/, controllers.ssh);
 | 
					  app.use(/\b(ssh)\b/, mustTrust, controllers.ssh);
 | 
				
			||||||
  app.use(/\b(enable)\b/, enable);
 | 
					  app.use(/\b(enable)\b/, mustTrust, enable);
 | 
				
			||||||
  app.use(/\b(disable)\b/, disable);
 | 
					  app.use(/\b(disable)\b/, mustTrust, disable);
 | 
				
			||||||
  app.use(/\b(status)\b/, getStatus);
 | 
					  app.use(/\b(status)\b/, mustTrust, getStatus);
 | 
				
			||||||
  app.use(/\b(list)\b/, listSuccess);
 | 
					  app.use(/\b(list)\b/, mustTrust, listSuccess);
 | 
				
			||||||
  app.use('/', function (req, res) {
 | 
					  app.use('/', function (req, res) {
 | 
				
			||||||
    res.send({"error":{"message":"unrecognized rpc"}});
 | 
					    res.send({"error":{"message":"unrecognized rpc"}});
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
				
			|||||||
@ -160,6 +160,7 @@ module.exports.create = function (state) {
 | 
				
			|||||||
    , protected: {
 | 
					    , protected: {
 | 
				
			||||||
        // alg will be filled out automatically
 | 
					        // alg will be filled out automatically
 | 
				
			||||||
        jwk: state.pub
 | 
					        jwk: state.pub
 | 
				
			||||||
 | 
					      , kid: false
 | 
				
			||||||
      , nonce: require('crypto').randomBytes(16).toString('hex') // TODO get from server
 | 
					      , nonce: require('crypto').randomBytes(16).toString('hex') // TODO get from server
 | 
				
			||||||
        // TODO make localhost exceptional
 | 
					        // TODO make localhost exceptional
 | 
				
			||||||
      , url: RC.resolve(reqOpts.path)
 | 
					      , url: RC.resolve(reqOpts.path)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user