update
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import * as plugins from '../../../plugins.js';
|
||||
import type { ITlsHandler, ISmtpServer } from './interfaces.js';
|
||||
import type { ITlsHandler, ISmtpServer, ISmtpSession } from './interfaces.js';
|
||||
import { SmtpResponseCode, SecurityEventType, SecurityLogLevel } from './constants.js';
|
||||
import { SmtpLogger } from './utils/logging.js';
|
||||
import { getSocketDetails, getTlsDetails } from './utils/helpers.js';
|
||||
@ -30,6 +30,11 @@ export class TlsHandler implements ITlsHandler {
|
||||
*/
|
||||
private certificates: ICertificateData;
|
||||
|
||||
/**
|
||||
* TLS options
|
||||
*/
|
||||
private options: plugins.tls.TlsOptions;
|
||||
|
||||
/**
|
||||
* Creates a new TLS handler
|
||||
* @param smtpServer - SMTP server instance
|
||||
@ -38,13 +43,13 @@ export class TlsHandler implements ITlsHandler {
|
||||
this.smtpServer = smtpServer;
|
||||
|
||||
// Initialize certificates
|
||||
const options = this.smtpServer.getOptions();
|
||||
const serverOptions = this.smtpServer.getOptions();
|
||||
try {
|
||||
// Try to load certificates from provided options
|
||||
this.certificates = loadCertificatesFromString({
|
||||
key: options.key,
|
||||
cert: options.cert,
|
||||
ca: options.ca
|
||||
key: serverOptions.key,
|
||||
cert: serverOptions.cert,
|
||||
ca: serverOptions.ca
|
||||
});
|
||||
|
||||
SmtpLogger.info('Successfully loaded TLS certificates');
|
||||
@ -54,30 +59,27 @@ export class TlsHandler implements ITlsHandler {
|
||||
// Fall back to self-signed certificates for testing
|
||||
this.certificates = generateSelfSignedCertificates();
|
||||
}
|
||||
|
||||
// Initialize TLS options
|
||||
this.options = createTlsOptions(this.certificates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle STARTTLS command
|
||||
* @param socket - Client socket
|
||||
*/
|
||||
public handleStartTls(socket: plugins.net.Socket | plugins.tls.TLSSocket): void {
|
||||
// Get the session for this socket
|
||||
const session = this.smtpServer.getSessionManager().getSession(socket);
|
||||
if (!session) {
|
||||
this.sendResponse(socket, `${SmtpResponseCode.LOCAL_ERROR} Internal server error - session not found`);
|
||||
return;
|
||||
}
|
||||
public async handleStartTls(socket: plugins.net.Socket, session: ISmtpSession): Promise<plugins.tls.TLSSocket | null> {
|
||||
|
||||
// Check if already using TLS
|
||||
if (session.useTLS) {
|
||||
this.sendResponse(socket, `${SmtpResponseCode.BAD_SEQUENCE} TLS already active`);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if we have the necessary TLS certificates
|
||||
if (!this.isTlsEnabled()) {
|
||||
this.sendResponse(socket, `${SmtpResponseCode.TLS_UNAVAILABLE_TEMP} TLS not available`);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Send ready for TLS response
|
||||
@ -85,7 +87,8 @@ export class TlsHandler implements ITlsHandler {
|
||||
|
||||
// Upgrade the connection to TLS
|
||||
try {
|
||||
this.startTLS(socket);
|
||||
const tlsSocket = await this.startTLS(socket);
|
||||
return tlsSocket;
|
||||
} catch (error) {
|
||||
SmtpLogger.error(`STARTTLS negotiation failed: ${error instanceof Error ? error.message : String(error)}`, {
|
||||
sessionId: session.id,
|
||||
@ -101,6 +104,8 @@ export class TlsHandler implements ITlsHandler {
|
||||
{ error: error instanceof Error ? error.message : String(error) },
|
||||
session.remoteAddress
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +113,7 @@ export class TlsHandler implements ITlsHandler {
|
||||
* Upgrade a connection to TLS
|
||||
* @param socket - Client socket
|
||||
*/
|
||||
public async startTLS(socket: plugins.net.Socket): Promise<void> {
|
||||
public async startTLS(socket: plugins.net.Socket): Promise<plugins.tls.TLSSocket> {
|
||||
// Get the session for this socket
|
||||
const session = this.smtpServer.getSessionManager().getSession(socket);
|
||||
|
||||
@ -120,11 +125,11 @@ export class TlsHandler implements ITlsHandler {
|
||||
SmtpLogger.info('Using enhanced STARTTLS implementation');
|
||||
|
||||
// Use the enhanced STARTTLS handler with better error handling and socket management
|
||||
const options = this.smtpServer.getOptions();
|
||||
const serverOptions = this.smtpServer.getOptions();
|
||||
const tlsSocket = await performStartTLS(socket, {
|
||||
key: options.key,
|
||||
cert: options.cert,
|
||||
ca: options.ca,
|
||||
key: serverOptions.key,
|
||||
cert: serverOptions.cert,
|
||||
ca: serverOptions.ca,
|
||||
session: session,
|
||||
sessionManager: this.smtpServer.getSessionManager(),
|
||||
connectionManager: this.smtpServer.getConnectionManager(),
|
||||
@ -180,7 +185,10 @@ export class TlsHandler implements ITlsHandler {
|
||||
sessionId: session?.id,
|
||||
remoteAddress: socket.remoteAddress
|
||||
});
|
||||
throw new Error('Failed to create TLS socket');
|
||||
}
|
||||
|
||||
return tlsSocket;
|
||||
} catch (error) {
|
||||
// Log STARTTLS failure
|
||||
SmtpLogger.error(`Failed to upgrade connection to TLS: ${error instanceof Error ? error.message : String(error)}`, {
|
||||
@ -206,6 +214,7 @@ export class TlsHandler implements ITlsHandler {
|
||||
|
||||
// Destroy the socket on error
|
||||
socket.destroy();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,6 +321,20 @@ export class TlsHandler implements ITlsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if TLS is available (interface requirement)
|
||||
*/
|
||||
public isTlsAvailable(): boolean {
|
||||
return this.isTlsEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TLS options (interface requirement)
|
||||
*/
|
||||
public getTlsOptions(): plugins.tls.TlsOptions {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up resources
|
||||
*/
|
||||
|
Reference in New Issue
Block a user