SMTP 最简单的方式发送邮件

SMTP 发送邮件


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "base64.h"
#include "net.h"
#include "ssl.h"
#include "entropy.h"
#include "ctr_drbg.h"
#include "certs.h"
#include "x509.h"
#include "config.h"
#include "error.h"
#include "bc_ssl.h"
#include "bc_email_internal.h"
//#include "time_ex.h"
#include "bc_log.h"

#include "smtp.h"

#if 0
static int do_handshake( mbedtls_ssl_context *ssl )
{
    int ret;
    unsigned char buf[1024];
    memset(buf, 0, 1024);

    /*
     * 4. Handshake
     */
    printf( "  . Performing the SSL/TLS handshake..." );
    fflush( stdout );

    while( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
#if defined(MBEDTLS_ERROR_C)
            mbedtls_strerror( ret, (char *) buf, 1024 );
#endif
            printf( " failed  ! mbedtls_ssl_handshake returned %d: %s\n\n", ret, buf );
            return( -1 );
        }
    }

    printf( " ok\n    [ Ciphersuite is %s ]\n", mbedtls_ssl_get_ciphersuite( ssl ) );

   
    //5. Verify the server certificate
   
    /*printf( "  . Verifying peer X.509 certificate..." );

    // In real life, we probably want to bail out when ret != 0 //
    if( ( flags = mbedtls_ssl_get_verify_result( ssl ) ) != 0 )
    {
        char vrfy_buf[512];

        printf( " failed" );

        mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ",
flags );

        printf( "%s\n", vrfy_buf );
    }
    else
        printf( " ok\n" );

    printf( "  . Peer certificate information    ...\n" );
    mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                   mbedtls_ssl_get_peer_cert( ssl ) );
    printf( "%s\n", buf );*/

    return( 0 );
}
#endif

#if 0
static int write_ssl_data( mbedtls_ssl_context *ssl, unsigned char *buf,
size_t len )
{
    int ret;

//    printf("\n%s", buf);
    while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            ERROR( " failed  ! mbedtls_ssl_write returned %d\n\n", ret );
            return -1;
        }
    }
    return( 0 );
}
#endif

#if 0
static int write_ssl_and_get_response( mbedtls_ssl_context *ssl, unsigned
char *buf, size_t len )
{
    int ret;
    unsigned char data[128];
    char code[4];
    size_t i, idx = 0;

    printf("\n%s", buf);
    while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            ERROR( " failed  ! mbedtls_ssl_write returned %d\n\n", ret );
            return -1;
        }
    }

    do
    {
        len = sizeof( data ) - 1;
        memset( data, 0, sizeof( data ) );
        ret = mbedtls_ssl_read( ssl, data, len );

        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
            continue;

        if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
            return -1;

        if( ret <= 0 )
        {
            ERROR( "failed  ! mbedtls_ssl_read returned %d\n\n", ret );
            return -1;
        }

        printf("\n%s", data);
        len = ret;
        for( i = 0; i < len; i++ )
        {
            if( data[i] != '\n' )
            {
                if( idx < 4 )
                    code[ idx++ ] = data[i];
                continue;
            }

            if( idx == 4 && code[0] >= '0' && code[0] <= '9' && code[3] == ' ' )
            {
                code[3] = '\0';
                return atoi( code );
            }

            idx = 0;
        }
    }
    while( 1 );
}

#endif

#if 1
static int write_and_get_response( mbedtls_net_context *sock_fd, unsigned
char *buf, size_t len )
{
    int ret;
    unsigned char data[128];
    char code[4];
    size_t i, idx = 0;

    printf("\n%s", buf);
    if( len && ( ret = mbedtls_net_send( sock_fd, buf, len ) ) <= 0 )
    {
        ERROR( " failed  ! mbedtls_ssl_write returned %d\n\n", ret );
        return -1;
    }

    do
    {
        len = sizeof( data ) - 1;
        memset( data, 0, sizeof( data ) );
  
        ret = mbedtls_net_recv( sock_fd, data, len );

        if( ret <= 0 )
        {
            ERROR( "failed  ! read returned %d\n\n", ret );
            return -1;
        }

        data[len] = '\0';
        printf("\n## %s", data);
        len = ret;
        for( i = 0; i < len; i++ )
        {
            if( data[i] != '\n' )
            {
                if( idx < 4 )
                    code[ idx++ ] = data[i];
                continue;
            }

            if( idx == 4 && code[0] >= '0' && code[0] <= '9' && code[3] == ' ' )
            {
                code[3] = '\0';
                return atoi( code );
            }

            idx = 0;
        }
    }
    while( 1 );
}


static int write_data( mbedtls_net_context *sock_fd, unsigned
char *buf, size_t len )
{
    int ret;
//    size_t i, idx = 0;

//    printf("\n%s", buf);
    if( len && ( ret = mbedtls_net_send( sock_fd, buf, len ) ) <= 0 )
    {
        ERROR( " failed  ! mbedtls_ssl_write returned %d\n\n", ret );
        return -1;
    }
 
 return 0;
}


#endif

void my_smtp_result_fn(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
{
   printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
         smtp_result, srv_err, err);
}

char arBodyHead[2048] = {0};
unsigned char arEmailContent[1024] = {0};

