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> |
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; |
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"); |
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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: |
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 |
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) { |