static int BSslSetupVerify(SSL_CTX *pSCtx, SslServerBind const *pSSLB) { char const *pszKeyFile = pSSLB->pszKeyFile; if (pSSLB->pszCertFile != NULL) { if (SSL_CTX_use_certificate_chain_file(pSCtx, pSSLB->pszCertFile) <= 0) { ErrSetErrorCode(ERR_SSL_SETCERT, pSSLB->pszCertFile); return ERR_SSL_SETCERT; } if (pszKeyFile == NULL) pszKeyFile = pSSLB->pszCertFile; } if (pszKeyFile != NULL) { if (SSL_CTX_use_PrivateKey_file(pSCtx, pszKeyFile, SSL_FILETYPE_PEM) <= 0) { ErrSetErrorCode(ERR_SSL_SETKEY, pszKeyFile); return ERR_SSL_SETKEY; } if (!SSL_CTX_check_private_key(pSCtx)) { ErrSetErrorCode(ERR_SSL_CHECKKEY, pszKeyFile); return ERR_SSL_CHECKKEY; } } if (pSSLB->ulFlags & BSSLF_WANT_VERIFY) { int iVerMode = SSL_VERIFY_PEER; if (pSSLB->ulFlags & BSSLF_WANT_CERT) iVerMode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; SSL_CTX_set_verify(pSCtx, iVerMode, BSslCertVerifyCB); if (pSSLB->iMaxDepth > 0) SSL_CTX_set_verify_depth(pSCtx, pSSLB->iMaxDepth); SSL_CTX_set_app_data(pSCtx, pSSLB); if (pSSLB->pszCAFile != NULL || pSSLB->pszCAPath != NULL) { if (!SSL_CTX_load_verify_locations(pSCtx, pSSLB->pszCAFile, pSSLB->pszCAPath)) { ErrSetErrorCode(ERR_SSL_VERPATHS); return ERR_SSL_VERPATHS; } } else if (!SSL_CTX_set_default_verify_paths(pSCtx)) { ErrSetErrorCode(ERR_SSL_VERPATHS); return ERR_SSL_VERPATHS; } } return 0; }
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; }
char *BSckChGetString(BSOCK_HANDLE hBSock, char *pszBuffer, int iMaxChars, int iTimeout, int *pLineLength, int *piGotNL) { int i; int iChar; for (i = 0, iMaxChars--; i < iMaxChars; i++) { iChar = BSckGetChar(hBSock, iTimeout); if (iChar == BSOCK_EOF) return NULL; if (iChar == '\n') { for (; (i > 0) && (pszBuffer[i - 1] == '\r'); i--); pszBuffer[i] = '\0'; if (pLineLength != NULL) *pLineLength = i; if (piGotNL != NULL) *piGotNL = 1; return pszBuffer; } else pszBuffer[i] = (char) iChar; } pszBuffer[i] = '\0'; if (pLineLength != NULL) *pLineLength = i; if (piGotNL != NULL) { *piGotNL = 0; return pszBuffer; } ErrSetErrorCode(ERR_LINE_TOO_LONG); return NULL; }
int HashGetFirst(HASH_HANDLE hHash, HashDatum const *pKey, HashEnum *pHEnum, HashNode **ppHNode) { Hash *pHash = (Hash *) hHash; unsigned long ulHIdx; SysListHead *pHead, *pPos; HashNode *pHNode; ulHIdx = (*pHash->Ops.pGetHashVal)(pHash->Ops.pPrivate, pKey) & pHash->ulHMask; pHead = &pHash->pBkts[ulHIdx]; for (pPos = SYS_LIST_FIRST(pHead); pPos != NULL; pPos = SYS_LIST_NEXT(pPos, pHead)) { pHNode = SYS_LIST_ENTRY(pPos, HashNode, Lnk); if ((*pHash->Ops.pCompare)(pHash->Ops.pPrivate, pKey, &pHNode->Key) == 0) { *ppHNode = pHNode; pHEnum->ulHIdx = ulHIdx; pHEnum->pNext = SYS_LIST_NEXT(pPos, pHead); return 0; } } ErrSetErrorCode(ERR_NOT_FOUND); return ERR_NOT_FOUND; }
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; }
static int BSckFetchData(BuffSocketData *pBSD, int iTimeout) { int iRdBytes; pBSD->iReadIndex = 0; if ((iRdBytes = BSOCK_READ(pBSD, pBSD->pszBuffer, pBSD->iBufferSize, iTimeout)) <= 0) { ErrSetErrorCode(ERR_SOCK_NOMORE_DATA); return iRdBytes; } pBSD->iBytesInBuffer = iRdBytes; return iRdBytes; }
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 HashFetchNext(Hash *pHash, unsigned long ulFrom, HashEnum *pHEnum, HashNode **ppHNode) { unsigned long i; SysListHead *pHead, *pPos; for (i = ulFrom; i <= pHash->ulHMask; i++) { pHead = &pHash->pBkts[i]; if ((pPos = SYS_LIST_FIRST(pHead)) != NULL) { pHEnum->ulHIdx = i; pHEnum->pNext = SYS_LIST_NEXT(pPos, pHead); *ppHNode = SYS_LIST_ENTRY(pPos, HashNode, Lnk); return 0; } } ErrSetErrorCode(ERR_NOT_FOUND); return ERR_NOT_FOUND; }
int HashGetNext(HASH_HANDLE hHash, HashDatum const *pKey, HashEnum *pHEnum, HashNode **ppHNode) { Hash *pHash = (Hash *) hHash; SysListHead *pPos, *pHead; HashNode *pHNode; pHead = &pHash->pBkts[pHEnum->ulHIdx]; for (pPos = pHEnum->pNext; pPos != NULL; pPos = SYS_LIST_NEXT(pPos, pHead)) { pHNode = SYS_LIST_ENTRY(pPos, HashNode, Lnk); if ((*pHash->Ops.pCompare)(pHash->Ops.pPrivate, pKey, &pHNode->Key) == 0) { *ppHNode = pHNode; pHEnum->pNext = SYS_LIST_NEXT(pPos, pHead); return 0; } } ErrSetErrorCode(ERR_NOT_FOUND); return ERR_NOT_FOUND; }
char *BSckGetString(BSOCK_HANDLE hBSock, char *pszBuffer, int iMaxChars, int iTimeout, int *pLineLength, int *piGotNL) { int i; BuffSocketData *pBSD = (BuffSocketData *) hBSock; for (i = 0, iMaxChars--; i < iMaxChars;) { /* Verify to have something to read */ if (pBSD->iBytesInBuffer == 0 && BSckFetchData(pBSD, iTimeout) <= 0) return NULL; int iBytesLookup = Min(pBSD->iBytesInBuffer, iMaxChars - i); if (iBytesLookup > 0) { char *pszNL = (char *) memchr(pBSD->pszBuffer + pBSD->iReadIndex, '\n', iBytesLookup); if (pszNL != NULL) { int iCopySize = (int) (pszNL - (pBSD->pszBuffer + pBSD->iReadIndex)); memcpy(pszBuffer + i, pBSD->pszBuffer + pBSD->iReadIndex, iCopySize); i += iCopySize; pBSD->iReadIndex += iCopySize + 1; pBSD->iBytesInBuffer -= iCopySize + 1; /* Line cleanup */ for (; i > 0 && pszBuffer[i - 1] == '\r'; i--); pszBuffer[i] = '\0'; if (pLineLength != NULL) *pLineLength = i; if (piGotNL != NULL) *piGotNL = 1; SysLogMessage(LOG_LEV_DEBUG, "socket read line: [%s]\n", pszBuffer); return pszBuffer; } else { memcpy(pszBuffer + i, pBSD->pszBuffer + pBSD->iReadIndex, iBytesLookup); i += iBytesLookup; pBSD->iReadIndex += iBytesLookup; pBSD->iBytesInBuffer -= iBytesLookup; } } } pszBuffer[i] = '\0'; if (pLineLength != NULL) *pLineLength = i; if (piGotNL != NULL) { *piGotNL = 0; SysLogMessage(LOG_LEV_DEBUG, "socket read line: [%s]\n", pszBuffer); return pszBuffer; } ErrSetErrorCode(ERR_LINE_TOO_LONG); return NULL; }
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; }