int  send_email_task( const BC_SendEmailInfo_St *pstSendEmailInfo)
{
 if(NULL == pstSendEmailInfo)
 {
  ERROR("pstSendEmailInfo is NULL \n");
  return BC_FAILURE;
 }
  
#if 0

//   int num_count_flag = 0 ;
   unsigned int context_len = 0;
   int ret,recv_flag = N0_EMAIL_RECIVER;
   unsigned int len = 0,u32MallcAchmentLen = 0;
   mbedtls_net_context server_fd;
   unsigned char buf[1024];
  

   //char hostname[32];
//   const char *pers = "ssl_mail_client";
//   size_t n;
   EmailSendCfg_St  EmailSendCfg_St;
//   mbedtls_entropy_context entropy;
   mbedtls_ctr_drbg_context ctr_drbg;
   mbedtls_ssl_context ssl;
   mbedtls_ssl_config conf;
   mbedtls_x509_crt cacert;
   mbedtls_x509_crt clicert;
   mbedtls_pk_context pkey;
//   unsigned int u32MaxLen = 0;
//   unsigned int u32SendLen = 0;
   unsigned int u32TotalLen = 0;
   unsigned int u32AttachmentLen = 0;
   char arMailRecvAddr[512] = {0};
   char *pMailRecvAddr =  arMailRecvAddr;
   char *pMallocEmail = NULL;
   char *pSendEmailBody = NULL; 
   char *pTemporaryBody = NULL;
   char *pAttachment_addr  = NULL;
   char arBodyEnd[] = "----PartBoundary12345678----\r\n";  
  
   memset(arMailRecvAddr,0,sizeof(arMailRecvAddr));
  
   mbedtls_net_init( &server_fd );
   mbedtls_ssl_init( &ssl );
   mbedtls_ssl_config_init( &conf );
   memset( &buf, 0, sizeof( buf ) );
   mbedtls_x509_crt_init( &cacert );
   mbedtls_x509_crt_init( &clicert );
   mbedtls_pk_init( &pkey );
   mbedtls_ctr_drbg_init( &ctr_drbg );
  
    /* def email cfg*/
    EmailSendCfg_St.debug_level     = DFL_DEBUG_LEVEL;
    EmailSendCfg_St.authentication    = DFL_AUTHENTICATION;
    EmailSendCfg_St.ca_file      = (char *)DFL_CA_FILE;
    EmailSendCfg_St.crt_file      = (char *)DFL_CRT_FILE;
    EmailSendCfg_St.key_file      = (char *)DFL_KEY_FILE;
    EmailSendCfg_St.force_ciphersuite[0]= DFL_FORCE_CIPHER;
   
    /*usr email cfg*/
    EmailSendCfg_St.server_name  = (char *)pstSendEmailInfo->smtp;
    EmailSendCfg_St.server_port  = pstSendEmailInfo->smtpport;
    EmailSendCfg_St.user_name  = (char *)pstSendEmailInfo->sender;
    EmailSendCfg_St.user_pwd   = (char *)pstSendEmailInfo->pass;
    EmailSendCfg_St.mail_from  = (char *)pstSendEmailInfo->sender;
    EmailSendCfg_St.mail_to   = (char *)pstSendEmailInfo->recver[0]; //no use
    EmailSendCfg_St.mode    = MODE_SSL_TLS;         //no use
    EmailSendCfg_St.stEmailTransCfg.battachment  = pstSendEmailInfo->battachment;
    EmailSendCfg_St.stEmailTransCfg.bssl    = pstSendEmailInfo->bssl;
    EmailSendCfg_St.stEmailTransCfg.subject   = pstSendEmailInfo->subject;
    EmailSendCfg_St.stEmailTransCfg.content   = pstSendEmailInfo->content;
    EmailSendCfg_St.stEmailTransCfg.attachment  = pstSendEmailInfo->attachment;
    EmailSendCfg_St.stEmailTransCfg.attachment_name = pstSendEmailInfo->attachment_name;
    EmailSendCfg_St.stEmailTransCfg.attachment_len = pstSendEmailInfo->attachment_len;
    memcpy(EmailSendCfg_St.stEmailTransCfg.recver,pstSendEmailInfo->recver,sizeof(pstSendEmailInfo->recver));
  
   //  ERROR("EmailSendCfg_St.stEmailTransCfg.attachment %p ,str: %s ,len: %d\n",EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment_len);

   BC_ERR("====000=====\n");


    for(int i=0;i<MAX_EMAIL_RECERVER;i++)
    {
     if('\0' != EmailSendCfg_St.stEmailTransCfg.recver[i][0])
     {
      if(N0_EMAIL_RECIVER == recv_flag)
      {
       recv_flag = EMAIL_RECIVER_EXIST;
       sprintf(pMailRecvAddr,"<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
      }
      else
      {
       pMailRecvAddr += strlen(pMailRecvAddr);
       sprintf(pMailRecvAddr,",<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
      }
     }
    }

    if(N0_EMAIL_RECIVER == recv_flag)
    {
//     ERROR( " failed NO Email receiver,please set Email receiver %d\n\n", ret );
//     ret = BC_FAILURE;
    }

    //邮件正文进行base64编码
    context_len = strlen(EmailSendCfg_St.stEmailTransCfg.content)+1;
    if(context_len < sizeof(arEmailContent))
    {
     ret = mbedtls_base64_encode( (unsigned char *)arEmailContent, context_len*2+MinBase64Encode_len, &len, (const unsigned char *)EmailSendCfg_St.stEmailTransCfg.content, context_len);
     if(BC_SUCCESS != ret)
     {
      ERROR("fail mbedtls_base64_encode %d \n",ret);
      ret = BC_FAILURE;
//      goto err;
     }
    }
    else
    {
     ERROR("fail stEmailTransCfg.content is to long \n");
     ret = BC_FAILURE;
//     goto err;
    }

    if(EmailSendCfg_St.stEmailTransCfg.battachment)
    {
     if((NULL == EmailSendCfg_St.stEmailTransCfg.attachment)||(EmailSendCfg_St.stEmailTransCfg.attachment_len <= 0))
     {
      ERROR( " failed: stEmailTransCfg.attachment is NULL or attachment_len is 0 \n" );
      ret = BC_FAILURE;
//      goto err;
     }

     u32AttachmentLen  = EmailSendCfg_St.stEmailTransCfg.attachment_len;
     pAttachment_addr  = EmailSendCfg_St.stEmailTransCfg.attachment;

     len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),

    "From: \"%s\"<%s>\r\n"
    "To:%s\r\n" 
    "Subject:%s\r\n"
    "MIME-Version:1.0\r\n" 
    "Content-Type: multipart/mixed;\r\n"
    "  boundary=--PartBoundary12345678--\r\n"
    "\r\n"
    "This is a multi-part message in MIME format.\r\n"
    "\r\n" 
    "----PartBoundary12345678--\r\n" 
    "Content-Type: text/plain;\r\n"
    " charset=utf-8\r\n"
    "Content-Transfer-Encoding: base64\r\n"
    "\r\n"
    "%s\r\n\r\n"  //send txt content
    "\r\n"
    "----PartBoundary12345678--\r\n" 
    "Content-Type: application/octet-stream;\r\n"
    "  name=%s\r\n"
    "Content-Transfer-Encoding: base64\r\n" 
    "Content-Disposion:attachment;\r\n"
    "  filename=%s\r\n"
    "\r\n",
    EmailSendCfg_St.mail_from,EmailSendCfg_St.mail_from,arMailRecvAddr,\
    EmailSendCfg_St.stEmailTransCfg.subject,\
    arEmailContent,\
    EmailSendCfg_St.stEmailTransCfg.attachment_name,\
    EmailSendCfg_St.stEmailTransCfg.attachment_name

    );

     // MinBase64Encode_len防止传入的附件内容小于2字节,因分配的空间太小在bsae64en时出错,len为头信息长度
     u32MallcAchmentLen = u32AttachmentLen*2+len+strlen(arBodyEnd)+MinBase64Encode_len;
     pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
     if(NULL == pMallocEmail) 
     { 
      ERROR("malloc() faile \n"); 
      ret = BC_FAILURE;
//      goto err;
     } 
     memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
    
     pSendEmailBody = pMallocEmail;
     pTemporaryBody = pMallocEmail;
    
     len = sprintf(pTemporaryBody, arBodyHead); 

     pTemporaryBody +=  len; 
     u32TotalLen = len;
    
 //需要分段编码,一次编码完成超过1M则发送会失败
     char arOutBuf[256] = {0};
     while(u32AttachmentLen > 0) 
     { 
      if(u32AttachmentLen > ENCODE_LEN)
      {
       ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, ENCODE_LEN );
       if(BC_SUCCESS != ret)
       {
        ERROR("fail mbedtls_base64_encode %d \n",ret);
        free(pMallocEmail);
        return BC_FAILURE;
       }
      
       len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
       sprintf(pTemporaryBody, arOutBuf); 
       memset(arOutBuf, 0x0, 256); 
       pTemporaryBody += len; 
       u32TotalLen += len;

       pAttachment_addr += ENCODE_LEN;
       u32AttachmentLen   -= ENCODE_LEN;
      }
      else
      {
       ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, u32AttachmentLen );
       if(BC_SUCCESS != ret)
       {
        ERROR(" fail mbedtls_base64_encode %d \n",ret);
        free(pMallocEmail);
        return BC_FAILURE;
       }
       
       len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
       sprintf(pTemporaryBody, arOutBuf); 
       memset(arOutBuf, 0x0, 256); 
       pTemporaryBody += len; 
       u32TotalLen += len;
      
       u32AttachmentLen   -= ENCODE_LEN;
       break;
      }
     } 

     len = sprintf(pTemporaryBody, arBodyEnd);
     u32TotalLen += len;
    }
    else //no attachment
    {
     BC_ERR("====222=====\n");
    
       len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),
    "Content-Type: text/plain;\r\n"
    " charset=utf-8\r\n"
    "\r\n"
    "%s\r\n",
    "asdfasdgasdgasdgasdgasdgasg"\
     );
    
     u32MallcAchmentLen = len*2;
     pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
     if(NULL == pMallocEmail) 
     { 
      ERROR("malloc(): fail \n"); 
      ret = BC_FAILURE;
//      goto err;
     } 
     memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
    
     pSendEmailBody = pMallocEmail;
     u32TotalLen = sprintf(pSendEmailBody, arBodyHead); 
    }

 //send email
  
