This commit is contained in:
2025-05-23 08:17:34 +00:00
parent 7344bf0f70
commit 53f5e30b23
3 changed files with 45 additions and 11 deletions

View File

@@ -210,7 +210,7 @@ export class CommandHandler implements ICommandHandler {
break; break;
case SmtpCommand.QUIT: case SmtpCommand.QUIT:
this.handleQuit(socket); this.handleQuit(socket, args);
break; break;
case SmtpCommand.STARTTLS: case SmtpCommand.STARTTLS:
@@ -734,7 +734,13 @@ export class CommandHandler implements ICommandHandler {
* Handle QUIT command * Handle QUIT command
* @param socket - Client socket * @param socket - Client socket
*/ */
public handleQuit(socket: plugins.net.Socket | plugins.tls.TLSSocket): void { public handleQuit(socket: plugins.net.Socket | plugins.tls.TLSSocket, args?: string): void {
// QUIT command should not have any parameters
if (args && args.trim().length > 0) {
this.sendResponse(socket, `${SmtpResponseCode.SYNTAX_ERROR_PARAMETERS} Syntax error in parameters`);
return;
}
// Get the session for this socket // Get the session for this socket
const session = this.smtpServer.getSessionManager().getSession(socket); const session = this.smtpServer.getSessionManager().getSession(socket);

View File

@@ -145,10 +145,10 @@ export const SMTP_PATTERNS = {
// Match parameter format: "PARAM=VALUE" // Match parameter format: "PARAM=VALUE"
PARAM: /\s+([A-Za-z0-9][A-Za-z0-9\-]*)(?:=([^\s]+))?/g, PARAM: /\s+([A-Za-z0-9][A-Za-z0-9\-]*)(?:=([^\s]+))?/g,
// Match email address format - made much more permissive // Match email address format - basic validation
// This only does very basic format validation to avoid rejecting valid addresses // This pattern rejects common invalid formats while being permissive for edge cases
// According to RFC 5321, we should accept a wide variety of sender formats // Checks: no spaces, has @, has domain with dot, no double dots, proper domain format
EMAIL: /^[^\s@]+(@[^\s@]+\.[^\s@]+)?$/, EMAIL: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
// Match end of DATA marker: \r\n.\r\n or just .\r\n at the start of a line (to handle various client implementations) // Match end of DATA marker: \r\n.\r\n or just .\r\n at the start of a line (to handle various client implementations)
END_DATA: /(\r\n\.\r\n$)|(\n\.\r\n$)|(\r\n\.\n$)|(\n\.\n$)|^\.(\r\n|\n)$/, END_DATA: /(\r\n\.\r\n$)|(\n\.\r\n$)|(\r\n\.\n$)|(\n\.\n$)|^\.(\r\n|\n)$/,

View File

@@ -100,7 +100,35 @@ export function isValidEmail(email: string): boolean {
return false; return false;
} }
return SMTP_PATTERNS.EMAIL.test(email); // Basic pattern check
if (!SMTP_PATTERNS.EMAIL.test(email)) {
return false;
}
// Additional validation for common invalid patterns
const [localPart, domain] = email.split('@');
// Check for double dots
if (email.includes('..')) {
return false;
}
// Check domain doesn't start or end with dot
if (domain && (domain.startsWith('.') || domain.endsWith('.'))) {
return false;
}
// Check local part length (max 64 chars per RFC)
if (localPart && localPart.length > 64) {
return false;
}
// Check domain length (max 253 chars per RFC - accounting for trailing dot)
if (domain && domain.length > 253) {
return false;
}
return true;
} }
/** /**
@@ -160,7 +188,7 @@ export function validateMailFrom(args: string): {
// During testing, we should validate the email format // During testing, we should validate the email format
// Check for basic email format (something@somewhere) // Check for basic email format (something@somewhere)
if (!SMTP_PATTERNS.EMAIL.test(emailPart)) { if (!isValidEmail(emailPart)) {
return { isValid: false, errorMessage: 'Invalid email address format' }; return { isValid: false, errorMessage: 'Invalid email address format' };
} }
@@ -185,7 +213,7 @@ export function validateMailFrom(args: string): {
// Tests expect us to reject formats without angle brackets // Tests expect us to reject formats without angle brackets
// For better compliance with tests, check if the argument might contain an email without brackets // For better compliance with tests, check if the argument might contain an email without brackets
if (SMTP_PATTERNS.EMAIL.test(cleanArgs)) { if (isValidEmail(cleanArgs)) {
return { isValid: false, errorMessage: 'Invalid syntax - angle brackets required' }; return { isValid: false, errorMessage: 'Invalid syntax - angle brackets required' };
} }
@@ -236,7 +264,7 @@ export function validateRcptTo(args: string): {
// During testing, we should validate the email format // During testing, we should validate the email format
// Check for basic email format (something@somewhere) // Check for basic email format (something@somewhere)
if (!SMTP_PATTERNS.EMAIL.test(emailPart)) { if (!isValidEmail(emailPart)) {
return { isValid: false, errorMessage: 'Invalid email address format' }; return { isValid: false, errorMessage: 'Invalid email address format' };
} }
@@ -261,7 +289,7 @@ export function validateRcptTo(args: string): {
// Tests expect us to reject formats without angle brackets // Tests expect us to reject formats without angle brackets
// For better compliance with tests, check if the argument might contain an email without brackets // For better compliance with tests, check if the argument might contain an email without brackets
if (SMTP_PATTERNS.EMAIL.test(cleanArgs)) { if (isValidEmail(cleanArgs)) {
return { isValid: false, errorMessage: 'Invalid syntax - angle brackets required' }; return { isValid: false, errorMessage: 'Invalid syntax - angle brackets required' };
} }