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;
}