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

Diff of /monit/ssl.c

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

revision 1.4 by chopp, Thu Oct 10 16:08:53 2002 UTC revision 1.5 by chopp, Fri Oct 11 20:59:58 2002 UTC
# Line 31  Line 31 
31  #include <netdb.h>  #include <netdb.h>
32  #include <pthread.h>  #include <pthread.h>
33  #include <unistd.h>  #include <unistd.h>
34    #include <errno.h>
35    
36    #ifdef HAVE_STRING_H
37    #include <string.h>
38    #endif
39    
40    
41  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
42  #include <openssl/crypto.h>  #include <openssl/crypto.h>
# Line 56  static void ssl_mutex_lock(int mode, int Line 62  static void ssl_mutex_lock(int mode, int
62  static int ssl_entropy_start(void);  static int ssl_entropy_start(void);
63  static int ssl_entropy_stop(void);  static int ssl_entropy_stop(void);
64    
65    static int verify_init(ssl_server_connection * );
66  static int verify_callback(int, X509_STORE_CTX *);  static int verify_callback(int, X509_STORE_CTX *);
67    static void verify_info(ssl_server_connection *);
68    
69  static pthread_mutex_t   ssl_mutex= PTHREAD_MUTEX_INITIALIZER;  static pthread_mutex_t   ssl_mutex= PTHREAD_MUTEX_INITIALIZER;
70  static pthread_mutex_t * ssl_mutex_table;  static pthread_mutex_t * ssl_mutex_table;
# Line 140  int embed_ssl_socket (ssl_connection * s Line 148  int embed_ssl_socket (ssl_connection * s
148    
149    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);
150    
   /*  
   if ((ssl->cert = SSL_get_peer_certificate (ssl->handler)) == NULL) {  
   
     error("Cannot get SSL server certificate!\n");  
     goto sslerror;  
   
   }  
   
   ssl->cert_issuer=X509_NAME_oneline (X509_get_issuer_name (ssl->cert),0,0);  
   ssl->cert_subject=X509_NAME_oneline (X509_get_subject_name (ssl->cert),0,0);  
   
   */  
   
