Microsoft Azure IoTHub client AMQP transport
Dependents: sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp iothub_client_sample_amqp ... more
This library implements the AMQP transport for Microsoft Azure IoTHub client. The code is replicated from https://github.com/Azure/azure-iot-sdks
iothubtransport_amqp_cbs_auth.c@31:adadaef857c1, 2017-03-24 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Fri Mar 24 16:35:00 2017 -0700
- Revision:
- 31:adadaef857c1
- Parent:
- 30:20a85b733111
- Child:
- 34:51d158b409d2
1.1.10
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AzureIoTClient | 30:20a85b733111 | 1 | // Copyright (c) Microsoft. All rights reserved. |
AzureIoTClient | 30:20a85b733111 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
AzureIoTClient | 30:20a85b733111 | 3 | |
AzureIoTClient | 30:20a85b733111 | 4 | #include <stdlib.h> |
AzureIoTClient | 30:20a85b733111 | 5 | #include "iothubtransport_amqp_cbs_auth.h" |
AzureIoTClient | 30:20a85b733111 | 6 | #include "azure_c_shared_utility/optimize_size.h" |
AzureIoTClient | 30:20a85b733111 | 7 | #include "azure_c_shared_utility/gballoc.h" |
AzureIoTClient | 30:20a85b733111 | 8 | #include "azure_c_shared_utility/agenttime.h" |
AzureIoTClient | 30:20a85b733111 | 9 | #include "azure_c_shared_utility/xlogging.h" |
AzureIoTClient | 30:20a85b733111 | 10 | #include "azure_c_shared_utility/sastoken.h" |
AzureIoTClient | 30:20a85b733111 | 11 | |
AzureIoTClient | 30:20a85b733111 | 12 | #define RESULT_OK 0 |
AzureIoTClient | 30:20a85b733111 | 13 | #define INDEFINITE_TIME ((time_t)(-1)) |
AzureIoTClient | 30:20a85b733111 | 14 | #define SAS_TOKEN_TYPE "servicebus.windows.net:sastoken" |
AzureIoTClient | 30:20a85b733111 | 15 | #define IOTHUB_DEVICES_PATH_FMT "%s/devices/%s" |
AzureIoTClient | 30:20a85b733111 | 16 | #define DEFAULT_CBS_REQUEST_TIMEOUT_SECS UINT32_MAX |
AzureIoTClient | 30:20a85b733111 | 17 | #define DEFAULT_SAS_TOKEN_LIFETIME_SECS 3600 |
AzureIoTClient | 30:20a85b733111 | 18 | #define DEFAULT_SAS_TOKEN_REFRESH_TIME_SECS 1800 |
AzureIoTClient | 30:20a85b733111 | 19 | |
AzureIoTClient | 30:20a85b733111 | 20 | typedef enum CREDENTIAL_TYPE_TAG |
AzureIoTClient | 30:20a85b733111 | 21 | { |
AzureIoTClient | 30:20a85b733111 | 22 | CREDENTIAL_TYPE_NONE, |
AzureIoTClient | 30:20a85b733111 | 23 | DEVICE_PRIMARY_KEY, |
AzureIoTClient | 30:20a85b733111 | 24 | DEVICE_SECONDARY_KEY, |
AzureIoTClient | 30:20a85b733111 | 25 | USER_PROVIDED_SAS_TOKEN |
AzureIoTClient | 30:20a85b733111 | 26 | } CREDENTIAL_TYPE; |
AzureIoTClient | 30:20a85b733111 | 27 | |
AzureIoTClient | 30:20a85b733111 | 28 | typedef struct AUTHENTICATION_INSTANCE_TAG |
AzureIoTClient | 30:20a85b733111 | 29 | { |
AzureIoTClient | 30:20a85b733111 | 30 | STRING_HANDLE device_id; |
AzureIoTClient | 30:20a85b733111 | 31 | STRING_HANDLE iothub_host_fqdn; |
AzureIoTClient | 30:20a85b733111 | 32 | |
AzureIoTClient | 30:20a85b733111 | 33 | STRING_HANDLE device_sas_token; |
AzureIoTClient | 30:20a85b733111 | 34 | STRING_HANDLE device_primary_key; |
AzureIoTClient | 30:20a85b733111 | 35 | STRING_HANDLE device_secondary_key; |
AzureIoTClient | 30:20a85b733111 | 36 | |
AzureIoTClient | 30:20a85b733111 | 37 | ON_AUTHENTICATION_STATE_CHANGED_CALLBACK on_state_changed_callback; |
AzureIoTClient | 30:20a85b733111 | 38 | void* on_state_changed_callback_context; |
AzureIoTClient | 30:20a85b733111 | 39 | |
AzureIoTClient | 30:20a85b733111 | 40 | ON_AUTHENTICATION_ERROR_CALLBACK on_error_callback; |
AzureIoTClient | 30:20a85b733111 | 41 | void* on_error_callback_context; |
AzureIoTClient | 30:20a85b733111 | 42 | |
AzureIoTClient | 30:20a85b733111 | 43 | size_t cbs_request_timeout_secs; |
AzureIoTClient | 30:20a85b733111 | 44 | size_t sas_token_lifetime_secs; |
AzureIoTClient | 30:20a85b733111 | 45 | size_t sas_token_refresh_time_secs; |
AzureIoTClient | 30:20a85b733111 | 46 | |
AzureIoTClient | 30:20a85b733111 | 47 | AUTHENTICATION_STATE state; |
AzureIoTClient | 30:20a85b733111 | 48 | CBS_HANDLE cbs_handle; |
AzureIoTClient | 30:20a85b733111 | 49 | |
AzureIoTClient | 30:20a85b733111 | 50 | bool is_cbs_put_token_in_progress; |
AzureIoTClient | 30:20a85b733111 | 51 | bool is_sas_token_refresh_in_progress; |
AzureIoTClient | 30:20a85b733111 | 52 | |
AzureIoTClient | 30:20a85b733111 | 53 | time_t current_sas_token_put_time; |
AzureIoTClient | 30:20a85b733111 | 54 | |
AzureIoTClient | 30:20a85b733111 | 55 | CREDENTIAL_TYPE current_credential_in_use; |
AzureIoTClient | 30:20a85b733111 | 56 | } AUTHENTICATION_INSTANCE; |
AzureIoTClient | 30:20a85b733111 | 57 | |
AzureIoTClient | 30:20a85b733111 | 58 | |
AzureIoTClient | 30:20a85b733111 | 59 | // Helper functions: |
AzureIoTClient | 30:20a85b733111 | 60 | |
AzureIoTClient | 30:20a85b733111 | 61 | static int get_seconds_since_epoch(double *seconds) |
AzureIoTClient | 30:20a85b733111 | 62 | { |
AzureIoTClient | 30:20a85b733111 | 63 | int result; |
AzureIoTClient | 30:20a85b733111 | 64 | time_t current_time; |
AzureIoTClient | 30:20a85b733111 | 65 | |
AzureIoTClient | 30:20a85b733111 | 66 | if ((current_time = get_time(NULL)) == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 67 | { |
AzureIoTClient | 30:20a85b733111 | 68 | LogError("Failed getting the current local time (get_time() failed)"); |
AzureIoTClient | 30:20a85b733111 | 69 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 70 | } |
AzureIoTClient | 30:20a85b733111 | 71 | else |
AzureIoTClient | 30:20a85b733111 | 72 | { |
AzureIoTClient | 30:20a85b733111 | 73 | *seconds = get_difftime(current_time, (time_t)0); |
AzureIoTClient | 30:20a85b733111 | 74 | |
AzureIoTClient | 30:20a85b733111 | 75 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 76 | } |
AzureIoTClient | 30:20a85b733111 | 77 | |
AzureIoTClient | 30:20a85b733111 | 78 | return result; |
AzureIoTClient | 30:20a85b733111 | 79 | } |
AzureIoTClient | 30:20a85b733111 | 80 | |
AzureIoTClient | 30:20a85b733111 | 81 | static void update_state(AUTHENTICATION_INSTANCE* instance, AUTHENTICATION_STATE new_state) |
AzureIoTClient | 30:20a85b733111 | 82 | { |
AzureIoTClient | 30:20a85b733111 | 83 | if (new_state != instance->state) |
AzureIoTClient | 30:20a85b733111 | 84 | { |
AzureIoTClient | 30:20a85b733111 | 85 | AUTHENTICATION_STATE previous_state = instance->state; |
AzureIoTClient | 30:20a85b733111 | 86 | instance->state = new_state; |
AzureIoTClient | 30:20a85b733111 | 87 | |
AzureIoTClient | 30:20a85b733111 | 88 | if (instance->on_state_changed_callback != NULL) |
AzureIoTClient | 30:20a85b733111 | 89 | { |
AzureIoTClient | 30:20a85b733111 | 90 | instance->on_state_changed_callback(instance->on_state_changed_callback_context, previous_state, new_state); |
AzureIoTClient | 30:20a85b733111 | 91 | } |
AzureIoTClient | 30:20a85b733111 | 92 | } |
AzureIoTClient | 30:20a85b733111 | 93 | } |
AzureIoTClient | 30:20a85b733111 | 94 | |
AzureIoTClient | 30:20a85b733111 | 95 | static void notify_error(AUTHENTICATION_INSTANCE* instance, AUTHENTICATION_ERROR_CODE error_code) |
AzureIoTClient | 30:20a85b733111 | 96 | { |
AzureIoTClient | 30:20a85b733111 | 97 | if (instance->on_error_callback != NULL) |
AzureIoTClient | 30:20a85b733111 | 98 | { |
AzureIoTClient | 30:20a85b733111 | 99 | instance->on_error_callback(instance->on_error_callback_context, error_code); |
AzureIoTClient | 30:20a85b733111 | 100 | } |
AzureIoTClient | 30:20a85b733111 | 101 | } |
AzureIoTClient | 30:20a85b733111 | 102 | |
AzureIoTClient | 30:20a85b733111 | 103 | static int verify_cbs_put_token_timeout(AUTHENTICATION_INSTANCE* instance, bool* is_timed_out) |
AzureIoTClient | 30:20a85b733111 | 104 | { |
AzureIoTClient | 30:20a85b733111 | 105 | int result; |
AzureIoTClient | 30:20a85b733111 | 106 | |
AzureIoTClient | 30:20a85b733111 | 107 | if (instance->current_sas_token_put_time == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 108 | { |
AzureIoTClient | 30:20a85b733111 | 109 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 110 | LogError("Failed verifying if cbs_put_token has timed out (current_sas_token_put_time is not set)"); |
AzureIoTClient | 30:20a85b733111 | 111 | } |
AzureIoTClient | 30:20a85b733111 | 112 | else |
AzureIoTClient | 30:20a85b733111 | 113 | { |
AzureIoTClient | 30:20a85b733111 | 114 | time_t current_time; |
AzureIoTClient | 30:20a85b733111 | 115 | |
AzureIoTClient | 30:20a85b733111 | 116 | if ((current_time = get_time(NULL)) == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 117 | { |
AzureIoTClient | 30:20a85b733111 | 118 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 119 | LogError("Failed verifying if cbs_put_token has timed out (get_time failed)"); |
AzureIoTClient | 30:20a85b733111 | 120 | } |
AzureIoTClient | 30:20a85b733111 | 121 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_083: [authentication_do_work() shall check for authentication timeout comparing the current time since `instance->current_sas_token_put_time` to `instance->cbs_request_timeout_secs`] |
AzureIoTClient | 30:20a85b733111 | 122 | else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->cbs_request_timeout_secs) |
AzureIoTClient | 30:20a85b733111 | 123 | { |
AzureIoTClient | 30:20a85b733111 | 124 | *is_timed_out = true; |
AzureIoTClient | 30:20a85b733111 | 125 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 126 | } |
AzureIoTClient | 30:20a85b733111 | 127 | else |
AzureIoTClient | 30:20a85b733111 | 128 | { |
AzureIoTClient | 30:20a85b733111 | 129 | *is_timed_out = false; |
AzureIoTClient | 30:20a85b733111 | 130 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 131 | } |
AzureIoTClient | 30:20a85b733111 | 132 | } |
AzureIoTClient | 30:20a85b733111 | 133 | |
AzureIoTClient | 30:20a85b733111 | 134 | return result; |
AzureIoTClient | 30:20a85b733111 | 135 | } |
AzureIoTClient | 30:20a85b733111 | 136 | |
AzureIoTClient | 30:20a85b733111 | 137 | static int verify_sas_token_refresh_timeout(AUTHENTICATION_INSTANCE* instance, bool* is_timed_out) |
AzureIoTClient | 30:20a85b733111 | 138 | { |
AzureIoTClient | 30:20a85b733111 | 139 | int result; |
AzureIoTClient | 30:20a85b733111 | 140 | |
AzureIoTClient | 30:20a85b733111 | 141 | if (instance->current_sas_token_put_time == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 142 | { |
AzureIoTClient | 30:20a85b733111 | 143 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 144 | LogError("Failed verifying if SAS token refresh timed out (current_sas_token_put_time is not set)"); |
AzureIoTClient | 30:20a85b733111 | 145 | } |
AzureIoTClient | 30:20a85b733111 | 146 | else |
AzureIoTClient | 30:20a85b733111 | 147 | { |
AzureIoTClient | 30:20a85b733111 | 148 | time_t current_time; |
AzureIoTClient | 30:20a85b733111 | 149 | |
AzureIoTClient | 30:20a85b733111 | 150 | if ((current_time = get_time(NULL)) == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 151 | { |
AzureIoTClient | 30:20a85b733111 | 152 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 153 | LogError("Failed verifying if SAS token refresh timed out (get_time failed)"); |
AzureIoTClient | 30:20a85b733111 | 154 | } |
AzureIoTClient | 30:20a85b733111 | 155 | else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->sas_token_refresh_time_secs) |
AzureIoTClient | 30:20a85b733111 | 156 | { |
AzureIoTClient | 30:20a85b733111 | 157 | *is_timed_out = true; |
AzureIoTClient | 30:20a85b733111 | 158 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 159 | } |
AzureIoTClient | 30:20a85b733111 | 160 | else |
AzureIoTClient | 30:20a85b733111 | 161 | { |
AzureIoTClient | 30:20a85b733111 | 162 | *is_timed_out = false; |
AzureIoTClient | 30:20a85b733111 | 163 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 164 | } |
AzureIoTClient | 30:20a85b733111 | 165 | } |
AzureIoTClient | 30:20a85b733111 | 166 | |
AzureIoTClient | 30:20a85b733111 | 167 | return result; |
AzureIoTClient | 30:20a85b733111 | 168 | } |
AzureIoTClient | 30:20a85b733111 | 169 | |
AzureIoTClient | 30:20a85b733111 | 170 | static STRING_HANDLE create_devices_path(STRING_HANDLE iothub_host_fqdn, STRING_HANDLE device_id) |
AzureIoTClient | 30:20a85b733111 | 171 | { |
AzureIoTClient | 30:20a85b733111 | 172 | STRING_HANDLE devices_path; |
AzureIoTClient | 30:20a85b733111 | 173 | |
AzureIoTClient | 30:20a85b733111 | 174 | if ((devices_path = STRING_new()) == NULL) |
AzureIoTClient | 30:20a85b733111 | 175 | { |
AzureIoTClient | 30:20a85b733111 | 176 | LogError("Failed creating devices_path (STRING_new failed)"); |
AzureIoTClient | 30:20a85b733111 | 177 | } |
AzureIoTClient | 30:20a85b733111 | 178 | else |
AzureIoTClient | 30:20a85b733111 | 179 | { |
AzureIoTClient | 30:20a85b733111 | 180 | const char* device_id_c_str = STRING_c_str(device_id); |
AzureIoTClient | 30:20a85b733111 | 181 | const char* iothub_host_fqdn_c_str = STRING_c_str(iothub_host_fqdn); |
AzureIoTClient | 30:20a85b733111 | 182 | |
AzureIoTClient | 30:20a85b733111 | 183 | if (STRING_sprintf(devices_path, IOTHUB_DEVICES_PATH_FMT, iothub_host_fqdn_c_str, device_id_c_str) != RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 184 | { |
AzureIoTClient | 30:20a85b733111 | 185 | STRING_delete(devices_path); |
AzureIoTClient | 30:20a85b733111 | 186 | devices_path = NULL; |
AzureIoTClient | 30:20a85b733111 | 187 | LogError("Failed creating devices_path (STRING_sprintf failed)"); |
AzureIoTClient | 30:20a85b733111 | 188 | } |
AzureIoTClient | 30:20a85b733111 | 189 | } |
AzureIoTClient | 30:20a85b733111 | 190 | |
AzureIoTClient | 30:20a85b733111 | 191 | return devices_path; |
AzureIoTClient | 30:20a85b733111 | 192 | } |
AzureIoTClient | 30:20a85b733111 | 193 | |
AzureIoTClient | 30:20a85b733111 | 194 | |
AzureIoTClient | 30:20a85b733111 | 195 | static bool are_device_keys_used_for_authentication(AUTHENTICATION_INSTANCE* instance) |
AzureIoTClient | 30:20a85b733111 | 196 | { |
AzureIoTClient | 30:20a85b733111 | 197 | return (instance->current_credential_in_use == DEVICE_PRIMARY_KEY || instance->current_credential_in_use == DEVICE_SECONDARY_KEY); |
AzureIoTClient | 30:20a85b733111 | 198 | } |
AzureIoTClient | 30:20a85b733111 | 199 | |
AzureIoTClient | 30:20a85b733111 | 200 | // @returns 0 there is one more device key to be attempted, !=0 otherwise. |
AzureIoTClient | 30:20a85b733111 | 201 | static int mark_current_device_key_as_invalid(AUTHENTICATION_INSTANCE* instance) |
AzureIoTClient | 30:20a85b733111 | 202 | { |
AzureIoTClient | 30:20a85b733111 | 203 | int result; |
AzureIoTClient | 30:20a85b733111 | 204 | |
AzureIoTClient | 30:20a85b733111 | 205 | if (instance->current_credential_in_use == DEVICE_PRIMARY_KEY) |
AzureIoTClient | 30:20a85b733111 | 206 | { |
AzureIoTClient | 30:20a85b733111 | 207 | if (instance->device_secondary_key != NULL) |
AzureIoTClient | 30:20a85b733111 | 208 | { |
AzureIoTClient | 30:20a85b733111 | 209 | instance->current_credential_in_use = DEVICE_SECONDARY_KEY; |
AzureIoTClient | 30:20a85b733111 | 210 | LogError("Primary key of device '%s' was marked as invalid. Using secondary key now", STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 211 | result = 0; |
AzureIoTClient | 30:20a85b733111 | 212 | } |
AzureIoTClient | 30:20a85b733111 | 213 | else |
AzureIoTClient | 30:20a85b733111 | 214 | { |
AzureIoTClient | 30:20a85b733111 | 215 | instance->current_credential_in_use = CREDENTIAL_TYPE_NONE; |
AzureIoTClient | 30:20a85b733111 | 216 | LogError("Primary key of device '%s' was marked as invalid. No other device keys available", STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 217 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 218 | } |
AzureIoTClient | 30:20a85b733111 | 219 | } |
AzureIoTClient | 30:20a85b733111 | 220 | else if (instance->current_credential_in_use == DEVICE_SECONDARY_KEY) |
AzureIoTClient | 30:20a85b733111 | 221 | { |
AzureIoTClient | 30:20a85b733111 | 222 | instance->current_credential_in_use = CREDENTIAL_TYPE_NONE; |
AzureIoTClient | 30:20a85b733111 | 223 | LogError("Secondary key of device '%s' was marked as invalid. No other device keys available", STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 224 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 225 | } |
AzureIoTClient | 30:20a85b733111 | 226 | else |
AzureIoTClient | 30:20a85b733111 | 227 | { |
AzureIoTClient | 30:20a85b733111 | 228 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 229 | } |
AzureIoTClient | 30:20a85b733111 | 230 | |
AzureIoTClient | 30:20a85b733111 | 231 | return result; |
AzureIoTClient | 30:20a85b733111 | 232 | } |
AzureIoTClient | 30:20a85b733111 | 233 | |
AzureIoTClient | 30:20a85b733111 | 234 | static STRING_HANDLE get_current_valid_device_key(AUTHENTICATION_INSTANCE* instance) |
AzureIoTClient | 30:20a85b733111 | 235 | { |
AzureIoTClient | 30:20a85b733111 | 236 | STRING_HANDLE device_key; |
AzureIoTClient | 30:20a85b733111 | 237 | |
AzureIoTClient | 30:20a85b733111 | 238 | switch (instance->current_credential_in_use) |
AzureIoTClient | 30:20a85b733111 | 239 | { |
AzureIoTClient | 30:20a85b733111 | 240 | case DEVICE_PRIMARY_KEY: |
AzureIoTClient | 30:20a85b733111 | 241 | device_key = instance->device_primary_key; |
AzureIoTClient | 30:20a85b733111 | 242 | break; |
AzureIoTClient | 30:20a85b733111 | 243 | case DEVICE_SECONDARY_KEY: |
AzureIoTClient | 30:20a85b733111 | 244 | device_key = instance->device_secondary_key; |
AzureIoTClient | 30:20a85b733111 | 245 | break; |
AzureIoTClient | 30:20a85b733111 | 246 | default: |
AzureIoTClient | 30:20a85b733111 | 247 | device_key = NULL; |
AzureIoTClient | 30:20a85b733111 | 248 | break; |
AzureIoTClient | 30:20a85b733111 | 249 | } |
AzureIoTClient | 30:20a85b733111 | 250 | |
AzureIoTClient | 30:20a85b733111 | 251 | return device_key; |
AzureIoTClient | 30:20a85b733111 | 252 | } |
AzureIoTClient | 30:20a85b733111 | 253 | |
AzureIoTClient | 30:20a85b733111 | 254 | static void on_cbs_put_token_complete_callback(void* context, CBS_OPERATION_RESULT operation_result, unsigned int status_code, const char* status_description) |
AzureIoTClient | 30:20a85b733111 | 255 | { |
AzureIoTClient | 30:20a85b733111 | 256 | #ifdef NO_LOGGING |
AzureIoTClient | 30:20a85b733111 | 257 | UNUSED(status_code); |
AzureIoTClient | 30:20a85b733111 | 258 | UNUSED(status_description); |
AzureIoTClient | 30:20a85b733111 | 259 | #endif |
AzureIoTClient | 30:20a85b733111 | 260 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)context; |
AzureIoTClient | 30:20a85b733111 | 261 | |
AzureIoTClient | 30:20a85b733111 | 262 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_095: [`instance->is_sas_token_refresh_in_progress` and `instance->is_cbs_put_token_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 263 | instance->is_cbs_put_token_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 264 | |
AzureIoTClient | 30:20a85b733111 | 265 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_091: [If `result` is CBS_OPERATION_RESULT_OK `instance->state` shall be set to AUTHENTICATION_STATE_STARTED and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 266 | if (operation_result == CBS_OPERATION_RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 267 | { |
AzureIoTClient | 30:20a85b733111 | 268 | update_state(instance, AUTHENTICATION_STATE_STARTED); |
AzureIoTClient | 30:20a85b733111 | 269 | } |
AzureIoTClient | 30:20a85b733111 | 270 | else |
AzureIoTClient | 30:20a85b733111 | 271 | { |
AzureIoTClient | 30:20a85b733111 | 272 | LogError("CBS reported status code %u, error: '%s' for put-token operation for device '%s'", status_code, status_description, STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 273 | |
AzureIoTClient | 30:20a85b733111 | 274 | if (mark_current_device_key_as_invalid(instance) != 0) |
AzureIoTClient | 30:20a85b733111 | 275 | { |
AzureIoTClient | 30:20a85b733111 | 276 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_092: [If `result` is not CBS_OPERATION_RESULT_OK `instance->state` shall be set to AUTHENTICATION_STATE_ERROR and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 277 | update_state(instance, AUTHENTICATION_STATE_ERROR); |
AzureIoTClient | 30:20a85b733111 | 278 | |
AzureIoTClient | 30:20a85b733111 | 279 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_094: [If `result` is not CBS_OPERATION_RESULT_OK and `instance->is_sas_token_refresh_in_progress` is TRUE, `instance->on_error_callback`shall be invoked with AUTHENTICATION_ERROR_SAS_REFRESH_FAILED] |
AzureIoTClient | 30:20a85b733111 | 280 | if (instance->is_sas_token_refresh_in_progress) |
AzureIoTClient | 30:20a85b733111 | 281 | { |
AzureIoTClient | 30:20a85b733111 | 282 | notify_error(instance, AUTHENTICATION_ERROR_SAS_REFRESH_FAILED); |
AzureIoTClient | 30:20a85b733111 | 283 | } |
AzureIoTClient | 30:20a85b733111 | 284 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_093: [If `result` is not CBS_OPERATION_RESULT_OK and `instance->is_sas_token_refresh_in_progress` is FALSE, `instance->on_error_callback`shall be invoked with AUTHENTICATION_ERROR_AUTH_FAILED] |
AzureIoTClient | 30:20a85b733111 | 285 | else |
AzureIoTClient | 30:20a85b733111 | 286 | { |
AzureIoTClient | 30:20a85b733111 | 287 | notify_error(instance, AUTHENTICATION_ERROR_AUTH_FAILED); |
AzureIoTClient | 30:20a85b733111 | 288 | } |
AzureIoTClient | 30:20a85b733111 | 289 | } |
AzureIoTClient | 30:20a85b733111 | 290 | } |
AzureIoTClient | 30:20a85b733111 | 291 | |
AzureIoTClient | 30:20a85b733111 | 292 | instance->is_sas_token_refresh_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 293 | } |
AzureIoTClient | 30:20a85b733111 | 294 | |
AzureIoTClient | 30:20a85b733111 | 295 | static int put_SAS_token_to_cbs(AUTHENTICATION_INSTANCE* instance, STRING_HANDLE cbs_audience, STRING_HANDLE sas_token) |
AzureIoTClient | 30:20a85b733111 | 296 | { |
AzureIoTClient | 30:20a85b733111 | 297 | int result; |
AzureIoTClient | 30:20a85b733111 | 298 | |
AzureIoTClient | 30:20a85b733111 | 299 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_043: [authentication_do_work() shall set `instance->is_cbs_put_token_in_progress` to TRUE] |
AzureIoTClient | 30:20a85b733111 | 300 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_057: [authentication_do_work() shall set `instance->is_cbs_put_token_in_progress` to TRUE] |
AzureIoTClient | 30:20a85b733111 | 301 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_075: [authentication_do_work() shall set `instance->is_cbs_put_token_in_progress` to TRUE] |
AzureIoTClient | 30:20a85b733111 | 302 | instance->is_cbs_put_token_in_progress = true; |
AzureIoTClient | 30:20a85b733111 | 303 | |
AzureIoTClient | 30:20a85b733111 | 304 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_046: [The SAS token provided shall be sent to CBS using cbs_put_token(), using `servicebus.windows.net:sastoken` as token type, `devices_path` as audience and passing on_cbs_put_token_complete_callback] |
AzureIoTClient | 30:20a85b733111 | 305 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_058: [The SAS token shall be sent to CBS using cbs_put_token(), using `servicebus.windows.net:sastoken` as token type, `devices_path` as audience and passing on_cbs_put_token_complete_callback] |
AzureIoTClient | 30:20a85b733111 | 306 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_076: [The SAS token shall be sent to CBS using cbs_put_token(), using `servicebus.windows.net:sastoken` as token type, `devices_path` as audience and passing on_cbs_put_token_complete_callback] |
AzureIoTClient | 30:20a85b733111 | 307 | const char* sas_token_c_str = STRING_c_str(sas_token); |
AzureIoTClient | 30:20a85b733111 | 308 | const char* cbs_audience_c_str = STRING_c_str(cbs_audience); |
AzureIoTClient | 31:adadaef857c1 | 309 | if (cbs_put_token_async(instance->cbs_handle, SAS_TOKEN_TYPE, cbs_audience_c_str, sas_token_c_str, on_cbs_put_token_complete_callback, instance) != RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 310 | { |
AzureIoTClient | 30:20a85b733111 | 311 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_048: [If cbs_put_token() failed, authentication_do_work() shall set `instance->is_cbs_put_token_in_progress` to FALSE, destroy `devices_path` and return] |
AzureIoTClient | 30:20a85b733111 | 312 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_060: [If cbs_put_token() fails, `instance->is_cbs_put_token_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 313 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_078: [If cbs_put_token() fails, `instance->is_cbs_put_token_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 314 | instance->is_cbs_put_token_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 315 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 316 | LogError("Failed putting SAS token to CBS for device '%s' (cbs_put_token failed)", STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 317 | } |
AzureIoTClient | 30:20a85b733111 | 318 | else |
AzureIoTClient | 30:20a85b733111 | 319 | { |
AzureIoTClient | 30:20a85b733111 | 320 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_047: [If cbs_put_token() succeeds, authentication_do_work() shall set `instance->current_sas_token_put_time` with current time] |
AzureIoTClient | 30:20a85b733111 | 321 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_059: [If cbs_put_token() succeeds, authentication_do_work() shall set `instance->current_sas_token_put_time` with current time] |
AzureIoTClient | 30:20a85b733111 | 322 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_077: [If cbs_put_token() succeeds, authentication_do_work() shall set `instance->current_sas_token_put_time` with the current time] |
AzureIoTClient | 30:20a85b733111 | 323 | time_t current_time; |
AzureIoTClient | 30:20a85b733111 | 324 | |
AzureIoTClient | 30:20a85b733111 | 325 | if ((current_time = get_time(NULL)) == INDEFINITE_TIME) |
AzureIoTClient | 30:20a85b733111 | 326 | { |
AzureIoTClient | 30:20a85b733111 | 327 | LogError("Failed setting current_sas_token_put_time for device '%s' (get_time() failed)", STRING_c_str(instance->device_id)); |
AzureIoTClient | 30:20a85b733111 | 328 | } |
AzureIoTClient | 30:20a85b733111 | 329 | |
AzureIoTClient | 30:20a85b733111 | 330 | instance->current_sas_token_put_time = current_time; // If it failed, fear not. `current_sas_token_put_time` shall be checked for INDEFINITE_TIME wherever it is used. |
AzureIoTClient | 30:20a85b733111 | 331 | |
AzureIoTClient | 30:20a85b733111 | 332 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 333 | } |
AzureIoTClient | 30:20a85b733111 | 334 | |
AzureIoTClient | 30:20a85b733111 | 335 | return result; |
AzureIoTClient | 30:20a85b733111 | 336 | } |
AzureIoTClient | 30:20a85b733111 | 337 | |
AzureIoTClient | 30:20a85b733111 | 338 | static int create_and_put_SAS_token_to_cbs(AUTHENTICATION_INSTANCE* instance, STRING_HANDLE device_key) |
AzureIoTClient | 30:20a85b733111 | 339 | { |
AzureIoTClient | 30:20a85b733111 | 340 | int result; |
AzureIoTClient | 30:20a85b733111 | 341 | double seconds_since_epoch; |
AzureIoTClient | 30:20a85b733111 | 342 | |
AzureIoTClient | 30:20a85b733111 | 343 | if (get_seconds_since_epoch(&seconds_since_epoch) != RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 344 | { |
AzureIoTClient | 30:20a85b733111 | 345 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 346 | LogError("Failed creating a SAS token (get_seconds_since_epoch() failed)"); |
AzureIoTClient | 30:20a85b733111 | 347 | } |
AzureIoTClient | 30:20a85b733111 | 348 | else |
AzureIoTClient | 30:20a85b733111 | 349 | { |
AzureIoTClient | 30:20a85b733111 | 350 | STRING_HANDLE devices_path = NULL; |
AzureIoTClient | 30:20a85b733111 | 351 | STRING_HANDLE sasTokenKeyName = NULL; |
AzureIoTClient | 30:20a85b733111 | 352 | STRING_HANDLE sas_token = NULL; |
AzureIoTClient | 30:20a85b733111 | 353 | |
AzureIoTClient | 30:20a85b733111 | 354 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_052: [The SAS token expiration time shall be calculated adding `instance->sas_token_lifetime_secs` to the current number of seconds since epoch time UTC] |
AzureIoTClient | 30:20a85b733111 | 355 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_070: [The SAS token expiration time shall be calculated adding `instance->sas_token_lifetime_secs` to the current number of seconds since epoch time UTC] |
AzureIoTClient | 30:20a85b733111 | 356 | size_t sas_token_expiration_time_secs = (size_t)seconds_since_epoch + instance->sas_token_lifetime_secs; |
AzureIoTClient | 30:20a85b733111 | 357 | |
AzureIoTClient | 30:20a85b733111 | 358 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_053: [A STRING_HANDLE, referred to as `devices_path`, shall be created from the following parts: iothub_host_fqdn + "/devices/" + device_id] |
AzureIoTClient | 30:20a85b733111 | 359 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_071: [A STRING_HANDLE, referred to as `devices_path`, shall be created from the following parts: iothub_host_fqdn + "/devices/" + device_id] |
AzureIoTClient | 30:20a85b733111 | 360 | if ((devices_path = create_devices_path(instance->iothub_host_fqdn, instance->device_id)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 361 | { |
AzureIoTClient | 30:20a85b733111 | 362 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_054: [If `devices_path` failed to be created, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 363 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_072: [If `devices_path` failed to be created, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 364 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 365 | LogError("Failed creating a SAS token (create_devices_path() failed)"); |
AzureIoTClient | 30:20a85b733111 | 366 | } |
AzureIoTClient | 30:20a85b733111 | 367 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_115: [An empty STRING_HANDLE, referred to as `sasTokenKeyName`, shall be created using STRING_new()] |
AzureIoTClient | 30:20a85b733111 | 368 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_117: [An empty STRING_HANDLE, referred to as `sasTokenKeyName`, shall be created using STRING_new()] |
AzureIoTClient | 30:20a85b733111 | 369 | else if ((sasTokenKeyName = STRING_new()) == NULL) |
AzureIoTClient | 30:20a85b733111 | 370 | { |
AzureIoTClient | 30:20a85b733111 | 371 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_116: [If `sasTokenKeyName` failed to be created, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 372 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_118: [If `sasTokenKeyName` failed to be created, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 373 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 374 | LogError("Failed creating a SAS token (STRING_new() failed)"); |
AzureIoTClient | 30:20a85b733111 | 375 | } |
AzureIoTClient | 30:20a85b733111 | 376 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_055: [The SAS token shall be created using SASToken_Create(), passing the selected device key, `device_path`, `sasTokenKeyName` and expiration time as arguments] |
AzureIoTClient | 30:20a85b733111 | 377 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_073: [The SAS token shall be created using SASToken_Create(), passing the selected device key, device_path, sasTokenKeyName and expiration time as arguments] |
AzureIoTClient | 30:20a85b733111 | 378 | else if ((sas_token = SASToken_Create(device_key, devices_path, sasTokenKeyName, (size_t)sas_token_expiration_time_secs)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 379 | { |
AzureIoTClient | 30:20a85b733111 | 380 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_056: [If SASToken_Create() fails, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 381 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_074: [If SASToken_Create() fails, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 382 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 383 | LogError("Failed creating a SAS token (SASToken_Create() failed)"); |
AzureIoTClient | 30:20a85b733111 | 384 | } |
AzureIoTClient | 30:20a85b733111 | 385 | else if (put_SAS_token_to_cbs(instance, devices_path, sas_token) != RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 386 | { |
AzureIoTClient | 30:20a85b733111 | 387 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 388 | LogError("Failed putting SAS token to CBS"); |
AzureIoTClient | 30:20a85b733111 | 389 | } |
AzureIoTClient | 30:20a85b733111 | 390 | else |
AzureIoTClient | 30:20a85b733111 | 391 | { |
AzureIoTClient | 30:20a85b733111 | 392 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 393 | } |
AzureIoTClient | 30:20a85b733111 | 394 | |
AzureIoTClient | 30:20a85b733111 | 395 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_081: [authentication_do_work() shall free the memory it allocated for `devices_path`, `sasTokenKeyName` and SAS token] |
AzureIoTClient | 30:20a85b733111 | 396 | if (devices_path != NULL) |
AzureIoTClient | 30:20a85b733111 | 397 | STRING_delete(devices_path); |
AzureIoTClient | 30:20a85b733111 | 398 | if (sasTokenKeyName != NULL) |
AzureIoTClient | 30:20a85b733111 | 399 | STRING_delete(sasTokenKeyName); |
AzureIoTClient | 30:20a85b733111 | 400 | if (sas_token != NULL) |
AzureIoTClient | 30:20a85b733111 | 401 | STRING_delete(sas_token); |
AzureIoTClient | 30:20a85b733111 | 402 | } |
AzureIoTClient | 30:20a85b733111 | 403 | |
AzureIoTClient | 30:20a85b733111 | 404 | return result; |
AzureIoTClient | 30:20a85b733111 | 405 | } |
AzureIoTClient | 30:20a85b733111 | 406 | |
AzureIoTClient | 30:20a85b733111 | 407 | |
AzureIoTClient | 30:20a85b733111 | 408 | // ---------- Set/Retrieve Options Helpers ----------// |
AzureIoTClient | 30:20a85b733111 | 409 | |
AzureIoTClient | 30:20a85b733111 | 410 | static void* authentication_clone_option(const char* name, const void* value) |
AzureIoTClient | 30:20a85b733111 | 411 | { |
AzureIoTClient | 30:20a85b733111 | 412 | void* result; |
AzureIoTClient | 30:20a85b733111 | 413 | |
AzureIoTClient | 30:20a85b733111 | 414 | if (name == NULL) |
AzureIoTClient | 30:20a85b733111 | 415 | { |
AzureIoTClient | 30:20a85b733111 | 416 | LogError("Failed to clone authentication option (name is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 417 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 418 | } |
AzureIoTClient | 30:20a85b733111 | 419 | else if (value == NULL) |
AzureIoTClient | 30:20a85b733111 | 420 | { |
AzureIoTClient | 30:20a85b733111 | 421 | LogError("Failed to clone authentication option (value is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 422 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 423 | } |
AzureIoTClient | 30:20a85b733111 | 424 | else |
AzureIoTClient | 30:20a85b733111 | 425 | { |
AzureIoTClient | 30:20a85b733111 | 426 | if (strcmp(AUTHENTICATION_OPTION_CBS_REQUEST_TIMEOUT_SECS, name) == 0 || |
AzureIoTClient | 30:20a85b733111 | 427 | strcmp(AUTHENTICATION_OPTION_SAS_TOKEN_REFRESH_TIME_SECS, name) == 0 || |
AzureIoTClient | 30:20a85b733111 | 428 | strcmp(AUTHENTICATION_OPTION_SAS_TOKEN_LIFETIME_SECS, name) == 0 || |
AzureIoTClient | 30:20a85b733111 | 429 | strcmp(AUTHENTICATION_OPTION_SAVED_OPTIONS, name) == 0) |
AzureIoTClient | 30:20a85b733111 | 430 | { |
AzureIoTClient | 30:20a85b733111 | 431 | result = (void*)value; |
AzureIoTClient | 30:20a85b733111 | 432 | } |
AzureIoTClient | 30:20a85b733111 | 433 | else |
AzureIoTClient | 30:20a85b733111 | 434 | { |
AzureIoTClient | 30:20a85b733111 | 435 | LogError("Failed to clone authentication option (option with name '%s' is not suppported)", name); |
AzureIoTClient | 30:20a85b733111 | 436 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 437 | } |
AzureIoTClient | 30:20a85b733111 | 438 | } |
AzureIoTClient | 30:20a85b733111 | 439 | |
AzureIoTClient | 30:20a85b733111 | 440 | return result; |
AzureIoTClient | 30:20a85b733111 | 441 | } |
AzureIoTClient | 30:20a85b733111 | 442 | |
AzureIoTClient | 30:20a85b733111 | 443 | static void authentication_destroy_option(const char* name, const void* value) |
AzureIoTClient | 30:20a85b733111 | 444 | { |
AzureIoTClient | 30:20a85b733111 | 445 | if (name == NULL) |
AzureIoTClient | 30:20a85b733111 | 446 | { |
AzureIoTClient | 30:20a85b733111 | 447 | LogError("Failed to destroy authentication option (name is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 448 | } |
AzureIoTClient | 30:20a85b733111 | 449 | else if (value == NULL) |
AzureIoTClient | 30:20a85b733111 | 450 | { |
AzureIoTClient | 30:20a85b733111 | 451 | LogError("Failed to destroy authentication option (value is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 452 | } |
AzureIoTClient | 30:20a85b733111 | 453 | else |
AzureIoTClient | 30:20a85b733111 | 454 | { |
AzureIoTClient | 30:20a85b733111 | 455 | if (strcmp(name, AUTHENTICATION_OPTION_SAVED_OPTIONS) == 0) |
AzureIoTClient | 30:20a85b733111 | 456 | { |
AzureIoTClient | 30:20a85b733111 | 457 | OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value); |
AzureIoTClient | 30:20a85b733111 | 458 | } |
AzureIoTClient | 30:20a85b733111 | 459 | } |
AzureIoTClient | 30:20a85b733111 | 460 | } |
AzureIoTClient | 30:20a85b733111 | 461 | |
AzureIoTClient | 30:20a85b733111 | 462 | |
AzureIoTClient | 30:20a85b733111 | 463 | // Public APIs: |
AzureIoTClient | 30:20a85b733111 | 464 | |
AzureIoTClient | 30:20a85b733111 | 465 | int authentication_start(AUTHENTICATION_HANDLE authentication_handle, const CBS_HANDLE cbs_handle) |
AzureIoTClient | 30:20a85b733111 | 466 | { |
AzureIoTClient | 30:20a85b733111 | 467 | int result; |
AzureIoTClient | 30:20a85b733111 | 468 | |
AzureIoTClient | 30:20a85b733111 | 469 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_025: [If authentication_handle is NULL, authentication_start() shall fail and return __FAILURE__ as error code] |
AzureIoTClient | 30:20a85b733111 | 470 | if (authentication_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 471 | { |
AzureIoTClient | 30:20a85b733111 | 472 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 473 | LogError("authentication_start failed (authentication_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 474 | } |
AzureIoTClient | 30:20a85b733111 | 475 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_026: [If `cbs_handle` is NULL, authentication_start() shall fail and return __FAILURE__ as error code] |
AzureIoTClient | 30:20a85b733111 | 476 | else if (cbs_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 477 | { |
AzureIoTClient | 30:20a85b733111 | 478 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 479 | LogError("authentication_start failed (cbs_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 480 | } |
AzureIoTClient | 30:20a85b733111 | 481 | else |
AzureIoTClient | 30:20a85b733111 | 482 | { |
AzureIoTClient | 30:20a85b733111 | 483 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 484 | |
AzureIoTClient | 30:20a85b733111 | 485 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_027: [If authenticate state has been started already, authentication_start() shall fail and return __FAILURE__ as error code] |
AzureIoTClient | 30:20a85b733111 | 486 | if (instance->state != AUTHENTICATION_STATE_STOPPED) |
AzureIoTClient | 30:20a85b733111 | 487 | { |
AzureIoTClient | 30:20a85b733111 | 488 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 489 | LogError("authentication_start failed (messenger has already been started; current state: %d)", instance->state); |
AzureIoTClient | 30:20a85b733111 | 490 | } |
AzureIoTClient | 30:20a85b733111 | 491 | else |
AzureIoTClient | 30:20a85b733111 | 492 | { |
AzureIoTClient | 30:20a85b733111 | 493 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_028: [authentication_start() shall save `cbs_handle` on `instance->cbs_handle`] |
AzureIoTClient | 30:20a85b733111 | 494 | instance->cbs_handle = cbs_handle; |
AzureIoTClient | 30:20a85b733111 | 495 | |
AzureIoTClient | 30:20a85b733111 | 496 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_029: [If no failures occur, `instance->state` shall be set to AUTHENTICATION_STATE_STARTING and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 497 | update_state(instance, AUTHENTICATION_STATE_STARTING); |
AzureIoTClient | 30:20a85b733111 | 498 | |
AzureIoTClient | 30:20a85b733111 | 499 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_030: [If no failures occur, authentication_start() shall return 0] |
AzureIoTClient | 30:20a85b733111 | 500 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 501 | } |
AzureIoTClient | 30:20a85b733111 | 502 | } |
AzureIoTClient | 30:20a85b733111 | 503 | |
AzureIoTClient | 30:20a85b733111 | 504 | return result; |
AzureIoTClient | 30:20a85b733111 | 505 | } |
AzureIoTClient | 30:20a85b733111 | 506 | |
AzureIoTClient | 30:20a85b733111 | 507 | int authentication_stop(AUTHENTICATION_HANDLE authentication_handle) |
AzureIoTClient | 30:20a85b733111 | 508 | { |
AzureIoTClient | 30:20a85b733111 | 509 | int result; |
AzureIoTClient | 30:20a85b733111 | 510 | |
AzureIoTClient | 30:20a85b733111 | 511 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_031: [If `authentication_handle` is NULL, authentication_stop() shall fail and return __FAILURE__] |
AzureIoTClient | 30:20a85b733111 | 512 | if (authentication_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 513 | { |
AzureIoTClient | 30:20a85b733111 | 514 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 515 | LogError("authentication_stop failed (authentication_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 516 | } |
AzureIoTClient | 30:20a85b733111 | 517 | else |
AzureIoTClient | 30:20a85b733111 | 518 | { |
AzureIoTClient | 30:20a85b733111 | 519 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 520 | |
AzureIoTClient | 30:20a85b733111 | 521 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_032: [If `instance->state` is AUTHENTICATION_STATE_STOPPED, authentication_stop() shall fail and return __FAILURE__] |
AzureIoTClient | 30:20a85b733111 | 522 | if (instance->state == AUTHENTICATION_STATE_STOPPED) |
AzureIoTClient | 30:20a85b733111 | 523 | { |
AzureIoTClient | 30:20a85b733111 | 524 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 525 | LogError("authentication_stop failed (messenger is already stopped)"); |
AzureIoTClient | 30:20a85b733111 | 526 | } |
AzureIoTClient | 30:20a85b733111 | 527 | else |
AzureIoTClient | 30:20a85b733111 | 528 | { |
AzureIoTClient | 30:20a85b733111 | 529 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_033: [`instance->cbs_handle` shall be set to NULL] |
AzureIoTClient | 30:20a85b733111 | 530 | instance->cbs_handle = NULL; |
AzureIoTClient | 30:20a85b733111 | 531 | |
AzureIoTClient | 30:20a85b733111 | 532 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_034: [`instance->state` shall be set to AUTHENTICATION_STATE_STOPPED and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 533 | update_state(instance, AUTHENTICATION_STATE_STOPPED); |
AzureIoTClient | 30:20a85b733111 | 534 | |
AzureIoTClient | 30:20a85b733111 | 535 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_035: [authentication_stop() shall return success code 0] |
AzureIoTClient | 30:20a85b733111 | 536 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 537 | } |
AzureIoTClient | 30:20a85b733111 | 538 | } |
AzureIoTClient | 30:20a85b733111 | 539 | |
AzureIoTClient | 30:20a85b733111 | 540 | return result; |
AzureIoTClient | 30:20a85b733111 | 541 | } |
AzureIoTClient | 30:20a85b733111 | 542 | |
AzureIoTClient | 30:20a85b733111 | 543 | void authentication_destroy(AUTHENTICATION_HANDLE authentication_handle) |
AzureIoTClient | 30:20a85b733111 | 544 | { |
AzureIoTClient | 30:20a85b733111 | 545 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_106: [If authentication_handle is NULL, authentication_destroy() shall return] |
AzureIoTClient | 30:20a85b733111 | 546 | if (authentication_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 547 | { |
AzureIoTClient | 30:20a85b733111 | 548 | LogError("authentication_destroy failed (authentication_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 549 | } |
AzureIoTClient | 30:20a85b733111 | 550 | else |
AzureIoTClient | 30:20a85b733111 | 551 | { |
AzureIoTClient | 30:20a85b733111 | 552 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 553 | |
AzureIoTClient | 30:20a85b733111 | 554 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_107: [If `instance->state` is AUTHENTICATION_STATE_STARTING or AUTHENTICATION_STATE_STARTED, authentication_stop() shall be invoked and its result ignored] |
AzureIoTClient | 30:20a85b733111 | 555 | if (instance->state != AUTHENTICATION_STATE_STOPPED) |
AzureIoTClient | 30:20a85b733111 | 556 | { |
AzureIoTClient | 30:20a85b733111 | 557 | (void)authentication_stop(authentication_handle); |
AzureIoTClient | 30:20a85b733111 | 558 | } |
AzureIoTClient | 30:20a85b733111 | 559 | |
AzureIoTClient | 30:20a85b733111 | 560 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_108: [authentication_destroy() shall destroy `instance->device_id` using STRING_delete()] |
AzureIoTClient | 30:20a85b733111 | 561 | if (instance->device_id != NULL) |
AzureIoTClient | 30:20a85b733111 | 562 | STRING_delete(instance->device_id); |
AzureIoTClient | 30:20a85b733111 | 563 | |
AzureIoTClient | 30:20a85b733111 | 564 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_109: [authentication_destroy() shall destroy `instance->device_sas_token` using STRING_delete()] |
AzureIoTClient | 30:20a85b733111 | 565 | if (instance->device_sas_token != NULL) |
AzureIoTClient | 30:20a85b733111 | 566 | STRING_delete(instance->device_sas_token); |
AzureIoTClient | 30:20a85b733111 | 567 | |
AzureIoTClient | 30:20a85b733111 | 568 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_110: [authentication_destroy() shall destroy `instance->device_primary_key` using STRING_delete()] |
AzureIoTClient | 30:20a85b733111 | 569 | if (instance->device_primary_key != NULL) |
AzureIoTClient | 30:20a85b733111 | 570 | STRING_delete(instance->device_primary_key); |
AzureIoTClient | 30:20a85b733111 | 571 | |
AzureIoTClient | 30:20a85b733111 | 572 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_111: [authentication_destroy() shall destroy `instance->device_secondary_key` using STRING_delete()] |
AzureIoTClient | 30:20a85b733111 | 573 | if (instance->device_secondary_key != NULL) |
AzureIoTClient | 30:20a85b733111 | 574 | STRING_delete(instance->device_secondary_key); |
AzureIoTClient | 30:20a85b733111 | 575 | |
AzureIoTClient | 30:20a85b733111 | 576 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_112: [authentication_destroy() shall destroy `instance->iothub_host_fqdn` using STRING_delete()] |
AzureIoTClient | 30:20a85b733111 | 577 | if (instance->iothub_host_fqdn != NULL) |
AzureIoTClient | 30:20a85b733111 | 578 | STRING_delete(instance->iothub_host_fqdn); |
AzureIoTClient | 30:20a85b733111 | 579 | |
AzureIoTClient | 30:20a85b733111 | 580 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_113: [authentication_destroy() shall destroy `instance` using free()] |
AzureIoTClient | 30:20a85b733111 | 581 | free(instance); |
AzureIoTClient | 30:20a85b733111 | 582 | } |
AzureIoTClient | 30:20a85b733111 | 583 | } |
AzureIoTClient | 30:20a85b733111 | 584 | |
AzureIoTClient | 30:20a85b733111 | 585 | AUTHENTICATION_HANDLE authentication_create(const AUTHENTICATION_CONFIG* config) |
AzureIoTClient | 30:20a85b733111 | 586 | { |
AzureIoTClient | 30:20a85b733111 | 587 | AUTHENTICATION_HANDLE result; |
AzureIoTClient | 30:20a85b733111 | 588 | |
AzureIoTClient | 30:20a85b733111 | 589 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_001: [If parameter `config` or `config->device_id` are NULL, authentication_create() shall fail and return NULL.] |
AzureIoTClient | 30:20a85b733111 | 590 | if (config == NULL) |
AzureIoTClient | 30:20a85b733111 | 591 | { |
AzureIoTClient | 30:20a85b733111 | 592 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 593 | LogError("authentication_create failed (config is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 594 | } |
AzureIoTClient | 30:20a85b733111 | 595 | else if (config->device_id == NULL) |
AzureIoTClient | 30:20a85b733111 | 596 | { |
AzureIoTClient | 30:20a85b733111 | 597 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 598 | LogError("authentication_create failed (config->device_id is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 599 | } |
AzureIoTClient | 30:20a85b733111 | 600 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_002: [If device keys and SAS token are NULL, authentication_create() shall fail and return NULL.] |
AzureIoTClient | 30:20a85b733111 | 601 | else if (config->device_sas_token == NULL && config->device_primary_key == NULL) |
AzureIoTClient | 30:20a85b733111 | 602 | { |
AzureIoTClient | 30:20a85b733111 | 603 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 604 | LogError("authentication_create failed (either config->device_sas_token or config->device_primary_key must be provided; config->device_secondary_key is optional)"); |
AzureIoTClient | 30:20a85b733111 | 605 | } |
AzureIoTClient | 30:20a85b733111 | 606 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_003: [If device keys and SAS token are both provided, authentication_create() shall fail and return NULL.] |
AzureIoTClient | 30:20a85b733111 | 607 | else if (config->device_sas_token != NULL && (config->device_primary_key != NULL || config->device_secondary_key != NULL)) |
AzureIoTClient | 30:20a85b733111 | 608 | { |
AzureIoTClient | 30:20a85b733111 | 609 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 610 | LogError("authentication_create failed (both config->device_sas_token and device device keys were provided; must provide only one)"); |
AzureIoTClient | 30:20a85b733111 | 611 | } |
AzureIoTClient | 30:20a85b733111 | 612 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_004: [If `config->iothub_host_fqdn` is NULL, authentication_create() shall fail and return NULL.] |
AzureIoTClient | 30:20a85b733111 | 613 | else if (config->iothub_host_fqdn == NULL) |
AzureIoTClient | 30:20a85b733111 | 614 | { |
AzureIoTClient | 30:20a85b733111 | 615 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 616 | LogError("authentication_create failed (config->iothub_host_fqdn is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 617 | } |
AzureIoTClient | 30:20a85b733111 | 618 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_005: [If `config->on_state_changed_callback` is NULL, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 619 | else if (config->on_state_changed_callback == NULL) |
AzureIoTClient | 30:20a85b733111 | 620 | { |
AzureIoTClient | 30:20a85b733111 | 621 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 622 | LogError("authentication_create failed (config->on_state_changed_callback is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 623 | } |
AzureIoTClient | 30:20a85b733111 | 624 | else |
AzureIoTClient | 30:20a85b733111 | 625 | { |
AzureIoTClient | 30:20a85b733111 | 626 | AUTHENTICATION_INSTANCE* instance; |
AzureIoTClient | 30:20a85b733111 | 627 | |
AzureIoTClient | 30:20a85b733111 | 628 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_006: [authentication_create() shall allocate memory for a new authenticate state structure AUTHENTICATION_INSTANCE.] |
AzureIoTClient | 30:20a85b733111 | 629 | if ((instance = (AUTHENTICATION_INSTANCE*)malloc(sizeof(AUTHENTICATION_INSTANCE))) == NULL) |
AzureIoTClient | 30:20a85b733111 | 630 | { |
AzureIoTClient | 30:20a85b733111 | 631 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_007: [If malloc() fails, authentication_create() shall fail and return NULL.] |
AzureIoTClient | 30:20a85b733111 | 632 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 633 | LogError("authentication_create failed (malloc failed)"); |
AzureIoTClient | 30:20a85b733111 | 634 | } |
AzureIoTClient | 30:20a85b733111 | 635 | else |
AzureIoTClient | 30:20a85b733111 | 636 | { |
AzureIoTClient | 30:20a85b733111 | 637 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_123: [authentication_create() shall initialize all fields of `instance` with 0 using memset().] |
AzureIoTClient | 30:20a85b733111 | 638 | memset(instance, 0, sizeof(AUTHENTICATION_INSTANCE)); |
AzureIoTClient | 30:20a85b733111 | 639 | |
AzureIoTClient | 30:20a85b733111 | 640 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_008: [authentication_create() shall save a copy of `config->device_id` into the `instance->device_id`] |
AzureIoTClient | 30:20a85b733111 | 641 | if ((instance->device_id = STRING_construct(config->device_id)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 642 | { |
AzureIoTClient | 30:20a85b733111 | 643 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_009: [If STRING_construct() fails, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 644 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 645 | LogError("authentication_create failed (config->device_id could not be copied; STRING_construct failed)"); |
AzureIoTClient | 30:20a85b733111 | 646 | } |
AzureIoTClient | 30:20a85b733111 | 647 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_010: [If `device_config->device_sas_token` is not NULL, authentication_create() shall save a copy into the `instance->device_sas_token`] |
AzureIoTClient | 30:20a85b733111 | 648 | else if (config->device_sas_token != NULL && (instance->device_sas_token = STRING_construct(config->device_sas_token)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 649 | { |
AzureIoTClient | 30:20a85b733111 | 650 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_011: [If STRING_construct() fails, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 651 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 652 | LogError("authentication_create failed (config->device_sas_token could not be copied; STRING_construct failed)"); |
AzureIoTClient | 30:20a85b733111 | 653 | } |
AzureIoTClient | 30:20a85b733111 | 654 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_012: [If provided, authentication_create() shall save a copy of `config->device_primary_key` into the `instance->device_primary_key`] |
AzureIoTClient | 30:20a85b733111 | 655 | else if (config->device_primary_key != NULL && (instance->device_primary_key = STRING_construct(config->device_primary_key)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 656 | { |
AzureIoTClient | 30:20a85b733111 | 657 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_013: [If STRING_construct() fails to copy `config->device_primary_key`, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 658 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 659 | LogError("authentication_create failed (config->device_primary_key could not be copied; STRING_construct failed)"); |
AzureIoTClient | 30:20a85b733111 | 660 | } |
AzureIoTClient | 30:20a85b733111 | 661 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_014: [If provided, authentication_create() shall save a copy of `config->device_secondary_key` into `instance->device_secondary_key`] |
AzureIoTClient | 30:20a85b733111 | 662 | else if (config->device_secondary_key != NULL && (instance->device_secondary_key = STRING_construct(config->device_secondary_key)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 663 | { |
AzureIoTClient | 30:20a85b733111 | 664 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_015: [If STRING_construct() fails to copy `config->device_secondary_key`, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 665 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 666 | LogError("authentication_create failed (config->device_secondary_key could not be copied; STRING_construct failed)"); |
AzureIoTClient | 30:20a85b733111 | 667 | } |
AzureIoTClient | 30:20a85b733111 | 668 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_016: [If provided, authentication_create() shall save a copy of `config->iothub_host_fqdn` into `instance->iothub_host_fqdn`] |
AzureIoTClient | 30:20a85b733111 | 669 | else if ((instance->iothub_host_fqdn = STRING_construct(config->iothub_host_fqdn)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 670 | { |
AzureIoTClient | 30:20a85b733111 | 671 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_017: [If STRING_clone() fails to copy `config->iothub_host_fqdn`, authentication_create() shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 672 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 673 | LogError("authentication_create failed (config->iothub_host_fqdn could not be copied; STRING_construct failed)"); |
AzureIoTClient | 30:20a85b733111 | 674 | } |
AzureIoTClient | 30:20a85b733111 | 675 | else |
AzureIoTClient | 30:20a85b733111 | 676 | { |
AzureIoTClient | 30:20a85b733111 | 677 | instance->state = AUTHENTICATION_STATE_STOPPED; |
AzureIoTClient | 30:20a85b733111 | 678 | |
AzureIoTClient | 30:20a85b733111 | 679 | if (instance->device_sas_token != NULL) |
AzureIoTClient | 30:20a85b733111 | 680 | { |
AzureIoTClient | 30:20a85b733111 | 681 | instance->current_credential_in_use = USER_PROVIDED_SAS_TOKEN; |
AzureIoTClient | 30:20a85b733111 | 682 | } |
AzureIoTClient | 30:20a85b733111 | 683 | else |
AzureIoTClient | 30:20a85b733111 | 684 | { |
AzureIoTClient | 30:20a85b733111 | 685 | instance->current_credential_in_use = DEVICE_PRIMARY_KEY; |
AzureIoTClient | 30:20a85b733111 | 686 | } |
AzureIoTClient | 30:20a85b733111 | 687 | |
AzureIoTClient | 30:20a85b733111 | 688 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_018: [authentication_create() shall save `config->on_state_changed_callback` and `config->on_state_changed_callback_context` into `instance->on_state_changed_callback` and `instance->on_state_changed_callback_context`.] |
AzureIoTClient | 30:20a85b733111 | 689 | instance->on_state_changed_callback = config->on_state_changed_callback; |
AzureIoTClient | 30:20a85b733111 | 690 | instance->on_state_changed_callback_context = config->on_state_changed_callback_context; |
AzureIoTClient | 30:20a85b733111 | 691 | |
AzureIoTClient | 30:20a85b733111 | 692 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_019: [authentication_create() shall save `config->on_error_callback` and `config->on_error_callback_context` into `instance->on_error_callback` and `instance->on_error_callback_context`.] |
AzureIoTClient | 30:20a85b733111 | 693 | instance->on_error_callback = config->on_error_callback; |
AzureIoTClient | 30:20a85b733111 | 694 | instance->on_error_callback_context = config->on_error_callback_context; |
AzureIoTClient | 30:20a85b733111 | 695 | |
AzureIoTClient | 30:20a85b733111 | 696 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_021: [authentication_create() shall set `instance->cbs_request_timeout_secs` with the default value of UINT32_MAX] |
AzureIoTClient | 30:20a85b733111 | 697 | instance->cbs_request_timeout_secs = DEFAULT_CBS_REQUEST_TIMEOUT_SECS; |
AzureIoTClient | 30:20a85b733111 | 698 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_022: [authentication_create() shall set `instance->sas_token_lifetime_secs` with the default value of one hour] |
AzureIoTClient | 30:20a85b733111 | 699 | instance->sas_token_lifetime_secs = DEFAULT_SAS_TOKEN_LIFETIME_SECS; |
AzureIoTClient | 30:20a85b733111 | 700 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_023: [authentication_create() shall set `instance->sas_token_refresh_time_secs` with the default value of 30 minutes] |
AzureIoTClient | 30:20a85b733111 | 701 | instance->sas_token_refresh_time_secs = DEFAULT_SAS_TOKEN_REFRESH_TIME_SECS; |
AzureIoTClient | 30:20a85b733111 | 702 | |
AzureIoTClient | 30:20a85b733111 | 703 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_024: [If no failure occurs, authentication_create() shall return a reference to the AUTHENTICATION_INSTANCE handle] |
AzureIoTClient | 30:20a85b733111 | 704 | result = (AUTHENTICATION_HANDLE)instance; |
AzureIoTClient | 30:20a85b733111 | 705 | } |
AzureIoTClient | 30:20a85b733111 | 706 | |
AzureIoTClient | 30:20a85b733111 | 707 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_020: [If any failure occurs, authentication_create() shall free any memory it allocated previously] |
AzureIoTClient | 30:20a85b733111 | 708 | if (result == NULL) |
AzureIoTClient | 30:20a85b733111 | 709 | { |
AzureIoTClient | 30:20a85b733111 | 710 | authentication_destroy((AUTHENTICATION_HANDLE)instance); |
AzureIoTClient | 30:20a85b733111 | 711 | } |
AzureIoTClient | 30:20a85b733111 | 712 | } |
AzureIoTClient | 30:20a85b733111 | 713 | } |
AzureIoTClient | 30:20a85b733111 | 714 | |
AzureIoTClient | 30:20a85b733111 | 715 | return result; |
AzureIoTClient | 30:20a85b733111 | 716 | } |
AzureIoTClient | 30:20a85b733111 | 717 | |
AzureIoTClient | 30:20a85b733111 | 718 | void authentication_do_work(AUTHENTICATION_HANDLE authentication_handle) |
AzureIoTClient | 30:20a85b733111 | 719 | { |
AzureIoTClient | 30:20a85b733111 | 720 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_036: [If authentication_handle is NULL, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 721 | if (authentication_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 722 | { |
AzureIoTClient | 30:20a85b733111 | 723 | LogError("authentication_do_work failed (authentication_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 724 | } |
AzureIoTClient | 30:20a85b733111 | 725 | else |
AzureIoTClient | 30:20a85b733111 | 726 | { |
AzureIoTClient | 30:20a85b733111 | 727 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 728 | |
AzureIoTClient | 30:20a85b733111 | 729 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_038: [If `instance->is_cbs_put_token_in_progress` is TRUE, authentication_do_work() shall only verify the authentication timeout] |
AzureIoTClient | 30:20a85b733111 | 730 | if (instance->is_cbs_put_token_in_progress) |
AzureIoTClient | 30:20a85b733111 | 731 | { |
AzureIoTClient | 30:20a85b733111 | 732 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_084: [If no timeout has occurred, authentication_do_work() shall return] |
AzureIoTClient | 30:20a85b733111 | 733 | |
AzureIoTClient | 30:20a85b733111 | 734 | bool is_timed_out; |
AzureIoTClient | 30:20a85b733111 | 735 | if (verify_cbs_put_token_timeout(instance, &is_timed_out) == RESULT_OK && is_timed_out) |
AzureIoTClient | 30:20a85b733111 | 736 | { |
AzureIoTClient | 30:20a85b733111 | 737 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_085: [`instance->is_cbs_put_token_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 738 | instance->is_cbs_put_token_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 739 | |
AzureIoTClient | 30:20a85b733111 | 740 | if (mark_current_device_key_as_invalid(instance)) |
AzureIoTClient | 30:20a85b733111 | 741 | { |
AzureIoTClient | 30:20a85b733111 | 742 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_086: [`instance->state` shall be updated to AUTHENTICATION_STATE_ERROR and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 743 | update_state(instance, AUTHENTICATION_STATE_ERROR); |
AzureIoTClient | 30:20a85b733111 | 744 | |
AzureIoTClient | 30:20a85b733111 | 745 | if (instance->is_sas_token_refresh_in_progress) |
AzureIoTClient | 30:20a85b733111 | 746 | { |
AzureIoTClient | 30:20a85b733111 | 747 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_087: [If `instance->is_sas_token_refresh_in_progress` is TRUE, `instance->on_error_callback` shall be invoked with AUTHENTICATION_ERROR_SAS_REFRESH_TIMEOUT] |
AzureIoTClient | 30:20a85b733111 | 748 | notify_error(instance, AUTHENTICATION_ERROR_SAS_REFRESH_TIMEOUT); |
AzureIoTClient | 30:20a85b733111 | 749 | } |
AzureIoTClient | 30:20a85b733111 | 750 | else |
AzureIoTClient | 30:20a85b733111 | 751 | { |
AzureIoTClient | 30:20a85b733111 | 752 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_088: [If `instance->is_sas_token_refresh_in_progress` is FALSE, `instance->on_error_callback` shall be invoked with AUTHENTICATION_ERROR_AUTH_TIMEOUT] |
AzureIoTClient | 30:20a85b733111 | 753 | notify_error(instance, AUTHENTICATION_ERROR_AUTH_TIMEOUT); |
AzureIoTClient | 30:20a85b733111 | 754 | } |
AzureIoTClient | 30:20a85b733111 | 755 | } |
AzureIoTClient | 30:20a85b733111 | 756 | |
AzureIoTClient | 30:20a85b733111 | 757 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_089: [`instance->is_sas_token_refresh_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 758 | instance->is_sas_token_refresh_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 759 | } |
AzureIoTClient | 30:20a85b733111 | 760 | } |
AzureIoTClient | 30:20a85b733111 | 761 | else if (instance->state == AUTHENTICATION_STATE_STARTED) |
AzureIoTClient | 30:20a85b733111 | 762 | { |
AzureIoTClient | 30:20a85b733111 | 763 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_040: [If `instance->state` is AUTHENTICATION_STATE_STARTED and user-provided SAS token was used, authentication_do_work() shall return] |
AzureIoTClient | 30:20a85b733111 | 764 | if (are_device_keys_used_for_authentication(instance)) |
AzureIoTClient | 30:20a85b733111 | 765 | { |
AzureIoTClient | 30:20a85b733111 | 766 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_039: [If `instance->state` is AUTHENTICATION_STATE_STARTED and device keys were used, authentication_do_work() shall only verify the SAS token refresh time] |
AzureIoTClient | 30:20a85b733111 | 767 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_065: [The SAS token shall be refreshed if the current time minus `instance->current_sas_token_put_time` equals or exceeds `instance->sas_token_refresh_time_secs`] |
AzureIoTClient | 30:20a85b733111 | 768 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_066: [If SAS token does not need to be refreshed, authentication_do_work() shall return] |
AzureIoTClient | 30:20a85b733111 | 769 | bool is_timed_out; |
AzureIoTClient | 30:20a85b733111 | 770 | if (verify_sas_token_refresh_timeout(instance, &is_timed_out) == RESULT_OK && is_timed_out) |
AzureIoTClient | 30:20a85b733111 | 771 | { |
AzureIoTClient | 30:20a85b733111 | 772 | STRING_HANDLE device_key; |
AzureIoTClient | 30:20a85b733111 | 773 | |
AzureIoTClient | 30:20a85b733111 | 774 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_119: [authentication_do_work() shall set `instance->is_sas_token_refresh_in_progress` to TRUE] |
AzureIoTClient | 30:20a85b733111 | 775 | instance->is_sas_token_refresh_in_progress = true; |
AzureIoTClient | 30:20a85b733111 | 776 | |
AzureIoTClient | 30:20a85b733111 | 777 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_067: [authentication_do_work() shall create a SAS token using `instance->device_primary_key`, unless it has failed previously] |
AzureIoTClient | 30:20a85b733111 | 778 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_069: [If using `instance->device_primary_key` has failed previously, a SAS token shall be created using `instance->device_secondary_key`] |
AzureIoTClient | 30:20a85b733111 | 779 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_068: [If using `instance->device_primary_key` has failed previously and `instance->device_secondary_key` is not provided, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 780 | while ((device_key = get_current_valid_device_key(instance)) != NULL) |
AzureIoTClient | 30:20a85b733111 | 781 | { |
AzureIoTClient | 30:20a85b733111 | 782 | if (create_and_put_SAS_token_to_cbs(instance, device_key) == RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 783 | { |
AzureIoTClient | 30:20a85b733111 | 784 | break; |
AzureIoTClient | 30:20a85b733111 | 785 | } |
AzureIoTClient | 30:20a85b733111 | 786 | else |
AzureIoTClient | 30:20a85b733111 | 787 | { |
AzureIoTClient | 30:20a85b733111 | 788 | LogError("Failed refreshing SAS token (%d)", instance->current_credential_in_use); |
AzureIoTClient | 30:20a85b733111 | 789 | (void)mark_current_device_key_as_invalid(instance); |
AzureIoTClient | 30:20a85b733111 | 790 | } |
AzureIoTClient | 30:20a85b733111 | 791 | } |
AzureIoTClient | 30:20a85b733111 | 792 | |
AzureIoTClient | 30:20a85b733111 | 793 | if (!instance->is_cbs_put_token_in_progress) |
AzureIoTClient | 30:20a85b733111 | 794 | { |
AzureIoTClient | 30:20a85b733111 | 795 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_120: [If cbs_put_token() fails, `instance->is_sas_token_refresh_in_progress` shall be set to FALSE] |
AzureIoTClient | 30:20a85b733111 | 796 | instance->is_sas_token_refresh_in_progress = false; |
AzureIoTClient | 30:20a85b733111 | 797 | |
AzureIoTClient | 30:20a85b733111 | 798 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_079: [If cbs_put_token() fails, `instance->state` shall be updated to AUTHENTICATION_STATE_ERROR and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 799 | update_state(instance, AUTHENTICATION_STATE_ERROR); |
AzureIoTClient | 30:20a85b733111 | 800 | |
AzureIoTClient | 30:20a85b733111 | 801 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_080: [If cbs_put_token() fails, `instance->on_error_callback` shall be invoked with AUTHENTICATION_ERROR_SAS_REFRESH_FAILED] |
AzureIoTClient | 30:20a85b733111 | 802 | notify_error(instance, AUTHENTICATION_ERROR_SAS_REFRESH_FAILED); |
AzureIoTClient | 30:20a85b733111 | 803 | } |
AzureIoTClient | 30:20a85b733111 | 804 | } |
AzureIoTClient | 30:20a85b733111 | 805 | } |
AzureIoTClient | 30:20a85b733111 | 806 | } |
AzureIoTClient | 30:20a85b733111 | 807 | else if (instance->state == AUTHENTICATION_STATE_STARTING) |
AzureIoTClient | 30:20a85b733111 | 808 | { |
AzureIoTClient | 30:20a85b733111 | 809 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_041: [If `instance->device_sas_token` is provided, authentication_do_work() shall put it to CBS] |
AzureIoTClient | 30:20a85b733111 | 810 | if (instance->device_sas_token != NULL) |
AzureIoTClient | 30:20a85b733111 | 811 | { |
AzureIoTClient | 30:20a85b733111 | 812 | STRING_HANDLE devices_path; |
AzureIoTClient | 30:20a85b733111 | 813 | |
AzureIoTClient | 30:20a85b733111 | 814 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_044: [A STRING_HANDLE, referred to as `devices_path`, shall be created from the following parts: iothub_host_fqdn + "/devices/" + device_id] |
AzureIoTClient | 30:20a85b733111 | 815 | if ((devices_path = create_devices_path(instance->iothub_host_fqdn, instance->device_id)) == NULL) |
AzureIoTClient | 30:20a85b733111 | 816 | { |
AzureIoTClient | 30:20a85b733111 | 817 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_045: [If `devices_path` failed to be created, authentication_do_work() shall set `instance->is_cbs_put_token_in_progress` to FALSE and return] |
AzureIoTClient | 30:20a85b733111 | 818 | LogError("Failed authenticating using SAS token (create_devices_path() failed)"); |
AzureIoTClient | 30:20a85b733111 | 819 | } |
AzureIoTClient | 30:20a85b733111 | 820 | else if (put_SAS_token_to_cbs(instance, devices_path, instance->device_sas_token) != RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 821 | { |
AzureIoTClient | 30:20a85b733111 | 822 | LogError("Failed authenticating using SAS token (put_SAS_token_to_cbs() failed)"); |
AzureIoTClient | 30:20a85b733111 | 823 | } |
AzureIoTClient | 30:20a85b733111 | 824 | |
AzureIoTClient | 30:20a85b733111 | 825 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_063: [authentication_do_work() shall free the memory it allocated for `devices_path`, `sasTokenKeyName` and SAS token] |
AzureIoTClient | 30:20a85b733111 | 826 | STRING_delete(devices_path); |
AzureIoTClient | 30:20a85b733111 | 827 | } |
AzureIoTClient | 30:20a85b733111 | 828 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_042: [Otherwise, authentication_do_work() shall use device keys for CBS authentication] |
AzureIoTClient | 30:20a85b733111 | 829 | else |
AzureIoTClient | 30:20a85b733111 | 830 | { |
AzureIoTClient | 30:20a85b733111 | 831 | STRING_HANDLE device_key; |
AzureIoTClient | 30:20a85b733111 | 832 | |
AzureIoTClient | 30:20a85b733111 | 833 | while ((device_key = get_current_valid_device_key(instance)) != NULL) |
AzureIoTClient | 30:20a85b733111 | 834 | { |
AzureIoTClient | 30:20a85b733111 | 835 | if (create_and_put_SAS_token_to_cbs(instance, device_key) == RESULT_OK) |
AzureIoTClient | 30:20a85b733111 | 836 | { |
AzureIoTClient | 30:20a85b733111 | 837 | break; |
AzureIoTClient | 30:20a85b733111 | 838 | } |
AzureIoTClient | 30:20a85b733111 | 839 | else |
AzureIoTClient | 30:20a85b733111 | 840 | { |
AzureIoTClient | 30:20a85b733111 | 841 | LogError("Failed authenticating device '%s' using device keys (%d)", STRING_c_str(instance->device_id), instance->current_credential_in_use); |
AzureIoTClient | 30:20a85b733111 | 842 | (void)mark_current_device_key_as_invalid(instance); |
AzureIoTClient | 30:20a85b733111 | 843 | } |
AzureIoTClient | 30:20a85b733111 | 844 | } |
AzureIoTClient | 30:20a85b733111 | 845 | } |
AzureIoTClient | 30:20a85b733111 | 846 | |
AzureIoTClient | 30:20a85b733111 | 847 | if (!instance->is_cbs_put_token_in_progress) |
AzureIoTClient | 30:20a85b733111 | 848 | { |
AzureIoTClient | 30:20a85b733111 | 849 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_061: [If cbs_put_token() fails, `instance->state` shall be updated to AUTHENTICATION_STATE_ERROR and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 850 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_121: [If cbs_put_token() fails, `instance->state` shall be updated to AUTHENTICATION_STATE_ERROR and `instance->on_state_changed_callback` invoked] |
AzureIoTClient | 30:20a85b733111 | 851 | update_state(instance, AUTHENTICATION_STATE_ERROR); |
AzureIoTClient | 30:20a85b733111 | 852 | |
AzureIoTClient | 30:20a85b733111 | 853 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_062: [If cbs_put_token() fails, `instance->on_error_callback` shall be invoked with AUTHENTICATION_ERROR_AUTH_FAILED] |
AzureIoTClient | 30:20a85b733111 | 854 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_122: [If cbs_put_token() fails, `instance->on_error_callback` shall be invoked with AUTHENTICATION_ERROR_AUTH_FAILED] |
AzureIoTClient | 30:20a85b733111 | 855 | notify_error(instance, AUTHENTICATION_ERROR_AUTH_FAILED); |
AzureIoTClient | 30:20a85b733111 | 856 | } |
AzureIoTClient | 30:20a85b733111 | 857 | } |
AzureIoTClient | 30:20a85b733111 | 858 | else |
AzureIoTClient | 30:20a85b733111 | 859 | { |
AzureIoTClient | 30:20a85b733111 | 860 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_037: [If `instance->state` is not AUTHENTICATION_STATE_STARTING or AUTHENTICATION_STATE_STARTED, authentication_do_work() shall fail and return] |
AzureIoTClient | 30:20a85b733111 | 861 | // Nothing to be done. |
AzureIoTClient | 30:20a85b733111 | 862 | } |
AzureIoTClient | 30:20a85b733111 | 863 | } |
AzureIoTClient | 30:20a85b733111 | 864 | } |
AzureIoTClient | 30:20a85b733111 | 865 | |
AzureIoTClient | 30:20a85b733111 | 866 | int authentication_set_option(AUTHENTICATION_HANDLE authentication_handle, const char* name, void* value) |
AzureIoTClient | 30:20a85b733111 | 867 | { |
AzureIoTClient | 30:20a85b733111 | 868 | int result; |
AzureIoTClient | 30:20a85b733111 | 869 | |
AzureIoTClient | 30:20a85b733111 | 870 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_097: [If `authentication_handle` or `name` or `value` is NULL, authentication_set_option shall fail and return a non-zero value] |
AzureIoTClient | 30:20a85b733111 | 871 | if (authentication_handle == NULL || name == NULL || value == NULL) |
AzureIoTClient | 30:20a85b733111 | 872 | { |
AzureIoTClient | 30:20a85b733111 | 873 | LogError("authentication_set_option failed (one of the followin are NULL: authentication_handle=%p, name=%p, value=%p)", |
AzureIoTClient | 30:20a85b733111 | 874 | authentication_handle, name, value); |
AzureIoTClient | 30:20a85b733111 | 875 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 876 | } |
AzureIoTClient | 30:20a85b733111 | 877 | else |
AzureIoTClient | 30:20a85b733111 | 878 | { |
AzureIoTClient | 30:20a85b733111 | 879 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 880 | |
AzureIoTClient | 30:20a85b733111 | 881 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_098: [If name matches AUTHENTICATION_OPTION_CBS_REQUEST_TIMEOUT_SECS, `value` shall be saved on `instance->cbs_request_timeout_secs`] |
AzureIoTClient | 30:20a85b733111 | 882 | if (strcmp(AUTHENTICATION_OPTION_CBS_REQUEST_TIMEOUT_SECS, name) == 0) |
AzureIoTClient | 30:20a85b733111 | 883 | { |
AzureIoTClient | 30:20a85b733111 | 884 | instance->cbs_request_timeout_secs = *((size_t*)value); |
AzureIoTClient | 30:20a85b733111 | 885 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 886 | } |
AzureIoTClient | 30:20a85b733111 | 887 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_124: [If name matches AUTHENTICATION_OPTION_SAS_TOKEN_REFRESH_TIME_SECS, `value` shall be saved on `instance->sas_token_refresh_time_secs`] |
AzureIoTClient | 30:20a85b733111 | 888 | else if (strcmp(AUTHENTICATION_OPTION_SAS_TOKEN_REFRESH_TIME_SECS, name) == 0) |
AzureIoTClient | 30:20a85b733111 | 889 | { |
AzureIoTClient | 30:20a85b733111 | 890 | instance->sas_token_refresh_time_secs = *((size_t*)value); |
AzureIoTClient | 30:20a85b733111 | 891 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 892 | } |
AzureIoTClient | 30:20a85b733111 | 893 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_125: [If name matches AUTHENTICATION_OPTION_SAS_TOKEN_LIFETIME_SECS, `value` shall be saved on `instance->sas_token_lifetime_secs`] |
AzureIoTClient | 30:20a85b733111 | 894 | else if (strcmp(AUTHENTICATION_OPTION_SAS_TOKEN_LIFETIME_SECS, name) == 0) |
AzureIoTClient | 30:20a85b733111 | 895 | { |
AzureIoTClient | 30:20a85b733111 | 896 | instance->sas_token_lifetime_secs = *((size_t*)value); |
AzureIoTClient | 30:20a85b733111 | 897 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 898 | } |
AzureIoTClient | 30:20a85b733111 | 899 | else if (strcmp(AUTHENTICATION_OPTION_SAVED_OPTIONS, name) == 0) |
AzureIoTClient | 30:20a85b733111 | 900 | { |
AzureIoTClient | 30:20a85b733111 | 901 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_098: [If name matches AUTHENTICATION_OPTION_SAVED_OPTIONS, `value` shall be applied using OptionHandler_FeedOptions] |
AzureIoTClient | 30:20a85b733111 | 902 | if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, authentication_handle) != OPTIONHANDLER_OK) |
AzureIoTClient | 30:20a85b733111 | 903 | { |
AzureIoTClient | 30:20a85b733111 | 904 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_126: [If OptionHandler_FeedOptions fails, authentication_set_option shall fail and return a non-zero value] |
AzureIoTClient | 30:20a85b733111 | 905 | LogError("authentication_set_option failed (OptionHandler_FeedOptions failed)"); |
AzureIoTClient | 30:20a85b733111 | 906 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 907 | } |
AzureIoTClient | 30:20a85b733111 | 908 | else |
AzureIoTClient | 30:20a85b733111 | 909 | { |
AzureIoTClient | 30:20a85b733111 | 910 | result = RESULT_OK; |
AzureIoTClient | 30:20a85b733111 | 911 | } |
AzureIoTClient | 30:20a85b733111 | 912 | } |
AzureIoTClient | 30:20a85b733111 | 913 | else |
AzureIoTClient | 30:20a85b733111 | 914 | { |
AzureIoTClient | 30:20a85b733111 | 915 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_128: [If name does not match any supported option, authentication_set_option shall fail and return a non-zero value] |
AzureIoTClient | 30:20a85b733111 | 916 | LogError("authentication_set_option failed (option with name '%s' is not suppported)", name); |
AzureIoTClient | 30:20a85b733111 | 917 | result = __FAILURE__; |
AzureIoTClient | 30:20a85b733111 | 918 | } |
AzureIoTClient | 30:20a85b733111 | 919 | } |
AzureIoTClient | 30:20a85b733111 | 920 | |
AzureIoTClient | 30:20a85b733111 | 921 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_099: [If no errors occur, authentication_set_option shall return 0] |
AzureIoTClient | 30:20a85b733111 | 922 | return result; |
AzureIoTClient | 30:20a85b733111 | 923 | } |
AzureIoTClient | 30:20a85b733111 | 924 | |
AzureIoTClient | 30:20a85b733111 | 925 | OPTIONHANDLER_HANDLE authentication_retrieve_options(AUTHENTICATION_HANDLE authentication_handle) |
AzureIoTClient | 30:20a85b733111 | 926 | { |
AzureIoTClient | 30:20a85b733111 | 927 | OPTIONHANDLER_HANDLE result; |
AzureIoTClient | 30:20a85b733111 | 928 | |
AzureIoTClient | 30:20a85b733111 | 929 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_100: [If `authentication_handle` is NULL, authentication_retrieve_options shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 930 | if (authentication_handle == NULL) |
AzureIoTClient | 30:20a85b733111 | 931 | { |
AzureIoTClient | 30:20a85b733111 | 932 | LogError("Failed to retrieve options from authentication instance (authentication_handle is NULL)"); |
AzureIoTClient | 30:20a85b733111 | 933 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 934 | } |
AzureIoTClient | 30:20a85b733111 | 935 | else |
AzureIoTClient | 30:20a85b733111 | 936 | { |
AzureIoTClient | 30:20a85b733111 | 937 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_101: [An OPTIONHANDLER_HANDLE instance shall be created using OptionHandler_Create] |
AzureIoTClient | 30:20a85b733111 | 938 | OPTIONHANDLER_HANDLE options = OptionHandler_Create(authentication_clone_option, authentication_destroy_option, (pfSetOption)authentication_set_option); |
AzureIoTClient | 30:20a85b733111 | 939 | |
AzureIoTClient | 30:20a85b733111 | 940 | if (options == NULL) |
AzureIoTClient | 30:20a85b733111 | 941 | { |
AzureIoTClient | 30:20a85b733111 | 942 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_102: [If an OPTIONHANDLER_HANDLE instance fails to be created, authentication_retrieve_options shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 943 | LogError("Failed to retrieve options from authentication instance (OptionHandler_Create failed)"); |
AzureIoTClient | 30:20a85b733111 | 944 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 945 | } |
AzureIoTClient | 30:20a85b733111 | 946 | else |
AzureIoTClient | 30:20a85b733111 | 947 | { |
AzureIoTClient | 30:20a85b733111 | 948 | AUTHENTICATION_INSTANCE* instance = (AUTHENTICATION_INSTANCE*)authentication_handle; |
AzureIoTClient | 30:20a85b733111 | 949 | |
AzureIoTClient | 30:20a85b733111 | 950 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_103: [Each option of `instance` shall be added to the OPTIONHANDLER_HANDLE instance using OptionHandler_AddOption] |
AzureIoTClient | 30:20a85b733111 | 951 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_104: [If OptionHandler_AddOption fails, authentication_retrieve_options shall fail and return NULL] |
AzureIoTClient | 30:20a85b733111 | 952 | if (OptionHandler_AddOption(options, AUTHENTICATION_OPTION_CBS_REQUEST_TIMEOUT_SECS, (void*)&instance->cbs_request_timeout_secs) != OPTIONHANDLER_OK) |
AzureIoTClient | 30:20a85b733111 | 953 | { |
AzureIoTClient | 30:20a85b733111 | 954 | LogError("Failed to retrieve options from authentication instance (OptionHandler_Create failed for option '%s')", AUTHENTICATION_OPTION_CBS_REQUEST_TIMEOUT_SECS); |
AzureIoTClient | 30:20a85b733111 | 955 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 956 | } |
AzureIoTClient | 30:20a85b733111 | 957 | else if (OptionHandler_AddOption(options, AUTHENTICATION_OPTION_SAS_TOKEN_REFRESH_TIME_SECS, (void*)&instance->sas_token_refresh_time_secs) != OPTIONHANDLER_OK) |
AzureIoTClient | 30:20a85b733111 | 958 | { |
AzureIoTClient | 30:20a85b733111 | 959 | LogError("Failed to retrieve options from authentication instance (OptionHandler_Create failed for option '%s')", AUTHENTICATION_OPTION_SAS_TOKEN_REFRESH_TIME_SECS); |
AzureIoTClient | 30:20a85b733111 | 960 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 961 | } |
AzureIoTClient | 30:20a85b733111 | 962 | else if (OptionHandler_AddOption(options, AUTHENTICATION_OPTION_SAS_TOKEN_LIFETIME_SECS, (void*)&instance->sas_token_lifetime_secs) != OPTIONHANDLER_OK) |
AzureIoTClient | 30:20a85b733111 | 963 | { |
AzureIoTClient | 30:20a85b733111 | 964 | LogError("Failed to retrieve options from authentication instance (OptionHandler_Create failed for option '%s')", AUTHENTICATION_OPTION_SAS_TOKEN_LIFETIME_SECS); |
AzureIoTClient | 30:20a85b733111 | 965 | result = NULL; |
AzureIoTClient | 30:20a85b733111 | 966 | } |
AzureIoTClient | 30:20a85b733111 | 967 | else |
AzureIoTClient | 30:20a85b733111 | 968 | { |
AzureIoTClient | 30:20a85b733111 | 969 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_127: [If no failures occur, authentication_retrieve_options shall return the OPTIONHANDLER_HANDLE instance] |
AzureIoTClient | 30:20a85b733111 | 970 | result = options; |
AzureIoTClient | 30:20a85b733111 | 971 | } |
AzureIoTClient | 30:20a85b733111 | 972 | |
AzureIoTClient | 30:20a85b733111 | 973 | if (result == NULL) |
AzureIoTClient | 30:20a85b733111 | 974 | { |
AzureIoTClient | 30:20a85b733111 | 975 | // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_105: [If authentication_retrieve_options fails, any allocated memory shall be freed] |
AzureIoTClient | 30:20a85b733111 | 976 | OptionHandler_Destroy(options); |
AzureIoTClient | 30:20a85b733111 | 977 | } |
AzureIoTClient | 30:20a85b733111 | 978 | } |
AzureIoTClient | 30:20a85b733111 | 979 | } |
AzureIoTClient | 30:20a85b733111 | 980 | |
AzureIoTClient | 30:20a85b733111 | 981 | return result; |
AzureIoTClient | 30:20a85b733111 | 982 | } |