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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }