From d43ac371fb313a0b681e7d1ce41c01deccce0e98 Mon Sep 17 00:00:00 2001 From: Yuxin Zhou Date: Sat, 3 Apr 2021 01:03:43 +0000 Subject: [PATCH] Release 6.1.6 --- addons/http/nx_http_client.c | 162 +------------ addons/http/nx_http_client.h | 11 +- addons/http/nx_http_server.c | 279 +---------------------- addons/http/nx_http_server.h | 12 +- addons/pop3/nx_pop3_client.c | 7 +- addons/smtp/nx_smtp_client.c | 428 +++++++---------------------------- addons/snmp/nx_snmp.c | 153 +++++++++++-- common/inc/nx_api.h | 9 +- common/src/nx_utility.c | 309 +++++++++++++++++++++++++ 9 files changed, 568 insertions(+), 802 deletions(-) diff --git a/addons/http/nx_http_client.c b/addons/http/nx_http_client.c index 5ac03b5..e4d52f3 100644 --- a/addons/http/nx_http_client.c +++ b/addons/http/nx_http_client.c @@ -42,13 +42,6 @@ /* Define global HTTP variables and strings. */ - -/* Define the Base64 array that is used to build username and passwords for Basic authentication. Indexing - into this array yields the base64 representation of the 6bit number. */ - -CHAR _nx_http_client_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /* Bring in externs for caller checking code. */ NX_CALLER_CHECKING_EXTERNS @@ -705,7 +698,7 @@ UINT status; /* FUNCTION RELEASE */ /* */ /* _nx_http_client_get_start_extended PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -769,6 +762,10 @@ UINT status; /* 09-30-2020 Yuxin Zhou Modified comment(s), and */ /* verified memcpy use cases, */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_http_client_get_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG server_ip, CHAR *resource, UINT resource_length, @@ -947,10 +944,7 @@ UINT temp_password_length = 0; string1[username_length + password_length + 1] = NX_NULL; /* Now encode the username:password string. */ - _nx_http_client_base64_encode(string1, username_length + password_length + 1, string2); - - /* Check string length. */ - _nx_utility_string_length_check(string2, &string2_length, NX_HTTP_MAX_STRING); + _nx_utility_base64_encode((UCHAR *)string1, username_length + password_length + 1, (UCHAR *)string2, sizeof(string2), &string2_length); nx_packet_data_append(packet_ptr, string2, string2_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER); nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER); } @@ -1586,7 +1580,7 @@ UINT status; /* FUNCTION RELEASE */ /* */ /* _nx_http_client_put_start_extended PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -1647,6 +1641,10 @@ UINT status; /* 09-30-2020 Yuxin Zhou Modified comment(s), and */ /* verified memcpy use cases, */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_http_client_put_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG server_ip, CHAR *resource, @@ -1815,10 +1813,7 @@ UINT temp_password_length = 0; string1[username_length + password_length + 1] = NX_NULL; /* Now encode the username:password string. */ - _nx_http_client_base64_encode(string1, username_length + password_length + 1, string2); - - /* Check string length. */ - _nx_utility_string_length_check(string2, &string2_length, NX_HTTP_MAX_STRING); + _nx_utility_base64_encode((UCHAR *)string1, username_length + password_length + 1, (UCHAR *)string2, sizeof(string2), &string2_length); nx_packet_data_append(packet_ptr, string2, string2_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER); nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER); @@ -2629,136 +2624,3 @@ UINT size; /* Return size to caller. */ return(size); } - - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _nx_http_client_base64_encode PORTABLE C */ -/* 6.1 */ -/* AUTHOR */ -/* */ -/* Yuxin Zhou, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function encodes the input string into a base64 */ -/* representation. */ -/* */ -/* INPUT */ -/* */ -/* name Name string */ -/* length Length of name */ -/* base64name Encoded base64 name string */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _nx_utility_string_length_check Check string length */ -/* */ -/* CALLED BY */ -/* */ -/* _nx_http_client_get_start_extended Start GET processing */ -/* _nx_http_client_put_start_extended Start PUT processing */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ -VOID _nx_http_client_base64_encode(CHAR *name, UINT length, CHAR *base64name) -{ - -UINT pad; -UINT i, j; -UINT step; - - - /* Adjust the length to represent the base64 name. */ - length = ((length * 8) / 6); - - /* Default padding to none. */ - pad = 0; - - /* Determine if an extra conversion is needed. */ - if ((length * 6) % 24) - { - - /* Some padding is needed. */ - - /* Calculate the number of pad characters. */ - pad = (length * 6) % 24; - pad = (24 - pad) / 6; - pad = pad - 1; - - /* Adjust the length to pickup the character fraction. */ - length++; - } - - /* Setup index into the base64name. */ - j = 0; - - /* Compute the base64name. */ - step = 0; - i = 0; - while (j < length) - { - - /* Determine which step we are in. */ - if (step == 0) - { - - /* Use first 6 bits of name character for index. */ - base64name[j++] = _nx_http_client_base64_array[((UINT) name[i]) >> 2]; - step++; - } - else if (step == 1) - { - - /* Use last 2 bits of name character and first 4 bits of next name character for index. */ - base64name[j++] = _nx_http_client_base64_array[((((UINT) name[i]) & 0x3) << 4) | (((UINT) name[i+1]) >> 4)]; - i++; - step++; - } - else if (step == 2) - { - - /* Use last 4 bits of name character and first 2 bits of next name character for index. */ - base64name[j++] = _nx_http_client_base64_array[((((UINT) name[i]) & 0xF) << 2) | (((UINT) name[i+1]) >> 6)]; - i++; - step++; - } - else /* Step 3 */ - { - - /* Use last 6 bits of name character for index. */ - base64name[j++] = _nx_http_client_base64_array[(((UINT) name[i]) & 0x3F)]; - i++; - step = 0; - } - } - - /* Determine if the index needs to be advanced. */ - if (step != 3) - i++; - - /* Now add the PAD characters. */ - while ((pad--) && (j < NX_HTTP_MAX_STRING)) - { - - /* Pad base64name with '=' characters. */ - base64name[j++] = '='; - } - - /* Put a NULL character in. */ - base64name[j] = NX_NULL; -} - diff --git a/addons/http/nx_http_client.h b/addons/http/nx_http_client.h index b94b90b..c73c054 100644 --- a/addons/http/nx_http_client.h +++ b/addons/http/nx_http_client.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* nx_http_client.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -45,6 +45,10 @@ /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -107,8 +111,8 @@ extern "C" { #define NX_HTTP_CLIENT_MIN_PACKET_SIZE 600 #endif -/* NX_HTTP_MAX_STRING is base64 of "name:password" and plus 1 if an extra conversion is needed. */ -#define NX_HTTP_MAX_STRING ((NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 1) * 4 / 3 + 1) +/* NX_HTTP_MAX_STRING is base64 of "name:password" and plus 1 if an extra conversion is needed and plus 2 pad if needed. */ +#define NX_HTTP_MAX_STRING ((NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 1) * 4 / 3 + 1 + 2) #define NX_HTTP_MAX_BINARY_MD5 16 #define NX_HTTP_MAX_ASCII_MD5 32 @@ -266,7 +270,6 @@ UINT _nx_http_client_type_get(CHAR *name, CHAR *http_type_string); UINT _nx_http_client_content_length_get(NX_PACKET *packet_ptr); UINT _nx_http_client_calculate_content_offset(NX_PACKET *packet_ptr); UINT _nx_http_client_number_convert(UINT number, CHAR *string); -VOID _nx_http_client_base64_encode(CHAR *name, UINT length, CHAR *base64name); #endif /* NX_HTTP_SOURCE_CODE */ diff --git a/addons/http/nx_http_server.c b/addons/http/nx_http_server.c index eb1d17e..60cdc0f 100644 --- a/addons/http/nx_http_server.c +++ b/addons/http/nx_http_server.c @@ -40,13 +40,6 @@ #include "nx_md5.h" #endif - -/* Define the Base64 array that is used to build username and passwords for Basic authentication. Indexing - into this array yields the base64 representation of the 6bit number. */ - -CHAR _nx_http_server_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - #ifdef NX_HTTP_DIGEST_ENABLE /* Define the default nonce, used only for MD5 authentication. For security reasons, this ASCII value should change over time. */ @@ -4674,7 +4667,7 @@ NX_PACKET *packet_ptr; /* FUNCTION RELEASE */ /* */ /* _nx_http_server_basic_authenticate PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -4723,6 +4716,10 @@ NX_PACKET *packet_ptr; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_http_server_basic_authenticate(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, CHAR *password_ptr, CHAR *realm_ptr, UINT realm_length, UINT *auth_request_present) @@ -4734,6 +4731,7 @@ CHAR quote[2] = {0x22, 0}; CHAR crlf[2] = {13,10}; UINT match; UINT length; +UINT authorization_decoded_size; /* Default to no authentication request detected. */ *auth_request_present = NX_FALSE; @@ -4754,14 +4752,14 @@ UINT length; *auth_request_present = NX_TRUE; /* Convert the request from Base64 representation to ASCII. */ - _nx_http_base64_decode(authorization_request, length, authorization_decoded); + _nx_utility_base64_decode((UCHAR *)authorization_request, length, (UCHAR *)authorization_decoded, sizeof(authorization_decoded), &authorization_decoded_size); /* See if it is valid. */ /* Compare the name. */ i = 0; match = NX_TRUE; - while (name_ptr[i] && (i < sizeof(authorization_decoded))) + while (name_ptr[i] && (i < authorization_decoded_size)) { /* Is there a mismatch? */ @@ -4777,7 +4775,7 @@ UINT length; } /* Determine if everything matches. */ - if (match && (i < sizeof(authorization_decoded)) && (authorization_decoded[i] == ':')) + if (match && (i < authorization_decoded_size) && (authorization_decoded[i] == ':')) { /* Move the authorization index past the semicolon. */ @@ -4786,7 +4784,7 @@ UINT length; /* Now compare the passwords. */ j = 0; match = NX_TRUE; - while (password_ptr[j] && (i < sizeof(authorization_decoded))) + while (password_ptr[j] && (i < authorization_decoded_size)) { /* Is there a mismatch? */ @@ -4803,7 +4801,7 @@ UINT length; } /* Determine if we have a match. */ - if (match && (i < sizeof(authorization_decoded)) && (authorization_decoded[i] == (CHAR) NX_NULL)) + if (match && (i == authorization_decoded_size) && (authorization_decoded[i] == (CHAR) NX_NULL)) { /* Yes, we have successful authorization!! */ @@ -5766,261 +5764,6 @@ UINT temp_name_length; return(sizeof(NX_HTTP_SERVER_DEFAULT_MIME) - 1); } - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _nx_http_base64_encode PORTABLE C */ -/* 6.1 */ -/* AUTHOR */ -/* */ -/* Yuxin Zhou, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function encodes the input string into a base64 */ -/* representation. */ -/* */ -/* INPUT */ -/* */ -/* name Name string */ -/* length Length of name */ -/* base64name Encoded base64 name string */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _nx_utility_string_length_check Check string length */ -/* */ -/* CALLED BY */ -/* */ -/* None */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ -VOID _nx_http_base64_encode(CHAR *name, UINT length, CHAR *base64name) -{ - -UINT pad; -UINT i, j; -UINT step; - - - /* Adjust the length to represent the base64 name. */ - length = ((length * 8) / 6); - - /* Default padding to none. */ - pad = 0; - - /* Determine if an extra conversion is needed. */ - if ((length * 6) % 24) - { - - /* Some padding is needed. */ - - /* Calculate the number of pad characters. */ - pad = (length * 6) % 24; - pad = (24 - pad) / 6; - pad = pad - 1; - - /* Adjust the length to pickup the character fraction. */ - length++; - } - - /* Setup index into the base64name. */ - j = 0; - - /* Compute the base64name. */ - step = 0; - i = 0; - while (j < length) - { - - /* Determine which step we are in. */ - if (step == 0) - { - - /* Use first 6 bits of name character for index. */ - base64name[j++] = _nx_http_server_base64_array[((UINT) name[i]) >> 2]; - step++; - } - else if (step == 1) - { - - /* Use last 2 bits of name character and first 4 bits of next name character for index. */ - base64name[j++] = _nx_http_server_base64_array[((((UINT) name[i]) & 0x3) << 4) | (((UINT) name[i+1]) >> 4)]; - i++; - step++; - } - else if (step == 2) - { - - /* Use last 4 bits of name character and first 2 bits of next name character for index. */ - base64name[j++] = _nx_http_server_base64_array[((((UINT) name[i]) & 0xF) << 2) | (((UINT) name[i+1]) >> 6)]; - i++; - step++; - } - else /* Step 3 */ - { - - /* Use last 6 bits of name character for index. */ - base64name[j++] = _nx_http_server_base64_array[(((UINT) name[i]) & 0x3F)]; - i++; - step = 0; - } - } - - /* Determine if the index needs to be advanced. */ - if (step != 3) - i++; - - /* Now add the PAD characters. */ - while ((pad--) && (j < NX_HTTP_MAX_STRING)) - { - - /* Pad base64name with '=' characters. */ - base64name[j++] = '='; - } - - /* Put a NULL character in. */ - base64name[j] = NX_NULL; -} - - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _nx_http_base64_decode PORTABLE C */ -/* 6.1 */ -/* AUTHOR */ -/* */ -/* Yuxin Zhou, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function decodes the input base64 ASCII string and converts */ -/* it into a standard ASCII representation. */ -/* */ -/* INPUT */ -/* */ -/* base64name Encoded base64 name string */ -/* length Length of encoded base64 name */ -/* name Name string */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _nx_utility_string_length_check Check string length */ -/* */ -/* CALLED BY */ -/* */ -/* _nx_http_server_basic_authenticate Basic authentication */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ -VOID _nx_http_base64_decode(CHAR *base64name, UINT length, CHAR *name) -{ - -UINT i, j; -UINT value1, value2; -UINT step; - - - /* Adjust the length to represent the ASCII name. */ - length = ((length * 6) / 8); - - /* Setup index into the ASCII name. */ - j = 0; - - /* Compute the ASCII name. */ - step = 0; - i = 0; - while ((j < length) && (base64name[i]) && (base64name[i] != '=')) - { - - /* Derive values of the Base64 name. */ - if ((base64name[i] >= 'A') && (base64name[i] <= 'Z')) - value1 = (UINT) (base64name[i] - 'A'); - else if ((base64name[i] >= 'a') && (base64name[i] <= 'z')) - value1 = (UINT) (base64name[i] - 'a') + 26; - else if ((base64name[i] >= '0') && (base64name[i] <= '9')) - value1 = (UINT) (base64name[i] - '0') + 52; - else if (base64name[i] == '+') - value1 = 62; - else if (base64name[i] == '/') - value1 = 63; - else - value1 = 0; - - /* Derive value for the next character. */ - if ((base64name[i+1] >= 'A') && (base64name[i+1] <= 'Z')) - value2 = (UINT) (base64name[i+1] - 'A'); - else if ((base64name[i+1] >= 'a') && (base64name[i+1] <= 'z')) - value2 = (UINT) (base64name[i+1] - 'a') + 26; - else if ((base64name[i+1] >= '0') && (base64name[i+1] <= '9')) - value2 = (UINT) (base64name[i+1] - '0') + 52; - else if (base64name[i+1] == '+') - value2 = 62; - else if (base64name[i+1] == '/') - value2 = 63; - else - value2 = 0; - - /* Determine which step we are in. */ - if (step == 0) - { - - /* Use first value and first 2 bits of second value. */ - name[j++] = (CHAR) (((value1 & 0x3f) << 2) | ((value2 >> 4) & 3)); - i++; - step++; - } - else if (step == 1) - { - - /* Use last 4 bits of first value and first 4 bits of next value. */ - name[j++] = (CHAR) (((value1 & 0xF) << 4) | (value2 >> 2)); - i++; - step++; - } - else if (step == 2) - { - - /* Use first 2 bits and following 6 bits of next value. */ - name[j++] = (CHAR) (((value1 & 3) << 6) | (value2 & 0x3f)); - i++; - i++; - step = 0; - } - } - - /* Put a NULL character in. */ - name[j] = NX_NULL; -} - - #ifdef NX_HTTP_DIGEST_ENABLE /**************************************************************************/ /* */ diff --git a/addons/http/nx_http_server.h b/addons/http/nx_http_server.h index aef9df5..9903e62 100644 --- a/addons/http/nx_http_server.h +++ b/addons/http/nx_http_server.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* nx_http_server.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -45,6 +45,10 @@ /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -172,8 +176,8 @@ extern "C" { #define NX_HTTP_SERVER_RETRY_SHIFT 1 /* Every retry is twice as long */ #endif -/* NX_HTTP_MAX_STRING is base64 of "name:password" and plus 1 if an extra conversion is needed. */ -#define NX_HTTP_MAX_STRING ((NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 1) * 4 / 3 + 1) +/* NX_HTTP_MAX_STRING is base64 of "name:password" and plus 1 if an extra conversion is needed and plus 2 pad if needed. */ +#define NX_HTTP_MAX_STRING ((NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 1) * 4 / 3 + 1 + 2) #define NX_HTTP_MAX_BINARY_MD5 16 #define NX_HTTP_MAX_ASCII_MD5 32 @@ -576,8 +580,6 @@ UINT _nx_http_server_calculate_content_offset(NX_PACKET *packet_ptr); UINT _nx_http_server_number_convert(UINT number, CHAR *string); UINT _nx_http_server_type_get(NX_HTTP_SERVER *server_ptr, CHAR *name, CHAR *http_type_string); UINT _nx_http_server_type_get_extended(NX_HTTP_SERVER *server_ptr, CHAR *name, UINT name_length, CHAR *http_type_string, UINT http_type_string_max_size); -VOID _nx_http_base64_encode(CHAR *name, UINT length, CHAR *base64name); -VOID _nx_http_base64_decode(CHAR *base64name, UINT length, CHAR *name); #ifdef NX_HTTP_DIGEST_ENABLE UINT _nx_http_server_digest_authenticate(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, UINT name_length, CHAR *password_ptr, UINT password_length, CHAR *realm_ptr, UINT realm_length, UINT *auth_request_present); diff --git a/addons/pop3/nx_pop3_client.c b/addons/pop3/nx_pop3_client.c index 6eaa6de..c52460e 100644 --- a/addons/pop3/nx_pop3_client.c +++ b/addons/pop3/nx_pop3_client.c @@ -2399,7 +2399,7 @@ UINT size; /* FUNCTION RELEASE */ /* */ /* _nx_pop3_client_connect PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -2446,6 +2446,9 @@ UINT size; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* corrected the client port, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_pop3_client_connect(NX_POP3_CLIENT *client_ptr, ULONG server_ip_address, ULONG server_port) @@ -2465,7 +2468,7 @@ CHAR argument[10]; return NX_POP3_PARAM_ERROR; } - status = nx_tcp_client_socket_bind(&client_ptr -> nx_pop3_client_tcp_socket, 4228, NX_IP_PERIODIC_RATE); + status = nx_tcp_client_socket_bind(&client_ptr -> nx_pop3_client_tcp_socket, NX_ANY_PORT, NX_IP_PERIODIC_RATE); /* Check for error. */ if (status != NX_SUCCESS) diff --git a/addons/smtp/nx_smtp_client.c b/addons/smtp/nx_smtp_client.c index 5d5bd2c..895d86d 100644 --- a/addons/smtp/nx_smtp_client.c +++ b/addons/smtp/nx_smtp_client.c @@ -20,33 +20,6 @@ /**************************************************************************/ /**************************************************************************/ -/**************************************************************************/ -/* */ -/* APPLICATION INTERFACE DEFINITION RELEASE */ -/* */ -/* nx_smtp_client.c PORTABLE C */ -/* 6.1 */ -/* 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. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ - #define NX_SMTP_SOURCE_CODE @@ -78,8 +51,6 @@ static CHAR _nx_smtp_buffer[NX_SMTP_BUFFER_SIZE]; /* Define internal SMTP Client functions. */ static VOID _nx_smtp_find_crlf(UCHAR *buffer, UINT length, UCHAR **CRLF, UINT reverse); -static VOID _nx_smtp_base64_encode(UCHAR *name, UCHAR *base64name, UINT length); -static VOID _nx_smtp_base64_decode(UCHAR *base64name, UCHAR *name); static UINT _nx_smtp_cmd_idle(NX_SMTP_CLIENT *client_ptr); static UINT _nx_smtp_rsp_idle(NX_SMTP_CLIENT *client_ptr); static UINT _nx_smtp_cmd_greeting(NX_SMTP_CLIENT *client_ptr); @@ -112,7 +83,7 @@ static UINT _nx_smtp_utility_send_to_server(NX_SMTP_CLIENT *client_ptr, CHAR *bu static UINT _nx_smtp_utility_authentication_challenge(NX_SMTP_CLIENT *client_ptr, UCHAR *buffer_ptr, UINT length); static UINT _nx_smtp_client_process(NX_SMTP_CLIENT *client_ptr); static UINT _nx_smtp_utility_send_header_to_server(NX_SMTP_CLIENT *client_ptr, ULONG timeout) ; -static UINT _nx_smtp_utility_parse_server_services(NX_SMTP_CLIENT *client_ptr); +static VOID _nx_smtp_utility_parse_server_services(NX_SMTP_CLIENT *client_ptr); static UINT _nx_smtp_parse_250_response(UCHAR *buffer_ptr, UINT buffer_length, UINT *is_last_code); static UINT _nx_smtp_parse_response(NX_SMTP_CLIENT *client_ptr, UCHAR *buffer, UINT arguement_index, UINT buffer_length, UCHAR *arguement, UINT arguement_length, @@ -1966,7 +1937,7 @@ UINT auth_length; /* FUNCTION RELEASE */ /* */ /* _nx_smtp_cmd_auth_challenge PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -1988,7 +1959,7 @@ UINT auth_length; /* CALLS */ /* */ /* _nx_smtp_utility_send_to_server Send data to server */ -/* _nx_smtp_base64_encode Base64 encode specified text */ +/* _nx_utility_base64_encode Base64 encode specified text */ /* memcpy Copy data to area of memory */ /* */ /* CALLED BY */ @@ -2004,6 +1975,10 @@ UINT auth_length; /* buffer length verification, */ /* verified memcpy use cases, */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_smtp_cmd_auth_challenge(NX_SMTP_CLIENT *client_ptr) @@ -2011,7 +1986,8 @@ UINT _nx_smtp_cmd_auth_challenge(NX_SMTP_CLIENT *client_ptr) UINT status; UINT index; -UCHAR auth_reply_encoded[NX_SMTP_CLIENT_AUTH_CHALLENGE_ENCODED_SIZE + 1]; +UCHAR auth_reply_encoded[NX_SMTP_CLIENT_AUTH_CHALLENGE_ENCODED_SIZE + 1]; +UINT auth_reply_encoded_size; UINT length; UINT password_length; @@ -2056,14 +2032,14 @@ UINT password_length; length += password_length; /* Now encode the combined client username/password. */ - _nx_smtp_base64_encode(&plain_auth_buffer[0], auth_reply_encoded, length); + _nx_utility_base64_encode(&plain_auth_buffer[0], length, auth_reply_encoded, sizeof(auth_reply_encoded), &auth_reply_encoded_size); } else { + /* Just encode the client username. */ - _nx_smtp_base64_encode((UCHAR *)client_ptr -> nx_smtp_username, auth_reply_encoded, - length); + _nx_utility_base64_encode((UCHAR *)client_ptr -> nx_smtp_username, length, auth_reply_encoded, sizeof(auth_reply_encoded), &auth_reply_encoded_size); } } @@ -2072,8 +2048,7 @@ UINT password_length; { /* Encode the client password. */ - _nx_smtp_base64_encode((UCHAR *)client_ptr -> nx_smtp_password, auth_reply_encoded, - password_length); + _nx_utility_base64_encode((UCHAR *)client_ptr -> nx_smtp_password, password_length, auth_reply_encoded, sizeof(auth_reply_encoded), &auth_reply_encoded_size); } else @@ -2081,14 +2056,10 @@ UINT password_length; /* Unknown prompt: Send the '*' to terminate the authentication process. */ memcpy(auth_reply_encoded, NX_SMTP_CANCEL_AUTHENTICATION, sizeof(NX_SMTP_CANCEL_AUTHENTICATION)); /* Use case of memcpy is verified. */ + auth_reply_encoded_size = sizeof(NX_SMTP_CANCEL_AUTHENTICATION) - 1; } - if (_nx_utility_string_length_check((CHAR *)auth_reply_encoded, &length, sizeof(auth_reply_encoded) - 1)) - { - return(NX_SIZE_ERROR); - } - - if (sizeof(_nx_smtp_buffer) < (length + sizeof(NX_SMTP_LINE_TERMINATOR) - 1)) + if (sizeof(_nx_smtp_buffer) < (auth_reply_encoded_size + sizeof(NX_SMTP_LINE_TERMINATOR) - 1)) { /* Buffer size too small. */ @@ -2096,8 +2067,8 @@ UINT password_length; } /* Format the encoded response. */ - memcpy(&_nx_smtp_buffer[0],auth_reply_encoded, length); /* Use case of memcpy is verified. */ - index = length; + memcpy(&_nx_smtp_buffer[0],auth_reply_encoded, auth_reply_encoded_size); /* Use case of memcpy is verified. */ + index = auth_reply_encoded_size; memcpy(&_nx_smtp_buffer[index], NX_SMTP_LINE_TERMINATOR, sizeof(NX_SMTP_LINE_TERMINATOR) - 1); /* Use case of memcpy is verified. */ index += sizeof(NX_SMTP_LINE_TERMINATOR) - 1; @@ -3812,7 +3783,7 @@ UINT subject_length; /* FUNCTION RELEASE */ /* */ /* _nx_smtp_utility_authentication_challenge PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -3837,7 +3808,7 @@ UINT subject_length; /* CALLS */ /* */ /* _nx_smtp_parse_response Parses argument from buffer text */ -/* _nx_smtp_base64_decode Decodes base64 text */ +/* _nx_utility_base64_decode Decodes base64 text */ /* memset Clears specified area of memory */ /* memcmp Compares data between areas of memory */ /* */ @@ -3852,6 +3823,10 @@ UINT subject_length; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved the logic of */ +/* parsing base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_smtp_utility_authentication_challenge(NX_SMTP_CLIENT *client_ptr, UCHAR *server_challenge, UINT length) @@ -3859,6 +3834,8 @@ UINT _nx_smtp_utility_authentication_challenge(NX_SMTP_CLIENT *client_ptr, UCHA UCHAR encrypted_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; +UINT encrypted_server_prompt_size; +UINT decoded_server_prompt_size; if (client_ptr -> nx_smtp_client_authentication_type == NX_SMTP_CLIENT_AUTH_PLAIN) { @@ -3887,11 +3864,18 @@ UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; return NX_SMTP_INVALID_SERVER_REPLY; } + /* Calculate the name length. */ + if (_nx_utility_string_length_check((CHAR *)encrypted_server_prompt, &encrypted_server_prompt_size, NX_SMTP_SERVER_CHALLENGE_MAX_STRING)) + { + return NX_SMTP_INVALID_SERVER_REPLY; + } + /* Decode the parsed server challenge. */ - _nx_smtp_base64_decode(encrypted_server_prompt, decoded_server_prompt); + _nx_utility_base64_decode(encrypted_server_prompt, encrypted_server_prompt_size, decoded_server_prompt, sizeof(decoded_server_prompt), &decoded_server_prompt_size); /* Is this a username prompt? */ - if (((decoded_server_prompt[0] == 'U') || (decoded_server_prompt[0] == 'u')) && + if ((decoded_server_prompt_size == 9) && + ((decoded_server_prompt[0] == 'U') || (decoded_server_prompt[0] == 'u')) && ((decoded_server_prompt[1] == 'S') || (decoded_server_prompt[1] == 's')) && ((decoded_server_prompt[2] == 'E') || (decoded_server_prompt[2] == 'e')) && ((decoded_server_prompt[3] == 'R') || (decoded_server_prompt[3] == 'r')) && @@ -3906,7 +3890,8 @@ UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; client_ptr -> nx_smtp_client_authentication_reply = NX_SMTP_CLIENT_REPLY_TO_USERNAME_PROMPT; } /* Is this a password prompt? */ - else if (((decoded_server_prompt[0] == 'P') || (decoded_server_prompt[0] == 'p')) && + else if ((decoded_server_prompt_size == 9) && + ((decoded_server_prompt[0] == 'P') || (decoded_server_prompt[0] == 'p')) && ((decoded_server_prompt[1] == 'A') || (decoded_server_prompt[1] == 'a')) && ((decoded_server_prompt[2] == 'S') || (decoded_server_prompt[2] == 's')) && ((decoded_server_prompt[3] == 'S') || (decoded_server_prompt[3] == 's')) && @@ -3937,7 +3922,7 @@ UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; /* FUNCTION RELEASE */ /* */ /* _nx_smtp_utility_parse_server_services PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -3957,7 +3942,7 @@ UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; /* */ /* OUTPUT */ /* */ -/* NX_SUCCESS Successful completion status */ +/* None */ /* */ /* CALLS */ /* */ @@ -3974,9 +3959,12 @@ UCHAR decoded_server_prompt[NX_SMTP_SERVER_CHALLENGE_MAX_STRING + 1]; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), */ +/* improved boundary check, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ -UINT _nx_smtp_utility_parse_server_services(NX_SMTP_CLIENT *client_ptr) +VOID _nx_smtp_utility_parse_server_services(NX_SMTP_CLIENT *client_ptr) { UINT plain_option = NX_FALSE; @@ -3996,6 +3984,12 @@ UINT found = NX_FALSE; /* Find the location of the AUTH command. */ work_ptr = client_ptr -> nx_smtp_server_packet -> nx_packet_prepend_ptr; + /* Check length. */ + if (length <= 4) + { + return; + } + for (i = 0; i < length - 4; i++) { if ( @@ -4019,7 +4013,7 @@ UINT found = NX_FALSE; { /* It does not. So leave the Client authentication type as is. */ - return NX_SUCCESS; + return; } /* Check if the client prefers no authentication. */ @@ -4027,14 +4021,24 @@ UINT found = NX_FALSE; { /* There is an AUTH keyword but the client prefers not to authenticate. */ - return NX_SUCCESS; + return; } /* Save the location where the search stopped. */ temp_ptr = work_ptr; found = NX_FALSE; - new_length = (length - 5) - (ULONG)(temp_ptr - client_ptr -> nx_smtp_server_packet -> nx_packet_prepend_ptr); + new_length = length - (ULONG)(temp_ptr - client_ptr -> nx_smtp_server_packet -> nx_packet_prepend_ptr); + + /* Check length. */ + if (new_length < 5) + { + return; + } + else + { + new_length -= 5; + } /* Search for supported authentication types. */ for (i = 0; i < new_length; i++) @@ -4100,14 +4104,14 @@ UINT found = NX_FALSE; if (login_option) { - return NX_SUCCESS; + return; } else { /* Switch client to plain authentication. */ client_ptr -> nx_smtp_client_authentication_type = NX_SMTP_CLIENT_AUTH_PLAIN; - return NX_SUCCESS; + return; } } @@ -4115,7 +4119,7 @@ UINT found = NX_FALSE; if (plain_option && (client_ptr -> nx_smtp_client_authentication_type == NX_SMTP_CLIENT_AUTH_PLAIN)) { /* Yes, and there's a match, we're done here. */ - return NX_SUCCESS; + return; } /* If we are here, the server offers LOGIN authentication but the Client preference is something else. */ @@ -4125,15 +4129,15 @@ UINT found = NX_FALSE; /* Switch client to LOGIN authentication. */ client_ptr -> nx_smtp_client_authentication_type = NX_SMTP_CLIENT_AUTH_LOGIN; - return NX_SUCCESS; + return; } /* Handle the case of no matches between server/client. Assume the server requires authentication and set Client type to plain. */ client_ptr -> nx_smtp_client_authentication_type = NX_SMTP_CLIENT_AUTH_PLAIN; - /* Return successful completion of checking options. */ - return NX_SUCCESS; + /* Return. */ + return; } @@ -4142,7 +4146,7 @@ UINT found = NX_FALSE; /* FUNCTION RELEASE */ /* */ /* _nx_smtp_parse_response PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -4192,6 +4196,9 @@ UINT found = NX_FALSE; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), */ +/* improved boundary check, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_smtp_parse_response(NX_SMTP_CLIENT *client_ptr, UCHAR *buffer, UINT argument_index, @@ -4207,17 +4214,15 @@ UCHAR *work_ptr; UINT is_last_code; - memset(&argument[0], 0, argument_length); - work_ptr = argument; - /* Check for invalid input parameters. */ - if ((buffer == NX_NULL) || (argument == NX_NULL) || (buffer_length == 0) || - (argument_length == 0) || (argument_index == 0)) + if ((buffer == NX_NULL) || (buffer_length == 0) || (argument_index == 0)) { return NX_SMTP_INVALID_PARAM; } + work_ptr = argument; + /* Is this the first word? The first word is the reply code, not an SMTP command parameter */ if (argument_index == 1) @@ -4242,6 +4247,11 @@ UINT is_last_code; else if ((*buffer >= 0x30) && (*buffer <= 0x39)) { + if (work_ptr >= argument + argument_length) + { + return(NX_SMTP_INTERNAL_ERROR); + } + /* Yes, copy to buffer. */ *work_ptr = *buffer; work_ptr++; @@ -4257,19 +4267,6 @@ UINT is_last_code; buffer++; i++; } - - /* Are we at the end of the buffer? */ - if (i == buffer_length) - { - - /* Yes, is there a line terminator? */ - if (*(argument - 2) == 0x0D && *(argument - 1) == 0x0A) - { - - /* Yes, remove it with a null character */ - *(argument - 2) = (CHAR) 0x0; - } - } } else { @@ -4547,270 +4544,3 @@ UINT i = 0; return ; } - - -CHAR _nx_smtp_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _nx_smtp_base64_encode PORTABLE C */ -/* 6.1 */ -/* AUTHOR */ -/* */ -/* Yuxin Zhou, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function encodes the input string into a base64 */ -/* representation. It is the caller's responsibility to match the */ -/* name and base64name buffers in size to avoid overwriting memory. */ -/* */ -/* INPUT */ -/* */ -/* name Pointer to name to encode */ -/* base64name Pointer to name base64 encoded */ -/* length Size of input buffer to encode */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* None */ -/* */ -/* CALLED BY */ -/* */ -/* Application Code */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ -VOID _nx_smtp_base64_encode(UCHAR *name, UCHAR *base64name, UINT length) -{ - -UINT pad; -UINT i, j; -UINT step; - - - /* Adjust the length to represent the base64 name. */ - length = ((length * 8) / 6); - - /* Default padding to none. */ - pad = 0; - - /* Determine if an extra conversion is needed. */ - if ((length * 6) % 24) - { - /* Some padding is needed. */ - - /* Calculate the number of pad characters. */ - pad = (length * 6) % 24; - pad = (24 - pad) / 6; - pad = pad - 1; - - /* Adjust the length to pickup the character fraction. */ - length++; - } - - /* Setup index into the base64name. */ - j = 0; - - /* Compute the base64name. */ - step = 0; - i = 0; - while (j < length) - { - /* Determine which step we are in. */ - if (step == 0) - { - /* Use first 6 bits of name character for index. */ - base64name[j++] = (UCHAR)_nx_smtp_base64_array[((UINT) name[i]) >> 2]; - step++; - } - else if (step == 1) - { - - /* Use last 2 bits of name character and first 4 bits of next name character for index. */ - base64name[j++] = (UCHAR)_nx_smtp_base64_array[((((UINT) name[i]) & 0x3) << 4) | (((UINT) name[i+1]) >> 4)]; - i++; - step++; - } - else if (step == 2) - { - - /* Use last 4 bits of name character and first 2 bits of next name character for index. */ - base64name[j++] = (UCHAR)_nx_smtp_base64_array[((((UINT) name[i]) & 0xF) << 2) | (((UINT) name[i+1]) >> 6)]; - i++; - step++; - } - else /* Step 3 */ - { - - /* Use last 6 bits of name character for index. */ - base64name[j++] = (UCHAR)_nx_smtp_base64_array[(((UINT) name[i]) & 0x3F)]; - i++; - step = 0; - } - } - - /* Determine if the index needs to be advanced. */ - if (step != 3) - i++; - - /* Now add the PAD characters. */ - while ((pad--) && (j < NX_SMTP_CLIENT_AUTH_CHALLENGE_ENCODED_SIZE)) - { - - /* Pad base64name with '=' characters. */ - base64name[j++] = '='; - } - - /* Put a NULL character in. */ - base64name[j] = NX_NULL; -} - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _nx_smtp_base64_decode PORTABLE C */ -/* 6.1 */ -/* AUTHOR */ -/* */ -/* Yuxin Zhou, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function decodes the input base64 ASCII string and converts */ -/* it into a standard ASCII representation. It is the caller's */ -/* responsibility to match the name and base64name buffers in size to */ -/* avoid overwriting memory. */ -/* */ -/* INPUT */ -/* */ -/* base64name Encoded base64 name string */ -/* name Name string */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _nx_utility_string_length_check Get length of string */ -/* */ -/* CALLED BY */ -/* */ -/* _nx_smtp_server_basic_authenticate Basic authentication */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ -/* 09-30-2020 Yuxin Zhou Modified comment(s), */ -/* resulting in version 6.1 */ -/* */ -/**************************************************************************/ -VOID _nx_smtp_base64_decode(UCHAR *base64name, UCHAR *name) -{ - -UINT length; -UINT i, j; -UINT value1, value2; -UINT step; - - - /* Calculate the name length. */ - if (_nx_utility_string_length_check((CHAR *)base64name, &length, NX_SMTP_SERVER_CHALLENGE_MAX_STRING)) - { - name[0] = NX_NULL; - return; - } - - /* Adjust the length to represent the ASCII name. */ - length = ((length * 6) / 8); - - /* Setup index into the ASCII name. */ - j = 0; - - /* Compute the ASCII name. */ - step = 0; - i = 0; - - while ((j < length) && (base64name[i]) && (base64name[i] != '=') && (j < NX_SMTP_CLIENT_AUTH_CHALLENGE_SIZE)) - { - - /* Derive values of the Base64 name. */ - if ((base64name[i] >= 'A') && (base64name[i] <= 'Z')) - value1 = (UINT) (base64name[i] - 'A'); - else if ((base64name[i] >= 'a') && (base64name[i] <= 'z')) - value1 = (UINT) (base64name[i] - 'a') + 26; - else if ((base64name[i] >= '0') && (base64name[i] <= '9')) - value1 = (UINT) (base64name[i] - '0') + 52; - else if (base64name[i] == '+') - value1 = 62; - else if (base64name[i] == '/') - value1 = 63; - else - value1 = 0; - - /* Derive value for the next character. */ - if ((base64name[i+1] >= 'A') && (base64name[i+1] <= 'Z')) - value2 = (UINT) (base64name[i+1] - 'A'); - else if ((base64name[i+1] >= 'a') && (base64name[i+1] <= 'z')) - value2 = (UINT) (base64name[i+1] - 'a') + 26; - else if ((base64name[i+1] >= '0') && (base64name[i+1] <= '9')) - value2 = (UINT) (base64name[i+1] - '0') + 52; - else if (base64name[i+1] == '+') - value2 = 62; - else if (base64name[i+1] == '/') - value2 = 63; - else - value2 = 0; - - /* Determine which step we are in. */ - if (step == 0) - { - - /* Use first value and first 2 bits of second value. */ - name[j++] = (UCHAR) (((value1 & 0x3f) << 2) | ((value2 >> 4) & 3)); - i++; - step++; - } - else if (step == 1) - { - - /* Use last 4 bits of first value and first 4 bits of next value. */ - name[j++] = (UCHAR) (((value1 & 0xF) << 4) | (value2 >> 2)); - i++; - step++; - } - else if (step == 2) - { - - /* Use first 2 bits and following 6 bits of next value. */ - name[j++] = (UCHAR) (((value1 & 3) << 6) | (value2 & 0x3f)); - i++; - i++; - step = 0; - } - } - - /* Put a NULL character in. */ - name[j] = NX_NULL; - - return; -} - diff --git a/addons/snmp/nx_snmp.c b/addons/snmp/nx_snmp.c index f5eecf3..8aa24c9 100644 --- a/addons/snmp/nx_snmp.c +++ b/addons/snmp/nx_snmp.c @@ -1610,7 +1610,7 @@ UINT _nx_snmp_agent_version_set(NX_SNMP_AGENT *agent_ptr, UINT enabled_v1, UINT /* FUNCTION RELEASE */ /* */ /* _nx_snmp_agent_set_interface PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -1643,6 +1643,9 @@ UINT _nx_snmp_agent_version_set(NX_SNMP_AGENT *agent_ptr, UINT enabled_v1, UINT /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), */ +/* checked the interface index,*/ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nxe_snmp_agent_set_interface(NX_SNMP_AGENT *agent_ptr, UINT if_index) @@ -1654,6 +1657,12 @@ UINT status; return NX_PTR_ERROR; } + /* Check for valid interface index. */ + if (if_index >= NX_MAX_PHYSICAL_INTERFACES) + { + return(NX_INVALID_INTERFACE); + } + status = _nx_snmp_agent_set_interface(agent_ptr, if_index); return status; @@ -3796,7 +3805,7 @@ UINT status; /* FUNCTION RELEASE */ /* */ /* _nx_snmp_agent_trap_send PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -3853,6 +3862,9 @@ UINT status; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), */ +/* checked the interface index,*/ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_snmp_agent_trap_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UCHAR *enterprise, @@ -4032,6 +4044,21 @@ UINT packet_type; trap_object_data.nx_snmp_object_data_type = NX_SNMP_ANS1_IP_ADDRESS; + + /* Check if the interface index is valid. */ + if (agent_ptr -> nx_snmp_agent_interface_index >= NX_MAX_PHYSICAL_INTERFACES) + { + + /* Increment the internal error counter. */ + agent_ptr -> nx_snmp_agent_internal_errors++; + + /* Release the trap packet. */ + nx_packet_release(trap_packet_ptr); + + /* Return to caller. */ + return(NX_SNMP_ERROR); + } + trap_object_data.nx_snmp_object_data_msw = (LONG)(agent_ptr -> nx_snmp_agent_ip_ptr) -> nx_ip_interface[agent_ptr -> nx_snmp_agent_interface_index].nx_interface_ip_address; @@ -15818,7 +15845,7 @@ UINT _nx_snmp_utility_version_set(UCHAR *buffer_ptr, UINT snmp_version, UCHAR * /* FUNCTION RELEASE */ /* */ /* _nx_snmp_version_error_response PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -15863,13 +15890,16 @@ UINT _nx_snmp_utility_version_set(UCHAR *buffer_ptr, UINT snmp_version, UCHAR * /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), improved */ +/* verification of encryption, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ VOID _nx_snmp_version_error_response(NX_SNMP_AGENT *agent_ptr, NX_PACKET *packet_ptr, UCHAR *request_type_ptr, UCHAR *error_string_ptr, UINT error_code, UINT error_index) { -UINT status; +UINT status = NX_SUCCESS; #ifndef NX_SNMP_DISABLE_V3 ULONG temp; #endif @@ -15914,24 +15944,47 @@ ULONG temp; _nx_snmp_utility_error_info_set(error_string_ptr, error_code, error_index, packet_ptr -> nx_packet_data_end); #ifndef NX_SNMP_DISABLE_V3 - /* Is the security set to encryption? */ - temp = (ULONG)agent_ptr -> nx_snmp_agent_v3_message_security_options; - if (temp & NX_SNMP_SECURITY_PRIVACY) + + if (agent_ptr -> nx_snmp_agent_current_version == NX_SNMP_VERSION_3) { - /* Encrypt the PDU and setup the response to have an encryption header. This - will also compute our privacy parameter. */ - _nx_snmp_agent_encrypt_pdu(agent_ptr, NX_NULL, NX_NULL, - NX_NULL, NX_NULL, - NX_NULL, NX_NULL, pdu_privacy_ptr); - } + /* Is the security set to encryption? */ + temp = (ULONG)agent_ptr -> nx_snmp_agent_v3_message_security_options; + if (temp & NX_SNMP_SECURITY_PRIVACY) + { - /* Is the security set to authentication? */ - if (temp & NX_SNMP_SECURITY_AUTHORIZE) - { + /* Encrypt the PDU and setup the response to have an encryption header. This + will also compute our privacy parameter. */ + status = _nx_snmp_agent_encrypt_pdu(agent_ptr, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, pdu_privacy_ptr); + + /* Check status. */ + if (status) + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + return; + } + } + + /* Is the security set to authentication? */ + if (temp & NX_SNMP_SECURITY_AUTHORIZE) + { - /* Compute our authentication parameter. */ - status = _nx_snmp_agent_add_auth_parameter(agent_ptr, packet_ptr, pdu_auth_parm_ptr); + /* Compute our authentication parameter. */ + status = _nx_snmp_agent_add_auth_parameter(agent_ptr, packet_ptr, pdu_auth_parm_ptr); + + /* Check status. */ + if (status) + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + return; + } + } } #endif @@ -17955,7 +18008,7 @@ INT buffer_length; /* FUNCTION RELEASE */ /* */ /* _nx_snmp_version_3_process PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -18020,6 +18073,10 @@ INT buffer_length; /* 09-30-2020 Yuxin Zhou Modified comment(s), and */ /* verified memcpy use cases, */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* improved boundary check, */ +/* checked NULL pointer, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ VOID _nx_snmp_version_3_process(NX_SNMP_AGENT *agent_ptr, NX_PACKET *packet_ptr) @@ -18490,6 +18547,23 @@ INT buffer_length; else { + /* Check if security option is set, but the security parameter is empty.*/ + if (agent_ptr -> nx_snmp_agent_v3_message_security_options) + { + + /* Increment the invalid packet error counter. */ + agent_ptr -> nx_snmp_agent_invalid_packets++; + + /* Increment the internal error counter. */ + agent_ptr -> nx_snmp_agent_internal_errors++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return; + } + /* Position past the empty security parameter field. */ length = 2; } @@ -18693,7 +18767,7 @@ INT buffer_length; return; } - else + else if (request_authentication_ptr) { /* Otherwise Ok to process authentication parameter. */ authenticate_message = NX_TRUE; @@ -20150,6 +20224,23 @@ INT buffer_length; /* Calculate the total variable size. */ total_variable_length = variable_length + length; + if ((length == 0) || (total_variable_length > variable_list_length) || + (total_variable_length > (UINT)buffer_length)) + { + + /* Increment the invalid packet error counter. */ + agent_ptr -> nx_snmp_agent_invalid_packets++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Release the response packet. */ + nx_packet_release(response_packet_ptr); + + /* Return to caller. */ + return; + } + /* Move the buffer pointer up. */ buffer_ptr = buffer_ptr + length; @@ -21900,7 +21991,7 @@ UCHAR report_security_level; /* FUNCTION RELEASE */ /* */ /* _nx_snmp_agent_add_auth_parameter PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -21943,6 +22034,9 @@ UCHAR report_security_level; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), */ +/* checked NULL pointer, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _nx_snmp_agent_add_auth_parameter(NX_SNMP_AGENT *agent_ptr, NX_PACKET *response_packet_ptr, UCHAR *response_authentication_ptr) @@ -21952,6 +22046,11 @@ UINT i; UCHAR key1[NX_SNMP_DIGEST_WORKING_SIZE]; UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE]; + /* Check if the pointer is NULL. */ + if (!response_authentication_ptr) + { + return(NX_SNMP_UNSUPPORTED_AUTHENTICATION); + } /* Determine which authentication is required. */ if ((agent_ptr -> nx_snmp_agent_v3_authentication_key) && @@ -22079,7 +22178,7 @@ UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE]; /* FUNCTION RELEASE */ /* */ /* _nx_snmp_agent_encrypt_pdu PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -22123,6 +22222,9 @@ UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE]; /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ /* 09-30-2020 Yuxin Zhou Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), improved */ +/* verification of encryption, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -22164,6 +22266,13 @@ UINT adjusted_pdu_length; } else { + + /* Check if the pointer is NULL. */ + if (!pdu_buffer_ptr) + { + return(NX_SNMP_INVALID_PDU_ENCRYPTION); + } + /* Set the temp ptr to where the PDU starts in the request packet. */ temp_ptr = pdu_buffer_ptr; adjusted_pdu_length = pdu_length; diff --git a/common/inc/nx_api.h b/common/inc/nx_api.h index 3979c3c..982f274 100644 --- a/common/inc/nx_api.h +++ b/common/inc/nx_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* nx_api.h PORTABLE C */ -/* 6.1.5 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Yuxin Zhou, Microsoft Corporation */ @@ -63,6 +63,9 @@ /* 03-02-2021 Yuxin Zhou Modified comment(s), and */ /* updated product constants, */ /* resulting in version 6.1.5 */ +/* 04-02-2021 Yuxin Zhou Modified comment(s), and */ +/* added functions for base64, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -371,7 +374,7 @@ VOID _nx_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, ULONG #define AZURE_RTOS_NETX #define NETX_MAJOR_VERSION 6 #define NETX_MINOR_VERSION 1 -#define NETX_PATCH_VERSION 5 +#define NETX_PATCH_VERSION 6 /* The following symbols are defined for backward compatibility reasons.*/ #define EL_PRODUCT_NETX @@ -2380,6 +2383,8 @@ VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index); /* Utility functions. */ UINT _nx_utility_string_length_check(CHAR *input_string, UINT *string_length, UINT max_string_length); UINT _nx_utility_string_to_uint(CHAR *input_string, UINT string_length, UINT *number); +UINT _nx_utility_base64_encode(UCHAR *name, UINT name_size, UCHAR *base64name, UINT base64name_size, UINT *bytes_copied); +UINT _nx_utility_base64_decode(UCHAR *base64name, UINT base64name_size, UCHAR *name, UINT name_size, UINT *bytes_copied); /* Determine if a C++ compiler is being used. If so, complete the standard C conditional started above. */ diff --git a/common/src/nx_utility.c b/common/src/nx_utility.c index 86e7284..3e3c69e 100644 --- a/common/src/nx_utility.c +++ b/common/src/nx_utility.c @@ -28,6 +28,8 @@ #include "tx_api.h" #include "nx_api.h" +/* Define the base64 letters. */ +static CHAR _nx_utility_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /**************************************************************************/ /* */ @@ -199,3 +201,310 @@ UINT i; /* Return success. */ return(NX_SUCCESS); } + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_utility_base64_encode PORTABLE C */ +/* 6.1.6 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function encodes the input string into a base64 */ +/* representation. */ +/* */ +/* INPUT */ +/* */ +/* name Name string */ +/* name_size Size of name */ +/* base64name Encoded base64 name string */ +/* base64name_size Size of encoded base64 name */ +/* bytes_copied Number of bytes copied */ +/* */ +/* OUTPUT */ +/* */ +/* status Completion status */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 04-02-2021 Yuxin Zhou Initial Version 6.1.6 */ +/* */ +/**************************************************************************/ +UINT _nx_utility_base64_encode(UCHAR *name, UINT name_size, UCHAR *base64name, UINT base64name_size, UINT *bytes_copied) +{ +UINT pad; +UINT i, j; +UINT step; + + + /* Check for invalid input pointers. */ + if ((name == NX_NULL) || (base64name == NX_NULL) || (bytes_copied == NX_NULL)) + { + return(NX_PTR_ERROR); + } + + /* Check the size. */ + if ((name_size == 0) || (base64name_size == 0)) + { + return(NX_SIZE_ERROR); + } + + /* Adjust the length to represent the base64 name. */ + name_size = ((name_size * 8) / 6); + + /* Default padding to none. */ + pad = 0; + + /* Determine if an extra conversion is needed. */ + if ((name_size * 6) % 24) + { + + /* Some padding is needed. */ + + /* Calculate the number of pad characters. */ + pad = (name_size * 6) % 24; + pad = (24 - pad) / 6; + pad = pad - 1; + + /* Adjust the length to pickup the character fraction. */ + name_size++; + } + + /* Check the buffer size. */ + if (base64name_size <= (name_size + pad)) + { + return(NX_SIZE_ERROR); + } + + /* Setup index into the base64name. */ + j = 0; + + /* Compute the base64name. */ + step = 0; + i = 0; + while (j < name_size) + { + + /* Determine which step we are in. */ + if (step == 0) + { + + /* Use first 6 bits of name character for index. */ + base64name[j++] = (UCHAR)_nx_utility_base64_array[((UCHAR)name[i]) >> 2]; + step++; + } + else if (step == 1) + { + + /* Use last 2 bits of name character and first 4 bits of next name character for index. */ + base64name[j++] = (UCHAR)_nx_utility_base64_array[((((UCHAR)name[i]) & 0x3) << 4) | (((UCHAR)name[i + 1]) >> 4)]; + i++; + step++; + } + else if (step == 2) + { + + /* Use last 4 bits of name character and first 2 bits of next name character for index. */ + base64name[j++] = (UCHAR)_nx_utility_base64_array[((((UCHAR)name[i]) & 0xF) << 2) | (((UCHAR)name[i + 1]) >> 6)]; + i++; + step++; + } + else /* Step 3 */ + { + + /* Use last 6 bits of name character for index. */ + base64name[j++] = (UCHAR)_nx_utility_base64_array[(((UCHAR)name[i]) & 0x3F)]; + i++; + step = 0; + } + } + + /* Determine if the index needs to be advanced. */ + if (step != 3) + { + i++; + } + + /* Now add the PAD characters. */ + while (pad--) + { + + /* Pad base64name with '=' characters. */ + base64name[j++] = '='; + } + + /* Put a NULL character in. */ + base64name[j] = NX_NULL; + *bytes_copied = j; + + return(NX_SUCCESS); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_utility_base64_decode PORTABLE C */ +/* 6.1.6 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function decodes the input base64 ASCII string and converts */ +/* it into a standard ASCII representation. */ +/* */ +/* INPUT */ +/* */ +/* base64name Encoded base64 name string */ +/* base64name_size Size of encoded base64 name */ +/* name Name string */ +/* name_size Size of name */ +/* bytes_copied Number of bytes copied */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 04-02-2021 Yuxin Zhou Initial Version 6.1.6 */ +/* */ +/**************************************************************************/ +UINT _nx_utility_base64_decode(UCHAR *base64name, UINT base64name_size, UCHAR *name, UINT name_size, UINT *bytes_copied) +{ +UINT i, j; +UINT value1, value2; +UINT step; +UINT source_size = base64name_size; + + /* Check for invalid input pointers. */ + if ((base64name == NX_NULL) || (name == NX_NULL) || (bytes_copied == NX_NULL)) + { + return(NX_PTR_ERROR); + } + + /* Check the size. */ + if ((base64name_size == 0) || (name_size == 0)) + { + return(NX_SIZE_ERROR); + } + + /* Adjust the length to represent the ASCII name. */ + base64name_size = ((base64name_size * 6) / 8); + + if (base64name[source_size - 1] == '=') + { + if (base64name[source_size - 2] == '=') + { + base64name_size --; + } + base64name_size--; + } + + /* Check the buffer size. */ + if (name_size <= base64name_size) + { + return(NX_SIZE_ERROR); + } + + /* Setup index into the ASCII name. */ + j = 0; + + /* Compute the ASCII name. */ + step = 0; + i = 0; + while ((j < base64name_size) && (base64name[i]) && (base64name[i] != '=')) + { + + /* Derive values of the Base64 name. */ + if ((base64name[i] >= 'A') && (base64name[i] <= 'Z')) + value1 = (UINT) (base64name[i] - 'A'); + else if ((base64name[i] >= 'a') && (base64name[i] <= 'z')) + value1 = (UINT) (base64name[i] - 'a') + 26; + else if ((base64name[i] >= '0') && (base64name[i] <= '9')) + value1 = (UINT) (base64name[i] - '0') + 52; + else if ((base64name[i] == '+') || + (base64name[i] == '-')) /* Base64 URL. */ + value1 = 62; + else if ((base64name[i] == '/') || + (base64name[i] == '_')) /* Base64 URL. */ + value1 = 63; + else + value1 = 0; + + /* Derive value for the next character. */ + if ((base64name[i + 1] >= 'A') && (base64name[i + 1] <= 'Z')) + value2 = (UINT) (base64name[i+1] - 'A'); + else if ((base64name[i + 1] >= 'a') && (base64name[i + 1] <= 'z')) + value2 = (UINT) (base64name[i+1] - 'a') + 26; + else if ((base64name[i + 1] >= '0') && (base64name[i + 1] <= '9')) + value2 = (UINT) (base64name[i+1] - '0') + 52; + else if ((base64name[i + 1] == '+') || + (base64name[i + 1] == '-')) /* Base64 URL. */ + value2 = 62; + else if ((base64name[i + 1] == '/') || + (base64name[i + 1] == '_')) /* Base64 URL. */ + value2 = 63; + else + value2 = 0; + + /* Determine which step we are in. */ + if (step == 0) + { + + /* Use first value and first 2 bits of second value. */ + name[j++] = (UCHAR) (((value1 & 0x3f) << 2) | ((value2 >> 4) & 3)); + i++; + step++; + } + else if (step == 1) + { + + /* Use last 4 bits of first value and first 4 bits of next value. */ + name[j++] = (UCHAR) (((value1 & 0xF) << 4) | (value2 >> 2)); + i++; + step++; + } + else if (step == 2) + { + + /* Use first 2 bits and following 6 bits of next value. */ + name[j++] = (UCHAR) (((value1 & 3) << 6) | (value2 & 0x3f)); + i++; + i++; + step = 0; + } + } + + /* Put a NULL character in. */ + name[j] = NX_NULL; + *bytes_copied = j; + + return(NX_SUCCESS); +} \ No newline at end of file