/[monit]/monit/ssl.c
ViewVC logotype

Diff of /monit/ssl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by chopp, Tue Nov 5 09:04:02 2002 UTC revision 1.13 by chopp, Fri Nov 8 15:41:14 2002 UTC
# Line 23  Line 23 
23  #include <config.h>  #include <config.h>
24  #include <stdio.h>  #include <stdio.h>
25  #include <memory.h>  #include <memory.h>
26    #include <time.h>
27    
28  #ifdef HAVE_SYS_TYPES_H  #ifdef HAVE_SYS_TYPES_H
29  #include <sys/types.h>  #include <sys/types.h>
# Line 69  Line 70 
70  #include <openssl/ssl.h>  #include <openssl/ssl.h>
71  #include <openssl/err.h>  #include <openssl/err.h>
72  #include <openssl/rand.h>  #include <openssl/rand.h>
73    #include <openssl/bio.h>
74  #endif  #endif
75    
76  #include "monitor.h"  #include "monitor.h"
77  #include "net.h"  #include "net.h"
78  #include "ssl.h"  #include "ssl.h"
79    
 /* Private prototypes */  
   
80  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
81    
82    /* Initialization code */
83  static int ssl_thread_start(void);  static int ssl_thread_start(void);
84  static int ssl_thread_stop(void);  static int ssl_thread_stop(void);
85  static int unsigned long ssl_thread_id(void);  static int unsigned long ssl_thread_id(void);
# Line 85  static void ssl_mutex_lock(int mode, int Line 87  static void ssl_mutex_lock(int mode, int
87  static int ssl_entropy_start(void);  static int ssl_entropy_start(void);
88  static int ssl_entropy_stop(void);  static int ssl_entropy_stop(void);
89    
90    static pthread_mutex_t   ssl_mutex= PTHREAD_MUTEX_INITIALIZER;
91    static pthread_mutex_t *ssl_mutex_table;
92    static int ssl_initilized= FALSE;
93    
94    /* Connection verification code */
95  static int verify_init(ssl_server_connection *);  static int verify_init(ssl_server_connection *);
96  static int verify_callback(int, X509_STORE_CTX *);  static int verify_callback(int, X509_STORE_CTX *);
97  static int verify_callback_noclientcert(int, X509_STORE_CTX *);  static int verify_callback_noclientcert(int, X509_STORE_CTX *);
98  static void verify_info(ssl_server_connection *);  static void verify_info(ssl_server_connection *);
99    static int check_preverify(X509_STORE_CTX *);
100    
 static pthread_mutex_t   ssl_mutex= PTHREAD_MUTEX_INITIALIZER;  
 static pthread_mutex_t *ssl_mutex_table;  
   
 static int ssl_initilized= FALSE;  
