1 /* 2 ** Copyright 2002-2008, Double Precision Inc. 3 ** 4 ** See COPYING for distribution information. 5 */ 6 #ifndef libmail_smtp_H 7 #define libmail_smtp_H 8 9 #include "libmail_config.h" 10 #if HAVE_FCNTL_H 11 #include <fcntl.h> 12 #endif 13 #include "mail.H" 14 #include <sys/types.h> 15 16 #include "smtpinfo.H" 17 #include "logininfo.H" 18 #include "fd.H" 19 #include <stdio.h> 20 #include <time.h> 21 #include <list> 22 #include <string> 23 #include <set> 24 #include <queue> 25 #include <vector> 26 27 LIBMAIL_START 28 29 /////////////////////////////////////////////////////////////////////////// 30 // 31 // An SMTP implementation 32 // 33 34 class smtp : public fd, public loginInfo::callbackTarget { 35 36 private: 37 void resumed(); 38 void handler(std::vector<pollfd> &fds, int &timeout); 39 40 std::set<std::string> capabilities; 41 42 bool orderlyShutdown; 43 44 loginInfo smtpLoginInfo; 45 46 int socketRead(const std::string &readbuffer); 47 48 void disconnect(const char *reason); 49 50 std::list<std::string> smtpResponse; 51 // SMTP server response being accumulated. 52 53 void (smtp::*responseHandler)(int numCode, 54 std::string multilineResponse); 55 // Handler called when an SMTP response is received in entirety 56 57 void installHandler(void (smtp::*)(int numCode, 58 std::string multilineResponse)); 59 // Install next handler. 60 61 time_t responseTimeout; 62 // SMTP timeout 63 64 void error(std::string); /* Login failed */ 65 void success(std::string); /* Login succeeded */ 66 67 void howdy(const char *); /* send ehlo/helo */ 68 69 void greetingResponse(int, std::string); 70 void ehloResponse(int, std::string); 71 void heloResponse(int, std::string); 72 void auth_external_response(int, std::string); 73 void quitResponse(int, std::string); 74 75 int hmac_method_index; 76 /* Next HMAC authentication hash function to try */ 77 78 void authenticate_hmac(); 79 void hmacResponse(int, std::string); 80 81 void starttls(); 82 void starttlsResponse(int, std::string); 83 84 void authenticate_login(); 85 86 void begin_auth(); 87 void begin_auth_nonexternal(); 88 89 void loginInfoCallback(std::string str); 90 void loginInfoCallbackCancel(); 91 92 93 void loginUseridResponse(int, std::string); 94 void loginPasswdResponse(int, std::string); 95 void loginResponse(int, std::string); 96 97 void authenticated(); 98 99 bool ready2send; /* Fully logged in */ 100 101 struct messageQueueInfo { 102 FILE *message; 103 mail::smtpInfo messageInfo; 104 mail::callback *callback; 105 bool flag8bit; 106 }; 107 108 std::queue<messageQueueInfo> sendQueue; 109 /* Queue of messages waiting to go out */ 110 111 bool fatalError; // Fatal connection error occured 112 time_t pingTimeout; // When idling, ping occasionally 113 114 // Custom WriteBuffer that spits out the whole message 115 116 class Blast : public fd::WriteBuffer { 117 118 bool eofSent; 119 public: 120 smtp *mySmtp; 121 122 char lastChar; 123 124 size_t bytesTotal; 125 size_t bytesDone; 126 127 Blast(smtp *smtpArg); 128 ~Blast(); 129 130 bool fillWriteBuffer(); 131 }; 132 133 Blast *myBlaster; 134 135 public: 136 friend class Blast; 137 138 smtp(std::string url, std::string passwd, 139 std::vector<std::string> &certificates, 140 mail::callback &callback, 141 mail::callback::disconnect &disconnectCallback, 142 loginCallback *loginCallbackFunc); 143 144 smtp(const smtp &); // UNDEFINED 145 smtp &operator=(const smtp &); // UNDEFINED 146 147 ~smtp(); 148 149 void logout(mail::callback &callback); 150 void checkNewMail(mail::callback &callback); 151 bool hasCapability(std::string capability); 152 std::string getCapability(std::string capability); 153 154 mail::folder *folderFromString(std::string); 155 156 void readTopLevelFolders(mail::callback::folderList &callback1, 157 mail::callback &callback2); 158 159 void findFolder(std::string folder, 160 class mail::callback::folderList &callback1, 161 class mail::callback &callback2); 162 std::string translatePath(std::string path); 163 164 mail::folder *getSendFolder(const mail::smtpInfo &info, 165 const mail::folder *folder, 166 std::string &errmsg); 167 168 169 void readMessageAttributes(const std::vector<size_t> &messages, 170 MessageAttributes attributes, 171 mail::callback::message &callback); 172 173 void readMessageContent(const std::vector<size_t> &messages, 174 bool peek, 175 enum mail::readMode readType, 176 mail::callback::message &callback); 177 178 void readMessageContent(size_t messageNum, 179 bool peek, 180 const mimestruct &msginfo, 181 enum mail::readMode readType, 182 mail::callback::message &callback); 183 184 void readMessageContentDecoded(size_t messageNum, 185 bool peek, 186 const mimestruct &msginfo, 187 mail::callback::message &callback); 188 189 size_t getFolderIndexSize(); 190 mail::messageInfo getFolderIndexInfo(size_t); 191 192 void saveFolderIndexInfo(size_t, 193 const mail::messageInfo &, 194 mail::callback &); 195 196 void updateFolderIndexFlags(const std::vector<size_t> &messages, 197 bool doFlip, 198 bool enableDisable, 199 const mail::messageInfo &flags, 200 mail::callback &callback); 201 202 void updateFolderIndexInfo(mail::callback &); 203 void removeMessages(const std::vector<size_t> &messages, 204 callback &cb); 205 206 void copyMessagesTo(const std::vector<size_t> &messages, 207 mail::folder *copyTo, 208 mail::callback &callback); 209 210 void searchMessages(const searchParams &searchInfo, 211 searchCallback &callback); 212 213 214 void send(FILE *tmpfile, mail::smtpInfo &info, 215 mail::callback *callback, 216 bool flag8bit); 217 218 private: 219 void startNextMessage(); 220 void messageProcessed(int, std::string); 221 222 void rsetResponse(int, std::string); 223 bool validString(std::string s); 224 225 std::string pipelineError; 226 unsigned pipelineCount; // Count pipelined replies received 227 unsigned rcptCount; // RCPT TO count. 228 std::string pipelineCmd; // Command that got rejected. 229 230 void pipelinedResponse(int, std::string); 231 void mailfromResponse(int, std::string); 232 233 void dataResponse(int, std::string); 234 void data2Response(int, std::string); 235 }; 236 237 LIBMAIL_END 238 239 #endif 240