Hello,

I created a patch that solves this problem. It does not simply append the
hostname to the To||Cc-Headers, but respects the RewriteDomain. If the
recipient is listed in /etc/ssmtp/revaliases, the alias address is used in
the To||Cc-Header.

Much of the patch code is taken from other functions in ssmtp.c.

Regards
  Christoph
diff -Naurp ssmtp-2.64.orig/ssmtp.c ssmtp-2.64/ssmtp.c
--- ssmtp-2.64.orig/ssmtp.c	2010-04-30 10:55:07.000000000 +0200
+++ ssmtp-2.64/ssmtp.c	2010-04-30 10:58:41.000000000 +0200
@@ -355,6 +355,64 @@ char *append_domain(char *str)
 }
 
 /*
+append_domain_header() -- Fix up address with @domain.com
+			  in To|Cc Headers
+*/
+char *append_domain_header(char *str)
+{
+	char buf1[(BUF_SZ + 1)], buf2[(BUF_SZ + 1)], *p;
+	int bool = False;
+	FILE *fp;
+
+	if (strchr(str, '@') != (char *) NULL) {
+		return strdup(str);
+	}
+
+	/* Try to open the reverse aliases file */
+	if ((fp = fopen(REVALIASES_FILE, "r"))) {
+		/* Search if a reverse alias is defined for the recipient */
+		while (fgets(buf1, sizeof(buf1), fp)) {
+			/* Make comments invisible */
+			if ((p = strchr(buf1, '#'))) {
+				*p = (char) NULL;
+			}
+
+			/* Ignore malformed lines and comments */
+			if (strchr(buf1, ':') == (char *) NULL) {
+				continue;
+			}
+
+			/* Parse the alias */
+			if (((p = strtok(buf1, ":"))) && (strcmp(p, str) == 0)) {
+				if ((p = strtok(NULL, ": \t\r\n"))) {
+					if (snprintf(buf2, BUF_SZ, "%s", p) == -1) {
+						die("append_domain_header() -- snprintf() failed");
+					}
+
+					bool = True;
+				}
+			}
+		}
+
+		fclose(fp);
+	}
+
+	if (! bool) {
+		if (snprintf(buf2, BUF_SZ, "%...@%s", str,
+#ifdef REWRITE_DOMAIN
+			rewrite_domain == True ? mail_domain : hostname
+#else
+			hostname
+#endif
+											) == -1) {
+				die("append_domain_header() -- snprintf() failed");
+		}
+	}
+
+	return(strdup(buf2));
+}
+
+/*
 standardise() -- Trim off '\n's and double leading dots
 */
 bool_t standardise(char *str, bool_t *linestart)
@@ -1416,6 +1474,90 @@ void handler(void)
 }
 
 /*
+rcpt_header() -- Break To|Cc into individual addresses
+	         and append domain, if necessary
+*/
+char *rcpt_header(const char *type, const char *addresses)
+{
+	bool_t in_quotes = False, got_addr = False;
+	char *p, *q, *r, *result, *ret;
+
+	result = NULL;
+
+	if ((p = strdup(addresses)) == (char *) NULL) {
+		die("rcpt_header(): strdup() failed");
+	}
+
+	q = p;
+
+	/* Replace <CR>, <LF> and <TAB> */
+	while (*q) {
+		switch(*q) {
+			case '\t':
+			case '\n':
+			case '\r':
+					*q = ' ';
+		}
+
+		q++;
+	}
+
+	q = p;
+	r = q;
+
+	while (*q) {
+		if (*q == '"') {
+			in_quotes = (in_quotes ? False : True);
+		}
+
+		/* End of string? */
+		if (*(q + 1) == (char) NULL) {
+			got_addr = True;
+		}
+
+		/* End of address? */
+		if ((*q == ',') && (in_quotes == False)) {
+			got_addr = True;
+			*q = (char) NULL;
+		}
+
+		if (got_addr) {
+			while (*r && isspace(*r)) r++;
+			ret = append_domain_header(addr_parse(r));
+
+			if (result == NULL) {
+				if (result = (char *) calloc(strlen(ret) + 5, sizeof(char))) {
+					sprintf(result, "%s: %s", type, ret);
+				}
+				else {
+					die("rcpt_header(): calloc() failed");
+				}
+			}
+			else {
+				if (result = (char *) realloc(result, (strlen(result) + 2 + strlen(ret) + 1) * sizeof(char))) {
+					result = strcat(result, ", ");
+					result = strcat(result, ret);
+				}
+				else {
+					die("rcpt_header(): realloc() failed");
+				}
+			}
+	
+			r = (q + 1);
+			got_addr = False;
+			free(ret);
+		}
+
+		q++;
+	}
+
+	free(p);
+
+	return result;
+}
+
+
+/*
 ssmtp() -- send the message (exactly one) from stdin to the mailhub SMTP port
 */
 int ssmtp(char *argv[])
@@ -1635,13 +1777,22 @@ int ssmtp(char *argv[])
 
 #ifdef HASTO_OPTION
 	if(have_to == False) {
-		outbytes += smtp_write(sock, "To: postmaster");
+		outbytes += smtp_write(sock, rcpt_header("To", "postmaster"));
 	}
 #endif
 
 	ht = &headers;
 	while(ht->next) {
-		outbytes += smtp_write(sock, "%s", ht->string);
+		if (strncasecmp(ht->string, "To:", 3) == 0) {
+			outbytes += smtp_write(sock, rcpt_header("To", ht->string + 3));
+		}
+		else if (strncasecmp(ht->string, "Cc:", 3) == 0) {
+			outbytes += smtp_write(sock, rcpt_header("Cc", ht->string + 3));
+		}
+		else {
+			outbytes += smtp_write(sock, "%s", ht->string);
+		}
+
 		ht = ht->next;
 	}
 

Reply via email to