ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:19.94 GB of 70.42 GB (28.32%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ src/ courier-0.66.1/ courier/ module.esmtp/ - drwxrwxrwx

Directory:
Viewing file:     courieresmtpd.c (25.72 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 1998 - 2010 Double Precision, Inc.
** See COPYING for distribution information.
*/

#if    HAVE_CONFIG_H
#include    "config.h"
#endif
#include    <stdio.h>
#if    HAVE_UNISTD_H
#include    <unistd.h>
#endif
#if    HAVE_FCNTL_H
#include    <fcntl.h>
#endif
#include    <ctype.h>
#include    <string.h>
#include    <stdlib.h>
#include    <sys/types.h>
#include    <sys/uio.h>
#include    <sys/time.h>
#include    <signal.h>
#include    <syslog.h>

#if    HAVE_LOCALE_H
#include    <locale.h>
#endif

#include    "courier.h"
#include    "rw.h"
#include    "comcargs.h"
#include    "comsubmitclient.h"
#include    "comreadtime.h"
#include    "rfc822.h"
#include    "waitlib/waitlib.h"
#include    "esmtpiov.h"
#include    "esmtpconfig.h"
#include    "numlib/numlib.h"
#include    "tcpd/spipe.h"
#include    "tcpd/tlsclient.h"
#include    <courierauth.h>
#include    <courierauthsasl.h>


static char helobuf[256];
static char authuserbuf[256];
static char tlsbuf[128+NUMBUFSIZE];
static int extended;

static unsigned long sizelimit;
static int submit_started=0;
static int hasexdata;
static int hasverp;
static int hasstarttls;

static char *mailfroms=0;
extern time_t iovread_timeout;
extern time_t iovwrite_timeout;
static char *input_line="";
static void cancelsubmit();
static time_t data_timeout;

static const char *tcpremoteip, *tcpremotehost;

#define    INIT_TEERGRUBE    8
#define    MAX_TEERGRUBE    128

static time_t teergrube=INIT_TEERGRUBE;

extern const char *externalauth();

static const char *smtp_externalauth()
{
    const char *p;

    if ((p=getenv("ESMTP_TLS")) && atoi(p))
        return externalauth();

    return NULL;
}

static void tarpit()
{
    const char *p;
    if ((p=getenv("TARPIT")) && atoi(p))
    {
        sleep(teergrube);
        teergrube *= 2;
        if (teergrube > MAX_TEERGRUBE)
            teergrube=MAX_TEERGRUBE;
    }
}

void iov_logerror(const char *q, const char *p)
{
    const char *ident=getenv("TCPREMOTEINFO");

    if (strcmp(input_line, "QUIT") == 0)
        return;
    /* Do not log write errors for QUIT cmd -- broken clients */

    clog_msg_start_info();
    clog_msg_str("error,relay=");
    clog_msg_str(tcpremoteip);
    if (ident)
    {
        clog_msg_str(",ident=\"");
        clog_msg_str(ident);
        clog_msg_str("\"");
    }
    clog_msg_str(",msg=\"");
    if (q)
        clog_msg_str(q);
    clog_msg_str(p);
    clog_msg_str("\",cmd: ");
    clog_msg_str(input_line);
    clog_msg_send();
}

void addiovec_error(const char *p)
{
    addiovec(p, strlen(p));
    addiovec("\r\n", 2);

    iov_logerror(NULL, p);
    iovflush();

    if (*p == '5')
        tarpit();
}

static void showbanner()
{
const char *banner=config_esmtpgreeting();
const char *p;

    do
    {
        for (p=banner; *p; p++)
            if (*p == '\n')    break;
        addiovec((*p && p[1] ? "220-":"220 "), 4);
        addiovec(banner, p-banner);
        addiovec("\r\n", 2);
        if (*p)    p++;
        banner=p;
    } while (*banner);
}

static void ehlo(const char *heloname, int hastls, int tls)
{
static const char e[]=
COURIER_EXTENSIONS
EHLO_VERP_EXTENSION
EHLO_EXDATA_EXTENSION
EHLO_SECURITY_EXTENSION
"250-PIPELINING\r\n"
"250-8BITMIME\r\n"
"250-SIZE\r\n"
"250 DSN\r\n";
const char *me=config_me();
const char *p, *q;

    if (helobuf[0] == 0) 
    {
        char *p;

        strncat(helobuf, heloname, sizeof(helobuf)-1);

        for (p=helobuf; *p; p++)
            if (isspace((int)(unsigned char)*p) ||
                (int)(unsigned char)*p < ' ')
                *p='_';
    }

        putenv(strcat(strcpy(courier_malloc(sizeof("ESMTPHELO=") +
                        strlen(helobuf)),
                 "ESMTPHELO="), helobuf));

    if (!extended)
    {
        addiovec("250 ", 4);
        addiovec(me, strlen(me));
        addiovec(" Ok.\r\n", 6);
        return;
    }

    addiovec("250-", 4);
    addiovec(me, strlen(me));
    addiovec(" Ok.\r\n", 6);

    if (tls && (p=getenv("ESMTPAUTH_TLS")) != 0 && *p)
        ;
    else
        p=getenv("ESMTPAUTH");

    if (!p)
        p="";

    q=smtp_externalauth() ? "EXTERNAL":"";

    if (*p || *q)
    {
        addiovec("250-AUTH ", 9);
        addiovec(p, strlen(p));
        if (*p && *q)
            addiovec(" ", 1);
        addiovec(q, strlen(q));
        addiovec("\r\n", 2);
#if 0
        /*
        ** Netscape.
        */

        addiovec("250-AUTH=", 9);
        addiovec(p, strlen(p));
        if (*p && *q)
            addiovec(" ", 1);
        addiovec(q, strlen(q));
        addiovec(" X-NETSCAPE-HAS-BUGS\r\n", 22);
#endif
    }

    if (hastls)
    {
        static const char starttls_msg[]=
            "250-STARTTLS\r\n";

        addiovec(starttls_msg, sizeof(starttls_msg)-1);
    }

    addiovec(e, sizeof(e)-1);
}

extern char **environ;

static void badfork()
{
    addiovec_error("432 Service temporarily unavailable.");
}

static void expnvrfy(const char *line, const char *cmd)
{
struct    rfc822t *t=rfc822t_alloc_new(line, NULL, NULL);
struct    rfc822a *a;
char    *addr;
char    *argv[5];
int    rc;

    if (!t)    clog_msg_errno();

    a=rfc822a_alloc(t);
    if (!a)    clog_msg_errno();

    if (a->naddrs != 1 || a->addrs[0].tokens == 0)
    {
        addiovec_error("502 EXPN syntax error.");
        rfc822a_free(a);
        rfc822t_free(t);
        return;
    }

    addr=rfc822_getaddr(a, 0);
    rfc822a_free(a);
    rfc822t_free(t);
    if (!addr)    clog_msg_errno();

    argv[0]="submit";
    argv[1]=strcat(strcpy(courier_malloc(strlen(cmd)+strlen(addr)+1),
        cmd), addr);
    free(addr);
    argv[2]="local";    /* Use the LOCAL rewrite module */
    argv[3]="unknown; unknown";
    argv[4]=0;
    if (submit_fork(argv, environ, submit_print_stdout))
    {
        badfork();
        free(argv[1]);
        return;
    }
    free(argv[1]);
    fclose(submit_to);
    rc=submit_readrcprintcrlf();
    (void)submit_wait();
    if (rc == 0)
        teergrube=INIT_TEERGRUBE;
    fclose(fromsubmit);
}

static void startsubmit(int tls)
{
    char    *argv[14];
    const char *ident;
    char    *identbuf=0;
    int    n, exid_ndx=0;
    const    char *host;
    char    *buf;
    char rfc3848_buf[32];

    if (submit_started)    return;
    if (helobuf[0] == '\0')    return;

    argv[0]="submit";
    argv[1]=getenv("RELAYCLIENT") ? "-src=authsmtp":"-src=smtp";
    n=2;

    if (authuserbuf[0])
    {
        char *p;

        static char authbuf[sizeof(authuserbuf)+sizeof("-auth=")];

        p=strchr(authuserbuf, ' ');
        if (p)
        {
            strcat(strcpy(authbuf, "-auth="), p+1);
            argv[n++]=authbuf;
        }
        exid_ndx=1;
    }

    strcpy(rfc3848_buf, "-rfc3848=");

    if (extended)
    {
        static char *exid[] =
            {"ESMTP",
             "ESMTPA",
             "ESMTPS",
             "ESMTPSA"};

        if (tls) exid_ndx += 2;
        strcat(rfc3848_buf, exid[exid_ndx]);

    }
    else
    {
        strcat(rfc3848_buf, "SMTP");
    }
    argv[n++]=rfc3848_buf;

    argv[n++]="esmtp";

    host=tcpremotehost;

    if (!host)    host="";
    argv[n]=buf=courier_malloc(strlen(host)+strlen(tcpremoteip)+strlen(
        helobuf)+sizeof("dns;  ( [])"));

    strcat(strcat(strcpy(buf, "dns; "), helobuf), " (");
    if (*host)
        strcat(strcat(buf, host), " ");
    strcat(strcat(strcat(buf, "["), tcpremoteip), "])");

    ++n;

    if ((ident=getenv("TCPREMOTEINFO")) == 0)
        ident="";

    if (*ident || authuserbuf[0] || tls)
    {
        argv[n]=identbuf=courier_malloc(sizeof("IDENT: , AUTH: , ")+
                        strlen(tlsbuf)+
                        strlen(ident)+
                        strlen(authuserbuf));
        ++n;
        *identbuf=0;
        if (*ident)
            strcat(strcat(identbuf, "IDENT: "), ident);
                if (authuserbuf[0])
                {
                        if (*identbuf)  strcat(identbuf, ", ");
                        strcat(strcat(identbuf, "AUTH: "), authuserbuf);
            putenv(strcat(
                 strcpy(
                   courier_malloc(sizeof("SENDERAUTH=") +
                          strlen(authuserbuf)),
                   "SENDERAUTH="), authuserbuf));
        }

        if (tls)
        {
            if (*identbuf)    strcat(identbuf, ", ");
            strcat(identbuf, tlsbuf);
        }
    }

    argv[n]=0;

    if (submit_fork(argv, environ, submit_print_stdout) == 0)
        submit_started=1;

    if (identbuf)    free(identbuf);
    free(buf);
}

static void cancelsubmit()
{
    if (submit_started)
    {
        fclose(submit_to);
        fclose(fromsubmit);
        (void)submit_wait();
        submit_started=0;
    }
}

static char *log_error_sender=0;
static char *log_error_to=0;

static void print_submit_log_fix(void);

static void set_submit_error(const char *r, int rl)
{
char    *p;

    if (log_error_sender)    free(log_error_sender);
    if (log_error_to)    free(log_error_to);

    log_error_sender=0;
    if (mailfroms && (log_error_sender=strdup(mailfroms)) == 0)
        clog_msg_errno();

    log_error_to=0;
    if (r && rl)
    {
        if ((log_error_to=malloc(rl+1)) == 0)
            clog_msg_errno();
        memcpy(log_error_to, r, rl);
        log_error_to[rl]=0;
    }

    if (log_error_sender && *log_error_sender)
        for (p=log_error_sender+1; p[1]; p++)
            if (*p == '<' || *p == '>' || *p == ':')
                *p=' ';

    if (log_error_to && *log_error_to)
        for (p=log_error_to+1; p[1]; p++)
            if (*p == '<' || *p == '>' || *p == ':')
                *p=' ';

    if (log_error_sender && *log_error_sender)
        submit_log_error_prefix(print_submit_log_fix);
    else
        submit_log_error_prefix(0);
}

static void print_submit_log_fix(void)
{
const char *p;

    clog_msg_str("error,relay=");
    clog_msg_str(tcpremoteip);
    if ((p=getenv("TCPREMOTEINFO")) != 0 && *p)
    {
    char    *q=strdup(p), *r;

        if (!q)    clog_msg_errno();
        for (r=q; *r; r++)
            if (*r == ',' || *r == ':')    *r=' ';
        clog_msg_str(",ident=");
        clog_msg_str(q);
        free(q);
    }

    if (log_error_sender)
    {
        clog_msg_str(",from=");
        clog_msg_str(log_error_sender);
    }
    if (log_error_to)
    {
        clog_msg_str(",to=");
        clog_msg_str(log_error_to);
    }
    clog_msg_str(": ");
}

/* Skip the E-mail address in the MAIL FROM:/RCPT TO: command */

static const char *skipaddress(const char **ptr)
{
const char *p;
int inquote=0;

    while ( **ptr && isspace((int)(unsigned char)**ptr) )
        ++*ptr;

    if (**ptr != '<')    return (0);
    p= ++*ptr;

    while (*p)
    {
        if (*p == '>' && !inquote)    return (p);
        if (*p == '"')    inquote ^= 1;
        if (*p == '\\' && p[1])    ++p;
        ++p;
    }
    return (0);
}

/**************************************************************************/

/*                          MAIL FROM                                     */

/**************************************************************************/

static int domailfrom(const char *, const char *);

static int mailfrom(const char *p)
{
const char *q=skipaddress(&p);

    set_submit_error(0, 0);
    if (q)
    {
        /* Save <address> in mailfroms */

        if (mailfroms)    free(mailfroms);
        mailfroms=courier_malloc(q-p+3);
        memcpy(mailfroms, p-1, q-p+2);
        mailfroms[q-p+2]=0;
        set_submit_error(0, 0);
        return (domailfrom(p, q));
    }
    addiovec_error("554 Syntax error - your mail software violates RFC 821.");
    return (-1);
}

static int domailfrom(const char *p, const char *q)
{
const char *r, *s;
char    retformat=0;
const char *envid=0;
size_t    envidlen=0;
char    *buf;
int    rc;

    hasexdata=0;
    hasverp=0;
    hasstarttls=0;

    for (r=q+1; *r; r++)
    {
        if (isspace((int)(unsigned char)*r))    continue;
        for (s=r; *s && !isspace((int)(unsigned char)*s); s++)
            ;
        if (s - r == 4 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "VERP", 4)
#else
            strnicmp(r, "VERP", 4)
#endif
            == 0)
        {
            hasverp=1;
        }
        else if (s - r == 17 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "SECURITY=STARTTLS", 17)
#else
            strnicmp(r, "SECURITY=STARTTLS", 17)
#endif
            == 0)
        {
            hasstarttls=1;
        }
        else if (s - r == 6 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "EXDATA", 6)
#else
            strnicmp(r, "EXDATA", 6)
#endif
            == 0)
        {
            hasexdata=1;
        }
        else if (s - r >= 4 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "RET=", 4)
#else
            strnicmp(r, "RET=", 4)
#endif
            == 0)
        {
            switch (r[4])    {
            case 'f':
            case 'F':
                retformat='F';
                break;
            case 'h':
            case 'H':
                retformat='H';
                break;
            }
        }
        else if (s - r >= 6 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "ENVID=", 6)
