Mark Radbourne / Mbed 2 deprecated iothub_client_sample_amqp

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sasl_plain.c Source File

sasl_plain.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #ifdef _CRTDBG_MAP_ALLOC
00006 #include <crtdbg.h>
00007 #endif
00008 #include <string.h>
00009 #include "azure_uamqp_c/sasl_plain.h"
00010 #include "azure_uamqp_c/amqpalloc.h"
00011 
00012 typedef struct SASL_PLAIN_INSTANCE_TAG
00013 {
00014     unsigned char* init_bytes;
00015     uint32_t init_bytes_length;
00016 } SASL_PLAIN_INSTANCE;
00017 
00018 static const SASL_MECHANISM_INTERFACE_DESCRIPTION saslplain_interface =
00019 {
00020     /* Codes_SRS_SASL_PLAIN_01_015: [**saslplain_get_interface shall return a pointer to a SASL_MECHANISM_INTERFACE_DESCRIPTION  structure that contains pointers to the functions: saslplain_create, saslplain_destroy, saslplain_get_init_bytes, saslplain_get_mechanism_name, saslplain_challenge.] */
00021     saslplain_create,
00022     saslplain_destroy,
00023     saslplain_get_init_bytes,
00024     saslplain_get_mechanism_name,
00025     saslplain_challenge
00026 };
00027 
00028 CONCRETE_SASL_MECHANISM_HANDLE saslplain_create(void* config)
00029 {
00030     SASL_PLAIN_INSTANCE* result;
00031 
00032     if (config == NULL)
00033     {
00034         /* Codes_SRS_SASL_PLAIN_01_003: [If the config argument is NULL, then saslplain_create shall fail and return NULL.] */
00035         result = NULL;
00036     }
00037     else
00038     {
00039         SASL_PLAIN_CONFIG* sasl_plain_config = (SASL_PLAIN_CONFIG*)config;
00040 
00041         /* Codes_SRS_SASL_PLAIN_01_004: [If either the authcid or passwd member of the config structure is NULL, then saslplain_create shall fail and return NULL.] */
00042         if ((sasl_plain_config->authcid == NULL) ||
00043             (sasl_plain_config->passwd == NULL))
00044         {
00045             result = NULL;
00046         }
00047         else
00048         {
00049             size_t authzid_length = sasl_plain_config->authzid == NULL ? 0 : strlen(sasl_plain_config->authzid);
00050             size_t authcid_length = strlen(sasl_plain_config->authcid);
00051             size_t passwd_length = strlen(sasl_plain_config->passwd);
00052 
00053             /* Codes_SRS_SASL_PLAIN_01_020: [   authcid   = 1*SAFE ; MUST accept up to 255 octets] */
00054             if ((authcid_length > 255) || (authcid_length == 0) ||
00055                 /* Codes_SRS_SASL_PLAIN_01_021: [   authzid   = 1*SAFE ; MUST accept up to 255 octets] */
00056                 (authzid_length > 255) ||
00057                 /* Codes_SRS_SASL_PLAIN_01_022: [   passwd    = 1*SAFE ; MUST accept up to 255 octets] */
00058                 (passwd_length > 255) || (passwd_length == 0))
00059             {
00060                 result = NULL;
00061             }
00062             else
00063             {
00064                 /* Codes_SRS_SASL_PLAIN_01_001: [saslplain_create shall return on success a non-NULL handle to a new SASL plain mechanism.] */
00065                 result = amqpalloc_malloc(sizeof(SASL_PLAIN_INSTANCE));
00066                 /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */
00067                 if (result != NULL)
00068                 {
00069                     /* Ignore UTF8 for now */
00070                     result->init_bytes = (unsigned char*)amqpalloc_malloc(authzid_length + authcid_length + passwd_length + 2);
00071                     if (result->init_bytes == NULL)
00072                     {
00073                         /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */
00074                         amqpalloc_free(result);
00075                         result = NULL;
00076                     }
00077                     else
00078                     {
00079                         /* Codes_SRS_SASL_PLAIN_01_016: [The mechanism consists of a single message, a string of [UTF-8] encoded [Unicode] characters, from the client to the server.] */
00080                         /* Codes_SRS_SASL_PLAIN_01_017: [The client presents the authorization identity (identity to act as), followed by a NUL (U+0000) character, followed by the authentication identity (identity whose password will be used), followed by a NUL (U+0000) character, followed by the clear-text password.] */
00081                         /* Codes_SRS_SASL_PLAIN_01_019: [   message   = [authzid] UTF8NUL authcid UTF8NUL passwd] */
00082                         /* Codes_SRS_SASL_PLAIN_01_023: [The authorization identity (authzid), authentication identity (authcid), password (passwd), and NUL character deliminators SHALL be transferred as [UTF-8] encoded strings of [Unicode] characters.] */
00083                         /* Codes_SRS_SASL_PLAIN_01_024: [As the NUL (U+0000) character is used as a deliminator, the NUL (U+0000) character MUST NOT appear in authzid, authcid, or passwd productions.] */
00084 
00085                         /* Codes_SRS_SASL_PLAIN_01_018: [As with other SASL mechanisms, the client does not provide an authorization identity when it wishes the server to derive an identity from the credentials and use that as the authorization identity.] */
00086                         if (authzid_length > 0)
00087                         {
00088                             (void)memcpy(result->init_bytes, sasl_plain_config->authzid, authzid_length);
00089                         }
00090 
00091                         result->init_bytes[authzid_length] = 0;
00092                         (void)memcpy(result->init_bytes + authzid_length + 1, sasl_plain_config->authcid, authcid_length);
00093                         result->init_bytes[authzid_length + authcid_length + 1] = 0;
00094                         (void)memcpy(result->init_bytes + authzid_length + authcid_length + 2, sasl_plain_config->passwd, passwd_length);
00095                         result->init_bytes_length = (uint32_t)(authzid_length + authcid_length + passwd_length + 2);
00096                     }
00097                 }
00098             }
00099         }
00100     }
00101 
00102     return result;
00103 }
00104 
00105 void saslplain_destroy(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle)
00106 {
00107     if (sasl_mechanism_concrete_handle != NULL)
00108     {
00109         /* Codes_SRS_SASL_PLAIN_01_005: [saslplain_destroy shall free all resources associated with the SASL mechanism.] */
00110         SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
00111         if (sasl_plain_instance->init_bytes != NULL)
00112         {
00113             amqpalloc_free(sasl_plain_instance->init_bytes);
00114         }
00115 
00116         amqpalloc_free(sasl_plain_instance);
00117     }
00118 }
00119 
00120 int saslplain_get_init_bytes(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle, SASL_MECHANISM_BYTES* init_bytes)
00121 {
00122     int result;
00123 
00124     if ((sasl_mechanism_concrete_handle == NULL) ||
00125         (init_bytes == NULL))
00126     {
00127         result = __LINE__;
00128     }
00129     else
00130     {
00131         SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
00132 
00133         init_bytes->bytes = sasl_plain_instance->init_bytes;
00134         init_bytes->length = sasl_plain_instance->init_bytes_length;
00135 
00136         /* Codes_SRS_SASL_PLAIN_01_008: [On success saslplain_get_init_bytes shall return zero.] */
00137         result = 0;
00138     }
00139 
00140     return result;
00141 }
00142 
00143 const char* saslplain_get_mechanism_name(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism)
00144 {
00145     const char* result;
00146 
00147     if (sasl_mechanism == NULL)
00148     {
00149         /* Codes_SRS_SASL_PLAIN_01_011: [If the argument concrete_sasl_mechanism is NULL, saslplain_get_mechanism_name shall return NULL.] */
00150         result = NULL;
00151     }
00152     else
00153     {
00154         /* Codes_SRS_SASL_PLAIN_01_010: [saslplain_get_mechanism_name shall validate the argument concrete_sasl_mechanism and on success it shall return a pointer to the string "PLAIN".] */
00155         result = "PLAIN";
00156     }
00157 
00158     return result;
00159 }
00160 
00161 int saslplain_challenge(CONCRETE_SASL_MECHANISM_HANDLE concrete_sasl_mechanism, const SASL_MECHANISM_BYTES* challenge_bytes, SASL_MECHANISM_BYTES* response_bytes)
00162 {
00163     int result;
00164 
00165     (void)challenge_bytes;
00166 
00167     /* Codes_SRS_SASL_PLAIN_01_014: [If the concrete_sasl_mechanism or response_bytes argument is NULL then saslplain_challenge shall fail and return a non-zero value.] */
00168     if ((concrete_sasl_mechanism == NULL) ||
00169         (response_bytes == NULL))
00170     {
00171         result = __LINE__;
00172     }
00173     else
00174     {
00175         /* Codes_SRS_SASL_PLAIN_01_012: [saslplain_challenge shall set the response_bytes buffer to NULL and 0 size as the PLAIN SASL mechanism does not implement challenge/response.] */
00176         response_bytes->bytes = NULL;
00177         response_bytes->length = 0;
00178 
00179         /* Codes_SRS_SASL_PLAIN_01_013: [On success, saslplain_challenge shall return 0.] */
00180         result = 0;
00181     }
00182 
00183     return result;
00184 }
00185 
00186 const SASL_MECHANISM_INTERFACE_DESCRIPTION* saslplain_get_interface(void)
00187 {
00188     return &saslplain_interface;
00189 }