X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Finternet_addressing.c;h=b845b304ab760362c0ee9a36e0537ade543137b3;hb=8d7cd043e07dfe4e0ae93befb667a2189e4b482d;hp=6eb6de68c3ac1b57d33083701c1787da964b7892;hpb=882ff5a53c3b4e440520a073cf07dc60b2671876;p=citadel.git diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index 6eb6de68c..b845b304a 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -172,9 +172,7 @@ void utf8ify_rfc822_string(char *buf) { end = nextend; } - /* Now we handle foreign character sets properly encoded - * in RFC2047 format. - */ + // Now we handle foreign character sets properly encoded in RFC2047 format. start = strstr(buf, "=?"); FindNextEnd((start != NULL)? start : buf, end); while (start != NULL && end != NULL && end > start) { @@ -375,27 +373,33 @@ void sanitize_truncated_recipient(char *str) * (What can I say, I'm in a weird mood today...) */ void remove_any_whitespace_to_the_left_or_right_of_at_symbol(char *name) { - unsigned int i; + char *ptr; + if (!name) return; - for (i = 0; i < strlen(name); ++i) { - if (name[i] == '@') { - while (isspace(name[i - 1]) && i > 0) { - strcpy(&name[i - 1], &name[i]); - --i; - } - while (isspace(name[i + 1])) { - strcpy(&name[i + 1], &name[i + 2]); - } + for (ptr=name; *ptr; ++ptr) { + while ( (isspace(*ptr)) && (*(ptr+1)=='@') ) { + strcpy(ptr, ptr+1); + if (ptr > name) --ptr; + } + while ( (*ptr=='@') && (*(ptr+1)!=0) && (isspace(*(ptr+1))) ) { + strcpy(ptr+1, ptr+2); } } } +// values that can be returned by expand_aliases() +enum { + EA_ERROR, // Can't send message due to bad address + EA_LOCAL, // Local message, do no network processing + EA_INTERNET // Convert msg and send as Internet mail +}; + + /* * Aliasing for network mail. */ -int alias(char *name) -{ /* process alias and routing info for mail */ +int expand_aliases(char *name) { /* process alias and routing info for mail */ int a; char aaa[SIZ]; int at = 0; @@ -413,9 +417,9 @@ int alias(char *name) strcpy(name, aaa); } - if (strcasecmp(original_name, name)) { + //if (strcasecmp(original_name, name)) { syslog(LOG_INFO, "internet_addressing: %s is being forwarded to %s", original_name, name); - } + //} /* Change "user @ xxx" to "user" if xxx is an alias for this host */ for (a=0; name[a] != '\0'; ++a) { @@ -430,8 +434,8 @@ int alias(char *name) /* determine local or remote type, see citadel.h */ at = haschar(name, '@'); - if (at == 0) return(MES_LOCAL); /* no @'s - local address */ - if (at > 1) return(MES_ERROR); /* >1 @'s - invalid address */ + if (at == 0) return(EA_LOCAL); /* no @'s - local address */ + if (at > 1) return(EA_ERROR); /* >1 @'s - invalid address */ remove_any_whitespace_to_the_left_or_right_of_at_symbol(name); /* figure out the delivery mode */ @@ -441,11 +445,11 @@ int alias(char *name) * is an FQDN and will attempt SMTP delivery to the Internet. */ if (haschar(node, '.') > 0) { - return(MES_INTERNET); + return(EA_INTERNET); } /* If we get to this point it's an invalid node name */ - return (MES_ERROR); + return (EA_ERROR); } @@ -459,7 +463,6 @@ int alias(char *name) * Caller needs to free the result using free_recipients() */ struct recptypes *validate_recipients(const char *supplied_recipients, const char *RemoteIdentifier, int Flags) { - struct CitContext *CCC = CC; struct recptypes *ret; char *recipients = NULL; char *org_recp; @@ -467,7 +470,6 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha char this_recp_cooked[256]; char append[SIZ]; long len; - int num_recps = 0; int i, j; int mailtype; int invalid; @@ -522,7 +524,7 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha } /* Now start extracting recipients... */ - + Array *recp_array = array_new(1024); while (!IsEmptyStr(recipients)) { for (i=0; i<=strlen(recipients); ++i) { if (recipients[i] == '\"') in_quotes = 1 - in_quotes; @@ -540,16 +542,28 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha } striplt(this_recp); - if (IsEmptyStr(this_recp)) - break; - syslog(LOG_DEBUG, "internet_addressing: evaluating recipient #%d: %s", num_recps, this_recp); - ++num_recps; + if (!IsEmptyStr(this_recp)) { + syslog(LOG_DEBUG, "internet_addressing: evaluating recipient: %s", this_recp); + array_append(recp_array, this_recp); + } + } + + for (int r=0; rnum_room; strcpy(this_recp, CtdlGetConfigStr("c_aideroom")); @@ -571,12 +587,11 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha } strcat(ret->recp_room, this_recp); } - else if ( (!strncasecmp(this_recp, "room_", 5)) - && (!CtdlGetRoom(&tempQR, &this_recp_cooked[5])) ) { + else if ( (!strncasecmp(this_recp, "room_", 5)) && (!CtdlGetRoom(&tempQR, &this_recp_cooked[5])) ) { /* Save room so we can restore it later */ - tempQR2 = CCC->room; - CCC->room = tempQR; + tempQR2 = CC->room; + CC->room = tempQR; /* Check permissions to send mail to this room */ err = CtdlDoIHavePermissionToPostInThisRoom( @@ -585,7 +600,7 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha RemoteIdentifier, Flags, 0 /* 0 = not a reply */ - ); + ); if (err) { ++ret->num_error; invalid = 1; @@ -605,7 +620,7 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha } /* Restore room in case something needs it */ - CCC->room = tempQR2; + CC->room = tempQR2; } else if (CtdlGetUser(&tempUS, this_recp) == 0) { @@ -629,7 +644,7 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha invalid = 1; } break; - case MES_INTERNET: + case EA_INTERNET: /* Yes, you're reading this correctly: if the target * domain points back to the local system, * the address is invalid. That's @@ -648,7 +663,7 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha strcat(ret->recp_internet, this_recp); } break; - case MES_ERROR: + case EA_ERROR: ++ret->num_error; invalid = 1; break; @@ -691,6 +706,8 @@ struct recptypes *validate_recipients(const char *supplied_recipients, const cha ); free(recipients); + array_free(recp_array); + return(ret); } @@ -722,8 +739,7 @@ void free_recipients(struct recptypes *valid) { } -char *qp_encode_email_addrs(char *source) -{ +char *qp_encode_email_addrs(char *source) { char *user, *node, *name; const char headerStr[] = "=?UTF-8?Q?"; char *Encoded; @@ -758,20 +774,19 @@ char *qp_encode_email_addrs(char *source) free (AddrPtr), AddrPtr = ptr; ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2); - memset(&ptr[nAddrPtrMax], 0, - sizeof (long) * nAddrPtrMax); + memset(&ptr[nAddrPtrMax], 0, sizeof (long) * nAddrPtrMax); memcpy (ptr, AddrUtf8, sizeof (long) * nAddrPtrMax); free (AddrUtf8), AddrUtf8 = ptr; nAddrPtrMax *= 2; } - if (((unsigned char) source[i] < 32) || - ((unsigned char) source[i] > 126)) { + if (((unsigned char) source[i] < 32) || ((unsigned char) source[i] > 126)) { need_to_encode = 1; AddrUtf8[nColons] = 1; } - if (source[i] == '"') + if (source[i] == '"') { InQuotes = !InQuotes; + } if (!InQuotes && source[i] == ',') { AddrPtr[nColons] = i; nColons++; @@ -801,28 +816,19 @@ char *qp_encode_email_addrs(char *source) for (i = 0; i < nColons && nPtr != NULL; i++) { nmax = EncodedMaxLen - (nPtr - Encoded); if (AddrUtf8[i]) { - process_rfc822_addr(&source[AddrPtr[i]], - user, - node, - name); + process_rfc822_addr(&source[AddrPtr[i]], user, node, name); /* TODO: libIDN here ! */ if (IsEmptyStr(name)) { - n = snprintf(nPtr, nmax, - (i==0)?"%s@%s" : ",%s@%s", - user, node); + n = snprintf(nPtr, nmax, (i==0)?"%s@%s" : ",%s@%s", user, node); } else { EncodedName = rfc2047encode(name, strlen(name)); - n = snprintf(nPtr, nmax, - (i==0)?"%s <%s@%s>" : ",%s <%s@%s>", - EncodedName, user, node); + n = snprintf(nPtr, nmax, (i==0)?"%s <%s@%s>" : ",%s <%s@%s>", EncodedName, user, node); free(EncodedName); } } else { - n = snprintf(nPtr, nmax, - (i==0)?"%s" : ",%s", - &source[AddrPtr[i]]); + n = snprintf(nPtr, nmax, (i==0)?"%s" : ",%s", &source[AddrPtr[i]]); } if (n > 0 ) nPtr += n; @@ -884,8 +890,7 @@ void unfold_rfc822_field(char **field, char **FieldEnd) else { if (*sField=='\"') quote = 1 - quote; if (!quote) { - if (isspace(*sField)) - { + if (isspace(*sField)) { *pField = ' '; pField++; sField++; @@ -909,8 +914,7 @@ void unfold_rfc822_field(char **field, char **FieldEnd) * Split an RFC822-style address into userid, host, and full name * */ -void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) -{ +void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) { int a; strcpy(user, ""); @@ -1005,7 +1009,6 @@ void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name) ) { strcpy(node, CtdlGetConfigStr("c_nodename")); } - else { /* strip anything to the left of a @ */