/* pGina PAM Server - A PAM-Aware Unix Daemon for pGina Copyright (C) 2003 Nathan Yocom This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Email: nate.yocom@xpasystems.com Web: http://pgina.xpasystems.com Snail Mail: Nathan Yocom 9 Evergreen Farms Rd. Scarborough, ME 04074 Phone: 207-450-4948 */ /* $Log: ssl_stuff.c,v $ Revision 1.1 2003/08/06 04:58:36 nyocom Initial Import Revision 1.8 2003/04/29 16:53:43 xpasys Several solaris compilation fixes added Revision 1.7 2003/04/28 18:50:38 xpasys Drastic changes in move to fork model Prepared for adding auth_asst code Memory management enhancements Revision 1.6 2003/04/17 17:56:11 xpasys Added debug output to read_string() Revision 1.5 2003/04/11 04:50:26 xpasys Refitted mutexing to allow for better performance, possible solve deadlock issues Added debug trace info Revision 1.4 2003/04/07 17:18:26 xpasys Changed line endings to Unix Added code to be a bit friendlier on bad arguments (thanks to Jiho Kim) Revision 1.3 2003/04/04 07:58:00 xpasys Made read_string() non_blocking, times out after some time Added -l for login service name Added -a for passwd service name Added -r for number of retries Added -s for sleep time (usecs) General security and stability improvements Revision 1.2 2003/04/03 04:42:45 xpasys Added better memory handling Added pthread_exit() instead of null returns Removed egads dependancy Revision 1.1.1.1 2003/03/22 06:02:20 xpasys Imported sources */ #include "pgina_pam_server.h" SSL_CTX *setup_ssl_ctx(char *certfile) { SSL_CTX *ctx; ctx = SSL_CTX_new(TLSv1_server_method()); if(SSL_CTX_use_certificate_file(ctx,certfile,SSL_FILETYPE_PEM) != 1) return NULL; if(SSL_CTX_use_PrivateKey_file(ctx,certfile,SSL_FILETYPE_PEM) != 1) return NULL; return ctx; } 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; fd_set rfds; struct timeval tv; int retval; int myFd = 0; int num_tries = 0; myFd = SSL_get_fd(mySSL); if(myFd > -1) { memset(buffer,'\0',sizeof(buffer)); read_in = 0; while(read_in < sizeof(buffer)) { FD_ZERO(&rfds); FD_SET(myFd, &rfds); tv.tv_sec = 0; tv.tv_usec = sleep_time;// wait at max sleep_time retval = select(myFd+1, &rfds, NULL, NULL, &tv); if (FD_ISSET(myFd,&rfds)) { error = SSL_read(mySSL,&this_one,1); if(error > 0) { buffer[read_in] = this_one; read_in+=1; } if(this_one == '\0' || this_one == '\n') { // Buffer is good here ret = (char *) malloc(strlen(buffer) + 1); strcpy(ret,buffer); return ret; } if(error <= 0) // if there was a flat out error, punt { syslog(LOG_ERR,"Error in read, Punt."); debug_out("Error in read, Closing thread."); SSL_shutdown(mySSL); SSL_free(mySSL); _exit(-1); } } else { num_tries++; if(num_tries >= num_retries) { syslog(LOG_ERR,"Retry limit reached for this client. Punting."); debug_out("Retry limit reached, Closing thread."); // Dont return, we should just handle that here. SSL_shutdown(mySSL); SSL_free(mySSL); _exit(-1); } } } } syslog(LOG_ERR,"Couldn't get a fd from SSL."); debug_out("Couldnt get an fd from SSL, Closing thread."); SSL_shutdown(mySSL); SSL_free(mySSL); _exit(-1); return NULL; } // From OpenSSL O'Reilly book int seed_prng(int bytes) { char *buf; buf = (char *)malloc(bytes); if(buf) RAND_seed(buf,bytes); else return -1; return 1; }