コード例 #1
0
ファイル: SSLBind.cpp プロジェクト: linkclau/XMail
static int BSslHandleAsync(SslBindCtx *pCtx, int iCode, int iDefError, int iTimeo)
{
	int iError, iResult = 0;
	SYS_fd_set FdSet;

	if ((iError = SSL_get_error(pCtx->pSSL, iCode)) != SSL_ERROR_NONE) {
		SYS_FD_ZERO(&FdSet);
		SYS_FD_SET(pCtx->SockFD, &FdSet);
		if (iError == SSL_ERROR_WANT_READ) {
			if (SysSelect((long) pCtx->SockFD + 1, &FdSet, NULL,
				      NULL, iTimeo) < 0)
				return ErrGetErrorCode();
			iResult = 1;
		} else if (iError == SSL_ERROR_WANT_WRITE) {
			if (SysSelect((long) pCtx->SockFD + 1, NULL, &FdSet,
				      NULL, iTimeo) < 0)
				return ErrGetErrorCode();
			iResult = 1;
		} else {
			ErrSetErrorCode(iDefError);
			iResult = iDefError;
		}
	}

	return iResult;
}
コード例 #2
0
ファイル: POP3Utils.cpp プロジェクト: GerHobbelt/xmail
int UPopCheckMailboxSize(UserInfo *pUI, SYS_OFF_T *pllAvailSpace)
{
    SYS_OFF_T llMBSize = 0, llProbeSize = (pllAvailSpace != NULL) ? *pllAvailSpace: 0;
    unsigned long ulNumMessages = 0;

    if (UPopGetMailboxSize(pUI, llMBSize, ulNumMessages) < 0)
        return ErrGetErrorCode();

    pszMaxMBSize = UsrGetUserInfoVar(pUI, "MaxMBSize");

    if (pszMaxMBSize != NULL) {
        SYS_OFF_T llMaxMBSize = Sys_atoi64(pszMaxMBSize) * 1024;

        SysFree(pszMaxMBSize);
        if (llMaxMBSize != 0 && (llMBSize + llProbeSize >= llMaxMBSize)) {
            ErrSetErrorCode(ERR_MAILBOX_SIZE);
            return ERR_MAILBOX_SIZE;
        }
        if (pllAvailSpace != NULL)
            *pllAvailSpace = (llMaxMBSize != 0 ? llMaxMBSize - llMBSize:
                      MaxSignedType(SYS_OFF_T));
    } else if (pllAvailSpace != NULL)
        *pllAvailSpace = MaxSignedType(SYS_OFF_T);

    return 0;
}
コード例 #3
0
ファイル: POP3Utils.cpp プロジェクト: GerHobbelt/xmail
int UPopGetMailboxSize(UserInfo *pUI, SYS_OFF_T &llMBSize, unsigned long &ulNumMessages)
{
    char szMBPath[SYS_MAX_PATH];

    UsrGetMailboxPath(pUI, szMBPath, sizeof(szMBPath), 0);

    char szResLock[SYS_MAX_PATH];
    RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szMBPath, szResLock,
                              sizeof(szResLock)));

    if (hResLock == INVALID_RLCK_HANDLE)
        return ErrGetErrorCode();

    llMBSize = 0;
    ulNumMessages = 0;
    if (MscGetDirectorySize(szMBPath, true, llMBSize, ulNumMessages,
                UPopMailFileNameFilter) < 0) {
        ErrorPush();
        RLckUnlockSH(hResLock);
        return ErrorPop();
    }
    RLckUnlockSH(hResLock);

    return 0;
}
コード例 #4
0
ファイル: Hash.cpp プロジェクト: GerHobbelt/xmail
static int HashGrow(Hash *pHash)
{
    unsigned long i, ulHIdx, ulHMask;
    SysListHead *pBkts, *pHead, *pPos;
    HashNode *pHNode;

    ulHMask = pHash->ulHMask + 1;
    if (ulHMask & HMASK_TOP_BIT)
        return 0;
    ulHMask = (ulHMask << 1) - 1;
    if ((pBkts = (SysListHead *)
         SysAlloc((ulHMask + 1) * sizeof(SysListHead))) == NULL)
        return ErrGetErrorCode();
    for (i = 0; i <= ulHMask; i++)
        SYS_INIT_LIST_HEAD(&pBkts[i]);
    for (i = 0; i <= pHash->ulHMask; i++) {
        pHead = &pHash->pBkts[i];
        while ((pPos = SYS_LIST_FIRST(pHead)) != NULL) {
            pHNode = SYS_LIST_ENTRY(pPos, HashNode, Lnk);
            SYS_LIST_DEL(&pHNode->Lnk);
            ulHIdx = (*pHash->Ops.pGetHashVal)(pHash->Ops.pPrivate,
                               &pHNode->Key) & ulHMask;
            SYS_LIST_ADDT(&pHNode->Lnk, &pBkts[ulHIdx]);
        }
    }
    SysFree(pHash->pBkts);
    pHash->pBkts = pBkts;
    pHash->ulHMask = ulHMask;

    return 0;
}
コード例 #5
0
ファイル: BuffSock.cpp プロジェクト: GerHobbelt/xmail
int BSckBufferInit(BSockLineBuffer *pBLB, int iSize)
{
    if (iSize <= 0)
        iSize = BSOCK_STD_BUFFER_SIZE;

    if ((pBLB->pszBuffer = (char *) SysAlloc(iSize)) == NULL)
        return ErrGetErrorCode();
    pBLB->iSize = iSize;

    return 0;
}
コード例 #6
0
ファイル: BuffSock.cpp プロジェクト: GerHobbelt/xmail
int BSckSendData(BSOCK_HANDLE hBSock, char const *pszBuffer, int iSize, int iTimeout)
{
    BuffSocketData *pBSD = (BuffSocketData *) hBSock;

    SysLogMessage(LOG_LEV_DEBUG, "socket write data (len = %d)\n", iSize);

    if (BSckWriteLL(pBSD, pszBuffer, iSize, iTimeout) != iSize)
        return ErrGetErrorCode();

    return iSize;
}
コード例 #7
0
ファイル: BuffSock.cpp プロジェクト: GerHobbelt/xmail
int BSckSendString(BSOCK_HANDLE hBSock, char const *pszBuffer, int iTimeout)
{
    BuffSocketData *pBSD = (BuffSocketData *) hBSock;
    char *pszSendBuffer = (char *) SysAlloc(strlen(pszBuffer) + 3);

    if (pszSendBuffer == NULL)
        return ErrGetErrorCode();

    SysLogMessage(LOG_LEV_DEBUG, "socket write line: [%s]\n", pszBuffer);

    sprintf(pszSendBuffer, "%s\r\n", pszBuffer);

    int iSendLength = (int)strlen(pszSendBuffer);

    if (BSckWriteLL(pBSD, pszSendBuffer, iSendLength, iTimeout) != iSendLength) {
        SysFree(pszSendBuffer);
        return ErrGetErrorCode();
    }
    SysFree(pszSendBuffer);

    return iSendLength;
}
コード例 #8
0
ファイル: POP3Utils.cpp プロジェクト: GerHobbelt/xmail
static int UPopBuildMessageList(UserInfo *pUI, SysListHead *pMsgList,
                int *piMsgCount, SYS_OFF_T *pllMBSize)
{
    char szMBPath[SYS_MAX_PATH];

    UsrGetMailboxPath(pUI, szMBPath, sizeof(szMBPath), 0);

    char szResLock[SYS_MAX_PATH];
    RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szMBPath, szResLock,
                              sizeof(szResLock)));

    if (hResLock == INVALID_RLCK_HANDLE)
        return ErrGetErrorCode();

    SYS_INIT_LIST_HEAD(pMsgList);

    int iMsgCount = 0;
    SYS_OFF_T llMBSize = 0;

    if (iMailboxType == XMAIL_MAILBOX) {
        if (UPopFillMessageList(szMBPath, NULL, pMsgList, iMsgCount,
                    llMBSize) < 0) {
            ErrorPush();
            UPopFreeMessageList(pMsgList);
            RLckUnlockEX(hResLock);
            return ErrorPop();
        }
    } else {
        int iScanCur = UsrGetUserInfoVarInt(pUI, "Pop3ScanCur", 0);

        if (UPopFillMessageList(szMBPath, "new", pMsgList, iMsgCount,
                    llMBSize) < 0 ||
            (iScanCur > 0 &&
             UPopFillMessageList(szMBPath, "cur", pMsgList, iMsgCount,
                     llMBSize) < 0)) {
            ErrorPush();
            UPopFreeMessageList(pMsgList);
            RLckUnlockEX(hResLock);
            return ErrorPop();
        }
    }
    RLckUnlockEX(hResLock);
    if (piMsgCount != NULL)
        *piMsgCount = iMsgCount;
    if (pllMBSize != NULL)
        *pllMBSize = llMBSize;

    return 0;
}
コード例 #9
0
ファイル: Hash.cpp プロジェクト: GerHobbelt/xmail
int HashAdd(HASH_HANDLE hHash, HashNode *pHNode)
{
    Hash *pHash = (Hash *) hHash;
    unsigned long ulHIdx;
    SysListHead *pHead;

    if (pHash->ulCount >= pHash->ulHMask && HashGrow(pHash) < 0)
        return ErrGetErrorCode();
    ulHIdx = (*pHash->Ops.pGetHashVal)(pHash->Ops.pPrivate,
                       &pHNode->Key) & pHash->ulHMask;
    pHead = &pHash->pBkts[ulHIdx];
    SYS_LIST_ADDT(&pHNode->Lnk, pHead);
    pHash->ulCount++;

    return 0;
}
コード例 #10
0
ファイル: BuffSock.cpp プロジェクト: GerHobbelt/xmail
int BSckVSendString(BSOCK_HANDLE hBSock, int iTimeout, char const *pszFormat, ...)
{
    char *pszBuffer = NULL;

    StrVSprint(pszBuffer, pszFormat, pszFormat);

    if (pszBuffer == NULL)
        return ErrGetErrorCode();
    if (BSckSendString(hBSock, pszBuffer, iTimeout) < 0) {
        ErrorPush();
        SysFree(pszBuffer);
        return ErrorPop();
    }
    SysFree(pszBuffer);

    return 0;
}
コード例 #11
0
ファイル: SSLBind.cpp プロジェクト: linkclau/XMail
static int BSslCtx__SendFile(void *pPrivate, char const *pszFilePath, SYS_OFF_T llOffStart,
			     SYS_OFF_T llOffEnd, int iTimeo)
{
	SslBindCtx *pCtx = (SslBindCtx *) pPrivate;
	SYS_MMAP hMap;
	SYS_OFF_T llSize, llAlnOff;
	void *pMapAddr;
	char *pCurAddr;

	if ((hMap = SysCreateMMap(pszFilePath, SYS_MMAP_READ)) == SYS_INVALID_MMAP)
		return ErrGetErrorCode();
	llSize = SysMMapSize(hMap);
	if (llOffEnd == -1)
		llOffEnd = llSize;
	if (llOffStart > llSize || llOffEnd > llSize || llOffStart > llOffEnd) {
		SysCloseMMap(hMap);
		ErrSetErrorCode(ERR_INVALID_PARAMETER);
		return ERR_INVALID_PARAMETER;
	}
	llAlnOff = SysMMapOffsetAlign(hMap, llOffStart);
	if ((pMapAddr = SysMapMMap(hMap, llAlnOff,
				   (SYS_SIZE_T) (llOffEnd - llAlnOff))) == NULL) {
		ErrorPush();
		SysCloseMMap(hMap);
		return ErrorPop();
	}
	pCurAddr = (char *) pMapAddr + (llOffStart - llAlnOff);
	while (llOffStart < llOffEnd) {
		int iSize = (int) Min(BSSL_WRITE_BLKSIZE, llOffEnd - llOffStart), iWrite;

		if ((iWrite = BSslWriteLL(pCtx, pCurAddr, iSize, iTimeo)) < 0) {
			ErrorPush();
			SysUnmapMMap(hMap, pMapAddr, (SYS_SIZE_T) (llOffEnd - llAlnOff));
			SysCloseMMap(hMap);
			return ErrorPop();
		}
		pCurAddr += iWrite;
		llOffStart += iWrite;
	}
	SysUnmapMMap(hMap, pMapAddr, (SYS_SIZE_T) (llOffEnd - llAlnOff));
	SysCloseMMap(hMap);

	return 0;
}
コード例 #12
0
ファイル: SSLBind.cpp プロジェクト: linkclau/XMail
static int BSslAllocCtx(SslBindCtx **ppCtx, SYS_SOCKET SockFD, SSL_CTX *pSCtx, SSL *pSSL)
{
	SslBindCtx *pCtx;

	if ((pCtx = (SslBindCtx *) SysAlloc(sizeof(SslBindCtx))) == NULL)
		return ErrGetErrorCode();
	pCtx->IOOps.pPrivate = pCtx;
	pCtx->IOOps.pName = BSslCtx__Name;
	pCtx->IOOps.pFree = BSslCtx__Free;
	pCtx->IOOps.pRead = BSslCtx__Read;
	pCtx->IOOps.pWrite = BSslCtx__Write;
	pCtx->IOOps.pSendFile = BSslCtx__SendFile;
	pCtx->SockFD = SockFD;
	pCtx->pSCtx = pSCtx;
	pCtx->pSSL = pSSL;

	*ppCtx = pCtx;

	return 0;
}
コード例 #13
0
ファイル: ResLocks.cpp プロジェクト: GerHobbelt/xmail
int RLckInitLockers(void)
{
    /* Create resource locking mutex */
    if ((hRLMutex = SysCreateMutex()) == SYS_INVALID_MUTEX)
        return ErrGetErrorCode();

    /* Initialize wait gates */
    for (int i = 0; i < STD_WAIT_GATES; i++) {
        if ((RLGates[i].hSemaphore = SysCreateSemaphore(0,
                                SYS_DEFAULT_MAXCOUNT)) ==
            SYS_INVALID_SEMAPHORE) {
            ErrorPush();
            for (--i; i >= 0; i--) {
                SysFree(RLGates[i].pResList);
                SysCloseSemaphore(RLGates[i].hSemaphore);
            }
            SysCloseMutex(hRLMutex);
            return ErrorPop();
        }

        RLGates[i].iWaitingProcesses = 0;
        RLGates[i].iHashSize = STD_RES_HASH_SIZE;

        if ((RLGates[i].pResList = (SysListHead *)
             SysAlloc(RLGates[i].iHashSize * sizeof(SysListHead))) == NULL) {
            ErrorPush();
            SysCloseSemaphore(RLGates[i].hSemaphore);
            for (--i; i >= 0; i--) {
                SysFree(RLGates[i].pResList);
                SysCloseSemaphore(RLGates[i].hSemaphore);
            }
            SysCloseMutex(hRLMutex);
            return ErrorPop();
        }
        for (int j = 0; j < RLGates[i].iHashSize; j++)
            SYS_INIT_LIST_HEAD(&RLGates[i].pResList[j]);
    }

    return 0;
}
コード例 #14
0
ファイル: SSLBind.cpp プロジェクト: linkclau/XMail
int BSslInit(void)
{
	int i, iNumLocks = CRYPTO_num_locks();

	if ((pSslMtxs = (SYS_MUTEX *) SysAlloc(iNumLocks * sizeof(SYS_MUTEX))) == NULL)
		return ErrGetErrorCode();
	for (i = 0; i < iNumLocks; i++) {
		if ((pSslMtxs[i] = SysCreateMutex()) == SYS_INVALID_MUTEX) {
			ErrorPush();
			for (i--; i >= 0; i--)
				SysCloseMutex(pSslMtxs[i]);
			SysFreeNullify(pSslMtxs);
			return ErrorPop();
		}
	}
	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
	CRYPTO_set_id_callback(SysGetCurrentThreadId);
	CRYPTO_set_locking_callback(BSslLockingCB);
	SysAddThreadExitHook(BSslThreadExit, NULL);

	return 0;
}
コード例 #15
0
ファイル: ResLocks.cpp プロジェクト: GerHobbelt/xmail
int RLckCleanupLockers(void)
{
    if (SysLockMutex(hRLMutex, SYS_INFINITE_TIMEOUT) < 0)
        return ErrGetErrorCode();
    for (int i = 0; i < STD_WAIT_GATES; i++) {
        for (int j = 0; j < RLGates[i].iHashSize; j++) {
            SysListHead *pHead = &RLGates[i].pResList[j];
            SysListHead *pLLink;

            while ((pLLink = SYS_LIST_FIRST(pHead)) != NULL) {
                ResLockEntry *pRLE = SYS_LIST_ENTRY(pLLink, ResLockEntry, LLink);

                SYS_LIST_DEL(&pRLE->LLink);
                RLckFreeEntry(pRLE);
            }
        }
        SysFree(RLGates[i].pResList);
        SysCloseSemaphore(RLGates[i].hSemaphore);
    }
    SysUnlockMutex(hRLMutex);
    SysCloseMutex(hRLMutex);

    return 0;
}
コード例 #16
0
ファイル: SSLBind.cpp プロジェクト: linkclau/XMail
int BSslBindServer(BSOCK_HANDLE hBSock, SslServerBind const *pSSLB,
		   int (*pfEnvCB)(void *, int, void const *), void *pPrivate)
{
	int iError;
	SYS_SOCKET SockFD;
	SSL_METHOD const *pMethod;
	SSL_CTX *pSCtx;
	SSL *pSSL;
	X509 *pCert;
	SslBindCtx *pCtx;

	pMethod = SSLv23_server_method();
	if ((pSCtx = SSL_CTX_new((SSL_METHOD *) pMethod)) == NULL) {
		ErrSetErrorCode(ERR_SSLCTX_CREATE);
		return ERR_SSLCTX_CREATE;
	}
	SSL_CTX_set_session_cache_mode(pSCtx, SSL_SESS_CACHE_OFF);
	if (BSslSetupVerify(pSCtx, pSSLB) < 0) {
		SSL_CTX_free(pSCtx);
		return ErrGetErrorCode();
	}
	if ((pSSL = SSL_new(pSCtx)) == NULL) {
		SSL_CTX_free(pSCtx);
		ErrSetErrorCode(ERR_SSL_CREATE);
		return ERR_SSL_CREATE;
	}
	SockFD = BSckGetAttachedSocket(hBSock);
	/*
	 * We want blocking sockets during the initial SSL negotiation.
	 */
	SysBlockSocket(SockFD, 1);
	SSL_set_fd(pSSL, SockFD);
	if (SSL_accept(pSSL) == -1) {
		SysBlockSocket(SockFD, -1);
		SSL_free(pSSL);
		SSL_CTX_free(pSCtx);
		ErrSetErrorCode(ERR_SSL_ACCEPT);
		return ERR_SSL_ACCEPT;
	}
	SSL_CTX_set_app_data(pSCtx, NULL);
	/*
	 * Client may not supply a certificate.
	 */
	iError = 0;
	if (pfEnvCB != NULL &&
	    (pCert = SSL_get_peer_certificate(pSSL)) != NULL) {
		iError = BSslEnvExport(pSCtx, pSSL, pCert, pfEnvCB, pPrivate);
		X509_free(pCert);
	}
	if (iError < 0 ||
	    BSslAllocCtx(&pCtx, SockFD, pSCtx, pSSL) < 0) {
		ErrorPush();
		SysBlockSocket(SockFD, -1);
		SSL_free(pSSL);
		SSL_CTX_free(pSCtx);
		return ErrorPop();
	}
	/*
	 * Need to use non-blocking socket to implement read/write timeouts.
	 */
	SysBlockSocket(SockFD, 0);
	BSckSetIOops(hBSock, &pCtx->IOOps);

	return 0;
}