/* echoserver.c */ #include "ssl.h" #include "cyassl_test.h" #ifndef NO_MAIN_DRIVER #define ECHO_OUT #endif #ifdef SESSION_STATS void PrintSessionStats(void); #endif static void SignalReady(void* args) { #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) /* signal ready to tcp_accept */ func_args* server_args = (func_args*)args; tcp_ready* ready = server_args->signal; pthread_mutex_lock(&ready->mutex); ready->ready = 1; pthread_cond_signal(&ready->cond); pthread_mutex_unlock(&ready->mutex); #endif } THREAD_RETURN CYASSL_API echoserver_test(void* args) { SOCKET_T sockfd = 0; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; int outCreated = 0; int shutdown = 0; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #ifdef ECHO_OUT FILE* fout = stdout; if (argc >= 2) { fout = fopen(argv[1], "w"); outCreated = 1; } if (!fout) err_sys("can't open output file"); #endif ((func_args*)args)->return_code = -1; /* error state */ tcp_listen(&sockfd); #if defined(CYASSL_DTLS) method = DTLSv1_server_method(); #elif !defined(NO_TLS) method = SSLv23_server_method(); #else method = SSLv3_server_method(); #endif ctx = SSL_CTX_new(method); /* SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); */ #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #ifndef NO_FILESYSTEM #ifdef HAVE_NTRU /* ntru */ if (SSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load ntru cert file"); if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ntruKey) != SSL_SUCCESS) err_sys("can't load ntru key file"); #elif HAVE_ECC /* ecc */ if (SSL_CTX_use_certificate_file(ctx, eccCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file"); if (SSL_CTX_use_PrivateKey_file(ctx, eccKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server key file"); #else /* normal */ if (SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file"); if (SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server key file"); #endif #else load_buffer(ctx, svrCert, CYASSL_CERT); load_buffer(ctx, svrKey, CYASSL_KEY); #endif SignalReady(args); while (!shutdown) { SSL* ssl = 0; char command[1024]; int echoSz = 0; int clientfd; #ifndef CYASSL_DTLS SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); clientfd = accept(sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); #else clientfd = udp_read_connect(sockfd); #endif if (clientfd == -1) err_sys("tcp accept failed"); ssl = SSL_new(ctx); if (ssl == NULL) err_sys("SSL_new failed"); SSL_set_fd(ssl, clientfd); if (SSL_accept(ssl) != SSL_SUCCESS) { printf("SSL_accept failed"); SSL_free(ssl); CloseSocket(clientfd); continue; } while ( (echoSz = SSL_read(ssl, command, sizeof(command))) > 0) { if ( strncmp(command, "quit", 4) == 0) { printf("client sent quit command: shutting down!\n"); shutdown = 1; break; } if ( strncmp(command, "break", 5) == 0) { printf("client sent break command: closing session!\n"); break; } #ifdef SESSION_STATS if ( strncmp(command, "printstats", 10) == 0) { PrintSessionStats(); break; } #endif if ( strncmp(command, "GET", 3) == 0) { char type[] = "HTTP/1.0 200 ok\r\nContent-type:" " text/html\r\n\r\n"; char header[] = "
\n\n"; char body[] = "greetings from CyaSSL\n"; char footer[] = "\r\n\r\n"; strncpy(command, type, sizeof(type)); echoSz = sizeof(type) - 1; strncpy(&command[echoSz], header, sizeof(header)); echoSz += sizeof(header) - 1; strncpy(&command[echoSz], body, sizeof(body)); echoSz += sizeof(body) - 1; strncpy(&command[echoSz], footer, sizeof(footer)); echoSz += sizeof(footer); if (SSL_write(ssl, command, echoSz) != echoSz) err_sys("SSL_write failed"); break; } command[echoSz] = 0; #ifdef ECHO_OUT fputs(command, fout); #endif if (SSL_write(ssl, command, echoSz) != echoSz) err_sys("SSL_write failed"); } #ifndef CYASSL_DTLS SSL_shutdown(ssl); #endif SSL_free(ssl); CloseSocket(clientfd); #ifdef CYASSL_DTLS tcp_listen(&sockfd); SignalReady(args); #endif } CloseSocket(sockfd); SSL_CTX_free(ctx); #ifdef ECHO_OUT if (outCreated) fclose(fout); #endif ((func_args*)args)->return_code = 0; return 0; } /* so overall tests can pull in test function */ #ifndef NO_MAIN_DRIVER int main(int argc, char** argv) { func_args args; StartTCP(); args.argc = argc; args.argv = argv; InitCyaSSL(); #ifdef DEBUG_CYASSL CyaSSL_Debugging_ON(); #endif echoserver_test(&args); FreeCyaSSL(); return args.return_code; } #endif /* NO_MAIN_DRIVER */