smtp_client.h
Go to the documentation of this file.
1 /**
2  * @file smtp_client.h
3  * @brief SMTP client (Simple Mail Transfer Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2023 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.2.2
29  **/
30 
31 #ifndef _SMTP_CLIENT_H
32 #define _SMTP_CLIENT_H
33 
34 //Dependencies
35 #include "core/net.h"
36 
37 //SMTP client support
38 #ifndef SMTP_CLIENT_SUPPORT
39  #define SMTP_CLIENT_SUPPORT ENABLED
40 #elif (SMTP_CLIENT_SUPPORT != ENABLED && SMTP_CLIENT_SUPPORT != DISABLED)
41  #error SMTP_CLIENT_SUPPORT parameter is not valid
42 #endif
43 
44 //MIME extension support
45 #ifndef SMTP_CLIENT_MIME_SUPPORT
46  #define SMTP_CLIENT_MIME_SUPPORT ENABLED
47 #elif (SMTP_CLIENT_MIME_SUPPORT != ENABLED && SMTP_CLIENT_MIME_SUPPORT != DISABLED)
48  #error SMTP_CLIENT_MIME_SUPPORT parameter is not valid
49 #endif
50 
51 //SMTP over TLS
52 #ifndef SMTP_CLIENT_TLS_SUPPORT
53  #define SMTP_CLIENT_TLS_SUPPORT DISABLED
54 #elif (SMTP_CLIENT_TLS_SUPPORT != ENABLED && SMTP_CLIENT_TLS_SUPPORT != DISABLED)
55  #error SMTP_CLIENT_TLS_SUPPORT parameter is not valid
56 #endif
57 
58 //LOGIN authentication support
59 #ifndef SMTP_CLIENT_LOGIN_AUTH_SUPPORT
60  #define SMTP_CLIENT_LOGIN_AUTH_SUPPORT ENABLED
61 #elif (SMTP_CLIENT_LOGIN_AUTH_SUPPORT != ENABLED && SMTP_CLIENT_LOGIN_AUTH_SUPPORT != DISABLED)
62  #error SMTP_CLIENT_LOGIN_AUTH_SUPPORT parameter is not valid
63 #endif
64 
65 //PLAIN authentication support
66 #ifndef SMTP_CLIENT_PLAIN_AUTH_SUPPORT
67  #define SMTP_CLIENT_PLAIN_AUTH_SUPPORT ENABLED
68 #elif (SMTP_CLIENT_PLAIN_AUTH_SUPPORT != ENABLED && SMTP_CLIENT_PLAIN_AUTH_SUPPORT != DISABLED)
69  #error SMTP_CLIENT_PLAIN_AUTH_SUPPORT parameter is not valid
70 #endif
71 
72 //CRAM-MD5 authentication support
73 #ifndef SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT
74  #define SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT DISABLED
75 #elif (SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT != ENABLED && SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT != DISABLED)
76  #error SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT parameter is not valid
77 #endif
78 
79 //Default timeout
80 #ifndef SMTP_CLIENT_DEFAULT_TIMEOUT
81  #define SMTP_CLIENT_DEFAULT_TIMEOUT 20000
82 #elif (SMTP_CLIENT_DEFAULT_TIMEOUT < 1000)
83  #error SMTP_CLIENT_DEFAULT_TIMEOUT parameter is not valid
84 #endif
85 
86 //Size of the buffer for input/output operations
87 #ifndef SMTP_CLIENT_BUFFER_SIZE
88  #define SMTP_CLIENT_BUFFER_SIZE 512
89 #elif (SMTP_CLIENT_BUFFER_SIZE < 64)
90  #error SMTP_CLIENT_BUFFER_SIZE parameter is not valid
91 #endif
92 
93 //TX buffer size for TLS connections
94 #ifndef SMTP_CLIENT_TLS_TX_BUFFER_SIZE
95  #define SMTP_CLIENT_TLS_TX_BUFFER_SIZE 2048
96 #elif (SMTP_CLIENT_TLS_TX_BUFFER_SIZE < 512)
97  #error SMTP_CLIENT_TLS_TX_BUFFER_SIZE parameter is not valid
98 #endif
99 
100 //RX buffer size for TLS connections
101 #ifndef SMTP_CLIENT_TLS_RX_BUFFER_SIZE
102  #define SMTP_CLIENT_TLS_RX_BUFFER_SIZE 4096
103 #elif (SMTP_CLIENT_TLS_RX_BUFFER_SIZE < 512)
104  #error SMTP_CLIENT_TLS_RX_BUFFER_SIZE parameter is not valid
105 #endif
106 
107 //Maximum length for content type
108 #ifndef SMTP_CLIENT_CONTENT_TYPE_MAX_LEN
109  #define SMTP_CLIENT_CONTENT_TYPE_MAX_LEN 32
110 #elif (SMTP_CLIENT_CONTENT_TYPE_MAX_LEN < 1)
111  #error SMTP_CLIENT_CONTENT_TYPE_MAX_LEN parameter is not valid
112 #endif
113 
114 //Maximum length for boundary string
115 #ifndef SMTP_CLIENT_BOUNDARY_MAX_LEN
116  #define SMTP_CLIENT_BOUNDARY_MAX_LEN 70
117 #elif (SMTP_CLIENT_BOUNDARY_MAX_LEN < 1)
118  #error SMTP_CLIENT_BOUNDARY_MAX_LEN parameter is not valid
119 #endif
120 
121 //Application specific context
122 #ifndef SMTP_CLIENT_PRIVATE_CONTEXT
123  #define SMTP_CLIENT_PRIVATE_CONTEXT
124 #endif
125 
126 //TLS supported?
127 #if (SMTP_CLIENT_TLS_SUPPORT == ENABLED)
128  #include "core/crypto.h"
129  #include "tls.h"
130 #endif
131 
132 //LOGIN or PLAIN authentication supported?
133 #if (SMTP_CLIENT_LOGIN_AUTH_SUPPORT == ENABLED || SMTP_CLIENT_PLAIN_AUTH_SUPPORT == ENABLED)
134  #include "core/crypto.h"
135  #include "encoding/base64.h"
136 #endif
137 
138 //CRAM-MD5 authentication supported?
139 #if (SMTP_CLIENT_CRAM_MD5_AUTH_SUPPORT == ENABLED)
140  #include "core/crypto.h"
141  #include "encoding/base64.h"
142  #include "mac/hmac.h"
143  #include "hash/md5.h"
144 #endif
145 
146 //SMTP port number (message relaying)
147 #define SMTP_RELAY_PORT 25
148 //SMTP port number (message submission)
149 #define SMTP_SUBMISSION_PORT 587
150 //SMTPS port number (message submission over TLS)
151 #define SMTPS_SUBMISSION_PORT 465
152 
153 //Test macros for SMTP response codes
154 #define SMTP_REPLY_CODE_2YZ(code) ((code) >= 200 && (code) < 300)
155 #define SMTP_REPLY_CODE_3YZ(code) ((code) >= 300 && (code) < 400)
156 #define SMTP_REPLY_CODE_4YZ(code) ((code) >= 400 && (code) < 500)
157 #define SMTP_REPLY_CODE_5YZ(code) ((code) >= 500 && (code) < 600)
158 
159 //Forward declaration of SmtpClientContext structure
160 struct _SmtpClientContext;
161 #define SmtpClientContext struct _SmtpClientContext
162 
163 //C++ guard
164 #ifdef __cplusplus
165 extern "C" {
166 #endif
167 
168 
169 /**
170  * @brief SMTP connection modes
171  **/
172 
173 typedef enum
174 {
179 
180 
181 /**
182  * @brief Email address types
183  **/
184 
185 typedef enum
186 {
192 
193 
194 /**
195  * @brief SMTP client states
196  */
197 
198 typedef enum
199 {
213 
214 
215 /**
216  * @brief Multiline reply parsing callback function
217  **/
218 
220  char_t *replyLine);
221 
222 
223 //TLS supported?
224 #if (SMTP_CLIENT_TLS_SUPPORT == ENABLED)
225 
226 /**
227  * @brief TLS initialization callback function
228  **/
229 
232 
233 #endif
234 
235 
236 /**
237  * @brief Email address
238  **/
239 
240 typedef struct
241 {
245 } SmtpMailAddr;
246 
247 
248 /**
249  * @brief SMTP client context
250  **/
251 
253 {
254  SmtpClientState state; ///<SMTP client state
255  NetInterface *interface; ///<Underlying network interface
256  systime_t timeout; ///<Timeout value
257  systime_t timestamp; ///<Timestamp to manage timeout
258  Socket *socket; ///<Underlying socket
259 #if (SMTP_CLIENT_TLS_SUPPORT == ENABLED)
260  TlsContext *tlsContext; ///<TLS context
261  TlsSessionState tlsSession; ///<TLS session state
262  SmtpClientTlsInitCallback tlsInitCallback; ///<TLS initialization callback function
263 #endif
264 #if (SMTP_CLIENT_MIME_SUPPORT == ENABLED)
266  char_t boundary[SMTP_CLIENT_BOUNDARY_MAX_LEN + 1]; ///<Boundary string
267  bool_t base64Encoding; ///<Base64 encoding
268 #endif
269  bool_t startTlsSupported; ///<STARTTLS command supported
270  bool_t authLoginSupported; ///<LOGIN authentication mechanism supported
271  bool_t authPlainSupported; ///<PLAIN authentication mechanism supported
272  bool_t authCramMd5Supported; ///<CRAM-MD5 authentication mechanism supported
273  char_t buffer[SMTP_CLIENT_BUFFER_SIZE + 1]; ///<Memory buffer for input/output operations
274  size_t bufferLen; ///<Length of the buffer, in bytes
275  size_t bufferPos; ///<Current position in the buffer
276  size_t commandLen; ///<Length of the SMTP command, in bytes
277  size_t replyLen; ///<Length of the SMTP reply, in bytes
278  uint_t replyCode; ///<SMTP reply code
279  uint_t recipientIndex; ///<Index of the current recipient
280  SMTP_CLIENT_PRIVATE_CONTEXT ///<Application specific context
281 };
282 
283 
284 //Callback function to parse a response line
285 typedef error_t (*SmtpReplyCallback)(SmtpClientContext *context, char_t *replyLine, uint_t replyCode);
286 
287 //SMTP related functions
289 
290 #if (SMTP_CLIENT_TLS_SUPPORT == ENABLED)
291 
293  SmtpClientTlsInitCallback callback);
294 
295 #endif
296 
298 
300  NetInterface *interface);
301 
303  const IpAddr *serverIpAddr, uint16_t serverPort, SmtpConnectionMode mode);
304 
305 error_t smtpClientLogin(SmtpClientContext *context, const char_t *username,
306  const char_t *password);
307 
309  const char_t *contentType);
310 
312  const char_t *boundary);
313 
315  const SmtpMailAddr *from, const SmtpMailAddr *recipients,
316  uint_t numRecipients, const char_t *subject);
317 
319  const void *data, size_t length, size_t *written, uint_t flags);
320 
322  const char_t *filename, const char_t *contentType,
323  const char_t *contentTransferEncoding, bool_t last);
324 
326  const void *data, size_t length, size_t *written, uint_t flags);
327 
329 
331 
334 
335 void smtpClientDeinit(SmtpClientContext *context);
336 
337 //C++ guard
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif
error_t smtpClientCloseMailBody(SmtpClientContext *context)
Complete email sending process and wait for server's status.
Definition: smtp_client.c:1081
uint8_t length
Definition: coap_common.h:193
@ SMTP_CLIENT_STATE_MAIL_BODY
Definition: smtp_client.h:208
TlsContext * tlsContext
TLS context.
Definition: smtp_client.h:260
SMTP client context.
Definition: smtp_client.h:253
int bool_t
Definition: compiler_port.h:53
char_t contentType[SMTP_CLIENT_CONTENT_TYPE_MAX_LEN+1]
Content type.
Definition: smtp_client.h:265
size_t replyLen
Length of the SMTP reply, in bytes.
Definition: smtp_client.h:277
#define SMTP_CLIENT_BUFFER_SIZE
Definition: smtp_client.h:88
uint8_t data[]
Definition: ethernet.h:220
error_t smtpClientClose(SmtpClientContext *context)
Close the connection with the SMTP server.
Definition: smtp_client.c:1278
IP network address.
Definition: ip.h:79
size_t bufferPos
Current position in the buffer.
Definition: smtp_client.h:275
systime_t timestamp
Timestamp to manage timeout.
Definition: smtp_client.h:257
Email address.
Definition: smtp_client.h:241
uint16_t last
Definition: ipv4_frag.h:96
@ SMTP_CLIENT_STATE_SUB_COMMAND_1
Definition: smtp_client.h:204
@ SMTP_CLIENT_STATE_MAIL_HEADER
Definition: smtp_client.h:207
bool_t authLoginSupported
LOGIN authentication mechanism supported.
Definition: smtp_client.h:270
error_t smtpClientWriteMultipartBody(SmtpClientContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Write data to the multipart body.
Definition: smtp_client.c:934
@ SMTP_CLIENT_STATE_DISCONNECTING
Definition: smtp_client.h:211
error_t smtpClientDisconnect(SmtpClientContext *context)
Gracefully disconnect from the SMTP server.
Definition: smtp_client.c:1186
@ SMTP_ADDR_TYPE_FROM
Definition: smtp_client.h:187
error_t smtpClientRegisterTlsInitCallback(SmtpClientContext *context, SmtpClientTlsInitCallback callback)
Register TLS initialization callback function.
Definition: smtp_client.c:102
SmtpMailAddrType
Email address types.
Definition: smtp_client.h:186
@ SMTP_MODE_PLAINTEXT
Definition: smtp_client.h:175
char_t buffer[SMTP_CLIENT_BUFFER_SIZE+1]
Memory buffer for input/output operations.
Definition: smtp_client.h:273
@ SMTP_MODE_IMPLICIT_TLS
Definition: smtp_client.h:176
bool_t authPlainSupported
PLAIN authentication mechanism supported.
Definition: smtp_client.h:271
#define SmtpClientContext
Definition: smtp_client.h:161
SmtpClientState
SMTP client states.
Definition: smtp_client.h:199
char_t filename[]
Definition: tftp_common.h:91
#define TlsContext
Definition: tls.h:36
#define SMTP_CLIENT_CONTENT_TYPE_MAX_LEN
Definition: smtp_client.h:109
error_t
Error codes.
Definition: error.h:43
bool_t authCramMd5Supported
CRAM-MD5 authentication mechanism supported.
Definition: smtp_client.h:272
@ SMTP_ADDR_TYPE_TO
Definition: smtp_client.h:188
error_t smtpClientWriteMultipartHeader(SmtpClientContext *context, const char_t *filename, const char_t *contentType, const char_t *contentTransferEncoding, bool_t last)
Write multipart header.
Definition: smtp_client.c:797
error_t(* SmtpClientTlsInitCallback)(SmtpClientContext *context, TlsContext *tlsContext)
TLS initialization callback function.
Definition: smtp_client.h:230
#define NetInterface
Definition: net.h:36
error_t smtpClientLogin(SmtpClientContext *context, const char_t *username, const char_t *password)
Login to the SMTP server using the provided user name and password.
Definition: smtp_client.c:431
#define SMTP_CLIENT_BOUNDARY_MAX_LEN
Definition: smtp_client.h:116
General definitions for cryptographic algorithms.
SmtpMailAddrType type
Definition: smtp_client.h:244
@ SMTP_CLIENT_STATE_SUB_COMMAND_2
Definition: smtp_client.h:205
@ SMTP_CLIENT_STATE_CONNECTED
Definition: smtp_client.h:203
Base64 encoding scheme.
error_t smtpClientWriteMailBody(SmtpClientContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Write email body.
Definition: smtp_client.c:727
@ SMTP_ADDR_TYPE_CC
Definition: smtp_client.h:189
Socket * socket
Underlying socket.
Definition: smtp_client.h:258
error_t smtpClientSetMultipartBoundary(SmtpClientContext *context, const char_t *boundary)
Define the boundary string to be used (multipart encoding)
Definition: smtp_client.c:520
#define SMTP_CLIENT_PRIVATE_CONTEXT
Definition: smtp_client.h:123
SmtpClientState state
SMTP client state.
Definition: smtp_client.h:254
char_t * name
Definition: smtp_client.h:242
void smtpClientDeinit(SmtpClientContext *context)
Release SMTP client context.
Definition: smtp_client.c:1299
uint32_t systime_t
System time.
error_t smtpClientSetTimeout(SmtpClientContext *context, systime_t timeout)
Set communication timeout.
Definition: smtp_client.c:126
uint8_t flags
Definition: tcp.h:349
@ SMTP_CLIENT_STATE_DISCONNECTED
Definition: smtp_client.h:200
char char_t
Definition: compiler_port.h:48
systime_t timeout
Timeout value.
Definition: smtp_client.h:256
TlsSessionState tlsSession
TLS session state.
Definition: smtp_client.h:261
uint_t smtpClientGetReplyCode(SmtpClientContext *context)
Retrieve server's reply code.
Definition: smtp_client.c:1159
error_t(* SmtpClientReplyCallback)(SmtpClientContext *context, char_t *replyLine)
Multiline reply parsing callback function.
Definition: smtp_client.h:219
error_t(* SmtpReplyCallback)(SmtpClientContext *context, char_t *replyLine, uint_t replyCode)
Definition: smtp_client.h:285
@ SMTP_CLIENT_STATE_SUB_COMMAND_3
Definition: smtp_client.h:206
uint_t recipientIndex
Index of the current recipient.
Definition: smtp_client.h:279
SmtpConnectionMode
SMTP connection modes.
Definition: smtp_client.h:174
TLS session state.
Definition: tls.h:1957
MD5 (Message-Digest Algorithm)
error_t smtpClientWriteMailHeader(SmtpClientContext *context, const SmtpMailAddr *from, const SmtpMailAddr *recipients, uint_t numRecipients, const char_t *subject)
Write email header.
Definition: smtp_client.c:559
#define Socket
Definition: socket.h:36
bool_t base64Encoding
Base64 encoding.
Definition: smtp_client.h:267
error_t smtpClientInit(SmtpClientContext *context)
Initialize SMTP client context.
Definition: smtp_client.c:61
error_t smtpClientConnect(SmtpClientContext *context, const IpAddr *serverIpAddr, uint16_t serverPort, SmtpConnectionMode mode)
Establish a connection with the specified SMTP server.
Definition: smtp_client.c:171
TLS (Transport Layer Security)
uint_t replyCode
SMTP reply code.
Definition: smtp_client.h:278
size_t bufferLen
Length of the buffer, in bytes.
Definition: smtp_client.h:274
uint8_t mode
Definition: ntp_common.h:149
error_t smtpClientSetContentType(SmtpClientContext *context, const char_t *contentType)
Set the content type to be used.
Definition: smtp_client.c:484
SmtpClientTlsInitCallback tlsInitCallback
TLS initialization callback function.
Definition: smtp_client.h:262
@ SMTP_CLIENT_STATE_CONNECTING_TLS
Definition: smtp_client.h:202
char_t * addr
Definition: smtp_client.h:243
size_t commandLen
Length of the SMTP command, in bytes.
Definition: smtp_client.h:276
error_t smtpClientBindToInterface(SmtpClientContext *context, NetInterface *interface)
Bind the SMTP client to a particular network interface.
Definition: smtp_client.c:147
bool_t startTlsSupported
STARTTLS command supported.
Definition: smtp_client.h:269
unsigned int uint_t
Definition: compiler_port.h:50
@ SMTP_MODE_EXPLICIT_TLS
Definition: smtp_client.h:177
TCP/IP stack core.
NetInterface * interface
Underlying network interface.
Definition: smtp_client.h:255
@ SMTP_ADDR_TYPE_BCC
Definition: smtp_client.h:190
@ SMTP_CLIENT_STATE_MULTIPART_BODY
Definition: smtp_client.h:210
HMAC (Keyed-Hashing for Message Authentication)
char_t boundary[SMTP_CLIENT_BOUNDARY_MAX_LEN+1]
Boundary string.
Definition: smtp_client.h:266
@ SMTP_CLIENT_STATE_CONNECTING_TCP
Definition: smtp_client.h:201
@ SMTP_CLIENT_STATE_MULTIPART_HEADER
Definition: smtp_client.h:209