#else
            strnicmp(r, "ENVID=", 6)
#endif
            == 0)
        {
            envid=r+6;
            envidlen=s-envid;
        }
        else if (s - r >= 5 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "SIZE=", 5)
#else
            strnicmp(r, "SIZE=", 5)
#endif
            == 0)
        {
        unsigned long l=0, n;

            for (r += 5; *r >= '0' && *r <= '9'; r++)
            {
                if ( (n=l * 10) < l ||
                    (n += *r-'0') < l ||
                    (sizelimit && n > sizelimit))
                {
                    addiovec_error("534 SIZE=Message too big.");
                    return (-1);
                }
                l=n;
            }
        }
        r= s-1;
    }

    buf=courier_malloc(q-p+envidlen+80);
    if (q > p)
        memcpy(buf, p, q-p);
    strcpy(buf + (q-p), "\t");
    if (retformat)
    {
    char b[2];

        b[0]=retformat;
        b[1]=0;
        strcat(buf, b);
    }
    if (hasverp)
        strcat(buf, "V");

    if (hasstarttls)
    {
        strcat(buf, "S{STARTTLS}");
    }

    if (envidlen)
    {
    char    *t;

        strcat(buf, "\t");
        t=buf+strlen(buf);
        memcpy(t, envid, envidlen);
        t[envidlen]=0;
    }
    submit_write_message(buf);
    free(buf);
    rc=submit_readrcprintcrlf();
    if (rc)
    {
        iovflush();
    }
    return (rc);
}

/**************************************************************************/

/*                            RCPT TO                                     */

/**************************************************************************/

static int dorcptto(const char *, const char *);

static int rcptto(const char *p)
{
const char *q=skipaddress(&p);

    if ( q )
    {
        set_submit_error(p-1, q-p+2);
        return (dorcptto(p, q));
    }
    addiovec_error("554 Syntax error - your mail software violates RFC 821.");
    return (-1);
}

static int dorcptto2(const char *p, const char *q);
static int rcpttolocal(const char *p, const char *r, const char *q);

static int dorcptto(const char *p, const char *q)
{
    const char *r;
    const char *tcp=getenv("TCPLOCALIP");

    /* foo@[our.ip.address] -> foo@default */

    for (r=p; r != q; r++)
    {
        if (*r == '@' && r[1] == '[' && tcp)
        {

            if (strncasecmp(r+2, tcp, strlen(tcp)) == 0 &&
                strncasecmp(r+2+strlen(tcp), "]>", 2) == 0)
            {
                return rcpttolocal(p, r+1, q);
            }

            if (strncmp(tcp, "::ffff:", 7) == 0)
            {
                tcp += 7;
                if (strncasecmp(r+2, tcp, strlen(tcp)) == 0 &&
                    strncasecmp(r+2+strlen(tcp), "]>", 2) == 0)
                {
                    return rcpttolocal(p, r+1, q);
                }
            }
        }
    }

    return dorcptto2(p, q);
}

static int rcpttolocal(const char *p, const char *r, const char *q)
{
    const char *d=config_defaultdomain();
    char *buf=courier_malloc(r-p + strlen(d)+strlen(q)+1);
    int rc;

    memcpy(buf, p, r-p);
    strcpy(buf+(r-p), d);

    p=buf+strlen(buf);
    strcat(buf, q);

    rc=dorcptto2(buf, p);
    free(buf);
    return rc;
}

static int dorcptto2(const char *p, const char *q)
{
int    notifyn=0,notifyf=0,notifys=0,notifyd=0;
const char *orcpt=0;
int    orcptlen=0;
const char *r, *s;
char    *t, *buf;
const char *relayclient=getenv("RELAYCLIENT");
int    relayclientl= relayclient ? strlen(relayclient):0;
int    rc;

    for (r=q+1; *r; r++)
    {
        if (isspace((int)(unsigned char)*r))    continue;
        for (s=r; *s && !isspace((int)(unsigned char)*s); s++)
            ;
        if (s - r > 7 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "NOTIFY=", 7)
#else
            strnicmp(r, "NOTIFY=", 7)
#endif
            == 0)
        {
            r += 7;
            while (r < s)
            {
                switch (toupper(*r))    {
                case 'N':
                    notifyn=1;
                    break;
                case 'S':
                    notifys=1;
                    break;
                case 'D':
                    notifyd=1;
                    break;
                case 'F':
                    notifyf=1;
                    break;
                }
                while (r < s)
                    if (*r++ == ',')    break;
            }


            hasverp=1;
        }
        else if (s - r > 6 &&
#if HAVE_STRNCASECMP
            strncasecmp(r, "ORCPT=", 6)
#else
            strnicmp(r, "ORCPT=", 6)
#endif
            == 0)
        {
            r += 6;
            orcpt=r;
            orcptlen=s-r;
        }
    }

    buf=courier_malloc(q-p + relayclientl + orcptlen + 10);
    memcpy(buf, p, q-p);
    t=buf + (q-p);
    if (relayclientl)
        memcpy(t, relayclient, relayclientl);
    t += relayclientl;

    *t++ = '\t';
    if (notifyn)
        *t++ = 'N';
    else
    {
        if (notifys)
            *t++ = 'S';
        if (notifyf)
            *t++ = 'F';
        if (notifyd)
            *t++ = 'D';
    }
    *t++ = '\t';
    if (orcptlen)
        memcpy(t, orcpt, orcptlen);
    t[orcptlen]=0;

    submit_write_message(buf);
    free(buf);
    rc=submit_readrcprintcrlf();
    if (rc)
    {
        iovflush();
    }
    return (rc);
}

static void getmoredata(char *p, int *l)
{
time_t    t;

    time(&t);
    t += data_timeout;
    if (iovwaitfordata(&t, 0) || (*l=read(0, p, *l)) <= 0)
    {
        submit_cancel();
        _exit(0);
    }
}

void data()
{
char    databuf[BUFSIZ];
char *p;
int l;
int    rc;

    l=0;
    p=databuf;
    for (;;)
    {
        if (l == 0)
        {
            p=databuf;
            l=sizeof(databuf);
            getmoredata(p, &l);
        }

        if ( *p == '.' )
        {
            ++p; --l;
            if (l == 0)
            {
                p=databuf;
                l=sizeof(databuf);
                getmoredata(p, &l);
            }
            if (*p == '\r')
            {
                ++p;
                --l;
                if (l == 0)
                {
                    p=databuf;
                    l=sizeof(databuf);
                    getmoredata(p, &l);
                }
                if (*p == '\n')
                {
                    ++p;
                    --l;
                    break;
                }
                putc('\r', submit_to);
            }
        }
        for (;;)
        {
            if (l == 0)
            {
                p=databuf;
                l=sizeof(databuf);
                getmoredata(p, &l);
            }
            if (*p == '\r')
            {
                ++p;
                --l;
                if (l == 0)
                {
                    p=databuf;
                    l=sizeof(databuf);
                    getmoredata(p, &l);
                }
                if (*p == '\n')    break;
                putc('\r', submit_to);
                continue;
            }
            putc(*p, submit_to);
            ++p;
            --l;
        }
        putc('\n', submit_to);
        ++p;
        --l;
    }
    fclose(submit_to);
    rc=submit_readrcprintcrlf();
    if (submit_wait() && rc == 0)
    {
        clog_msg_start_err();
        clog_msg_str("submit terminated with a non-zero exit code.");
        clog_msg_send();
        exit(0);
    }

    if (rc == 0)
        teergrube=INIT_TEERGRUBE;
    fclose(fromsubmit);
}

static int bofh(const char *bofh)
{
const char *p=getenv(bofh);

    if (p && *p == '1')    return (1);
    return (0);
}

static char *sasl_conv_func(const char *s, void *dummy)
{
char    *p;

    addiovec("334 ", 4);
    addiovec(s, strlen(s));
    addiovec("\r\n", 2);
    iovflush();

    p=iovreadline();
    if (!p)    exit(0);
    if ((p=strdup(p)) == 0)
    {
        perror("malloc");
        exit(0);
    }
    return (p);
}

static int auth_callback_func(struct authinfo *a, void *va)
{
    char *p;

    strcpy(authuserbuf, "");
    strncat(authuserbuf, (const char *)va, 20);
    strcat(authuserbuf, " ");
    strncat(authuserbuf, a->address,
        sizeof(authuserbuf)-10-strlen(a->address));

    for (p=authuserbuf; *p; p++)
        if ((int)(unsigned char)*p < ' ' || *p >= 127)
            *p=' ';
    return 0;
}

static char *rtrim(char *s)
{
    char *end = s + strlen(s);
    while (s < end)
        if (isspace(*(unsigned char*)--end))
            *end = 0;
        else
            break;
    return s;
}


/*****************************************************************************

courieresmtpd can be started in two situations:

* No command line arguments: courier is not configured to support the ESMTP
  AUTH extension

* Command line arguments are present: Courier is configured to support the
  ESMTP AUTH extension

*****************************************************************************/

