comparison src/dnsbl.cpp @ 346:66969443a012

need to strip <> from recipient address before sending to verifier
author Carl Byington <carl@five-ten-sg.com>
date Fri, 23 Dec 2016 09:35:10 -0800
parents 891281cb6d3d
children 8fe6d5120771
comparison
equal deleted inserted replaced
345:9f328a0a1719 346:66969443a012
1099 // that. So the <> wrapper is now optional. It may have mixed case, just 1099 // that. So the <> wrapper is now optional. It may have mixed case, just
1100 // as the mail client sent it. We dup the string and convert the duplicate 1100 // as the mail client sent it. We dup the string and convert the duplicate
1101 // to lower case. Some clients enclose the entire address in single quotes, 1101 // to lower case. Some clients enclose the entire address in single quotes,
1102 // so we strip those as well. We also remove the SRS and prvs coding. 1102 // so we strip those as well. We also remove the SRS and prvs coding.
1103 // 1103 //
1104 const char *to_lower_string(const char *email); 1104 const char *to_lower_string(const char *email, bool srs = true);
1105 const char *to_lower_string(const char *email) { 1105 const char *to_lower_string(const char *email, bool srs) {
1106 if (!email) return strdup("<>"); 1106 if (!email) return strdup("<>");
1107 size_t n = strlen(email); 1107 size_t n = strlen(email);
1108 if ((n > 1) && (email[0] == '<') && (email[n-1] == '>')) { 1108 if ((n > 1) && (email[0] == '<') && (email[n-1] == '>')) {
1109 n -= 2; 1109 n -= 2;
1110 email++; 1110 email++;
1115 } 1115 }
1116 if (n ==0) return strdup("<>"); 1116 if (n ==0) return strdup("<>");
1117 char *key = strdup(email); 1117 char *key = strdup(email);
1118 key[n] = '\0'; 1118 key[n] = '\0';
1119 for (size_t i=0; i<n; i++) key[i] = tolower(key[i]); 1119 for (size_t i=0; i<n; i++) key[i] = tolower(key[i]);
1120 if ((n > 14) && (strncmp(key, "srs", 3) == 0)) { 1120
1121 // might have srs coding to be removed 1121 if (srs) {
1122 const int nmatch = 7; 1122 if ((n > 14) && (strncmp(key, "srs", 3) == 0)) {
1123 regmatch_t match[nmatch]; 1123 // might have srs coding to be removed
1124 if (0 == regexec(&srs_pattern, key, nmatch, match, 0)) { 1124 const int nmatch = 7;
1125 int s4 = match[5].rm_so; // domain 1125 regmatch_t match[nmatch];
1126 int e4 = match[5].rm_eo; 1126 if (0 == regexec(&srs_pattern, key, nmatch, match, 0)) {
1127 int s5 = match[6].rm_so; // user 1127 int s4 = match[5].rm_so; // domain
1128 int e5 = match[6].rm_eo; 1128 int e4 = match[5].rm_eo;
1129 if ((s4 != -1) && (s5 != -1)) { 1129 int s5 = match[6].rm_so; // user
1130 char *newkey = strdup(key); // large enough 1130 int e5 = match[6].rm_eo;
1131 key[e4] = '\0'; 1131 if ((s4 != -1) && (s5 != -1)) {
1132 key[e5] = '\0'; 1132 char *newkey = strdup(key); // large enough
1133 strcpy(newkey, key+s5); // user 1133 key[e4] = '\0';
1134 strcat(newkey, "@"); // @ 1134 key[e5] = '\0';
1135 strcat(newkey, key+s4); // domain 1135 strcpy(newkey, key+s5); // user
1136 free(key); 1136 strcat(newkey, "@"); // @
1137 key = newkey; 1137 strcat(newkey, key+s4); // domain
1138 } 1138 free(key);
1139 } 1139 key = newkey;
1140 } 1140 }
1141 if ((n > 7) && (strncmp(key, "prvs", 4) == 0)) { 1141 }
1142 // might have prvs coding to be removed 1142 }
1143 const int nmatch = 3; 1143 if ((n > 7) && (strncmp(key, "prvs", 4) == 0)) {
1144 regmatch_t match[nmatch]; 1144 // might have prvs coding to be removed
1145 if (0 == regexec(&prvs_pattern, key, nmatch, match, 0)) { 1145 const int nmatch = 3;
1146 int s2 = match[2].rm_so; // user@domain 1146 regmatch_t match[nmatch];
1147 if (s2 != -1) { 1147 if (0 == regexec(&prvs_pattern, key, nmatch, match, 0)) {
1148 char *newkey = strdup(key+s2); // user@domain 1148 int s2 = match[2].rm_so; // user@domain
1149 free(key); 1149 if (s2 != -1) {
1150 key = newkey; 1150 char *newkey = strdup(key+s2); // user@domain
1151 free(key);
1152 key = newkey;
1153 }
1151 } 1154 }
1152 } 1155 }
1153 } 1156 }
1154 return key; 1157 return key;
1155 } 1158 }
1363 return SMFIS_REJECT; 1366 return SMFIS_REJECT;
1364 } 1367 }
1365 1368
1366 if (ver) { 1369 if (ver) {
1367 // try to verify this from/to pair of addresses even if it might be explicitly whitelisted 1370 // try to verify this from/to pair of addresses even if it might be explicitly whitelisted
1371 const char *loto = to_lower_string(rcptaddr, false);
1368 bool rc = ver->ok(priv.queueid, priv.mailaddr, rcptaddr); 1372 bool rc = ver->ok(priv.queueid, priv.mailaddr, rcptaddr);
1373 free((void*)loto);
1369 if (!rc) { 1374 if (!rc) {
1370 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"no such user"); 1375 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"no such user");
1371 return SMFIS_REJECT; 1376 return SMFIS_REJECT;
1372 } 1377 }
1373 } 1378 }