//   smtp_set_server_addr(EmailSendCfg_St.server_name);
// smtp_set_server_port(25);
//   smtp_set_auth(EmailSendCfg_St.user_name, EmailSendCfg_St.user_pwd);  

 smtp_set_server_addr("smtp.163.com");
  smtp_set_server_port(25);
 smtp_set_auth("baichuang111111@163.com", "As520213");  


   printf("sending....\n");

 
   smtp_send_mail("baichuang111111@163.com", "baichuang111111@163.com", "SMTP_server", arBodyHead, my_smtp_result_fn, NULL);

//   smtp_send_mail("baichuang111111@163.com", "baichuang111111@163.com", "SMTP_server", "The gm8136 sent e-mail to here pass the SMTP", my_smtp_result_fn, NULL);

   BC_ERR("====111=====\n");

 if(NULL != pMallocEmail)
 {
  free(pMallocEmail);
  pMallocEmail = NULL;
 }

 ERROR(" send email success \n");

 return 0;

#else
 int num_count_flag = 0 ;
   unsigned int context_len = 0;
   int ret,recv_flag = N0_EMAIL_RECIVER;
   unsigned int len = 0,u32MallcAchmentLen = 0;
   mbedtls_net_context server_fd;
   unsigned char buf[1024];
  
#if defined(MBEDTLS_BASE64_C)
    unsigned char base[1024];
#endif
   //char hostname[32];
//   const char *pers = "ssl_mail_client";
   size_t n;
   EmailSendCfg_St  EmailSendCfg_St;
