97 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			97 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | /** | ||
|  |  * Secure SMTP Server Utility Functions | ||
|  |  * Provides helper functions for creating and managing secure TLS server | ||
|  |  */ | ||
|  | 
 | ||
|  | import * as plugins from '../../../plugins.ts'; | ||
|  | import {  | ||
|  |   loadCertificatesFromString,  | ||
|  |   generateSelfSignedCertificates, | ||
|  |   createTlsOptions, | ||
|  |   type ICertificateData | ||
|  | } from './certificate-utils.ts'; | ||
|  | import { SmtpLogger } from './utils/logging.ts'; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Create a secure TLS server for direct TLS connections | ||
|  |  * @param options - TLS certificate options | ||
|  |  * @returns A configured TLS server or undefined if TLS is not available | ||
|  |  */ | ||
|  | export function createSecureTlsServer(options: { | ||
|  |   key: string; | ||
|  |   cert: string; | ||
|  |   ca?: string; | ||
|  | }): plugins.tls.Server | undefined { | ||
|  |   try { | ||
|  |     // Log the creation attempt
 | ||
|  |     SmtpLogger.info('Creating secure TLS server for direct connections'); | ||
|  |      | ||
|  |     // Load certificates from strings
 | ||
|  |     let certificates: ICertificateData; | ||
|  |     try { | ||
|  |       certificates = loadCertificatesFromString({ | ||
|  |         key: options.key, | ||
|  |         cert: options.cert, | ||
|  |         ca: options.ca | ||
|  |       }); | ||
|  |        | ||
|  |       SmtpLogger.info('Successfully loaded TLS certificates for secure server'); | ||
|  |     } catch (certificateError) { | ||
|  |       SmtpLogger.warn(`Failed to load certificates, using self-signed: ${certificateError instanceof Error ? certificateError.message : String(certificateError)}`); | ||
|  |       certificates = generateSelfSignedCertificates(); | ||
|  |     } | ||
|  |      | ||
|  |     // Create server-side TLS options
 | ||
|  |     const tlsOptions = createTlsOptions(certificates, true); | ||
|  |      | ||
|  |     // Log details for debugging
 | ||
|  |     SmtpLogger.debug('Creating secure server with options', { | ||
|  |       certificates: { | ||
|  |         keyLength: certificates.key.length, | ||
|  |         certLength: certificates.cert.length, | ||
|  |         caLength: certificates.ca ? certificates.ca.length : 0 | ||
|  |       }, | ||
|  |       tlsOptions: { | ||
|  |         minVersion: tlsOptions.minVersion, | ||
|  |         maxVersion: tlsOptions.maxVersion, | ||
|  |         ciphers: tlsOptions.ciphers?.substring(0, 50) + '...' // Truncate long cipher list
 | ||
|  |       } | ||
|  |     }); | ||
|  |      | ||
|  |     // Create the TLS server
 | ||
|  |     const server = new plugins.tls.Server(tlsOptions); | ||
|  |      | ||
|  |     // Set up error handlers
 | ||
|  |     server.on('error', (err) => { | ||
|  |       SmtpLogger.error(`Secure server error: ${err.message}`, { | ||
|  |         component: 'secure-server', | ||
|  |         error: err, | ||
|  |         stack: err.stack | ||
|  |       }); | ||
|  |     }); | ||
|  |      | ||
|  |     // Log secure connections
 | ||
|  |     server.on('secureConnection', (socket) => { | ||
|  |       const protocol = socket.getProtocol(); | ||
|  |       const cipher = socket.getCipher(); | ||
|  |        | ||
|  |       SmtpLogger.info('New direct TLS connection established', { | ||
|  |         component: 'secure-server', | ||
|  |         remoteAddress: socket.remoteAddress, | ||
|  |         remotePort: socket.remotePort, | ||
|  |         protocol: protocol || 'unknown', | ||
|  |         cipher: cipher?.name || 'unknown' | ||
|  |       }); | ||
|  |     }); | ||
|  |      | ||
|  |     return server; | ||
|  |   } catch (error) { | ||
|  |     SmtpLogger.error(`Failed to create secure TLS server: ${error instanceof Error ? error.message : String(error)}`, { | ||
|  |       component: 'secure-server', | ||
|  |       error: error instanceof Error ? error : new Error(String(error)), | ||
|  |       stack: error instanceof Error ? error.stack : 'No stack trace available' | ||
|  |     }); | ||
|  |      | ||
|  |     return undefined; | ||
|  |   } | ||
|  | } |