151    if (! update_ssl_cert_data(ssl)) {    if (! update_ssl_cert_data(ssl)) {
152    
153      error("Cannot get SSL server certificate!\n");      error("Cannot get SSL server certificate!\n");
# Line 217  ssl_connection * create_ssl_socket(char Line 212  ssl_connection * create_ssl_socket(char
212  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
213    
214    int socket;    int socket;
215    ssl_connection * ssl = new_ssl_connection();    ssl_connection * ssl = new_ssl_connection(NULL);
216    
217    if ((socket= create_socket(hostname, port, protocol)) == -1) {    if ((socket= create_socket(hostname, port, protocol)) == -1) {
218    
# Line 427  ssl_server_connection * init_ssl_server Line 422  ssl_server_connection * init_ssl_server
422    /**    /**
423     * We do need this to force transmission of client certs     * We do need this to force transmission of client certs
424     */     */
425    SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER, verify_callback);    if (!verify_init(ssl_server)) {
426    
427        error("Verification engine was not properly initilized!\n");
428        goto sslerror;
429    
430      }
431      verify_info(ssl_server);
432    
433    return ssl_server;    return ssl_server;
434    
# Line 607  ssl_connection * insert_accepted_ssl_soc Line 608  ssl_connection * insert_accepted_ssl_soc
608    
609  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
610    
611    ssl_connection * ssl = new_ssl_connection();    ssl_connection * ssl = new_ssl_connection(NULL);
612    
613    if(( ssl_server == NULL ) || (ssl == NULL)) {    if(( ssl_server == NULL ) || (ssl == NULL)) {
614    
# Line 655  int close_accepted_ssl_socket(ssl_server Line 656  int close_accepted_ssl_socket(ssl_server
656    
657  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
658    
659      int return_value= TRUE;
660    
661    if ((ssl == NULL) ||  (ssl_server == NULL)) {    if ((ssl == NULL) ||  (ssl_server == NULL)) {
662      return FALSE;      return FALSE;
663    }    }
664    
665    return (delete_accepted_ssl_socket(ssl_server,  ssl) && (close(ssl->socket) >= 0));    if (close(ssl->socket) < 0) {
666    
667        return_value= FALSE;
668    
669      }
670    
671      if (! delete_accepted_ssl_socket(ssl_server,  ssl)) {
672    
673        return_value= FALSE;
674    
675      }
676    
677      return return_value;
678    
679  #else  #else
680    
# Line 747  int embed_accepted_ssl_socket(ssl_connec Line 762  int embed_accepted_ssl_socket(ssl_connec
762    
763      error("Accept with SSL service has failed!\n");      error("Accept with SSL service has failed!\n");
764      goto sslerror;      goto sslerror;
765    
766    }    }
767    
768    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);    ssl->cipher= (char *) SSL_get_cipher(ssl->handler);
769    
770    update_ssl_cert_data(ssl);    if (! update_ssl_cert_data(ssl) && (Run.httpsslclientpem != NULL)) {
771    
772        error("Client did not supply required client certificate!\n");
773        goto sslerror;
774    
775      }
776    
777    return TRUE;    return TRUE;
778    
# Line 1000  int stop_ssl() { Line 1021  int stop_ssl() {
1021   * @return ssl connection container   * @return ssl connection container
1022   */   */
1023    
1024  ssl_connection * new_ssl_connection(void) {  ssl_connection * new_ssl_connection(char * clientpemfilename) {
1025    
1026  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1027    
# Line 1029  ssl_connection * new_ssl_connection(void Line 1050  ssl_connection * new_ssl_connection(void
1050    
1051    }    }
1052    
1053      if ( clientpemfilename!=NULL ) {
1054    
1055        if (SSL_CTX_use_certificate_file(ssl->ctx, clientpemfilename, SSL_FILETYPE_PEM) <= 0) {
1056    
1057          error("Cannot initilize SSL server certificate!\n");
1058          goto sslerror;
1059          
1060        }
1061    
1062        if (SSL_CTX_use_PrivateKey_file(ssl->ctx, clientpemfilename, SSL_FILETYPE_PEM) <= 0) {
1063    
1064          error("Cannot initilize SSL server private key!\n");
1065          goto sslerror;
1066    
1067        }
1068    
1069        if (!SSL_CTX_check_private_key(ssl->ctx)) {
1070    
1071          error("Private key does not match the certificate public key!\n");
1072          goto sslerror;
1073    
1074        }
1075    
1076      }
1077    
1078    
1079    return ssl;    return ssl;
1080    
1081   sslerror:   sslerror:
# Line 1097  int have_ssl(void) { Line 1144  int have_ssl(void) {
1144  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
1145    
1146  /**  /**
1147   * We do need this to force transmission of client certs   * Init verification of transmitted client certs
1148   * @return current thread number   */
1149    
1150    static int verify_init(ssl_server_connection * ssl_server) {
1151    
1152      struct stat stat_buf;
1153    
1154      if (Run.httpsslclientpem==NULL) {
1155    
1156         goto end_success; /* No verification, but we have to call the callback! */
1157    
1158      }
1159    
1160      if ( -1 == stat(Run.httpsslclientpem, &stat_buf )) {
1161    
1162        error("%s: Cannot stat the SSL pem path '%s' -- %s\n",
1163              prog, Run.httpsslclientpem, STRERROR);
1164    
1165        goto end_error;
1166    
1167      }
1168      
1169      if (S_ISDIR(stat_buf.st_mode)) {
1170    
1171        if (!SSL_CTX_load_verify_locations(ssl_server->ctx, NULL ,
1172                                           Run.httpsslclientpem)) {
1173    
1174          error("%s: Error setting verify directory to %s\n",
1175                Run.httpsslclientpem);
1176    
1177          goto end_error;
1178    
1179        }
1180    
1181        log("Loaded SSL client pem directory '%s'\n", Run.httpsslclientpem);
1182    
1183        /* Monits server cert for cli support ! */
1184    
1185        if(!SSL_CTX_load_verify_locations(ssl_server->ctx, Run.httpsslpem,
1186                                          NULL)) {
1187    
1188          error("%s: Error loading verify certificates from %s\n",
1189                prog, Run.httpsslclientpem);
1190    
1191          goto end_error;
1192    
1193        }
1194    
1195        log("Loaded monit's SSL pem server file '%s'\n", Run.httpsslpem);
1196    
1197      } else if (S_ISREG(stat_buf.st_mode)) {
1198    
1199        if(!SSL_CTX_load_verify_locations(ssl_server->ctx, Run.httpsslclientpem,
1200                                          NULL)) {
1201    
1202          error("%s: Error loading verify certificates from %s\n",
1203                prog, Run.httpsslclientpem);
1204    
1205          goto end_error;
1206    
1207        }
1208    
1209        log("Loaded SSL pem client file '%s'\n", Run.httpsslclientpem);
1210    
1211        /* Monits server cert for cli support ! */
1212    
1213        if(!SSL_CTX_load_verify_locations(ssl_server->ctx, Run.httpsslpem,
1214                                          NULL)) {
1215    
1216          error("%s: Error loading verify certificates from %s\n",
1217                prog, Run.httpsslclientpem);
1218    
1219          goto end_error;
1220    
1221        }
1222    
1223        log("Loaded monit's SSL pem server file '%s'\n", Run.httpsslpem);
1224    
1225        SSL_CTX_set_client_CA_list(ssl_server->ctx,
1226                                   SSL_load_client_CA_file(Run.httpsslclientpem));
1227    
1228      } else {
1229    
1230        error("%s: SSL client pem path is no file or directory %s\n",
1231              prog, Run.httpsslclientpem);
1232    
1233        goto end_error;
1234    
1235      }
1236    
1237     end_success:
1238    
1239        SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER , verify_callback);
1240    
1241        return TRUE;
1242    
1243     end_error:
1244    
1245        return FALSE;
1246    }
1247    
1248    
1249    /**
1250     * Check the transmitted client certs
1251   */   */
1252    
1253  static int verify_callback(int preverify, X509_STORE_CTX *ctx) {  static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
1254    return 1;  
1255      char subject[STRLEN];
1256      X509_OBJECT found_cert;
1257    
1258      X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), subject, STRLEN);
1259    
1260      if(!preverify_ok) {
1261    
1262        if (ctx->error != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
1263            Run.allowselfcert ) {
1264    
1265          /* Remote site specified a certificate, but it's not correct */
1266    
1267          log("SSL VERIFY ERROR: depth=%d, error=[%d] '%s': %s\n",
1268              ctx->error_depth, ctx->error,
1269              X509_verify_cert_error_string (ctx->error), subject);
1270          goto reject; /* Reject connection */
1271    
1272        } else {
1273    
1274          /* Let's accept self signed Certs for the moment! */
1275    
1276          log("SSL VERIFY WARNING: depth=%d, error=[%d] '%s': %s\n",
1277              ctx->error_depth, ctx->error,
1278              X509_verify_cert_error_string (ctx->error), subject);
1279    
1280        }
1281    
1282      }
1283    
1284      if(Run.httpsslclientpem==NULL) {
1285    
1286        goto accept;
1287    
1288      }
1289    
1290      if(ctx->error_depth==0 &&
1291         X509_STORE_get_by_subject(ctx, X509_LU_X509,
1292                                   X509_get_subject_name(ctx->current_cert),
1293                                   &found_cert)!=1) {
1294    
1295        log("SSL VERIFY ERROR: no cert found for %s\n", subject);
1296    
1297        goto reject;
1298    
1299      }
1300    
1301     accept:
1302      log("HTTPD connection accepted to %s!\n", subject);
1303      return 1; /* Accept connection */
1304    
1305     reject:
1306      log("HTTPD connection denied!\n");
1307      return 0; /* Reject connection */
1308    
1309  }  }
1310    
1311    static void verify_info(ssl_server_connection *ssl_server) {
1312        STACK_OF(X509_NAME) *stack;
1313    
1314        stack=SSL_CTX_get_client_CA_list(ssl_server->ctx);
1315        log("We have found there are %d certificates\n", sk_X509_NAME_num(stack));
1316    }
1317    
1318    
1319  /**  /**
1320   * Helper function for the SSL threadding support   * Helper function for the SSL threadding support
1321   * @return current thread number   * @return current thread number
# Line 1120  static int unsigned long ssl_thread_id(v Line 1331  static int unsigned long ssl_thread_id(v
1331   * Helper function for the SSL threadding support   * Helper function for the SSL threadding support
1332   */   */
1333    
1334  static void ssl_mutex_lock(int mode, int n, const char *file, int line) {  static void ssl_mutex_lock(int mode, int n, const char *file, int line) {
1335    
1336    
1337    if(mode & CRYPTO_LOCK) {    if(mode & CRYPTO_LOCK) {

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

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