//   mbedtls_entropy_context entropy;
   mbedtls_ctr_drbg_context ctr_drbg;
   mbedtls_ssl_context ssl;
   mbedtls_ssl_config conf;
   mbedtls_x509_crt cacert;
   mbedtls_x509_crt clicert;
   mbedtls_pk_context pkey;
   unsigned int u32MaxLen = 0;
   unsigned int u32SendLen = 0;
   unsigned int u32TotalLen = 0;
   unsigned int u32AttachmentLen = 0;
   char arMailRecvAddr[512] = {0};
   char *pMailRecvAddr =  arMailRecvAddr;
   char *pMallocEmail = NULL;
   char *pSendEmailBody = NULL; 
   char *pTemporaryBody = NULL;
   char *pAttachment_addr  = NULL;
   char arBodyEnd[] = "----PartBoundary12345678----\r\n";  
  
   memset(arMailRecvAddr,0,sizeof(arMailRecvAddr));
  
   mbedtls_net_init( &server_fd );
   mbedtls_ssl_init( &ssl );
   mbedtls_ssl_config_init( &conf );
   memset( &buf, 0, sizeof( buf ) );
   mbedtls_x509_crt_init( &cacert );
   mbedtls_x509_crt_init( &clicert );
   mbedtls_pk_init( &pkey );
   mbedtls_ctr_drbg_init( &ctr_drbg );
  
   /* def email cfg*/
   EmailSendCfg_St.debug_level     = DFL_DEBUG_LEVEL;
   EmailSendCfg_St.authentication    = DFL_AUTHENTICATION;
   EmailSendCfg_St.ca_file      = (char *)DFL_CA_FILE;
   EmailSendCfg_St.crt_file      = (char *)DFL_CRT_FILE;
   EmailSendCfg_St.key_file      = (char *)DFL_KEY_FILE;
   EmailSendCfg_St.force_ciphersuite[0]= DFL_FORCE_CIPHER;
  
   /*usr email cfg*/
   EmailSendCfg_St.server_name  = (char *)pstSendEmailInfo->smtp;
   EmailSendCfg_St.server_port  = pstSendEmailInfo->smtpport;
   EmailSendCfg_St.user_name  = (char *)pstSendEmailInfo->sender;
   EmailSendCfg_St.user_pwd   = (char *)pstSendEmailInfo->pass;
   EmailSendCfg_St.mail_from  = (char *)pstSendEmailInfo->sender;
   EmailSendCfg_St.mail_to   = (char *)pstSendEmailInfo->recver[0]; //no use
   EmailSendCfg_St.mode    = MODE_SSL_TLS;         //no use
   EmailSendCfg_St.stEmailTransCfg.battachment  = pstSendEmailInfo->battachment;
   EmailSendCfg_St.stEmailTransCfg.bssl    = pstSendEmailInfo->bssl;
   EmailSendCfg_St.stEmailTransCfg.subject   = pstSendEmailInfo->subject;
   EmailSendCfg_St.stEmailTransCfg.content   = pstSendEmailInfo->content;
   EmailSendCfg_St.stEmailTransCfg.attachment  = pstSendEmailInfo->attachment;
   EmailSendCfg_St.stEmailTransCfg.attachment_name = pstSendEmailInfo->attachment_name;
   EmailSendCfg_St.stEmailTransCfg.attachment_len = pstSendEmailInfo->attachment_len;
   memcpy(EmailSendCfg_St.stEmailTransCfg.recver,pstSendEmailInfo->recver,sizeof(pstSendEmailInfo->recver));

   ERROR("EmailSendCfg_St.stEmailTransCfg.attachment %p ,str: %s ,len: %d\n",EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment_len);


   if( ( ret = mbedtls_net_connect( &server_fd, EmailSendCfg_St.server_name,
                             EmailSendCfg_St.server_port, 0 ) ) != BC_SUCCESS )                           
   {
       ERROR( " failed ! mbedtls_net_connect returned %d\n\n", ret );
    goto err;
   }else
      printf( " ok\n" );
     

   len = sprintf( (char *) buf, "HELO GUEST\r\n" );
   ret = write_and_get_response( &server_fd, buf, len );
   if( ret < 200 || ret > 299 )
   {
  ERROR( " failed ! server responded with %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
   }

   if( EmailSendCfg_St.authentication )
   {   
    len = sprintf( (char *) buf, "AUTH LOGIN\r\n" );
    ret = write_and_get_response( &server_fd, buf, len );
    if( ret < 200 || ret > 399 )
    {
        ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
    }
 
       ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) EmailSendCfg_St.user_name,\
     strlen( EmailSendCfg_St.user_name ) );
       if( ret != BC_SUCCESS )
    {
            ERROR( " failed  ! mbedtls_base64_encode returned %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
       }
       len = sprintf( (char *) buf, "%s\r\n", base );
       ret = write_and_get_response( &server_fd, buf, len );
       if( ret < 300 || ret > 399 )
       {
           ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
   
       ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) EmailSendCfg_St.user_pwd,\
     strlen( EmailSendCfg_St.user_pwd ) );
       if( ret != BC_SUCCESS )
    {
           ERROR( " failed  ! mbedtls_base64_encode returned %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
       len = sprintf( (char *) buf, "%s\r\n", base );
       ret = write_and_get_response( &server_fd, buf, len );
       if( ret < 200 || ret > 399 )
       {
           ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
 } 

   len = sprintf( (char *) buf, "MAIL FROM:<%s>\r\n", EmailSendCfg_St.mail_from );
   ret = write_and_get_response( &server_fd, buf, len );
   if( ret < 200 || ret > 299 )
   {
        ERROR( " failed  ! server responded with %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
   }
  
 for(int i=0;i<MAX_EMAIL_RECERVER;i++)
 {
  if('\0' != EmailSendCfg_St.stEmailTransCfg.recver[i][0])
  {
   len = sprintf( (char *) buf, "RCPT TO:<%s>\r\n", EmailSendCfg_St.stEmailTransCfg.recver[i] );
   ret = write_and_get_response( &server_fd, buf, len );
   if( ret < 200 || ret > 299 )
   {
     ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
   }
   
   if(N0_EMAIL_RECIVER == recv_flag)
   {
    recv_flag = EMAIL_RECIVER_EXIST;
    sprintf(pMailRecvAddr,"<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
   }
   else
   {
    pMailRecvAddr += strlen(pMailRecvAddr);
    sprintf(pMailRecvAddr,",<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
   }
  }
 }

 if(N0_EMAIL_RECIVER == recv_flag)
 {
  ERROR( " failed  NO Email receiver,please set Email receiver %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
 }

 len = sprintf( (char *) buf, "DATA\r\n" );
 ret = write_and_get_response( &server_fd, buf, len );
 if( ret < 300 || ret > 399 )
 {
     ERROR( " failed  ! server responded with %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
 }

 //邮件正文进行base64编码
 context_len = strlen(EmailSendCfg_St.stEmailTransCfg.content)+1;
 if(context_len < sizeof(arEmailContent))
 {
  ret = mbedtls_base64_encode( (unsigned char *)arEmailContent, context_len*2+MinBase64Encode_len, &len, (const unsigned char *)EmailSendCfg_St.stEmailTransCfg.content, context_len);
  if(BC_SUCCESS != ret)
  {
   ERROR("fail mbedtls_base64_encode %d \n",ret);
   ret = BC_FAILURE;
   goto err;
  }
 }
 else
 {
  ERROR("fail stEmailTransCfg.content is to long \n");
  ret = BC_FAILURE;
  goto err;
 }

 if(EmailSendCfg_St.stEmailTransCfg.battachment)
 {
  if((NULL == EmailSendCfg_St.stEmailTransCfg.attachment)||(EmailSendCfg_St.stEmailTransCfg.attachment_len <= 0))
  {
   ERROR( " failed: stEmailTransCfg.attachment is NULL or attachment_len is 0 \n" );
   ret = BC_FAILURE;
   goto err;
  }

  u32AttachmentLen  = EmailSendCfg_St.stEmailTransCfg.attachment_len;
  pAttachment_addr  = EmailSendCfg_St.stEmailTransCfg.attachment;

  len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),

//邮件正文以base64编码方式发送
#if 0
     "From: \"%s\"<%s>\r\n"
     "To: \"%s\"<%s>\r\n"
     "Subject:%s\r\n"
     "MIME-Version:1.0\r\n" 
     "Content-Type: multipart/mixed; boundary=--PartBoundary12345678--\r\n" 
     "Content-Transfer-Encoding:8Bit\r\n"  
     "\r\n" 
     "----PartBoundary12345678--\r\n" 
     "Content-Type: text/plain; charset=ISO-8859-1\r\n"
     "\r\n"
     "%s\r\n"  //send txt content
     "\r\n\r\n"
     "----PartBoundary12345678--\r\n" 
     "Content-Type: application/octet-stream; name=%s\r\n"
     "Content-Disposion:attachment; filename=%s\r\n"
     "Content-Transfer-Encoding: base64\r\n" 
     "\r\n",
      EmailSendCfg_St.mail_from,EmailSendCfg_St.mail_from,arMailRecvAddr,arMailRecvAddr,\
      EmailSendCfg_St.stEmailTransCfg.subject,\
      EmailSendCfg_St.stEmailTransCfg.content,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name

#else 
       "From: \"%s\"<%s>\r\n"
      "To:%s\r\n" 
      "Subject:%s\r\n"
      "MIME-Version:1.0\r\n" 
      "Content-Type: multipart/mixed;\r\n"
      "    boundary=--PartBoundary12345678--\r\n"
      "\r\n" 
      "This is a multi-part message in MIME format.\r\n"
      "\r\n" 
      "----PartBoundary12345678--\r\n" 
      "Content-Type: text/plain;\r\n"
      "  charset=utf-8\r\n"
      "Content-Transfer-Encoding: base64\r\n"
      "\r\n"
      "%s\r\n\r\n"  //send txt content
      "\r\n"
      "----PartBoundary12345678--\r\n" 
      "Content-Type: application/octet-stream;\r\n"
      "    name=%s\r\n"
      "Content-Transfer-Encoding: base64\r\n" 
      "Content-Disposion:attachment;\r\n"
      "    filename=%s\r\n"
      "\r\n",
      EmailSendCfg_St.mail_from,EmailSendCfg_St.mail_from,arMailRecvAddr,\
      EmailSendCfg_St.stEmailTransCfg.subject,\
      arEmailContent,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name
#endif     
      );

  // MinBase64Encode_len防止传入的附件内容小于2字节,因分配的空间太小在bsae64en时出错,len为头信息长度
  u32MallcAchmentLen = u32AttachmentLen*2+len+strlen(arBodyEnd)+MinBase64Encode_len;
  pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
     if(NULL == pMallocEmail) 
     { 
         ERROR("malloc() faile \n"); 
   ret = BC_FAILURE;
   goto err;
     } 
     memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
  
  pSendEmailBody = pMallocEmail;
  pTemporaryBody = pMallocEmail;
  
   len = sprintf(pTemporaryBody, arBodyHead); 

     pTemporaryBody +=  len; 
  u32TotalLen = len;
  
//需要分段编码,一次编码完成超过1M则发送会失败
#if 1 //分段编码    
  char arOutBuf[256] = {0};

  while(u32AttachmentLen > 0) 
     { 
      if(u32AttachmentLen > ENCODE_LEN)
      {
    ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, ENCODE_LEN );
    if(BC_SUCCESS != ret)
    {
     ERROR("fail mbedtls_base64_encode %d \n",ret);
     free(pMallocEmail);
     return BC_FAILURE;
    }
    
    len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
    sprintf(pTemporaryBody, arOutBuf); 
    memset(arOutBuf, 0x0, 256); 
    pTemporaryBody += len; 
    u32TotalLen += len;

    pAttachment_addr += ENCODE_LEN;
    u32AttachmentLen   -= ENCODE_LEN;
      }
   else
   {
    ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, u32AttachmentLen );
    if(BC_SUCCESS != ret)
    {
     ERROR(" fail mbedtls_base64_encode %d \n",ret); 
     free(pMallocEmail);
     return BC_FAILURE;
    }
     
    len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
    sprintf(pTemporaryBody, arOutBuf); 
    memset(arOutBuf, 0x0, 256); 
    pTemporaryBody += len; 
    u32TotalLen += len;
    
    u32AttachmentLen   -= ENCODE_LEN;
    break;
   }
     } 
#else   // 一次完成编码
  ret = mbedtls_base64_encode( (unsigned char *)pTemporaryBody, u32AttachmentLen*2+MinBase64Encode_len, &len, (const unsigned char *)pAttachment_addr, u32AttachmentLen );
  if(BC_SUCCESS != ret)
  {
   ERROR("fail mbedtls_base64_encode %d \n",ret);
   free(pMallocEmail);
   goto err;
  }
  
  len = sprintf(pTemporaryBody, "%s\r\n\r\n", pTemporaryBody); 
//  ERROR("u32TotalLen %d ,len = %d ,pTemporaryBody %d \n",u32TotalLen,len,strlen(pTemporaryBody));
  pTemporaryBody += len;
  u32TotalLen += len;
#endif
     len = sprintf(pTemporaryBody, arBodyEnd);
  u32TotalLen += len;
 }
 else //no attachment
 {
  len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),
     "From:%s\r\n" 
     "To:%s\r\n" 
     "MIME-Version:1.0\r\n" 
     "Subject:%s\r\n"
     "Content-Type: text/plain;\r\n"
     " charset=utf-8\r\n"
     "Content-Transfer-Encoding: base64\r\n"
     "\r\n"
     "%s\r\n", //sent txt content
     EmailSendCfg_St.mail_from, arMailRecvAddr,\
     EmailSendCfg_St.stEmailTransCfg.subject,\
     arEmailContent
   );
  
  u32MallcAchmentLen = len*2;
  pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
  if(NULL == pMallocEmail) 
  { 
   ERROR("malloc(): fail \n"); 
   ret = BC_FAILURE;
   goto err;
  } 
  memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
  
  pSendEmailBody = pMallocEmail;
  u32TotalLen = sprintf(pSendEmailBody, arBodyHead); 
 }

//send email
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 u32MaxLen = mbedtls_ssl_get_max_frag_len( &ssl );
 u32SendLen = u32TotalLen;
  
 while(u32SendLen > 0)
 {
  if(u32SendLen > u32MaxLen)
  {
   ret = write_data( &server_fd, (unsigned char*)pSendEmailBody, u32MaxLen );
   if( BC_SUCCESS != ret)
   {
    ERROR( " failed  ! write_ssl_data %d\n\n", ret );
    free(pMallocEmail);
    goto err;
   }
   
   pSendEmailBody += u32MaxLen;
   u32SendLen     -= u32MaxLen;
  }
  else
  {
   ret = write_data( &server_fd, (unsigned char*)pSendEmailBody, u32SendLen );    
   if( BC_SUCCESS != ret)
   {
    ERROR( " failed  ! write_ssl_data %d\n\n", ret );
    free(pMallocEmail);
    goto err;
   }
   u32SendLen -= u32MaxLen;
   break;
  }
  num_count_flag++;
 }

#else
   ret = write_data( &server_fd, (unsigned char*)pSendEmailBody, u32SendLen );
   if( BC_SUCCESS != ret)
   {
  ERROR( " failed ! write_ssl_data %d\n\n", ret );
  free(pMallocEmail);
  goto err;
   }
#endif
  
   len = sprintf( (char *) buf, "\r\n.\r\n");
   ret = write_and_get_response( &server_fd, buf, len );
   if( ret < 200 || ret > 299 )
   {
        ERROR( " failed  ! server responded with %d\n\n", ret );
  free(pMallocEmail);
  ret = BC_FAILURE;
  goto err;
   }

   len = sprintf( (char *) buf, "QUIT\r\n");
   ret = write_and_get_response( &server_fd, buf, len );
   if( ret < 200 || ret > 299 )
   {
        ERROR( " failed  ! server responded with %d\n\n", ret );
  free(pMallocEmail);
  ret = BC_FAILURE;
  goto err;
   }

   if(NULL != pMallocEmail)
   {
    free(pMallocEmail);
    pMallocEmail = NULL;
   }
  
   ERROR(" send email success \n"); 

err:
  
   mbedtls_net_free( &server_fd );

   return ret;

#endif


#if 0

   int num_count_flag = 0 ;
   unsigned int context_len = 0;
   int ret,s32Ret,recv_flag = N0_EMAIL_RECIVER;
   unsigned int len = 0,u32MallcAchmentLen = 0;
   mbedtls_net_context server_fd;
   unsigned char buf[1024];
  
#if defined(MBEDTLS_BASE64_C)
    unsigned char base[1024];
#endif
   //char hostname[32];
   const char *pers = "ssl_mail_client";
   size_t n;
   EmailSendCfg_St  EmailSendCfg_St;
   mbedtls_entropy_context entropy;
   mbedtls_ctr_drbg_context ctr_drbg;
   mbedtls_ssl_context ssl;
   mbedtls_ssl_config conf;
   mbedtls_x509_crt cacert;
   mbedtls_x509_crt clicert;
   mbedtls_pk_context pkey;
   unsigned int u32MaxLen = 0;
   unsigned int u32SendLen = 0;
   unsigned int u32TotalLen = 0;
   unsigned int u32AttachmentLen = 0;
   char arMailRecvAddr[512] = {0};
   char *pMailRecvAddr =  arMailRecvAddr;
   char *pMallocEmail = NULL;
   char *pSendEmailBody = NULL; 
   char *pTemporaryBody = NULL;
   char *pAttachment_addr  = NULL;
   char arBodyEnd[] = "----PartBoundary12345678----\r\n";  
  
   memset(arMailRecvAddr,0,sizeof(arMailRecvAddr));
  
   mbedtls_net_init( &server_fd );
   mbedtls_ssl_init( &ssl );
   mbedtls_ssl_config_init( &conf );
   memset( &buf, 0, sizeof( buf ) );
   mbedtls_x509_crt_init( &cacert );
   mbedtls_x509_crt_init( &clicert );
   mbedtls_pk_init( &pkey );
   mbedtls_ctr_drbg_init( &ctr_drbg );
  
    /* def email cfg*/
    EmailSendCfg_St.debug_level     = DFL_DEBUG_LEVEL;
    EmailSendCfg_St.authentication    = DFL_AUTHENTICATION;
    EmailSendCfg_St.ca_file      = (char *)DFL_CA_FILE;
    EmailSendCfg_St.crt_file      = (char *)DFL_CRT_FILE;
    EmailSendCfg_St.key_file      = (char *)DFL_KEY_FILE;
    EmailSendCfg_St.force_ciphersuite[0]= DFL_FORCE_CIPHER;
   
    /*usr email cfg*/
    EmailSendCfg_St.server_name  = (char *)pstSendEmailInfo->smtp;
    EmailSendCfg_St.server_port  = pstSendEmailInfo->smtpport;
    EmailSendCfg_St.user_name  = (char *)pstSendEmailInfo->sender;
    EmailSendCfg_St.user_pwd   = (char *)pstSendEmailInfo->pass;
    EmailSendCfg_St.mail_from  = (char *)pstSendEmailInfo->sender;
    EmailSendCfg_St.mail_to   = (char *)pstSendEmailInfo->recver[0]; //no use
    EmailSendCfg_St.mode    = MODE_SSL_TLS;         //no use
    EmailSendCfg_St.stEmailTransCfg.battachment  = pstSendEmailInfo->battachment;
    EmailSendCfg_St.stEmailTransCfg.bssl    = pstSendEmailInfo->bssl;
    EmailSendCfg_St.stEmailTransCfg.subject   = pstSendEmailInfo->subject;
    EmailSendCfg_St.stEmailTransCfg.content   = pstSendEmailInfo->content;
    EmailSendCfg_St.stEmailTransCfg.attachment  = pstSendEmailInfo->attachment;
    EmailSendCfg_St.stEmailTransCfg.attachment_name = pstSendEmailInfo->attachment_name;
    EmailSendCfg_St.stEmailTransCfg.attachment_len = pstSendEmailInfo->attachment_len;
    memcpy(EmailSendCfg_St.stEmailTransCfg.recver,pstSendEmailInfo->recver,sizeof(pstSendEmailInfo->recver));
  
    ERROR("EmailSendCfg_St.stEmailTransCfg.attachment %p ,str: %s ,len: %d\n",EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment,EmailSendCfg_St.stEmailTransCfg.attachment_len);

   /*
     * 0. Initialize the RNG and the session data
   */
  
   mbedtls_entropy_init( &entropy );
   if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                         (const unsigned char *) pers,strlen( pers ) ) ) != BC_SUCCESS )
   {
       ERROR( " failed  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
    goto err;
   }


#if defined(MBEDTLS_FS_IO)
   if( strlen( EmailSendCfg_St.ca_file ) )
       ret = mbedtls_x509_crt_parse_file( &cacert, EmailSendCfg_St.ca_file );
   else
#endif
#if defined(MBEDTLS_CERTS_C)
   ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *)
                 mbedtls_test_cas_pem,mbedtls_test_cas_pem_len );
