smtp-client
SMTP Client C Library
|
SMTP client library. More...
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "smtp.h"
Go to the source code of this file.
Data Structures | |
struct | smtp_address |
struct | smtp_attachment |
struct | smtp_header |
struct | smtp |
Macros | |
#define | SMTP_INTERNAL_DEFINE |
#define | SMTP_LINKAGE static |
#define | SMTP_GETDELIM_READ_SZ 1000 |
#define | SMTP_LINE_MAX 78 |
#define | SMTP_DATE_MAX_SZ (32 + 15) |
#define | SMTP_MIME_BOUNDARY_LEN 15 |
#define | SMTP_FLAG_INVALID_MEMORY (enum smtp_flag)(0xFFFFFFFF) |
Functions | |
SMTP_LINKAGE int | smtp_si_add_size_t (const size_t a, const size_t b, size_t *const result) |
SMTP_LINKAGE int | smtp_si_sub_size_t (const size_t a, const size_t b, size_t *const result) |
SMTP_LINKAGE int | smtp_si_mul_size_t (const size_t a, const size_t b, size_t *const result) |
static enum smtp_status_code | smtp_str_getdelimfd_read_timeout (struct smtp *const smtp) |
static long | smtp_str_getdelimfd_read (struct str_getdelimfd *const gdfd, void *buf, size_t count) |
static int | smtp_str_getdelimfd_search_delim (const char *const buf, size_t buf_len, int delim, size_t *const delim_pos) |
SMTP_LINKAGE int | smtp_str_getdelimfd_set_line_and_buf (struct str_getdelimfd *const gdfd, size_t copy_len) |
SMTP_LINKAGE void | smtp_str_getdelimfd_free (struct str_getdelimfd *const gdfd) |
static enum str_getdelim_retcode | smtp_str_getdelimfd_throw_error (struct str_getdelimfd *const gdfd) |
SMTP_LINKAGE enum str_getdelim_retcode | smtp_str_getdelimfd (struct str_getdelimfd *const gdfd) |
SMTP_LINKAGE char * | smtp_stpcpy (char *s1, const char *s2) |
SMTP_LINKAGE void * | smtp_reallocarray (void *ptr, size_t nmemb, size_t size) |
SMTP_LINKAGE char * | smtp_strdup (const char *s) |
SMTP_LINKAGE char * | smtp_str_replace (const char *const search, const char *const replace, const char *const s) |
static void | smtp_base64_encode_block (const char *const buf, size_t buf_block_sz, char *const b64) |
SMTP_LINKAGE char * | smtp_base64_encode (const char *const buf, size_t buflen) |
static size_t | smtp_base64_decode_block (const unsigned char *const buf, unsigned char *const decode) |
SMTP_LINKAGE size_t | smtp_base64_decode (const char *const buf, unsigned char **decode) |
SMTP_LINKAGE char * | smtp_bin2hex (const unsigned char *const s, size_t slen) |
SMTP_LINKAGE size_t | smtp_utf8_charlen (char c) |
SMTP_LINKAGE int | smtp_str_has_nonascii_utf8 (const char *const s) |
SMTP_LINKAGE size_t | smtp_strnlen_utf8 (const char *s, size_t maxlen) |
SMTP_LINKAGE size_t | smtp_fold_whitespace_get_offset (const char *const s, unsigned int maxlen) |
SMTP_LINKAGE char * | smtp_fold_whitespace (const char *const s, unsigned int maxlen) |
SMTP_LINKAGE char * | smtp_chunk_split (const char *const s, size_t chunklen, const char *const end) |
SMTP_LINKAGE char * | smtp_ffile_get_contents (FILE *stream, size_t *bytes_read) |
SMTP_LINKAGE char * | smtp_file_get_contents (const char *const filename, size_t *bytes_read) |
SMTP_LINKAGE int | smtp_parse_cmd_line (char *const line, struct smtp_command *const cmd) |
static void | smtp_puts_dbg (struct smtp *const smtp, const char *const prefix, const char *const str) |
static enum str_getdelim_retcode | smtp_getline (struct smtp *const smtp) |
static int | smtp_read_and_parse_code (struct smtp *const smtp) |
SMTP_LINKAGE enum smtp_status_code | smtp_write (struct smtp *const smtp, const char *const buf, size_t len) |
static enum smtp_status_code | smtp_puts (struct smtp *const smtp, const char *const s) |
static enum smtp_status_code | smtp_puts_terminate (struct smtp *const smtp, const char *const s) |
static int | smtp_connect (struct smtp *const smtp, const char *const server, const char *const port) |
static int | smtp_tls_init (struct smtp *const smtp, const char *const server) |
static enum smtp_status_code | smtp_ehlo (struct smtp *const smtp) |
static int | smtp_auth_plain (struct smtp *const smtp, const char *const user, const char *const pass) |
static int | smtp_auth_login (struct smtp *const smtp, const char *const user, const char *const pass) |
static int | smtp_auth_cram_md5 (struct smtp *const smtp, const char *const user, const char *const pass) |
static void | smtp_set_read_timeout (struct smtp *const smtp, long seconds) |
static enum smtp_status_code | smtp_initiate_handshake (struct smtp *const smtp, const char *const server, enum smtp_connection_security connection_security) |
SMTP_LINKAGE int | smtp_date_rfc_2822 (char *const date) |
static int | smtp_header_cmp_key (const void *const v1, const void *const v2) |
static int | smtp_header_exists (const struct smtp *const smtp, const char *const key) |
static void | smtp_gen_mime_boundary (char *const boundary) |
static enum smtp_status_code | smtp_print_mime_header_and_body (struct smtp *const smtp, const char *const boundary, const char *const body_dd) |
static enum smtp_status_code | smtp_print_mime_attachment (struct smtp *const smtp, const char *const boundary, const struct smtp_attachment *const attachment) |
static enum smtp_status_code | smtp_print_mime_end (struct smtp *const smtp, const char *const boundary) |
static enum smtp_status_code | smtp_print_mime_email (struct smtp *const smtp, const char *const body_dd) |
static enum smtp_status_code | smtp_print_nomime_email (struct smtp *const smtp, const char *const body_dd) |
static enum smtp_status_code | smtp_print_email (struct smtp *const smtp, const char *const body) |
static enum smtp_status_code | smtp_print_header (struct smtp *const smtp, const struct smtp_header *const header) |
static enum smtp_status_code | smtp_append_address_to_header (struct smtp *const smtp, enum smtp_address_type address_type, const char *const key) |
static enum smtp_status_code | smtp_mail_envelope_header (struct smtp *const smtp, const char *const header, const struct smtp_address *const address) |
static int | smtp_header_cmp (const void *v1, const void *v2) |
SMTP_LINKAGE int | smtp_header_key_validate (const char *const key) |
SMTP_LINKAGE int | smtp_header_value_validate (const char *const value) |
SMTP_LINKAGE int | smtp_address_validate_email (const char *const email) |
SMTP_LINKAGE int | smtp_address_validate_name (const char *const name) |
SMTP_LINKAGE int | smtp_attachment_validate_name (const char *const name) |
enum smtp_status_code | smtp_open (const char *const server, const char *const port, enum smtp_connection_security connection_security, enum smtp_flag flags, const char *const cafile, struct smtp **smtp) |
enum smtp_status_code | smtp_auth (struct smtp *const smtp, enum smtp_authentication_method auth_method, const char *const user, const char *const pass) |
enum smtp_status_code | smtp_mail (struct smtp *const smtp, const char *const body) |
enum smtp_status_code | smtp_close (struct smtp *smtp) |
enum smtp_status_code | smtp_status_code_get (const struct smtp *const smtp) |
enum smtp_status_code | smtp_status_code_clear (struct smtp *const smtp) |
enum smtp_status_code | smtp_status_code_set (struct smtp *const smtp, enum smtp_status_code status_code) |
const char * | smtp_status_code_errstr (enum smtp_status_code status_code) |
enum smtp_status_code | smtp_header_add (struct smtp *const smtp, const char *const key, const char *const value) |
void | smtp_header_clear_all (struct smtp *const smtp) |
enum smtp_status_code | smtp_address_add (struct smtp *const smtp, enum smtp_address_type type, const char *const email, const char *const name) |
void | smtp_address_clear_all (struct smtp *const smtp) |
enum smtp_status_code | smtp_attachment_add_path (struct smtp *const smtp, const char *const name, const char *const path) |
enum smtp_status_code | smtp_attachment_add_fp (struct smtp *const smtp, const char *const name, FILE *fp) |
enum smtp_status_code | smtp_attachment_add_mem (struct smtp *const smtp, const char *const name, const void *const data, size_t datasz) |
void | smtp_attachment_clear_all (struct smtp *const smtp) |
Variables | |
static char | g_base64_encode_table [] |
static signed char | g_base64_decode_table [] |
static struct smtp | g_smtp_error |
SMTP client library.
This SMTP client library allows the user to send emails to an SMTP server. The user can include custom headers and MIME attachments.
This software has been placed into the public domain using CC0.
Definition in file smtp.c.
#define SMTP_DATE_MAX_SZ (32 + 15) |
Maximum size of an RFC 2822 date string.
Thu, 21 May 1998 05:33:29 -0700 12345678901234567890123456789012 10 20 30 32 (bytes)
Add more bytes to the 32 maximum size to silence compiler warning on the computed UTF offset.
Definition at line 2222 of file smtp.c.
Referenced by smtp_date_rfc_2822(), and smtp_mail().
#define SMTP_FLAG_INVALID_MEMORY (enum smtp_flag)(0xFFFFFFFF) |
Special flag value for the SMTP context used to determine if the initial memory allocation failed to create the context.
Definition at line 2945 of file smtp.c.
Referenced by smtp_close().
#define SMTP_GETDELIM_READ_SZ 1000 |
Increment the read buffer size by this amount if the delimiter has not been found.
Definition at line 88 of file smtp.c.
Referenced by smtp_str_getdelimfd().
#define SMTP_INTERNAL_DEFINE |
Get access to the smtp_result_code and smtp_command definitions.
#define SMTP_LINE_MAX 78 |
Email header lines should have no more than 78 characters and must not be more than 998 characters.
Definition at line 1218 of file smtp.c.
Referenced by smtp_attachment_add_mem(), and smtp_print_header().
#define SMTP_LINKAGE static |
When not testing, all functions should have static linkage except for those in the header.
Definition at line 81 of file smtp.c.
Referenced by smtp_address_validate_email(), smtp_address_validate_name(), smtp_base64_decode(), smtp_base64_decode_block(), smtp_base64_encode_block(), smtp_bin2hex(), smtp_chunk_split(), smtp_ffile_get_contents(), smtp_file_get_contents(), smtp_fold_whitespace(), smtp_header_cmp(), smtp_header_key_validate(), smtp_header_value_validate(), smtp_read_and_parse_code(), smtp_reallocarray(), smtp_si_add_size_t(), smtp_si_sub_size_t(), smtp_stpcpy(), smtp_str_getdelimfd(), smtp_str_getdelimfd_search_delim(), smtp_str_getdelimfd_set_line_and_buf(), smtp_str_getdelimfd_throw_error(), smtp_str_has_nonascii_utf8(), smtp_strdup(), smtp_strnlen_utf8(), and smtp_utf8_charlen().
#define SMTP_MIME_BOUNDARY_LEN 15 |
Minimum length of buffer required to hold the MIME boundary test: mimeXXXXXXXXXX 123456789012345 1 10 15 bytes
Definition at line 2370 of file smtp.c.
Referenced by smtp_gen_mime_boundary(), smtp_print_mime_attachment(), smtp_print_mime_email(), and smtp_print_mime_end().
enum smtp_status_code smtp_address_add | ( | struct smtp *const | smtp, |
enum smtp_address_type | type, | ||
const char *const | email, | ||
const char *const | name | ||
) |
Add a FROM, TO, CC, or BCC address destination to this SMTP context.
[in] | smtp | SMTP client context. |
[in] | type | See smtp_address_type. |
[in] | The email address of the party. Must consist only of printable characters excluding the angle brackets (<) and (>). | |
[in] | name | Name or description of the party. Must consist only of printable characters, excluding the quote characters. If set to NULL or empty string, no name will get associated with this email. |
Definition at line 3347 of file smtp.c.
References smtp::address_list, smtp_address::email, smtp_address::name, smtp::num_address, smtp_address_validate_email(), smtp_address_validate_name(), smtp_reallocarray(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, SMTP_STATUS_OK, SMTP_STATUS_PARAM, smtp_strdup(), smtp::status_code, and smtp_address::type.
Referenced by SMTPMail::address_add(), mailx_send(), smtp_address_add_check(), and test_nossl_smtp().
void smtp_address_clear_all | ( | struct smtp *const | smtp | ) |
Free all memory related to the address list.
[in] | smtp | SMTP client context. |
Definition at line 3401 of file smtp.c.
References smtp::address_list, smtp_address::email, smtp_address::name, and smtp::num_address.
Referenced by SMTPMail::address_clear_all(), smtp_close(), smtp_func_test_all_address(), and smtp_func_test_all_names().
SMTP_LINKAGE int smtp_address_validate_email | ( | const char *const | ) |
Validate characters in the email address.
The email address must consist only of printable characters excluding the angle brackets (<) and (>).
[in] | The email address of the party. |
0 | Successful validation. |
-1 | Failed to validate. |
Definition at line 2878 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_address_add(), and smtp_unit_test_all_smtp_address_validate_email().
SMTP_LINKAGE int smtp_address_validate_name | ( | const char *const | name | ) |
Validate characters in the email name.
Email user name must consist only of printable characters, excluding the double quote character.
[in] | name | Email name to validate. |
0 | Successful validation. |
-1 | Failed to validate. |
Definition at line 2903 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_address_add(), and smtp_unit_test_all_smtp_address_validate_name().
|
static |
Take a FROM, TO, and CC address and add it into the email header list.
The following example shows what the final header might look like when the client sends an email to two CC addresses: Cc: mail1@example.com, mail2@example.com
[in] | smtp | SMTP client context. |
[in] | address_type | See smtp_address_type. |
[in] | key | Header key value, for example, To From Cc. |
Definition at line 2674 of file smtp.c.
References smtp::address_list, smtp_address::email, smtp_address::name, smtp::num_address, realloc, smtp_header_add(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_stpcpy(), smtp::status_code, strlen, and smtp_address::type.
Referenced by smtp_mail().
enum smtp_status_code smtp_attachment_add_fp | ( | struct smtp *const | smtp, |
const char *const | name, | ||
FILE * | fp | ||
) |
Add an attachment using a file pointer.
See smtp_attachment_add_mem for more details.
[in] | smtp | SMTP client context. |
[in] | name | Filename of the attachment shown to recipients. Must consist only of printable ASCII characters, excluding the quote characters (') and ("). |
[in] | fp | File pointer already opened by the caller. |
Definition at line 3439 of file smtp.c.
References smtp_attachment_add_mem(), smtp_ffile_get_contents(), smtp_status_code_set(), SMTP_STATUS_FILE, SMTP_STATUS_NOMEM, SMTP_STATUS_OK, and smtp::status_code.
Referenced by SMTPMail::attachment_add_fp(), smtp_func_test_attachment_fp(), and test_failure_attachment_add().
enum smtp_status_code smtp_attachment_add_mem | ( | struct smtp *const | smtp, |
const char *const | name, | ||
const void *const | data, | ||
size_t | datasz | ||
) |
Add a MIME attachment to this SMTP context with the data retrieved from memory.
The attachment data will get base64 encoded before sending to the server.
[in] | smtp | SMTP client context. |
[in] | name | Filename of the attachment shown to recipients. Must consist only of printable ASCII characters, excluding the quote characters (') and ("). |
[in] | data | Raw attachment data stored in memory. |
[in] | datasz | Number of bytes in data , or -1 if data null-terminated. |
Definition at line 3462 of file smtp.c.
References smtp::attachment_list, smtp_attachment::b64_data, smtp_attachment::name, smtp::num_attachment, SIZE_MAX, smtp_attachment_validate_name(), smtp_base64_encode(), smtp_chunk_split(), SMTP_LINE_MAX, smtp_reallocarray(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, SMTP_STATUS_OK, SMTP_STATUS_PARAM, smtp_strdup(), smtp::status_code, and strlen.
Referenced by SMTPMail::attachment_add_mem(), smtp_attachment_add_fp(), smtp_attachment_add_path(), smtp_func_test_attachment_long_text(), smtp_func_test_attachment_mem(), test_failure_attachment_add(), and test_smtp_open_default().
enum smtp_status_code smtp_attachment_add_path | ( | struct smtp *const | smtp, |
const char *const | name, | ||
const char *const | path | ||
) |
Add a file attachment from a path.
See smtp_attachment_add_mem for more details.
[in] | smtp | SMTP client context. |
[in] | name | Filename of the attachment shown to recipients. Must consist only of printable ASCII characters, excluding the quote characters (') and ("). |
[in] | path | Path to file. |
Definition at line 3416 of file smtp.c.
References smtp_attachment_add_mem(), smtp_file_get_contents(), smtp_status_code_set(), SMTP_STATUS_FILE, SMTP_STATUS_NOMEM, SMTP_STATUS_OK, and smtp::status_code.
Referenced by SMTPMail::attachment_add_path(), mailx_send(), smtp_func_test_attachment_path(), smtp_func_test_attachment_pdf(), smtp_func_test_gmail_attachment(), and test_failure_attachment_add().
void smtp_attachment_clear_all | ( | struct smtp *const | smtp | ) |
Remove all attachments from the SMTP client context.
[in] | smtp | SMTP client context. |
Definition at line 3515 of file smtp.c.
References smtp::attachment_list, smtp_attachment::b64_data, smtp_attachment::name, and smtp::num_attachment.
Referenced by SMTPMail::attachment_clear_all(), and smtp_close().
SMTP_LINKAGE int smtp_attachment_validate_name | ( | const char *const | name | ) |
Validate characters in the attachment file name.
Must consist only of printable characters or the space character ( ), and excluding the quote characters (') and (").
[in] | name | Filename of the attachment shown to recipients. |
0 | Successful validation. |
-1 | Failed to validate. |
Definition at line 2927 of file smtp.c.
Referenced by smtp_attachment_add_mem(), and smtp_unit_test_all_smtp_attachment_validate_name().
enum smtp_status_code smtp_auth | ( | struct smtp *const | smtp, |
enum smtp_authentication_method | auth_method, | ||
const char *const | user, | ||
const char *const | pass | ||
) |
Authenticate the user using one of the methods listed in smtp_authentication_method.
[in] | smtp | SMTP client context. |
[in] | auth_method | See smtp_authentication_method. |
[in] | user | SMTP user name. |
[in] | pass | SMTP password. |
Definition at line 3026 of file smtp.c.
References SMTP_AUTH_CRAM_MD5, smtp_auth_cram_md5(), SMTP_AUTH_LOGIN, smtp_auth_login(), SMTP_AUTH_NONE, SMTP_AUTH_PLAIN, smtp_auth_plain(), SMTP_STATUS_AUTH, smtp_status_code_set(), SMTP_STATUS_OK, SMTP_STATUS_PARAM, and smtp::status_code.
Referenced by SMTPMail::auth(), mailx_send(), and smtp_auth_check().
|
static |
Authenticate using the CRAM-MD5 method.
[in] | smtp | SMTP client context. |
[in] | user | SMTP account user name. |
[in] | pass | SMTP account password. |
0 | Successfully authenticated. |
-1 | Failed to authenticate. |
Definition at line 2037 of file smtp.c.
References smtp::gdfd, HMAC, str_getdelimfd::line, malloc, SIZE_MAX, SMTP_AUTH_CONTINUE, SMTP_AUTH_SUCCESS, smtp_base64_decode(), smtp_base64_encode(), smtp_bin2hex(), smtp_getline(), smtp_parse_cmd_line(), smtp_puts(), smtp_puts_terminate(), smtp_read_and_parse_code(), smtp_si_add_size_t(), SMTP_STATUS_OK, smtp_stpcpy(), smtp::status_code, STRING_GETDELIMFD_ERROR, strlen, and smtp_command::text.
Referenced by smtp_auth().
|
static |
Authenticate using the LOGIN method.
[in] | smtp | SMTP client context. |
[in] | user | SMTP account user name. |
[in] | pass | SMTP account password. |
0 | Successfully authenticated. |
-1 | Failed to authenticate. |
Definition at line 1966 of file smtp.c.
References malloc, SIZE_MAX, SMTP_AUTH_CONTINUE, SMTP_AUTH_SUCCESS, smtp_base64_encode(), smtp_puts(), smtp_puts_terminate(), smtp_read_and_parse_code(), smtp_si_add_size_t(), SMTP_STATUS_OK, smtp_stpcpy(), smtp::status_code, and strlen.
Referenced by smtp_auth().
|
static |
Authenticate using the PLAIN method.
[in] | smtp | SMTP client context. |
[in] | user | SMTP account user name. |
[in] | pass | SMTP account password. |
0 | Successfully authenticated. |
-1 | Failed to authenticate. |
Definition at line 1893 of file smtp.c.
References malloc, SMTP_AUTH_SUCCESS, smtp_base64_encode(), smtp_puts(), smtp_read_and_parse_code(), smtp_si_add_size_t(), SMTP_STATUS_OK, smtp_stpcpy(), smtp::status_code, and strlen.
Referenced by smtp_auth().
SMTP_LINKAGE size_t smtp_base64_decode | ( | const char *const | buf, |
unsigned char ** | decode | ||
) |
Decode a base64 string.
The decode parameter will get dynamically allocated by this function if it successfully completes. Therefore, the caller must free the decode parameter after use.
[in] | buf | Null-terminated base64 string. |
[out] | decode | Pointer to buffer which will get dynamically allocated and will contain the decoded binary data. This parameter will get set to NULL if the memory allocation fails. |
>=0 | Length of the data stored in the decode parameter. |
-1 | Memory allocation failure or invalid base64 byte sequences. |
Definition at line 984 of file smtp.c.
References calloc, SIZE_MAX, smtp_base64_decode_block(), SMTP_LINKAGE, smtp_si_add_size_t(), and strlen.
Referenced by smtp_auth_cram_md5(), and smtp_unit_test_base64_decode().
|
static |
Decodes a base64 block of up to four bytes at a time.
[in] | buf | Buffer containing bytes to decode. |
[out] | decode | Buffer for storing base64 decoded bytes. |
>0 | Length of the decoded block. |
0 | If the block contains invalid base64 data. |
Definition at line 924 of file smtp.c.
References g_base64_decode_table, and SMTP_LINKAGE.
Referenced by smtp_base64_decode().
SMTP_LINKAGE char* smtp_base64_encode | ( | const char *const | buf, |
size_t | buflen | ||
) |
Encode binary data into a base64 string.
[in] | buf | Binary data to encode in base64. |
[in] | buflen | Number of bytes in the buf parameter, or -1 if null-terminated. |
char* | Dynamically allocated base64 encoded string. The caller must free this string when finished. |
NULL | Memory allocation failure. |
Definition at line 825 of file smtp.c.
References calloc, SIZE_MAX, smtp_base64_encode_block(), smtp_si_mul_size_t(), and strlen.
Referenced by smtp_attachment_add_mem(), smtp_auth_cram_md5(), smtp_auth_login(), smtp_auth_plain(), and smtp_unit_test_base64_encode().
|
static |
Encode a single block of binary data into base64.
[in] | buf | Buffer with data to encode. |
[in] | buf_block_sz | Number of bytes in buf to encode (min 1, max 3). |
[out] | b64 | Pointer to buffer with at least 4 bytes for storing the base64 encoded result. |
Definition at line 792 of file smtp.c.
References g_base64_encode_table, and SMTP_LINKAGE.
Referenced by smtp_base64_encode().
SMTP_LINKAGE char* smtp_bin2hex | ( | const unsigned char *const | s, |
size_t | slen | ||
) |
Convert binary data to lowercase hexadecimal representation.
[in] | s | Buffer containing binary data to convert. |
[in] | slen | Number of bytes in s . |
char* | Dynamically allocated string consisting of a hexadecimal representation of binary data in s . The caller must free this memory when finished. |
NULL | Memory allocation or encoding error. |
Definition at line 1031 of file smtp.c.
References malloc, SMTP_LINKAGE, smtp_si_add_size_t(), smtp_si_mul_size_t(), and sprintf.
Referenced by smtp_auth_cram_md5(), and smtp_unit_test_bin2hex().
SMTP_LINKAGE char* smtp_chunk_split | ( | const char *const | s, |
size_t | chunklen, | ||
const char *const | end | ||
) |
Splits a string into smaller chunks separated by a terminating string.
[in] | s | The string to chunk. |
[in] | chunklen | Number of bytes for each chunk in the string. |
[in] | end | Terminating string placed at the end of each chunk. |
char* | Pointer to an allocated string with the contents split into separate chunks. The caller must free this memory when done. |
NULL | Memory allocation failure. |
Definition at line 1312 of file smtp.c.
References calloc, SIZE_MAX, SMTP_LINKAGE, smtp_si_add_size_t(), smtp_si_mul_size_t(), smtp_strdup(), smtp_strnlen_utf8(), and strlen.
Referenced by smtp_attachment_add_mem(), and smtp_unit_test_chunk_split().
enum smtp_status_code smtp_close | ( | struct smtp * | smtp | ) |
Close the SMTP connection and frees all resources held by the SMTP context.
[in] | smtp | SMTP client context. |
Definition at line 3168 of file smtp.c.
References close, smtp::flags, smtp::gdfd, smtp_address_clear_all(), smtp_attachment_clear_all(), SMTP_FLAG_INVALID_MEMORY, smtp_header_clear_all(), smtp_puts(), SMTP_STATUS_CLOSE, smtp_status_code_set(), SMTP_STATUS_OK, smtp_str_getdelimfd_free(), smtp::sock, smtp::status_code, smtp::tls, smtp::tls_ctx, and smtp::tls_on.
Referenced by SMTPMail::close(), mailx_send(), smtp_close_check(), smtp_func_test_server_secureserver(), and test_nossl_smtp().
|
static |
Connect to the server using a standard TCP socket.
This function handles the server name lookup to get an IP address for the server, and then to connect to that IP using a normal TCP connection.
[in] | smtp | SMTP client context. |
[in] | server | Mail server name or IP address. |
[in] | port | Mail server port number. |
0 | Successfully connected to server. |
-1 | Failed to connect to server. |
Definition at line 1703 of file smtp.c.
References close, connect, smtp::sock, and socket.
Referenced by smtp_open().
SMTP_LINKAGE int smtp_date_rfc_2822 | ( | char *const | date | ) |
Convert the time into an RFC 2822 formatted string.
Example date format: Thu, 21 May 1998 05:33:29 -0700
[out] | date | Buffer that has at least SMTP_DATE_MAX_SZ bytes. |
0 | Successfully copied the current date to the buffer. |
-1 | Failed to establish the current date or an output format error occurred. |
Definition at line 2236 of file smtp.c.
References gmtime_r, localtime_r, mktime, SMTP_DATE_MAX_SZ, sprintf, and time.
Referenced by smtp_mail(), and smtp_unit_test_date_rfc_2822().
|
static |
Send the EHLO command and parse through the responses.
Ignores all of the server extensions that get returned. If a server doesn't support an extension we need, then we should receive an error later on when we try to use that extension.
[in] | smtp | SMTP client context. |
Definition at line 1870 of file smtp.c.
References smtp_puts(), smtp_read_and_parse_code(), SMTP_STATUS_OK, and smtp::status_code.
Referenced by smtp_initiate_handshake().
SMTP_LINKAGE char* smtp_ffile_get_contents | ( | FILE * | stream, |
size_t * | bytes_read | ||
) |
Read the entire contents of a file stream and store the data into a dynamically allocated buffer.
[in] | stream | File stream already opened by the caller. |
[out] | bytes_read | Number of bytes stored in the return buffer. |
char* | A dynamically allocated buffer which contains the entire contents of stream . The caller must free this memory when done. |
NULL | Memory allocation or file read error. |
Definition at line 1386 of file smtp.c.
References ferror, realloc, SMTP_LINKAGE, and smtp_si_add_size_t().
Referenced by smtp_attachment_add_fp(), and smtp_file_get_contents().
SMTP_LINKAGE char* smtp_file_get_contents | ( | const char *const | filename, |
size_t * | bytes_read | ||
) |
Read the entire contents of a file from a given path, and store the data into a dynamically allocated buffer.
[in] | filename | Path of file to open and read from. |
[out] | bytes_read | Number of bytes stored in the return buffer. |
char* | A dynamically allocated buffer which has the contents of the file at filename . The caller must free this memory when done. |
NULL | Memory allocation or file read error. |
Definition at line 1439 of file smtp.c.
References fclose, smtp_ffile_get_contents(), and SMTP_LINKAGE.
Referenced by smtp_attachment_add_path(), smtp_test_config_load_from_file(), smtp_unit_test_all_file_get_contents(), and smtp_unit_test_file_get_contents().
SMTP_LINKAGE char* smtp_fold_whitespace | ( | const char *const | s, |
unsigned int | maxlen | ||
) |
Fold a line at whitespace characters.
This function tries to keep the total number of characters per line under maxlen
, but does not guarantee this. For really long text with no whitespace, the line will still extend beyond maxlen
and possibly beyond the RFC limit as defined in SMTP_LINE_MAX. This is by design and intended to keep the algorithm simpler to implement. Users sending long headers with no space characters should not assume that will work, but modern email systems may correctly process those headers anyways.
Lines get folded by adding a [CR][LF] and then two space characters on the beginning of the next line. For example, this Subject line:
Subject: Email[WS][WS]Header
Would get folded like this (assuming a small maxlen
):
Subject: Email[WS][CR][LF] [WS][WS]Header
[in] | s | String to fold. |
[in] | maxlen | Number of bytes for each line in the string (soft limit). The minimum value of this parameter is 3 and it will get forced to 3 if the provided value is less. |
char* | Pointer to an allocated string with the contents split into separate lines. The caller must free this memory when done. |
NULL | Memory allocation failed. |
Definition at line 1250 of file smtp.c.
References realloc, smtp_fold_whitespace_get_offset(), SMTP_LINKAGE, smtp_si_add_size_t(), and strlen.
Referenced by smtp_print_header(), and smtp_unit_test_fold_whitespace().
SMTP_LINKAGE size_t smtp_fold_whitespace_get_offset | ( | const char *const | s, |
unsigned int | maxlen | ||
) |
Get the offset of the next whitespace block to process folding.
If a string does not have whitespace before maxlen
, then the index will get returned past maxlen
. Also returns the index of NULL character if that fits within the next block. The caller must check for the NULL index to indicate the last block. It will skip past any leading whitespace even if that means going over maxlen.
Examples: smtp_fold_whitespace_get_offset ("Subject: Test WS", 1/2/8/9/10/13) -> 8 smtp_fold_whitespace_get_offset ("Subject: Test WS", 14/15) -> 13 smtp_fold_whitespace_get_offset ("Subject: Test WS", 17/18) -> 16
[in] | s | String to get offset from. |
[in] | maxlen | Number of bytes for each line in the string (soft limit). |
s
. Definition at line 1179 of file smtp.c.
Referenced by smtp_fold_whitespace(), and smtp_unit_test_fold_whitespace_get_offset().
|
static |
Generate the MIME boundary text field and store it in a user-supplied buffer.
For example: mimeXXXXXXXXXX where each X gets set to a pseudo-random uppercase ASCII character.
This uses a simple pseudo-random number generator since we only care about preventing accidental boundary collisions.
[out] | boundary | Buffer that has at least SMTP_MIME_BOUNDARY_LEN bytes. |
Definition at line 2386 of file smtp.c.
References SMTP_MIME_BOUNDARY_LEN, and time.
Referenced by smtp_print_mime_email().
|
static |
Read a server response line.
[in] | smtp | SMTP client context. |
Definition at line 1544 of file smtp.c.
References smtp::gdfd, str_getdelimfd::line, str_getdelimfd::line_len, smtp_puts_dbg(), smtp_status_code_set(), SMTP_STATUS_NOMEM, SMTP_STATUS_RECV, smtp_str_getdelimfd(), and STRING_GETDELIMFD_ERROR.
Referenced by smtp_auth_cram_md5(), smtp_initiate_handshake(), and smtp_read_and_parse_code().
enum smtp_status_code smtp_header_add | ( | struct smtp *const | smtp, |
const char *const | key, | ||
const char *const | value | ||
) |
Add a key/value header to the header list in the SMTP context.
If adding a header with an existing key, this will insert instead of replacing the existing header. See smtp_header_clear_all.
See smtp_mail when overriding the default 'Content-Type' header.
[in] | smtp | SMTP client context. |
[in] | key | Key name for new header. It must consist only of printable US-ASCII characters except colon. |
[in] | value | Value for new header. It must consist only of printable US-ASCII, space, or horizontal tab. If set to NULL, this will prevent the header from printing out. |
Definition at line 3278 of file smtp.c.
References smtp::header_list, smtp_header::key, smtp::num_headers, smtp_header_cmp(), smtp_header_key_validate(), smtp_header_value_validate(), smtp_reallocarray(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, SMTP_STATUS_OK, SMTP_STATUS_PARAM, smtp_strdup(), smtp::status_code, and smtp_header::value.
Referenced by SMTPMail::header_add(), mailx_send(), smtp_append_address_to_header(), smtp_header_add_check(), smtp_mail(), and test_nossl_smtp().
void smtp_header_clear_all | ( | struct smtp *const | smtp | ) |
Free all memory related to email headers.
[in] | smtp | SMTP client context. |
Definition at line 3332 of file smtp.c.
References smtp::header_list, smtp_header::key, smtp::num_headers, and smtp_header::value.
Referenced by SMTPMail::header_clear_all(), smtp_close(), smtp_func_test_all_address(), smtp_func_test_all_names(), smtp_func_test_all_nodebug(), smtp_func_test_header_custom_date(), smtp_func_test_header_long(), smtp_func_test_header_null_no_date(), smtp_func_test_html(), and smtp_func_test_html_with_plaintext().
|
static |
Comparison function for qsort which sorts headers alphabetically based on the key.
[in] | v1 | The first smtp_header to compare. |
[in] | v2 | The second smtp_header to compare. |
0 | If the keys match. |
!0 | If the keys do not match. |
Definition at line 2802 of file smtp.c.
References smtp_header::key, and SMTP_LINKAGE.
Referenced by smtp_header_add().
|
static |
Search function used by bsearch, allowing the caller to check for headers with existing keys.
v1 | String to search for in the list. |
v2 | The smtp_header to compare. |
0 | If the keys match. |
!0 | If the keys do not match. |
Definition at line 2333 of file smtp.c.
References smtp_header::key.
Referenced by smtp_header_exists().
|
static |
Determine if the header key has already been defined in this context.
[in] | smtp | SMTP client context. |
[in] | key | Header key value to search for. |
1 | If the header already exists in this context. |
0 | If the header does not exist in this context. |
Definition at line 2352 of file smtp.c.
References smtp::header_list, smtp::num_headers, and smtp_header_cmp_key().
Referenced by smtp_mail(), and smtp_print_email().
SMTP_LINKAGE int smtp_header_key_validate | ( | const char *const | key | ) |
Validate characters in the email header key.
Must consist only of printable US-ASCII characters except colon.
[in] | key | Header key to validate. |
0 | Successful validation. |
-1 | Failed to validate. |
Definition at line 2822 of file smtp.c.
References SMTP_LINKAGE, and strlen.
Referenced by smtp_header_add(), and smtp_unit_test_all_smtp_header_key_validate().
SMTP_LINKAGE int smtp_header_value_validate | ( | const char *const | value | ) |
Validate characters in the email header contents.
Must consist only of printable character, space, or horizontal tab.
[in] | value | Header value to validate. |
0 | Successful validation. |
-1 | Failed to validate. |
Definition at line 2852 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_header_add(), and smtp_unit_test_all_smtp_header_value_validate().
|
static |
Perform a handshake with the SMTP server which includes optionally setting up TLS and sending the EHLO greeting.
At this point, the client has already connected to the SMTP server through its socket connection. In this function, the client will:
[in] | smtp | SMTP client context. |
[in] | server | Server name or IP address. |
[in] | connection_security | See smtp_connection_security. |
Definition at line 2161 of file smtp.c.
References smtp_ehlo(), smtp_getline(), smtp_puts(), smtp_read_and_parse_code(), SMTP_READY, SMTP_SECURITY_STARTTLS, SMTP_SECURITY_TLS, smtp_set_read_timeout(), smtp_status_code_set(), SMTP_STATUS_HANDSHAKE, SMTP_STATUS_OK, smtp_tls_init(), smtp::status_code, and STRING_GETDELIMFD_ERROR.
Referenced by smtp_open().
enum smtp_status_code smtp_mail | ( | struct smtp *const | smtp, |
const char *const | body | ||
) |
Sends an email using the addresses, attachments, and headers defined in the current SMTP context.
The caller must call the smtp_open function prior to this.
The 'Date' header will automatically get generated here if it hasn't already been set using smtp_header_add.
If the application overrides the default 'Content-Type' header, then this function will output the body
as raw data just below the email headers, and it will not output the attachments added using the smtp_attachment_add_* functions. In other words, the application must create its own MIME sections (if needed) when overriding the 'Content-Type' header.
[in] | smtp | SMTP client context. |
[in] | body | Null-terminated string to send in the email body. |
Definition at line 3062 of file smtp.c.
References smtp::address_list, smtp::header_list, smtp::num_address, smtp::num_headers, SMTP_ADDRESS_CC, SMTP_ADDRESS_FROM, SMTP_ADDRESS_TO, smtp_append_address_to_header(), SMTP_BEGIN_MAIL, SMTP_DATE_MAX_SZ, smtp_date_rfc_2822(), SMTP_DONE, smtp_header_add(), smtp_header_exists(), smtp_mail_envelope_header(), smtp_print_email(), smtp_print_header(), smtp_puts(), smtp_read_and_parse_code(), smtp_set_read_timeout(), smtp_status_code_set(), SMTP_STATUS_DATE, SMTP_STATUS_OK, SMTP_STATUS_PARAM, SMTP_STATUS_SERVER_RESPONSE, smtp::status_code, and smtp_address::type.
Referenced by SMTPMail::mail(), mailx_send(), smtp_mail_check(), and test_nossl_smtp().
|
static |
Send envelope MAIL FROM or RCPT TO header address.
Examples: MAIL FROM:<mail@example.com> RCPT TO:<mail@example.com>
[in] | smtp | SMTP client context. |
[in] | header | Either "MAIL FROM" or "RCPT TO". |
[in] | address | See smtp_address -> email field. |
Definition at line 2752 of file smtp.c.
References smtp_address::email, malloc, smtp_puts(), smtp_read_and_parse_code(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, SMTP_STATUS_OK, smtp_stpcpy(), smtp_str_has_nonascii_utf8(), smtp::status_code, and strlen.
Referenced by smtp_mail().
enum smtp_status_code smtp_open | ( | const char *const | server, |
const char *const | port, | ||
enum smtp_connection_security | connection_security, | ||
enum smtp_flag | flags, | ||
const char *const | cafile, | ||
struct smtp ** | smtp | ||
) |
Open a connection to an SMTP server and return the context.
After successfully connecting and performing a handshake with the SMTP server, this will return a valid SMTP client context that the application can use in the other library functions.
This always returns a valid SMTP client context even if the server connection or memory allocation fails. In this scenario, the error status will continue to propagate to future library calls for the SMTP context while in this failure mode.
This function will ignore the SIGPIPE signal. Applications that require a handler for that signal should set it up after calling this function.
[in] | server | Server name or IP address. |
[in] | port | Server port number. |
[in] | connection_security | See smtp_connection_security. |
[in] | flags | See smtp_flag. |
[in] | cafile | Path to certificate file, or NULL to use certificates in the default path. |
[out] | smtp | Pointer to a new SMTP context. When finished, the caller must free this context using smtp_close. |
Definition at line 2987 of file smtp.c.
References smtp::cafile, calloc, str_getdelimfd::delim, smtp::flags, g_smtp_error, smtp::gdfd, str_getdelimfd::getdelimfd_read, smtp_connect(), smtp_initiate_handshake(), smtp_status_code_get(), smtp_status_code_set(), SMTP_STATUS_CONNECT, SMTP_STATUS_HANDSHAKE, SMTP_STATUS_OK, smtp_str_getdelimfd_read(), smtp::sock, smtp::status_code, and str_getdelimfd::user_data.
Referenced by mailx_send(), SMTPMail::open(), smtp_func_test_all_address(), smtp_func_test_all_body(), smtp_func_test_all_names(), smtp_func_test_all_nodebug(), smtp_func_test_all_status_code_get(), smtp_func_test_all_write(), smtp_func_test_attachment_fp(), smtp_func_test_attachment_long_text(), smtp_func_test_attachment_mem(), smtp_func_test_attachment_path(), smtp_func_test_attachment_pdf(), smtp_func_test_gmail_attachment(), smtp_func_test_header_custom_date(), smtp_func_test_header_long(), smtp_func_test_header_null_no_date(), smtp_func_test_html(), smtp_func_test_html_with_plaintext(), smtp_func_test_send_email(), smtp_func_test_server_secureserver(), test_failure_address_add(), test_failure_attachment_add(), test_failure_close(), test_failure_header_add(), test_failure_misc(), test_failure_open(), test_failure_status_code_set(), test_failure_timeout(), test_nossl_smtp(), and test_smtp_open_default().
SMTP_LINKAGE int smtp_parse_cmd_line | ( | char *const | line, |
struct smtp_command *const | cmd | ||
) |
Parse a server response line into the smtp_command data structure.
[in] | line | Server response string. |
[out] | cmd | Structure containing the server response data broken up into its separate components. |
Definition at line 1467 of file smtp.c.
References smtp_command::code, smtp_command::more, SMTP_BEGIN_MAIL, SMTP_INTERNAL_ERROR, strlen, and smtp_command::text.
Referenced by smtp_auth_cram_md5(), smtp_read_and_parse_code(), and smtp_unit_test_parse_cmd_line().
|
static |
Send the email body to the mail server.
[in,out] | smtp | SMTP client context. |
[in] | body | Email body text. |
Definition at line 2589 of file smtp.c.
References smtp_header_exists(), smtp_print_mime_email(), smtp_print_nomime_email(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_str_replace(), and smtp::status_code.
Referenced by smtp_mail().
|
static |
Convert a header into an RFC 5322 formatted string and send it to the SMTP server.
This will adding proper line wrapping and indentation for long header lines.
[in] | smtp | SMTP client context. |
[in] | header | See smtp_header. |
Definition at line 2624 of file smtp.c.
References smtp_header::key, malloc, smtp_fold_whitespace(), SMTP_LINE_MAX, smtp_puts_terminate(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_stpcpy(), smtp::status_code, strlen, and smtp_header::value.
Referenced by smtp_mail().
|
static |
Print a MIME section containing an attachment.
[in] | smtp | SMTP client context. |
[in] | boundary | MIME boundary text. |
[in] | attachment | See smtp_attachment. |
Definition at line 2464 of file smtp.c.
References smtp_attachment::b64_data, malloc, smtp_attachment::name, SMTP_MIME_BOUNDARY_LEN, smtp_puts(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_stpcpy(), smtp::status_code, and strlen.
Referenced by smtp_print_mime_email().
|
static |
Send the main email body to the SMTP server.
This includes the MIME sections for the email body and attachments.
[in] | smtp | SMTP client context. |
[in] | body_dd | Email body with double dots added at the beginning of each line. |
Definition at line 2543 of file smtp.c.
References smtp::attachment_list, smtp::num_attachment, smtp_gen_mime_boundary(), SMTP_MIME_BOUNDARY_LEN, smtp_print_mime_attachment(), smtp_print_mime_end(), smtp_print_mime_header_and_body(), SMTP_STATUS_OK, and smtp::status_code.
Referenced by smtp_print_email().
|
static |
Prints double hyphen on both sides of the MIME boundary which indicates the end of the MIME sections.
[in] | smtp | SMTP client context. |
[in] | boundary | MIME boundary text. |
Definition at line 2521 of file smtp.c.
References SMTP_MIME_BOUNDARY_LEN, smtp_puts(), and smtp_stpcpy().
Referenced by smtp_print_mime_email().
|
static |
Print the MIME header and the MIME section containing the email body.
[in] | smtp | SMTP client context. |
[in] | boundary | MIME boundary text. |
[in] | body_dd | Email body with double dots added at the beginning of each line. |
Definition at line 2411 of file smtp.c.
References malloc, smtp_puts(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_stpcpy(), smtp::status_code, and strlen.
Referenced by smtp_print_mime_email().
|
static |
Print the email data provided by the user without MIME formatting.
[in,out] | smtp | SMTP client context. |
[in] | body_dd | Email body with double dots added at the beginning of each line. |
Definition at line 2576 of file smtp.c.
References smtp_puts_terminate().
Referenced by smtp_print_email().
|
static |
Send a null-terminated string to the SMTP server.
[in] | smtp | SMTP client context. |
[in] | s | Null-terminated string to send to the SMTP server. |
Definition at line 1655 of file smtp.c.
References smtp_write(), and strlen.
Referenced by smtp_auth_cram_md5(), smtp_auth_login(), smtp_auth_plain(), smtp_close(), smtp_ehlo(), smtp_initiate_handshake(), smtp_mail(), smtp_mail_envelope_header(), smtp_print_mime_attachment(), smtp_print_mime_end(), smtp_print_mime_header_and_body(), and smtp_puts_terminate().
|
static |
Prints communication between the client and server to stderr only if the debug flag has been set.
[in] | smtp | SMTP client context. |
[in] | prefix | Print this prefix before the main debug line text. |
[in] | str | Debug text to print out. |
Definition at line 1512 of file smtp.c.
References smtp::flags, SMTP_DEBUG, and smtp_strdup().
Referenced by smtp_getline(), and smtp_write().
|
static |
Same as smtp_puts except this function also appends the line terminating carriage return and newline bytes at the end of the string.
[in] | smtp | SMTP client context. |
[in] | s | Null-terminated string to send to the SMTP server. |
Definition at line 1669 of file smtp.c.
References malloc, smtp_puts(), smtp_si_add_size_t(), smtp_status_code_set(), SMTP_STATUS_NOMEM, smtp_stpcpy(), and strlen.
Referenced by smtp_auth_cram_md5(), smtp_auth_login(), smtp_print_header(), and smtp_print_nomime_email().
|
static |
Loop through all of the server response lines until the last line, and then return the status code from the last response line.
[in] | smtp | SMTP client context. |
Definition at line 1574 of file smtp.c.
References smtp_command::code, smtp::gdfd, str_getdelimfd::line, smtp_command::more, smtp_getline(), SMTP_INTERNAL_ERROR, SMTP_LINKAGE, smtp_parse_cmd_line(), STRING_GETDELIMFD_DONE, and STRING_GETDELIMFD_ERROR.
Referenced by smtp_auth_cram_md5(), smtp_auth_login(), smtp_auth_plain(), smtp_ehlo(), smtp_initiate_handshake(), smtp_mail(), and smtp_mail_envelope_header().
SMTP_LINKAGE void* smtp_reallocarray | ( | void * | ptr, |
size_t | nmemb, | ||
size_t | size | ||
) |
Reallocate memory with unsigned wrapping checks.
[in] | ptr | Existing allocation buffer, or NULL when allocating a new buffer. |
[in] | nmemb | Number of elements to allocate. |
[in] | size | Size of each element in nmemb . |
void* | Pointer to a reallocated buffer containing nmemb * size bytes. |
NULL | Failed to reallocate memory. |
Definition at line 622 of file smtp.c.
References realloc, SMTP_LINKAGE, and smtp_si_mul_size_t().
Referenced by smtp_address_add(), smtp_attachment_add_mem(), smtp_header_add(), and smtp_unit_test_reallocarray().
|
static |
Set the timeout for the next socket read operation.
[in] | smtp | SMTP client context. |
[in] | seconds | Timeout in seconds. |
Definition at line 2138 of file smtp.c.
References smtp::timeout_sec.
Referenced by smtp_initiate_handshake(), and smtp_mail().
SMTP_LINKAGE int smtp_si_add_size_t | ( | const size_t | a, |
const size_t | b, | ||
size_t *const | result | ||
) |
Check if adding a size_t value will cause a wrap.
[in] | a | Add this value with b . |
[in] | b | Add this value with a . |
[out] | result | Save the addition to this buffer. Does not perform the addition if set to NULL. |
1 | Value wrapped. |
0 | Value did not wrap. |
Definition at line 252 of file smtp.c.
References g_smtp_test_err_si_add_size_t_ctr, SIZE_MAX, SMTP_LINKAGE, and smtp_test_seam_dec_err_ctr().
Referenced by smtp_address_add(), smtp_append_address_to_header(), smtp_attachment_add_mem(), smtp_auth_cram_md5(), smtp_auth_login(), smtp_auth_plain(), smtp_base64_decode(), smtp_bin2hex(), smtp_chunk_split(), smtp_ffile_get_contents(), smtp_fold_whitespace(), smtp_header_add(), smtp_mail_envelope_header(), smtp_print_header(), smtp_print_mime_attachment(), smtp_print_mime_header_and_body(), smtp_puts_terminate(), smtp_str_getdelimfd(), smtp_str_getdelimfd_set_line_and_buf(), smtp_str_replace(), smtp_strdup(), and smtp_unit_test_all_si().
SMTP_LINKAGE int smtp_si_mul_size_t | ( | const size_t | a, |
const size_t | b, | ||
size_t *const | result | ||
) |
Check if multiplying a size_t value will cause a wrap.
[in] | a | Multiply this value with b . |
[in] | b | Multiply this value with a . |
[out] | result | Save the multiplication to this buffer. Does not perform the multiplication if set to NULL. |
1 | Value wrapped. |
0 | Value did not wrap. |
Definition at line 320 of file smtp.c.
References g_smtp_test_err_si_mul_size_t_ctr, SIZE_MAX, and smtp_test_seam_dec_err_ctr().
Referenced by smtp_base64_encode(), smtp_bin2hex(), smtp_chunk_split(), smtp_reallocarray(), and smtp_unit_test_all_si().
SMTP_LINKAGE int smtp_si_sub_size_t | ( | const size_t | a, |
const size_t | b, | ||
size_t *const | result | ||
) |
Check if subtracting a size_t value will cause wrap.
[in] | a | Subtract this value by b . |
[in] | b | Subtract this value from a . |
[out] | result | Save the subtraction to this buffer. Does not perform the subtraction if set to NULL. |
1 | Value wrapped. |
0 | Value did not wrap. |
Definition at line 286 of file smtp.c.
References g_smtp_test_err_si_sub_size_t_ctr, SMTP_LINKAGE, and smtp_test_seam_dec_err_ctr().
Referenced by smtp_str_getdelimfd(), smtp_str_getdelimfd_set_line_and_buf(), and smtp_unit_test_all_si().
enum smtp_status_code smtp_status_code_clear | ( | struct smtp *const | smtp | ) |
Clear the current error code set in the SMTP client context.
[in,out] | smtp | SMTP client context. |
Definition at line 3222 of file smtp.c.
References smtp_status_code_get(), smtp_status_code_set(), and SMTP_STATUS_OK.
Referenced by smtp_func_test_all_address(), smtp_func_test_all_status_code_get(), test_failure_address_add(), test_failure_attachment_add(), test_failure_header_add(), and test_failure_status_code_set().
const char* smtp_status_code_errstr | ( | enum smtp_status_code | status_code | ) |
Convert a standard SMTP client status code to a descriptive string.
[in] | status_code | Status code returned from one of the other library functions. |
status_code
. The caller must not free or modify this string. Definition at line 3241 of file smtp.c.
References SMTP_STATUS__LAST.
Referenced by mailx_send(), smtp_unit_test_smtp_status_code_errstr(), and SMTPMailException::what().
enum smtp_status_code smtp_status_code_get | ( | const struct smtp *const | smtp | ) |
Get the current status/error code.
[in] | smtp | SMTP client context. |
Definition at line 3217 of file smtp.c.
References smtp::status_code.
Referenced by smtp_func_test_all_status_code_get(), smtp_open(), smtp_status_code_clear(), SMTPMail::status_code_get(), and test_failure_status_code_set().
enum smtp_status_code smtp_status_code_set | ( | struct smtp *const | smtp, |
enum smtp_status_code | new_status_code | ||
) |
Set the error status of the SMTP client context and return the same code.
This allows the caller to clear an error status to SMTP_STATUS_OK so that previous errors will stop propagating. However, this will only work correctly for clearing the SMTP_STATUS_PARAM and SMTP_STATUS_FILE errors. Do not use this to clear any other error codes.
[in] | smtp | SMTP client context. |
[in] | new_status_code | See smtp_status_code. |
Definition at line 3231 of file smtp.c.
References SMTP_STATUS__LAST, SMTP_STATUS_PARAM, and smtp::status_code.
Referenced by smtp_address_add(), smtp_append_address_to_header(), smtp_attachment_add_fp(), smtp_attachment_add_mem(), smtp_attachment_add_path(), smtp_auth(), smtp_close(), smtp_func_test_all_status_code_get(), smtp_getline(), smtp_header_add(), smtp_initiate_handshake(), smtp_mail(), smtp_mail_envelope_header(), smtp_open(), smtp_print_email(), smtp_print_header(), smtp_print_mime_attachment(), smtp_print_mime_header_and_body(), smtp_puts_terminate(), smtp_status_code_clear(), smtp_str_getdelimfd_read_timeout(), smtp_write(), SMTPMail::status_code_set(), test_failure_address_add(), test_failure_attachment_add(), test_failure_auth(), test_failure_header_add(), test_failure_mail(), and test_failure_status_code_set().
SMTP_LINKAGE char* smtp_stpcpy | ( | char * | s1, |
const char * | s2 | ||
) |
Copy a string and get the pointer to the end of the copied buffer.
This function behaves similar to POSIX stpcpy(), useful for concatenating multiple strings onto a buffer. It always adds a null-terminated byte at the end of the string.
[in] | s1 | Destination buffer. |
[in] | s2 | Null-terminated source string to copy to s1 . |
s1
after the last copied byte. Definition at line 599 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_append_address_to_header(), smtp_auth_cram_md5(), smtp_auth_login(), smtp_auth_plain(), smtp_mail_envelope_header(), smtp_print_header(), smtp_print_mime_attachment(), smtp_print_mime_end(), smtp_print_mime_header_and_body(), smtp_puts_terminate(), and smtp_unit_test_stpcpy().
SMTP_LINKAGE enum str_getdelim_retcode smtp_str_getdelimfd | ( | struct str_getdelimfd *const | gdfd | ) |
Read and parse a delimited string using a custom socket read function.
This interface handles all of the logic for expanding the buffer, parsing the delimiter in the buffer, and returning each "line" to the caller for handling.
[in] | gdfd | See str_getdelimfd. |
Definition at line 523 of file smtp.c.
References str_getdelimfd::_buf, str_getdelimfd::_buf_len, str_getdelimfd::_bufsz, str_getdelimfd::delim, str_getdelimfd::getdelimfd_read, realloc, SMTP_GETDELIM_READ_SZ, SMTP_LINKAGE, smtp_si_add_size_t(), smtp_si_sub_size_t(), smtp_str_getdelimfd_search_delim(), smtp_str_getdelimfd_set_line_and_buf(), smtp_str_getdelimfd_throw_error(), STRING_GETDELIMFD_DONE, STRING_GETDELIMFD_ERROR, and STRING_GETDELIMFD_NEXT.
Referenced by smtp_getline(), and smtp_unit_test_str_getdelimfd().
SMTP_LINKAGE void smtp_str_getdelimfd_free | ( | struct str_getdelimfd *const | gdfd | ) |
Free memory in the str_getdelimfd data structure.
[in] | gdfd | Frees memory stored in this socket parsing structure. |
Definition at line 489 of file smtp.c.
References str_getdelimfd::_buf, str_getdelimfd::_buf_len, str_getdelimfd::_bufsz, str_getdelimfd::line, and str_getdelimfd::line_len.
Referenced by smtp_close(), smtp_str_getdelimfd_throw_error(), and smtp_unit_test_str_getdelimfd().
|
static |
This function gets called by the smtp_str_getdelimfd interface when it needs to read in more data.
It reads using either the plain socket connection if encryption not enabled, or it reads using OpenSSL if it has an active TLS connection.
[in] | gdfd | See str_getdelimfd. |
[out] | buf | Pointer to buffer for storing bytes read. |
[in] | count | Maximum number of bytes to try reading. |
>=0 | Number of bytes read. |
-1 | Failed to read from the socket. |
Definition at line 382 of file smtp.c.
References BIO_should_retry, recv, SMTP_STATUS_OK, smtp_str_getdelimfd_read_timeout(), smtp::sock, SSL_read, smtp::tls, smtp::tls_bio, smtp::tls_on, and str_getdelimfd::user_data.
Referenced by smtp_open().
|
static |
Wait until more data has been made available on the socket read end.
[in] | smtp | SMTP client context. |
SMTP_STATUS_OK | If data available to read on the socket. |
SMTP_STATUS_RECV | If the connection times out before any data appears on the socket. |
Definition at line 352 of file smtp.c.
References select, smtp_status_code_set(), SMTP_STATUS_OK, SMTP_STATUS_RECV, smtp::sock, and smtp::timeout_sec.
Referenced by smtp_str_getdelimfd_read().
|
static |
Find and return the location of the delimiter character in the search buffer.
This function gets used by the main socket parsing function which continually reads from the socket and expands the buffer until it encounters the expected delimiter. This function provides the logic to check for the delimiter character in order to simplify the code in the main parse function.
[in] | buf | Search buffer used to find the delimiter. |
[in] | buf_len | Number of bytes to search for in buf. |
[in] | delim | The delimiter to search for in buf. |
[out] | delim_pos | If delimiter found in buf, return the delimiter position in this parameter. |
1 | If the delimiter character found. |
0 | If the delimiter character not found. |
Definition at line 431 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_str_getdelimfd().
SMTP_LINKAGE int smtp_str_getdelimfd_set_line_and_buf | ( | struct str_getdelimfd *const | gdfd, |
size_t | copy_len | ||
) |
Set the internal line buffer to the number of bytes specified.
[in] | gdfd | See str_getdelimfd. |
[in] | copy_len | Number of bytes to copy to the internal line buffer. |
0 | Successfully allocated and copied data over to the new line buffer. |
-1 | Failed to allocate memory for the new line buffer. |
Definition at line 457 of file smtp.c.
References str_getdelimfd::_buf, str_getdelimfd::_buf_len, calloc, str_getdelimfd::line, str_getdelimfd::line_len, SMTP_LINKAGE, smtp_si_add_size_t(), and smtp_si_sub_size_t().
Referenced by smtp_str_getdelimfd(), and smtp_unit_test_getdelimfd_set_line_and_buf().
|
static |
Free the str_getdelimfd and return the STRING_GETDELIMFD_ERROR error code.
[in] | gdfd | See str_getdelimfd. |
Definition at line 507 of file smtp.c.
References SMTP_LINKAGE, smtp_str_getdelimfd_free(), and STRING_GETDELIMFD_ERROR.
Referenced by smtp_str_getdelimfd().
SMTP_LINKAGE int smtp_str_has_nonascii_utf8 | ( | const char *const | s | ) |
Check if a string contains non-ASCII UTF-8 characters.
Uses the simple algorithm from smtp_utf8_charlen to check for non-ASCII UTF-8 characters.
[in] | s | UTF-8 string. |
1 | String contains non-ASCII UTF-8 characters. |
0 | String contains only ASCII characters. |
Definition at line 1110 of file smtp.c.
References SMTP_LINKAGE, and smtp_utf8_charlen().
Referenced by smtp_mail_envelope_header(), and smtp_unit_test_all_smtp_str_has_nonascii_utf8().
SMTP_LINKAGE char* smtp_str_replace | ( | const char *const | search, |
const char *const | replace, | ||
const char *const | s | ||
) |
Search for all substrings in a string and replace each instance with a replacement string.
[in] | search | Substring to search for in s . |
[in] | replace | Replace each instance of the search string with this. |
[in] | s | Null-terminated string to search and replace. |
char* | A dynamically allocated string with the replaced instances as described above. The caller must free the allocated memory when finished. |
NULL | Memory allocation failure. |
Definition at line 679 of file smtp.c.
References realloc, smtp_si_add_size_t(), smtp_strdup(), and strlen.
Referenced by smtp_print_email(), and smtp_unit_test_str_replace().
SMTP_LINKAGE char* smtp_strdup | ( | const char * | s | ) |
Copy a string into a new dynamically allocated buffer.
Returns a dynamically allocated string, with the same contents as the input string. The caller must free the returned string when finished.
[in] | s | String to duplicate. |
char* | Pointer to a new dynamically allocated string duplicated from s . |
NULL | Failed to allocate memory for the new duplicate string. |
Definition at line 650 of file smtp.c.
References malloc, SMTP_LINKAGE, smtp_si_add_size_t(), and strlen.
Referenced by smtp_address_add(), smtp_attachment_add_mem(), smtp_chunk_split(), smtp_header_add(), smtp_puts_dbg(), smtp_str_repeat(), smtp_str_replace(), smtp_unit_test_parse_cmd_line(), and smtp_unit_test_strdup().
SMTP_LINKAGE size_t smtp_strnlen_utf8 | ( | const char * | s, |
size_t | maxlen | ||
) |
Get the number of bytes in a UTF-8 string, or a shorter count if the string exceeds a maximum specified length.
See maxlen
for more information on multi-byte parsing.
[in] | s | Null-terminated UTF-8 string. |
[in] | maxlen | Do not check more than maxlen bytes of string s except if in the middle of a multi-byte character. |
strlen(s) | If length of s has less bytes than maxlen or the same number of bytes as maxlen. See maxlen for more details. |
maxlen | If length of s has more bytes than maxlen. |
-1 | If s contains an invalid UTF-8 byte sequence. |
Definition at line 1138 of file smtp.c.
References SIZE_MAX, SMTP_LINKAGE, and smtp_utf8_charlen().
Referenced by smtp_chunk_split(), and smtp_unit_test_strnlen_utf8().
|
static |
Initialize the TLS library and establish a TLS handshake with the server over the existing socket connection.
[in] | smtp | SMTP client context. |
[in] | server | Server name or IP address. |
0 | Successfully established a TLS connection with the server. |
-1 | Failed to establish a TLS connection with the server. |
Definition at line 1770 of file smtp.c.
References BIO_new_socket, smtp::cafile, ERR_peek_error, smtp::flags, SMTP_NO_CERT_VERIFY, smtp::sock, SSL_connect, SSL_CTX_new, SSL_do_handshake, SSL_get_peer_certificate, SSL_new, smtp::tls, smtp::tls_bio, smtp::tls_ctx, smtp::tls_on, and X509_check_host.
Referenced by smtp_initiate_handshake().
SMTP_LINKAGE size_t smtp_utf8_charlen | ( | char | c | ) |
Get the length in bytes of a UTF-8 character.
This consists of a very simple check and assumes the user provides a valid UTF-8 byte sequence. It gets the length from the first byte in the sequence and does not validate any other bytes in the character sequence or any other bits in the first byte of the character sequence.
[in] | c | The first byte in a valid UTF-8 character sequence. |
>0 | Number of bytes for the current UTF-8 character sequence. |
-1 | Invalid byte sequence. |
Definition at line 1078 of file smtp.c.
References SMTP_LINKAGE.
Referenced by smtp_str_has_nonascii_utf8(), smtp_strnlen_utf8(), and smtp_unit_test_all_smtp_utf8_charlen().
SMTP_LINKAGE enum smtp_status_code smtp_write | ( | struct smtp *const | smtp, |
const char *const | buf, | ||
size_t | len | ||
) |
Send data to the SMTP server.
Writes a buffer of length len into either the unencrypted TCP socket or the TLS encrypted socket, depending on the current underlying mode of the socket.
[in] | smtp | SMTP client context. |
[in] | buf | Data to send to the SMTP server. |
[in] | len | Number of bytes in buf. |
Definition at line 1603 of file smtp.c.
References send, smtp_puts_dbg(), smtp_status_code_set(), SMTP_STATUS_SEND, smtp::sock, SSL_write, smtp::status_code, smtp::tls, and smtp::tls_on.
Referenced by smtp_puts(), and test_failure_misc().
|
static |
Lookup table used to decode base64 data.
For base64 encoding, every six bits have been encoded using only the ASCII characters from g_base64_encode_table. This table has entries which allow the reversal of that process. It has 128 entries which map over to the index value from the encoding table. If an indexing result ends up with -1 during the decoding process, then that indicates an invalid base64 character in the encoded data.
Definition at line 894 of file smtp.c.
Referenced by smtp_base64_decode_block().
|
static |
Lookup table used to encode data into base64.
Base64 encoding takes six bits of data and encodes those bits using this table. Since 2^6 = 64, this array has 64 entries which maps directly from the 6 bit value into the corresponding array value.
Definition at line 772 of file smtp.c.
Referenced by smtp_base64_encode_block().
|
static |
This error structure used for the single error case where we cannot initially allocate memory. This makes it easier to propagate any error codes when calling the other header functions because the caller will always get a valid SMTP structure returned.
Definition at line 2954 of file smtp.c.
Referenced by smtp_open().