|  | @@ -41,6 +41,7 @@
 | 
	
		
			
				|  |  |  #include <errno.h>
 | 
	
		
			
				|  |  |  #include <pwd.h>
 | 
	
		
			
				|  |  |  #include <grp.h>
 | 
	
		
			
				|  |  | +#include <stdint.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "libmilter/mfapi.h"
 | 
	
		
			
				|  |  |  #include "libmilter/mfdef.h"
 | 
	
	
		
			
				|  | @@ -56,19 +57,21 @@ struct mlfiPriv {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static unsigned long mta_caps = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Function to extract addresses from the header/envelope fields.
 | 
	
		
			
				|  |  | -// If the field contains a < with a subsequent >, the inner part is used. If not, the whole header field is used. This allows matching "Max Mustermann <max.mustermann@example.invalid>" matching.
 | 
	
		
			
				|  |  | -const char *parse_address(const char *address, int *len)
 | 
	
		
			
				|  |  | +// Function to extract addresses from the header/envelope fields.  If the field
 | 
	
		
			
				|  |  | +// contains a < with a subsequent >, the inner part is used. If not, the whole
 | 
	
		
			
				|  |  | +// header field is used. This allows matching "Max Mustermann
 | 
	
		
			
				|  |  | +// <max.mustermann@example.invalid>".
 | 
	
		
			
				|  |  | +const char *parse_address(const char *address, size_t *len)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	int inlen = strlen(address);
 | 
	
		
			
				|  |  | -	int pos_open = -1, pos_close = -1;
 | 
	
		
			
				|  |  | -	int i;
 | 
	
		
			
				|  |  | +	size_t inlen = strlen(address);
 | 
	
		
			
				|  |  | +	size_t pos_open = SIZE_MAX, pos_close = SIZE_MAX;
 | 
	
		
			
				|  |  | +	size_t i;
 | 
	
		
			
				|  |  |  	for (i = 0; i < inlen; ++i) {
 | 
	
		
			
				|  |  |  		if (address[i] == '<') pos_open = i;
 | 
	
		
			
				|  |  |  		else if (address[i] == '>') pos_close = i;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (pos_open != -1 && pos_close != -1 && pos_open < pos_close) {
 | 
	
		
			
				|  |  | +	if (pos_open != SIZE_MAX && pos_close != SIZE_MAX && pos_open < pos_close) {
 | 
	
		
			
				|  |  |  		*len = pos_close - pos_open - 1;
 | 
	
		
			
				|  |  |  		return address + pos_open + 1;
 | 
	
		
			
				|  |  |  	} else {
 | 
	
	
		
			
				|  | @@ -91,17 +94,26 @@ void mlfi_cleanup(SMFICTX *ctx)
 | 
	
		
			
				|  |  |  sfsistat mlfi_envfrom(SMFICTX *ctx, char **envfrom)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	struct mlfiPriv *priv;
 | 
	
		
			
				|  |  | +	char *fromcp = NULL;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// Allocate some private memory.
 | 
	
		
			
				|  |  | -	priv = malloc(sizeof *priv);
 | 
	
		
			
				|  |  | -	if (priv == NULL) return SMFIS_TEMPFAIL;
 | 
	
		
			
				|  |  | -	memset(priv, '\0', sizeof *priv);
 | 
	
		
			
				|  |  | +	priv = calloc(1, sizeof(*priv));
 | 
	
		
			
				|  |  | +	if (priv == NULL) {
 | 
	
		
			
				|  |  | +		goto fail;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// Parse envelope from.
 | 
	
		
			
				|  |  | -	int len;
 | 
	
		
			
				|  |  | +	size_t len = 0;
 | 
	
		
			
				|  |  |  	const char *from = parse_address(*envfrom, &len);
 | 
	
		
			
				|  |  | -	char *fromcp = strndup(from, len);
 | 
	
		
			
				|  |  | -	if (fromcp == NULL) return SMFIS_TEMPFAIL;
 | 
	
		
			
				|  |  | +	if (len == 0) {
 | 
	
		
			
				|  |  | +		/* The strndup call below with a length of 0 will allocate a string of size
 | 
	
		
			
				|  |  | +		 * 0 so avoid that entirely and fail. */
 | 
	
		
			
				|  |  | +		goto fail;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	fromcp = strndup(from, len);
 | 
	
		
			
				|  |  | +	if (fromcp == NULL) {
 | 
	
		
			
				|  |  | +		goto fail;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// Set private values.
 | 
	
		
			
				|  |  |  	priv->is_auth = smfi_getsymval(ctx, "{auth_type}") ? 1 : 0;
 | 
	
	
		
			
				|  | @@ -112,6 +124,9 @@ sfsistat mlfi_envfrom(SMFICTX *ctx, char **envfrom)
 | 
	
		
			
				|  |  |  	smfi_setpriv(ctx, priv);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	return SMFIS_CONTINUE;
 | 
	
		
			
				|  |  | +fail:
 | 
	
		
			
				|  |  | +	free(fromcp);
 | 
	
		
			
				|  |  | +	return SMFIS_TEMPFAIL;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  sfsistat mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
 | 
	
	
		
			
				|  | @@ -121,7 +136,7 @@ sfsistat mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
 | 
	
		
			
				|  |  |  	// Perform checks if the sender is authenticated and the message is not rejected yet (the mail may contain multiple from tags, all have to match!).
 | 
	
		
			
				|  |  |  	if (priv->is_auth && !priv->reject) {
 | 
	
		
			
				|  |  |  		if (strcasecmp(headerf, "from") == 0) {
 | 
	
		
			
				|  |  | -			int len;
 | 
	
		
			
				|  |  | +			size_t len = 0;
 | 
	
		
			
				|  |  |  			const char *from = parse_address(headerv, &len);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			// Check whether header from matches envelope from and reject if not.
 |