#else
   {
       ret = 1;
       printf("MBEDTLS_CERTS_C not defined.");
   }
#endif
   if( ret < 0 )
   {
       ERROR( " failed  !  mbedtls_x509_crt_parse returned %d\n\n", ret );
    goto err;
   }


#if defined(MBEDTLS_FS_IO)
   if( strlen( EmailSendCfg_St.crt_file ) )
       ret = mbedtls_x509_crt_parse_file( &clicert, EmailSendCfg_St.crt_file );
   else
#endif
#if defined(MBEDTLS_CERTS_C)
       ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *)
        mbedtls_test_cli_crt, mbedtls_test_cli_crt_len );
#else
   {
       ret = BC_FAILURE;
       ERROR("MBEDTLS_CERTS_C not defined.");
   }
#endif
   if( ret != BC_SUCCESS )
   {
       printf( " failed  !  mbedtls_x509_crt_parse returned %d\n\n", ret );
    goto err;
   }
  
#if defined(MBEDTLS_FS_IO)
   if( strlen( EmailSendCfg_St.key_file ) )
        ret = mbedtls_pk_parse_keyfile( &pkey, EmailSendCfg_St.key_file, "" );
   else
#endif

#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_PEM_PARSE_C)
       ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *)mbedtls_test_cli_key,
                                           mbedtls_test_cli_key_len, NULL, 0 );
