POP3 with OpenSSL 0.9.8

自己写了一个小工具,用来检测POP3信箱是否有新邮件到了(其实邮件客户端outlook、foxmail等都可以检测,但不想在电脑上开太多的程序,所以自己写了一个),我一直用来检测公司邮箱,用得很好。前两天老婆说要用来检测gmail邮箱的邮件,却一直没反应,研究了一下gmail的说明,发现gmail的pop3需要ssl加密连接,所以就研究了一下OpenSSL的安装和使用

下载openssl-0.9.8.tar.gz,解压后,可以查看INSTALL.W32这个文件,告诉你在windows环境下如何编译和安装。

安装openssl之前你必须先安装Active Perl(http://www.activestate.com/ActivePerl)和NASM(http://www.kernel.org/pub/software/devel/nasm/binaries/win32/)(或者MASN,手册上说windows DDK里面包含了MASM,但是windows DDK不容易找,直接找MASM可能更容易些,比如asm.yeah.net里面就有下载的)。

我是在Borland C++ Builder 6环境下编译的,VC的方法也差不多。

进入到openssl解压后的目录,该目录下应该包含有README,NEWS等等文件,在windows控制台逐步执行下列步骤

> perl Configure BC-32
生成配置文件

> ms\do_nasm
生成makefile

> make -f ms\bcb.mak
生成结果

最终得到的lib文件在out32目录下,分别是libeay32.lib和ssleay32.lib
开发所用到的头文件在inc32目录下,你可以把这些文件组合到你同一个目录,以方便配置编译器选项

下面是一段用pop3来连接gmail的例子,供参考。


//---------------------------------------------------------------------------
// NOTE!!!
// Change gmail account and password first before begin test.
//---------------------------------------------------------------------------
#include "vcl.h"
#pragma hdrstop
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "winsock2.h"
#include "openssl/ssl.h"
#include "openssl/bio.h"
#include "openssl/err.h"
//---------------------------------------------------------------------------
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "openssl\\libeay32.lib")
#pragma comment(lib, "openssl\\ssleay32.lib")

#pragma warn-8004
#pragma argsused

int main(int argc, char* argv[])
{
SSL * ssl;
SSL_CTX * ctx;
SOCKET sock;
char* hostname = "pop.gmail.com";
int port = 995;

fprintf(stdout, "HOST: %s\t PORT: %d\nConnecting, standby...", hostname, port);
// start winsock
WSAData ws;
WSAStartup(0x0101, &ws);

unsigned long ip = inet_addr(hostname);
hostent* h_entity;
if (ip == 0xFFFFFFFF) {
h_entity = gethostbyname(hostname);
if (!h_entity) {
fprintf(stdout, "Can't reach the host\n");
return -1;
}
memcpy(&ip, h_entity->h_addr_list[0], sizeof(int));
}

// create socket and connect to server
sockaddr_in server;
memcpy(&server.sin_addr, &ip, sizeof(int));
server.sin_port = htons(port);
server.sin_family = AF_INET;
memset(&server.sin_zero, 0x00, 0x08);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sock, (sockaddr*)&server, sizeof(server));

// Load ssl context with socket binded
SSL_library_init();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_client_method());
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
int sslErr = SSL_connect(ssl);

char buff[1024];

// Read welcome info
memset(buff, 0x0, sizeof(buff));
int total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "\n%s", buff);

// Send account
char* p = "USER youraccount@gmail.com\r\n";
SSL_write(ssl, p, strlen(p));

memset(buff, 0x0, sizeof(buff));
total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "\n%s", buff);

// Send password
p = "PASS yourpassword\r\n";
SSL_write(ssl, p, strlen(p));
memset(buff, 0x0, sizeof(buff));
total = SSL_read(ssl, buff, 1023);
fprintf(stdout, "%s", buff);

fprintf(stdout, "Disconnect from the server.\nPress any key to exit.\n");
getch();

// Clear and free
SSL_shutdown(ssl);
closesocket(sock);
SSL_free(ssl);
SSL_CTX_free(ctx);
WSACleanup();
return 0;
}

2 Comments »

  1. Neo said

    真的那么简单?我在 BCB6 中编译 OpenSSL 0.9.6g 的时候遇到如下错误:

    n_o_T_a_s_m /Focrypto\md5\asm\m5_win32.obj .\crypto\md5\asm\m5_win32.asm

    ‘n_o_T_a_s_m’ 不是内部或外部命令,也不是可运行的程序或批处理文件。

  2. Neo said

    Found solution :-)

    Here is how to build with BCB5 using nasm
    Keary Phillips
    Sun, 03 Nov 2002 11:45:41 -0800

    Hi all,

    Here are directions for compiling OpenSSL 0.9.6g with Borland
    C++ Builder 5 (BCB5) using nasm.

    BUILD WITH NASM
    —————
    1) Setup up ActivePerl

    2) Install nasm. I put the executables in my
    {Borland}\CBuilder5\Bin directory because it is on my PATH.

    3) Execute “perl Configure BC-32″.

    4) Execute “ms\do_nasm”.

    5) In {OpenSSL}\ms\bcb.mak find the line like this: ASM=n_o_T_a_s_m
    and change it to this: ASM=nasmw -f obj

    VC++ uses a newer object format so it uses “nasmw -f win32″ while
    Borland uses the older format.

    6) Find all the lines in ms\bcb.mak with this: $(ASM) /Focrypto\
    and change the first part so it is like this: $(ASM) -o crypto\

    I didn’t hunt down where in the PERL scripts this is broken. The
    VC++ mak doesn’t have this. If someone with PERL knowledge
    and CVS access could fix this that would be great.

    7) If you tried making everything now you would get errors like this:

    Error E2293 .\crypto\bn\bn_asm.c 741: ) expected in function
    bn_sqr_comba8

    The solution is to search in crypto\bn\bn.h and find the line like
    this:
    #ifdef _MSC_VER
    and change it to this:
    #if defined(_MSC_VER) || defined(__BORLANDC__)

    Again. If someone with CVS access could change this that would be
    great.

    8) Finally execute “make -f ms\bcb.mak” to compile everything.

    TEST
    —-
    To confirm this all works I ran the tests by doing this:

    > cd out32
    > ..\ms\test

    They all passed.

    I also compiled a very old test program I built with BCB4 and the
    non-asm version of OpenSSL years ago. It only used RSA but it
    worked fine as well.

    Cheers,
    Keary Phillips

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.