mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Added certificate expiration warning.
This commit is contained in:
		
							parent
							
								
									9c2db4887c
								
							
						
					
					
						commit
						5d11173f10
					
				
					 6 changed files with 36 additions and 5 deletions
				
			
		|  | @ -1443,9 +1443,6 @@ function CreateMeshCentralServer(config, args) { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Update proxy certificates
 | ||||
|         if (obj.supportsProxyCertificatesRequest == true) { obj.updateProxyCertificates(true); } | ||||
| 
 | ||||
|         // Load CloudFlare trusted proxies list if needed
 | ||||
|         if ((obj.config.settings.trustedproxy != null) && (typeof obj.config.settings.trustedproxy == 'string') && (obj.config.settings.trustedproxy.toLowerCase() == 'cloudflare')) { | ||||
|             obj.config.settings.extrascriptsrc = 'ajax.cloudflare.com'; // Add CloudFlare as a trusted script source. This allows for CloudFlare's RocketLoader feature.
 | ||||
|  | @ -1536,6 +1533,9 @@ function CreateMeshCentralServer(config, args) { | |||
|                 obj.webserver = require('./webserver.js').CreateWebServer(obj, obj.db, obj.args, obj.certificates); | ||||
|                 if (obj.redirserver != null) { obj.redirserver.hookMainWebServer(obj.certificates); } | ||||
| 
 | ||||
|                 // Update proxy certificates
 | ||||
|                 if (obj.supportsProxyCertificatesRequest == true) { obj.updateProxyCertificates(true); } | ||||
| 
 | ||||
|                 // Setup the Intel AMT event handler
 | ||||
|                 obj.amtEventHandler = require('./amtevents.js').CreateAmtEventsHandler(obj); | ||||
| 
 | ||||
|  | @ -1789,8 +1789,10 @@ function CreateMeshCentralServer(config, args) { | |||
|                                 // Decode a RSA certificate and hash the public key, if this is not RSA, skip this.
 | ||||
|                                 var forgeCert = obj.certificateOperations.forge.pki.certificateFromAsn1(obj.certificateOperations.forge.asn1.fromDer(cert)); | ||||
|                                 xdomain.certkeyhash = obj.certificateOperations.forge.pki.getPublicKeyFingerprint(forgeCert.publicKey, { md: obj.certificateOperations.forge.md.sha384.create(), encoding: 'hex' }); | ||||
|                                 obj.webserver.webCertificateExpire[xdomain.id] = Date.parse(forgeCert.validity.notAfter); // Update certificate expire time
 | ||||
|                                 //console.log('V1: ' + xdomain.certkeyhash);
 | ||||
|                             } catch (ex) { | ||||
|                                 delete obj.webserver.webCertificateExpire[xdomain.id]; // Remove certificate expire time
 | ||||
|                                 delete xdomain.certkeyhash; | ||||
|                             } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								meshuser.js
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								meshuser.js
									
										
									
									
									
								
							|  | @ -495,6 +495,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|             if (user.siteadmin === SITERIGHT_ADMIN) { | ||||
|                 if (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) { serverinfo.manageAllDeviceGroups = true; } | ||||
|                 if (obj.crossDomain === true) { serverinfo.crossDomain = []; for (var i in parent.parent.config.domains) { serverinfo.crossDomain.push(i); } } | ||||
|                 if (typeof parent.webCertificateExpire[domain.id] == 'number') { serverinfo.certExpire = parent.webCertificateExpire[domain.id]; } | ||||
|             } | ||||
|             if (typeof domain.terminal == 'object') { // Settings used for remote terminal feature
 | ||||
|                 if ((typeof domain.terminal.linuxshell == 'string') && (domain.terminal.linuxshell != 'any')) { serverinfo.linuxshell = domain.terminal.linuxshell; } | ||||
|  | @ -904,7 +905,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
| 
 | ||||
|                     switch (cmd) { | ||||
|                         case 'help': { | ||||
|                             var fin = '', f = '', availcommands = 'help,maintenance,info,versions,resetserver,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,agentissues,webstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,dbcounters,sms,amtacm,certhashes,watchdog,amtmanager,amtpasswords'; | ||||
|                             var fin = '', f = '', availcommands = 'help,maintenance,info,versions,resetserver,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,agentissues,webstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,dbcounters,sms,amtacm,certhashes,watchdog,amtmanager,amtpasswords,certexpire'; | ||||
|                             if (parent.parent.config.settings.heapdump === true) { availcommands += ',heapdump'; } | ||||
|                             availcommands = availcommands.split(',').sort(); | ||||
|                             while (availcommands.length > 0) { if (f.length > 80) { fin += (f + ',\r\n'); f = ''; } f += (((f != '') ? ', ' : ' ') + availcommands.shift()); } | ||||
|  | @ -925,6 +926,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                             } | ||||
|                             break; | ||||
|                         } | ||||
|                         case 'certexpire': { | ||||
|                             const now = Date.now(); | ||||
|                             for (var i in parent.webCertificateExpire) { | ||||
|                                 const domainName = (i == '') ? '[Default]' : i; | ||||
|                                 r += domainName + ', expires in ' + Math.floor((parent.webCertificateExpire[i] - now) / 86400000) + ' day(s)\r\n'; | ||||
|                             } | ||||
|                             break; | ||||
|                         } | ||||
|                         case 'webpush': { | ||||
|                             if (parent.parent.webpush == null) { | ||||
|                                 r = "Web push not supported."; | ||||
|  |  | |||
|  | @ -1024,7 +1024,7 @@ NoMeshesPanel img { | |||
|     padding-left: 15px; | ||||
| } | ||||
| 
 | ||||
| #p2noMeshFound, #serverStats, #serverWarnings { | ||||
| #p2noMeshFound, #serverStats, #serverWarnings, #serverCertWarnings { | ||||
|     margin-left: 40px; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1398,6 +1398,12 @@ | |||
|                     serverinfo = message.serverinfo; | ||||
|                     if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); } | ||||
|                     if (userinfo != null) updateSelf(); | ||||
|                     if (serverinfo.certExpire != null) { | ||||
|                         var days = Math.floor((serverinfo.certExpire - Date.now()) / 86400000); | ||||
|                         if ((days >= 0) && (days < 20)) { | ||||
|                             addNotification({ text: format("Certificate expires in {0} day(s)", days) }); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 case 'authcookie': { | ||||
|  |  | |||
|  | @ -525,6 +525,7 @@ | |||
|                     </div> | ||||
|                     <div id="serverWarningsDiv" style="display:none"> | ||||
|                         <br /><strong>Server Warnings</strong><br /><br /> | ||||
|                         <div id="serverCertWarnings"></div> | ||||
|                         <div id="serverWarnings"></div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | @ -2138,6 +2139,14 @@ | |||
|                     if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); } | ||||
|                     if (debugmode == 1) { console.log('Server time: ', printDateTime(new Date(serverinfo.serverTime))); } | ||||
|                     setupServiceWorker(); | ||||
|                     if (serverinfo.certExpire != null) { | ||||
|                         var days = Math.floor((serverinfo.certExpire - Date.now()) / 86400000); | ||||
|                         if ((days >= 0) && (days < 20)) { | ||||
|                             QH('serverCertWarnings', '<div style=color:red;padding-bottom:6px><b>' + "WARNING: " + format("Certificate expires in {0} day(s)", days) + '</b></div>'); | ||||
|                             QV('serverWarningsDiv', true); | ||||
|                             addNotification({ text: format("Certificate expires in {0} day(s)", days) }); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 case 'userinfo': { | ||||
|  |  | |||
|  | @ -114,6 +114,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { | |||
|     obj.webCertificateHashBase64 = Buffer.from(obj.webCertificateHash, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); | ||||
|     obj.webCertificateFullHash = parent.certificateOperations.getCertHashBinary(obj.certificates.web.cert); | ||||
|     obj.webCertificateFullHashs = { '': obj.webCertificateFullHash }; | ||||
|     obj.webCertificateExpire = { '': Date.parse(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.web.cert).validity.notAfter) }; | ||||
|     obj.agentCertificateHashHex = parent.certificateOperations.getPublicKeyHash(obj.certificates.agent.cert); | ||||
|     obj.agentCertificateHashBase64 = Buffer.from(obj.agentCertificateHashHex, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); | ||||
|     obj.agentCertificateAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes(); | ||||
|  | @ -126,10 +127,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { | |||
|             // If the web certificate hash is provided, use it.
 | ||||
|             obj.webCertificateHashs[i] = obj.webCertificateFullHashs[i] = Buffer.from(obj.parent.config.domains[i].certhash, 'hex').toString('binary'); | ||||
|             if (obj.parent.config.domains[i].certkeyhash != null) { obj.webCertificateHashs[i] = Buffer.from(obj.parent.config.domains[i].certkeyhash, 'hex').toString('binary'); } | ||||
|             delete obj.webCertificateExpire[i]; // Expire time is not provided
 | ||||
|         } else if ((obj.parent.config.domains[i].dns != null) && (obj.parent.config.domains[i].certs != null)) { | ||||
|             // If the domain has a different DNS name, use a different certificate hash.
 | ||||
|             // Hash the full certificate
 | ||||
|             obj.webCertificateFullHashs[i] = parent.certificateOperations.getCertHashBinary(obj.parent.config.domains[i].certs.cert); | ||||
|             obj.webCertificateExpire[i] = Date.parse(parent.certificateOperations.forge.pki.certificateFromPem(obj.parent.config.domains[i].certs.cert).validity.notAfter); | ||||
|             try { | ||||
|                 // Decode a RSA certificate and hash the public key.
 | ||||
|                 obj.webCertificateHashs[i] = parent.certificateOperations.getPublicKeyHashBinary(obj.parent.config.domains[i].certs.cert); | ||||
|  | @ -141,10 +144,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { | |||
|             // If this domain has a DNS and a matching DNS cert, use it. This case works for wildcard certs.
 | ||||
|             obj.webCertificateFullHashs[i] = parent.certificateOperations.getCertHashBinary(obj.certificates.dns[i].cert); | ||||
|             obj.webCertificateHashs[i] = parent.certificateOperations.getPublicKeyHashBinary(obj.certificates.dns[i].cert); | ||||
|             obj.webCertificateExpire[i] = Date.parse(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.dns[i].cert).validity.notAfter); | ||||
|         } else if (i != '') { | ||||
|             // For any other domain, use the default cert.
 | ||||
|             obj.webCertificateFullHashs[i] = obj.webCertificateFullHashs['']; | ||||
|             obj.webCertificateHashs[i] = obj.webCertificateHashs['']; | ||||
|             obj.webCertificateExpire[i] = obj.webCertificateExpire['']; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue