Exemplo n.º 1
0
Arquivo: kmail.c Projeto: klopp/ksmtp
int mail_SendFromFile( KMail mail, const char * file, const char * from,
        const List to, const List cc, const List bcc )
{
    char buf[1024];
    size_t rc = 1;
    size_t readed;
    Pair addr;
    FILE * msg = fopen( file, "rb" );
    if( !msg )
    {
        mail_FormatError( mail, "mail_SendFromFile(\"%s\") - %s", file,
                strerror(errno) );
        return 0;
    }

    if( !smtp_MAIL_FROM( mail->smtp, from ) )
    {
        rc = 0;
        goto pmend;
    }

    addr = to ? lfirst( to ) : NULL;
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( to );
    }

    addr = cc ? lfirst( cc ) : NULL;
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( cc );
    }

    addr = bcc ? lfirst( bcc ) : NULL;
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( bcc );
    }

    if( !smtp_DATA( mail->smtp ) )
    {
        rc = 0;
        goto pmend;
    }
    while( (readed = fread( buf, 1, sizeof(buf), msg )) > 0 )
    {
        if( !smtp_write_buf( mail->smtp, buf, readed ) )
        {
            rc = 0;
            goto pmend;
        }
        if( mail->flags & KMAIL_VERBOSE_MSG )
        {
            fwrite( buf, 1, readed, stderr );
        }
    }

    pmend: smtp_END_DATA( mail->smtp );
    fclose( msg );
    return rc;
}
Exemplo n.º 2
0
/* returns 0 on success, -1 on failure */
int send_the_mail(char *from,char *to,char *cc,char *bcc,char *sub,
             char *smtp_server,int smtp_port,char *helo_domain,
             char *attach_file,char *txt_msg_file,char *the_msg,int is_mime,char *rrr,char *rt,
             int add_dateh)
{
    SOCKET
        sfd;

    TheMail
        *mail;


    Sll
        *al;

    int
        rc=(-1);

    char
        *mech=NULL,
        *auth=NULL;

    /*
    unsigned char
		*b64=NULL;
    */
    char
        *b64 = NULL;

    int
        authenticated=0;
 
    /*
    (void) fprintf(stderr,"From: %s\n",from);
    (void) fprintf(stderr,"To: %s\n",to);
    (void) fprintf(stderr,"Cc: %s\n",cc);
    (void) fprintf(stderr,"Cc: %s\n",bcc);
    (void) fprintf(stderr,"Sub: %s\n",sub);
    (void) fprintf(stderr,"smtp: %s\n",smtp_server);
    (void) fprintf(stderr,"smtp port: %d\n",smtp_port);
    (void) fprintf(stderr,"domain: %s\n",helo_domain);
    (void) fprintf(stderr,"attach file: %s\n",attach_file);
    (void) fprintf(stderr,"txt_msg_file: %s\n",txt_msg_file);
    (void) fprintf(stderr,"the_msg: %s\n",the_msg);
    (void) fprintf(stderr,"is_mime: %d\n",is_mime);
    */

    al=getAddressList();

    if (al == (Sll *) NULL)
    {
        errorMsg("No To address/es specified");
        return (-1);
    }

    if (from == (char *) NULL)
    {
        errorMsg("No From address specified");
        return (-1);
    }

    if (smtp_server == (char *) NULL)
        smtp_server="127.0.0.1";

    if (smtp_port == -1)
        smtp_port=MAILSEND_SMTP_PORT;

    if (sub == (char *) NULL)
        sub=MAILSEND_DEF_SUB;

    if (helo_domain == (char *) NULL)
    {
        errorMsg("No domain specified");
        return (-1);
    }

    mail=newTheMail();
    if (mail == (TheMail *) NULL)
    {
        errorMsg("Error: malloc failed in createTheMail()\n");
        return (-1);
    }

    showVerbose("Connecting to %s:%d\n",smtp_server,smtp_port);
    /* open the network connection */
    sfd=smtpConnect(smtp_server,smtp_port);
    if (sfd == INVALID_SOCKET)
    {
        rc=(-1);
        goto cleanup;
    }

    if (g_do_ssl) /* smtp.gmail:465 supports it for example */
    {
        turn_on_raw_ssl(sfd);
    }

    /* read greeting */
    rc=read_greetings();
    if (rc < 0)
        goto cleanup;

    /* say HELO/EHLO */
    say_helo(helo_domain);

    /* check if the server supports STARTTLS or TLS */
    if (g_do_starttls)
    {
        if (check_server_cap("STARTTLS") ||
            check_server_cap("TLS"))
        {
            rc=smtp_start_tls(sfd);
            if (rc == 0)
            {
               /* send HELO again */
                say_helo(helo_domain);
            }
        }
    }

    if (g_do_auth || g_auth_cram_md5 || g_auth_login || g_auth_plain)
    {
        auth=check_server_cap("AUTH");
    }
    if (!auth)
        goto MailFrom;
    /*
    (void) fprintf(stderr,"auth=%s\n",auth);
    (void) fprintf(stderr," g_auth_cram_md5=%d; g_auth_login=%d; g_auth_plain=%d\n", g_auth_cram_md5, g_auth_login, g_auth_plain);
    */

    /*
    if (auth && g_do_auth)
    {
        g_auth_cram_md5=1;
        g_auth_login=1;
        g_auth_plain=1;
    }
    */
    /* Try CRAM-MD5 first */
    mech="CRAM-MD5";
    if (g_auth_cram_md5 && check_server_cap(mech))
    {
        char
            *cmd5 = NULL;

        CHECK_USERNAME(mech);
        CHECK_USERPASS(mech);

#ifndef HAVE_OPENSSL
        errorMsg("Must be compiled with OpenSSL in order to get CRAM-MD5 support\n");
        goto cleanup;
#endif /* !HAVE_OPENSSL */
        showVerbose("Using AUTH %s\n",mech);
        memset(buf,0,sizeof(buf));
        (void) snprintf(buf,sizeof(buf)-1,"AUTH %s\r\n",mech);
        showVerbose("[C] %s",buf);
        msock_puts(buf);

        read_smtp_line();
        if (smtp_code != 334)
        {
            errorMsg("AUTH CRAM-MD5 failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }
        cmd5 = encode_cram_md5(smtp_line,g_username,g_userpass);
        if (cmd5 == NULL)
        {
            errorMsg("Could not encode CRAM-MD5");
            rc = (-1);
            goto cleanup;
        }
        memset(buf,0,sizeof(buf));
        (void) snprintf(buf,sizeof(buf)-1,"%s\r\n",cmd5);
        showVerbose("[C] %s",buf);
        msock_puts(buf);
        read_smtp_line();
        if (smtp_code != 235)
        {
            errorMsg("AUTH CRAM-MD5 failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }

        showVerbose("%s Authentication succeeded\n",mech);
        authenticated++;
        if (cmd5)
        {
            (void) free((char *) cmd5);
        }
    }
    else
    {
        if (g_auth_cram_md5)
            showVerbose("Server does not support AUTH CRAM-MD5\n");
    }
    if (authenticated)
        goto MailFrom;

    mech="LOGIN";
    if (g_auth_login && check_server_cap(mech))
    {
        CHECK_USERNAME(mech);
        CHECK_USERPASS(mech);

        showVerbose("Using AUTH %s\n",mech);
        memset(buf,0,sizeof(buf));
        (void) snprintf(buf,sizeof(buf)-1,"AUTH %s\r\n",mech);
        showVerbose("[C] %s",buf);
        msock_puts(buf);

        read_smtp_line();
        if (smtp_code != 334)
        {
            errorMsg("AUTH LOGIN failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }
        /*
        b64=mutils_encode_base64(g_username,strlen(g_username),&b64len);
        b64[b64len-2]='\0';
        */
        b64=mutils_encode_base64_noformat(g_username,strlen(g_username));
        if (b64 == NULL)
        {
            errorMsg("Could not base64 encode user: %s",g_username);
            rc=(-1);
            goto cleanup;
        }

        memset(buf,0,sizeof(buf));
        (void) snprintf(buf,sizeof(buf)-1,"%s\r\n",b64);
        showVerbose("[C] %s",buf);
        msock_puts(buf);
        read_smtp_line();
        if (smtp_code != 334)
        {
            errorMsg("AUTH LOGIN failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }

        /*
        b64=mutils_encode_base64(g_userpass,strlen(g_userpass),&b64len);
        b64[b64len-2]='\0';
        */
        b64=mutils_encode_base64_noformat(g_userpass,strlen(g_userpass));
        if (b64 == NULL)
        {
            errorMsg("Could not base64 encode passworf of user: %s",g_username);
            rc=(-1);
            goto cleanup;
        }

        memset(buf,0,sizeof(buf));
        (void) snprintf(buf,sizeof(buf)-1,"%s\r\n",b64);
        showVerbose("[C] %s",buf);
        msock_puts(buf);
        read_smtp_line();
        if (smtp_code != 235)
        {
            errorMsg("AUTH LOGIN failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }
        authenticated++;
    }
    else
    {
        if (g_auth_login)
            showVerbose("Server does not support AUTH LOGIN\n");
    }


    if (authenticated)
        goto MailFrom;

    mech="PLAIN";
    if (g_auth_plain && check_server_cap(mech))
    {
        int
            len,
            ulen,
            plen;

        unsigned char
            *b64=NULL;

        CHECK_USERNAME(mech);
        CHECK_USERPASS(mech);

        showVerbose("Using AUTH %s\n",mech);
        memset(buf,0,sizeof(buf));
        /*
        ** authzid\0authid\0pass
        ** authzid can be skipped if both are the same
        */

        ulen=strlen(g_username);
        memcpy(buf + 1,g_username,ulen);
        plen=strlen(g_userpass);

        memcpy(buf + ulen + 2,g_userpass,plen);
        len=ulen + plen + 2;
#if 0
        b64=mutils_encode_base64(buf,len,&b64len);
        /* mutils_encode_base64 adds CRLF */
        b64[b64len-2]='\0';
#endif
        b64=mutils_encode_base64_noformat(buf,len);
        if (b64 == NULL)
        {
            errorMsg("Could not base64 for AUTH-PLAIN for user: %s",g_username);
            rc=(-1);
            goto cleanup;
        }

        (void) snprintf(buf,sizeof(buf)-1,"AUTH PLAIN %s\r\n",(char *) b64);

        showVerbose("[C] %s",buf);
        msock_puts(buf);

        read_smtp_line();
        if (smtp_code != 235)
        {
            errorMsg("AUTH PLAIN failed: '%d %s'",
                    smtp_code,
                    smtp_line);
            rc=(-1);
            goto cleanup;
        }
        showVerbose("PLAIN Authentication succeeded\n");
        authenticated++;
    }
    else
    {
        if (g_auth_plain)
            showVerbose("Server does not support AUTH PLAIN\n");
    }

    if (authenticated)
        goto MailFrom;

    if (auth && !g_quiet)
    {
        if (!g_auth_cram_md5)
        {
            if (check_server_cap("CRAM-MD5"))
            {
                (void) fprintf(stderr,
" * Server supports AUTH CRAM-MD5.");
            }
        }
        if (!g_auth_login)
        {
            if (check_server_cap("LOGIN"))
            {
                (void) fprintf(stderr,
" * Server supports AUTH LOGIN.\n");
            }
        }

        if (!g_auth_plain)
        {
            if (check_server_cap("PLAIN"))
            {
                (void) fprintf(stderr,
" * Server supports AUTH PLAIN.\n");
            }
        }
        if (!authenticated)
        {
                (void) fprintf(stderr,
" Use -auth or specify a mechanism that server supports. exiting.\n");
            exit(1);
        }
    }

MailFrom:
    rc=smtp_MAIL_FROM(from);
    if (rc != 0)
        goto cleanup;

    rc=smtp_RCPT_TO();
    if (rc != 0)
        goto cleanup;

    rc=smtp_DATA();
    if (rc != 0)
        goto cleanup;

    rc=smtpMail(sfd,to,cc,bcc,from,rrr,rt,sub,attach_file,txt_msg_file,the_msg,is_mime,add_dateh);
    RETURN_IF_NOT_ZERO(rc);

    rc=smtpEom(sfd);
    RETURN_IF_NOT_ZERO(rc);
    smtp_QUIT();

cleanup:
    return (rc);
}
Exemplo n.º 3
0
Arquivo: kmail.c Projeto: klopp/ksmtp
int mail_SendMessage( KMail mail, KMsg msg )
{
    Pair addr;
    int rc = 1;
    string out = NULL;
    string related = NULL;
    string multipart = NULL;
    char mp_boundary[36];
    char r_boundary[36];

    if( !smtp_MAIL_FROM( mail->smtp, A_EMAIL(msg->from) ) )
    {
        rc = 0;
        goto pmend;
    }

    addr = lfirst( msg->to );
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( msg->to );
    }
    addr = lfirst( msg->cc );
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( msg->cc );
    }

    addr = lfirst( msg->bcc );
    while( addr )
    {
        if( !smtp_RCPT_TO( mail->smtp, A_EMAIL(addr) ) )
        {
            rc = 0;
            goto pmend;
        }
        addr = lnext( msg->bcc );
    }

    out = msg_CreateHeaders( msg );
    if( !out )
    {
        rc = 0;
        goto pmend;
    }

    if( mail->flags & KMAIL_VERBOSE_MSG )
    {
        fprintf( stderr, "%s", sstr( out ) );
    }

    if( !smtp_DATA( mail->smtp ) || !smtp_write( mail->smtp, sstr( out ) ) )
    {
        rc = 0;
        goto pmend;
    }

    sdel( out );
    out = msg_CreateBody( msg );
    if( !out )
    {
        rc = 0;
        goto pmend;
    }

    if( mail->flags & KMAIL_VERBOSE_MSG )
    {
        fprintf( stderr, "%s", sstr( out ) );
    }

    if( msg->efiles->size )
    {
        mimeMakeBoundary( r_boundary );
        related = sfromchar( "Content-Type: multipart/related; boundary=\"" );
        if( !related || !xscatc( related, r_boundary, "\"\r\n\r\n", NULL ) )
        {
            rc = 0;
            goto pmend;
        }
    }

    if( msg->afiles->size )
    {
        mimeMakeBoundary( mp_boundary );
        multipart = sfromchar( "Content-Type: multipart/mixed; boundary=\"" );
        if( !multipart
                || !xscatc( multipart, mp_boundary, "\"\r\n\r\n", NULL ) )
        {
            rc = 0;
            goto pmend;
        }
        if( !smtp_write( mail->smtp, sstr( multipart ) ) )
        {
            rc = 0;
            goto pmend;
        }
        if( slen(out) && !write_boundary( mail->smtp, mp_boundary ) )
        {
            rc = 0;
            goto pmend;
        }

        if( related )
        {
            if( !smtp_write( mail->smtp, sstr( related ) )
                    || !write_boundary( mail->smtp, r_boundary )
                    || !smtp_write( mail->smtp, sstr( out ) )
                    || !mail_EmbedFiles( mail, msg, r_boundary )
                    || !write_boundary_end( mail->smtp, r_boundary ) )
            {
                rc = 0;
                goto pmend;
            }
        }

        if( !mail_AttachFiles( mail, msg, mp_boundary )
                || !write_boundary_end( mail->smtp, mp_boundary ) )
        {
            rc = 0;
            goto pmend;
        }
    }
    else if( msg->efiles->size )
    {
        if( !smtp_write( mail->smtp, sstr( related ) )
                || !write_boundary( mail->smtp, r_boundary )
                || !smtp_write( mail->smtp, sstr( out ) )
                || !mail_EmbedFiles( mail, msg, r_boundary )
                || !write_boundary_end( mail->smtp, r_boundary ) )
        {
            rc = 0;
            goto pmend;
        }
    }
    else
    {
        if( slen( out ) && !smtp_write( mail->smtp, sstr( out ) ) )
        {
            rc = 0;
            goto pmend;
        }
    }

    pmend: sdel( out );
    sdel( related );
    sdel( multipart );
    smtp_END_DATA( mail->smtp );
    return rc;
}