diff options
Diffstat (limited to 'qmail-smtpd.c')
| -rw-r--r-- | qmail-smtpd.c | 42 |
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 | ||
| 859 | char **childargs; | 859 | char **childargs; |
| 860 | char ssauthbuf[512]; | 860 | char ssauthbuf[512]; |
| 861 | char ssauth2buf[512]; | ||
| 861 | substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf)); | 862 | substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf)); |
| 863 | substdio ssauth2 = SUBSTDIO_FDBUF(saferead,4,ssauth2buf,sizeof(ssauth2buf)); | ||
| 862 | 864 | ||
| 863 | int authgetl(void) { | 865 | int 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 */ |
