diff options
| -rw-r--r-- | NEWS | 1 | ||||
| -rw-r--r-- | daemon.c | 7 | ||||
| -rw-r--r-- | sink.c | 2 | ||||
| -rw-r--r-- | socket.c | 111 | 
4 files changed, 55 insertions, 66 deletions
| @@ -4,6 +4,7 @@  * SSL certificate options from Thomas Moestl <tmoestl@gmx.net>.  * Frantisek Brabec's patch for better UIDL error recovery. +* Another zombie-leak patch from HMH.  fetchmail-5.8.3 (Sat May 12 04:07:12 EDT 2001), 20502 lines: @@ -82,6 +82,11 @@ sigchld_handler (int sig)      lastsig = SIGCHLD;  } +/*  + * This function is called by other parts of the program to + * setup the sigchld handler after a change to the signal context. + * This is done to improve robustness of the signal handling code. + */  void deal_with_sigchld(void)  {    RETSIGTYPE sigchld_handler(int); @@ -95,7 +100,7 @@ void deal_with_sigchld(void)    /* set up to catch child process termination signals */     sa_new.sa_handler = sigchld_handler;  #ifdef SA_RESTART	/* SunOS 4.1 portability hack */ -  sa_new.sa_flags = SA_RESTART; +  sa_new.sa_flags = SA_RESTART | SA_NOCLDSTOP;  #endif    sigaction (SIGCHLD, &sa_new, NULL);  #if defined(SIGPWR) @@ -937,6 +937,7 @@ void release_sink(struct query *ctl)  #else  	sigaction (SIGCHLD, &sa_old, NULL);  #endif /* HAVE_SIGACTION */ +	deal_with_sigchld();      }  } @@ -960,6 +961,7 @@ int close_sink(struct query *ctl, struct msgblk *msg, flag forward)  #else  	sigaction (SIGCHLD, &sa_old, NULL);  #endif /* HAVE_SIGACTION */ +	deal_with_sigchld();  	if (rc)  	{  	    report(stderr,  @@ -657,93 +657,76 @@ SSL *SSLGetContext( int sock )  int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )  { -	char buf[260]; -	char cbuf[260]; -	char ibuf[260]; -	char *str_ptr; +	char buf[257];  	X509 *x509_cert;  	int err, depth;  	unsigned char digest[EVP_MAX_MD_SIZE];  	char text[EVP_MAX_MD_SIZE * 3 + 1], *tp, *te;  	EVP_MD *digest_tp;  	unsigned int dsz, i, esz; +	X509_NAME *subj, *issuer;  	x509_cert = X509_STORE_CTX_get_current_cert(ctx);  	err = X509_STORE_CTX_get_error(ctx);  	depth = X509_STORE_CTX_get_error_depth(ctx); +	subj = X509_get_subject_name(x509_cert); +	issuer = X509_get_issuer_name(x509_cert); +  	if (depth == 0) {  		_depth0ck = 1; -		X509_NAME_oneline(X509_get_subject_name(x509_cert), buf, 256); -		X509_NAME_oneline(X509_get_issuer_name(x509_cert), ibuf, 256); - -		/* Just to be sure those buffers are terminated...  I think the -		   X509 libraries do, but... */ -		buf[256] = ibuf[256] = '\0'; -		if( ( str_ptr = strstr( ibuf, "/O=" ) ) ) { -			str_ptr += 3; -			strcpy( cbuf, str_ptr ); -			if( ( str_ptr = strchr(cbuf, '/' ) ) ) { -				*str_ptr = '\0'; -			} -			if (outlevel == O_VERBOSE) -				report(stdout, _("Issuer Organization: %s\n"), cbuf ); -		} else { -			if (outlevel == O_VERBOSE) +		if (outlevel == O_VERBOSE) { +			if ((i = X509_NAME_get_text_by_NID(issuer, NID_organizationName, buf, sizeof(buf))) != -1) { +				report(stdout, _("Issuer Organization: %s\n"), buf); +				if (i >= sizeof(buf) - 1) +					report(stdout, _("Warning: Issuer Organization Name too long (possibly truncated).\n")); +			} else  				report(stdout, _("Unknown Organization\n")); -		} -		if( ( str_ptr = strstr( ibuf, "/CN=" ) ) ) { -			str_ptr += 4; -			strcpy( cbuf, str_ptr ); -			if( ( str_ptr = strchr(cbuf, '/' ) ) ) { -				*str_ptr = '\0'; -			} -			if (outlevel == O_VERBOSE) -				report(stdout, _("Issuer CommonName: %s\n"), cbuf ); -		} else { -			if (outlevel == O_VERBOSE) +			if ((i = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf, sizeof(buf))) != -1) { +				report(stdout, _("Issuer CommonName: %s\n"), buf); +				if (i >= sizeof(buf) - 1) +					report(stdout, _("Warning: Issuer CommonName too long (possibly truncated).\n")); +			} else  				report(stdout, _("Unknown Issuer CommonName\n"));  		} -		if( ( str_ptr = strstr( buf, "/CN=" ) ) ) { -			str_ptr += 4; -			strcpy( cbuf, str_ptr ); -			if( ( str_ptr = strchr(cbuf, '/' ) ) ) { -				*str_ptr = '\0'; -			} +		if ((i = X509_NAME_get_text_by_NID(subj, NID_commonName, buf, sizeof(buf))) != -1) {  			if (outlevel == O_VERBOSE) -				report(stdout, _("Server CommonName: %s\n"), cbuf); - -			if (_ssl_server_cname != NULL)  -			{ -				char *p1 = cbuf; +				report(stdout, _("Server CommonName: %s\n"), buf); +			if (i >= sizeof(buf) - 1) { +				/* Possible truncation. In this case, this is a DNS name, so this +				 * is really bad. We do not tolerate this even in the non-strict case. */ +				report(stderr, _("Bad certificate: Subject CommonName too long!\n")); +				return (0); +			} +			if (_ssl_server_cname != NULL) { +				char *p1 = buf;  				char *p2 = _ssl_server_cname;  				int n; - -				if (*p1 == '*')  -				{ +				 +				if (*p1 == '*') {  					++p1;  					n = strlen(p2) - strlen(p1);  					if (n >= 0)  						p2 += n; -				} -				if ( 0 != strcasecmp( p1, p2 ) ) { +				}	 +				if (0 != strcasecmp(p1, p2)) {  					report(stderr,  					    _("Server CommonName mismatch: %s != %s\n"), -					    cbuf, _ssl_server_cname ); +					    buf, _ssl_server_cname );  					if (ok_return && strict) -						return( 0 ); +						return (0);  				}  			} else if (ok_return && strict) { -				report(stderr, _("Canonical server name not set, could not verify certificate!\n")); -				return( 0 ); -		       } +				report(stderr, _("Server name not set, could not verify certificate!\n")); +				return (0); +			}  		} else {  			if (outlevel == O_VERBOSE)  				report(stdout, _("Unknown Server CommonName\n"));  			if (ok_return && strict) {  				report(stderr, _("Server name not specified in certificate!\n")); -				return( 0 ); +				return (0);  			}  		}  		/* Print the finger print. Note that on errors, we might print it more than once @@ -753,11 +736,11 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )  			digest_tp = EVP_md5();  			if (digest_tp == NULL) {  				report(stderr, _("EVP_md5() failed!\n")); -				return( 0 ); +				return (0);  			}  			if (!X509_digest(x509_cert, digest_tp, digest, &dsz)) { -				report(stderr, _("out of memory!\n")); -				return( 0 ); +				report(stderr, _("Out of memory!\n")); +				return (0);  			}  			tp = text;  			te = text + sizeof(text); @@ -765,7 +748,7 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )  				esz = snprintf(tp, te - tp, i > 0 ? ":%02X" : "%02X", digest[i]);  				if (esz >= te - tp) {  					report(stderr, _("Digest text buffer too small!\n")); -					return( 0 ); +					return (0);  				}  				tp += esz;  			} @@ -775,7 +758,7 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )  					report(stdout, _("%s fingerprints match.\n"), _server_label);  				else {  					report(stderr, _("%s fingerprints do not match!\n"), _server_label); -					return( 0 ); +					return (0);  				}  			}  		} @@ -784,19 +767,17 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )  	if (err != X509_V_OK && (strict || outlevel == O_VERBOSE)) {  		report(strict ? stderr : stdout, _("Warning: server certificate verification: %s\n"), X509_verify_cert_error_string(err));  		/* We gave the error code, but maybe we can add some more details for debugging */ -		switch (ctx->error) { +		switch (err) {  		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: -			X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); -			buf[256] = '\0'; -			report(stdout, _("unknown issuer= %s\n"), buf); +			X509_NAME_oneline(issuer, buf, sizeof(buf)); +			buf[sizeof(buf) - 1] = '\0'; +			report(stdout, _("unknown issuer (first %d characters): %s\n"), sizeof(buf), buf);  			break;  		}  	} -	/* We are not requiring or validating server or issuer id's as yet */ -	/* Always return OK from here */  	if (!strict)  		ok_return = 1; -	return( ok_return ); +	return (ok_return);  }  int SSL_nock_verify_callback( int ok_return, X509_STORE_CTX *ctx ) | 
