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