いろんなものはつながっている

ネットワークプログラミング基礎 POP3

「猫でもわかるネットワークプログラミング」を参考にSocketを用いたプログラミングの例としてPOP3接続してみる。

1.ソケットをオープンする
2.gethostbyname関数でホスト情報を取得する
3.SOCKADDR_IN構造体に接続先に関する情報をセットしconnect関数で接続する
4.接続が成功すると+OK … と返事がくる
5.ユーザ名をUSER XXX\r\nの形で送信する。
6.受け入れられると+OK … と返事がくる
7.パスワードをPASS YYY\r\nの形で送信する。
8.パスワードが通れば+OK XXX has x visible … と返事がくる
9.メールを受信したり、リストをうけとったりする
10.QUIT\r\nを送信して通信を終了する
11.ソケットを閉じる

// POP3プログラミング
//
#include "stdafx.h"

#pragma comment(lib, "ws2_32.lib")
#include "winsock2.h"

int ConvertWidetoMultiByte(TCHAR* szBuf);

#define PORT 110
#define BUFFER_SIZE 1024

int _tmain(int argc, _TCHAR* argv[])
{
	// WinSockの初期化
	WSADATA data;
	WSAStartup(MAKEWORD(2,0), &data);

	// ソケットの生成
	int nDestSocket;
	nDestSocket = socket(AF_INET, SOCK_STREAM, 0);	

	// POPサーバ情報を取得
	TCHAR szPopServerName[] = _T("ServerName");
	LPHOSTENT lpHost = gethostbyname(szPopServerName);
	if(lpHost == NULL){
		return -1;
	}

	// 接続先の情報をsockaddr_in 構造体にセット
	struct sockaddr_in dstAddr;
	memset(&dstAddr, 0, sizeof(dstAddr));
	dstAddr.sin_port = htons(PORT);
	dstAddr.sin_family = AF_INET;
	dstAddr.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list);

	// 接続
	if(connect(nDestSocket, (struct sockaddr*)&dstAddr, sizeof(dstAddr))){
		printf("%s に接続できませんでした\n", szPopServerName);
		return(-1);
	}

	// 接続の応答 
	TCHAR szBuf[BUFFER_SIZE];
	memset(szBuf, _T('\0'), BUFFER_SIZE);
	recv(nDestSocket, szBuf, sizeof(szBuf) - 1, 0);
	if(_tcsstr(szBuf, _T("+OK")) == NULL){
		closesocket(nDestSocket);
		WSACleanup();
		return -1;
	}

	// ユーザIDの送信
	TCHAR szUserID[] = _T("UserID");
	TCHAR szUserRequest[64];
	_stprintf(szUserRequest, _T("USER %s\n"), szUserID);
	send(nDestSocket, szUserRequest, (int)_tcslen(szUserRequest), 0);

	memset(szBuf, _T('\0'), BUFFER_SIZE);
	recv(nDestSocket, szBuf, sizeof(szBuf) - 1, 0);

	// パスワードの送信
	TCHAR szPass[] = _T("Password");
	TCHAR szPassRequest[64];
	_stprintf(szPassRequest, _T("PASS %s\n"), szPass);
	send(nDestSocket, szPassRequest, (int)_tcslen(szPassRequest), 0);

	memset(szBuf, _T('\0'), BUFFER_SIZE);
	recv(nDestSocket, szBuf, sizeof(szBuf) - 1, 0);

	if(_tcsstr(szBuf, _T("+OK")) == NULL){
		closesocket(nDestSocket);
		WSACleanup();
		return -1;
	}

	// メールリストを取得
	TCHAR szListRequest[] = _T("LIST\r\n");
	send(nDestSocket, szListRequest, sizeof(szListRequest), 0);
	TCHAR szList[BUFFER_SIZE * 4];
	memset(szList, _T('\0'), BUFFER_SIZE*4);
	while(1){
		memset(szBuf, _T('\0'), BUFFER_SIZE);
		recv(nDestSocket, szBuf, sizeof(szBuf), 0);
		_tcscat(szList, szBuf);
		if(_tcsstr(szBuf, _T(".\r\n"))) break;
	}

	// 接続をきる
	TCHAR szQuitRequest[] = _T("QUIT\r\n");
	send(nDestSocket, szQuitRequest, sizeof(szQuitRequest), 0);
	memset(szBuf, _T('\0'), BUFFER_SIZE);
	recv(nDestSocket, szBuf, sizeof(szBuf), 0);

	// Windows でのソケットの終了
	closesocket(nDestSocket);
	WSACleanup();

	return 0;

}

あたりまえではあるが、パスワードは平文でながれるのでパケットをキャプチャしてやればパスワードがわかってしまう。
POP31

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサード リンク

カテゴリー

スポンサード リンク