#else
   {
        ret = BC_FAILURE;
        printf("MBEDTLS_CERTS_C or MBEDTLS_PEM_PARSE_C not defined.");
   }
#endif
   if( ret != BC_SUCCESS )
   {
       printf( " failed  !  mbedtls_pk_parse_key returned %d\n\n", ret );
    goto err;
   }

   if( ( ret = mbedtls_net_connect( &server_fd, EmailSendCfg_St.server_name,
                             EmailSendCfg_St.server_port, 0 ) ) != BC_SUCCESS )                           
   {
       ERROR( " failed ! mbedtls_net_connect returned %d\n\n", ret );
    goto err;
   }else
      printf( " ok\n" );
     
   /*
    * 3. Setup stuff
   */

   if( ( ret = mbedtls_ssl_config_defaults( &conf,
                    MBEDTLS_SSL_IS_CLIENT,
                    MBEDTLS_SSL_TRANSPORT_STREAM,
                    MBEDTLS_SSL_PRESET_DEFAULT ) ) != BC_SUCCESS )
   {
        ERROR( " failed  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
  goto err;
   }

   /* OPTIONAL is not stEmailCfgimal for security,
    * but makes interop easier in this simplified example */
   mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );

   mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
   //mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );

   if( EmailSendCfg_St.force_ciphersuite[0] != DFL_FORCE_CIPHER )
       mbedtls_ssl_conf_ciphersuites( &conf, EmailSendCfg_St.force_ciphersuite );

   mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
   if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != BC_SUCCESS )
   {
       ERROR( " failed  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
    goto err;
   }
  
   if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != BC_SUCCESS )
   {
       ERROR( " failed  ! mbedtls_ssl_setup returned %d\n\n", ret );
    goto err;
   }

   if( ( ret = mbedtls_ssl_set_hostname( &ssl, EmailSendCfg_St.server_name ) ) != BC_SUCCESS )
   {
       ERROR( " failed  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
    goto err;
   }

   mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );

 BC_ERR("EmailSendCfg_St.server_port %d ,stEmailTransCfg.bssl %d \n",EmailSendCfg_St.server_port,EmailSendCfg_St.stEmailTransCfg.bssl);
 //MODE_SSL_TLS
 if(EmailSendCfg_St.stEmailTransCfg.bssl)
 {
//  if(465 != EmailSendCfg_St.server_port)
//  {
//      ERROR(" failed ! server_port is  %d ,ssl is %d,please set port = 465 \n", EmailSendCfg_St.server_port,EmailSendCfg_St.stEmailTransCfg.bssl );
//   ret = BC_FAILURE;
//   goto err;
//  }

  if( do_handshake( &ssl ) != BC_SUCCESS )
  {
      ERROR( " handshake failed" );
   ret = BC_FAILURE;
   goto err;
  }

  ret = write_ssl_and_get_response( &ssl, buf, 0 );
  if( ret < 200 || ret > 299 )
  {
      ERROR( " failed  ! server responded with %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
  }
  
  //gethostname( hostname, 32 );
  len = sprintf( (char *) buf, "EHLO GUEST\r\n" );
  ret = write_ssl_and_get_response( &ssl, buf, len );
  if( ret < 200 || ret > 299 )
  {
      ERROR( " failed  ! server responded with %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
  }
 }
 else
 {
//  if(25 != EmailSendCfg_St.server_port)
//  {
//      ERROR(" failed  ! server_port is  %d ,ssl is %d, please set port = 25\n", EmailSendCfg_St.server_port,EmailSendCfg_St.stEmailTransCfg.bssl );
//   ret = BC_FAILURE;
//   goto err;
//  }

  ret = write_and_get_response( &server_fd, buf, 0 );
  if( ret < 200 || ret > 299 )
  {
   ERROR( " failed  ! server responded with %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
  }
  
  //gethostname( hostname, 32 );
  len = sprintf( (char *) buf, "EHLO GUEST\r\n" );
  ret = write_and_get_response( &server_fd, buf, len );
  if( ret < 200 || ret > 299 )
  {
    ERROR( " failed ! server responded with %d\n\n", ret );
    ret = BC_FAILURE;
    goto err;
  }

  len = sprintf( (char *) buf, "STARTTLS\r\n" );
  ret = write_and_get_response( &server_fd, buf, len );
  if( ret < 200 || ret > 299 )
  {
      ERROR( " failed ! server responded with %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
  }

  if( do_handshake( &ssl ) != BC_SUCCESS )
  {
      ERROR( " handshake failed" );
   ret = BC_FAILURE;
   goto err;
  }
 }
  
#if defined(MBEDTLS_BASE64_C)
   if( EmailSendCfg_St.authentication )
   {   
//    printf( "  > Write AUTH LOGIN to server:" );

    len = sprintf( (char *) buf, "AUTH LOGIN\r\n" );
    ret = write_ssl_and_get_response( &ssl, buf, len );
    if( ret < 200 || ret > 399 )
    {
        ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
    }
 
//    printf(" ok\n" );
//    printf( "  > Write username to server: %s", EmailSendCfg_St.user_name );

       ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) EmailSendCfg_St.user_name,\
     strlen( EmailSendCfg_St.user_name ) );
       if( ret != BC_SUCCESS )
    {
            ERROR( " failed  ! mbedtls_base64_encode returned %d\n\n", ret );
   ret = BC_FAILURE;
   goto err;
       }
       len = sprintf( (char *) buf, "%s\r\n", base );
       ret = write_ssl_and_get_response( &ssl, buf, len );
       if( ret < 300 || ret > 399 )
       {
           ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
   
       ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) EmailSendCfg_St.user_pwd,\
     strlen( EmailSendCfg_St.user_pwd ) );
       if( ret != BC_SUCCESS )
    {
           ERROR( " failed  ! mbedtls_base64_encode returned %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
       len = sprintf( (char *) buf, "%s\r\n", base );
       ret = write_ssl_and_get_response( &ssl, buf, len );
       if( ret < 200 || ret > 399 )
       {
           ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
       }
 } 
#endif

   len = sprintf( (char *) buf, "MAIL FROM:<%s>\r\n", EmailSendCfg_St.mail_from );
   ret = write_ssl_and_get_response( &ssl, buf, len );
   if( ret < 200 || ret > 299 )
   {
        ERROR( " failed  ! server responded with %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
   }
  
 for(int i=0;i<MAX_EMAIL_RECERVER;i++)
 {
  if('\0' != EmailSendCfg_St.stEmailTransCfg.recver[i][0])
  {
   len = sprintf( (char *) buf, "RCPT TO:<%s>\r\n", EmailSendCfg_St.stEmailTransCfg.recver[i] );
   ret = write_ssl_and_get_response( &ssl, buf, len );
   if( ret < 200 || ret > 299 )
   {
     ERROR( " failed  ! server responded with %d\n\n", ret );
     ret = BC_FAILURE;
     goto err;
   }
   
   if(N0_EMAIL_RECIVER == recv_flag)
   {
    recv_flag = EMAIL_RECIVER_EXIST;
    sprintf(pMailRecvAddr,"<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
   }
   else
   {
    pMailRecvAddr += strlen(pMailRecvAddr);
    sprintf(pMailRecvAddr,",<%s>",EmailSendCfg_St.stEmailTransCfg.recver[i]);
   }
  }
 }

 if(N0_EMAIL_RECIVER == recv_flag)
 {
  ERROR( " failed  NO Email receiver,please set Email receiver %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
 }

 len = sprintf( (char *) buf, "DATA\r\n" );
 ret = write_ssl_and_get_response( &ssl, buf, len );
 if( ret < 300 || ret > 399 )
 {
     ERROR( " failed  ! server responded with %d\n\n", ret );
  ret = BC_FAILURE;
  goto err;
 }

 //邮件正文进行base64编码
 context_len = strlen(EmailSendCfg_St.stEmailTransCfg.content)+1;
 if(context_len < sizeof(arEmailContent))
 {
  ret = mbedtls_base64_encode( (unsigned char *)arEmailContent, context_len*2+MinBase64Encode_len, &len, (const unsigned char *)EmailSendCfg_St.stEmailTransCfg.content, context_len);
  if(BC_SUCCESS != ret)
  {
   ERROR("fail mbedtls_base64_encode %d \n",ret);
   ret = BC_FAILURE;
   goto err;
  }
 }
 else
 {
  ERROR("fail stEmailTransCfg.content is to long \n");
  ret = BC_FAILURE;
  goto err;
 }


 if(EmailSendCfg_St.stEmailTransCfg.battachment)
 {
  if((NULL == EmailSendCfg_St.stEmailTransCfg.attachment)||(EmailSendCfg_St.stEmailTransCfg.attachment_len <= 0))
  {
   ERROR( " failed: stEmailTransCfg.attachment is NULL or attachment_len is 0 \n" );
   ret = BC_FAILURE;
   goto err;
  }

  u32AttachmentLen  = EmailSendCfg_St.stEmailTransCfg.attachment_len;
  pAttachment_addr  = EmailSendCfg_St.stEmailTransCfg.attachment;

  len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),

//邮件正文以base64编码方式发送
#if 0
     "From: \"%s\"<%s>\r\n"
     "To: \"%s\"<%s>\r\n"
     "Subject:%s\r\n"
     "MIME-Version:1.0\r\n" 
     "Content-Type: multipart/mixed; boundary=--PartBoundary12345678--\r\n" 
     "Content-Transfer-Encoding:8Bit\r\n"  
     "\r\n" 
     "----PartBoundary12345678--\r\n" 
     "Content-Type: text/plain; charset=ISO-8859-1\r\n"
     "\r\n"
     "%s\r\n"  //send txt content
     "\r\n\r\n"
     "----PartBoundary12345678--\r\n" 
     "Content-Type: application/octet-stream; name=%s\r\n"
     "Content-Disposion:attachment; filename=%s\r\n"
     "Content-Transfer-Encoding: base64\r\n" 
     "\r\n",
      EmailSendCfg_St.mail_from,EmailSendCfg_St.mail_from,arMailRecvAddr,arMailRecvAddr,\
      EmailSendCfg_St.stEmailTransCfg.subject,\
      EmailSendCfg_St.stEmailTransCfg.content,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name

#else
       "From: \"%s\"<%s>\r\n"
      "To:%s\r\n" 
      "Subject:%s\r\n"
      "MIME-Version:1.0\r\n" 
      "Content-Type: multipart/mixed;\r\n"
      "    boundary=--PartBoundary12345678--\r\n"
      "\r\n" 
      "This is a multi-part message in MIME format.\r\n"
      "\r\n" 
      "----PartBoundary12345678--\r\n" 
      "Content-Type: text/plain;\r\n"
      "  charset=utf-8\r\n"
      "Content-Transfer-Encoding: base64\r\n"
      "\r\n"
      "%s\r\n\r\n"  //send txt content
      "\r\n"
      "----PartBoundary12345678--\r\n" 
      "Content-Type: application/octet-stream;\r\n"
      "    name=%s\r\n"
      "Content-Transfer-Encoding: base64\r\n" 
      "Content-Disposion:attachment;\r\n"
      "    filename=%s\r\n"
      "\r\n",
      EmailSendCfg_St.mail_from,EmailSendCfg_St.mail_from,arMailRecvAddr,\
      EmailSendCfg_St.stEmailTransCfg.subject,\
      arEmailContent,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name,\
      EmailSendCfg_St.stEmailTransCfg.attachment_name
#endif     
      );

  // MinBase64Encode_len防止传入的附件内容小于2字节,因分配的空间太小在bsae64en时出错,len为头信息长度
  u32MallcAchmentLen = u32AttachmentLen*2+len+strlen(arBodyEnd)+MinBase64Encode_len;
  pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
     if(NULL == pMallocEmail) 
     { 
         ERROR("malloc() faile \n"); 
   ret = BC_FAILURE;
   goto err;
     } 
     memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
  
  pSendEmailBody = pMallocEmail;
  pTemporaryBody = pMallocEmail;
  
   len = sprintf(pTemporaryBody, arBodyHead); 

     pTemporaryBody +=  len; 
  u32TotalLen = len;
  
//需要分段编码,一次编码完成超过1M则发送会失败
#if 1 //分段编码    
  char arOutBuf[256] = {0};

  while(u32AttachmentLen > 0) 
     { 
      if(u32AttachmentLen > ENCODE_LEN)
      {
    ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, ENCODE_LEN );
    if(BC_SUCCESS != ret)
    {
     ERROR("fail mbedtls_base64_encode %d \n",ret);
     free(pMallocEmail);
     return BC_FAILURE;
    }
    
    len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
    sprintf(pTemporaryBody, arOutBuf); 
    memset(arOutBuf, 0x0, 256); 
    pTemporaryBody += len; 
    u32TotalLen += len;

    pAttachment_addr += ENCODE_LEN;
    u32AttachmentLen   -= ENCODE_LEN;
      }
   else
   {
    ret = mbedtls_base64_encode( (unsigned char *)arOutBuf, sizeof( arOutBuf ), &len, (unsigned char *)pAttachment_addr, u32AttachmentLen );
    if(BC_SUCCESS != ret)
    {
     ERROR(" fail mbedtls_base64_encode %d \n",ret); 
     free(pMallocEmail);
     return BC_FAILURE;
    }
     
    len = sprintf(arOutBuf, "%s\r\n", arOutBuf); 
    sprintf(pTemporaryBody, arOutBuf); 
    memset(arOutBuf, 0x0, 256); 
    pTemporaryBody += len; 
    u32TotalLen += len;
    
    u32AttachmentLen   -= ENCODE_LEN;
    break;
   }
     } 
#else   // 一次完成编码
  ret = mbedtls_base64_encode( (unsigned char *)pTemporaryBody, u32AttachmentLen*2+MinBase64Encode_len, &len, (const unsigned char *)pAttachment_addr, u32AttachmentLen );
  if(BC_SUCCESS != ret)
  {
   ERROR("fail mbedtls_base64_encode %d \n",ret);
   free(pMallocEmail);
   goto err;
  }
  
  len = sprintf(pTemporaryBody, "%s\r\n\r\n", pTemporaryBody); 
//  ERROR("u32TotalLen %d ,len = %d ,pTemporaryBody %d \n",u32TotalLen,len,strlen(pTemporaryBody));
  pTemporaryBody += len;
  u32TotalLen += len;
#endif

     len = sprintf(pTemporaryBody, arBodyEnd);
  u32TotalLen += len;
 }
 else //no attachment
 {
  len = snprintf( (char *) arBodyHead, sizeof(arBodyHead),
     "From:%s\r\n" 
     "To:%s\r\n" 
     "MIME-Version:1.0\r\n" 
     "Subject:%s\r\n"
     "Content-Type: text/plain;\r\n"
     " charset=utf-8\r\n"
     "Content-Transfer-Encoding: base64\r\n"
     "\r\n"
     "%s\r\n", //sent txt content
     EmailSendCfg_St.mail_from, arMailRecvAddr,\
     EmailSendCfg_St.stEmailTransCfg.subject,\
     arEmailContent

   );
  
  u32MallcAchmentLen = len*2;
  pMallocEmail = (char *)malloc(u32MallcAchmentLen); 
  if(NULL == pMallocEmail) 
  { 
   ERROR("malloc(): fail \n"); 
   ret = BC_FAILURE;
   goto err;
  } 
  memset(pMallocEmail, 0x0, u32MallcAchmentLen); 
  
  pSendEmailBody = pMallocEmail;
  u32TotalLen = sprintf(pSendEmailBody, arBodyHead); 
 }

//send email
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 u32MaxLen = mbedtls_ssl_get_max_frag_len( &ssl );
 u32SendLen = u32TotalLen;
 
// BC_ERR("#####u32TotalLen  %d ##### \n",u32TotalLen);
 
 while(u32SendLen > 0)
 {
  if(u32SendLen > u32MaxLen)
  {
   ret = write_ssl_data( &ssl, (unsigned char*)pSendEmailBody, u32MaxLen );
   if( BC_SUCCESS != ret)
   {
    ERROR( " failed  ! write_ssl_data %d\n\n", ret );
//    BC_ERR("num_count is %d \n",num_count_flag);
    free(pMallocEmail);
    goto err;
   }
   
   pSendEmailBody += u32MaxLen;
   u32SendLen     -= u32MaxLen;
  }
  else
  {
   ret = write_ssl_data( &ssl, (unsigned char*)pSendEmailBody, u32SendLen );    
   if( BC_SUCCESS != ret)
   {
    ERROR( " failed  ! write_ssl_data %d\n\n", ret );
//    BC_ERR("num_count is %d \n",num_count_flag);
    free(pMallocEmail);
    goto err;
   }
   u32SendLen -= u32MaxLen;
   break;
  }
  num_count_flag++;
 }

#else
   ret = write_ssl_data( &ssl, (unsigned char*)pSendEmailBody, u32SendLen );
   if( BC_SUCCESS != ret)
   {
  ERROR( " failed ! write_ssl_data %d\n\n", ret );
  free(pMallocEmail);
  goto err;
   }
#endif
  
   len = sprintf( (char *) buf, "\r\n.\r\n");
   ret = write_ssl_and_get_response( &ssl, buf, len );
   if( ret < 200 || ret > 299 )
   {
        ERROR( " failed  ! server responded with %d\n\n", ret );
  free(pMallocEmail);
  ret = BC_FAILURE;
  goto err;
   }

//   len = sprintf( (char *) buf, "QUIT\r\n");
//   ret = write_ssl_and_get_response( &ssl, buf, len );
//   if( ret < 200 || ret > 299 )
//   {
//        ERROR( " failed  ! server responded with %d\n\n", ret );
//  free(pMallocEmail);
//  ret = BC_FAILURE;
//  goto err;
//   }

   if(NULL != pMallocEmail)
   {
    free(pMallocEmail);
    pMallocEmail = NULL;
   }
  
   ERROR(" send email success \n"); 

err:
   s32Ret = mbedtls_ssl_close_notify( &ssl );
   mbedtls_net_free( &server_fd );
   mbedtls_x509_crt_free( &clicert );
   mbedtls_x509_crt_free( &cacert );
   mbedtls_pk_free( &pkey );
   mbedtls_ssl_free( &ssl );
   mbedtls_ssl_config_free( &conf );
   mbedtls_ctr_drbg_free( &ctr_drbg );
   mbedtls_entropy_free( &entropy );

   ERROR(" send email  s32Ret %d , ret %d  \n",s32Ret,ret); 

   return ret;

#endif

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值