A small memory footprint AMQP implimentation
Dependents: iothub_client_sample_amqp remote_monitoring simplesample_amqp
sasl_plain.c@17:923575db8b2d, 2017-01-24 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Tue Jan 24 15:23:52 2017 -0800
- Revision:
- 17:923575db8b2d
- Parent:
- 6:641a9672db08
- Child:
- 19:000ab4e6a2c1
1.1.5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 0:6ae2f7bca550 | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 0:6ae2f7bca550 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 0:6ae2f7bca550 | 3 | |
Azure.IoT Build | 0:6ae2f7bca550 | 4 | #include <stdlib.h> |
Azure.IoT Build | 0:6ae2f7bca550 | 5 | #include <string.h> |
Azure.IoT Build | 0:6ae2f7bca550 | 6 | #include "azure_uamqp_c/sasl_plain.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 7 | #include "azure_uamqp_c/amqpalloc.h" |
Azure.IoT Build | 0:6ae2f7bca550 | 8 | |
Azure.IoT Build | 0:6ae2f7bca550 | 9 | typedef struct SASL_PLAIN_INSTANCE_TAG |
Azure.IoT Build | 0:6ae2f7bca550 | 10 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 11 | unsigned char* init_bytes; |
AzureIoTClient | 6:641a9672db08 | 12 | uint32_t init_bytes_length; |
Azure.IoT Build | 0:6ae2f7bca550 | 13 | } SASL_PLAIN_INSTANCE; |
Azure.IoT Build | 0:6ae2f7bca550 | 14 | |
Azure.IoT Build | 0:6ae2f7bca550 | 15 | static const SASL_MECHANISM_INTERFACE_DESCRIPTION saslplain_interface = |
Azure.IoT Build | 0:6ae2f7bca550 | 16 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 17 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 18 | saslplain_create, |
Azure.IoT Build | 0:6ae2f7bca550 | 19 | saslplain_destroy, |
Azure.IoT Build | 0:6ae2f7bca550 | 20 | saslplain_get_init_bytes, |
Azure.IoT Build | 0:6ae2f7bca550 | 21 | saslplain_get_mechanism_name, |
Azure.IoT Build | 0:6ae2f7bca550 | 22 | saslplain_challenge |
Azure.IoT Build | 0:6ae2f7bca550 | 23 | }; |
Azure.IoT Build | 0:6ae2f7bca550 | 24 | |
Azure.IoT Build | 0:6ae2f7bca550 | 25 | CONCRETE_SASL_MECHANISM_HANDLE saslplain_create(void* config) |
Azure.IoT Build | 0:6ae2f7bca550 | 26 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 27 | SASL_PLAIN_INSTANCE* result; |
Azure.IoT Build | 0:6ae2f7bca550 | 28 | |
Azure.IoT Build | 0:6ae2f7bca550 | 29 | if (config == NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 30 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 31 | /* Codes_SRS_SASL_PLAIN_01_003: [If the config argument is NULL, then saslplain_create shall fail and return NULL.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 32 | result = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 33 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 34 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 35 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 36 | SASL_PLAIN_CONFIG* sasl_plain_config = (SASL_PLAIN_CONFIG*)config; |
Azure.IoT Build | 0:6ae2f7bca550 | 37 | |
Azure.IoT Build | 0:6ae2f7bca550 | 38 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 39 | if ((sasl_plain_config->authcid == NULL) || |
Azure.IoT Build | 0:6ae2f7bca550 | 40 | (sasl_plain_config->passwd == NULL)) |
Azure.IoT Build | 0:6ae2f7bca550 | 41 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 42 | result = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 43 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 44 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 45 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 46 | size_t authzid_length = sasl_plain_config->authzid == NULL ? 0 : strlen(sasl_plain_config->authzid); |
Azure.IoT Build | 0:6ae2f7bca550 | 47 | size_t authcid_length = strlen(sasl_plain_config->authcid); |
Azure.IoT Build | 0:6ae2f7bca550 | 48 | size_t passwd_length = strlen(sasl_plain_config->passwd); |
Azure.IoT Build | 0:6ae2f7bca550 | 49 | |
Azure.IoT Build | 0:6ae2f7bca550 | 50 | /* Codes_SRS_SASL_PLAIN_01_020: [ authcid = 1*SAFE ; MUST accept up to 255 octets] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 51 | if ((authcid_length > 255) || (authcid_length == 0) || |
Azure.IoT Build | 0:6ae2f7bca550 | 52 | /* Codes_SRS_SASL_PLAIN_01_021: [ authzid = 1*SAFE ; MUST accept up to 255 octets] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 53 | (authzid_length > 255) || |
Azure.IoT Build | 0:6ae2f7bca550 | 54 | /* Codes_SRS_SASL_PLAIN_01_022: [ passwd = 1*SAFE ; MUST accept up to 255 octets] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 55 | (passwd_length > 255) || (passwd_length == 0)) |
Azure.IoT Build | 0:6ae2f7bca550 | 56 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 57 | result = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 58 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 59 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 60 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 61 | /* Codes_SRS_SASL_PLAIN_01_001: [saslplain_create shall return on success a non-NULL handle to a new SASL plain mechanism.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 62 | result = amqpalloc_malloc(sizeof(SASL_PLAIN_INSTANCE)); |
Azure.IoT Build | 0:6ae2f7bca550 | 63 | /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 64 | if (result != NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 65 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 66 | /* Ignore UTF8 for now */ |
Azure.IoT Build | 0:6ae2f7bca550 | 67 | result->init_bytes = (unsigned char*)amqpalloc_malloc(authzid_length + authcid_length + passwd_length + 2); |
Azure.IoT Build | 0:6ae2f7bca550 | 68 | if (result->init_bytes == NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 69 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 70 | /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 71 | amqpalloc_free(result); |
Azure.IoT Build | 0:6ae2f7bca550 | 72 | result = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 73 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 74 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 75 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 76 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 77 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 78 | /* Codes_SRS_SASL_PLAIN_01_019: [ message = [authzid] UTF8NUL authcid UTF8NUL passwd] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 79 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 80 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 81 | |
Azure.IoT Build | 0:6ae2f7bca550 | 82 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 83 | if (authzid_length > 0) |
Azure.IoT Build | 0:6ae2f7bca550 | 84 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 85 | (void)memcpy(result->init_bytes, sasl_plain_config->authzid, authzid_length); |
Azure.IoT Build | 0:6ae2f7bca550 | 86 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 87 | |
Azure.IoT Build | 0:6ae2f7bca550 | 88 | result->init_bytes[authzid_length] = 0; |
Azure.IoT Build | 0:6ae2f7bca550 | 89 | (void)memcpy(result->init_bytes + authzid_length + 1, sasl_plain_config->authcid, authcid_length); |
Azure.IoT Build | 0:6ae2f7bca550 | 90 | result->init_bytes[authzid_length + authcid_length + 1] = 0; |
Azure.IoT Build | 0:6ae2f7bca550 | 91 | (void)memcpy(result->init_bytes + authzid_length + authcid_length + 2, sasl_plain_config->passwd, passwd_length); |
AzureIoTClient | 6:641a9672db08 | 92 | result->init_bytes_length = (uint32_t)(authzid_length + authcid_length + passwd_length + 2); |
Azure.IoT Build | 0:6ae2f7bca550 | 93 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 94 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 95 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 96 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 97 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 98 | |
Azure.IoT Build | 0:6ae2f7bca550 | 99 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 100 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 101 | |
Azure.IoT Build | 0:6ae2f7bca550 | 102 | void saslplain_destroy(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle) |
Azure.IoT Build | 0:6ae2f7bca550 | 103 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 104 | if (sasl_mechanism_concrete_handle != NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 105 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 106 | /* Codes_SRS_SASL_PLAIN_01_005: [saslplain_destroy shall free all resources associated with the SASL mechanism.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 107 | SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle; |
Azure.IoT Build | 0:6ae2f7bca550 | 108 | if (sasl_plain_instance->init_bytes != NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 109 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 110 | amqpalloc_free(sasl_plain_instance->init_bytes); |
Azure.IoT Build | 0:6ae2f7bca550 | 111 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 112 | |
Azure.IoT Build | 0:6ae2f7bca550 | 113 | amqpalloc_free(sasl_plain_instance); |
Azure.IoT Build | 0:6ae2f7bca550 | 114 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 115 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 116 | |
Azure.IoT Build | 0:6ae2f7bca550 | 117 | int saslplain_get_init_bytes(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle, SASL_MECHANISM_BYTES* init_bytes) |
Azure.IoT Build | 0:6ae2f7bca550 | 118 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 119 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 120 | |
Azure.IoT Build | 0:6ae2f7bca550 | 121 | if ((sasl_mechanism_concrete_handle == NULL) || |
Azure.IoT Build | 0:6ae2f7bca550 | 122 | (init_bytes == NULL)) |
Azure.IoT Build | 0:6ae2f7bca550 | 123 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 124 | result = __LINE__; |
Azure.IoT Build | 0:6ae2f7bca550 | 125 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 126 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 127 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 128 | SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle; |
Azure.IoT Build | 0:6ae2f7bca550 | 129 | |
Azure.IoT Build | 0:6ae2f7bca550 | 130 | init_bytes->bytes = sasl_plain_instance->init_bytes; |
Azure.IoT Build | 0:6ae2f7bca550 | 131 | init_bytes->length = sasl_plain_instance->init_bytes_length; |
Azure.IoT Build | 0:6ae2f7bca550 | 132 | |
Azure.IoT Build | 0:6ae2f7bca550 | 133 | /* Codes_SRS_SASL_PLAIN_01_008: [On success saslplain_get_init_bytes shall return zero.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 134 | result = 0; |
Azure.IoT Build | 0:6ae2f7bca550 | 135 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 136 | |
Azure.IoT Build | 0:6ae2f7bca550 | 137 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 138 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 139 | |
Azure.IoT Build | 0:6ae2f7bca550 | 140 | const char* saslplain_get_mechanism_name(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism) |
Azure.IoT Build | 0:6ae2f7bca550 | 141 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 142 | const char* result; |
Azure.IoT Build | 0:6ae2f7bca550 | 143 | |
Azure.IoT Build | 0:6ae2f7bca550 | 144 | if (sasl_mechanism == NULL) |
Azure.IoT Build | 0:6ae2f7bca550 | 145 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 146 | /* Codes_SRS_SASL_PLAIN_01_011: [If the argument concrete_sasl_mechanism is NULL, saslplain_get_mechanism_name shall return NULL.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 147 | result = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 148 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 149 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 150 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 151 | /* 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".] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 152 | result = "PLAIN"; |
Azure.IoT Build | 0:6ae2f7bca550 | 153 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 154 | |
Azure.IoT Build | 0:6ae2f7bca550 | 155 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 156 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 157 | |
Azure.IoT Build | 0:6ae2f7bca550 | 158 | int saslplain_challenge(CONCRETE_SASL_MECHANISM_HANDLE concrete_sasl_mechanism, const SASL_MECHANISM_BYTES* challenge_bytes, SASL_MECHANISM_BYTES* response_bytes) |
Azure.IoT Build | 0:6ae2f7bca550 | 159 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 160 | int result; |
Azure.IoT Build | 0:6ae2f7bca550 | 161 | |
Azure.IoT Build | 0:6ae2f7bca550 | 162 | (void)challenge_bytes; |
Azure.IoT Build | 0:6ae2f7bca550 | 163 | |
Azure.IoT Build | 0:6ae2f7bca550 | 164 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 165 | if ((concrete_sasl_mechanism == NULL) || |
Azure.IoT Build | 0:6ae2f7bca550 | 166 | (response_bytes == NULL)) |
Azure.IoT Build | 0:6ae2f7bca550 | 167 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 168 | result = __LINE__; |
Azure.IoT Build | 0:6ae2f7bca550 | 169 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 170 | else |
Azure.IoT Build | 0:6ae2f7bca550 | 171 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 172 | /* 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.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 173 | response_bytes->bytes = NULL; |
Azure.IoT Build | 0:6ae2f7bca550 | 174 | response_bytes->length = 0; |
Azure.IoT Build | 0:6ae2f7bca550 | 175 | |
Azure.IoT Build | 0:6ae2f7bca550 | 176 | /* Codes_SRS_SASL_PLAIN_01_013: [On success, saslplain_challenge shall return 0.] */ |
Azure.IoT Build | 0:6ae2f7bca550 | 177 | result = 0; |
Azure.IoT Build | 0:6ae2f7bca550 | 178 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 179 | |
Azure.IoT Build | 0:6ae2f7bca550 | 180 | return result; |
Azure.IoT Build | 0:6ae2f7bca550 | 181 | } |
Azure.IoT Build | 0:6ae2f7bca550 | 182 | |
Azure.IoT Build | 0:6ae2f7bca550 | 183 | const SASL_MECHANISM_INTERFACE_DESCRIPTION* saslplain_get_interface(void) |
Azure.IoT Build | 0:6ae2f7bca550 | 184 | { |
Azure.IoT Build | 0:6ae2f7bca550 | 185 | return &saslplain_interface; |
Azure.IoT Build | 0:6ae2f7bca550 | 186 | } |