Electroneum
smtp.h
Go to the documentation of this file.
1 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the Andrey N. Sabelnikov nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 
28 
29 
30 #pragma once
31 #include <iostream>
32 #include <istream>
33 #include <ostream>
34 #include <string>
35 #include <boost/asio.hpp>
36 #include <boost/bind.hpp>
37 #include <boost/lexical_cast.hpp>
38 #include <boost/archive/iterators/base64_from_binary.hpp>
39 #include <boost/archive/iterators/transform_width.hpp>
40 #include <boost/archive/iterators/ostream_iterator.hpp>
41 
42 
43 namespace epee
44 {
45 namespace net_utils
46 {
47  namespace smtp
48  {
49 
50  using boost::asio::ip::tcp;
51  using namespace boost::archive::iterators;
52  typedef base64_from_binary<transform_width<const char *,6,8> > base64_text;
53 
54  /************************************************************************/
55  /* */
56  /************************************************************************/
58  {
59  public:
60  smtp_client(std::string pServer,unsigned int pPort,std::string pUser,std::string pPassword):
61  mServer(pServer),mPort(pPort),mUserName(pUser),mPassword(pPassword),mSocket(mIOService),mResolver(mIOService)
62  {
63  tcp::resolver::query qry(mServer,boost::lexical_cast<std::string>( mPort ));
64  mResolver.async_resolve(qry,boost::bind(&smtp_client::handleResolve,this,boost::asio::placeholders::error,
65  boost::asio::placeholders::iterator));
66  }
67  bool Send(std::string pFrom,std::string pTo,std::string pSubject,std::string pMessage)
68  {
69  mHasError = true;
70  mFrom=pFrom;
71  mTo=pTo;
72  mSubject=pSubject;
73  mMessage=pMessage;
74  mIOService.run();
75  return !mHasError;
76  }
77  private:
78  std::string encodeBase64(std::string pData)
79  {
80  std::stringstream os;
81  size_t sz=pData.size();
82  std::copy(base64_text(pData.c_str()),base64_text(pData.c_str()+sz),std::ostream_iterator<char>(os));
83  return os.str();
84  }
85  void handleResolve(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
86  {
87  if(!err)
88  {
89  tcp::endpoint endpoint=*endpoint_iterator;
90  mSocket.async_connect(endpoint,
91  boost::bind(&smtp_client::handleConnect,this,boost::asio::placeholders::error,++endpoint_iterator));
92  }
93  else
94  {
95  mHasError=true;
96  mErrorMsg= err.message();
97  }
98  }
99  void writeLine(std::string pData)
100  {
101  std::ostream req_strm(&mRequest);
102  req_strm << pData << "\r\n";
103  boost::asio::write(mSocket,mRequest);
104  req_strm.clear();
105  }
106  void readLine(std::string& pData)
107  {
108  boost::asio::streambuf response;
109  boost::asio::read_until(mSocket, response, "\r\n");
110  std::istream response_stream(&response);
111  response_stream >> pData;
112  }
113  void handleConnect(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
114  {
115  if (!err)
116  {
117  std::string read_buff;
118  // The connection was successful. Send the request.
119  std::ostream req_strm(&mRequest);
120  writeLine("EHLO "+mServer);
121  readLine(read_buff);//220
122  writeLine("AUTH LOGIN");
123  readLine(read_buff);//
124  writeLine(encodeBase64(mUserName));
125  readLine(read_buff);
126  writeLine(encodeBase64(mPassword));
127  readLine(read_buff);
128  writeLine( "MAIL FROM:<"+mFrom+">");
129  writeLine( "RCPT TO:<"+mTo+">");
130  writeLine( "DATA");
131  writeLine( "SUBJECT:"+mSubject);
132  writeLine( "From:"+mFrom);
133  writeLine( "To:"+mTo);
134  writeLine( "");
135  writeLine( mMessage );
136  writeLine( "\r\n.\r\n");
137  readLine(read_buff);
138  if(read_buff == "250")
139  mHasError = false;
140  writeLine( "QUIT");
141  }
142  else
143  {
144  mHasError=true;
145  mErrorMsg= err.message();
146  }
147  }
148  std::string mServer;
149  std::string mUserName;
150  std::string mPassword;
151  std::string mFrom;
152  std::string mTo;
153  std::string mSubject;
154  std::string mMessage;
155  unsigned int mPort;
156  boost::asio::io_service mIOService;
157  tcp::resolver mResolver;
158  tcp::socket mSocket;
159  boost::asio::streambuf mRequest;
160  boost::asio::streambuf mResponse;
161  bool mHasError;
162  std::string mErrorMsg;
163  };
164 
165 
166  bool send_mail(const std::string& server, int port, const std::string& login, const std::string& pass, const std::string& from_email, /*"STIL CRAWLER",*/
167  const std::string& maillist, const std::string& subject, const std::string& body)
168  {
169  STD_TRY_BEGIN();
170  //smtp_client mailc("yoursmtpserver.com",25,"user@yourdomain.com","password");
171  //mailc.Send("from@yourdomain.com","to@somewhere.com","subject","Hello from C++ SMTP Client!");
172  smtp_client mailc(server,port,login,pass);
173  return mailc.Send(from_email,maillist,subject,body);
174  STD_TRY_CATCH("at send_mail", false);
175  }
176 
177  }
178 }
179 }
180 
181 //#include "smtp.inl"
base64_from_binary< transform_width< const char *, 6, 8 > > base64_text
Definition: smtp.h:52
::std::string string
Definition: gtest-port.h:1097
epee::misc_utils::struct_init< response_t > response
smtp_client(std::string pServer, unsigned int pPort, std::string pUser, std::string pPassword)
Definition: smtp.h:60
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition: zmq.h:101
void copy(key &AA, const key &A)
Definition: rctOps.h:79
#define STD_TRY_BEGIN()
Definition: misc_language.h:36
bool Send(std::string pFrom, std::string pTo, std::string pSubject, std::string pMessage)
Definition: smtp.h:67
boost::endian::big_uint16_t port
Definition: socks.cpp:60
bool send_mail(const std::string &server, int port, const std::string &login, const std::string &pass, const std::string &from_email, const std::string &maillist, const std::string &subject, const std::string &body)
Definition: smtp.h:166
#define STD_TRY_CATCH(where_, ret_val)
Definition: misc_language.h:38
error
Tracks LMDB error codes.
Definition: error.h:44