summaryrefslogtreecommitdiffstats
path: root/qmail-smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-smtpd.c')
-rw-r--r--qmail-smtpd.c42
1 files changed, 42 insertions, 0 deletions
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 */
858 858
859char **childargs; 859char **childargs;
860char ssauthbuf[512]; 860char ssauthbuf[512];
861char ssauth2buf[512];
861substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf)); 862substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf));
863substdio ssauth2 = SUBSTDIO_FDBUF(saferead,4,ssauth2buf,sizeof(ssauth2buf));
862 864
863int authgetl(void) { 865int authgetl(void) {
864 int i; 866 int i;
@@ -884,6 +886,9 @@ int authenticate(void)
884 int child; 886 int child;
885 int wstat; 887 int wstat;
886 int pi[2]; 888 int pi[2];
889 int piauth[2], i, len;
890 char *arg;
891 static stralloc authout = {0}, authparams = {0};
887 892
888 if (!stralloc_0(&user)) die_nomem(); 893 if (!stralloc_0(&user)) die_nomem();
889 if (!stralloc_0(&pass)) die_nomem(); 894 if (!stralloc_0(&pass)) die_nomem();
@@ -892,19 +897,24 @@ int authenticate(void)
892#endif 897#endif
893 898
894 if (pipe(pi) == -1) return err_pipe(); 899 if (pipe(pi) == -1) return err_pipe();
900 if (pipe(piauth) == -1) return err_pipe();
895 switch(child = fork()) { 901 switch(child = fork()) {
896 case -1: 902 case -1:
897 return err_fork(); 903 return err_fork();
898 case 0: 904 case 0:
899 close(pi[1]); 905 close(pi[1]);
906 close(piauth[0]);
900 if(fd_copy(3,pi[0]) == -1) return err_pipe(); 907 if(fd_copy(3,pi[0]) == -1) return err_pipe();
908 if(fd_copy(4,piauth[1]) == -1) return err_pipe();
901 sig_pipedefault(); 909 sig_pipedefault();
902 execvp(*childargs, childargs); 910 execvp(*childargs, childargs);
903 _exit(1); 911 _exit(1);
904 } 912 }
905 close(pi[0]); 913 close(pi[0]);
914 close(piauth[1]);
906 915
907 substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf); 916 substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf);
917 substdio_fdbuf(&ssauth2,read,piauth[0],ssauth2buf,sizeof ssauth2buf);
908 if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write(); 918 if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write();
909 if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write(); 919 if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write();
910#ifdef CRAM_MD5 920#ifdef CRAM_MD5
@@ -913,11 +923,43 @@ int authenticate(void)
913 if (substdio_flush(&ssauth) == -1) return err_write(); 923 if (substdio_flush(&ssauth) == -1) return err_write();
914 924
915 close(pi[1]); 925 close(pi[1]);
926
927 if (!stralloc_copys(&authout, "")) die_nomem();
928 for (;;) {
929 if (!stralloc_readyplus(&authout, 1)) die_nomem();
930 i = substdio_get(&ssauth2, authout.s + authout.len, 1);
931 if (i == 0) break;
932 ++authout.len;
933 }
934 authout.s[authout.len] = 0;
935 if (substdio_flush(&ssauth2) == -1) return err_write();
936 close(piauth[0]);
937
938 if (authout.len > 0) {
939 len = authout.len;
940 arg = authout.s;
941 if (!stralloc_copys(&authparams, "")) die_nomem;
942 while (len) {
943 if (*arg == '\0') {
944 if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) {
945 if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem();
946 if (!stralloc_0(&user)) die_nomem();
947 }
948 if (!stralloc_copys(&authparams, "")) die_nomem;
949 }
950 else
951 if (!stralloc_catb(&authparams, arg, 1)) die_nomem;
952 arg++;
953 len--;
954 }
955 }
956
916#ifdef CRAM_MD5 957#ifdef CRAM_MD5
917 if (!stralloc_copys(&chal,"")) die_nomem(); 958 if (!stralloc_copys(&chal,"")) die_nomem();
918 if (!stralloc_copys(&slop,"")) die_nomem(); 959 if (!stralloc_copys(&slop,"")) die_nomem();
919#endif 960#endif
920 byte_zero(ssauthbuf,sizeof ssauthbuf); 961 byte_zero(ssauthbuf,sizeof ssauthbuf);
962 byte_zero(ssauth2buf,sizeof ssauth2buf);
921 if (wait_pid(&wstat,child) == -1) return err_child(); 963 if (wait_pid(&wstat,child) == -1) return err_child();
922 if (wait_crashed(wstat)) return err_child(); 964 if (wait_crashed(wstat)) return err_child();
923 if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */ 965 if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */