diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-10 22:09:25 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-10 22:09:25 +0300 |
commit | ff698797be85d53705306b7f0311fcd09e3072d7 (patch) | |
tree | a946713e0bffde2a127a270b42fff841d87093e4 | |
parent | 2c1fa67dc052dac712437bb0fe4deb7e4dc21e59 (diff) | |
download | mqrd-ff698797be85d53705306b7f0311fcd09e3072d7.tar.gz mqrd-ff698797be85d53705306b7f0311fcd09e3072d7.tar.bz2 |
Accept only commands whose arguments are valid Sendmail queue IDs.
-rw-r--r-- | mqrd.8 | 12 | ||||
-rw-r--r-- | mqrd.c | 43 |
2 files changed, 41 insertions, 14 deletions
@@ -14,7 +14,7 @@ .\" You should have received a copy of the GNU General Public License .\" along with MRRD. If not, see <http://www.gnu.org/licenses/>. .\" -.TH MQRD 8 "September 3, 2012" "MQRD" +.TH MQRD 8 "April 10, 2013" "MQRD" .SH NAME mqrd \- mail quarantine queue manager .SH SYNOPSIS @@ -24,7 +24,6 @@ mqrd \- mail quarantine queue manager \fBmqrd\fR \-h \fBmqrd\fR \-v - .SH DESCRIPTION .B Mqrd is a daemon for managing Sendmail quarantine queue. Its purpose is to @@ -79,7 +78,6 @@ it in production environment. .TP \fB\-v\fR Print program version and exit. - .SH EXIT CODES .B Mqrd uses the following exit codes (values in parentheses indicate the @@ -134,6 +132,11 @@ on error. These tokens can be followed by a single space character and a human-readable description of the result. .PP After issuing a reply the server closes connection. +.PP +A command is rejected if its argument does not look like a valid +Sendmail queue identifier. That is, the argument must consist of +exactly 14 characters, the first eight of them being alphanumeric +characters and the subsequent six being decimal digits. .SH BUGS Several parameters are hardcoded: mail queue directory, path to the @@ -148,9 +151,8 @@ variable in the Makefile. Sergey Poznyakoff .SH "BUG REPORTS" Report bugs to <gray+mqrd@gnu.org.ua>. - .SH COPYRIGHT -Copyright \(co 2012 Sergey Poznyakoff +Copyright \(co 2012, 2013 Sergey Poznyakoff .br .na License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> @@ -304,20 +304,41 @@ globerrfunc(const char *epath, int eerrno) return 1; } +/* The QID format is: YMDhmsNMPPPPP */ +#define QIDLEN 14 +/* The valid QID letters are: */ +static const char qabc[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; +/* stem of a queue file (globbing pattern) */ +#define QFSTEMGLOB "[dqtx]f" + +static int +valid_qid(const char *qid) +{ + int i; + + if (strlen(qid) != QIDLEN) + return 0; + for (i = 0; i < 8; i++) + if (!strchr(qabc, qid[i])) + return 0; + for (; qid[i]; qid++) + if (!isdigit(qid[i])) + return 0; + return 1; +} + int drop_msg(const char *id) { glob_t g; size_t i; - char *pat = malloc(strlen(id) + 2); + char pat[sizeof(QFSTEMGLOB) + QIDLEN]; int rc = 0; - if (!pat) { - syslog(LOG_ERR, "not enough memory"); - return -1; - } - pat[0] = '*'; - strcpy(pat + 1, id); + strcpy(pat, QFSTEMGLOB); + strcat(pat, id); switch (glob(pat, 0, globerrfunc, &g)) { case 0: @@ -384,8 +405,12 @@ process(FILE *fp) } *p++ = 0; - - if (strcmp(inbuf, "DROP") == 0) + + if (!valid_qid(p)) { + syslog(LOG_ERR, "invalid QID: %s", p); + fprintf(fp, "-ERR Invalid QID\r\n"); + return; + } else if (strcmp(inbuf, "DROP") == 0) rc = drop_msg(p); else if (strcmp(inbuf, "DLVR") == 0) { rc = deliver_message(p); |