Mercurial > dnsbl
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 } |