101  static int allow_self_certfication= FALSE;  static int allow_self_certfication= FALSE;
102    static int allow_any_purpose= FALSE;
103    
104    /* Error handling */
105    static int handle_connection_error(int, ssl_connection *, char *);
106    static void handle_ssl_error(char *);
107    #define SSLERROR ERR_error_string(ERR_get_error(),NULL)
108    
109    #define ALLOW_ANY_PURPOSE
110    
111  #endif  #endif
112    
113  /**  /**
# Line 127  static int allow_self_certfication= FALS Line 140  static int allow_self_certfication= FALS
140   */   */
141    
142    
143      /*
144       * For some of the code I was enlightened by:
145       *
146       * An Introduction to OpenSSL Programming, Part I of II
147       *
148       * by Eric Rescorla
149       * Linux Journal 9/2001
150       * http://www.linuxjournal.com/article.php?sid=4822
151       */
152    
153  /* ------------------------------------------------------------------ Public */  /* ------------------------------------------------------------------ Public */
154    
155    
# Line 138  static int allow_self_certfication= FALS Line 161  static int allow_self_certfication= FALS
161  int embed_ssl_socket (ssl_connection *ssl, int socket) {  int embed_ssl_socket (ssl_connection *ssl, int socket) {
162    
163  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
164    
165      int ssl_error;
166      time_t ssl_time;
167        
168    if ( ssl == NULL ) {    if ( ssl == NULL ) {
169            
# Line 157  int embed_ssl_socket (ssl_connection *ss Line 183  int embed_ssl_socket (ssl_connection *ss
183    
184    } else {    } else {
185    
186      error("Socket error!\n");      error("%s: Socket error!\n", prog);
187      goto sslerror;      goto sslerror;
188    }    }
189    
190    if ((ssl->handler= SSL_new (ssl->ctx)) == NULL ) {    if ((ssl->handler= SSL_new (ssl->ctx)) == NULL ) {
191    
192      error("Cannot initialize the SSL handler!\n");      handle_ssl_error("embed_ssl_socket()");
193        error("%s: Cannot initialize the SSL handler!\n", prog);
194      goto sslerror;      goto sslerror;
195    
196    }    }
197    
198    SSL_set_fd (ssl->handler, ssl->socket);    set_noblock(ssl->socket);
199    
200    if (SSL_connect (ssl->handler) == -1) {    if((ssl->socket_bio= BIO_new_socket(ssl->socket, BIO_NOCLOSE)) == NULL) {
201        
202      error("Cannot connect with the SSL service!\n");      handle_ssl_error("embed_ssl_socket()");
203        error("%s: Cannot generate IO buffer!\n", prog);
204      goto sslerror;      goto sslerror;
205    
206    }    }
207    
208      SSL_set_bio(ssl->handler, ssl->socket_bio, ssl->socket_bio);
209    
210      ssl_time=time(NULL);
211    
212      while((ssl_error= SSL_connect (ssl->handler)) < 0) {
213    
214        if((time(NULL)-ssl_time) > SSL_TIMEOUT) {
215    
216          error("%s: The connection process with the SSL service timed out!\n",
217                prog);
218          goto sslerror;
219        
220        }
221    
222        if (!handle_connection_error(ssl_error, ssl, "embed_ssl_socket()")) {
223    
224          goto sslerror;
225    
226        }
227    
228      }
229    
230    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);
231    
232    if (! update_ssl_cert_data(ssl)) {    if (! update_ssl_cert_data(ssl)) {
233    
234      error("Cannot get the SSL server certificate!\n");      error("%s: Cannot get the SSL server certificate!\n",
235              prog);
236      goto sslerror;      goto sslerror;
237    
238    }    }
# Line 300  ssl_connection *create_ssl_socket(char * Line 351  ssl_connection *create_ssl_socket(char *
351    
352    if ((socket= create_socket(hostname, port, protocol)) == -1) {    if ((socket= create_socket(hostname, port, protocol)) == -1) {
353    
354      error("Cannot connect!\n");      error("%s: Cannot connect!\n", prog);
355      goto sslerror;      goto sslerror;
356    
357    }    }
358    
359    if (! embed_ssl_socket(ssl, socket)) {    if (! embed_ssl_socket(ssl, socket)) {
360    
361      error("Cannot embed socket!\n");      error("%s: Cannot embed socket!\n", prog);
362    
363      goto sslerror;      goto sslerror;
364    
# Line 337  int close_ssl_socket(ssl_connection *ssl Line 388  int close_ssl_socket(ssl_connection *ssl
388    
389  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
390    
391      int error;
392    
393    if(ssl == NULL) {    if(ssl == NULL) {
394    
395      return FALSE;      return FALSE;
396    
397    }    }
398    
399    SSL_shutdown (ssl->handler);    if (! (error= SSL_shutdown (ssl->handler))) {
400    
401        shutdown(ssl->socket,1 );
402        error= SSL_shutdown (ssl->handler);
403    
404      }
405    
406    close(ssl->socket);    close(ssl->socket);
407    cleanup_ssl_socket(ssl);    cleanup_ssl_socket(ssl);
408    
409    return TRUE;    if ( error<=0 ) {
410      
411        return FALSE;
412    
413      } else {
414    
415        return TRUE;
416    
417      }
418    
419  #else  #else
420    
# Line 387  int cleanup_ssl_socket(ssl_connection *s Line 454  int cleanup_ssl_socket(ssl_connection *s
454    
455    }    }
456    
457      if (ssl->socket_bio != NULL) {
458        
459        /*
460         * no BIO_free(ssl->socket_bio); necessary, because BIO is freed
461         * by ssl->handler
462         */
463    
464        ssl->socket_bio= NULL;
465    
466      }
467    
468    if (ssl->cert_issuer != NULL) {    if (ssl->cert_issuer != NULL) {
469    
470      free(ssl->cert_issuer);      free(ssl->cert_issuer);
# Line 471  ssl_server_connection *init_ssl_server ( Line 549  ssl_server_connection *init_ssl_server (
549    
550  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
551    
552    ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile, clientpemfile);    ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile,
553                                                                    clientpemfile);
554    
555    ASSERT(pemfile);    ASSERT(pemfile);
556    
# Line 483  ssl_server_connection *init_ssl_server ( Line 562  ssl_server_connection *init_ssl_server (
562        
563    if ((ssl_server->method= SSLv23_server_method()) == NULL ) {    if ((ssl_server->method= SSLv23_server_method()) == NULL ) {
564    
565      error("Cannot initialize the SSL method to use!\n");      handle_ssl_error("init_ssl_server()");
566        error("%s: Cannot initialize the SSL method to use!\n", prog);
567      goto sslerror;      goto sslerror;
568    
569    }    }
570    
571    if ((ssl_server->ctx= SSL_CTX_new(ssl_server->method)) == NULL ) {    if ((ssl_server->ctx= SSL_CTX_new(ssl_server->method)) == NULL ) {
572    
573      error("Cannot initialize the SSL server's certificate handler!\n");      handle_ssl_error("init_ssl_server()");
574        error("%s: Cannot initialize the SSL server's certificate handler!\n"
575              , prog);
576      goto sslerror;      goto sslerror;
577    
578    }    }
# Line 498  ssl_server_connection *init_ssl_server ( Line 580  ssl_server_connection *init_ssl_server (
580    if (SSL_CTX_use_certificate_file(ssl_server->ctx, pemfile,    if (SSL_CTX_use_certificate_file(ssl_server->ctx, pemfile,
581                                     SSL_FILETYPE_PEM) <= 0) {                                     SSL_FILETYPE_PEM) <= 0) {
582    
583      error("Cannot initialize the SSL server's certificate!\n");      handle_ssl_error("init_ssl_server()");
584        error("%s: Cannot initialize the SSL server's certificate!\n", prog);
585      goto sslerror;      goto sslerror;
586    
587    }    }
# Line 506  ssl_server_connection *init_ssl_server ( Line 589  ssl_server_connection *init_ssl_server (
589    if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile,    if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile,
590                                    SSL_FILETYPE_PEM) <= 0) {                                    SSL_FILETYPE_PEM) <= 0) {
591    
592      error("Cannot initialize the SSL server's private key!\n");      handle_ssl_error("init_ssl_server()");
593        error("%s: Cannot initialize the SSL server's private key!\n", prog);
594      goto sslerror;      goto sslerror;
595    
596    }    }
597    
598    if (!SSL_CTX_check_private_key(ssl_server->ctx)) {    if (!SSL_CTX_check_private_key(ssl_server->ctx)) {
599    
600      error("The private key does not match the certificate public key!\n");      handle_ssl_error("init_ssl_server()");
601        error("%s: The private key does not match the certificate public key!\n",
602              prog);
603      goto sslerror;      goto sslerror;
604    
605    }    }
# Line 523  ssl_server_connection *init_ssl_server ( Line 609  ssl_server_connection *init_ssl_server (
609     */     */
610    if (!verify_init(ssl_server)) {    if (!verify_init(ssl_server)) {
611    
612      error("Verification engine was not properly initilized!\n");      handle_ssl_error("init_ssl_server()");
613        error("%s: Verification engine was not properly initilized!\n", prog);
614      goto sslerror;      goto sslerror;
615    
616    }    }
# Line 576  ssl_server_connection *create_ssl_server Line 663  ssl_server_connection *create_ssl_server
663    
664    if ((socket= create_server_socket(port, backlog, bindAddr)) == -1) {    if ((socket= create_server_socket(port, backlog, bindAddr)) == -1) {
665    
666      error("Cannot connect!\n");      error("%s: Cannot connect!\n", prog);
667      goto sslerror;      goto sslerror;
668    
669    }    }
# Line 855  int delete_accepted_ssl_socket (ssl_serv Line 942  int delete_accepted_ssl_socket (ssl_serv
942    LOCK(ssl_mutex);    LOCK(ssl_mutex);
943    
944    if ( ssl->prev == NULL ) {    if ( ssl->prev == NULL ) {
945        
946      ssl_server->ssl_conn_list=ssl->next;      ssl_server->ssl_conn_list=ssl->next;
947    
948    } else {    } else {
# Line 866  int delete_accepted_ssl_socket (ssl_serv Line 953  int delete_accepted_ssl_socket (ssl_serv
953    
954    END_LOCK;      END_LOCK;  
955    
956    if (! cleanup_ssl_socket(ssl)) {    if(! cleanup_ssl_socket(ssl)) {
957    
958      return_value= FALSE;      return_value= FALSE;
959    
960    }    }
961              
962    if (! delete_ssl_socket(ssl)) {    if (! delete_ssl_socket(ssl)) {
963    
964      return_value= FALSE;      return_value= FALSE;
# Line 899  int embed_accepted_ssl_socket(ssl_connec Line 986  int embed_accepted_ssl_socket(ssl_connec
986    
987  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
988    
989      int ssl_error;
990      time_t ssl_time;
991    
992    ASSERT(ssl);    ASSERT(ssl);
993        
994    ssl->socket=socket;    ssl->socket=socket;
995    
996    if (!ssl_initilized) {    if(!ssl_initilized) {
997    
998      start_ssl();      start_ssl();
999    
1000    }    }
1001    
1002    if ((ssl->handler= SSL_new(ssl->ctx)) == NULL ) {    if((ssl->handler= SSL_new(ssl->ctx)) == NULL) {
   
     error("Cannot initialize the SSL handler!\n");  
1003    
1004        handle_ssl_error("embed_accepted_ssl_socket()");
1005        error("%s: Cannot initialize the SSL handler!\n", prog);
1006        goto sslerror;
1007    
1008    }    }
1009    
1010    if ( socket >= 0 ) {    if(socket < 0) {
     
     SSL_set_fd(ssl->handler, ssl->socket);  
   
   } else {  
1011    
1012      error("Socket error!\n");      error("Socket error!\n");
1013      goto sslerror;      goto sslerror;
1014    
1015    }    }
1016    
1017    if (SSL_accept(ssl->handler) == -1) {    set_noblock(ssl->socket);
1018    
1019      if((ssl->socket_bio= BIO_new_socket(ssl->socket, BIO_NOCLOSE)) == NULL) {
1020    
1021      error("Accept with SSL service has failed!\n");      handle_ssl_error("embed_accepted_ssl_socket()");
1022        error("%s: Cannot generate IO buffer!\n", prog);
1023      goto sslerror;      goto sslerror;
1024    
1025    }    }
1026    
1027      SSL_set_bio(ssl->handler, ssl->socket_bio, ssl->socket_bio);
1028    
1029      ssl_time= time(NULL);
1030      
1031      while((ssl_error= SSL_accept(ssl->handler)) < 0) {
1032    
1033        if((time(NULL)-ssl_time) > SSL_TIMEOUT) {
1034    
1035          error("%s: The connection process with the SSL service timed out!\n",
1036                prog);
1037          goto sslerror;
1038          
1039        }
1040    
1041        if (!handle_connection_error(ssl_error, ssl,
1042                                     "embed_accepted_ssl_socket()")) {
1043    
1044          goto sslerror;
1045    
1046        }
1047    
1048      }
1049    
1050    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);
1051    
1052    if (! update_ssl_cert_data(ssl) && (ssl->clientpemfile != NULL)) {    if(!update_ssl_cert_data(ssl) && (ssl->clientpemfile != NULL)) {
1053    
1054      error("The client did not supply a required client certificate!\n");      error("%s: The client did not supply a required client certificate!\n",
1055              prog);
1056        goto sslerror;
1057    
1058      }
1059    
1060      if (SSL_get_verify_result(ssl->handler)>0) {
1061    
1062        error("%s: Verification of the certificate has failed!\n",
1063              prog);
1064      goto sslerror;      goto sslerror;
1065    
1066    }    }
# Line 975  ssl_connection *accept_ssl_socket(ssl_se Line 1098  ssl_connection *accept_ssl_socket(ssl_se
1098    no_crypt_socket= accept(ssl_server->server_socket, (struct sockaddr*)&in,    no_crypt_socket= accept(ssl_server->server_socket, (struct sockaddr*)&in,
1099                            &len);                            &len);
1100    
1101    if ( no_crypt_socket >= 0 ) {    if(no_crypt_socket >= 0) {
1102            
1103      ssl_connection *ssl = insert_accepted_ssl_socket(ssl_server);      ssl_connection *ssl = insert_accepted_ssl_socket(ssl_server);
1104            
1105      if ( ssl == NULL ) {      if(ssl == NULL) {
1106    
1107        return NULL;        return NULL;
1108    
1109      }      }
1110    
1111      if (embed_accepted_ssl_socket(ssl, no_crypt_socket)) {      if(embed_accepted_ssl_socket(ssl, no_crypt_socket)) {
1112    
1113        return ssl;        return ssl;
1114    
# Line 1021  ssl_connection *accept_ssl_socket(ssl_se Line 1144  ssl_connection *accept_ssl_socket(ssl_se
1144  int send_ssl_socket(ssl_connection *ssl, void *buffer, int len) {  int send_ssl_socket(ssl_connection *ssl, void *buffer, int len) {
1145    
1146  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1147      int ssl_error;
1148      time_t ssl_time= time(NULL);
1149    
1150    ASSERT(ssl);    ASSERT(ssl);
1151    
1152    return SSL_write (ssl->handler, (void *) buffer, len);  
1153      while((ssl_error= SSL_write (ssl->handler, (void *) buffer, len))  < 0) {
1154    
1155        if((time(NULL)-ssl_time) > SSL_TIMEOUT) {
1156    
1157          error("%s: The connection process with the SSL service has timed"
1158                " out!\n", prog);
1159          break;
1160          
1161        }
1162    
1163        if (!handle_connection_error(ssl_error, ssl, "send_ssl_socket()")) {
1164    
1165          break;
1166    
1167        }
1168    
1169      }
1170    
1171      return ssl_error;
1172    
1173  #else  #else
1174    
# Line 1045  int send_ssl_socket(ssl_connection *ssl, Line 1189  int send_ssl_socket(ssl_connection *ssl,
1189  int recv_ssl_socket(ssl_connection *ssl, void *buffer, int len) {  int recv_ssl_socket(ssl_connection *ssl, void *buffer, int len) {
1190    
1191  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1192      int ssl_error;
1193      time_t ssl_time= time(NULL);
1194    
1195    ASSERT(ssl);    ASSERT(ssl);
1196    
1197    return SSL_read(ssl->handler, (void *) buffer, len);    while((ssl_error= SSL_read(ssl->handler, (void *) buffer, len))  < 0) {
1198        
1199        if((time(NULL)-ssl_time) > SSL_TIMEOUT) {
1200    
1201          error("%s: The connection process with the SSL service has timed"
1202                " out!\n", prog);
1203          break;
1204          
1205        }
1206    
1207        if (!handle_connection_error(ssl_error, ssl, "recv_ssl_socket()")) {
1208    
1209          break;
1210    
1211        }
1212      }
1213    
1214      return ssl_error;
1215    
1216  #else  #else
1217    
# Line 1165  int start_ssl() { Line 1328  int start_ssl() {
1328    if (! ssl_initilized ) {    if (! ssl_initilized ) {
1329    
1330      ssl_initilized=TRUE;      ssl_initilized=TRUE;
1331        ERR_load_crypto_strings();
1332      return (ssl_thread_start() && SSL_library_init() && ssl_entropy_start());      return (ssl_thread_start() && SSL_library_init() && ssl_entropy_start());
1333    
1334    } else {    } else {
# Line 1193  int stop_ssl() { Line 1357  int stop_ssl() {
1357    if ( ssl_initilized ) {    if ( ssl_initilized ) {
1358    
1359      ssl_initilized=FALSE;      ssl_initilized=FALSE;
1360        ERR_free_strings();
1361      return (ssl_thread_stop() && ssl_entropy_stop());      return (ssl_thread_stop() && ssl_entropy_stop());
1362    
1363    } else {    } else {
# Line 1241  ssl_connection *new_ssl_connection(char Line 1406  ssl_connection *new_ssl_connection(char
1406    
1407    }    }
1408    
1409      ssl->socket_bio= NULL;
1410    ssl->handler= NULL;    ssl->handler= NULL;
1411    ssl->cert= NULL;    ssl->cert= NULL;
1412    ssl->cipher= NULL;    ssl->cipher= NULL;
# Line 1262  ssl_connection *new_ssl_connection(char Line 1428  ssl_connection *new_ssl_connection(char
1428    
1429    if ((ssl->method= SSLv23_client_method()) == NULL ) {    if ((ssl->method= SSLv23_client_method()) == NULL ) {
1430    
1431      error("Cannot initilize SSL method!\n");      handle_ssl_error("new_ssl_connection()");
1432        error("%s: Cannot initilize SSL method!\n", prog);
1433      goto sslerror;      goto sslerror;
1434    
1435    }    }
1436    
1437    if ((ssl->ctx= SSL_CTX_new (ssl->method)) == NULL ) {    if ((ssl->ctx= SSL_CTX_new (ssl->method)) == NULL ) {
1438    
1439      error("Cannot initilize SSL server certificate handler!\n");      handle_ssl_error("new_ssl_connection()");
1440        error("%s: Cannot initilize SSL server certificate handler!\n", prog);
1441      goto sslerror;      goto sslerror;
1442    
1443    }    }
# Line 1279  ssl_connection *new_ssl_connection(char Line 1447  ssl_connection *new_ssl_connection(char
1447      if (SSL_CTX_use_certificate_file(ssl->ctx, ssl->clientpemfile,      if (SSL_CTX_use_certificate_file(ssl->ctx, ssl->clientpemfile,
1448                                       SSL_FILETYPE_PEM) <= 0) {                                       SSL_FILETYPE_PEM) <= 0) {
1449    
1450        error("Cannot initilize SSL server certificate!\n");        handle_ssl_error("new_ssl_connection()");
1451          error("%s: Cannot initilize SSL server certificate!\n", prog);
1452        goto sslerror;        goto sslerror;
1453                
1454      }      }
# Line 1287  ssl_connection *new_ssl_connection(char Line 1456  ssl_connection *new_ssl_connection(char
1456      if (SSL_CTX_use_PrivateKey_file(ssl->ctx, ssl->clientpemfile,      if (SSL_CTX_use_PrivateKey_file(ssl->ctx, ssl->clientpemfile,
1457                                      SSL_FILETYPE_PEM) <= 0) {                                      SSL_FILETYPE_PEM) <= 0) {
1458    
1459        error("Cannot initilize SSL server private key!\n");        handle_ssl_error("new_ssl_connection()");
1460          error("%s: Cannot initilize SSL server private key!\n", prog);
1461        goto sslerror;        goto sslerror;
1462    
1463      }      }
1464    
1465      if (!SSL_CTX_check_private_key(ssl->ctx)) {      if (!SSL_CTX_check_private_key(ssl->ctx)) {
1466    
1467        error("Private key does not match the certificate public key!\n");        handle_ssl_error("new_ssl_connection()");
1468          error("%s: Private key does not match the certificate public key!\n",
1469                prog);
1470        goto sslerror;        goto sslerror;
1471    
1472      }      }
# Line 1323  ssl_connection *new_ssl_connection(char Line 1495  ssl_connection *new_ssl_connection(char
1495   * Generate a new ssl server connection   * Generate a new ssl server connection
1496   * @return ssl server connection container   * @return ssl server connection container
1497   */   */
1498  ssl_server_connection *new_ssl_server_connection(char * pemfile, char * clientpemfile) {  ssl_server_connection *new_ssl_server_connection(char * pemfile,
1499                                                     char * clientpemfile) {
1500    
1501  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1502    
1503    ssl_server_connection *ssl_server = (ssl_server_connection *) NEW(ssl_server);    ssl_server_connection *ssl_server =
1504        (ssl_server_connection *) NEW(ssl_server);
1505    
1506    ASSERT(pemfile);    ASSERT(pemfile);
1507    
# Line 1384  int have_ssl(void) { Line 1558  int have_ssl(void) {
1558    
1559  /* ----------------------------------------------------------------- Private */  /* ----------------------------------------------------------------- Private */
1560    
   
   
1561  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1562    
   
1563  /**  /**
1564   * Init verification of transmitted client certs   * Init verification of transmitted client certs
1565   */   */
# Line 1398  static int verify_init(ssl_server_connec Line 1569  static int verify_init(ssl_server_connec
1569    
1570    if (ssl_server->clientpemfile==NULL) {    if (ssl_server->clientpemfile==NULL) {
1571    
1572        allow_any_purpose= TRUE;
1573      SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER ,      SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER ,
1574                         verify_callback_noclientcert);                         verify_callback_noclientcert);
1575      goto end_success; /* No verification, but we have to call the callback! */      goto end_success; /* No verification, but we have to call the callback! */
# Line 1418  static int verify_init(ssl_server_connec Line 1590  static int verify_init(ssl_server_connec
1590      if (!SSL_CTX_load_verify_locations(ssl_server->ctx, NULL ,      if (!SSL_CTX_load_verify_locations(ssl_server->ctx, NULL ,
1591                                         ssl_server->clientpemfile)) {                                         ssl_server->clientpemfile)) {
1592    
1593          handle_ssl_error("verify_init()");
1594        error("%s: Error setting verify directory to %s\n",        error("%s: Error setting verify directory to %s\n",
1595              Run.httpsslclientpem);              Run.httpsslclientpem);
1596    
# Line 1432  static int verify_init(ssl_server_connec Line 1605  static int verify_init(ssl_server_connec
1605      if(!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile,      if(!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile,
1606                                        NULL)) {                                        NULL)) {
1607    
1608          handle_ssl_error("verify_init()");
1609        error("%s: Error loading verify certificates from %s\n",        error("%s: Error loading verify certificates from %s\n",
1610              prog, ssl_server->pemfile);              prog, ssl_server->pemfile);
1611    
# Line 1443  static int verify_init(ssl_server_connec Line 1617  static int verify_init(ssl_server_connec
1617    
1618    } else if (S_ISREG(stat_buf.st_mode)) {    } else if (S_ISREG(stat_buf.st_mode)) {
1619    
1620      if(!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->clientpemfile,      if(!SSL_CTX_load_verify_locations(ssl_server->ctx,
1621                                          ssl_server->clientpemfile,
1622                                        NULL)) {                                        NULL)) {
1623    
1624          handle_ssl_error("verify_init()");
1625        error("%s: Error loading verify certificates from %s\n",        error("%s: Error loading verify certificates from %s\n",
1626              prog, Run.httpsslclientpem);              prog, Run.httpsslclientpem);
1627    
# Line 1460  static int verify_init(ssl_server_connec Line 1636  static int verify_init(ssl_server_connec
1636      if(!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile,      if(!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile,
1637                                        NULL)) {                                        NULL)) {
1638    
1639          handle_ssl_error("verify_init()");
1640        error("%s: Error loading verify certificates from %s\n",        error("%s: Error loading verify certificates from %s\n",
1641              prog, ssl_server->pemfile);              prog, ssl_server->pemfile);
1642    
# Line 1481  static int verify_init(ssl_server_connec Line 1658  static int verify_init(ssl_server_connec
1658    
1659    }    }
1660    
1661      allow_any_purpose= FALSE;
1662    SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER , verify_callback);    SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER , verify_callback);
1663    
1664   end_success:   end_success:
# Line 1505  static int verify_callback(int preverify Line 1683  static int verify_callback(int preverify
1683    
1684    if(!preverify_ok) {    if(!preverify_ok) {
1685    
1686      if (ctx->error != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {      if (!check_preverify(ctx)) {
1687    
1688        /* Remote site specified a certificate, but it's not correct */        goto reject;
   
       log("SSL VERIFY ERROR: depth=%d, error=[%d] '%s': %s\n",  
           ctx->error_depth, ctx->error,  
           X509_verify_cert_error_string (ctx->error), subject);  
       goto reject; /* Reject connection */  
   
     } else {  
   
       if(allow_self_certfication) {  
   
         /* Let's accept self signed Certs for the moment! */  
   
         log("SSL VERIFY WARNING: depth=%d, error=[%d] '%s': %s\n",  
             ctx->error_depth, ctx->error,  
             X509_verify_cert_error_string (ctx->error), subject);  
   
       } else {  
   
         log("SSL VERIFY ERROR: depth=%d, error=[%d] '%s': %s\n",  
             ctx->error_depth, ctx->error,  
             X509_verify_cert_error_string (ctx->error), subject);  
         goto reject; /* Reject connection */  
   
       }  
1689    
1690      }      }
1691    
# Line 1542  static int verify_callback(int preverify Line 1696  static int verify_callback(int preverify
1696                                 X509_get_subject_name(ctx->current_cert),                                 X509_get_subject_name(ctx->current_cert),
1697                                 &found_cert)!=1) {                                 &found_cert)!=1) {
1698    
1699      log("SSL VERIFY ERROR: no cert found for %s\n", subject);      handle_ssl_error("verify_callback()");
1700        error("%s: SSL connection rejected. No matching certificate found.", prog);
1701    
1702      goto reject;      goto reject;
1703    
# Line 1551  static int verify_callback(int preverify Line 1706  static int verify_callback(int preverify
1706    return 1;    return 1;
1707    
1708   reject:   reject:
   log("HTTPD connection denied!\n");  
1709    return 0;    return 0;
1710    
1711  }  }
# Line 1569  static int verify_callback_noclientcert( Line 1723  static int verify_callback_noclientcert(
1723    
1724    if(!preverify_ok) {    if(!preverify_ok) {
1725    
1726      if (ctx->error != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {      if (!check_preverify(ctx)) {
1727    
1728        /* Remote site specified a certificate, but it's not correct */        goto reject;
1729    
1730        log("SSL VERIFY ERROR: depth=%d, error=[%d] '%s': %s\n",      }
           ctx->error_depth, ctx->error,  
           X509_verify_cert_error_string (ctx->error), subject);  
       goto reject; /* Reject connection */  
1731    
1732      } else {    }
1733    
1734        if(allow_self_certfication) {    return 1;
1735    
1736          /* Let's accept self signed Certs for the moment! */   reject:
1737      return 0;
1738    
1739          log("SSL VERIFY WARNING: depth=%d, error=[%d] '%s': %s\n",  }
             ctx->error_depth, ctx->error,  
             X509_verify_cert_error_string (ctx->error), subject);  
1740    
1741        } else {  /**
1742     * Analyse errors found before actual verification
1743     * @return TRUE if successful
1744     */
1745    static int check_preverify(X509_STORE_CTX *ctx) {
1746    
1747          log("SSL VERIFY ERROR: depth=%d, error=[%d] '%s': %s\n",    if ((ctx->error != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) &&
1748              ctx->error_depth, ctx->error,        (ctx->error != X509_V_ERR_INVALID_PURPOSE)) {
             X509_verify_cert_error_string (ctx->error), subject);  
         goto reject; /* Reject connection */  
1749    
1750        }      /* Remote site specified a certificate, but it's not correct */
1751        
1752        error("%s: SSL connection rejected because certificate verification"
1753              " has failed -- Error %i\n", prog, ctx->error);
1754        return FALSE; /* Reject connection */
1755    
1756      }    }
1757    
   }  
1758    
1759    return 1;    if(allow_self_certfication &&
1760         (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) {
1761        
1762        /* Let's accept self signed certs for the moment! */
1763        
1764        log("SSL connection accepted with self signed certificate!\n");
1765    
1766   reject:      ctx->error=0;
1767    log("HTTPD connection denied!\n");      return TRUE;
   return 0;  
1768    
1769  }    }
1770    
1771      if(allow_any_purpose &&
1772         (ctx->error == X509_V_ERR_INVALID_PURPOSE)) {
1773        
1774        /* Let's accept any purpose certs for the moment! */
1775        
1776        log("SSL connection accepted with invalid purpose!\n");
1777    
1778        ctx->error=0;
1779        return TRUE;
1780    
1781      }
1782        
1783      error("%s: SSL connection rejected because certificate verification"
1784            " has failed -- Error %i!\n", prog, ctx->error);
1785      return FALSE; /* Reject connection */
1786    
1787    
1788    }
1789    
1790    /**
1791     * Print info about the verification engine
1792     */
1793  static void verify_info(ssl_server_connection *ssl_server) {  static void verify_info(ssl_server_connection *ssl_server) {
1794        
1795    STACK_OF(X509_NAME) *stack;    STACK_OF(X509_NAME) *stack;
# Line 1723  static int ssl_entropy_stop(void) { Line 1903  static int ssl_entropy_stop(void) {
1903    
1904  }  }
1905    
1906    
1907    /**
1908     * Handle errors during read, write, connect and accept
1909     * @return TRUE if non fatal, FALSE if non fatal and retry
1910     */
1911    static int handle_connection_error(int code, ssl_connection *ssl,
1912                                       char *operation) {
1913    
1914      int ssl_error= 0;
1915    
1916      switch ((ssl_error= SSL_get_error(ssl->handler, code))) {
1917        
1918      case SSL_ERROR_WANT_READ:
1919      case SSL_ERROR_WANT_WRITE:
1920        return TRUE;
1921        
1922      case SSL_ERROR_SYSCALL:
1923        error("%s: Openssl syscall error during %s: %s!\n", prog, operation,
1924              STRERROR);
1925        return FALSE;
1926    
1927      case SSL_ERROR_SSL:
1928        handle_ssl_error(operation);
1929        return FALSE;
1930          
1931      default:
1932        error("%s: Openssl error during %s!\n", prog, operation);
1933        return FALSE;
1934    
1935      }
1936    
1937      return FALSE;
1938    }
1939    
1940    
1941    /**
1942     * Handle errors of arbitrary SSL calls
1943     */
1944    static void handle_ssl_error(char *operation) {
1945    
1946      error("%s: Openssl engine error during %s: %s\n", prog, operation, SSLERROR);
1947    
1948    }
1949    
1950  #endif  #endif

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26