1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2025-present Eclipse ThreadX Contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX SMTP Client Component */
/** */
/** Simple Mail Transfer Protocol (SMTP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* nxd_smtp_client.h PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Simple Mail Transfer Protocol (SMTP) */
/* Client component, including all data types and external references. */
/* It is assumed that tx_api.h, tx_port.h, nx_api.h, and nx_port.h, */
/* have already been included. */
/* */
/**************************************************************************/
#ifndef NXD_SMTP_CLIENT_H
#define NXD_SMTP_CLIENT_H
/* Determine if a C++ compiler is being used. If so, ensure that standard
C is used to process the API information. */
#ifdef __cplusplus
/* Yes, C++ compiler is present. Use standard C. */
extern "C" {
#endif
#include "nx_api.h"
/* NX SMTP Client configurable options. */
/* Set the TCP socket window size. */
#ifndef NX_SMTP_CLIENT_TCP_WINDOW_SIZE
#define NX_SMTP_CLIENT_TCP_WINDOW_SIZE 1460
#endif
/* Set timeout on Client packet allocation in ticks. */
#ifndef NX_SMTP_CLIENT_PACKET_TIMEOUT
#define NX_SMTP_CLIENT_PACKET_TIMEOUT (2 * NX_IP_PERIODIC_RATE)
#endif
/* Set Client TCP connection timeout in seconds. */
#ifndef NX_SMTP_CLIENT_CONNECTION_TIMEOUT
#define NX_SMTP_CLIENT_CONNECTION_TIMEOUT (10 * NX_IP_PERIODIC_RATE)
#endif
/* Set Client TCP disconnect timeout in seconds. */
#ifndef NX_SMTP_CLIENT_DISCONNECT_TIMEOUT
#define NX_SMTP_CLIENT_DISCONNECT_TIMEOUT (5 * NX_IP_PERIODIC_RATE)
#endif
/* Set Client timeout in seconds for waiting for server reply to client greeting. */
#ifndef NX_SMTP_GREETING_TIMEOUT
#define NX_SMTP_GREETING_TIMEOUT (10 * NX_IP_PERIODIC_RATE)
#endif
/* Set Client 'envelope' timeout in seconds for waiting for server reply to client commands. */
#ifndef NX_SMTP_ENVELOPE_TIMEOUT
#define NX_SMTP_ENVELOPE_TIMEOUT (10 * NX_IP_PERIODIC_RATE)
#endif
/* Set Client timeout in seconds for waiting to receive server acceptance of client message data. */
#ifndef NX_SMTP_MESSAGE_TIMEOUT
#define NX_SMTP_MESSAGE_TIMEOUT (30 * NX_IP_PERIODIC_RATE)
#endif
/* Set timeout for TCP socket send completion. */
#ifndef NX_SMTP_CLIENT_SEND_TIMEOUT
#define NX_SMTP_CLIENT_SEND_TIMEOUT (5 * NX_IP_PERIODIC_RATE)
#endif
/* Define size for Client profile data. */
#ifndef NX_SMTP_CLIENT_MAX_USERNAME
#define NX_SMTP_CLIENT_MAX_USERNAME 40
#endif
#ifndef NX_SMTP_CLIENT_MAX_PASSWORD
#define NX_SMTP_CLIENT_MAX_PASSWORD 20
#endif
/* Define size of the buffer to extract the server challenge for authentication.
There is no specific size here so 200 bytes is sufficient to cover all digest string handling. */
#ifndef NX_SMTP_SERVER_CHALLENGE_MAX_STRING
#define NX_SMTP_SERVER_CHALLENGE_MAX_STRING 200
#endif
/* Define size for handling data for authentication (LOGIN, PLAIN):
PLAIN requires rooms for authorization-id\0authentication-id\0passwd'.
The two bytes are for the NULL byte between the first two auth id and
between auth id and password. */
#define NX_SMTP_CLIENT_AUTH_CHALLENGE_SIZE (NX_SMTP_CLIENT_MAX_USERNAME + NX_SMTP_CLIENT_MAX_USERNAME + NX_SMTP_CLIENT_MAX_PASSWORD + 2)
#define NX_SMTP_CLIENT_AUTH_CHALLENGE_ENCODED_SIZE (NX_SMTP_CLIENT_AUTH_CHALLENGE_SIZE * 4 / 3 + 1)
/* These define the states of the protocol state machine */
#define NX_SMTP_CLIENT_STATE_AWAITING_REPLY 0xFFFFFFFF /* Session state depends on outcome of current response handler. */
#define NX_SMTP_CLIENT_STATE_COMPLETED_NORMALLY 0xFFFFFFFE /* No internal errors, session completed normally. */
#define NX_SMTP_CLIENT_STATE_ERROR 0xFFFFFFFD /* Internal errors e.g. TCP send or receive fails; session terminated abnormally. */
#define NX_SMTP_INVALID_PARAM 0xA5 /* Invalid non pointer input in an SMTP service call */
#define NX_SMTP_INTERNAL_ERROR 0xA3 /* Internal processing error */
#define NX_SMTP_AUTHENTICATION_ERROR 0xA0 /* Invalid input for creating Client authentication. */
#define NX_SMTP_OVERSIZE_MAIL_DATA 0xA1 /* Mail message exceeds buffer size */
#define NX_SMTP_INVALID_SERVER_REPLY 0xA2 /* Unknown or invalid server reply */
#define NX_SMTP_SERVER_ERROR_CODE_RECEIVED 0xA4 /* Received an SMTP Server error code */
#define NX_SMTP_PACKET_ALLOCATE_ERROR 0xA6 /* Error allocating packet for SMTP message transmission */
#define NX_SMTP_GREET_REPLY_ERROR 0xA7 /* Error in response to Client SMTP GREET command */
#define NX_SMTP_HELLO_REPLY_ERROR 0xA8 /* Error in response to Client SMTP HELO or EHLO command */
#define NX_SMTP_MAIL_REPLY_ERROR 0xA9 /* Error in response to Client SMTP MAIL command */
#define NX_SMTP_RCPT_REPLY_ERROR 0xAA /* Error in response to Client SMTP RCPT command */
#define NX_SMTP_MESSAGE_REPLY_ERROR 0xAB /* Error in response to Client SMTP MESSAGE data sent */
#define NX_SMTP_DATA_REPLY_ERROR 0xAC /* Error in response to Client SMTP DATA command */
#define NX_SMTP_AUTH_REPLY_ERROR 0xAD /* Error in response to Client SMTP AUTH command */
#define NX_SMTP_SERVER_ERROR_REPLY 0xAE /* Error in parsing Server reply code (not found or unknown) */
#define NX_SMTP_TRANSMIT_ERROR 0xAF /* Error occurred during TCP packet transmission e.g. send queue full */
#define NX_SMTP_INVALID_SERVER_CHALLENGE 0xB0 /* Invalid server challenge (e.g. missing enclosing angle brackets). */
#define NX_SMTP_OVERSIZE_SERVER_REPLY 0xB1 /* Server reply exceeds client session buffer size */
#define NX_SMTP_CLIENT_NOT_INTIALIZED 0xB2 /* Client not created successfully e.g. socket create failed. Cannot transmit mail. */
/* Basic SMTP commands supported by this NetX SMTP API. */
#define NX_SMTP_COMMAND_EHLO "EHLO"
#define NX_SMTP_COMMAND_HELO "HELO"
#define NX_SMTP_COMMAND_MAIL "MAIL FROM"
#define NX_SMTP_COMMAND_RCPT "RCPT TO"
#define NX_SMTP_COMMAND_AUTH "AUTH"
#define NX_SMTP_COMMAND_NOOP "NOOP"
#define NX_SMTP_COMMAND_DATA "DATA"
#define NX_SMTP_COMMAND_RSET "RSET"
#define NX_SMTP_COMMAND_QUIT "QUIT"
/* List of common SMTP server reply codes */
#define NX_SMTP_CODE_GREETING_OK 220
#define NX_SMTP_CODE_ACKNOWLEDGE_QUIT 221
#define NX_SMTP_CODE_AUTHENTICATION_SUCCESSFUL 235
#define NX_SMTP_CODE_OK_TO_CONTINUE 250
#define NX_SMTP_CODE_CANNOT_VERIFY_RECIPIENT 252
#define NX_SMTP_CODE_AUTHENTICATION_TYPE_ACCEPTED 334
#define NX_SMTP_CODE_SEND_MAIL_INPUT 354
#define NX_SMTP_CODE_SERVICE_NOT_AVAILABLE 421
#define NX_SMTP_CODE_SERVICE_INTERNAL_SERVER_ERROR 451
#define NX_SMTP_CODE_INSUFFICIENT_STORAGE 452
#define NX_SMTP_CODE_AUTH_FAILED_INTERNAL_SERVER_ERROR 454
#define NX_SMTP_CODE_COMMAND_SYNTAX_ERROR 500
#define NX_SMTP_CODE_PARAMETER_SYNTAX_ERROR 501
#define NX_SMTP_CODE_COMMAND_NOT_IMPLEMENTED 502
#define NX_SMTP_CODE_BAD_SEQUENCE 503
#define NX_SMTP_CODE_PARAMETER_NOT_IMPLEMENTED 504
#define NX_SMTP_CODE_AUTH_REQUIRED 530
#define NX_SMTP_CODE_AUTH_FAILED 535
#define NX_SMTP_CODE_REQUESTED_ACTION_NOT_TAKEN 550
#define NX_SMTP_CODE_USER_NOT_LOCAL 551
#define NX_SMTP_CODE_OVERSIZE_MAIL_DATA 552
#define NX_SMTP_CODE_BAD_MAILBOX 553
#define NX_SMTP_CODE_TRANSACTION_FAILED 554
#define NX_SMTP_CODE_BAD_SERVER_CODE_RECEIVED 555
/* Common components of SMTP command messages */
#define NX_SMTP_LINE_TERMINATOR "\r\n"
#define NX_SMTP_EOM "\r\n.\r\n"
#define NX_SMTP_MESSAGE_ID "Message-ID"
#define NX_SMTP_TO_STRING "To: "
#define NX_SMTP_FROM_STRING "From: "
#define NX_SMTP_SUBJECT_STRING "Subject: "
#define NX_SMTP_MAIL_HEADER_COMPONENTS "MIME-Version: 1.0\r\n" \
"Content-Type: text/plain;\r\n" \
" charset=\"utf-8\"\r\n" \
"Content-Transfer-Encoding: 8bit\r\n" \
"\r\n"
/* Enumerated states of the protocol state machine. These MUST be in the
same order as the list of protocol states in NX_SMTP_CLIENT_STATES.*/
typedef enum NX_SMTP_CLIENT_STATE_ENUM
{
NX_SMTP_CLIENT_STATE_IDLE = 0,
NX_SMTP_CLIENT_STATE_GREETING, /*1*/
NX_SMTP_CLIENT_STATE_EHLO, /*2 */
NX_SMTP_CLIENT_STATE_HELO, /*3*/
NX_SMTP_CLIENT_STATE_MAIL, /*4*/
NX_SMTP_CLIENT_STATE_RCPT, /*5*/
NX_SMTP_CLIENT_STATE_DATA, /*6*/
NX_SMTP_CLIENT_STATE_MESSAGE, /*7*/
NX_SMTP_CLIENT_STATE_RSET, /*8*/
NX_SMTP_CLIENT_STATE_QUIT, /*9*/
NX_SMTP_CLIENT_STATE_NOOP, /*10 */
NX_SMTP_CLIENT_STATE_AUTH, /*11*/
NX_SMTP_CLIENT_STATE_AUTH_CHALLENGE /*12*/
} NX_SMTP_CLIENT_STATE;
/* Enumeration of common server challenges to the client */
#define NX_SMTP_CLIENT_REPLY_TO_UNKNOWN_PROMPT 1
#define NX_SMTP_CLIENT_REPLY_TO_USERNAME_PROMPT 2
#define NX_SMTP_CLIENT_REPLY_TO_PASSWORD_PROMPT 3
#define NX_SMTP_CLIENT_REPLY_SERVER_CHALLENGE_PROMPT 4
/* Common server challenges from the SMTP server. */
#define NX_SMTP_USERNAME_PROMPT "Username:"
#define NX_SMTP_PASSWORD_PROMPT "Password:"
/* ID for identifying as an SMTP client */
#define NX_SMTP_CLIENT_ID 0x534D5450UL
/* Define the character to cancel authentication process (RFC mandated). */
#define NX_SMTP_CANCEL_AUTHENTICATION "*"
/* Enumeration of the state of authentication between server and client */
typedef enum NX_SMTP_AUTHENTICATION_STATE_ENUM
{
NX_SMTP_NOT_AUTHENTICATED,
NX_SMTP_AUTHENTICATION_IN_PROGRESS,
NX_SMTP_AUTHENTICATION_FAILED,
NX_SMTP_AUTHENTICATION_SUCCEEDED
} NX_SMTP_AUTHENTICATION_STATE;
/* Defines for deciding priority of mail. */
#define NX_SMTP_MAIL_PRIORITY_LOW 0x01
#define NX_SMTP_MAIL_PRIORITY_NORMAL 0x02
#define NX_SMTP_MAIL_PRIORITY_HIGH 0x04
/* Defines for type of mail recipient. */
#define NX_SMTP_RECIPIENT_TO 0x01
#define NX_SMTP_RECIPIENT_CC 0x02
#define NX_SMTP_RECIPIENT_BCC 0x04
/* Define size of SMTP reply status codes (RFC mandated). */
#define NX_SMTP_SERVER_REPLY_CODE_SIZE 3
#define NX_SMTP_CLIENT_AUTH_NONE 0xFFFF
#define NX_SMTP_CLIENT_AUTH_LOGIN 1
#define NX_SMTP_CLIENT_AUTH_LOGIN_TEXT "AUTH LOGIN"
#define NX_SMTP_CLIENT_AUTH_CRAM_MD5 2
#define NX_SMTP_CLIENT_AUTH_CRAM_MD5_TEXT "AUTH CRAM-MD5"
#define NX_SMTP_CLIENT_AUTH_PLAIN 3
#define NX_SMTP_CLIENT_AUTH_PLAIN_TEXT "AUTH PLAIN"
/* Define the NetX SMTP RECIPIENT structure */
/* Define the NetX SMTP MAIL structure */
typedef struct NX_SMTP_CLIENT_MAIL_STRUCT
{
CHAR *nx_smtp_client_mail_recipient_address; /* Recipient's mailbox address */
CHAR *nx_smtp_client_mail_from_address; /* Sender's mailbox address. */
UINT nx_smtp_client_mail_priority; /* Mail item priority level */
CHAR *nx_smtp_client_mail_subject;
CHAR *nx_smtp_client_mail_body; /* Pointer to text of mail to send. */
UINT nx_smtp_client_mail_body_length; /* Size of mail buffer. */
} NX_SMTP_CLIENT_MAIL;
/* Define the SMTP client structure */
typedef struct NX_SMTP_CLIENT_STRUCT
{
ULONG nx_smtp_client_id; /* SMTP ID for identify client service. */
CHAR nx_smtp_username[NX_SMTP_CLIENT_MAX_USERNAME + 1]; /* Client name (may be used in authentication) */
CHAR nx_smtp_password[NX_SMTP_CLIENT_MAX_PASSWORD + 1]; /* Client password (used in authentication) */
CHAR nx_smtp_client_domain[NX_SMTP_CLIENT_MAX_USERNAME + 1]; /* Client domain of the client (and sender) */
UINT nx_smtp_client_authentication_type; /* Default Client authentication. */
NX_IP *nx_smtp_client_ip_ptr; /* Client IP instance */
NX_PACKET_POOL *nx_smtp_client_packet_pool_ptr; /* Client packet pool for sending data packets to the server */
NX_SMTP_CLIENT_MAIL nx_smtp_client_mail; /* Session mail is the collection of parameters required to create an SMTP mail message. */
UINT nx_smtp_client_init_status; /* If true SMTP client successfully created and ready for transmitting mail. */
NXD_ADDRESS nx_smtp_server_address; /* Server IP address (IPv4 or IPv6). */
USHORT nx_smtp_server_port; /* Server port. */
NX_TCP_SOCKET nx_smtp_client_socket; /* Client NetX TCP socket. */
UINT nx_smtp_client_cmd_state; /* Command state of the SMTP session. */
UINT nx_smtp_client_rsp_state; /* Response state of the SMTP session. */
UINT nx_smtp_client_reply_code_status; /* Reply code received from SMTP server. */
NX_PACKET *nx_smtp_server_packet; /* Packet containing server reply. */
UINT nx_smtp_client_authentication_reply; /* Buffer holding server reply text during authentication process */
NX_SMTP_AUTHENTICATION_STATE nx_smtp_client_authentication_state; /* State of the authentication process */
UINT nx_smtp_client_data_transparency_bytes; /* Extra bytes allowed for data transparency processing to add to message data. */
UINT nx_smtp_client_mail_status; /* Status of mail acceptance by the server */
UINT nx_smtp_client_mute; /* Mute command state; client waits for another packet in same SMTP state */
} NX_SMTP_CLIENT;
typedef struct NX_SMTP_CLIENT_STATES_STRUCT
{
UINT (*cmd) (NX_SMTP_CLIENT *client_ptr);
UINT (*rsp) (NX_SMTP_CLIENT *client_ptr);
} NX_SMTP_CLIENT_STATES;
#ifndef NX_SMTP_SOURCE_CODE
/* Define the system API mappings based on the error checking
selected by the user. */
/* Determine if error checking is desired. If so, map API functions
to the appropriate error checking front-ends. Otherwise, map API
functions to the core functions that actually perform the work.
Note: error checking is enabled by default. */
#ifdef NX_SMTP_DISABLE_ERROR_CHECKING
/* Services without error checking. */
#define nxd_smtp_client_create _nxd_smtp_client_create
#define nx_smtp_client_delete _nx_smtp_client_delete
#define nx_smtp_mail_send _nx_smtp_mail_send
#else
/* Services with error checking. */
#define nxd_smtp_client_create _nxde_smtp_client_create
#define nx_smtp_client_delete _nxe_smtp_client_delete
#define nx_smtp_mail_send _nxe_smtp_mail_send
#endif /* NX_SMTP_DISABLE_ERROR_CHECKING */
/* Define the prototypes accessible to the application software. */
UINT nxd_smtp_client_create(NX_SMTP_CLIENT *client_ptr, NX_IP *ip_ptr, NX_PACKET_POOL *client_packet_pool_ptr,
CHAR *username, CHAR *password, CHAR *from_address,
CHAR *client_domain, UINT authentication_type,
NXD_ADDRESS *server_address, UINT port);
UINT nx_smtp_client_delete (NX_SMTP_CLIENT *client_ptr);
UINT nx_smtp_mail_send(NX_SMTP_CLIENT *client_ptr, CHAR *recipient_address, UINT priority,
CHAR *subject, CHAR *mail_body, UINT mail_body_length);
#else /* NX_SMTP_SOURCE_CODE */
/* SMTP source code is being compiled, do not perform any API mapping. */
UINT _nxd_smtp_client_create(NX_SMTP_CLIENT *client_ptr, NX_IP *ip_ptr, NX_PACKET_POOL *client_packet_pool_ptr,
CHAR *username, CHAR *password, CHAR *from_address,
CHAR *client_domain, UINT authentication_type,
NXD_ADDRESS *server_address, UINT port);
UINT _nxde_smtp_client_create(NX_SMTP_CLIENT *client_ptr, NX_IP *ip_ptr, NX_PACKET_POOL *client_packet_pool_ptr,
CHAR *username, CHAR *password, CHAR *from_address,
CHAR *client_domain, UINT authentication_type,
NXD_ADDRESS *server_address, UINT port);
UINT _nx_smtp_client_delete (NX_SMTP_CLIENT *client_ptr);
UINT _nxe_smtp_client_delete (NX_SMTP_CLIENT *client_ptr);
UINT _nx_smtp_mail_send(NX_SMTP_CLIENT *client_ptr, CHAR *recipient_address, UINT priority,
CHAR *subject, CHAR *mail_body, UINT mail_body_length);
UINT _nxe_smtp_mail_send(NX_SMTP_CLIENT *client_ptr, CHAR *recipient_address, UINT priority,
CHAR *subject, CHAR *mail_body, UINT mail_body_length);
#endif /* NX_SMTP_SOURCE_CODE */
/* If a C++ compiler is being used....*/
#ifdef __cplusplus
}
#endif
#endif /* NXD_SMTP_CLIENT_H */
|