int main(int argc, char **argv)
{
int    seenmailfrom;
int    seenrcptto;
char    *line;
int    starttls=0;
int    tls=0;
int    tls_required=0;
int    auth_required=0;
int    authenticated=0;

#if HAVE_SETLOCALE
    setlocale(LC_ALL, "C");
#endif
    /*
    ** When called via -bs to sendmail, dump log to /dev/null via stderr,
    ** else record everything via syslog.
    */

    if (chdir(courierdir()))
        clog_msg_errno();

    if (fcntl(0, F_SETFL, O_NONBLOCK) ||
        fcntl(1, F_SETFL, O_NONBLOCK))
    {
        perror("fcntl");
        exit(1);
    }

    helobuf[0]=0;
    submit_set_teergrube(tarpit);

    if (strcmp(argv[0], "sendmail") == 0)
        clog_open_stderr("courieresmtpd");
        /* We are being called by the sendmail command line wrapper */

    else
    {
    const char *p;

        clog_open_syslog("courieresmtpd");

        if ((p=getenv("ESMTP_TLS")) && atoi(p))
        {
            const char *p=getenv("TLS_CONNECTED_PROTOCOL");

            tls=1;
            /* This is the smtps service, and we don't need to
             * initialize the STARTTLS feature. */

            if (p && *p)
            {
                strcpy(tlsbuf, "SSL: ");
                strncat(tlsbuf, p, sizeof(tlsbuf)-6);
            }
        }
        else
        {
            if ((p=getenv("COURIERTLS")) != 0 && *p
                && access(p, X_OK) == 0 &&
                (p=getenv("TLS_CERTFILE")) != 0 && *p &&
                access(p, R_OK) == 0)
                starttls=1;

            if ((p=getenv("ESMTP_TLS_REQUIRED")) && atoi(p))
            {
                tls_required=1;
                if (!starttls)
                {
                    addiovec_error("440 TLS not available,  but"
                        " it's required for this connection.");
                    return (1);
                }
            }
        }
    }


    {
        const char *p=getenv("AUTH_REQUIRED");

        if (p)
            auth_required=atoi(p);
    }

    iovread_timeout=config_time_esmtptimeout();
    iovwrite_timeout=data_timeout=config_time_esmtpdata();

    tcpremoteip=getenv("TCPREMOTEIP");
    tcpremotehost=getenv("TCPREMOTEHOST");

    if (!tcpremoteip)
    {
        fprintf(stderr, "%s: don't know your IP address, no dice.\n",
            argv[0]);
        exit(1);
    }

    showbanner();
    iovflush();

    signal(SIGPIPE, SIG_IGN);
    /* Some house keeping, while waiting for a reply */

    if (rw_init_courier("esmtp"))    return (1);

    clog_msg_start_info();
    clog_msg_str("started,ip=[");
    clog_msg_str(tcpremoteip);
    clog_msg_str("]");
    clog_msg_send();

    seenmailfrom=0;
    seenrcptto=0;
    sizelimit=config_sizelimit();

    for (;;)
    {
    char    *p;

        input_line=line=iovreadline();

        /* Optionally log the esmtp dialog */
        if ((p=getenv("ESMTP_LOG_DIALOG")) && *p == '1')
        {
            clog_msg_start_info();
            clog_msg_str(input_line);
            clog_msg_str("\n");
            clog_msg_send();
        }

        for (p=line; *p && *p != ':'; p++)
        {
            if (*p == ' ' && strncmp(line, "MAIL", 4) &&
                strncmp(line, "RCPT", 4))
                break;

            *p=toupper(*p);
        }

        rtrim(line);
        if (strcmp(line, "QUIT") == 0)    break;
        if ((strncmp(line, "EHLO ", 5) == 0 ||
            strncmp(line, "HELO ", 5) == 0) &&
            line[5])
        {
            extended=line[0] == 'E';
            ehlo(line+5, starttls, tls);
            iovflush();
            cancelsubmit();
            startsubmit(tls);
            continue;
        }

        if (strcmp(line, "STARTTLS") == 0)
        {
        int    pipefd[2];
        struct couriertls_info cinfo;
        char    *argvec[4];
        char    buf1[NUMBUFSIZE+40];
        char    buf2[NUMBUFSIZE];

            if (!starttls)
            {
                addiovec_error("540 TLS not available.");
                continue;
            }
            if (libmail_streampipe(pipefd))
            {
                addiovec_error("432 libmail_streampipe() failed.");
                exit(1);
            }

            couriertls_init(&cinfo);

            strcat(strcpy(buf1, "-localfd="),
                   libmail_str_size_t(pipefd[1], buf2));

            argvec[0]=buf1;
            argvec[1]="-tcpd";
            argvec[2]="-server";
            argvec[3]=NULL;
            fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);

            addiovec("220 Ok\r\n", 8);
            iovflush();
            iovreset();

            if (couriertls_start(argvec, &cinfo))
            {
                close(pipefd[0]);
                close(pipefd[1]);
                syslog(LOG_MAIL|LOG_ERR,
                       "courieresmtpd: STARTTLS failed: %s\n",
                       cinfo.errmsg);
                couriertls_destroy(&cinfo);
                exit(1);
            }

            close(pipefd[1]);
            strcpy(tlsbuf, "TLS: ");
            strncat(tlsbuf, cinfo.version, 40);
            if (cinfo.bits > 0)
                strcat(strcat(strcat(tlsbuf, ","),
                          libmail_str_size_t(cinfo.bits,
                             buf2)),
                       "bits");
            strncat(strcat(tlsbuf, ","), cinfo.cipher, 40);

            couriertls_export_subject_environment(&cinfo);
            couriertls_destroy(&cinfo);

            tls=1;
            starttls=0;
            tls_required=0;
            close(pipefd[1]);
            close(0);
            close(1);
            if (dup(pipefd[0]) != 0 || dup(pipefd[0]) != 1)
            {
                perror("dup");
                exit(1);
            }
            close(pipefd[0]);
            cancelsubmit();
            startsubmit(tls);    /* Mark */

            setenv("ESMTP_TLS", "1", 1);
            continue;
        }

        if (tls_required && strcmp(line, "RSET"))
        {
            addiovec_error("400 STARTTLS is required first.");
            continue;
        }

        if (strncmp(line, "AUTH ", 5) == 0 && mailfroms == 0
            && authuserbuf[0] == 0)
        {
        char    *authmethod;
        char    *initreply;
        const char *q;
        char    *buf=strcpy(courier_malloc(strlen(line)+1), line);
        char    *authtype;
        char    *authdata;
        char    fakecmd[5];

                strcpy(fakecmd, "AUTH");

            starttls=0;
            (void)strtok(buf, " \t\r\n");
            authmethod=strtok(0, " \t\r\n");
            initreply=strtok(0, " \t\r\n");

            if (tls && (q=getenv("ESMTPAUTH_TLS")) != 0 && *q)
                ;
            else
                q=getenv("ESMTPAUTH");

            if (q == 0 || *q == 0)    authmethod=0;

            if (authmethod == 0 || *authmethod == 0)
            {
                input_line=fakecmd;
                addiovec_error("535 Authentication rejected");
                free(buf);
                continue;
            }

            if (initreply && *initreply)
            {
                if (strcmp(initreply, "=") == 0)
                    initreply="";
            }
            else
            {
                initreply=0;
            }

            if (auth_sasl_ex(authmethod, initreply,
                     smtp_externalauth(),
                     sasl_conv_func,
                     NULL,
                     &authtype,
                     &authdata) != AUTHSASL_OK)
            {
                /* TODO - better error messages */

                strcpy(authuserbuf, "");
            }
            else
            {
                int rc=auth_generic("esmtp", authtype,
                            authdata,
                            auth_callback_func,
                            authmethod);

                free(authtype);
                free(authdata);

                if (rc)
                    strcpy(authuserbuf, "");
            }

            if (authuserbuf[0] == 0)
            {
                input_line=fakecmd;
                addiovec_error("535 Authentication failed.");
                iovflush();
            }
            else
            {
            const char *rc;
            char *p;

                addiovec("235 Ok\r\n", 8);
                iovflush();
                cancelsubmit();
                putenv("BLOCK=");
                rc=getenv("AUTHRELAYCLIENT");
                if (!rc)    rc="";
                p=courier_malloc(sizeof("RELAYCLIENT=")+
                    strlen(rc));
                strcat(strcpy(p, "RELAYCLIENT="), rc);
                putenv(p);
                putenv("FAXRELAYCLIENT=");
                startsubmit(tls);
                authenticated=1;
            }
            free(buf);
            continue;
        }

        if (auth_required && !authenticated && strcmp(line, "RSET"))
        {
            addiovec_error("535 Authentication required.");
            continue;
        }

        if (strncmp(line, "EXPN ", 5) == 0)
        {
            starttls=0;
            if (bofh("BOFHNOEXPN") == 0 && seenmailfrom == 0)
            {
                cancelsubmit();
                expnvrfy(line+5, "-expn=");
                startsubmit(tls);
            }
            else    addiovec_error("252 EXPN disabled");
            continue;
        }
        if (strncmp(line, "VRFY ", 5) == 0)
        {
            starttls=0;
            if (bofh("BOFHNOVRFY") == 0 && seenmailfrom == 0)
            {
                cancelsubmit();
                expnvrfy(line+5, "-vrfy=");
                startsubmit(tls);
            }
            else    addiovec_error("252 VRFY disabled");
            continue;
        }
        if (strcmp(line, "RSET") == 0)
        {
            starttls=0;
            addiovec("250 Ok\r\n", 8);
            iovflush();
            cancelsubmit();
            startsubmit(tls);
            seenmailfrom=0;
            if (mailfroms)    free(mailfroms);
            mailfroms=0;
            set_submit_error(0, 0);
            continue;
        }
        if (strncmp(line, "NOOP", 4) == 0)
        {
            addiovec("250 Ok\r\n", 8);
            iovflush();
            continue;
        }
        if (strncmp(line, "MAIL", 4) == 0 && (p=strchr(line, ':')) != 0
            && !seenmailfrom)
        {
            starttls=0;
            if (!helobuf[0])
            {
                addiovec_error("502 Polite people say HELO first");
                continue;
            }
            if (!submit_started)
            {
                badfork();
                continue;
            }
            if (mailfrom(p+1) == 0)
            {
                seenmailfrom=1;
                seenrcptto=0;
            }
            else
            {
                cancelsubmit();
                startsubmit(tls);
            }
            continue;
        }

        if (strncmp(line, "RCPT", 4) == 0 && (p=strchr(line, ':')) != 0
                && seenmailfrom)
        {
            if (rcptto(p+1) == 0)
                seenrcptto=1;
            continue;
        }
        if (strcmp(line, "DATA") == 0 && seenmailfrom && seenrcptto)
        {
            set_submit_error(0, 0);
            addiovec("354 Ok.\r\n", 9);
            iovflush();
            putc('\n', submit_to);
            data();
            seenmailfrom=0;
            seenrcptto=0;
            submit_started=0;
            if (mailfroms)    free(mailfroms);
            mailfroms=0;
            startsubmit(tls);
            continue;
        }
        addiovec_error("502 ESMTP command error");
    }
    addiovec("221 Bye.\r\n", 10);
    iovflush();
    return (0);
}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2307 seconds