#include #include #include #include #include #include #include #define AUTH_ACTION "AUTH" #define SUCCESS "SUCC" #define ERROR "ERR" #define CHANGE_PASS "CHPS" #define GET_GROUP "GGRP" #define DONE "!" #include void send_string(SSL *mySSL, char *message); char * read_string(SSL *mySSL); int main(int argc, char *argv[]) { SSL *ssl; SSL_CTX *ctx; BIO *conn; int i; char *username; char *good_pass; char bad_pass[200]; char *users_group; char *server_resp; int num_times = 1; int good_times = 0, bad_times = 0; int x; int perc = 0; int num_kids = 0; int my_pid = 0; char *server_addr; struct timeval start, end; double good_resp_time=0,bad_resp_time=0,temp_resp_time=0,avg_good=0,avg_bad=0; int good=0; strcpy(bad_pass,"this_is_a_bad_password"); initscr(); noecho(); attron(A_BOLD); attron(A_UNDERLINE); mvprintw(0,0,"pGina PAM Stress Tester"); attroff(A_UNDERLINE); mvprintw(2,0,"Server : %s",argv[3]); mvprintw(3,0,"Good attempts : "); mvprintw(4,0,"Bad attempts : "); mvprintw(5,0,"Response Time : "); mvprintw(6,0,"Error Time : "); refresh(); srand(time(NULL)); username = argv[1]; good_pass = argv[2]; server_addr = argv[3]; num_times = atoi(argv[4]); if(num_times > 3000) num_times = 3000; // Init OpenSSL OpenSSL_add_all_algorithms(); SSL_load_error_strings(); for(x = 0; x < num_times; x++) { mvprintw(3,16,"%d",good_times); mvprintw(4,16,"%d",bad_times); mvprintw(5,16,"%f (worst) %f (average)",good_resp_time,(float)(avg_good/good_times)); mvprintw(6,16,"%f (worst) %f (average)",bad_resp_time,(float)(avg_bad/bad_times)); mvprintw(7,0,"%d of %d attempts made.",x+1,num_times); refresh(); // Init context ctx = SSL_CTX_new(TLSv1_method()); if(!ctx) { // Error creating context printf("Problem creating CTX. Aborting.\n"); endwin(); exit(-1); } // Init SSL ssl = SSL_new(ctx); if(!ssl) { // Error creating SSL. printf("Problem creating SSL Aborting.\n"); endwin(); exit(-1); } conn = BIO_new_connect(server_addr); if(!conn) { // Error in BIO_new_connect mvprintw(8,0,"Last Server Msg : Error in BIO_new_connect "); continue; } if(BIO_do_connect(conn) <= 0) { // Error in BIO_do_connect mvprintw(8,0,"Last Server Msg : Error in BIO_do_connect "); continue; } SSL_set_bio(ssl,conn,conn); if(SSL_connect(ssl) <= 0) { // Error in SSL handshake. mvprintw(8,0,"Last Server Msg : Error in SSL handshake "); continue; } // we can now communicate with ssl // send a string gettimeofday(&start,0); // Tell the server what action we are doing send_string(ssl,AUTH_ACTION); // printf("<-- %s\n",AUTH_ACTION); send_string(ssl,username); // printf("<-- %s\n",username); // decide whether to send a good password or not if((rand() % 10) != 6) { send_string(ssl,good_pass); // printf("<-- GOOD PASSWORD\n"); good_times++; good=1; } else { send_string(ssl,bad_pass); // printf("<-- BAD PASSWORD\n"); bad_times++; //good_times++; good=0; } server_resp = read_string(ssl); // printf("--> %s\n",server_resp); mvprintw(8,0,"Last Server Msg : %s ",server_resp); if(server_resp == NULL) { // printf("Server responded erroneously.\n"); SSL_shutdown(ssl); break; } if(!strcmp(server_resp,SUCCESS)) { // printf("**** User: %s authenticated. Checking group membership.\n",username); free(server_resp); send_string(ssl,GET_GROUP); // printf("<-- %s\n",GET_GROUP); send_string(ssl,username); // printf("<-- %s\n",username); server_resp = read_string(ssl); // Get the resulting group // printf("--> %s\n",server_resp); } send_string(ssl,DONE); // Tell the server we need nothing more right now SSL_shutdown(ssl); gettimeofday(&end,0); temp_resp_time = (end.tv_sec + end.tv_usec/1.0e6) - (start.tv_sec + start.tv_usec/1.0e6); if(good) { if(temp_resp_time > good_resp_time) good_resp_time = temp_resp_time; avg_good += temp_resp_time; } else { if(temp_resp_time > bad_resp_time) bad_resp_time = temp_resp_time; avg_bad += temp_resp_time; } } endwin(); return 0; } /* why does this function send bytes one byte at a time? */ void send_string(SSL *mySSL, char *message) { int error = 0, wrote = 0; for(wrote = 0; wrote <= strlen(message); wrote++) { error = SSL_write(mySSL,&message[wrote],1); if(error <= 0) break; } return; } char * read_string(SSL *mySSL) { char buffer[1024]; char *ret; char this_one; int error = 0, read_in = 0; memset(buffer,'\0',sizeof(buffer)); for(read_in = 0; read_in < sizeof(buffer); read_in += error) { error = SSL_read(mySSL,&this_one,1); if(error>0) buffer[read_in] = this_one; if(error <= 0 || this_one == '\0' || this_one == '\n') break; } if(error <= 0) return NULL; // Buffer is good here ret = (char *) malloc(strlen(buffer) + 1); strcpy(ret,buffer); return ret; }