SMTPUtils.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:61k
- /*
- * XMail by Davide Libenzi ( Intranet and Internet mail server )
- * Copyright (C) 1999,..,2004 Davide Libenzi
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Davide Libenzi <davidel@xmailserver.org>
- *
- */
- #include "SysInclude.h"
- #include "SysDep.h"
- #include "SvrDefines.h"
- #include "ShBlocks.h"
- #include "ResLocks.h"
- #include "StrUtils.h"
- #include "SList.h"
- #include "BuffSock.h"
- #include "MailConfig.h"
- #include "UsrUtils.h"
- #include "UsrAuth.h"
- #include "SvrUtils.h"
- #include "MiscUtils.h"
- #include "DNS.h"
- #include "DNSCache.h"
- #include "MessQueue.h"
- #include "SMAILUtils.h"
- #include "QueueUtils.h"
- #include "SMTPSvr.h"
- #include "SMTPUtils.h"
- #include "Base64Enc.h"
- #include "MD5.h"
- #include "MailSvr.h"
- #define STD_SMTP_TIMEOUT STD_SERVER_TIMEOUT
- #define SMTPGW_LINE_MAX 1024
- #define SMTPGW_TABLE_FILE "smtpgw.tab"
- #define SMTPFWD_LINE_MAX 1024
- #define SMTPFWD_TABLE_FILE "smtpfwd.tab"
- #define SMTPRELAY_LINE_MAX 512
- #define SMTP_RELAY_FILE "smtprelay.tab"
- #define MAX_MX_RECORDS 32
- #define SMTP_SPAMMERS_FILE "spammers.tab"
- #define SMTP_SPAM_ADDRESS_FILE "spam-address.tab"
- #define SPAMMERS_LINE_MAX 512
- #define SPAM_ADDRESS_LINE_MAX 512
- #define SMTPAUTH_LINE_MAX 512
- #define SMTP_EXTAUTH_TIMEOUT 60
- #define SMTP_EXTAUTH_PRIORITY SYS_PRIORITY_NORMAL
- #define SMTP_EXTAUTH_SUCCESS 0
- #define RFC_SPECIALS "()<>@,/\;:"[]*?"
- #define SMTPCH_SUPPORT_SIZE (1 << 0)
- enum SmtpGwFileds {
- gwDomain = 0,
- gwGateway,
- gwMax
- };
- enum SmtpFwdFileds {
- fwdDomain = 0,
- fwdGateway,
- fwdMax
- };
- enum SmtpRelayFileds {
- rlyFromIP = 0,
- rlyFromMask,
- rlyMax
- };
- enum SpammerFileds {
- spmFromIP = 0,
- spmFromMask,
- spmMax
- };
- struct SmtpMXRecords {
- int iNumMXRecords;
- int iMXCost[MAX_MX_RECORDS];
- char *pszMXName[MAX_MX_RECORDS];
- int iCurrMxCost;
- };
- struct SmtpChannel {
- BSOCK_HANDLE hBSock;
- unsigned long ulFlags;
- unsigned long ulMaxMsgSize;
- SYS_INET_ADDR SvrAddr;
- char *pszServer;
- };
- static int USmtpWriteGateway(FILE * pGwFile, const char *pszDomain, const char *pszGateway);
- static char *USmtpGetGwTableFilePath(char *pszGwFilePath, int iMaxPath);
- static char *USmtpGetFwdTableFilePath(char *pszFwdFilePath, int iMaxPath);
- static char *USmtpGetRelayFilePath(char *pszRelayFilePath, int iMaxPath);
- static int USmtpSetError(SMTPError * pSMTPE, int iSTMPResponse, char const *pszSTMPResponse,
- char const *pszServer);
- static int USmtpSetErrorServer(SMTPError * pSMTPE, char const *pszServer);
- static int USmtpResponseClass(int iResponseCode, int iResponseClass);
- static int USmtpGetResultCode(const char *pszResult);
- static int USmtpIsPartialResponse(char const *pszResponse);
- static int USmtpGetResponse(BSOCK_HANDLE hBSock, char *pszResponse, int iMaxResponse,
- int iTimeout = STD_SMTP_TIMEOUT);
- static int USmtpSendCommand(BSOCK_HANDLE hBSock, const char *pszCommand,
- char *pszResponse, int iMaxResponse, int iTimeout = STD_SMTP_TIMEOUT);
- static int USmtpGetServerAuthFile(char const *pszServer, char *pszAuthFilePath);
- static int USmtpDoPlainAuth(SmtpChannel * pSmtpCh, char const *pszServer,
- char const *const *ppszAuthTokens, SMTPError * pSMTPE);
- static int USmtpDoLoginAuth(SmtpChannel * pSmtpCh, char const *pszServer,
- char const *const *ppszAuthTokens, SMTPError * pSMTPE);
- static int USmtpDoCramMD5Auth(SmtpChannel * pSmtpCh, char const *pszServer,
- char const *const *ppszAuthTokens, SMTPError * pSMTPE);
- static int USmtpExternalAuthSubstitute(char **ppszAuthTokens, char const *pszChallenge,
- char const *pszSecret, char const *pszRespFile);
- static int USmtpDoExternAuth(SmtpChannel * pSmtpCh, char const *pszServer,
- char **ppszAuthTokens, SMTPError * pSMTPE);
- static int USmtpServerAuthenticate(SmtpChannel * pSmtpCh, char const *pszServer,
- SMTPError * pSMTPE);
- static int USmtpParseEhloResponse(SmtpChannel * pSmtpCh, char const *pszResponse);
- static int USmtpGetDomainMX(SVRCFG_HANDLE hSvrConfig, const char *pszDomain, char *&pszMXDomains);
- static char *USmtpGetSpammersFilePath(char *pszSpamFilePath, int iMaxPath);
- static char *USmtpGetSpamAddrFilePath(char *pszSpamFilePath, int iMaxPath);
- static char *USmtpGetGwTableFilePath(char *pszGwFilePath, int iMaxPath)
- {
- CfgGetRootPath(pszGwFilePath, iMaxPath);
- StrNCat(pszGwFilePath, SMTPGW_TABLE_FILE, iMaxPath);
- return (pszGwFilePath);
- }
- static char *USmtpGetFwdTableFilePath(char *pszFwdFilePath, int iMaxPath)
- {
- CfgGetRootPath(pszFwdFilePath, iMaxPath);
- StrNCat(pszFwdFilePath, SMTPFWD_TABLE_FILE, iMaxPath);
- return (pszFwdFilePath);
- }
- char **USmtpGetFwdGateways(SVRCFG_HANDLE hSvrConfig, const char *pszDomain)
- {
- char szFwdFilePath[SYS_MAX_PATH] = "";
- USmtpGetFwdTableFilePath(szFwdFilePath, sizeof(szFwdFilePath));
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szFwdFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (NULL);
- FILE *pFwdFile = fopen(szFwdFilePath, "rt");
- if (pFwdFile == NULL) {
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_SMTPFWD_FILE_NOT_FOUND);
- return (NULL);
- }
- char szFwdLine[SMTPFWD_LINE_MAX] = "";
- while (MscGetConfigLine(szFwdLine, sizeof(szFwdLine) - 1, pFwdFile) != NULL) {
- char **ppszStrings = StrGetTabLineStrings(szFwdLine);
- if (ppszStrings == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszStrings);
- if ((iFieldsCount >= fwdMax) && StrIWildMatch(pszDomain, ppszStrings[fwdDomain])) {
- char **ppszFwdGws = NULL;
- if (ppszStrings[fwdGateway][0] == '#') {
- if ((ppszFwdGws =
- StrTokenize(ppszStrings[fwdGateway] + 1, ",")) != NULL) {
- int iGwCount = StrStringsCount(ppszFwdGws);
- srand((unsigned int) time(NULL));
- for (int ii = 0; ii < (iGwCount / 2); ii++) {
- int iSwap1 = rand() % iGwCount;
- int iSwap2 = rand() % iGwCount;
- char *pszGw1 = ppszFwdGws[iSwap1];
- char *pszGw2 = ppszFwdGws[iSwap2];
- ppszFwdGws[iSwap1] = pszGw2;
- ppszFwdGws[iSwap2] = pszGw1;
- }
- }
- } else
- ppszFwdGws = StrTokenize(ppszStrings[fwdGateway], ",");
- StrFreeStrings(ppszStrings);
- fclose(pFwdFile);
- RLckUnlockSH(hResLock);
- return (ppszFwdGws);
- }
- StrFreeStrings(ppszStrings);
- }
- fclose(pFwdFile);
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_SMTPFWD_NOT_FOUND);
- return (NULL);
- }
- static char *USmtpGetRelayFilePath(char *pszRelayFilePath, int iMaxPath)
- {
- CfgGetRootPath(pszRelayFilePath, iMaxPath);
- StrNCat(pszRelayFilePath, SMTP_RELAY_FILE, iMaxPath);
- return (pszRelayFilePath);
- }
- int USmtpGetGateway(SVRCFG_HANDLE hSvrConfig, const char *pszDomain, char *pszGateway)
- {
- char szGwFilePath[SYS_MAX_PATH] = "";
- USmtpGetGwTableFilePath(szGwFilePath, sizeof(szGwFilePath));
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szGwFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- FILE *pGwFile = fopen(szGwFilePath, "rt");
- if (pGwFile == NULL) {
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_SMTPGW_FILE_NOT_FOUND);
- return (ERR_SMTPGW_FILE_NOT_FOUND);
- }
- char szGwLine[SMTPGW_LINE_MAX] = "";
- while (MscGetConfigLine(szGwLine, sizeof(szGwLine) - 1, pGwFile) != NULL) {
- char **ppszStrings = StrGetTabLineStrings(szGwLine);
- if (ppszStrings == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszStrings);
- if ((iFieldsCount >= gwMax) && StrIWildMatch(pszDomain, ppszStrings[gwDomain])) {
- strcpy(pszGateway, ppszStrings[gwGateway]);
- StrFreeStrings(ppszStrings);
- fclose(pGwFile);
- RLckUnlockSH(hResLock);
- return (0);
- }
- StrFreeStrings(ppszStrings);
- }
- fclose(pGwFile);
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_SMTPGW_NOT_FOUND);
- return (ERR_SMTPGW_NOT_FOUND);
- }
- static int USmtpWriteGateway(FILE * pGwFile, const char *pszDomain, const char *pszGateway)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Domain
- ///////////////////////////////////////////////////////////////////////////////
- char *pszQuoted = StrQuote(pszDomain, '"');
- if (pszQuoted == NULL)
- return (ErrGetErrorCode());
- fprintf(pGwFile, "%st", pszQuoted);
- SysFree(pszQuoted);
- ///////////////////////////////////////////////////////////////////////////////
- // Gateway
- ///////////////////////////////////////////////////////////////////////////////
- pszQuoted = StrQuote(pszGateway, '"');
- if (pszQuoted == NULL)
- return (ErrGetErrorCode());
- fprintf(pGwFile, "%sn", pszQuoted);
- SysFree(pszQuoted);
- return (0);
- }
- int USmtpAddGateway(const char *pszDomain, const char *pszGateway)
- {
- char szGwFilePath[SYS_MAX_PATH] = "";
- USmtpGetGwTableFilePath(szGwFilePath, sizeof(szGwFilePath));
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szGwFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- FILE *pGwFile = fopen(szGwFilePath, "r+t");
- if (pGwFile == NULL) {
- RLckUnlockEX(hResLock);
- ErrSetErrorCode(ERR_SMTPGW_FILE_NOT_FOUND);
- return (ERR_SMTPGW_FILE_NOT_FOUND);
- }
- char szGwLine[SMTPGW_LINE_MAX] = "";
- while (MscGetConfigLine(szGwLine, sizeof(szGwLine) - 1, pGwFile) != NULL) {
- char **ppszStrings = StrGetTabLineStrings(szGwLine);
- if (ppszStrings == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszStrings);
- if ((iFieldsCount >= gwMax) && (stricmp(pszDomain, ppszStrings[gwDomain]) == 0) &&
- (stricmp(pszGateway, ppszStrings[gwGateway]) == 0)) {
- StrFreeStrings(ppszStrings);
- fclose(pGwFile);
- RLckUnlockEX(hResLock);
- ErrSetErrorCode(ERR_GATEWAY_ALREADY_EXIST);
- return (ERR_GATEWAY_ALREADY_EXIST);
- }
- StrFreeStrings(ppszStrings);
- }
- fseek(pGwFile, 0, SEEK_END);
- if (USmtpWriteGateway(pGwFile, pszDomain, pszGateway) < 0) {
- fclose(pGwFile);
- RLckUnlockEX(hResLock);
- return (ErrGetErrorCode());
- }
- fclose(pGwFile);
- RLckUnlockEX(hResLock);
- return (0);
- }
- int USmtpRemoveGateway(const char *pszDomain)
- {
- char szGwFilePath[SYS_MAX_PATH] = "";
- USmtpGetGwTableFilePath(szGwFilePath, sizeof(szGwFilePath));
- char szTmpFile[SYS_MAX_PATH] = "";
- SysGetTmpFile(szTmpFile);
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szGwFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- FILE *pGwFile = fopen(szGwFilePath, "rt");
- if (pGwFile == NULL) {
- RLckUnlockEX(hResLock);
- ErrSetErrorCode(ERR_SMTPGW_FILE_NOT_FOUND);
- return (ERR_SMTPGW_FILE_NOT_FOUND);
- }
- FILE *pTmpFile = fopen(szTmpFile, "wt");
- if (pTmpFile == NULL) {
- fclose(pGwFile);
- RLckUnlockEX(hResLock);
- ErrSetErrorCode(ERR_FILE_CREATE);
- return (ERR_FILE_CREATE);
- }
- int iGatewayFound = 0;
- char szGwLine[SMTPGW_LINE_MAX] = "";
- while (MscGetConfigLine(szGwLine, sizeof(szGwLine) - 1, pGwFile, false) != NULL) {
- if (szGwLine[0] == TAB_COMMENT_CHAR) {
- fprintf(pTmpFile, "%sn", szGwLine);
- continue;
- }
- char **ppszStrings = StrGetTabLineStrings(szGwLine);
- if (ppszStrings == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszStrings);
- if ((iFieldsCount >= gwMax) && (stricmp(pszDomain, ppszStrings[gwDomain]) == 0)) {
- ++iGatewayFound;
- } else
- fprintf(pTmpFile, "%sn", szGwLine);
- StrFreeStrings(ppszStrings);
- }
- fclose(pGwFile);
- fclose(pTmpFile);
- if (iGatewayFound == 0) {
- SysRemove(szTmpFile);
- RLckUnlockEX(hResLock);
- ErrSetErrorCode(ERR_GATEWAY_NOT_FOUND);
- return (ERR_GATEWAY_NOT_FOUND);
- }
- char szTmpGwFilePath[SYS_MAX_PATH] = "";
- sprintf(szTmpGwFilePath, "%s.tmp", szGwFilePath);
- if (MscMoveFile(szGwFilePath, szTmpGwFilePath) < 0) {
- ErrorPush();
- RLckUnlockEX(hResLock);
- return (ErrorPop());
- }
- if (MscMoveFile(szTmpFile, szGwFilePath) < 0) {
- ErrorPush();
- MscMoveFile(szTmpGwFilePath, szGwFilePath);
- RLckUnlockEX(hResLock);
- return (ErrorPop());
- }
- SysRemove(szTmpGwFilePath);
- RLckUnlockEX(hResLock);
- return (0);
- }
- int USmtpIsAllowedRelay(const SYS_INET_ADDR & PeerInfo, SVRCFG_HANDLE hSvrConfig)
- {
- char szRelayFilePath[SYS_MAX_PATH] = "";
- USmtpGetRelayFilePath(szRelayFilePath, sizeof(szRelayFilePath));
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szRelayFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- FILE *pRelayFile = fopen(szRelayFilePath, "rt");
- if (pRelayFile == NULL) {
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_SMTPRELAY_FILE_NOT_FOUND);
- return (ERR_SMTPRELAY_FILE_NOT_FOUND);
- }
- NET_ADDRESS TestAddr;
- SysGetAddrAddress(PeerInfo, TestAddr);
- char szRelayLine[SMTPRELAY_LINE_MAX] = "";
- while (MscGetConfigLine(szRelayLine, sizeof(szRelayLine) - 1, pRelayFile) != NULL) {
- char **ppszStrings = StrGetTabLineStrings(szRelayLine);
- if (ppszStrings == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszStrings);
- AddressFilter AF;
- if ((iFieldsCount > 0) &&
- (MscLoadAddressFilter(ppszStrings, iFieldsCount, AF) == 0) &&
- MscAddressMatch(AF, TestAddr)) {
- StrFreeStrings(ppszStrings);
- fclose(pRelayFile);
- RLckUnlockSH(hResLock);
- return (0);
- }
- StrFreeStrings(ppszStrings);
- }
- fclose(pRelayFile);
- RLckUnlockSH(hResLock);
- ErrSetErrorCode(ERR_RELAY_NOT_ALLOWED);
- return (ERR_RELAY_NOT_ALLOWED);
- }
- char **USmtpGetPathStrings(const char *pszMailCmd)
- {
- const char *pszOpen = strchr(pszMailCmd, '<');
- const char *pszClose = strchr(pszMailCmd, '>');
- if ((pszOpen == NULL) || (pszClose == NULL)) {
- ErrSetErrorCode(ERR_SMTP_PATH_PARSE_ERROR);
- return (NULL);
- }
- int iPathLength = (int) (pszClose - pszOpen) - 1;
- if ((iPathLength < 0) || (iPathLength >= MAX_SMTP_ADDRESS)) {
- ErrSetErrorCode(ERR_SMTP_PATH_PARSE_ERROR, pszMailCmd);
- return (NULL);
- }
- char *pszPath = (char *) SysAlloc(iPathLength + 1);
- if (pszPath == NULL)
- return (NULL);
- strncpy(pszPath, pszOpen + 1, iPathLength);
- pszPath[iPathLength] = ' ';
- char **ppszDomains = StrTokenize(pszPath, ",:");
- SysFree(pszPath);
- return (ppszDomains);
- }
- int USmtpSplitEmailAddr(const char *pszAddr, char *pszUser, char *pszDomain)
- {
- const char *pszAT = strchr(pszAddr, '@');
- if (pszAT == NULL) {
- ErrSetErrorCode(ERR_BAD_EMAIL_ADDR);
- return (ERR_BAD_EMAIL_ADDR);
- }
- int iUserLength = (int) (pszAT - pszAddr);
- int iDomainLength = strlen(pszAT + 1);
- if (pszUser != NULL) {
- if (iUserLength == 0) {
- ErrSetErrorCode(ERR_BAD_EMAIL_ADDR);
- return (ERR_BAD_EMAIL_ADDR);
- }
- iUserLength = Min(iUserLength, MAX_ADDR_NAME - 1);
- strncpy(pszUser, pszAddr, iUserLength);
- pszUser[iUserLength] = ' ';
- }
- if (pszDomain != NULL) {
- if (iDomainLength == 0) {
- ErrSetErrorCode(ERR_BAD_EMAIL_ADDR);
- return (ERR_BAD_EMAIL_ADDR);
- }
- StrNCpy(pszDomain, pszAT + 1, MAX_ADDR_NAME);
- }
- return (0);
- }
- int USmtpCheckAddressPart(char const *pszName)
- {
- for (; *pszName; pszName++)
- if ((*pszName <= ' ') || (*pszName == 127) ||
- (strchr(RFC_SPECIALS, *pszName) != NULL)) {
- ErrSetErrorCode(ERR_BAD_RFCNAME);
- return (ERR_BAD_RFCNAME);
- }
- return (0);
- }
- int USmtpCheckAddress(char const *pszAddress)
- {
- char szUser[MAX_ADDR_NAME] = "";
- char szDomain[MAX_ADDR_NAME] = "";
- if ((USmtpSplitEmailAddr(pszAddress, szUser, szDomain) < 0) ||
- (USmtpCheckAddressPart(szUser) < 0) || (USmtpCheckAddressPart(szDomain) < 0))
- return (ErrGetErrorCode());
- return (0);
- }
- int USmtpInitError(SMTPError * pSMTPE)
- {
- ZeroData(*pSMTPE);
- pSMTPE->iSTMPResponse = 0;
- pSMTPE->pszSTMPResponse = NULL;
- pSMTPE->pszServer = NULL;
- return (0);
- }
- static int USmtpSetError(SMTPError * pSMTPE, int iSTMPResponse, char const *pszSTMPResponse,
- char const *pszServer)
- {
- pSMTPE->iSTMPResponse = iSTMPResponse;
- if (pSMTPE->pszSTMPResponse != NULL)
- SysFree(pSMTPE->pszSTMPResponse);
- if (pSMTPE->pszServer != NULL)
- SysFree(pSMTPE->pszServer);
- pSMTPE->pszSTMPResponse = SysStrDup(pszSTMPResponse);
- pSMTPE->pszServer = SysStrDup(pszServer);
- return (0);
- }
- static int USmtpSetErrorServer(SMTPError * pSMTPE, char const *pszServer)
- {
- if (pSMTPE->pszServer != NULL)
- SysFree(pSMTPE->pszServer);
- pSMTPE->pszServer = SysStrDup(pszServer);
- return (0);
- }
- bool USmtpIsFatalError(SMTPError const *pSMTPE)
- {
- return ((pSMTPE->iSTMPResponse == SMTP_FATAL_ERROR) ||
- ((pSMTPE->iSTMPResponse >= 500) && (pSMTPE->iSTMPResponse < 600)));
- }
- char const *USmtpGetErrorMessage(SMTPError const *pSMTPE)
- {
- return ((pSMTPE->pszSTMPResponse != NULL) ? pSMTPE->pszSTMPResponse : "");
- }
- int USmtpCleanupError(SMTPError * pSMTPE)
- {
- if (pSMTPE->pszSTMPResponse != NULL)
- SysFree(pSMTPE->pszSTMPResponse);
- if (pSMTPE->pszServer != NULL)
- SysFree(pSMTPE->pszServer);
- USmtpInitError(pSMTPE);
- return (0);
- }
- char *USmtpGetSMTPError(SMTPError * pSMTPE, char *pszError, int iMaxError)
- {
- char const *pszSmtpErr =
- (pSMTPE != NULL) ? USmtpGetErrorMessage(pSMTPE) : DEFAULT_SMTP_ERR;
- if (IsEmptyString(pszSmtpErr))
- pszSmtpErr = DEFAULT_SMTP_ERR;
- StrNCpy(pszError, pszSmtpErr, iMaxError);
- return (pszError);
- }
- char const *USmtpGetErrorServer(SMTPError const *pSMTPE)
- {
- return ((pSMTPE->pszServer != NULL) ? pSMTPE->pszServer : "");
- }
- static int USmtpResponseClass(int iResponseCode, int iResponseClass)
- {
- return (((iResponseCode >= iResponseClass) &&
- (iResponseCode < (iResponseClass + 100))) ? 1 : 0);
- }
- static int USmtpGetResultCode(const char *pszResult)
- {
- int ii;
- char szResCode[64] = "";
- for (ii = 0; (ii < sizeof(szResCode)) && isdigit(pszResult[ii]); ii++)
- szResCode[ii] = pszResult[ii];
- if ((ii == 0) || (ii == sizeof(szResCode))) {
- ErrSetErrorCode(ERR_BAD_SMTP_RESPONSE);
- return (ERR_BAD_SMTP_RESPONSE);
- }
- szResCode[ii] = ' ';
- return (atoi(szResCode));
- }
- static int USmtpIsPartialResponse(char const *pszResponse)
- {
- return (((strlen(pszResponse) >= 4) && (pszResponse[3] == '-')) ? 1 : 0);
- }
- static int USmtpGetResponse(BSOCK_HANDLE hBSock, char *pszResponse, int iMaxResponse,
- int iTimeout)
- {
- int iResultCode = -1;
- int iResponseLenght = 0;
- char szPartial[1024] = "";
- SetEmptyString(pszResponse);
- do {
- int iLineLength = 0;
- if (BSckGetString(hBSock, szPartial, sizeof(szPartial) - 1, iTimeout,
- &iLineLength) == NULL)
- return (ErrGetErrorCode());
- if ((iResponseLenght + 2) < iMaxResponse) {
- if (iResponseLenght > 0)
- strcat(pszResponse, "rn"), iResponseLenght += 2;
- int iCopyLenght = Min(iMaxResponse - 1 - iResponseLenght, iLineLength);
- if (iCopyLenght > 0) {
- strncpy(pszResponse + iResponseLenght, szPartial, iCopyLenght);
- iResponseLenght += iCopyLenght;
- pszResponse[iResponseLenght] = ' ';
- }
- }
- if ((iResultCode = USmtpGetResultCode(szPartial)) < 0)
- return (ErrGetErrorCode());
- } while (USmtpIsPartialResponse(szPartial));
- return (iResultCode);
- }
- static int USmtpSendCommand(BSOCK_HANDLE hBSock, const char *pszCommand,
- char *pszResponse, int iMaxResponse, int iTimeout)
- {
- if (BSckSendString(hBSock, pszCommand, iTimeout) <= 0)
- return (ErrGetErrorCode());
- return (USmtpGetResponse(hBSock, pszResponse, iMaxResponse, iTimeout));
- }
- static int USmtpGetServerAuthFile(char const *pszServer, char *pszAuthFilePath)
- {
- int iRootedName = MscRootedName(pszServer);
- char szAuthPath[SYS_MAX_PATH] = "";
- UAthGetRootPath(AUTH_SERVICE_SMTP, szAuthPath, sizeof(szAuthPath));
- char const *pszDot = pszServer;
- while ((pszDot != NULL) && (strlen(pszDot) > 0)) {
- if (iRootedName)
- sprintf(pszAuthFilePath, "%s%stab", szAuthPath, pszDot);
- else
- sprintf(pszAuthFilePath, "%s%s.tab", szAuthPath, pszDot);
- if (SysExistFile(pszAuthFilePath))
- return (0);
- if ((pszDot = strchr(pszDot, '.')) != NULL)
- ++pszDot;
- }
- ErrSetErrorCode(ERR_NO_SMTP_AUTH_CONFIG);
- return (ERR_NO_SMTP_AUTH_CONFIG);
- }
- static int USmtpDoPlainAuth(SmtpChannel * pSmtpCh, char const *pszServer,
- char const *const *ppszAuthTokens, SMTPError * pSMTPE)
- {
- if (StrStringsCount(ppszAuthTokens) < 3) {
- ErrSetErrorCode(ERR_BAD_SMTP_AUTH_CONFIG);
- return (ERR_BAD_SMTP_AUTH_CONFIG);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Build plain text authentication token ( "