From aa4cc23071213f405b1671a5beaae3266cc1af45 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 6 Feb 2013 00:45:11 +0100 Subject: [PATCH] rewriteuser-0.1-qmail-smtpd --- qmail-smtpd.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/qmail-smtpd.c b/qmail-smtpd.c index 43570f4..b4c4ce2 100644 --- a/qmail-smtpd.c +++ b/qmail-smtpd.c @@ -858,7 +858,9 @@ static stralloc slop = {0}; /* b64 challenge */ char **childargs; char ssauthbuf[512]; +char ssauth2buf[512]; substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf)); +substdio ssauth2 = SUBSTDIO_FDBUF(saferead,4,ssauth2buf,sizeof(ssauth2buf)); int authgetl(void) { int i; @@ -884,6 +886,9 @@ int authenticate(void) int child; int wstat; int pi[2]; + int piauth[2], i, len; + char *arg; + static stralloc authout = {0}, authparams = {0}; if (!stralloc_0(&user)) die_nomem(); if (!stralloc_0(&pass)) die_nomem(); @@ -892,19 +897,24 @@ int authenticate(void) #endif if (pipe(pi) == -1) return err_pipe(); + if (pipe(piauth) == -1) return err_pipe(); switch(child = fork()) { case -1: return err_fork(); case 0: close(pi[1]); + close(piauth[0]); if(fd_copy(3,pi[0]) == -1) return err_pipe(); + if(fd_copy(4,piauth[1]) == -1) return err_pipe(); sig_pipedefault(); execvp(*childargs, childargs); _exit(1); } close(pi[0]); + close(piauth[1]); substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf); + substdio_fdbuf(&ssauth2,read,piauth[0],ssauth2buf,sizeof ssauth2buf); if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write(); if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write(); #ifdef CRAM_MD5 @@ -913,11 +923,43 @@ int authenticate(void) if (substdio_flush(&ssauth) == -1) return err_write(); close(pi[1]); + + if (!stralloc_copys(&authout, "")) die_nomem(); + for (;;) { + if (!stralloc_readyplus(&authout, 1)) die_nomem(); + i = substdio_get(&ssauth2, authout.s + authout.len, 1); + if (i == 0) break; + ++authout.len; + } + authout.s[authout.len] = 0; + if (substdio_flush(&ssauth2) == -1) return err_write(); + close(piauth[0]); + + if (authout.len > 0) { + len = authout.len; + arg = authout.s; + if (!stralloc_copys(&authparams, "")) die_nomem; + while (len) { + if (*arg == '\0') { + if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) { + if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem(); + if (!stralloc_0(&user)) die_nomem(); + } + if (!stralloc_copys(&authparams, "")) die_nomem; + } + else + if (!stralloc_catb(&authparams, arg, 1)) die_nomem; + arg++; + len--; + } + } + #ifdef CRAM_MD5 if (!stralloc_copys(&chal,"")) die_nomem(); if (!stralloc_copys(&slop,"")) die_nomem(); #endif byte_zero(ssauthbuf,sizeof ssauthbuf); + byte_zero(ssauth2buf,sizeof ssauth2buf); if (wait_pid(&wstat,child) == -1) return err_child(); if (wait_crashed(wstat)) return err_child(); if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */ -- cgit v1.2.3