comparison src/context.cpp @ 360:17f21fcd44a8

allow quoted comma separated multiple signers in the dkim_from config entries
author Carl Byington <carl@five-ten-sg.com>
date Mon, 16 Jan 2017 11:13:40 -0800
parents ed04479a8e12
children bcfbffe254ed
comparison
equal deleted inserted replaced
359:3dfa93d65701 360:17f21fcd44a8
1108 my_syslog(queueid, buf); 1108 my_syslog(queueid, buf);
1109 } 1109 }
1110 } 1110 }
1111 1111
1112 1112
1113 bool CONTEXT::in_signing_set(const char *s, const char *signers) {
1114 size_t n = strlen(s);
1115 const char *p = signers;
1116 do {
1117 if ((strncasecmp(p, s, n) == 0) && ((p[n] == '\0') || (p[n] == ','))) return true;
1118 p = strchr(p, ',');
1119 if (!p) return false;
1120 } while (true);
1121 }
1122
1123
1113 const char *CONTEXT::acceptable_content(recorder &memory, int score, int bulk, const char *queueid, string_set &signers, const char *from, string& msg) { 1124 const char *CONTEXT::acceptable_content(recorder &memory, int score, int bulk, const char *queueid, string_set &signers, const char *from, string& msg) {
1114 DKIMP dk = find_dkim_from(from); 1125 DKIMP dk = find_dkim_from(from);
1115 bool requirement = false; 1126 if (dk) {
1127 const char *st = dk->action;
1128 for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
1129 // signed by a white listed signer
1130 if ((st == token_signed_white) && in_signing_set(*s,dk->signer)) {
1131 log(queueid, "whitelisted dkim signer %s", *s);
1132 return token_white;
1133 }
1134 // signed by the required signer
1135 if ((st == token_require_signed) && in_signing_set(*s,dk->signer)) {
1136 log(queueid, "required dkim signer %s", *s);
1137 return token_white;
1138 }
1139 // signed by a black listed signer
1140 if ((st == token_signed_black) && in_signing_set(*s,dk->signer)) {
1141 char buf[maxlen];
1142 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", *s);
1143 msg = string(buf);
1144 return token_black;
1145 }
1146 }
1147 if (st == token_require_signed) {
1148 char buf[maxlen];
1149 snprintf(buf, sizeof(buf), "Mail rejected - not dkim signed by %s", dk->signer);
1150 msg = string(buf);
1151 return token_black;
1152 }
1153 }
1154
1116 for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) { 1155 for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
1117 const char *st = find_dkim_signer(*s); 1156 const char *st = find_dkim_signer(*s);
1118 // signed by a white listed signer 1157 // signed by a white listed signer
1119 if (st == token_white) { 1158 if (st == token_white) {
1120 log(queueid, "whitelisted dkim signer %s", *s); 1159 log(queueid, "whitelisted dkim signer %s", *s);
1121 return token_white; 1160 return token_white;
1122 } 1161 }
1162 }
1163
1164 for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
1165 const char *st = find_dkim_signer(*s);
1123 // signed by a black listed signer 1166 // signed by a black listed signer
1124 if (st == token_black) { 1167 if (st == token_black) {
1125 char buf[maxlen]; 1168 char buf[maxlen];
1126 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", *s); 1169 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", *s);
1127 msg = string(buf);
1128 return token_black;
1129 }
1130
1131 if (dk) {
1132 st = dk->action;
1133 // signed by a white listed signer
1134 if ((st == token_signed_white) && (strcasecmp(*s,dk->signer) == 0)) {
1135 log(queueid, "whitelisted dkim signer %s", *s);
1136 return token_white;
1137 }
1138 // signed by the required signer
1139 if ((st == token_require_signed) && (strcasecmp(*s,dk->signer) == 0)) {
1140 log(queueid, "required dkim signer %s", *s);
1141 requirement = true;
1142 }
1143 // signed by a black listed signer
1144 if ((st == token_signed_black) && (strcasecmp(*s,dk->signer) == 0)) {
1145 char buf[maxlen];
1146 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", dk->signer);
1147 msg = string(buf);
1148 return token_black;
1149 }
1150 }
1151 }
1152
1153 if (dk && (dk->action == token_require_signed)) {
1154 if (requirement) return token_white;
1155 else {
1156 char buf[maxlen];
1157 snprintf(buf, sizeof(buf), "Mail rejected - not dkim signed by %s", dk->signer);
1158 msg = string(buf); 1170 msg = string(buf);
1159 return token_black; 1171 return token_black;
1160 } 1172 }
1161 } 1173 }
1162 1174
1237 printf("%s }; \n", indent); 1249 printf("%s }; \n", indent);
1238 printf("%s dkim_from { \n", indent); 1250 printf("%s dkim_from { \n", indent);
1239 for (dkimp_map::iterator i=dkim_from_names.begin(); i!=dkim_from_names.end(); i++) { 1251 for (dkimp_map::iterator i=dkim_from_names.begin(); i!=dkim_from_names.end(); i++) {
1240 const char *n = (*i).first; 1252 const char *n = (*i).first;
1241 DKIM &d = *(*i).second; 1253 DKIM &d = *(*i).second;
1242 printf("%s %s %s %s; \n", indent, n, d.action, d.signer); 1254 printf("%s %s %s \"%s\"; \n", indent, n, d.action, d.signer);
1243 } 1255 }
1244 printf("%s }; \n", indent); 1256 printf("%s }; \n", indent);
1245 if (content_suffix) { 1257 if (content_suffix) {
1246 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message); 1258 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message);
1247 } 1259 }
1531 // optional separators 1543 // optional separators
1532 } 1544 }
1533 else { 1545 else {
1534 const char *signer = have; 1546 const char *signer = have;
1535 const char *action = tok.next(); 1547 const char *action = tok.next();
1536 if ((action == token_white) || (action == token_black)) { 1548 if ((action == token_white) || (action == token_black) || (action == token_unknown)) {
1537 me.add_dkim_signer(signer, action); 1549 me.add_dkim_signer(signer, action);
1538 } 1550 }
1539 else { 1551 else {
1540 tok.token_error("white/black", action); 1552 tok.token_error("white/black/unknown", action);
1541 } 1553 }
1542 } 1554 }
1543 } 1555 }
1544 return tsa(tok, token_semi); 1556 return tsa(tok, token_semi);
1545 } 1557 }