本程序基于imap邮件协议
环境比较奇葩,eclipse+window 7+cygwin+openssl+gcc
eclipse主要用于编写代码,gcc用来编译
$ gcc -g -L"C:\cygwin64\lib" -o main main.c -lssl -lcrypto
/**
* 对返回值未做分析,存在很多不足
* gcc -g -L"C:\cygwin64\lib" -o main main.c -lssl -lcrypto
* gdb
* b 设置断点(行数)
* l 查看代码片段
* n 下一步
* s 下一步,可进去方法
* r 运行
* c 继续
* q 退出
* p 打印值
*/
#include
#include
#include
#include
#include
#include
#include
#include
char *mgetline(int lim); int mContains(char* des,char*src); SSL_CTX* init() { /* Initializing OpenSSL */ printf("--------------enter init method--------------------\n"); SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_CTX *ctx = SSL_CTX_new(TLSv1_client_method()); return ctx; } BIO* createConnect(SSL_CTX* ctx) { printf("--------------enter createConnect method--------------------\n"); //新建ssl认证方法 SSL *ssl; if (!SSL_CTX_load_verify_locations(ctx, "ca-bundle.crt", NULL )) printf("Error: %s\n", ERR_reason_error_string(ERR_get_error())); BIO* bio = BIO_new_ssl_connect(ctx); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); //设置连接 BIO_set_conn_hostname(bio, "imap.gmail.com:993"); if (BIO_do_connect(bio) <= 0) { printf("Error: %s\n", ERR_reason_error_string(ERR_get_error())); return NULL; } if (SSL_get_verify_result(ssl) != X509_V_OK) { printf("Error: %s\n", ERR_reason_error_string(ERR_get_error())); return NULL; } char* mes = (char*)malloc(1024*10); int ret = BIO_read(bio,mes,1024*10-1); if(ret<=0){ return NULL; }else { printf(mes); } return bio; } int login(BIO *bio){ int ret; printf("username:"); char* username; char* password; //scanf("%s",username); username = mgetline(1024); printf("password:"); //scanf("%s",password); password = mgetline(1024); char loginCom[100]; memset(loginCom,'\0',100); strcat(loginCom,"a001 login "); strcat(loginCom,username); strcat(loginCom," "); strcat(loginCom,password); strcat(loginCom,"\r\n"); printf(loginCom); ret = BIO_write(bio,loginCom,strlen(loginCom)); if (ret<=0)return 0; char* mes = (char*)malloc(1024*10); ret = BIO_read(bio,mes,1024*10-1); if (ret<=0)return 0; printf(mes); if(mContains(mes,"a001 OK")) return 1; else{ printf("username or password error!\n"); return 0; } } void destory(SSL_CTX* ctx,BIO *bio){ SSL_CTX_free(ctx); BIO_free_all(bio); } int main() { SSL_CTX* ctx = init(); BIO *bio = createConnect(ctx); int ret; if(login(bio)) { char* command = (char*)malloc(1024); char* reci = (char*)malloc(1024*10); while(1){ printf("please enter command:"); //scanf("%s",command); //fgets(command,sizeof(command),stdin); command = mgetline(1024); if(strcmp(command,"000000")!=0){ //strcat(command,"\r\n"); strcat(command,"\r\n"); ret = BIO_write(bio,command,strlen(command)); if(ret<=0) break; ret = BIO_read(bio,reci,1024*10-1); if(ret<=0) break; printf(reci); if(mContains(reci,"BYE LOGOUT Requested")){ memset(reci,'\0',1024*10); break; } memset(reci,'\0',1024*10); }else{ BIO_write(bio,"a001 logout\r\n",strlen("a001 logout\r\n")); ret = BIO_read(bio,reci,1024*10-1); if(ret<=0) break; printf(reci); memset(reci,'\0',1024*10); break; } } } destory(ctx,bio); return 1; } char *mgetline(int lim) { char c; int i; char *line, *tmp; tmp = line = malloc(sizeof(char) * lim); i = 0; /* NOTE: 'i' is completely redundant as you can use 'tmp', * 'line,' and 'lim' to determine if you are going to * overflow your buffer */ while((c = getchar()) != '\n' && c != EOF && i < lim-1) { *tmp = c; tmp++; i++; } *tmp = '\0'; //printf("%s", line); return line; } int mContains(char* des,char*src){ char* p = des; char* q = src; while(*p!='\0'){ if(*p==*q){ p++; q++; if(*q=='\0')return 1; continue; } p++; q = src; } return 0; }