mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	close #9 write rewenal config files
This commit is contained in:
		
							parent
							
								
									873e8ea89f
								
							
						
					
					
						commit
						77f54981c5
					
				| @ -14,7 +14,7 @@ function createAccount(args, handlers) { | ||||
|   // TODO support ECDSA
 | ||||
|   // arg.rsaBitLength args.rsaExponent
 | ||||
|   return leCrypto.generateRsaKeypairAsync(args.rsaBitLength, args.rsaExponent).then(function (pems) { | ||||
|     /* pems = { privateKeyPem, privateKeyJwk, publicKeyPem, publicKeyMd5 } */ | ||||
|     /* pems = { privateKeyPem, privateKeyJwk, publicKeyPem, publicKeyMd5, publicKeySha256 } */ | ||||
| 
 | ||||
|     return LeCore.registerNewAccountAsync({ | ||||
|       email: args.email | ||||
| @ -28,7 +28,13 @@ function createAccount(args, handlers) { | ||||
| 
 | ||||
|     , debug: args.debug || handlers.debug | ||||
|     }).then(function (body) { | ||||
|       var accountDir = path.join(args.accountsDir, pems.publicKeyMd5); | ||||
|       // TODO XXX use sha256
 | ||||
|       var accountId = pems.publicKeyMd5; | ||||
|       var accountDir = path.join(args.accountsDir, accountId); | ||||
|       var regr = { body: body }; | ||||
| 
 | ||||
|       args.accountId = accountId; | ||||
|       args.accountDir = accountDir; | ||||
| 
 | ||||
|       return mkdirpAsync(accountDir).then(function () { | ||||
| 
 | ||||
| @ -52,8 +58,12 @@ function createAccount(args, handlers) { | ||||
|             new_authzr_uri: 'https://acme-v01.api.letsencrypt.org/acme/new-authz', | ||||
|             terms_of_service: 'https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf' } | ||||
|            */ | ||||
|         , fs.writeFileAsync(path.join(accountDir, 'regr.json'), JSON.stringify({ body: body }), 'utf8') | ||||
|         , fs.writeFileAsync(path.join(accountDir, 'regr.json'), JSON.stringify(regr), 'utf8') | ||||
|         ]).then(function () { | ||||
|           pems.meta = accountMeta; | ||||
|           pems.privateKey = pems.privateKeyJwk; | ||||
|           pems.regr = regr; | ||||
|           pems.accountId = accountId; | ||||
|           return pems; | ||||
|         }); | ||||
|       }); | ||||
| @ -94,11 +104,13 @@ function getAccount(accountId, args, handlers) { | ||||
|     } | ||||
| 
 | ||||
|     return leCrypto.parseAccountPrivateKeyAsync(files.private_key).then(function (keypair) { | ||||
|       files.accountId = accountId;                  // md5sum(publicKeyPem)
 | ||||
|       files.publicKeyMd5 = accountId;               // md5sum(publicKeyPem)
 | ||||
|       files.accountId = accountId;                  // preserve current account id
 | ||||
|       files.publicKeySha256 = keypair.publicKeySha256; | ||||
|       files.publicKeyMd5 = keypair.publicKeyMd5; | ||||
|       files.publicKeyPem = keypair.publicKeyPem;    // ascii PEM: ----BEGIN...
 | ||||
|       files.privateKeyPem = keypair.privateKeyPem;  // ascii PEM: ----BEGIN...
 | ||||
|       files.privateKeyJson = keypair.private_key;   // json { n: ..., e: ..., iq: ..., etc }
 | ||||
|       files.privateKeyJwk = keypair.private_key;    // json { n: ..., e: ..., iq: ..., etc }
 | ||||
| 
 | ||||
|       return files; | ||||
|     }); | ||||
|  | ||||
							
								
								
									
										188
									
								
								lib/core.js
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								lib/core.js
									
									
									
									
									
								
							| @ -34,13 +34,13 @@ function getAcmeUrls(args) { | ||||
| 
 | ||||
| 
 | ||||
| function getCertificateAsync(account, args, defaults, handlers) { | ||||
|   return leCrypto.generateRsaKeypairAsync(args.rsaBitLength, args.rsaExponent).then(function (domain) { | ||||
|   return leCrypto.generateRsaKeypairAsync(args.rsaKeySize, args.rsaExponent).then(function (domainKey) { | ||||
|     return LeCore.getCertificateAsync({ | ||||
|       newAuthzUrl: args._acmeUrls.newAuthz | ||||
|     , newCertUrl: args._acmeUrls.newCert | ||||
| 
 | ||||
|     , accountPrivateKeyPem: account.privateKeyPem | ||||
|     , domainPrivateKeyPem: domain.privateKeyPem | ||||
|     , domainPrivateKeyPem: domainKey.privateKeyPem | ||||
|     , domains: args.domains | ||||
| 
 | ||||
|       //
 | ||||
| @ -82,31 +82,97 @@ function getCertificateAsync(account, args, defaults, handlers) { | ||||
|         } | ||||
|       } | ||||
|     }).then(function (result) { | ||||
|       var liveDir = path.join(args.configDir, 'live', args.domains[0]); | ||||
|       var certPath = path.join(liveDir, 'cert.pem'); | ||||
|       var fullchainPath = path.join(liveDir, 'fullchain.pem'); | ||||
|       var chainPath = path.join(liveDir, 'chain.pem'); | ||||
|       var privkeyPath = path.join(liveDir, 'privkey.pem'); | ||||
| 
 | ||||
|       result.fullchain = result.cert + '\n' + result.ca; | ||||
| 
 | ||||
|       // TODO write to archive first, then write to live
 | ||||
|       var pyconf = PromiseA.promisifyAll(require('pyconf')); | ||||
| 
 | ||||
|       // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 | ||||
|       // TODO read renewal.conf.default, write renewal.conf
 | ||||
|       // var pyconf = PromiseA.promisifyAll(require('pyconf'));
 | ||||
|       // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 | ||||
|       return pyconf.readFileAsync(args.renewalPath, function (obj) { | ||||
|         return obj; | ||||
|       }, function () { | ||||
|         return pyconf.readFileAsync(path.join(__dirname, 'lib', 'renewal.conf.tpl')).then(function (obj) { | ||||
|           return obj; | ||||
|         }); | ||||
|       }).then(function (obj) { | ||||
|         obj.checkpoint = parseInt(obj.checkpoint, 10) || 0; | ||||
| 
 | ||||
|         var liveDir = args.liveDir || path.join(args.configDir, 'live', args.domains[0]); | ||||
| 
 | ||||
|         var certPath = args.certPath || obj.cert || path.join(liveDir, 'cert.pem'); | ||||
|         var fullchainPath = args.fullchainPath || obj.fullchain || path.join(liveDir, 'fullchain.pem'); | ||||
|         var chainPath = args.chainPath || obj.chain || path.join(liveDir, 'chain.pem'); | ||||
|         var privkeyPath = args.domainPrivateKeyPath || args.domainKeyPath | ||||
|           || obj.privkey || obj.keyPath | ||||
|           || path.join(liveDir, 'privkey.pem'); | ||||
| 
 | ||||
|         var archiveDir = args.archiveDir || path.join(args.configDir, 'live', args.domains[0]); | ||||
| 
 | ||||
|         var checkpoint = obj.checkpoint.toString(); | ||||
|         var certArchive = path.join(archiveDir, 'cert' + checkpoint + '.pem'); | ||||
|         var fullchainArchive = path.join(archiveDir, 'fullchain' + checkpoint + '.pem'); | ||||
|         var chainArchive = path.join(archiveDir, 'chain'+ checkpoint + '.pem'); | ||||
|         var privkeyArchive = path.join(archiveDir, 'privkey' + checkpoint + '.pem'); | ||||
| 
 | ||||
|         return mkdirpAsync(archiveDir).then(function () { | ||||
|           return PromiseA.all([ | ||||
|             sfs.writeFileAsync(certArchive, result.cert, 'ascii') | ||||
|           , sfs.writeFileAsync(chainArchive, result.ca || result.chain, 'ascii') | ||||
|           , sfs.writeFileAsync(fullchainArchive, result.fullchain, 'ascii') | ||||
|           , sfs.writeFileAsync(privkeyArchive, result.key || result.privkey, 'ascii') | ||||
|           ]); | ||||
|         }).then(function () { | ||||
|           return mkdirpAsync(liveDir); | ||||
|         }).then(function () { | ||||
|           return PromiseA.all([ | ||||
|             sfs.writeFileAsync(certPath, result.cert, 'ascii') | ||||
|           , sfs.writeFileAsync(chainPath, result.ca || result.chain, 'ascii') | ||||
|           , sfs.writeFileAsync(fullchainPath, result.fullchain, 'ascii') | ||||
|           , sfs.writeFileAsync(privkeyPath, result.key || result.privkey, 'ascii') | ||||
|           ]); | ||||
|         }).then(function () { | ||||
|           obj.checkpoint += 1; | ||||
| 
 | ||||
|           var updates = { | ||||
|             cert: certPath | ||||
|           , privkey: privkeyPath | ||||
|           , chain: chainPath | ||||
|           , fullchain: fullchainPath | ||||
|           , configDir: args.configDir | ||||
|           , workDir: args.workDir | ||||
|           , tos: args.agreeTos && true | ||||
|           , http01Port: args.http01Port | ||||
|           , keyPath: args.domainPrivateKeyPath || args.privkeyPath | ||||
|           , email: args.email | ||||
|           , domains: args.domains | ||||
|           , rsaKeySize: args.rsaKeySize | ||||
|           , checkpoints: obj.checkpoint | ||||
|             // TODO XXX what's the deal with these? they don't make sense
 | ||||
|             // are they just old junk? or do they have a meaning that I don't know about?
 | ||||
|           , fullchainPath: path.join(args.configDir, 'chain.pem') | ||||
|           , certPath: path.join(args.configDir, 'cert.pem') | ||||
|           , chainPath: path.join(args.configDir, 'chain.pem') | ||||
|             // TODO XXX end
 | ||||
|             // yes, it's an array. weird, right?
 | ||||
|           , webrootPath: args.webrootPath && [args.webrootPath] || [] | ||||
|           , account: account.accountId | ||||
|           , server: args.server || args.acmeDiscoveryUrl | ||||
|           , logsDir: args.logsDir | ||||
|           }; | ||||
| 
 | ||||
|           // final section is completely dynamic
 | ||||
|           // :hostname = :webroot_path
 | ||||
|           args.domains.forEach(function (hostname) { | ||||
|             updates[hostname] = args.webrootPath; | ||||
|           }); | ||||
| 
 | ||||
|           // must write back to the original object or
 | ||||
|           // annotations will be lost
 | ||||
|           Object.keys(updates).forEach(function (key) { | ||||
|             obj[key] = updates[key]; | ||||
|           }); | ||||
| 
 | ||||
|           return pyconf.writeFile(args.renewalPath, obj); | ||||
|         }).then(function () { | ||||
| 
 | ||||
|       return mkdirpAsync(liveDir).then(function () { | ||||
|         return PromiseA.all([ | ||||
|           sfs.writeFileAsync(certPath, result.cert, 'ascii') | ||||
|         , sfs.writeFileAsync(chainPath, result.ca || result.chain, 'ascii') | ||||
|         , sfs.writeFileAsync(fullchainPath, result.fullchain, 'ascii') | ||||
|         , sfs.writeFileAsync(privkeyPath, result.key || result.privkey, 'ascii') | ||||
|         ]).then(function () { | ||||
|         // TODO format result licesy
 | ||||
|           //console.log(liveDir);
 | ||||
|           //console.log(result);
 | ||||
|           return { | ||||
|             certPath: certPath | ||||
|           , chainPath: chainPath | ||||
| @ -135,8 +201,7 @@ function registerWithAcme(args, defaults, handlers) { | ||||
|   var acmeHostname = require('url').parse(server).hostname; | ||||
|   var configDir = args.configDir; | ||||
| 
 | ||||
|   args.server = server; | ||||
|   args.renewalDir = args.renewalDir || path.join(configDir, 'renewal', args.domains[0] + '.conf'); | ||||
|   args.renewalPath = args.renewalPath || path.join(configDir, 'renewal', args.domains[0] + '.conf'); | ||||
|   args.accountsDir = args.accountsDir || path.join(configDir, 'accounts', acmeHostname, 'directory'); | ||||
| 
 | ||||
|   return pyconf.readFileAsync(args.renewalDir).then(function (renewal) { | ||||
| @ -195,71 +260,6 @@ function registerWithAcme(args, defaults, handlers) { | ||||
|         return certs; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     /* | ||||
|     cert = /home/aj/node-letsencrypt/tests/letsencrypt.config/live/lds.io/cert.pem | ||||
|     privkey = /home/aj/node-letsencrypt/tests/letsencrypt.config/live/lds.io/privkey.pem | ||||
|     chain = /home/aj/node-letsencrypt/tests/letsencrypt.config/live/lds.io/chain.pem | ||||
|     fullchain = /home/aj/node-letsencrypt/tests/letsencrypt.config/live/lds.io/fullchain.pem | ||||
| 
 | ||||
|     # Options and defaults used in the renewal process | ||||
|     [renewalparams] | ||||
|     apache_enmod = a2enmod | ||||
|     no_verify_ssl = False | ||||
|     ifaces = None | ||||
|     apache_dismod = a2dismod | ||||
|     register_unsafely_without_email = False | ||||
|     uir = None | ||||
|     installer = none | ||||
|     config_dir = /home/aj/node-letsencrypt/tests/letsencrypt.config | ||||
|     text_mode = True | ||||
|     func = <function obtain_cert at 0x7f46af0f02a8> | ||||
|     prepare = False | ||||
|     work_dir = /home/aj/node-letsencrypt/tests/letsencrypt.work | ||||
|     tos = True | ||||
|     init = False | ||||
|     http01_port = 80 | ||||
|     duplicate = False | ||||
|     key_path = None | ||||
|     nginx = False | ||||
|     fullchain_path = /home/aj/node-letsencrypt/chain.pem | ||||
|     email = coolaj86@gmail.com | ||||
|     csr = None | ||||
|     agree_dev_preview = None | ||||
|     redirect = None | ||||
|     verbose_count = -3 | ||||
|     config_file = None | ||||
|     renew_by_default = True | ||||
|     hsts = False | ||||
|     authenticator = webroot | ||||
|     domains = lds.io, | ||||
|     rsa_key_size = 2048 | ||||
|     checkpoints = 1 | ||||
|     manual_test_mode = False | ||||
|     apache = False | ||||
|     cert_path = /home/aj/node-letsencrypt/cert.pem | ||||
|     webroot_path = /home/aj/node-letsencrypt/examples/../tests/acme-challenge, | ||||
|     strict_permissions = False | ||||
|     apache_server_root = /etc/apache2 | ||||
|     account = 1c41c64dfaf10d511db8aef0cc33b27f | ||||
|     manual_public_ip_logging_ok = False | ||||
|     chain_path = /home/aj/node-letsencrypt/chain.pem | ||||
|     standalone = False | ||||
|     manual = False | ||||
|     server = https://acme-staging.api.letsencrypt.org/directory
 | ||||
|     standalone_supported_challenges = "http-01,tls-sni-01" | ||||
|     webroot = True | ||||
|     apache_init_script = None | ||||
|     user_agent = None | ||||
|     apache_ctl = apache2ctl | ||||
|     apache_le_vhost_ext = -le-ssl.conf | ||||
|     debug = False | ||||
|     tls_sni_01_port = 443 | ||||
|     logs_dir = /home/aj/node-letsencrypt/tests/letsencrypt.logs | ||||
|     configurator = None | ||||
|     [[webroot_map]] | ||||
|     lds.io = /home/aj/node-letsencrypt/examples/../tests/acme-challenge | ||||
|     */ | ||||
|   }); | ||||
| /* | ||||
|   return fs.readdirAsync(accountsDir, function (nodes) { | ||||
| @ -277,7 +277,13 @@ module.exports.create = function (defaults, handlers) { | ||||
| 
 | ||||
|   var wrapped = { | ||||
|     registerAsync: function (args) { | ||||
|       var copy = merge(args, defaults); | ||||
|       var copy; | ||||
|       // TODO move these defaults elsewhere?
 | ||||
|       args.renewalPath = args.renewalPath || ':config/renewal/:hostname.conf'; | ||||
|       // Note: the /directory is part of the server url and, as such, bleeds into the pathname
 | ||||
|       // So :config/accounts/:server/directory is *incorrect*, but the following *is* correct:
 | ||||
|       args.accountsDir = args.accountsDir || ':config/accounts/:server'; | ||||
|       copy = merge(args, defaults); | ||||
|       tplHostname(args.domains[0], copy); | ||||
| 
 | ||||
|       if (args.debug) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user