comparison src/dnsbl.cpp @ 328:b4f766947202

allow multiple dkim signers in authentication results
author Carl Byington <carl@five-ten-sg.com>
date Sun, 18 Dec 2016 17:55:16 -0800
parents 51846836ec92
children c9932c4d8053
comparison
equal deleted inserted replaced
327:51846836ec92 328:b4f766947202
322 in_addr ip; 322 in_addr ip;
323 if (inet_aton(question, &ip)) { 323 if (inet_aton(question, &ip)) {
324 return ip.s_addr; 324 return ip.s_addr;
325 } 325 }
326 } 326 }
327 int n = strlen(question); 327 size_t n = strlen(question);
328 if (question[n-1] == '.') { 328 if (question[n-1] == '.') {
329 priv.my_write(question, n+1); // write the question including the null terminator 329 priv.my_write(question, n+1); // write the question including the null terminator
330 } 330 }
331 else { 331 else {
332 priv.my_write(question, n); // write the question 332 priv.my_write(question, n); // write the question
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);
1105 const char *to_lower_string(const char *email) { 1105 const char *to_lower_string(const char *email) {
1106 if (!email) return strdup("<>"); 1106 if (!email) return strdup("<>");
1107 int n = strlen(email); 1107 size_t n = strlen(email);
1108 if (n == 0) return strdup("<>"); 1108 if ((n > 1) && (email[0] == '<') && (email[n-1] == '>')) {
1109 if (email[0] == '<') {
1110 // assume it also ends with >
1111 n -= 2;
1112 if (n < 1) return strdup("<>");
1113 email++;
1114 }
1115 if ((email[0] == '\'') && (email[n-1] == '\'') && (n > 2)) {
1116 n -= 2; 1109 n -= 2;
1117 email++; 1110 email++;
1118 } 1111 }
1112 if ((n > 1) && (email[0] == '\'') && (email[n-1] == '\'')) {
1113 n -= 2;
1114 email++;
1115 }
1116 if (n ==0) return strdup("<>");
1119 char *key = strdup(email); 1117 char *key = strdup(email);
1120 key[n] = '\0'; 1118 key[n] = '\0';
1121 for (int i=0; i<n; i++) key[i] = tolower(key[i]); 1119 for (int i=0; i<n; i++) key[i] = tolower(key[i]);
1122 if ((n > 14) && (strncmp(key, "srs", 3) == 0)) { 1120 if ((n > 14) && (strncmp(key, "srs", 3) == 0)) {
1123 // might have srs coding to be removed 1121 // might have srs coding to be removed
1456 mlfiPriv &priv = *MLFIPRIV; 1454 mlfiPriv &priv = *MLFIPRIV;
1457 priv.header_count++; 1455 priv.header_count++;
1458 char msg[maxlen]; 1456 char msg[maxlen];
1459 if ((priv.header_count < 4) || (strcasecmp(headerf, "from") == 0)) { 1457 if ((priv.header_count < 4) || (strcasecmp(headerf, "from") == 0)) {
1460 snprintf(msg, sizeof(msg), "header %s: %s", headerf, headerv); 1458 snprintf(msg, sizeof(msg), "header %s: %s", headerf, headerv);
1461 for (int i=0; i<strlen(msg); i++) { 1459 for (size_t i=0; i<strlen(msg); i++) {
1462 if (msg[i] < 0x20) msg[i] = ' '; 1460 if (msg[i] < 0x20) msg[i] = ' ';
1463 } 1461 }
1464 my_syslog(&priv, msg); 1462 my_syslog(&priv, msg);
1465 } 1463 }
1466 1464
1470 if (strcasecmp(headerf, "Authentication-Results") != 0) priv.dkim_ok = false; 1468 if (strcasecmp(headerf, "Authentication-Results") != 0) priv.dkim_ok = false;
1471 if (strncasecmp(headerv, token_myhostname, strlen(token_myhostname)) != 0) priv.dkim_ok = false; 1469 if (strncasecmp(headerv, token_myhostname, strlen(token_myhostname)) != 0) priv.dkim_ok = false;
1472 if (priv.dkim_ok) { 1470 if (priv.dkim_ok) {
1473 const int nmatch = 2; 1471 const int nmatch = 2;
1474 regmatch_t match[nmatch]; 1472 regmatch_t match[nmatch];
1475 int offset = 0; 1473 char *msgo = msg;
1476 while (true) { 1474 while (true) {
1477 if (0 == regexec(&dkim_pattern, msg+offset, nmatch, match, 0)) { 1475 if (0 == regexec(&dkim_pattern, msgo, nmatch, match, 0)) {
1478 int s1 = match[1].rm_so; // domain 1476 int s1 = match[1].rm_so; // domain
1479 int e1 = match[1].rm_eo; 1477 int e1 = match[1].rm_eo;
1480 if (s1 != -1) { 1478 if (s1 != -1) {
1481 char save = msg[offset+e1]; 1479 char save = msgo[e1];
1482 msg[offset+e1] = '\0'; 1480 msgo[e1] = '\0';
1483 priv.dkim_signers.insert(strdup(msg+offset+s1)); 1481 priv.dkim_signers.insert(strdup(msgo+s1));
1484 msg[offset+e1] = save; 1482 msgo[e1] = save;
1485 offset += e1 + 1; 1483 msgo += e1 + 1;
1486 } 1484 }
1487 else break; 1485 else break;
1488 } 1486 }
1489 else break; 1487 else break;
1490 } 1488 }
1491 } 1489 }
1492 } 1490 }
1493 if ((priv.header_count > 2) && (strcasecmp(headerf, "from"))) { 1491 }
1494 const int nmatch = 2; 1492
1495 regmatch_t match[nmatch]; 1493 if ((priv.header_count > 2) && (strcasecmp(headerf, "from"))) {
1496 if (0 == regexec(&from_pattern, msg, nmatch, match, 0)) { 1494 const int nmatch = 2;
1497 int s1 = match[1].rm_so; // domain 1495 regmatch_t match[nmatch];
1498 int e1 = match[1].rm_eo; 1496 if (0 == regexec(&from_pattern, msg, nmatch, match, 0)) {
1499 if (s1 != -1) { 1497 int s1 = match[1].rm_so; // domain
1500 msg[e1] = '\0'; 1498 int e1 = match[1].rm_eo;
1501 priv.fromaddr = strdup(msg+s1); 1499 if (s1 != -1) {
1502 } 1500 msg[e1] = '\0';
1501 priv.fromaddr = strdup(msg+s1);
1503 } 1502 }
1504 } 1503 }
1505 } 1504 }
1506 1505
1507 // headers that avoid autowhitelisting 1506 // headers that avoid autowhitelisting