X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fsmtp%2Fserv_smtp.c;h=b7ee16a693da15c0fa14789e12ba67b041226b0f;hb=e329db30593524cc2d8851a4500bac41f2340354;hp=f21e9d16ecd55c82de1a2a4f9c414314b393c12e;hpb=5e3befebe2ed0ce85324da3be83b21880dc7d069;p=citadel.git diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index f21e9d16e..b7ee16a69 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -20,15 +20,15 @@ * The VRFY and EXPN commands have been removed from this implementation * because nobody uses these commands anymore, except for spammers. * - * Copyright (c) 1998-2012 by the citadel.org team + * Copyright (c) 1998-2018 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "sysdep.h" @@ -69,6 +69,7 @@ #include "config.h" #include "control.h" #include "user_ops.h" +#include "room_ops.h" #include "database.h" #include "msgbase.h" #include "internet_addressing.h" @@ -80,6 +81,7 @@ #include "ctdl_module.h" #include "smtp_util.h" + enum { /* Command states for login authentication */ smtp_command, smtp_user, @@ -100,6 +102,8 @@ typedef struct _smtp_handler_hook { int Flags; } smtp_handler_hook; +int EnableSMTPLog = 0; + HashList *SMTPCmds = NULL; #define MaxSMTPCmdLen 10 @@ -112,7 +116,9 @@ void registerSmtpCMD(const char *First, long FLen, smtp_handler_hook *h; if (FLen >= MaxSMTPCmdLen) - cit_panic_backtrace (0); + { + abort(); + } h = (smtp_handler_hook*) malloc(sizeof(smtp_handler_hook)); memset(h, 0, sizeof(smtp_handler_hook)); @@ -122,6 +128,7 @@ void registerSmtpCMD(const char *First, long FLen, Put(SMTPCmds, First, FLen, h, NULL); } + void smtp_cleanup(void) { DeleteHash(&SMTPCmds); @@ -147,12 +154,14 @@ void smtp_greeting(int is_msa) sSMTP->from = NewStrBufPlain(NULL, SIZ); sSMTP->recipients = NewStrBufPlain(NULL, SIZ); sSMTP->OneRcpt = NewStrBufPlain(NULL, SIZ); + sSMTP->preferred_sender_email = NULL; + sSMTP->preferred_sender_name = NULL; /* If this config option is set, reject connections from problem * addresses immediately instead of after they execute a RCPT */ - if ( (config.c_rbl_at_greeting) && (sSMTP->is_msa == 0) ) { - if (rbl_check(message_to_spammer)) { + if ( (CtdlGetConfigInt("c_rbl_at_greeting")) && (sSMTP->is_msa == 0) ) { + if (rbl_check(CC->cs_addr, message_to_spammer)) { if (server_shutting_down) cprintf("421 %s\r\n", message_to_spammer); else @@ -175,7 +184,7 @@ void smtp_greeting(int is_msa) /* Note: the FQDN *must* appear as the first thing after the 220 code. * Some clients (including citmail.c) depend on it being there. */ - cprintf("220 %s ESMTP Citadel server ready.\r\n", config.c_fqdn); + cprintf("220 %s ESMTP Citadel server ready.\r\n", CtdlGetConfigStr("c_fqdn")); } @@ -234,10 +243,11 @@ void lmtp_unfiltered_greeting(void) { * Login greeting common to all auth methods */ void smtp_auth_greeting(long offset, long Flags) { - cprintf("235 Hello, %s\r\n", CC->user.fullname); - syslog(LOG_NOTICE, "SMTP authenticated %s\n", CC->user.fullname); - CC->internal_pgm = 0; - CC->cs_flags &= ~CS_STEALTH; + struct CitContext *CCC = CC; + cprintf("235 Hello, %s\r\n", CCC->user.fullname); + syslog(LOG_NOTICE, "SMTP authenticated %s", CCC->user.fullname); + CCC->internal_pgm = 0; + CCC->cs_flags &= ~CS_STEALTH; } @@ -248,6 +258,7 @@ void smtp_auth_greeting(long offset, long Flags) { */ void smtp_hello(long offset, long which_command) { + struct CitContext *CCC = CC; citsmtp *sSMTP = SMTP; StrBufAppendBuf (sSMTP->helo_node, sSMTP->Cmd, offset); @@ -265,23 +276,23 @@ void smtp_hello(long offset, long which_command) if (which_command == HELO) { cprintf("250 Hello %s (%s [%s])\r\n", ChrPtr(sSMTP->helo_node), - CC->cs_host, - CC->cs_addr + CCC->cs_host, + CCC->cs_addr ); } else { if (which_command == EHLO) { cprintf("250-Hello %s (%s [%s])\r\n", ChrPtr(sSMTP->helo_node), - CC->cs_host, - CC->cs_addr + CCC->cs_host, + CCC->cs_addr ); } else { cprintf("250-Greetings and joyous salutations.\r\n"); } cprintf("250-HELP\r\n"); - cprintf("250-SIZE %ld\r\n", config.c_maxmsglen); + cprintf("250-SIZE %ld\r\n", CtdlGetConfigLong("c_maxmsglen")); #ifdef HAVE_OPENSSL /* @@ -290,7 +301,7 @@ void smtp_hello(long offset, long which_command) * the SMTP-MSA port, not on the SMTP-MTA port, due to * questionable reliability of TLS in certain sending MTA's. */ - if ( (!CC->redirect_ssl) && (sSMTP->is_msa) ) { + if ( (!CCC->redirect_ssl) && (sSMTP->is_msa) ) { cprintf("250-STARTTLS\r\n"); } #endif /* HAVE_OPENSSL */ @@ -315,7 +326,7 @@ void smtp_webcit_preferences_hack_backend(long msgnum, void *userdata) { return; // already got it } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { return; } @@ -336,11 +347,13 @@ void smtp_webcit_preferences_hack_backend(long msgnum, void *userdata) { * stored in the account's WebCit configuration. We have to fetch it now. */ void smtp_webcit_preferences_hack(void) { + struct CitContext *CCC = CC; char config_roomname[ROOMNAMELEN]; char *webcit_conf = NULL; + citsmtp *sSMTP = SMTP; - snprintf(config_roomname, sizeof config_roomname, "%010ld.%s", CC->user.usernum, USERCONFIGROOM); - if (CtdlGetRoom(&CC->room, config_roomname) != 0) { + snprintf(config_roomname, sizeof config_roomname, "%010ld.%s", CCC->user.usernum, USERCONFIGROOM); + if (CtdlGetRoom(&CCC->room, config_roomname) != 0) { return; } @@ -354,10 +367,24 @@ void smtp_webcit_preferences_hack(void) { return; } - /* FIXME : now do something with this data */ + /* Parse the webcit configuration and attempt to do something useful with it */ + char *str = webcit_conf; + char *saveptr = str; + char *this_line = NULL; + while (this_line = strtok_r(str, "\n", &saveptr), this_line != NULL) { + str = NULL; + if (!strncasecmp(this_line, "defaultfrom|", 12)) { + sSMTP->preferred_sender_email = NewStrBufPlain(&this_line[12], -1); + } + if (!strncasecmp(this_line, "defaultname|", 12)) { + sSMTP->preferred_sender_name = NewStrBufPlain(&this_line[12], -1); + } + if ((!strncasecmp(this_line, "defaultname|", 12)) && (sSMTP->preferred_sender_name == NULL)) { + sSMTP->preferred_sender_name = NewStrBufPlain(&this_line[12], -1); + } + } free(webcit_conf); - abort(); } @@ -376,13 +403,16 @@ void smtp_help(long offset, long Flags) { void smtp_get_user(long offset) { char buf[SIZ]; - char username[SIZ]; citsmtp *sSMTP = SMTP; - CtdlDecodeBase64(username, ChrPtr(sSMTP->Cmd) + offset, SIZ); - /* syslog(LOG_DEBUG, "Trying <%s>\n", username); */ - if (CtdlLoginExistingUser(NULL, username) == login_ok) { - CtdlEncodeBase64(buf, "Password:", 9, 0); + StrBufDecodeBase64(sSMTP->Cmd); + + if (CtdlLoginExistingUser(ChrPtr(sSMTP->Cmd)) == login_ok) { + size_t len = CtdlEncodeBase64(buf, "Password:", 9, 0); + + if (buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } cprintf("334 %s\r\n", buf); sSMTP->command_state = smtp_password; } @@ -400,12 +430,11 @@ void smtp_get_pass(long offset, long Flags) { citsmtp *sSMTP = SMTP; char password[SIZ]; - long len; - memset(password, 0, sizeof(password)); - len = CtdlDecodeBase64(password, ChrPtr(sSMTP->Cmd), SIZ); - /* syslog(LOG_DEBUG, "Trying <%s>\n", password); */ - if (CtdlTryPassword(password, len) == pass_ok) { + memset(password, 0, sizeof(password)); + StrBufDecodeBase64(sSMTP->Cmd); + syslog(LOG_DEBUG, "Trying <%s>", password); + if (CtdlTryPassword(SKEY(sSMTP->Cmd)) == pass_ok) { smtp_auth_greeting(offset, Flags); } else { @@ -421,32 +450,57 @@ void smtp_get_pass(long offset, long Flags) void smtp_try_plain(long offset, long Flags) { citsmtp *sSMTP = SMTP; - char decoded_authstring[1024]; - char ident[256]; - char user[256]; - char pass[256]; + const char*decoded_authstring; + char ident[256] = ""; + char user[256] = ""; + char pass[256] = ""; int result; - long len; - CtdlDecodeBase64(decoded_authstring, ChrPtr(sSMTP->Cmd), StrLength(sSMTP->Cmd)); - safestrncpy(ident, decoded_authstring, sizeof ident); - safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user); - len = safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass); - if (len == -1) - len = sizeof(pass) - 1; + long decoded_len; + long len = 0; + long plen = 0; + + memset(pass, 0, sizeof(pass)); + decoded_len = StrBufDecodeBase64(sSMTP->Cmd); + + if (decoded_len > 0) + { + decoded_authstring = ChrPtr(sSMTP->Cmd); + + len = safestrncpy(ident, decoded_authstring, sizeof ident); + + decoded_len -= len - 1; + decoded_authstring += len + 1; + + if (decoded_len > 0) + { + len = safestrncpy(user, decoded_authstring, sizeof user); + + decoded_authstring += len + 1; + decoded_len -= len - 1; + } + + if (decoded_len > 0) + { + plen = safestrncpy(pass, decoded_authstring, sizeof pass); + + if (plen < 0) + plen = sizeof(pass) - 1; + } + } sSMTP->command_state = smtp_command; if (!IsEmptyStr(ident)) { - result = CtdlLoginExistingUser(user, ident); + result = CtdlLoginExistingUser(ident); } else { - result = CtdlLoginExistingUser(NULL, user); + result = CtdlLoginExistingUser(user); } if (result == login_ok) { - if (CtdlTryPassword(pass, len) == pass_ok) { -//// smtp_webcit_preferences_hack(); + if (CtdlTryPassword(pass, plen) == pass_ok) { + smtp_webcit_preferences_hack(); smtp_auth_greeting(offset, Flags); return; } @@ -460,12 +514,13 @@ void smtp_try_plain(long offset, long Flags) */ void smtp_auth(long offset, long Flags) { + struct CitContext *CCC = CC; citsmtp *sSMTP = SMTP; char username_prompt[64]; char method[64]; char encoded_authstring[1024]; - if (CC->logged_in) { + if (CCC->logged_in) { cprintf("504 Already logged in.\r\n"); return; } @@ -477,7 +532,10 @@ void smtp_auth(long offset, long Flags) smtp_get_user(6); } else { - CtdlEncodeBase64(username_prompt, "Username:", 9, 0); + size_t len = CtdlEncodeBase64(username_prompt, "Username:", 9, 0); + if (username_prompt[len - 1] == '\n') { + username_prompt[len - 1] = '\0'; + } cprintf("334 %s\r\n", username_prompt); sSMTP->command_state = smtp_user; } @@ -580,6 +638,7 @@ void smtp_mail(long offset, long flags) { char user[SIZ]; char node[SIZ]; char name[SIZ]; + struct CitContext *CCC = CC; citsmtp *sSMTP = SMTP; if (StrLength(sSMTP->from) > 0) { @@ -604,15 +663,15 @@ void smtp_mail(long offset, long flags) { * address so we don't have to contend with the empty string causing * other code to fail when it's expecting something there. */ - if (StrLength(sSMTP->from)) { + if (StrLength(sSMTP->from) == 0) { StrBufPlain(sSMTP->from, HKEY("someone@example.com")); } /* If this SMTP connection is from a logged-in user, force the 'from' * to be the user's Internet e-mail address as Citadel knows it. */ - if (CC->logged_in) { - StrBufPlain(sSMTP->from, CC->cs_inet_email, -1); + if (CCC->logged_in) { + StrBufPlain(sSMTP->from, CCC->cs_inet_email, -1); cprintf("250 Sender ok <%s>\r\n", ChrPtr(sSMTP->from)); sSMTP->message_originated_locally = 1; return; @@ -625,7 +684,7 @@ void smtp_mail(long offset, long flags) { /* Otherwise, make sure outsiders aren't trying to forge mail from * this system (unless, of course, c_allow_spoofing is enabled) */ - else if (config.c_allow_spoofing == 0) { + else if (CtdlGetConfigInt("c_allow_spoofing") == 0) { process_rfc822_addr(ChrPtr(sSMTP->from), user, node, name); syslog(LOG_DEBUG, "Claimed envelope sender is '%s' == '%s' @ '%s' ('%s')", ChrPtr(sSMTP->from), user, node, name @@ -650,7 +709,7 @@ void smtp_rcpt(long offset, long flags) { struct CitContext *CCC = CC; char message_to_spammer[SIZ]; - struct recptypes *valid = NULL; + recptypes *valid = NULL; citsmtp *sSMTP = SMTP; if (StrLength(sSMTP->from) == 0) { @@ -681,8 +740,8 @@ void smtp_rcpt(long offset, long flags) /* RBL check */ if ( (!CCC->logged_in) /* Don't RBL authenticated users */ && (!sSMTP->is_lmtp) ) { /* Don't RBL LMTP clients */ - if (config.c_rbl_at_greeting == 0) { /* Don't RBL again if we already did it */ - if (rbl_check(message_to_spammer)) { + if (CtdlGetConfigInt("c_rbl_at_greeting") == 0) { /* Don't RBL again if we already did it */ + if (rbl_check(CC->cs_addr, message_to_spammer)) { if (server_shutting_down) cprintf("421 %s\r\n", message_to_spammer); else @@ -749,7 +808,7 @@ void smtp_data(long offset, long flags) struct CtdlMessage *msg = NULL; long msgnum = (-1L); char nowstamp[SIZ]; - struct recptypes *valid; + recptypes *valid; int scan_errors; int i; citsmtp *sSMTP = SMTP; @@ -777,7 +836,7 @@ void smtp_data(long offset, long flags) " by %s; %s\n", ChrPtr(sSMTP->helo_node), (long int) CCC->cs_UDSclientUID, - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), nowstamp); } else { @@ -788,18 +847,18 @@ void smtp_data(long offset, long flags) ChrPtr(sSMTP->helo_node), CCC->cs_host, CCC->cs_addr, - config.c_fqdn, + CtdlGetConfigStr("c_fqdn"), nowstamp); } } - body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL); + body = CtdlReadMessageBodyBuf(HKEY("."), CtdlGetConfigLong("c_maxmsglen"), defbody, 1); FreeStrBuf(&defbody); if (body == NULL) { cprintf("550 Unable to save message: internal error.\r\n"); return; } - syslog(LOG_DEBUG, "Converting message...\n"); + syslog(LOG_DEBUG, "Converting message..."); msg = convert_internet_message_buf(&body); /* If the user is locally authenticated, FORCE the From: header to @@ -812,12 +871,12 @@ void smtp_data(long offset, long flags) * to something ugly like "0000058008.Sent Items>" when the message * is read with a Citadel client. */ - if ( (CCC->logged_in) && (config.c_rfc822_strict_from != CFG_SMTP_FROM_NOFILTER) ) { + if ( (CCC->logged_in) && (CtdlGetConfigInt("c_rfc822_strict_from") != CFG_SMTP_FROM_NOFILTER) ) { int validemail = 0; if (!CM_IsEmpty(msg, erFc822Addr) && - ((config.c_rfc822_strict_from == CFG_SMTP_FROM_CORRECT) || - (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT) ) ) + ((CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_CORRECT) || + (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT) ) ) { if (!IsEmptyStr(CCC->cs_inet_email)) validemail = strcmp(CCC->cs_inet_email, msg->cm_fields[erFc822Addr]) == 0; @@ -835,19 +894,24 @@ void smtp_data(long offset, long flags) } } - if (!validemail && (config.c_rfc822_strict_from == CFG_SMTP_FROM_REJECT)) { + if (!validemail && (CtdlGetConfigInt("c_rfc822_strict_from") == CFG_SMTP_FROM_REJECT)) { syslog(LOG_ERR, "invalid sender '%s' - rejecting this message", msg->cm_fields[erFc822Addr]); cprintf("550 Invalid sender '%s' - rejecting this message.\r\n", msg->cm_fields[erFc822Addr]); return; } - CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); - CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename)); - CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode)); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); CM_SetField(msg, eOriginalRoom, HKEY(MAILROOM)); + if (sSMTP->preferred_sender_name != NULL) + CM_SetField(msg, eAuthor, SKEY(sSMTP->preferred_sender_name)); + else + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); if (!validemail) { - CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); + if (sSMTP->preferred_sender_email != NULL) + CM_SetField(msg, erFc822Addr, SKEY(sSMTP->preferred_sender_email)); + else + CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); } } @@ -872,7 +936,7 @@ void smtp_data(long offset, long flags) scan_errors = 0; } else { - scan_errors = PerformMessageHooks(msg, EVT_SMTPSCAN); + scan_errors = PerformMessageHooks(msg, valid, EVT_SMTPSCAN); } if (scan_errors > 0) { /* We don't want this message! */ @@ -913,13 +977,13 @@ void smtp_data(long offset, long flags) * rest of the Citadel logs are going; some sysadmins want LOG_MAIL). */ syslog((LOG_MAIL | LOG_INFO), - "%ld: from=<%s>, nrcpts=%d, relay=%s [%s], stat=%s", - msgnum, - ChrPtr(sSMTP->from), - sSMTP->number_of_recipients, - CCC->cs_host, - CCC->cs_addr, - ChrPtr(sSMTP->OneRcpt) + "%ld: from=<%s>, nrcpts=%d, relay=%s [%s], stat=%s", + msgnum, + ChrPtr(sSMTP->from), + sSMTP->number_of_recipients, + CCC->cs_host, + CCC->cs_addr, + ChrPtr(sSMTP->OneRcpt) ); /* Clean up */ @@ -951,6 +1015,7 @@ void smtp_starttls(long offset, long flags) */ void smtp_command_loop(void) { + static const ConstStr AuthPlainStr = {HKEY("AUTH PLAIN")}; struct CitContext *CCC = CC; citsmtp *sSMTP = SMTP; const char *pch, *pchs; @@ -958,28 +1023,34 @@ void smtp_command_loop(void) char CMD[MaxSMTPCmdLen + 1]; if (sSMTP == NULL) { - syslog(LOG_EMERG, "Session SMTP data is null. WTF? We will crash now.\n"); - return cit_panic_backtrace (0); + syslog(LOG_EMERG, "Session SMTP data is null. WTF? We will crash now."); + abort(); } time(&CCC->lastcmd); if (CtdlClientGetLine(sSMTP->Cmd) < 1) { - syslog(LOG_CRIT, "SMTP: client disconnected: ending session.\n"); + syslog(LOG_CRIT, "SMTP: client disconnected: ending session."); CC->kill_me = KILLME_CLIENT_DISCONNECTED; return; } - syslog(LOG_DEBUG, "SMTP server: %s\n", ChrPtr(sSMTP->Cmd)); + syslog(LOG_DEBUG, "SMTP server: %s", ChrPtr(sSMTP->Cmd)); if (sSMTP->command_state == smtp_user) { - smtp_get_user(0); + if (!strncmp(ChrPtr(sSMTP->Cmd), AuthPlainStr.Key, AuthPlainStr.len)) + smtp_try_plain(0, 0); + else + smtp_get_user(0); + return; } else if (sSMTP->command_state == smtp_password) { smtp_get_pass(0, 0); + return; } else if (sSMTP->command_state == smtp_plain) { smtp_try_plain(0, 0); + return; } pchs = pch = ChrPtr(sSMTP->Cmd); @@ -1036,17 +1107,20 @@ void smtp_quit(long offest, long Flags) void smtp_cleanup_function(void) { citsmtp *sSMTP = SMTP; + struct CitContext *CCC = CC; /* Don't do this stuff if this is not an SMTP session! */ - if (CC->h_command_function != smtp_command_loop) return; + if (CCC->h_command_function != smtp_command_loop) return; - syslog(LOG_DEBUG, "Performing SMTP cleanup hook\n"); + syslog(LOG_DEBUG, "Performing SMTP cleanup hook"); FreeStrBuf(&sSMTP->Cmd); FreeStrBuf(&sSMTP->helo_node); FreeStrBuf(&sSMTP->from); FreeStrBuf(&sSMTP->recipients); FreeStrBuf(&sSMTP->OneRcpt); + FreeStrBuf(&sSMTP->preferred_sender_email); + FreeStrBuf(&sSMTP->preferred_sender_name); free(sSMTP); } @@ -1057,6 +1131,7 @@ const char *CitadelServiceSMTP_MSA="SMTP-MSA"; const char *CitadelServiceSMTP_LMTP="LMTP"; const char *CitadelServiceSMTP_LMTP_UNF="LMTP-UnF"; + CTDL_MODULE_INIT(smtp) { if (!threading) @@ -1079,7 +1154,7 @@ CTDL_MODULE_INIT(smtp) #endif - CtdlRegisterServiceHook(config.c_smtp_port, /* SMTP MTA */ + CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtp_port"), /* SMTP MTA */ NULL, smtp_mta_greeting, smtp_command_loop, @@ -1087,7 +1162,7 @@ CTDL_MODULE_INIT(smtp) CitadelServiceSMTP_MTA); #ifdef HAVE_OPENSSL - CtdlRegisterServiceHook(config.c_smtps_port, + CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtps_port"), /* SMTPS MTA */ NULL, smtps_greeting, smtp_command_loop, @@ -1095,7 +1170,7 @@ CTDL_MODULE_INIT(smtp) CitadelServiceSMTPS_MTA); #endif - CtdlRegisterServiceHook(config.c_msa_port, /* SMTP MSA */ + CtdlRegisterServiceHook(CtdlGetConfigInt("c_msa_port"), /* SMTP MSA */ NULL, smtp_msa_greeting, smtp_command_loop,