Bläddra i källkod

Added the SSL_LogIpAddr flag and fixed up log messages to include
the IP address of the remote. Also got rid of the ssl_adh_key
option, since coding for it was getting difficult, and it's not
really required if SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE)
is called, which it now is.

John C. Frickson 10 år sedan
förälder
incheckning
0d007a3def
1 ändrade filer med 48 tillägg och 94 borttagningar
  1. 48 94
      src/nrpe.c

+ 48 - 94
src/nrpe.c

@@ -80,13 +80,13 @@ char    *command_prefix=NULL;
 
 /* SSL/TLS parameters */
 typedef enum _SSL_VER { SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus, TLSv1,
-					TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
+    	TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
 				} SslVer;
 typedef enum _CLNT_CERTS {
-					Ask_For_Cert = 1, Require_Cert = 2
+		Ask_For_Cert = 1, Require_Cert = 2
 				} ClntCerts;
-typedef enum _SSL_LOGGING { SSL_NoLogging, SSL_LogStartup, SSL_LogVersion,
-					SSL_LogCipher, SSL_LogIfClientCert, SSL_LogCertDetails
+typedef enum _SSL_LOGGING { SSL_NoLogging, SSL_LogStartup, SSL_LogIpAddr,
+        SSL_LogVersion, SSL_LogCipher, SSL_LogIfClientCert, SSL_LogCertDetails
 				} SslLogging;
 struct _SSL_PARMS {
 	char		*cert_file;
@@ -101,6 +101,8 @@ struct _SSL_PARMS {
 	SslLogging	log_opts;
 } sslprm = { NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", NULL, 0, TLSv1_plus, TRUE, 0, 0 };
 
+char	remote_host[MAX_HOST_ADDRESS_LENGTH];
+
 command *command_list=NULL;
 
 char    *nrpe_user=NULL;
@@ -134,7 +136,7 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx);
 
 int main(int argc, char **argv){
 	int result=OK;
-	int x, ssl_opts = SSL_OP_ALL, vrfy;
+	int x, ssl_opts = SSL_OP_ALL|SSL_OP_SINGLE_DH_USE, vrfy;
 	char buffer[MAX_INPUT_BUFFER];
 	char *env_string=NULL;
 #ifdef HAVE_SSL
@@ -378,27 +380,9 @@ int main(int argc, char **argv){
 			/* use anonymous DH ciphers */
 			if (sslprm.allowDH == 2)
 				SSL_CTX_set_cipher_list(ctx, "ADH");
-			if (sslprm.adh_key != NULL && sslprm.adhk_len > 0) {
-				if ((dh=DH_new()) == NULL) {
-					syslog(LOG_ERR, "Error: could not create DH object");
-					exit(STATE_CRITICAL);
-				}
-				dh->p = BN_bin2bn(sslprm.adh_key, sslprm.adhk_len, NULL);
-				dh->g = BN_bin2bn("\2", 2, NULL);
-				if ((dh->p == NULL) || (dh->g == NULL)) {
-					DH_free(dh);
-					SSL_CTX_free(ctx);
-					syslog(LOG_ERR, "Error: could not create DH object");
-					exit(STATE_CRITICAL);
-				}
-				SSL_CTX_set_tmp_dh(ctx, dh);
-				DH_free(dh);
-			} else {
-				dh = get_dh2048();
-				SSL_CTX_set_tmp_dh(ctx, dh);
-				DH_free(dh);
-			}
-
+			dh = get_dh2048();
+			SSL_CTX_set_tmp_dh(ctx, dh);
+			DH_free(dh);
 		}
 		
 		if(debug==TRUE)
@@ -858,52 +842,6 @@ int read_config_file(char *filename){
 				sslprm.client_certs |= Ask_For_Cert;
 		}
 
-		else if (!strcmp(varname, "ssl_adh_key")) {
-			if (!strncmp(varvalue, "B64:", 4)) {
-				sslprm.adh_key = strdup(&varvalue[4]);
-				sslprm.adhk_len = b64_decode(sslprm.adh_key);
-			} else {
-				sslprm.adh_key = strdup(varvalue);
-				if (sslprm.adh_key[0] != '/' && sslprm.adh_key[0] != '\\' && strncmp(&sslprm.adh_key[1], ":\\", 2)) {
-					syslog(LOG_ERR, "Invalid ssl adh key value specified in config file '%s' - Line %d", filename, line);
-					return ERROR;
-				}
-				if ((pskfd = open(sslprm.adh_key, O_RDONLY)) < 0) {
-					syslog(LOG_ERR, "Unable to open adh key file '%s' for reading", pskfd);
-					return ERROR;
-				}
-				if (fstat(pskfd, &st) < 0) {
-					close(pskfd);
-					syslog(LOG_ERR, "Unable to stat adh key file '%s'", pskfd);
-					return ERROR;
-				}
-				if (st.st_mode != S_IFREG) {
-					close(pskfd);
-					syslog(LOG_ERR, "adh key file '%s' is not a regular file", pskfd);
-					return ERROR;
-				}
-				if (st.st_size == 0 || st.st_size > 4096) {
-					close(pskfd);
-					syslog(LOG_ERR, "adh key file '%s' is not a valid file", pskfd);
-					return ERROR;
-				}
-				if (st.st_size > strlen(sslprm.adh_key)) {
-					if ((sslprm.adh_key = realloc(sslprm.adh_key, st.st_size))  == NULL) {
-						close(pskfd);
-						syslog(LOG_ERR, "Memory allocation error");
-						return ERROR;
-					}
-				}
-				sslprm.adhk_len = st.st_size;
-				if (read(pskfd, sslprm.adh_key, sslprm.adhk_len) != sslprm.adhk_len) {
-					close(pskfd);
-					syslog(LOG_ERR, "Error reading adh key file '%s'", pskfd);
-					return ERROR;
-				}
-				close(pskfd);
-			}
-		}
-
 		else if(!strcmp(varname,"log_facility")){
 			if((get_log_facility(varvalue))==OK){
 				/* re-open log using new facility */
@@ -1351,11 +1289,12 @@ void wait_for_connections(void){
 							nptr = (struct sockaddr_in *)&addr;
 
 							/* log info to syslog facility */
-							if(debug==TRUE) {
+							strncpy(remote_host, inet_ntoa(nptr->sin_addr), sizeof(remote_host) - 1);
+							remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
+							if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr)) {
 								syslog(LOG_DEBUG, "Connection from %s port %d",
-										inet_ntoa(nptr->sin_addr), 
-										nptr->sin_port);
-								}
+										remote_host,  nptr->sin_port);
+							}
 							if(!is_an_allowed_host(AF_INET,
 									(void *)&(nptr->sin_addr))) {
 								/* log error to syslog facility */
@@ -1392,10 +1331,11 @@ void wait_for_connections(void){
 								} 
 
 							/* log info to syslog facility */
-							if(debug==TRUE) {
+							strcpy(remote_host, ipstr);
+							if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr)) {
 								syslog(LOG_DEBUG, "Connection from %s port %d",
 										ipstr, nptr6->sin6_port);
-								}
+							}
 							if(!is_an_allowed_host(AF_INET6, 
 									(void *)&(nptr6->sin6_addr))) {
 								/* log error to syslog facility */
@@ -1548,16 +1488,25 @@ void handle_connection(int sock){
 	if (result == STATE_OK && use_ssl == TRUE) {
 		if ((ssl = SSL_new(ctx)) != NULL) {
 			SSL_set_fd(ssl,sock);
-
+ 
 			/* keep attempting the request if needed */
 			while (((rc = SSL_accept(ssl)) != 1) && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
 
 			if (rc != 1) {
 				if (sslprm.log_opts & (SSL_LogCertDetails|SSL_LogIfClientCert)) {
-					while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0)
-						syslog(LOG_ERR, "Error: Could not complete SSL handshake: %s", ERR_reason_error_string(x));
+					int	nerrs = 0;
+					rc = 0;
+					while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
+						syslog(LOG_ERR, "Error: Could not complete SSL handshake with %s: %s",
+								remote_host, ERR_reason_error_string(x));
+						++nerrs;
+					}
+					if (nerrs == 0)
+						syslog(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
+								remote_host, SSL_get_error(ssl,rc));
 				} else
-					syslog(LOG_ERR, "Error: Could not complete SSL handshake. %d", SSL_get_error(ssl,rc));
+					syslog(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
+							remote_host, SSL_get_error(ssl,rc));
 #ifdef DEBUG
 				errfp = fopen("/tmp/err.log", "a");
 				ERR_print_errors_fp(errfp);
@@ -1566,27 +1515,31 @@ void handle_connection(int sock){
 				return;
 			}
 			if (sslprm.log_opts & SSL_LogVersion)
-				syslog(LOG_NOTICE, "SSL Version: %s", SSL_get_version(ssl));
+				syslog(LOG_NOTICE, "Remote %s - SSL Version: %s",
+						remote_host, SSL_get_version(ssl));
 			if (sslprm.log_opts & SSL_LogCipher) {
 				c = SSL_get_current_cipher(ssl);
-				syslog(LOG_NOTICE, "%s, Cipher is %s",
+				syslog(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host,
 					   SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
 			}
 			if ((sslprm.log_opts & SSL_LogIfClientCert) || (sslprm.log_opts & SSL_LogCertDetails)) {
 				peer = SSL_get_peer_certificate(ssl);
 				if (peer) {
 					if (sslprm.log_opts & SSL_LogIfClientCert)
-						syslog(LOG_NOTICE, "SSL Client has %s certificate",
-								peer->valid ? "a valid" : "an invalid");
+						syslog(LOG_NOTICE, "SSL Client %s has %s certificate",
+								remote_host, peer->valid ? "a valid" : "an invalid");
 					if (sslprm.log_opts & SSL_LogCertDetails) {
-						syslog(LOG_NOTICE, "SSL Client Cert Name: %s", peer->name);
+						syslog(LOG_NOTICE, "SSL Client %s Cert Name: %s",
+								remote_host, peer->name);
 						X509_NAME_oneline(X509_get_issuer_name(peer), buffer, sizeof(buffer));
-						syslog(LOG_NOTICE, "SSL Client Cert Issuer: %s", buffer);
+						syslog(LOG_NOTICE, "SSL Client %s Cert Issuer: %s",
+								remote_host, buffer);
 					}
 				} else if (sslprm.client_certs == 0)
 					syslog(LOG_NOTICE, "SSL Not asking for client certification");
 				else
-					syslog(LOG_NOTICE, "SSL Client did not present a certificate");
+					syslog(LOG_NOTICE, "SSL Client %s did not present a certificate",
+							remote_host);
 			}
 		}
 		else {
@@ -1614,7 +1567,7 @@ void handle_connection(int sock){
 	if(rc<=0){
 
 		/* log error to syslog facility */
-		syslog(LOG_ERR,"Could not read request from client, bailing out...");
+		syslog(LOG_ERR,"Could not read request from client %s, bailing out...", remote_host);
 
 #ifdef HAVE_SSL
 		if(ssl){
@@ -1631,7 +1584,7 @@ void handle_connection(int sock){
 	else if(bytes_to_recv!=sizeof(receive_packet)){
 
 		/* log error to syslog facility */
-		syslog(LOG_ERR,"Data packet from client was too short, bailing out...");
+		syslog(LOG_ERR,"Data packet from client (%s) was too short, bailing out...", remote_host);
 
 #ifdef HAVE_SSL
 		if(ssl){
@@ -1655,7 +1608,7 @@ void handle_connection(int sock){
 	if(validate_request(&receive_packet)==ERROR){
 
 		/* log an error */
-		syslog(LOG_ERR,"Client request was invalid, bailing out...");
+		syslog(LOG_ERR,"Client request from %s was invalid, bailing out...", remote_host);
 
 		/* free memory */
 		free(command_name);
@@ -1677,7 +1630,8 @@ void handle_connection(int sock){
 
 	/* log info to syslog facility */
 	if(debug==TRUE)
-		syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer);
+		syslog(LOG_DEBUG,"Host %s is asking for command '%s' to be run...",
+				remote_host, receive_packet.buffer);
 
 	/* disable connection alarm - a new alarm will be setup during my_system */
 	alarm(0);
@@ -1690,7 +1644,7 @@ void handle_connection(int sock){
 
 		/* log info to syslog facility */
 		if(debug==TRUE)
-			syslog(LOG_DEBUG,"Response: %s",buffer);
+			syslog(LOG_DEBUG,"Response to %s: %s", remote_host, buffer);
 
 		result=STATE_OK;
 	        }