CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Dec 2010
    Posts
    3

    Need tweaking done for a SMTP Client.

    Hello fellow programmers,

    As you can see, this is my 1st post and I am sad that this is not to contribute to the forum but to get help from you professional coders.

    Problem:
    I have been learning Network programming for a while and I gave a shot at programming a EMail sending program. It was going well until I stumbled across an unusual problem. I sent my message: EHLO example.org. I received a message from it. I sent it: STARTTLS. I received: "Ready to start TLS". Now, I am supposed to send MAIL FROM:<email.smtp.com>. However, I didn't receive "ok", like I supposed to, according to this: http://en.wikipedia.org/wiki/Simple_...nsfer_Protocol

    My output:
    Code:
    WinSock 2.0 has loaded successfully!
    WinSock 2.0's Status: Running
    
    Socket is okay!
    WinSock 2.0's Status: Running
    
    74.125.47.109
    220 mx.google.com ESMTP 347sm2387468yhc.4
    250-mx.google.com at your service, [myipaddresshere]
    250-SIZE 35651584
    250-SBITMIME
    250-STARTTLS
    250-ENHANCEDSTATUSCODES
    220 2.0.0 Ready to start TLS
    Code can be found here, also: http://pastebin.com/2PiYQuw4
    Code:
    #include <iostream>
    #include <windows.h>
    #pragma comment(lib, "ws2_32.lib")
    
    unsigned int mServer;
    
    typedef struct __SMTPInfo
    {
    	char *server;
    	char *from;
    	char *to;
    	char *subject;
    	char message[2000];
    } SMTPInfo;
    
    void send_to(char *msg)
    {
    	send(mServer, msg, strlen(msg), 0);
    }
    
    void recv_to(char *msg)
    {
    	int ret = 0;
    	Sleep(1000);
    	memset(msg, 0, 2000);
    	ret = recv(mServer, msg, 2000, 0);
    
    	if(ret == SOCKET_ERROR)
    	{
    	
    	}
    	else
    	{
    		std::cout << msg;
    	}
    }
    
    void MailIt(SMTPInfo *smtp)
    {
    	char recvmsg[2000];
    	char sendmsg[20000];
    	memset(recvmsg, 0, 2000);
    
    	recv_to(recvmsg);
    
    	strcpy(sendmsg, "EHLO smtp.gmail.com\r\n");
    	send_to(sendmsg);
    
    	recv_to(recvmsg);
    
    	char tt[256];
    	memset(tt, 0, 256);
    
    	strcat(tt, "STARTTLS\r\n");
    	send_to(tt);
    
    	recv_to(recvmsg);
    
    	char fromtt[256];
    	memset(fromtt, 0, 256);
    	strcat(fromtt, "MAIL FROM:<");
    	strcat(fromtt, smtp->from);
    	strcat(fromtt, ">\r\n");
    	send_to(fromtt);
    
    	recv_to(recvmsg);
    }
    
    int main(int argc, char *argv[])
    {
    	WSADATA wsData;
    	if(WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
    	{
    		std::cout << "Winsock didn't load successfully!\n";
    		WSACleanup();
    		std::cin.get();
    		return 0;
    	}
    	else
    	{
    		std::cout << wsData.szDescription << " has loaded successfully!\n";
    		std::cout << wsData.szDescription << "'s Status: " << wsData.szSystemStatus << "\n\n";
    	}
    
    	mServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if(mServer == INVALID_SOCKET)
    	{
    		std::cout << "Socket is invalid!\n";
    		WSACleanup();
    		std::cin.get();
    		return 0;
    	}
    	else
    	{
    		std::cout << "Socket is okay!\n";
    		std::cout << wsData.szDescription << "'s Status: " << wsData.szSystemStatus << "\n\n";
    	}
    	
    	SMTPInfo smtp;
    	smtp.server = argv[1];
    	sockaddr_in sin;
    	smtp.from = argv[3];
    	smtp.to = argv[4];
    	smtp.subject = argv[5];
    
    
    	HOSTENT *host = gethostbyname(smtp.server);
    
    	memset(&sin, 0, sizeof(sin));
    	memcpy(&(sin.sin_addr), host->h_addr, host->h_length);
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(atoi(argv[2]));
    	while(connect(mServer, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
    	{
    		connect(mServer, (sockaddr*)&sin, sizeof(sin));
    	}
    	sockaddr_in GoogleAddress;
    	int iSize = sizeof(GoogleAddress);
    	getpeername(mServer, (sockaddr*)&GoogleAddress, &iSize);
    	char *szIP = inet_ntoa(GoogleAddress.sin_addr);
    	std::cout << szIP << "\n";
    
    	MailIt(&smtp);
    	std::cin.get();
    	std::cin.get();
    	closesocket(mServer);
    	return 0;
    }
    Also, there are some junk code in there because I initially planned this as a Winsock practice project and I never intended to start a Email sending project.

    Any help is appreciated, Thanks in advance,
    Slumdog.

  2. #2
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Need tweaking done for a SMTP Client.

    I don't know much about TLS, but doesn't that hand off the process to another port? Are you using port 25 or port 587?

    At any rate, encrypted email seems like a bit much for a learning example.

  3. #3
    Join Date
    Dec 2010
    Posts
    3

    Re: Need tweaking done for a SMTP Client.

    This is not for teaching anyone. I need some helping making it work. Anyway, to answer your question, I am using port 587.

  4. #4
    Join Date
    Feb 2005
    Posts
    2,160

    Re: Need tweaking done for a SMTP Client.

    I didn't say anything about teaching. It seemed implicit in your post that you were doing this as an exercise in learning network programming.

    I just took a quick look at RFC3207 and it seems that after issuing the STARTTLS command, you then negotiate an encryption handshake, then restart the session from scratch (starting again with EHLO) once the encryption negotiation is complete. You don't appear to be doing anything cryptographic after the STARTTLS command.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured