/*********** Invoke Forground Command *********************/ static void command_invoke(void *args) { void (*func)(void * ) ; int i,iteration ; func = (void(*)(void *))((func_args *)args)->argv[0] ; #ifdef HAVE_KEIL_RTX LockMutex((CyaSSL_Mutex *)&command_mutex) ; #endif iteration = for_iteration ; for(i=0; i< iteration; i++) { if(iteration > 1) printf("--- Start for %d ---->\n", i) ; #if defined(HAVE_KEIL_RTX) stack_fill(command_stack, COMMAND_STACK_SIZE) ; #endif func(args) ; /* invoke command */ #if defined(HAVE_KEIL_RTX) stack_check(command_stack, COMMAND_STACK_SIZE) ; #endif } if(iteration > 1) for_iteration = 1 ; #ifdef HAVE_KEIL_RTX UnLockMutex((CyaSSL_Mutex *)&command_mutex) ; os_tsk_delete_self() ; #endif }
static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request, OcspEntry** entry) { WOLFSSL_ENTER("GetOcspEntry"); *entry = NULL; if (LockMutex(&ocsp->ocspLock) != 0) { WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); return BAD_MUTEX_E; } for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next) if (XMEMCMP((*entry)->issuerHash, request->issuerHash, OCSP_DIGEST_SIZE) == 0 && XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE) == 0) break; if (*entry == NULL) { *entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL, DYNAMIC_TYPE_OCSP_ENTRY); if (*entry) { InitOcspEntry(*entry, request); (*entry)->next = ocsp->ocspList; ocsp->ocspList = *entry; } } UnLockMutex(&ocsp->ocspLock); return *entry ? 0 : MEMORY_ERROR; }
/* Add Decoded CRL, 0 on success */ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl) { CRL_Entry* crle; WOLFSSL_ENTER("AddCRL"); crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap, DYNAMIC_TYPE_CRL_ENTRY); if (crle == NULL) { WOLFSSL_MSG("alloc CRL Entry failed"); return -1; } if (InitCRL_Entry(crle, dcrl) < 0) { WOLFSSL_MSG("Init CRL Entry failed"); XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); return -1; } if (LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("LockMutex failed"); FreeCRL_Entry(crle, crl->heap); XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); return BAD_MUTEX_E; } crle->next = crl->crlList; crl->crlList = crle; UnLockMutex(&crl->crlLock); return 0; }
/*++ * Function: ICC_Logout * * Purpose: set the last logout time for an IMAP connection context. * * Parameters: char *Username * int server-side socket descriptor * * Returns: nada * * Authors: Dave McMurtrie <*****@*****.**> *-- */ extern void ICC_Logout( char *Username, ICD_Struct *conn ) { char *fn = "ICC_Logout()"; unsigned int HashIndex; ICC_Struct *HashEntry = NULL; ICC_Struct *ICC_Active = NULL; int rc; IMAPCount->InUseServerConnections--; IMAPCount->RetainedServerConnections++; if ( IMAPCount->RetainedServerConnections > IMAPCount->PeakRetainedServerConnections ) IMAPCount->PeakRetainedServerConnections = IMAPCount->RetainedServerConnections; HashIndex = Hash( Username, HASH_TABLE_SIZE ); LockMutex( &mp ); for ( HashEntry = ICC_HashTable[ HashIndex ]; HashEntry; HashEntry = HashEntry->next ) { if ( ( strcmp( Username, HashEntry->username ) == 0 ) && ( HashEntry->server_conn->sd == conn->sd ) ) { ICC_Active = HashEntry; } } if ( !ICC_Active ) { UnLockMutex( &mp ); syslog(LOG_WARNING, "%s: Cannot find ICC for '%s' on server sd %d to set logout time.", fn, Username, conn->sd ); return; } ICC_Active->logouttime = time(0); UnLockMutex( &mp ); syslog(LOG_INFO, "LOGOUT: '%s' from server sd [%d]", Username, conn->sd ); return; }
int wolfSSL_CryptHwMutexUnLock(void) { int ret = BAD_MUTEX_E; if(wcCryptHwMutexInit) { ret = UnLockMutex(&wcCryptHwMutex); } return ret; }
/*++ * Function: cmd_dumpicc * * Purpose: Dump the contents of all imap connection context structs. * * Parameters: ptr to ITD_Struct for client connection. * char ptr to Tag sent with this command. * * Returns: 0 on success * -1 on failure * * Authors: Dave McMurtrie <*****@*****.**> *-- */ static int cmd_dumpicc( ITD_Struct *itd, char *Tag ) { char *fn = "cmd_dumpicc"; char SendBuf[BUFSIZE]; unsigned int HashIndex; ICC_Struct *HashEntry; unsigned int BufLen = BUFSIZE - 1; SendBuf[BUFSIZE - 1] = '\0'; LockMutex( &mp ); for ( HashIndex = 0; HashIndex < HASH_TABLE_SIZE; HashIndex++ ) { HashEntry = ICC_HashTable[ HashIndex ]; while ( HashEntry ) { snprintf( SendBuf, BufLen, "* %d %s %s\r\n", HashEntry->server_conn->sd, HashEntry->username, ( ( HashEntry->logouttime ) ? "Cached" : "Active" ) ); if ( IMAP_Write( itd->conn, SendBuf, strlen(SendBuf) ) == -1 ) { UnLockMutex( &mp ); syslog(LOG_WARNING, "%s: IMAP_Write() failed: %s", fn, strerror(errno) ); return( -1 ); } HashEntry = HashEntry->next; } } UnLockMutex( &mp ); snprintf( SendBuf, BufLen, "%s OK Completed\r\n", Tag ); if ( IMAP_Write( itd->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_WARNING, "%s: IMAP_Write() failed: %s", fn, strerror(errno) ); return( -1 ); } return( 0 ); }
/********* SHEULL MAIN LOOP ***********************************/ void shell_main(void) { int i ; func_args args ; int bf_flg ; i = BackGround ; /* Dummy for avoiding warning: BackGround is defined but not used. */ #if defined(HAVE_KEIL_RTX) InitMutex(&command_mutex) ; #endif time_main(NULL) ; printf("Starting Shell\n") ; while(1) { if(getline(line, LINESIZE, &args, &bf_flg) > 0) { for(i=0; commandTable[i].func != NULL; i++) { if(strcmp(commandTable[i].command, args.argv[0]) == 0) { args.argv[0] = (char *) commandTable[i].func ; if(bf_flg == FORGROUND) { #ifdef HAVE_KEIL_RTX UnLockMutex((CyaSSL_Mutex *)&command_mutex) ; os_tsk_create_user_ex( (void(*)(void *))&command_invoke, 7, command_stack, COMMAND_STACK_SIZE, &args) ; #else command_invoke(&args) ; #endif #ifdef HAVE_KEIL_RTX LockMutex((CyaSSL_Mutex *)&command_mutex) ; #endif } else { #if (!defined(NO_SIMPLE_SERVER) && \ !defined(NO_ECHOSERVER)) && \ defined(HAVE_KEIL_RTX) if(BackGround != 0) { printf("Multiple background servers not supported.\n") ; } else { printf("\"%s\" is running with the background mode.\n", commandTable[i].command) ; os_tsk_create_user_ex( (void(*)(void *))&bg_job_invoke, 6, bg_job_stack, BG_JOB_STACK_SIZE, &args) ; } #else printf("Invalid Command: no background job\n") ; #endif } break ; } } if(commandTable[i].func == NULL) printf("Command not found\n") ; } } }
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, OcspEntry* entry, CertStatus** status, buffer* responseBuffer) { int ret = OCSP_INVALID_STATUS; WOLFSSL_ENTER("GetOcspStatus"); *status = NULL; if (LockMutex(&ocsp->ocspLock) != 0) { WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); return BAD_MUTEX_E; } for (*status = entry->status; *status; *status = (*status)->next) if ((*status)->serialSz == request->serialSz && !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz)) break; if (responseBuffer && *status && !(*status)->rawOcspResponse) { /* force fetching again */ ret = OCSP_INVALID_STATUS; } else if (*status) { if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE) && ((*status)->nextDate[0] != 0) && ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER)) { ret = xstat2err((*status)->status); if (responseBuffer) { responseBuffer->buffer = (byte*)XMALLOC( (*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (responseBuffer->buffer) { responseBuffer->length = (*status)->rawOcspResponseSz; XMEMCPY(responseBuffer->buffer, (*status)->rawOcspResponse, (*status)->rawOcspResponseSz); } } } } UnLockMutex(&ocsp->ocspLock); return ret; }
/* read in new CRL entries and save new list */ static int SwapLists(CYASSL_CRL* crl) { int ret; CYASSL_CRL tmp; CRL_Entry* newList; if (InitCRL(&tmp, crl->cm) < 0) { CYASSL_MSG("Init tmp CRL failed"); return -1; } if (crl->monitors[0].path) { ret = LoadCRL(&tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0); if (ret != SSL_SUCCESS) { CYASSL_MSG("PEM LoadCRL on dir change failed"); FreeCRL(&tmp, 0); return -1; } } if (crl->monitors[1].path) { ret = LoadCRL(&tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0); if (ret != SSL_SUCCESS) { CYASSL_MSG("DER LoadCRL on dir change failed"); FreeCRL(&tmp, 0); return -1; } } if (LockMutex(&crl->crlLock) != 0) { CYASSL_MSG("LockMutex failed"); FreeCRL(&tmp, 0); return -1; } newList = tmp.crlList; /* swap lists */ tmp.crlList = crl->crlList; crl->crlList = newList; UnLockMutex(&crl->crlLock); FreeCRL(&tmp, 0); return 0; }
/* Start Monitoring the CRL path(s) in a thread */ static int StartMonitorCRL(WOLFSSL_CRL* crl) { int ret = SSL_SUCCESS; WOLFSSL_ENTER("StartMonitorCRL"); if (crl == NULL) return BAD_FUNC_ARG; if (crl->tid != 0) { WOLFSSL_MSG("Monitor thread already running"); return ret; /* that's ok, someone already started */ } if (pthread_create(&crl->tid, NULL, DoMonitor, crl) != 0) { WOLFSSL_MSG("Thread creation error"); return THREAD_CREATE_E; } /* wait for setup to complete */ if (LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("LockMutex crlLock error"); return BAD_MUTEX_E; } while (crl->setup == 0) { if (pthread_cond_wait(&crl->cond, &crl->crlLock) != 0) { ret = BAD_COND_E; break; } } if (crl->setup < 0) ret = crl->setup; /* store setup error */ UnLockMutex(&crl->crlLock); if (ret < 0) { WOLFSSL_MSG("DoMonitor setup failure"); crl->tid = 0; /* thread already done */ } return ret; }
/* Signal Monitor thread is setup, save status to setup flag, 0 on success */ static int SignalSetup(WOLFSSL_CRL* crl, int status) { int ret; /* signal to calling thread we're setup */ if (LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("LockMutex crlLock failed"); return BAD_MUTEX_E; } crl->setup = status; ret = pthread_cond_signal(&crl->cond); UnLockMutex(&crl->crlLock); if (ret != 0) return BAD_COND_E; return 0; }
/*++ * Function: Get_Server_sd * * Purpose: When a client login attempt is made, fetch a usable server * socket descriptor. This means that either we reuse an * existing sd, or we open a new one. Hide that abstraction from * the caller... * * Parameters: ptr to username string * ptr to password string * const ptr to client hostname or IP string (for logging only) * * Returns: int sd on success * -1 on failure * * Authors: dgm * *-- */ extern int Get_Server_sd( char *Username, char *Password, const char *ClientAddr ) { char *fn = "Get_Server_sd()"; unsigned int HashIndex; ICC_Struct *HashEntry = NULL; char SendBuf[BUFSIZE]; unsigned int BufLen = BUFSIZE - 1; char md5pw[16]; char *tokenptr; char *endptr; char *last; ICC_Struct *ICC_Active; ICC_Struct *ICC_tptr; ITD_Struct Server; int rc; unsigned int Expiration; Expiration = PC_Struct.cache_expiration_time; memset( &Server, 0, sizeof Server ); /* need to md5 the passwd regardless, so do that now */ md5_calc( md5pw, Password, strlen( Password ) ); /* see if we have a reusable connection available */ ICC_Active = NULL; HashIndex = Hash( Username, HASH_TABLE_SIZE ); LockMutex( &mp ); /* * Now we just iterate through the linked list at this hash index until * we either find the string we're looking for or we find a NULL. */ for ( HashEntry = ICC_HashTable[ HashIndex ]; HashEntry; HashEntry = HashEntry->next ) { if ( ( strcmp( Username, HashEntry->username ) == 0 ) && ( HashEntry->logouttime > 1 ) ) { ICC_Active = HashEntry; /* * we found this username in our hash table. Need to know if * the password matches. */ if ( memcmp( md5pw, ICC_Active->hashedpw, sizeof md5pw ) ) { /* the passwords don't match. Shake this guy. */ UnLockMutex( &mp ); syslog(LOG_INFO, "LOGIN: '******' (%s) failed: password incorrect", Username, ClientAddr ); return( -1 ); } /* * We found a matching password on an inactive server socket. We * can use this guy. Before we release the mutex, set the * logouttime such that we mark this connection as "active" again. */ ICC_Active->logouttime = 0; /* * The fact that we have this stored in a table as an open server * socket doesn't really mean that it's open. The server could've * closed it on us. * We need a speedy way to make sure this is still open. * We'll set the fd to non-blocking and try to read from it. If we * get a zero back, the connection is closed. If we get * EWOULDBLOCK (or some data) we know it's still open. If we do * read data, make sure we read all the data so we "drain" any * puss that may be left on this socket. */ fcntl( ICC_Active->server_sd, F_SETFL, fcntl( ICC_Active->server_sd, F_GETFL, 0) | O_NONBLOCK ); while ( ( rc = recv( ICC_Active->server_sd, Server.ReadBuf, sizeof Server.ReadBuf, 0 ) ) > 0 ); if ( !rc ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s). Connection closed by server.", fn, ICC_Active->server_sd, Username, ClientAddr ); ICC_Active->logouttime = 1; continue; } if ( errno != EWOULDBLOCK ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s). recv() error: %s", fn, ICC_Active->server_sd, Username, ClientAddr, strerror( errno ) ); ICC_Active->logouttime = 1; continue; } fcntl( ICC_Active->server_sd, F_SETFL, fcntl( ICC_Active->server_sd, F_GETFL, 0) & ~O_NONBLOCK ); /* now release the mutex and return the sd to the caller */ UnLockMutex( &mp ); /* * We're reusing an existing server socket. There are a few * counters we have to deal with. */ IMAPCount->RetainedServerConnections--; IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsReused++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s) on existing sd [%d]", Username, ClientAddr, ICC_Active->server_sd ); return( ICC_Active->server_sd ); } } UnLockMutex( &mp ); /* * We don't have an active connection for this user. * Open a connection to the IMAP server so we can attempt to login */ Server.sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( Server.sd == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Unable to open server socket: %s", Username, ClientAddr, strerror( errno ) ); return( -1 ); } if ( connect( Server.sd, (struct sockaddr *)&ISD.srv, sizeof(ISD.srv) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Unable to connect to IMAP server: %s", Username, ClientAddr, strerror( errno ) ); close( Server.sd ); return( -1 ); } /* Read & throw away the banner line from the server */ if ( IMAP_Line_Read( &Server ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: No banner line received from IMAP server", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Send the login command off to the IMAP server. */ snprintf( SendBuf, BufLen, "A0001 LOGIN %s %s\r\n", Username, Password ); if ( send( Server.sd, SendBuf, strlen(SendBuf), 0 ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: send() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, strerror( errno ) ); close( Server.sd ); return( -1 ); } /* * Read the server response */ if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: No response from IMAP server after sending LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Try to match up the tag in the server response to the client tag. */ endptr = Server.ReadBuf + rc; tokenptr = memtok( Server.ReadBuf, endptr, &last ); if ( !tokenptr ) { /* * no tokens found in server response? Not likely, but we still * have to check. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: server response to LOGIN command contained no tokens.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } if ( memcmp( (const void *)tokenptr, (const void *)"A0001", strlen( tokenptr ) ) ) { /* * non-matching tag read back from the server... Lord knows what this * is, so we'll fail. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: server response to LOGIN command contained non-matching tag.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * Now that we've matched the tags up, see if the response was 'OK' */ tokenptr = memtok( NULL, endptr, &last ); if ( !tokenptr ) { /* again, not likely but we still have to check... */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Malformed server response to LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } if ( memcmp( (const void *)tokenptr, "OK", 2 ) ) { /* * If the server sent back a "NO" or "BAD", we can look at the actual * server logs to figure out why. We don't have to break our ass here * putting the string back together just for the sake of logging. */ syslog(LOG_INFO, "LOGIN: '******' (%s) failed: non-OK server response to LOGIN command", Username, ClientAddr ); close( Server.sd ); return( -1 ); } /* * put this in our used list and remove it from the free list */ for( ; ; ) { LockMutex( &mp ); if ( ICC_free->next ) { /* generate the hash index */ HashIndex = Hash( Username, HASH_TABLE_SIZE ); /* temporarily store the address of the next free structure */ ICC_tptr = ICC_free->next; /* * We want to add the newest "used" structure at the front of * the list at the hash index. */ ICC_free->next = ICC_HashTable[ HashIndex ]; ICC_HashTable[ HashIndex ] = ICC_free; /* * less typing and more readability, set an "active" pointer. */ ICC_Active = ICC_free; /* now point the free listhead to the next available free struct */ ICC_free = ICC_tptr; /* fill in the newest used (oxymoron?) structure */ strncpy( ICC_Active->username, Username, sizeof ICC_Active->username ); memcpy( ICC_Active->hashedpw, md5pw, sizeof ICC_Active->hashedpw ); ICC_Active->logouttime = 0; /* zero means, "it's active". */ ICC_Active->server_sd = Server.sd; UnLockMutex( &mp ); IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsCreated++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s) on new sd [%d]", Username, ClientAddr, Server.sd ); return( Server.sd ); } /* * There weren't any free ICC structs. Try to free one. Make sure * we unlock the mutex, since ICC_Recycle needs to obtain it. */ UnLockMutex( &mp ); Expiration = abs( Expiration / 2 ); /* * Eventually, we have to fail */ if ( Expiration <= 2 ) { syslog(LOG_INFO, "LOGIN: '******' (%s) failed: Out of free ICC structs.", Username, ClientAddr ); close( Server.sd ); return( -1 ); } ICC_Recycle( Expiration ); } }
/*++ * Function: Get_Server_conn * * Purpose: When a client login attempt is made, fetch a usable server * connection descriptor. This means that either we reuse an * existing ICD, or we open a new one. Hide that abstraction from * the caller... * * Parameters: ptr to username string * ptr to password string * const ptr to client hostname or IP string (for logging only) * in_port_t, client port number (for logging only) * unsigned char - flag to indicate that the client sent the * password as a string literal. * * Returns: ICD * on success * NULL on failure * * Authors: Dave McMurtrie <*****@*****.**> * * Credit: Major SSL additions by Ken Murchison <*****@*****.**> * *-- */ extern ICD_Struct *Get_Server_conn( char *Username, char *Password, const char *ClientAddr, in_port_t sin_port, unsigned char LiteralPasswd ) { char *fn = "Get_Server_conn()"; unsigned int HashIndex; ICC_Struct *HashEntry = NULL; char SendBuf[BUFSIZE]; unsigned int BufLen = BUFSIZE - 1; char md5pw[MD5_DIGEST_LENGTH]; char *tokenptr; char *endptr; char *last; ICC_Struct *ICC_Active; ICC_Struct *ICC_tptr; ITD_Struct Server; int rc; unsigned int Expiration; EVP_MD_CTX mdctx; int md_len; Expiration = PC_Struct.cache_expiration_time; memset( &Server, 0, sizeof Server ); /* need to md5 the passwd regardless, so do that now */ EVP_DigestInit(&mdctx, EVP_md5()); EVP_DigestUpdate(&mdctx, Password, strlen(Password)); EVP_DigestFinal(&mdctx, md5pw, &md_len); /* see if we have a reusable connection available */ ICC_Active = NULL; HashIndex = Hash( Username, HASH_TABLE_SIZE ); LockMutex( &mp ); /* * Now we just iterate through the linked list at this hash index until * we either find the string we're looking for or we find a NULL. */ for ( HashEntry = ICC_HashTable[ HashIndex ]; HashEntry; HashEntry = HashEntry->next ) { if ( ( strcmp( Username, HashEntry->username ) == 0 ) && ( HashEntry->logouttime > 1 ) ) { ICC_Active = HashEntry; /* * we found this username in our hash table. Need to know if * the password matches. */ if ( memcmp( md5pw, ICC_Active->hashedpw, sizeof md5pw ) ) { syslog( LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d) because password doesn't match.", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port ); ICC_Active->logouttime = 1; } else { /* * We found a matching password on an inactive server socket. * We can use this guy. Before we release the mutex, set the * logouttime such that we mark this connection as "active" * again. */ ICC_Active->logouttime = 0; /* * The fact that we have this stored in a table as an open * server socket doesn't really mean that it's open. The * server could've closed it on us. * We need a speedy way to make sure this is still open. * We'll set the fd to non-blocking and try to read from it. * If we get a zero back, the connection is closed. If we get * EWOULDBLOCK (or some data) we know it's still open. If we * do read data, make sure we read all the data so we "drain" * any puss that may be left on this socket. */ fcntl( ICC_Active->server_conn->sd, F_SETFL, fcntl( ICC_Active->server_conn->sd, F_GETFL, 0) | O_NONBLOCK ); while ( ( rc = IMAP_Read( ICC_Active->server_conn, Server.ReadBuf, sizeof Server.ReadBuf ) ) > 0 ); if ( !rc ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d). Connection closed by server.", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port ); ICC_Active->logouttime = 1; continue; } if ( errno != EWOULDBLOCK ) { syslog(LOG_NOTICE, "%s: Unable to reuse server sd [%d] for user '%s' (%s:%d). IMAP_read() error: %s", fn, ICC_Active->server_conn->sd, Username, ClientAddr, sin_port, strerror( errno ) ); ICC_Active->logouttime = 1; continue; } fcntl( ICC_Active->server_conn->sd, F_SETFL, fcntl( ICC_Active->server_conn->sd, F_GETFL, 0) & ~O_NONBLOCK ); /* now release the mutex and return the sd to the caller */ UnLockMutex( &mp ); /* * We're reusing an existing server socket. There are a few * counters we have to deal with. */ IMAPCount->RetainedServerConnections--; IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsReused++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s:%d) on existing sd [%d]", Username, ClientAddr, sin_port, ICC_Active->server_conn->sd ); return( ICC_Active->server_conn ); } } } UnLockMutex( &mp ); /* * We don't have an active connection for this user, or the password * didn't match. * Open a connection to the IMAP server so we can attempt to login */ Server.conn = ( ICD_Struct * ) malloc( sizeof ( ICD_Struct ) ); memset( Server.conn, 0, sizeof ( ICD_Struct ) ); Server.conn->sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( Server.conn->sd == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Unable to open server socket: %s", Username, ClientAddr, sin_port, strerror( errno ) ); goto fail; } if ( PC_Struct.send_tcp_keepalives ) { int onoff = 1; setsockopt( Server.conn->sd, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof onoff ); } if ( connect( Server.conn->sd, (struct sockaddr *)&ISD.srv, sizeof(ISD.srv) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Unable to connect to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) ); goto fail; } /* Read & throw away the banner line from the server */ if ( IMAP_Line_Read( &Server ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: No banner line received from IMAP server", Username, ClientAddr, sin_port ); goto fail; } /* * Do STARTTLS if necessary. */ #if HAVE_LIBSSL if ( PC_Struct.login_disabled ) { snprintf( SendBuf, BufLen, "S0001 STARTTLS\r\n" ); if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_INFO, "STARTTLS failed: IMAP_Write() failed attempting to send STARTTLS command to IMAP server: %s", strerror( errno ) ); goto fail; } /* * Read the server response */ if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 ) { syslog(LOG_INFO, "STARTTLS failed: No response from IMAP server after sending STARTTLS command" ); goto fail; } /* * Try to match up the tag in the server response to the client tag. */ endptr = Server.ReadBuf + rc; tokenptr = memtok( Server.ReadBuf, endptr, &last ); if ( !tokenptr ) { /* * no tokens found in server response? Not likely, but we still * have to check. */ syslog(LOG_INFO, "STARTTLS failed: server response to STARTTLS command contained no tokens." ); goto fail; } if ( memcmp( (const void *)tokenptr, (const void *)"S0001", strlen( tokenptr ) ) ) { /* * non-matching tag read back from the server... Lord knows what this * is, so we'll fail. */ syslog(LOG_INFO, "STARTTLS failed: server response to STARTTLS command contained non-matching tag." ); goto fail; } /* * Now that we've matched the tags up, see if the response was 'OK' */ tokenptr = memtok( NULL, endptr, &last ); if ( !tokenptr ) { /* again, not likely but we still have to check... */ syslog(LOG_INFO, "STARTTLS failed: Malformed server response to STARTTLS command" ); goto fail; } if ( memcmp( (const void *)tokenptr, "OK", 2 ) ) { /* * If the server sent back a "NO" or "BAD", we can look at the actual * server logs to figure out why. We don't have to break our ass here * putting the string back together just for the sake of logging. */ syslog(LOG_INFO, "STARTTLS failed: non-OK server response to STARTTLS command" ); goto fail; } Server.conn->tls = SSL_new( tls_ctx ); if ( Server.conn->tls == NULL ) { syslog(LOG_INFO, "STARTTLS failed: SSL_new() failed" ); goto fail; } SSL_clear( Server.conn->tls ); rc = SSL_set_fd( Server.conn->tls, Server.conn->sd ); if ( rc == 0 ) { syslog(LOG_INFO, "STARTTLS failed: SSL_set_fd() failed: %d", SSL_get_error( Server.conn->tls, rc ) ); goto fail; } SSL_set_connect_state( Server.conn->tls ); rc = SSL_connect( Server.conn->tls ); if ( rc <= 0 ) { syslog(LOG_INFO, "STARTTLS failed: SSL_connect() failed, %d: %s", SSL_get_error( Server.conn->tls, rc ), SSLerrmessage() ); goto fail; } /* XXX Should we grab the session id for later reuse? */ } #endif /* HAVE_LIBSSL */ /* * Send the login command off to the IMAP server. Have to treat a literal * password different. */ if ( LiteralPasswd ) { snprintf( SendBuf, BufLen, "A0001 LOGIN %s {%d}\r\n", Username, strlen( Password ) ); if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) ); goto fail; } /* * the server response should be a go ahead */ if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Failed to receive go-ahead from IMAP server after sending LOGIN command", Username, ClientAddr, sin_port ); goto fail; } if ( Server.ReadBuf[0] != '+' ) { syslog( LOG_INFO, "LOGIN: '******' (%s:%d) failed: bad response from server after sending string literal specifier", Username, ClientAddr, sin_port ); goto fail; } /* * now send the password */ snprintf( SendBuf, BufLen, "%s\r\n", Password ); if ( IMAP_Write( Server.conn, SendBuf, strlen( SendBuf ) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send literal password to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) ); goto fail; } } else { /* * just send the login command via normal means. */ snprintf( SendBuf, BufLen, "A0001 LOGIN %s %s\r\n", Username, Password ); if ( IMAP_Write( Server.conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: IMAP_Write() failed attempting to send LOGIN command to IMAP server: %s", Username, ClientAddr, sin_port, strerror( errno ) ); goto fail; } } /* * Read the server response. From RFC 3501: * * A server MAY include a CAPABILITY response code in the tagged OK * response to a successful LOGIN command in order to send * capabilities automatically. It is unnecessary for a client to * send a separate CAPABILITY command if it recognizes these * automatic capabilities. * * We have to be ready for the possibility that this might be an * untagged response... In an ideal world, we'd want to pass the * untagged stuff back to the client. For now, since the RFC doesn't * mandate that behaviour, we're not going to since we don't have a client * socket descriptor to send it to. */ for ( ;; ) { if ( ( rc = IMAP_Line_Read( &Server ) ) == -1 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: No response from IMAP server after sending LOGIN command", Username, ClientAddr, sin_port ); goto fail; } if ( Server.ReadBuf[0] != '*' ) break; } /* * Try to match up the tag in the server response to the client tag. */ endptr = Server.ReadBuf + rc; tokenptr = memtok( Server.ReadBuf, endptr, &last ); if ( !tokenptr ) { /* * no tokens found in server response? Not likely, but we still * have to check. */ syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: server response to LOGIN command contained no tokens.", Username, ClientAddr, sin_port ); goto fail; } if ( memcmp( (const void *)tokenptr, (const void *)"A0001", strlen( tokenptr ) ) ) { /* * non-matching tag read back from the server... Lord knows what this * is, so we'll fail. */ syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: server response to LOGIN command contained non-matching tag.", Username, ClientAddr, sin_port ); goto fail; } /* * Now that we've matched the tags up, see if the response was 'OK' */ tokenptr = memtok( NULL, endptr, &last ); if ( !tokenptr ) { /* again, not likely but we still have to check... */ syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Malformed server response to LOGIN command", Username, ClientAddr, sin_port ); goto fail; } if ( memcmp( (const void *)tokenptr, "OK", 2 ) ) { /* * If the server sent back a "NO" or "BAD", we can look at the actual * server logs to figure out why. We don't have to break our ass here * putting the string back together just for the sake of logging. */ syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: non-OK server response to LOGIN command", Username, ClientAddr, sin_port ); goto fail; } /* * put this in our used list and remove it from the free list */ for( ; ; ) { LockMutex( &mp ); if ( ICC_free->next ) { /* generate the hash index */ HashIndex = Hash( Username, HASH_TABLE_SIZE ); /* temporarily store the address of the next free structure */ ICC_tptr = ICC_free->next; /* * We want to add the newest "used" structure at the front of * the list at the hash index. */ ICC_free->next = ICC_HashTable[ HashIndex ]; ICC_HashTable[ HashIndex ] = ICC_free; /* * less typing and more readability, set an "active" pointer. */ ICC_Active = ICC_free; /* now point the free listhead to the next available free struct */ ICC_free = ICC_tptr; /* fill in the newest used (oxymoron?) structure */ strncpy( ICC_Active->username, Username, sizeof ICC_Active->username ); memcpy( ICC_Active->hashedpw, md5pw, sizeof ICC_Active->hashedpw ); ICC_Active->logouttime = 0; /* zero means, "it's active". */ ICC_Active->server_conn = Server.conn; UnLockMutex( &mp ); IMAPCount->InUseServerConnections++; IMAPCount->TotalServerConnectionsCreated++; if ( IMAPCount->InUseServerConnections > IMAPCount->PeakInUseServerConnections ) IMAPCount->PeakInUseServerConnections = IMAPCount->InUseServerConnections; syslog(LOG_INFO, "LOGIN: '******' (%s:%d) on new sd [%d]", Username, ClientAddr, sin_port, Server.conn->sd ); return( Server.conn ); } /* * There weren't any free ICC structs. Try to free one. Make sure * we unlock the mutex, since ICC_Recycle needs to obtain it. */ UnLockMutex( &mp ); Expiration = abs( Expiration / 2 ); /* * Eventually, we have to fail */ if ( Expiration <= 2 ) { syslog(LOG_INFO, "LOGIN: '******' (%s:%d) failed: Out of free ICC structs.", Username, ClientAddr, sin_port ); goto fail; } ICC_Recycle( Expiration ); } fail: #if HAVE_LIBSSL if ( Server.conn->tls ) { SSL_shutdown( Server.conn->tls ); SSL_free( Server.conn->tls ); } #endif close( Server.conn->sd ); free( Server.conn ); return( NULL ); }
/*----------------------------------------------------------------------------- Name : globalsReset Description : resets the globals.c variables Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void globalsResetFunc(bool firstTime) { udword i = 0; if (firstTime) { gMessageMutex = gameCreateMutex(); } gameIsRunning = FALSE; multiPlayerGame = FALSE; multiPlayerGameUnderWay = FALSE; singlePlayerGame = FALSE; tutorial = 0; tutorialdone = FALSE; sigsPressedStartGame = FALSE; sigsNumPlayers = 0; sigsPlayerIndex = 0; captainIndex = -1; captainProposal = 1; captainTransferState = 0; receiveSyncPacketsFrom = 0; startRecordingGameWhenSafe = FALSE; aiCurrentAIPlayer = NULL; hrAbortLoadingGame = FALSE; mrRenderMainScreen = TRUE; explicitlyRequestingPackets = FALSE; explicitlyRequestingFrom = 0; explicitlyRequestingTo = 0; startingGameState = 0; startingGame = FALSE; HaveSentNonCaptainReadyPacket = FALSE; numPlayers = 0; curPlayer = 0; universePause = FALSE; #if UNIVERSE_TURBOPAUSE_DEBUG universeTurbo = FALSE; #endif LockMutex(gMessageMutex); while (i < MAX_MESSAGES) { gMessage[i].MessageExpire = (real32)0; gMessage[i].message[0] = (char)NULL; i++; } UnLockMutex(gMessageMutex); for (i=0;i<MAX_BIGMESSAGES;i++) { bMessage[i].messageOn = FALSE; bMessage[i].message[0] = (char)0; } for (i=0;i<MAX_MULTIPLAYER_PLAYERS;i++) { playersReadyToGo[i] = FALSE; } CommandNetworkReset(); netcheckReset(); if (!firstTime) { profReset(); for (i=0;i<MAX_MULTIPLAYER_PLAYERS;i++) { ComputerPlayerEnabled[i] = FALSE; ComputerPlayerOn[i] = -1; } recordPackets = FALSE; playPackets = FALSE; recordplayPacketsInGame = FALSE; recordFakeSendPackets = FALSE; smGhostMode = FALSE; } else { profInit(); } }
int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert) { byte* ocspReqBuf = NULL; int ocspReqSz = 2048; byte* ocspRespBuf = NULL; OcspRequest ocspRequest; OcspResponse ocspResponse; int result = -1; OCSP_Entry* ocspe; CertStatus* certStatus = NULL; CertStatus newStatus; const char *url; int urlSz; CYASSL_ENTER("CheckCertOCSP"); if (LockMutex(&ocsp->ocspLock) != 0) { CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E); return BAD_MUTEX_E; } ocspe = ocsp->ocspList; while (ocspe) { if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0 && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE) == 0) break; else ocspe = ocspe->next; } if (ocspe == NULL) { ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry), NULL, DYNAMIC_TYPE_OCSP_ENTRY); if (ocspe != NULL) { InitOCSP_Entry(ocspe, cert); ocspe->next = ocsp->ocspList; ocsp->ocspList = ocspe; } else { UnLockMutex(&ocsp->ocspLock); CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_ERROR; } } else { certStatus = ocspe->status; while (certStatus) { if (certStatus->serialSz == cert->serialSz && XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0) break; else certStatus = certStatus->next; } } if (certStatus != NULL) { if (!ValidateDate(certStatus->thisDate, certStatus->thisDateFormat, BEFORE) || (certStatus->nextDate[0] == 0) || !ValidateDate(certStatus->nextDate, certStatus->nextDateFormat, AFTER)) { CYASSL_MSG("\tinvalid status date, looking up cert"); } else { result = xstat2err(certStatus->status); UnLockMutex(&ocsp->ocspLock); CYASSL_LEAVE("CheckCertOCSP", result); return result; } } UnLockMutex(&ocsp->ocspLock); if (ocsp->cm->ocspUseOverrideURL) { url = ocsp->cm->ocspOverrideURL; if (url != NULL && url[0] != '\0') urlSz = (int)XSTRLEN(url); else return OCSP_NEED_URL; } else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) { url = (const char *)cert->extAuthInfo; urlSz = cert->extAuthInfoSz; } else { /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ return 0; } ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); if (ocspReqBuf == NULL) { CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_ERROR; } InitOcspRequest(&ocspRequest, cert, ocsp->cm->ocspSendNonce, ocspReqBuf, ocspReqSz); ocspReqSz = EncodeOcspRequest(&ocspRequest); if (ocsp->cm->ocspIOCb) result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, ocspReqBuf, ocspReqSz, &ocspRespBuf); if (result >= 0 && ocspRespBuf) { XMEMSET(&newStatus, 0, sizeof(CertStatus)); InitOcspResponse(&ocspResponse, &newStatus, ocspRespBuf, result); OcspResponseDecode(&ocspResponse); if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) result = OCSP_LOOKUP_FAIL; else { if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) { result = xstat2err(ocspResponse.status->status); if (LockMutex(&ocsp->ocspLock) != 0) result = BAD_MUTEX_E; else { if (certStatus != NULL) /* Replace existing certificate entry with updated */ XMEMCPY(certStatus, &newStatus, sizeof(CertStatus)); else { /* Save new certificate entry */ certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, DYNAMIC_TYPE_OCSP_STATUS); if (certStatus != NULL) { XMEMCPY(certStatus, &newStatus, sizeof(CertStatus)); certStatus->next = ocspe->status; ocspe->status = certStatus; ocspe->totalStatus++; } } UnLockMutex(&ocsp->ocspLock); } } else result = OCSP_LOOKUP_FAIL; } } else result = OCSP_LOOKUP_FAIL; if (ocspReqBuf != NULL) XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb) ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf); CYASSL_LEAVE("CheckCertOCSP", result); return result; }
/* read in new CRL entries and save new list */ static int SwapLists(WOLFSSL_CRL* crl) { int ret; CRL_Entry* newList; #ifdef WOLFSSL_SMALL_STACK WOLFSSL_CRL* tmp; #else WOLFSSL_CRL tmp[1]; #endif #ifdef WOLFSSL_SMALL_STACK tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return MEMORY_E; #endif if (InitCRL(tmp, crl->cm) < 0) { WOLFSSL_MSG("Init tmp CRL failed"); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return -1; } if (crl->monitors[0].path) { ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0); if (ret != SSL_SUCCESS) { WOLFSSL_MSG("PEM LoadCRL on dir change failed"); FreeCRL(tmp, 0); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return -1; } } if (crl->monitors[1].path) { ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0); if (ret != SSL_SUCCESS) { WOLFSSL_MSG("DER LoadCRL on dir change failed"); FreeCRL(tmp, 0); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return -1; } } if (LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("LockMutex failed"); FreeCRL(tmp, 0); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return -1; } newList = tmp->crlList; /* swap lists */ tmp->crlList = crl->crlList; crl->crlList = newList; UnLockMutex(&crl->crlLock); FreeCRL(tmp, 0); #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return 0; }
void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) #endif { void* res = 0; wc_Memory* pt = NULL; word32 prvSz; int i; /* check for testing heap hint was set */ #ifdef WOLFSSL_HEAP_TEST if (heap == (void*)WOLFSSL_HEAP_TEST) { return realloc(ptr, size); } #endif if (heap == NULL) { #ifdef WOLFSSL_HEAP_TEST WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n"); #endif #ifndef WOLFSSL_NO_MALLOC res = realloc(ptr, size); #else WOLFSSL_MSG("NO heap found to use for realloc"); #endif /* WOLFSSL_NO_MALLOC */ } else { WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; WOLFSSL_HEAP* mem = hint->memory; word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); if (LockMutex(&(mem->memory_mutex)) != 0) { WOLFSSL_MSG("Bad memory_mutex lock"); return NULL; } /* case of using fixed IO buffers or IO pool */ if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED)) && (type == DYNAMIC_TYPE_OUT_BUFFER || type == DYNAMIC_TYPE_IN_BUFFER)) { /* no realloc, is fixed size */ pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory)); if (pt->sz < size) { WOLFSSL_MSG("Error IO memory was not large enough"); res = NULL; /* return NULL in error case */ } res = pt->buffer; } else { /* general memory */ for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { if ((word32)size < mem->sizeList[i]) { if (mem->ava[i] != NULL) { pt = mem->ava[i]; mem->ava[i] = pt->next; break; } } } if (pt != NULL && res == NULL) { res = pt->buffer; /* copy over original information and free ptr */ prvSz = ((wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory)))->sz; prvSz = (prvSz > pt->sz)? pt->sz: prvSz; XMEMCPY(pt->buffer, ptr, prvSz); mem->inUse += pt->sz; mem->alloc += 1; /* free memory that was previously being used */ UnLockMutex(&(mem->memory_mutex)); wolfSSL_Free(ptr, heap, type #ifdef WOLFSSL_DEBUG_MEMORY , func, line #endif ); if (LockMutex(&(mem->memory_mutex)) != 0) { WOLFSSL_MSG("Bad memory_mutex lock"); return NULL; } } } UnLockMutex(&(mem->memory_mutex)); } #ifdef WOLFSSL_MALLOC_CHECK if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { WOLFSSL_MSG("ERROR memory is not alligned"); res = NULL; } #endif (void)i; (void)pt; (void)type; return res; }
/* Is the cert ok with CRL, return 0 on success */ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert) { CRL_Entry* crle; int foundEntry = 0; int ret = 0; WOLFSSL_ENTER("CheckCertCRL"); if (LockMutex(&crl->crlLock) != 0) { WOLFSSL_MSG("LockMutex failed"); return BAD_MUTEX_E; } crle = crl->crlList; while (crle) { if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) { int doNextDate = 1; WOLFSSL_MSG("Found CRL Entry on list"); WOLFSSL_MSG("Checking next date validity"); #ifdef WOLFSSL_NO_CRL_NEXT_DATE if (crle->nextDateFormat == ASN_OTHER_TYPE) doNextDate = 0; /* skip */ #endif if (doNextDate && !ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) { WOLFSSL_MSG("CRL next date is no longer valid"); ret = ASN_AFTER_DATE_E; } else foundEntry = 1; break; } crle = crle->next; } if (foundEntry) { RevokedCert* rc = crle->certs; while (rc) { if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) { WOLFSSL_MSG("Cert revoked"); ret = CRL_CERT_REVOKED; break; } rc = rc->next; } } UnLockMutex(&crl->crlLock); if (foundEntry == 0) { WOLFSSL_MSG("Couldn't find CRL for status check"); ret = CRL_MISSING; if (crl->cm->cbMissingCRL) { char url[256]; WOLFSSL_MSG("Issuing missing CRL callback"); url[0] = '\0'; if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) { XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz); url[cert->extCrlInfoSz] = '\0'; } else { WOLFSSL_MSG("CRL url too long"); } crl->cm->cbMissingCRL(url); } } return ret; }
void wolfSSL_Free(void *ptr, void* heap, int type) #endif { int i; wc_Memory* pt; if (ptr) { /* check for testing heap hint was set */ #ifdef WOLFSSL_HEAP_TEST if (heap == (void*)WOLFSSL_HEAP_TEST) { return free(ptr); } #endif if (heap == NULL) { #ifdef WOLFSSL_HEAP_TEST /* allow using malloc for creating ctx and method */ if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || type == DYNAMIC_TYPE_CERT_MANAGER) { WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); } else { WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n"); } #endif #ifndef WOLFSSL_NO_MALLOC free(ptr); #else WOLFSSL_MSG("Error trying to call free when turned off"); #endif /* WOLFSSL_NO_MALLOC */ } else { WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; WOLFSSL_HEAP* mem = hint->memory; word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); /* get memory struct and add it to available list */ pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz); if (LockMutex(&(mem->memory_mutex)) != 0) { WOLFSSL_MSG("Bad memory_mutex lock"); return; } /* case of using fixed IO buffers */ if (mem->flag & WOLFMEM_IO_POOL_FIXED && (type == DYNAMIC_TYPE_OUT_BUFFER || type == DYNAMIC_TYPE_IN_BUFFER)) { /* fixed IO pools are free'd at the end of SSL lifetime using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */ } else if (mem->flag & WOLFMEM_IO_POOL && (type == DYNAMIC_TYPE_OUT_BUFFER || type == DYNAMIC_TYPE_IN_BUFFER)) { pt->next = mem->io; mem->io = pt; } else { /* general memory free */ for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { if (pt->sz == mem->sizeList[i]) { pt->next = mem->ava[i]; mem->ava[i] = pt; break; } } } mem->inUse -= pt->sz; mem->frAlc += 1; #ifdef WOLFSSL_DEBUG_MEMORY printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); #endif /* keep track of connection statistics if flag is set */ if (mem->flag & WOLFMEM_TRACK_STATS) { WOLFSSL_MEM_CONN_STATS* stats = hint->stats; if (stats != NULL) { /* avoid under flow */ if (stats->curMem > pt->sz) { stats->curMem -= pt->sz; } else { stats->curMem = 0; } if (stats->curAlloc > 0) { stats->curAlloc--; } stats->totalFr++; } } UnLockMutex(&(mem->memory_mutex)); } } (void)i; (void)pt; (void)type; }
void wolfSSL_TI_unlockCCM() { UnLockMutex(&TI_CCM_Mutex) ; }
/*++ * Function: _ICC_Recycle * * Purpose: core logic to implement the ICC_Recycle() & ICC_Recycle_Loop() * functions. * * Parameters: unsigned int -- ICC expiration time * * Returns: nada * * Authors: Dave McMurtrie <*****@*****.**> *-- */ static void _ICC_Recycle( unsigned int Expiration ) { char *fn = "_ICC_Recycle()"; time_t CurrentTime; int rc; unsigned int HashIndex; ICC_Struct *HashEntry; ICC_Struct *Previous; CurrentTime = time(0); LockMutex( &mp ); /* * Need to iterate through every single item in our hash table * to decide if we can free it or not. */ for ( HashIndex = 0; HashIndex < HASH_TABLE_SIZE; HashIndex++ ) { Previous = NULL; HashEntry = ICC_HashTable[ HashIndex ]; while ( HashEntry ) { /* * If the last logout time is non-zero, and it's been logged * out for longer than our default expiration time, free it. * Note that this allows for the logouttime to be explicitly * set to 1 (such as in the Get_Server_conn code) if we want to * reap a connection before waiting the normal expiration * cycle. */ if ( HashEntry->logouttime && ( ( CurrentTime - HashEntry->logouttime ) > Expiration ) ) { syslog(LOG_INFO, "Expiring server sd [%d]", HashEntry->server_conn->sd); /* Logout of the imap server and close the server socket. */ IMAP_Write( HashEntry->server_conn, "VIC20 LOGOUT\r\n", strlen( "VIC20 LOGOUT\r\n" ) ); #if HAVE_LIBSSL if ( HashEntry->server_conn->tls ) { SSL_shutdown( HashEntry->server_conn->tls ); SSL_free( HashEntry->server_conn->tls ); } #endif close( HashEntry->server_conn->sd ); free( HashEntry->server_conn ); /* * This was being counted as a "retained" connection. It was * open, but not in use. Now that we're closing it, we have * to decrement the number of retained connections. */ IMAPCount->RetainedServerConnections--; if ( Previous ) { Previous->next = HashEntry->next; HashEntry->next = ICC_free; ICC_free = HashEntry; HashEntry = Previous->next; } else { ICC_HashTable[ HashIndex ] = HashEntry->next; HashEntry->next = ICC_free; ICC_free = HashEntry; HashEntry = ICC_HashTable[ HashIndex ]; } } else { Previous = HashEntry; HashEntry = HashEntry->next; } } } UnLockMutex( &mp ); }
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, buffer* responseBuffer) { OcspEntry* entry = NULL; CertStatus* status = NULL; byte* request = NULL; int requestSz = 2048; byte* response = NULL; const char* url = NULL; int urlSz = 0; int ret = -1; #ifdef WOLFSSL_SMALL_STACK CertStatus* newStatus; OcspResponse* ocspResponse; #else CertStatus newStatus[1]; OcspResponse ocspResponse[1]; #endif WOLFSSL_ENTER("CheckOcspRequest"); if (responseBuffer) { responseBuffer->buffer = NULL; responseBuffer->length = 0; } ret = GetOcspEntry(ocsp, ocspRequest, &entry); if (ret != 0) return ret; ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer); if (ret != OCSP_INVALID_STATUS) return ret; if (ocsp->cm->ocspUseOverrideURL) { url = ocsp->cm->ocspOverrideURL; if (url != NULL && url[0] != '\0') urlSz = (int)XSTRLEN(url); else return OCSP_NEED_URL; } else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) { url = (const char *)ocspRequest->url; urlSz = ocspRequest->urlSz; } else { /* cert doesn't have extAuthInfo, assuming CERT_GOOD */ return 0; } request = (byte*)XMALLOC(requestSz, NULL, DYNAMIC_TYPE_OCSP); if (request == NULL) { WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_ERROR; } #ifdef WOLFSSL_SMALL_STACK newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, DYNAMIC_TYPE_TMP_BUFFER); ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (newStatus == NULL || ocspResponse == NULL) { if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(request, NULL, DYNAMIC_TYPE_OCSP); WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); return MEMORY_E; } #endif requestSz = EncodeOcspRequest(ocspRequest, request, requestSz); if (ocsp->cm->ocspIOCb) ret = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, request, requestSz, &response); if (ret >= 0 && response) { XMEMSET(newStatus, 0, sizeof(CertStatus)); InitOcspResponse(ocspResponse, newStatus, response, ret); OcspResponseDecode(ocspResponse, ocsp->cm); if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) ret = OCSP_LOOKUP_FAIL; else { if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) { if (responseBuffer) { responseBuffer->buffer = (byte*)XMALLOC(ret, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (responseBuffer->buffer) { responseBuffer->length = ret; XMEMCPY(responseBuffer->buffer, response, ret); } } ret = xstat2err(ocspResponse->status->status); if (LockMutex(&ocsp->ocspLock) != 0) ret = BAD_MUTEX_E; else { if (status != NULL) { if (status->rawOcspResponse) XFREE(status->rawOcspResponse, NULL, DYNAMIC_TYPE_OCSP_STATUS); /* Replace existing certificate entry with updated */ XMEMCPY(status, newStatus, sizeof(CertStatus)); } else { /* Save new certificate entry */ status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, DYNAMIC_TYPE_OCSP_STATUS); if (status != NULL) { XMEMCPY(status, newStatus, sizeof(CertStatus)); status->next = entry->status; entry->status = status; entry->totalStatus++; } } if (status && responseBuffer && responseBuffer->buffer) { status->rawOcspResponse = (byte*)XMALLOC( responseBuffer->length, NULL, DYNAMIC_TYPE_OCSP_STATUS); if (status->rawOcspResponse) { status->rawOcspResponseSz = responseBuffer->length; XMEMCPY(status->rawOcspResponse, responseBuffer->buffer, responseBuffer->length); } } UnLockMutex(&ocsp->ocspLock); } } else ret = OCSP_LOOKUP_FAIL; } } else ret = OCSP_LOOKUP_FAIL; #ifdef WOLFSSL_SMALL_STACK XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif if (response != NULL && ocsp->cm->ocspRespFreeCb) ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response); WOLFSSL_LEAVE("CheckOcspRequest", ret); return ret; }
/*++ * Function: cmd_trace * * Purpose: turn on per-user tracing in the proxy server. * * Parameters: ptr to ITD_Struct for client connection. * char ptr to Tag sent with this command. * char ptr to the username we want to trace (NULL to turn * off tracing) * * Returns: 0 on success * -1 on failure * * Authors: Dave McMurtrie <*****@*****.**> *-- */ static int cmd_trace( ITD_Struct *itd, char *Tag, char *Username ) { char *fn = "cmd_trace"; char SendBuf[BUFSIZE]; unsigned int BufLen = BUFSIZE - 1; SendBuf[BUFSIZE - 1] = '\0'; /* * Here are the tracing semantics: * * Tracing is to be limited to only one user at a time. This decision was * made for a few different reasons. First, to conserve system resources * such as disk space. Second, to improve overall server performance -- * tracing will slow a thread down. Third, so a sysadmin doesn't forget * that tracing is turned on for a user (like I commonly do when I enable * tracing in cyrus imapd). Fourth, it's just easier this way. */ LockMutex( &trace ); if ( !Username ) { snprintf( SendBuf, BufLen, "\n\n-----> C= %s PROXY: user tracing disabled. Expect further output until client logout.\n", TraceUser ); write( Tracefd, SendBuf, strlen( SendBuf ) ); memset( TraceUser, 0, sizeof TraceUser ); snprintf( SendBuf, BufLen, "%s OK Tracing disabled\r\n", Tag ); if ( IMAP_Write( itd->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_WARNING, "%s: IMAP_Write() failed: %s", fn, strerror(errno) ); UnLockMutex( &trace ); return( -1 ); } UnLockMutex( &trace ); return( 0 ); } if ( TraceUser[0] ) { /* guarantee no runaway strings */ TraceUser[sizeof TraceUser - 1] = '\0'; snprintf( SendBuf, BufLen, "%s BAD Tracing already enabled for user %s\r\n", Tag, TraceUser ); if ( IMAP_Write( itd->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_WARNING, "%s: IMAP_Write() failed: %s", fn, strerror(errno) ); UnLockMutex( &trace ); return( -1 ); } UnLockMutex( &trace ); return( 0 ); } strncpy( TraceUser, Username, sizeof TraceUser - 1 ); snprintf( SendBuf, BufLen, "%s OK Tracing enabled\r\n", Tag ); if ( IMAP_Write( itd->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_WARNING, "%s: IMAP_Write() failed: %s", fn, strerror(errno) ); UnLockMutex( &trace ); return( -1 ); } snprintf( SendBuf, BufLen, "\n\n-----> C= %s PROXY: user tracing enabled.\n", TraceUser ); write( Tracefd, SendBuf, strlen( SendBuf ) ); UnLockMutex( &trace ); return( 0 ); }
void* wolfSSL_Malloc(size_t size, void* heap, int type) #endif { void* res = 0; wc_Memory* pt = NULL; int i; /* check for testing heap hint was set */ #ifdef WOLFSSL_HEAP_TEST if (heap == (void*)WOLFSSL_HEAP_TEST) { return malloc(size); } #endif /* if no heap hint then use dynamic memory*/ if (heap == NULL) { #ifdef WOLFSSL_HEAP_TEST /* allow using malloc for creating ctx and method */ if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || type == DYNAMIC_TYPE_CERT_MANAGER) { WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); res = malloc(size); } else { WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n"); res = NULL; } #else #ifndef WOLFSSL_NO_MALLOC res = malloc(size); #else WOLFSSL_MSG("No heap hint found to use and no malloc"); #endif /* WOLFSSL_NO_MALLOC */ #endif /* WOLFSSL_HEAP_TEST */ } else { WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; WOLFSSL_HEAP* mem = hint->memory; if (LockMutex(&(mem->memory_mutex)) != 0) { WOLFSSL_MSG("Bad memory_mutex lock"); return NULL; } /* case of using fixed IO buffers */ if (mem->flag & WOLFMEM_IO_POOL_FIXED) { if (type == DYNAMIC_TYPE_OUT_BUFFER) { pt = hint->outBuf; } if (type == DYNAMIC_TYPE_IN_BUFFER) { pt = hint->inBuf; } } /* check if using IO pool flag */ if (mem->flag & WOLFMEM_IO_POOL && pt == NULL && (type == DYNAMIC_TYPE_OUT_BUFFER || type == DYNAMIC_TYPE_IN_BUFFER)) { if (mem->io != NULL) { pt = mem->io; mem->io = pt->next; } } /* general static memory */ if (pt == NULL) { for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { if ((word32)size < mem->sizeList[i]) { if (mem->ava[i] != NULL) { pt = mem->ava[i]; mem->ava[i] = pt->next; break; } } } } if (pt != NULL) { mem->inUse += pt->sz; mem->alloc += 1; res = pt->buffer; #ifdef WOLFSSL_DEBUG_MEMORY printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); #endif /* keep track of connection statistics if flag is set */ if (mem->flag & WOLFMEM_TRACK_STATS) { WOLFSSL_MEM_CONN_STATS* stats = hint->stats; if (stats != NULL) { stats->curMem += pt->sz; if (stats->peakMem < stats->curMem) { stats->peakMem = stats->curMem; } stats->curAlloc++; if (stats->peakAlloc < stats->curAlloc) { stats->peakAlloc = stats->curAlloc; } stats->totalAlloc++; } } } else { WOLFSSL_MSG("ERROR ran out of static memory"); } UnLockMutex(&(mem->memory_mutex)); } #ifdef WOLFSSL_MALLOC_CHECK if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { WOLFSSL_MSG("ERROR memory is not alligned"); res = NULL; } #endif (void)i; (void)pt; (void)type; return res; }