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
}