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