void test_KineticBuilder_BuildSetPin_should_build_a_SECURITY_operation_to_set_new_ERASE_PIN(void) { char oldPinData[] = "1234"; char newPinData[] = "5678"; ByteArray oldPin = ByteArray_Create(oldPinData, sizeof(oldPinData)); ByteArray newPin = ByteArray_Create(newPinData, sizeof(newPinData)); KineticOperation_ValidateOperation_Expect(&Operation); KineticBuilder_BuildSetPin(&Operation, oldPin, newPin, false); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(KineticOperation_TimeoutSetPin, Operation.timeoutSeconds); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__SECURITY, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body); TEST_ASSERT_EQUAL_PTR(&Request.message.security, Request.command->body->security); TEST_ASSERT_TRUE(Request.command->body->security->has_olderasepin); TEST_ASSERT_EQUAL_PTR(oldPinData, Request.command->body->security->olderasepin.data); TEST_ASSERT_EQUAL(oldPin.len, Request.command->body->security->olderasepin.len); TEST_ASSERT_TRUE(Request.command->body->security->has_newerasepin); TEST_ASSERT_EQUAL_PTR(newPinData, Request.command->body->security->newerasepin.data); TEST_ASSERT_EQUAL(newPin.len, Request.command->body->security->newerasepin.len); TEST_ASSERT_NULL(Request.command->body->pinop); TEST_ASSERT_EQUAL_PTR(&KineticCallbacks_Basic, Operation.opCallback); TEST_ASSERT_NULL(Operation.response); }
void test_KineticClient_Get_should_execute_GET_operation(void) { uint8_t KeyData[64]; ByteArray Key = ByteArray_Create(KeyData, sizeof(KeyData)); ByteBuffer KeyBuffer = ByteBuffer_CreateWithArray(Key); uint8_t ValueData[64]; ByteArray Value = ByteArray_Create(ValueData, sizeof(ValueData)); ByteBuffer ValueBuffer = ByteBuffer_CreateWithArray(Value); ByteBuffer_AppendDummyData(&KeyBuffer, Key.len); KineticEntry entry = { .key = KeyBuffer, .value = ValueBuffer, }; KineticOperation operation; KineticAllocator_NewOperation_ExpectAndReturn(&Session, &operation); KineticBuilder_BuildGet_ExpectAndReturn(&operation, &entry, KINETIC_STATUS_SUCCESS); KineticController_ExecuteOperation_ExpectAndReturn(&operation, NULL, KINETIC_STATUS_CLUSTER_MISMATCH); KineticStatus status = KineticClient_Get(&Session, &entry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_CLUSTER_MISMATCH, status); }
void test_ByteArray_Create_should_create_a_byte_array(void) { uint8_t data[] = {0x1u, 0x2u, 0x3u, 0x4u}; size_t len = sizeof(data); ByteArray array = ByteArray_Create(data, len); TEST_ASSERT_EQUAL_PTR(data, array.data); TEST_ASSERT_EQUAL(len, array.len); TEST_ASSERT_EQUAL_HEX8_ARRAY(data, array.data, len); }
void SystemTestSetup(int log_level, bool secure_erase) { const uint8_t *key = (const uint8_t *)SESSION_HMAC_KEY; SystemTestSetupWithIdentity(log_level, SESSION_IDENTITY, key, strlen((const char*)key)); if (secure_erase) { InitPin = ByteArray_Create(InitPinData, 0); KineticStatus status = KineticAdminClient_SecureErase(Fixture.adminSession, InitPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } }
void test_KineticClient_Get_should_get_error_MISSING_KEY_if_called_without_key(void) { uint8_t ValueData[64]; ByteArray Value = ByteArray_Create(ValueData, sizeof(ValueData)); ByteBuffer ValueBuffer = ByteBuffer_CreateWithArray(Value); KineticEntry entry = {.value = ValueBuffer}; memset(&entry, 0, sizeof(entry)); KineticStatus status = KineticClient_Get(&Session, &entry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_MISSING_KEY, status); }
void test_KineticClient_Get_should_get_error_MISSING_VALUE_BUFFER_if_called_without_value_buffer(void) { uint8_t KeyData[64]; ByteArray Key = ByteArray_Create(KeyData, sizeof(KeyData)); ByteBuffer KeyBuffer = ByteBuffer_CreateWithArray(Key); KineticEntry entry = { .key = KeyBuffer }; memset(&entry, 0, sizeof(entry)); KineticStatus status = KineticClient_Get(&Session, &entry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_MISSING_KEY, status); }
void test_KineticClient_Get_should_execute_GET_operation_and_retrieve_only_metadata(void) { uint8_t KeyData[64]; ByteArray Key = ByteArray_Create(KeyData, sizeof(KeyData)); ByteBuffer KeyBuffer = ByteBuffer_CreateWithArray(Key); ByteBuffer_AppendDummyData(&KeyBuffer, Key.len); KineticEntry entry = { .key = KeyBuffer, .metadataOnly = true, }; KineticOperation operation; KineticAllocator_NewOperation_ExpectAndReturn(&Session, &operation); KineticBuilder_BuildGet_ExpectAndReturn(&operation, &entry, KINETIC_STATUS_SUCCESS); KineticController_ExecuteOperation_ExpectAndReturn(&operation, NULL, KINETIC_STATUS_SUCCESS); KineticStatus status = KineticClient_Get(&Session, &entry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); }
void test_KineticBuilder_BuildLockUnlock_should_build_an_UNLOCK_operation_with_PIN_auth(void) { char pinData[] = "abc123"; ByteArray pin = ByteArray_Create(pinData, strlen(pinData)); KineticOperation_ValidateOperation_Expect(&Operation); KineticBuilder_BuildLockUnlock(&Operation, false, &pin); TEST_ASSERT_NOT_NULL(Operation.pin); TEST_ASSERT_EQUAL_PTR(&pinData, Operation.pin->data); TEST_ASSERT_EQUAL_PTR(strlen(pinData), Operation.pin->len); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__PINOP, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body); TEST_ASSERT_EQUAL_PTR(&Request.message.pinOp, Request.command->body->pinop); TEST_ASSERT_TRUE(&Request.message.pinOp.has_pinoptype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__PIN_OPERATION__PIN_OP_TYPE__UNLOCK_PINOP, Request.command->body->pinop->pinoptype); TEST_ASSERT_EQUAL_PTR(&KineticCallbacks_Basic, Operation.opCallback); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_EQUAL(KineticOperation_TimeoutLockUnlock, Operation.timeoutSeconds); }
void test_KineticBuilder_BuildPut_should_build_and_execute_a_PUT_operation_to_create_a_new_object_with_calculated_tag(void) { ByteArray value = ByteArray_CreateWithCString("Luke, I am your father"); ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray newVersion = ByteArray_CreateWithCString("v1.0"); ByteArray tag = ByteArray_CreateWithCString("some_tag"); KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .newVersion = ByteBuffer_CreateWithArray(newVersion), .tag = ByteBuffer_CreateWithArray(tag), .algorithm = KINETIC_ALGORITHM_SHA1, .value = ByteBuffer_CreateWithArray(value), .computeTag = true, }; KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Operation.request->message, &entry); // Build the operation KineticBuilder_BuildPut(&Operation, &entry); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL_PTR(entry.value.array.data, Operation.value.data); TEST_ASSERT_EQUAL(entry.value.bytesUsed, Operation.value.len); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__PUT, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_ByteArray(value, Operation.entry->value.array); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); } uint8_t ValueData[KINETIC_OBJ_SIZE]; void test_KineticBuilder_BuildGet_should_build_a_GET_operation(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = {.data = ValueData, .len = sizeof(ValueData)}; KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGet(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GET, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_FALSE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildGet_should_build_a_GET_operation_requesting_metadata_only(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData)); KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .metadataOnly = true, .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGet(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GET, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_TRUE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildGetNext_should_build_a_GETNEXT_operation(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = {.data = ValueData, .len = sizeof(ValueData)}; KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGetNext(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETNEXT, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_FALSE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildGetNext_should_build_a_GETNEXT_operation_with_metadata_only(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData)); KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .metadataOnly = true, .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGetNext(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETNEXT, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_TRUE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildGetPrevious_should_build_a_GETPREVIOUS_operation(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = {.data = ValueData, .len = sizeof(ValueData)}; KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGetPrevious(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETPREVIOUS, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_FALSE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildGetPrevious_should_build_a_GETPREVIOUS_operation_with_metadata_only(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData)); KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .metadataOnly = true, .value = ByteBuffer_CreateWithArray(value), }; entry.value.bytesUsed = 123; // Set to non-empty state, since it should be reset to 0 for a metadata-only request KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildGetPrevious(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETPREVIOUS, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Get, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_TRUE(Operation.entry->metadataOnly); } void test_KineticBuilder_BuildFlush_should_build_a_FLUSHALLDATA_operation(void) { KineticOperation_ValidateOperation_Expect(&Operation); KineticBuilder_BuildFlush(&Operation); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__FLUSHALLDATA, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Basic, Operation.opCallback); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); } void test_KineticBuilder_BuildDelete_should_build_a_DELETE_operation(void) { const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData)); KineticEntry entry = {.key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value)}; KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyValue_Expect(&Request.message, &entry); KineticBuilder_BuildDelete(&Operation, &entry); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__DELETE, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_Delete, Operation.opCallback); TEST_ASSERT_EQUAL_PTR(value.data, Operation.entry->value.array.data); TEST_ASSERT_EQUAL_PTR(value.len, Operation.entry->value.array.len); TEST_ASSERT_EQUAL(0, Operation.entry->value.bytesUsed); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); } void test_KineticBuilder_BuildGetKeyRange_should_build_a_GetKeyRange_request(void) { const int maxKeyLen = 32; // arbitrary key length for test uint8_t startKeyData[maxKeyLen]; uint8_t endKeyData[maxKeyLen]; ByteBuffer startKey, endKey; startKey = ByteBuffer_Create(startKeyData, sizeof(startKeyData), 0); ByteBuffer_AppendCString(&startKey, "key_range_00_00"); endKey = ByteBuffer_Create(endKeyData, sizeof(endKeyData), 0); ByteBuffer_AppendCString(&endKey, "key_range_00_03"); const int numKeysInRange = 4; KineticKeyRange range = { .startKey = startKey, .endKey = endKey, .startKeyInclusive = true, .endKeyInclusive = true, .maxReturned = numKeysInRange, .reverse = false, }; uint8_t keysData[numKeysInRange][maxKeyLen]; ByteBuffer keyBuffers[numKeysInRange]; for (int i = 0; i < numKeysInRange; i++) { keyBuffers[i] = ByteBuffer_Create(keysData[i], maxKeyLen, 0); } ByteBufferArray keys = {.buffers = keyBuffers, .count = numKeysInRange}; KineticOperation_ValidateOperation_Expect(&Operation); KineticMessage_ConfigureKeyRange_Expect(&Request.message, &range); KineticBuilder_BuildGetKeyRange(&Operation, &range, &keys); TEST_ASSERT_TRUE(Request.command->header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETKEYRANGE, Request.command->header->messagetype); TEST_ASSERT_EQUAL_PTR(KineticCallbacks_GetKeyRange, Operation.opCallback); TEST_ASSERT_NULL(Operation.entry); TEST_ASSERT_EQUAL_PTR(&Request, Operation.request); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); TEST_ASSERT_EQUAL_PTR(&Request.message.command, Request.command); } void test_KineticBuilder_BuildP2POperation_should_build_a_P2POperation_request(void) { ByteBuffer oldKey1 = ByteBuffer_Create((void*)0x1234, 10, 10); ByteBuffer newKey1 = ByteBuffer_Create((void*)0x4321, 33, 33); ByteBuffer version1 = ByteBuffer_Create((void*)0xABC, 6, 6); ByteBuffer oldKey2 = ByteBuffer_Create((void*)0x5678, 12, 12); ByteBuffer newKey2 = ByteBuffer_Create((void*)0x8765, 200, 200); KineticP2P_OperationData ops2[] ={ { .key = oldKey2, .newKey = newKey2, } }; KineticP2P_Operation chained_p2pOp = { .peer = { .hostname = "hostname1", .port = 4321, }, .numOperations = 1, .operations = ops2 }; KineticP2P_OperationData ops[] ={ { .key = oldKey1, .version = version1, .newKey = newKey1, .chainedOperation = &chained_p2pOp, }, { .key = oldKey2, .newKey = newKey2, } }; KineticP2P_Operation p2pOp = { .peer = { .hostname = "hostname", .port = 1234, .tls = true, }, .numOperations = 2, .operations = ops }; KineticOperation_ValidateOperation_Expect(&Operation); KineticBuilder_BuildP2POperation(&Operation, &p2pOp); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__PEER2PEERPUSH, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body); TEST_ASSERT_NOT_NULL(Request.command->body->p2poperation); TEST_ASSERT_EQUAL("hostname", Request.command->body->p2poperation->peer->hostname); TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->has_port); TEST_ASSERT_EQUAL(1234, Request.command->body->p2poperation->peer->port); TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->has_tls); TEST_ASSERT_TRUE(Request.command->body->p2poperation->peer->tls); TEST_ASSERT_FALSE(Request.command->body->p2poperation->allchildoperationssucceeded); TEST_ASSERT_FALSE(Request.command->body->p2poperation->has_allchildoperationssucceeded); TEST_ASSERT_EQUAL(2, Request.command->body->p2poperation->n_operation); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_key); TEST_ASSERT_EQUAL(oldKey1.array.data, Request.command->body->p2poperation->operation[0]->key.data); TEST_ASSERT_EQUAL(oldKey1.bytesUsed, Request.command->body->p2poperation->operation[0]->key.len); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_newkey); TEST_ASSERT_EQUAL(newKey1.array.data, Request.command->body->p2poperation->operation[0]->newkey.data); TEST_ASSERT_EQUAL(newKey1.bytesUsed, Request.command->body->p2poperation->operation[0]->newkey.len); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->has_version); TEST_ASSERT_EQUAL(version1.array.data, Request.command->body->p2poperation->operation[0]->version.data); TEST_ASSERT_EQUAL(version1.bytesUsed, Request.command->body->p2poperation->operation[0]->version.len); TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->has_force); TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->force); TEST_ASSERT_NOT_NULL(Request.command->body->p2poperation->operation[0]->p2pop); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->peer->has_port); TEST_ASSERT_EQUAL(4321, Request.command->body->p2poperation->operation[0]->p2pop->peer->port); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->peer->has_tls); TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->p2pop->peer->tls); TEST_ASSERT_EQUAL(1, Request.command->body->p2poperation->operation[0]->p2pop->n_operation); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_key); TEST_ASSERT_EQUAL(oldKey2.array.data, Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->key.data); TEST_ASSERT_EQUAL(oldKey2.bytesUsed, Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->key.len); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_newkey); TEST_ASSERT_EQUAL(newKey2.array.data, Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->newkey.data); TEST_ASSERT_EQUAL(newKey2.bytesUsed, Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->newkey.len); TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_version); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->has_force); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[0]->p2pop->operation[0]->force); TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[0]->status); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_key); TEST_ASSERT_EQUAL(oldKey2.array.data, Request.command->body->p2poperation->operation[1]->key.data); TEST_ASSERT_EQUAL(oldKey2.bytesUsed, Request.command->body->p2poperation->operation[1]->key.len); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_newkey); TEST_ASSERT_EQUAL(newKey2.array.data, Request.command->body->p2poperation->operation[1]->newkey.data); TEST_ASSERT_EQUAL(newKey2.bytesUsed, Request.command->body->p2poperation->operation[1]->newkey.len); TEST_ASSERT_FALSE(Request.command->body->p2poperation->operation[1]->has_version); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->has_force); TEST_ASSERT_TRUE(Request.command->body->p2poperation->operation[1]->force); TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[1]->p2pop); TEST_ASSERT_NULL(Request.command->body->p2poperation->operation[1]->status); TEST_ASSERT_EQUAL_PTR(&p2pOp, Operation.p2pOp); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); // This just free's the malloc'd memory and sets statuses to "invalid" (since no operation was actually performed) KineticAllocator_FreeP2PProtobuf(Request.command->body->p2poperation); } /******************************************************************************* * Admin Client Operations *******************************************************************************/ void test_KineticBuilder_BuildGetLog_should_build_a_GetLog_request(void) { KineticLogInfo* pInfo; KineticOperation_ValidateOperation_Expect(&Operation); KineticStatus status = KineticBuilder_BuildGetLog(&Operation, KINETIC_DEVICE_INFO_TYPE_STATISTICS, BYTE_ARRAY_NONE, &pInfo); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETLOG, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body); TEST_ASSERT_EQUAL_PTR(&Request.message.getLog, Request.command->body->getlog); TEST_ASSERT_NOT_NULL(Request.command->body->getlog->types); TEST_ASSERT_EQUAL(1, Request.command->body->getlog->n_types); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__STATISTICS, Request.command->body->getlog->types[0]); TEST_ASSERT_EQUAL_PTR(&pInfo, Operation.deviceInfo); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); } void test_KineticBuilder_BuildGetLog_should_build_a_GetLog_request_to_retrieve_device_specific_log_info(void) { KineticLogInfo* pInfo; const char nameData[] = "com.WD"; ByteArray name = ByteArray_CreateWithCString(nameData); KineticOperation_ValidateOperation_Expect(&Operation); KineticStatus status = KineticBuilder_BuildGetLog(&Operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_TRUE(Request.message.command.header->has_messagetype); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETLOG, Request.message.command.header->messagetype); TEST_ASSERT_EQUAL_PTR(&Request.message.body, Request.command->body); TEST_ASSERT_EQUAL_PTR(&Request.message.getLog, Request.command->body->getlog); TEST_ASSERT_NOT_NULL(Request.command->body->getlog->types); TEST_ASSERT_EQUAL(1, Request.command->body->getlog->n_types); TEST_ASSERT_EQUAL(COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, Request.command->body->getlog->types[0]); TEST_ASSERT_EQUAL_PTR(&Request.message.getLogDevice, Request.command->body->getlog->device); TEST_ASSERT_TRUE(Request.command->body->getlog->device->has_name); TEST_ASSERT_EQUAL_PTR(nameData, Request.command->body->getlog->device->name.data); TEST_ASSERT_EQUAL(strlen(nameData), Request.command->body->getlog->device->name.len); TEST_ASSERT_EQUAL_PTR(&pInfo, Operation.deviceInfo); TEST_ASSERT_FALSE(Request.pinAuth); TEST_ASSERT_EQUAL(0, Operation.timeoutSeconds); TEST_ASSERT_NULL(Operation.response); } void test_KineticBuilder_BuildGetLog_should_return_KINETIC_STATUS_DEVICE_NAME_REQUIRED_if_name_not_specified_correctly(void) { KineticLogInfo* pInfo; char nameData[] = "com.WD"; ByteArray name; KineticStatus status; // Length is zero name.data = (uint8_t*)nameData; name.len = 0; KineticOperation_ValidateOperation_Expect(&Operation); status = KineticBuilder_BuildGetLog(&Operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status); // Data is NULL name.data = NULL; name.len = strlen(nameData); KineticOperation_ValidateOperation_Expect(&Operation); status = KineticBuilder_BuildGetLog(&Operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status); // Length is zero and data is NULL name.data = NULL; name.len = 0; KineticOperation_ValidateOperation_Expect(&Operation); status = KineticBuilder_BuildGetLog(&Operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, &pInfo); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_NAME_REQUIRED, status); }
void setUp(void) { SystemTestSetup(0, true); KeyBuffer = ByteBuffer_CreateAndAppendCString(KeyData, sizeof(KeyData), strKey); ExpectedKeyBuffer = ByteBuffer_CreateAndAppendCString(ExpectedKeyData, sizeof(ExpectedKeyData), strKey); TagBuffer = ByteBuffer_CreateAndAppendCString(TagData, sizeof(TagData), "SomeTagValue"); ExpectedTagBuffer = ByteBuffer_CreateAndAppendCString(ExpectedTagData, sizeof(ExpectedTagData), "SomeTagValue"); TestValue = ByteArray_CreateWithCString("lorem ipsum... blah blah blah... etc."); ValueBuffer = ByteBuffer_CreateAndAppendArray(ValueData, sizeof(ValueData), TestValue); // Setup to write some test data KineticEntry putEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_FLUSH, }; KineticStatus status = KineticClient_Put(Fixture.session, &putEntry, NULL); if (status != KINETIC_STATUS_SUCCESS) { failing = true; TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } // Validate the object exists initially KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_WRITETHROUGH, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL_ByteArray(putEntry.key.array, getEntry.key.array); TEST_ASSERT_EQUAL_ByteArray(putEntry.tag.array, getEntry.tag.array); TEST_ASSERT_EQUAL(putEntry.algorithm, getEntry.algorithm); TEST_ASSERT_EQUAL_ByteBuffer(putEntry.value, getEntry.value); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); // Set the erase PIN to something non-empty strcpy(NewPinData, SESSION_PIN); OldPin = ByteArray_Create(OldPinData, 0); NewPin = ByteArray_Create(NewPinData, strlen(NewPinData)); status = KineticAdminClient_SetErasePin(Fixture.adminSession, OldPin, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } void tearDown(void) { KineticStatus status = KINETIC_STATUS_INVALID; if (failing) { return; } // Validate the object no longer exists KineticEntry regetEntryMetadata = { .key = KeyBuffer, .tag = TagBuffer, .metadataOnly = true, }; status = KineticClient_Get(Fixture.session, ®etEntryMetadata, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_NOT_FOUND, status); TEST_ASSERT_ByteArray_EMPTY(regetEntryMetadata.value.array); SystemTestShutDown(); } void test_SecureErase_should_erase_device_contents(void) { KineticStatus status = KineticAdminClient_SecureErase(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); } void test_InstantErase_should_erase_device_contents(void) { KineticStatus status = KineticAdminClient_InstantErase(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); }
const uint8_t *key, size_t key_size) { KineticClientConfig clientConfig = { .logFile = "stdout", .logLevel = log_level, }; Fixture = (SystemTestFixture) { .connected = false, .client = KineticClient_Init(&clientConfig), }; KineticSessionConfig config = { .clusterVersion = SESSION_CLUSTER_VERSION, .identity = identity, .hmacKey = ByteArray_Create((void *)key, key_size), }; strncpy((char*)config.host, GetSystemTestHost1(), sizeof(config.host)-1); config.port = GetSystemTestPort1(); strncpy((char*)config.keyData, SESSION_HMAC_KEY, sizeof(config.keyData)-1); KineticStatus status = KineticClient_CreateSession(&config, Fixture.client, &Fixture.session); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); KineticSessionConfig adminConfig = { .clusterVersion = SESSION_CLUSTER_VERSION, .identity = identity, .hmacKey = ByteArray_Create((void *)key, key_size), .useSsl = true, }; strncpy(adminConfig.host, GetSystemTestHost1(), sizeof(adminConfig.host)-1); adminConfig.port = GetSystemTestTlsPort1();
void ConfigureEntry(struct UtilConfig * cfg, const char* key, const char* tag, const char* version, KineticAlgorithm algorithm, bool force, const char* value) { assert(cfg != NULL); // Setup to write some test data cfg->entry = (KineticEntry) { .key = ByteBuffer_CreateAndAppendCString(cfg->keyData, sizeof(cfg->keyData), key), .tag = ByteBuffer_CreateAndAppendCString(cfg->tagData, sizeof(cfg->tagData), tag), .newVersion = ByteBuffer_CreateAndAppendCString(cfg->newVersionData, sizeof(cfg->newVersionData), version), .dbVersion = ByteBuffer_Create(cfg->versionData, sizeof(cfg->versionData), 0), .algorithm = algorithm, .value = ByteBuffer_CreateAndAppendCString(cfg->valueData, sizeof(cfg->valueData), value), .force = force, }; } int ParseOptions( const int argc, char** const argv, struct UtilConfig * cfg) { // Create an ArgP processor to parse arguments struct { OptionID opID; int logLevel; char host[HOST_NAME_MAX]; int port; int tlsPort; int64_t clusterVersion; int64_t identity; char hmacKey[KINETIC_MAX_KEY_LEN]; char logType[64]; char deviceLogName[64]; char key[64]; char version[64]; char tag[64]; KineticAlgorithm algorithm; bool force; char value[1024]; } opts = { .logLevel = 0, .host = "localhost", .port = KINETIC_PORT, .tlsPort = KINETIC_TLS_PORT, .clusterVersion = 0, .identity = 1, .hmacKey = "asdfasdf", .logType = "utilizations", .key = "foo", .tag = "SomeTagValue", .algorithm = KINETIC_ALGORITHM_SHA1, .force = true, .value = "Hello!", }; // Create configuration for long format options struct option long_options[] = { // Help {"help", no_argument, 0, OPT_HELP}, // Commands {"noop", no_argument, 0, OPT_NOOP}, {"put", no_argument, 0, OPT_PUT}, {"get", no_argument, 0, OPT_GET}, {"delete", no_argument, 0, OPT_DELETE}, {"getnext", no_argument, 0, OPT_GETNEXT}, {"getprevious", no_argument, 0, OPT_GETPREVIOUS}, {"getlog", no_argument, 0, OPT_GETLOG}, {"getdevicespecificlog", no_argument, 0, OPT_GETDEVICESPECIFICLOG}, {"seterasepin", no_argument, 0, OPT_SETERASEPIN}, {"instanterase", no_argument, 0, OPT_INSTANTERASE}, {"secureerase", no_argument, 0, OPT_SECUREERASE}, {"setlockpin", no_argument, 0, OPT_SETLOCKPIN}, {"lockdevice", no_argument, 0, OPT_LOCKDEVICE}, {"unlockdevice", no_argument, 0, OPT_UNLOCKDEVICE}, {"setclusterversion", no_argument, 0, OPT_SETCLUSTERVERSION}, {"setacl", no_argument, 0, OPT_SETACL}, {"updatefirmware", no_argument, 0, OPT_UPDATEFIRMWARE}, // Options {"loglevel", required_argument, 0, OPT_LOGLEVEL}, {"host", required_argument, 0, OPT_HOST}, {"port", required_argument, 0, OPT_PORT}, {"tlsport", required_argument, 0, OPT_TLSPORT}, {"identity", required_argument, 0, OPT_IDENTITY}, {"hmackey", required_argument, 0, OPT_HMACKEY}, {"clusterversion", required_argument, 0, OPT_CLUSTERVERSION}, {"file", required_argument, 0, OPT_FILE}, {"newclusterversion", required_argument, 0, OPT_NEWCLUSTERVERSION}, {"pin", required_argument, 0, OPT_PIN}, {"newpin", required_argument, 0, OPT_NEWPIN}, {"logtype", required_argument, 0, OPT_LOGTYPE}, {"devicelogname", required_argument, 0, OPT_DEVICELOGNAME}, {"key", required_argument, 0, OPT_KEY}, {"value", required_argument, 0, OPT_VALUE}, {0, 0, 0, 0}, }; // Parse the options from the command line extern char *optarg; extern int optind; int option, optionIndex = 0; while ((option = getopt_long(argc, argv, "?lhptics:", long_options, &optionIndex)) != -1) { switch (option) { case 0: // If this option, just set the flag if (long_options[optionIndex].flag != 0) {break;} // assert(false); // break; case OPT_LOGLEVEL: opts.logLevel = atoi(optarg); break; case OPT_HOST: strncpy(opts.host, optarg, sizeof(opts.host)); break; case OPT_PORT: opts.port = atoi(optarg); break; case OPT_TLSPORT: opts.tlsPort = atoi(optarg); break; case OPT_IDENTITY: opts.identity = atoi(optarg); break; case OPT_HMACKEY: strncpy(opts.hmacKey, optarg, sizeof(opts.hmacKey)-1); break; case OPT_KEY: strncpy(opts.key, optarg, sizeof(opts.key)-1); break; case OPT_VALUE: strncpy(opts.value, optarg, sizeof(opts.value)-1); break; case OPT_CLUSTERVERSION: opts.clusterVersion = (int64_t)atol(optarg); break; case OPT_NEWCLUSTERVERSION: cfg->newClusterVersion = (int64_t)atol(optarg); break; case OPT_FILE: strncpy(cfg->file, optarg, sizeof(cfg->file)-1); break; case OPT_PIN: strncpy(cfg->pin, optarg, sizeof(cfg->pin)-1); break; case OPT_NEWPIN: strncpy(cfg->newPin, optarg, sizeof(cfg->newPin)-1); break; case OPT_LOGTYPE: strncpy(opts.logType, optarg, sizeof(opts.logType)-1); break; case OPT_DEVICELOGNAME: strncpy(cfg->deviceLogName, optarg, sizeof(cfg->deviceLogName)-1); break; case OPT_NOOP: case OPT_PUT: case OPT_GET: case OPT_DELETE: case OPT_GETNEXT: case OPT_GETPREVIOUS: case OPT_GETLOG: case OPT_GETDEVICESPECIFICLOG: case OPT_SETERASEPIN: case OPT_INSTANTERASE: case OPT_SECUREERASE: case OPT_SETLOCKPIN: case OPT_LOCKDEVICE: case OPT_UNLOCKDEVICE: case OPT_SETCLUSTERVERSION: case OPT_SETACL: case OPT_UPDATEFIRMWARE: if ((int)opts.opID == 0) { opts.opID = option; break; } fprintf(stderr, "Multiple operations specified!\n"); PrintUsage(argv[0]); exit(-1); case OPT_HELP: PrintUsage(argv[0]); exit(0); default: PrintUsage(argv[0]); exit(-1); } } // Configure client cfg->logLevel = opts.logLevel; // Configure session cfg->config = (KineticSessionConfig) { .port = opts.port, .clusterVersion = opts.clusterVersion, .identity = opts.identity, .hmacKey = ByteArray_Create(cfg->hmacKeyData, strlen(opts.hmacKey)), }; memcpy(cfg->hmacKeyData, opts.hmacKey, strlen(opts.hmacKey)); strncpy(cfg->config.host, opts.host, sizeof(cfg->config.host)-1); // Configure admin session cfg->adminConfig = cfg->config; cfg->adminConfig.port = opts.tlsPort; cfg->adminConfig.useSsl = true; // Populate and configure the entry to be used for operations ConfigureEntry(cfg, opts.key, opts.tag, opts.version, opts.algorithm, opts.force, opts.value); cfg->opID = opts.opID; // Parse log type from string if (strcmp("utilizations", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_UTILIZATIONS; } else if (strcmp("temperatures", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_TEMPERATURES; } else if (strcmp("capacities", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_CAPACITIES; } else if (strcmp("configuration", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_CONFIGURATION; } else if (strcmp("statistics", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_STATISTICS; } else if (strcmp("messages", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_MESSAGES; } else if (strcmp("limits", opts.logType) == 0) { cfg->logType = KINETIC_DEVICE_INFO_TYPE_LIMITS; } else { fprintf(stderr, "Invalid log info type: %s\n", opts.logType); exit(1); } return optind; }
KineticStatus ExecuteOperation( struct UtilConfig * cfg) { KineticStatus status = KINETIC_STATUS_INVALID; KineticLogInfo * logInfo; ByteArray tmpArray; switch (cfg->opID) { case OPT_NOOP: status = KineticClient_NoOp(cfg->session); if (status == KINETIC_STATUS_SUCCESS) { printf("NoOp operation completed successfully." " Kinetic Device is alive and well!\n"); } break; case OPT_PUT: status = KineticClient_Put(cfg->session, &cfg->entry, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("Put operation completed successfully." " Your data has been stored!\n"); PrintEntry(&cfg->entry); } break; case OPT_GET: status = KineticClient_Get(cfg->session, &cfg->entry, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("Get executed successfully.\n"); PrintEntry(&cfg->entry); } break; case OPT_GETNEXT: status = KineticClient_GetNext(cfg->session, &cfg->entry, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("GetNext executed successfully.\n"); PrintEntry(&cfg->entry); } break; case OPT_GETPREVIOUS: status = KineticClient_GetPrevious(cfg->session, &cfg->entry, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("GetPrevious executed successfully.\n"); PrintEntry(&cfg->entry); } break; case OPT_DELETE: status = KineticClient_Delete(cfg->session, &cfg->entry, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("Delete executed successfully. The entry has been destroyed!\n"); PrintEntry(&cfg->entry); } break; case OPT_GETLOG: status = KineticAdminClient_GetLog(cfg->adminSession, cfg->logType, &logInfo, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("GetLog executed successfully.\n" "The device log info has been retrieved!\n"); PrintLogInfo(cfg->logType, logInfo); } break; case OPT_GETDEVICESPECIFICLOG: if (strlen(cfg->deviceLogName) == 0) { fprintf(stderr, "Device-specific log type requires '--devicelogname' to be set!\n"); exit(1); } tmpArray.data = (uint8_t*)cfg->deviceLogName; tmpArray.len = strlen(cfg->deviceLogName); status = KineticAdminClient_GetDeviceSpecificLog(cfg->adminSession, tmpArray, &logInfo, NULL); if (status == KINETIC_STATUS_SUCCESS) { printf("GetDeviceSpecificLog executed successfully." "The device-specific device log info has been retrieved!\n"); printf("Device-Specific Log Info:\n"); char* dev = calloc(1, logInfo->device->name.len + 1); memcpy(dev, logInfo->device->name.data, logInfo->device->name.len); printf(" %s\n", dev); free(dev); } else if (status == KINETIC_STATUS_NOT_FOUND) { fprintf(stderr, "The specified device-specific log '%s' was not found on the device!\n", cfg->deviceLogName); status = KINETIC_STATUS_SUCCESS; } break; case OPT_SETERASEPIN: status = KineticAdminClient_SetErasePin(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin)), ByteArray_Create(cfg->newPin, strlen(cfg->newPin))); if (status == KINETIC_STATUS_SUCCESS) { printf("SetErasePin executed successfully.\n" "The kinetic device erase pin has been changed!\n"); } break; case OPT_INSTANTERASE: status = KineticAdminClient_InstantErase(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin))); if (status == KINETIC_STATUS_SUCCESS) { printf("InstantErase executed successfully.\n" "The kinetic device has been erased!\n"); } break; case OPT_SECUREERASE: status = KineticAdminClient_SecureErase(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin))); if (status == KINETIC_STATUS_SUCCESS) { printf("SecureErase executed successfully.\n" "The kinetic device has been erased!\n"); } break; case OPT_SETLOCKPIN: status = KineticAdminClient_SetLockPin(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin)), ByteArray_Create(cfg->newPin, strlen(cfg->newPin))); if (status == KINETIC_STATUS_SUCCESS) { printf("SetLockPin executed successfully.\n" "The kinetic device lock/unlock pin has been changed!\n"); } break; case OPT_LOCKDEVICE: status = KineticAdminClient_LockDevice(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin))); if (status == KINETIC_STATUS_SUCCESS) { printf("LockDevice executed successfully.\n" "The kinetic device is now locked!\n"); } break; case OPT_UNLOCKDEVICE: status = KineticAdminClient_UnlockDevice(cfg->adminSession, ByteArray_Create(cfg->pin, strlen(cfg->pin))); if (status == KINETIC_STATUS_SUCCESS) { printf("UnlockDevice executed successfully.\n" "The kinetic device is now unlocked!\n"); } break; case OPT_SETCLUSTERVERSION: status = KineticAdminClient_SetClusterVersion(cfg->adminSession, cfg->newClusterVersion); if (status == KINETIC_STATUS_SUCCESS) { printf("SetClusterVersion executed successfully.\n" "The kinetic device's cluster version has been updated!\n"); } break; case OPT_SETACL: status = KineticAdminClient_SetACL(cfg->adminSession, cfg->file); if (status == KINETIC_STATUS_SUCCESS) { printf("SetACL executed successfully.\n" "The kinetic device ACLs have been replaced!\n"); } break; case OPT_UPDATEFIRMWARE: status = KineticAdminClient_UpdateFirmware(cfg->session, cfg->file); if (status == KINETIC_STATUS_SUCCESS) { printf("SecureErase executed successfully.\n" "The kinetic device has been restored to empty status!\n"); } break; default: fprintf(stderr, "Specified operation '%d' is invalid!\n", (int)cfg->opID); exit(-1); }; // Print out status code description if operation was not successful if (status != KINETIC_STATUS_SUCCESS) { fprintf(stderr, "\nERROR: Operation '%s' failed with status '%s'\n", GetOptString(cfg->opID), Kinetic_GetStatusDescription(status)); } return status; }
void test_KineticPDU_Receive_should_receive_a_message_for_the_exchange_and_return_false_upon_value_field_receive_failure(void) { LOG_LOCATION; KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); PDU.protoData.message.status.code = KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS; PDU.protoData.message.status.has_code = true; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); PDU.headerNBO = (KineticPDUHeader) { .versionPrefix = 'F', .protobufLength = KineticNBO_ToHostU32(17), .valueLength = KineticNBO_ToHostU32(124) }; // Fake value/payload length uint8_t data[124]; size_t bytesToRead = sizeof(data); ByteArray expectedValue = ByteArray_Create(data, sizeof(data)); ByteArray_FillWithDummyData(expectedValue); KineticEntry entry = {.value = ByteBuffer_CreateWithArray(expectedValue)}; KineticPDU_AttachEntry(&PDU, &entry); KineticSocket_Read_ExpectAndReturn(Connection.socket, &headerNBO, sizeof(KineticPDUHeader), KINETIC_STATUS_SUCCESS); KineticSocket_ReadProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS); KineticHMAC_Validate_ExpectAndReturn(PDU.proto, PDU.connection->session.hmacKey, true); KineticSocket_Read_ExpectAndReturn(Connection.socket, &entry.value, bytesToRead, KINETIC_STATUS_SOCKET_ERROR); KineticStatus status = KineticPDU_Receive(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_ERROR, status); TEST_ASSERT_EQUAL(17, PDU.header.protobufLength); TEST_ASSERT_EQUAL(bytesToRead, expectedValue.len); TEST_ASSERT_EQUAL(expectedValue.len, PDU.header.valueLength); } void test_KineticPDU_Receive_should_receive_a_message_and_update_the_ConnectionID_for_the_connection_when_provided(void) { LOG_LOCATION; Connection.connectionID = 98765; KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); PDU.protoData.message.status.code = KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS; PDU.protoData.message.status.has_code = true; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); // Fake value/payload length uint8_t data[124]; size_t bytesToRead = sizeof(data); ByteArray expectedValue = {.data = data, .len = sizeof(data)}; ByteArray_FillWithDummyData(expectedValue); KineticEntry entry = {.value = ByteBuffer_CreateWithArray(expectedValue)}; KineticPDU_AttachEntry(&PDU, &entry); KineticSocket_Read_ExpectAndReturn(Connection.socket, &headerNBO, sizeof(KineticPDUHeader), KINETIC_STATUS_SUCCESS); KineticSocket_ReadProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS); KineticHMAC_Validate_ExpectAndReturn(PDU.proto, PDU.connection->session.hmacKey, true); KineticSocket_Read_ExpectAndReturn(Connection.socket, &entry.value, bytesToRead, KINETIC_STATUS_SUCCESS); PDU.headerNBO.valueLength = KineticNBO_FromHostU32(expectedValue.len); EnableAndSetPDUConnectionID(&PDU, 12345); EnableAndSetPDUStatus(&PDU, KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS); KineticStatus status = KineticPDU_Receive(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL(KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS, PDU.protoData.message.status.code); TEST_ASSERT_EQUAL(12345, PDU.proto->command->header->connectionID); TEST_ASSERT_EQUAL(12345, PDU.connection->connectionID); } void test_KineticPDU_Receive_should_receive_a_message_and_NOT_update_the_ConnectionID_for_the_connection_if_not_provided(void) { LOG_LOCATION; Connection.connectionID = 98765; KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); PDU.protoData.message.status.code = KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS; PDU.protoData.message.status.has_code = true; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); // Fake value/payload length uint8_t data[124]; size_t bytesToRead = sizeof(data); ByteArray expectedValue = {.data = data, .len = sizeof(data)}; ByteArray_FillWithDummyData(expectedValue); KineticEntry entry = {.value = ByteBuffer_CreateWithArray(expectedValue)}; KineticPDU_AttachEntry(&PDU, &entry); KineticSocket_Read_ExpectAndReturn(Connection.socket, &headerNBO, sizeof(KineticPDUHeader), KINETIC_STATUS_SUCCESS); KineticSocket_ReadProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS); KineticHMAC_Validate_ExpectAndReturn(PDU.proto, PDU.connection->session.hmacKey, true); KineticSocket_Read_ExpectAndReturn(Connection.socket, &entry.value, bytesToRead, KINETIC_STATUS_SUCCESS); PDU.headerNBO.valueLength = KineticNBO_FromHostU32(expectedValue.len); EnableAndSetPDUStatus(&PDU, KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS); KineticStatus status = KineticPDU_Receive(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL(KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS, PDU.protoData.message.status.code); TEST_ASSERT_EQUAL(98765, PDU.proto->command->header->connectionID); TEST_ASSERT_EQUAL(98765, PDU.connection->connectionID); } void test_KineticPDU_GetStatus_should_return_KINETIC_STATUS_INVALID_if_no_KineticProto_Status_StatusCode_in_response(void) { LOG_LOCATION; KineticStatus status; status = KineticPDU_GetStatus(NULL); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); PDU.proto = NULL; status = KineticPDU_GetStatus(&PDU); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); PDU.proto = &PDU.protoData.message.proto; PDU.proto->command = NULL; status = KineticPDU_GetStatus(&PDU); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); PDU.proto->command = &PDU.protoData.message.command; status = KineticPDU_GetStatus(&PDU); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); PDU.proto->command->status = &PDU.protoData.message.status; PDU.proto->command->status->has_code = false; status = KineticPDU_GetStatus(&PDU); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); PDU.proto->command->status->has_code = true; PDU.proto->command->status->code = KINETIC_PROTO_STATUS_STATUS_CODE_INVALID_STATUS_CODE; status = KineticPDU_GetStatus(&PDU); TEST_ASSERT_EQUAL(KINETIC_STATUS_INVALID, status); }
void test_KineticPDU_Send_should_send_the_specified_message_and_return_false_upon_failure_to_send_header(void) { LOG_LOCATION; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); char valueData[] = "Some arbitrary value"; KineticEntry entry = {.value = ByteBuffer_Create(valueData, strlen(valueData))}; KineticPDU_AttachEntry(&PDU, &entry); KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1); KineticHMAC_Populate_Expect(&PDU.hmac, &PDU.protoData.message.proto, PDU.connection->session.hmacKey); KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SOCKET_ERROR); TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header"); KineticStatus status = KineticPDU_Send(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_ERROR, status); } void test_KineticPDU_Send_should_send_the_specified_message_and_return_false_upon_failure_to_send_protobuf(void) { LOG_LOCATION; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); char valueData[] = "Some arbitrary value"; KineticEntry entry = {.value = ByteBuffer_Create(valueData, strlen(valueData))}; KineticPDU_AttachEntry(&PDU, &entry); KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1); KineticHMAC_Populate_Expect(&PDU.hmac, &PDU.protoData.message.proto, PDU.connection->session.hmacKey); KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SUCCESS); KineticSocket_WriteProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SOCKET_TIMEOUT); TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header"); KineticStatus status = KineticPDU_Send(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_TIMEOUT, status); } void test_KineticPDU_Send_should_send_the_specified_message_and_return_KineticStatus_if_value_write_fails(void) { LOG_LOCATION; ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); uint8_t valueData[128]; KineticEntry entry = {.value = ByteBuffer_Create(valueData, sizeof(valueData))}; ByteBuffer_AppendCString(&entry.value, "Some arbitrary value"); KineticPDU_AttachEntry(&PDU, &entry); KineticHMAC_Init_Expect(&PDU.hmac, KINETIC_PROTO_SECURITY_ACL_HMACALGORITHM_HmacSHA1); KineticHMAC_Populate_Expect(&PDU.hmac, &PDU.protoData.message.proto, PDU.connection->session.hmacKey); KineticSocket_Write_ExpectAndReturn(Connection.socket, &headerNBO, KINETIC_STATUS_SUCCESS); KineticSocket_WriteProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS); KineticSocket_Write_ExpectAndReturn(Connection.socket, &entry.value, KINETIC_STATUS_SOCKET_TIMEOUT); TEST_IGNORE_MESSAGE("Need to figure out how to handle address of PDU header"); KineticStatus status = KineticPDU_Send(&PDU); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SOCKET_TIMEOUT, status); } void test_KineticPDU_Receive_should_receive_a_message_with_value_payload_and_return_true_upon_receipt_of_valid_PDU(void) { LOG_LOCATION; Connection.connectionID = 98765; KINETIC_PDU_INIT_WITH_MESSAGE(&PDU, &Connection); ByteBuffer headerNBO = ByteBuffer_Create(&PDU.headerNBO, sizeof(KineticPDUHeader)); // Fake value/payload length uint8_t data[1024]; ByteArray expectedValue = ByteArray_Create(data, sizeof(data)); ByteArray_FillWithDummyData(expectedValue); KineticEntry entry = {.value = ByteBuffer_CreateWithArray(expectedValue)}; KineticPDU_AttachEntry(&PDU, &entry); KineticSocket_Read_ExpectAndReturn(Connection.socket, &headerNBO, sizeof(KineticPDUHeader), KINETIC_STATUS_SUCCESS); KineticSocket_ReadProtobuf_ExpectAndReturn(Connection.socket, &PDU, KINETIC_STATUS_SUCCESS); KineticHMAC_Validate_ExpectAndReturn(PDU.proto, PDU.connection->session.hmacKey, true); KineticSocket_Read_ExpectAndReturn(Connection.socket, &entry.value, expectedValue.len, KINETIC_STATUS_SUCCESS); PDU.headerNBO.valueLength = KineticNBO_FromHostU32(expectedValue.len); EnableAndSetPDUConnectionID(&PDU, 12345); EnableAndSetPDUStatus(&PDU, KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS); KineticStatus status = KineticPDU_Receive(&PDU); TEST_ASSERT_EQUAL(KINETIC_PROTO_STATUS_STATUS_CODE_SUCCESS, PDU.protoData.message.status.code); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); }
void test_KineticOperation_BuildGet_should_build_a_GET_operation(void) { LOG_LOCATION; const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = {.data = ValueData, .len = sizeof(ValueData)}; KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .value = ByteBuffer_CreateWithArray(value), }; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildGet(&Operation, &entry); // GET // The GET operation is used to retrieve the value and metadata for a given key. // // Request Message: // command { // header { // // See above for descriptions of these fields // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // // The mesageType should be GET // messageType: GET TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType); // } // body { // keyValue { // // See above // key: "..." // } // } // } // // See above // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_EQUAL_ByteArray(value, Operation.response->entry.value.array); TEST_ASSERT_EQUAL(0, Operation.response->entry.value.bytesUsed); } void test_KineticOperation_BuildGet_should_build_a_GET_operation_requesting_metadata_only(void) { LOG_LOCATION; const ByteArray key = ByteArray_CreateWithCString("foobar"); ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData)); KineticEntry entry = { .key = ByteBuffer_CreateWithArray(key), .metadataOnly = true, .value = ByteBuffer_CreateWithArray(value), }; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildGet(&Operation, &entry); // GET // The GET operation is used to retrieve the value and metadata for a given key. // // Request Message: // command { // header { // // See above for descriptions of these fields // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // // The mesageType should be GET // messageType: GET TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType); // } // body { // keyValue { // // See above // key: "..." // } // } // } // // See above // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_ByteBuffer_NULL(Response.entry.value); } void test_KineticOperation_BuildDelete_should_build_a_DELETE_operation(void) { LOG_LOCATION; const ByteArray key = ByteArray_CreateWithCString("foobar"); KineticEntry entry = {.key = ByteBuffer_CreateWithArray(key)}; KineticConnection_IncrementSequence_Expect(&Connection); KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry); KineticOperation_BuildDelete(&Operation, &entry); // The `DELETE` operation removes the entry for a given key. It respects the // same locking behavior around `dbVersion` and `force` as described in the previous sections. // The following request will remove a key value pair to the store. // // ``` // command { // // See top level cross cutting concerns for header details // header { // clusterVersion: ... // identity: ... // connectionID: ... // sequence: ... // // messageType should be DELETE // messageType: DELETE TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType); TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_DELETE, Request.proto->command->header->messageType); // } // body { // keyValue { // key: "..." // // See write operation cross cutting concerns // synchronization: ... // } // } // } // hmac: "..." TEST_ASSERT_ByteBuffer_NULL(Request.entry.value); TEST_ASSERT_ByteBuffer_NULL(Response.entry.value); }
void test_KineticHMAC_Populate_should_compute_and_populate_the_SHA1_HMAC_for_the_supplied_message_and_key(void) { KineticHMAC actual; Com__Seagate__Kinetic__Proto__Message msg = COM__SEAGATE__KINETIC__PROTO__MESSAGE__INIT; Com__Seagate__Kinetic__Proto__Message__HMACauth hmacAuth = COM__SEAGATE__KINETIC__PROTO__MESSAGE__HMACAUTH__INIT; uint8_t data[KINETIC_HMAC_MAX_LEN]; ProtobufCBinaryData hmac = {.len = KINETIC_HMAC_MAX_LEN, .data = data}; const ByteArray key = ByteArray_CreateWithCString("1234567890ABCDEFGHIJK"); uint8_t commandBytes[123]; ByteArray commandArray = ByteArray_Create(commandBytes, sizeof(commandBytes)); ByteArray_FillWithDummyData(commandArray); ProtobufCBinaryData dummyCommandData = {.data = commandArray.data, .len = commandArray.len}; msg.commandbytes = dummyCommandData; msg.has_commandbytes = true; msg.authtype = COM__SEAGATE__KINETIC__PROTO__MESSAGE__AUTH_TYPE__HMACAUTH; msg.has_authtype = true; hmacAuth.has_hmac = true; hmacAuth.hmac = hmac; msg.hmacauth = &hmacAuth; KineticHMAC_Init(&actual, COM__SEAGATE__KINETIC__PROTO__COMMAND__SECURITY__ACL__HMACALGORITHM__HmacSHA1); KineticHMAC_Populate(&actual, &msg, key); TEST_ASSERT_TRUE(msg.hmacauth->has_hmac); TEST_ASSERT_EQUAL_PTR(hmac.data, msg.hmacauth->hmac.data); TEST_ASSERT_EQUAL(KINETIC_HMAC_MAX_LEN, msg.hmacauth->hmac.len); LOG0("Computed HMAC: "); LOGF0(" %02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", actual.data[0], actual.data[1], actual.data[2], actual.data[3], actual.data[4], actual.data[5], actual.data[6], actual.data[7]); LOGF0(" %02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", actual.data[8], actual.data[9], actual.data[10], actual.data[11], actual.data[12], actual.data[13], actual.data[14], actual.data[15]); LOGF0(" %02hhX%02hhX%02hhX%02hhX", actual.data[16], actual.data[17], actual.data[18], actual.data[19]); } void test_KineticHMAC_Validate_should_return_true_if_the_HMAC_for_the_supplied_message_and_key_is_correct(void) { KineticHMAC actual; Com__Seagate__Kinetic__Proto__Command__Status status = COM__SEAGATE__KINETIC__PROTO__COMMAND__STATUS__INIT; Com__Seagate__Kinetic__Proto__Command command = COM__SEAGATE__KINETIC__PROTO__COMMAND__INIT; status.code = COM__SEAGATE__KINETIC__PROTO__COMMAND__STATUS__STATUS_CODE__NO_SPACE; status.has_code = true; command.status = &status; Com__Seagate__Kinetic__Proto__Message proto = COM__SEAGATE__KINETIC__PROTO__MESSAGE__INIT; Com__Seagate__Kinetic__Proto__Message__HMACauth hmacAuth = COM__SEAGATE__KINETIC__PROTO__MESSAGE__HMACAUTH__INIT; uint8_t data[KINETIC_HMAC_MAX_LEN]; ProtobufCBinaryData hmac = {.len = KINETIC_HMAC_MAX_LEN, .data = data}; const ByteArray key = ByteArray_CreateWithCString("1234567890ABCDEFGHIJK"); proto.has_commandbytes = true; uint8_t packedCmd[128]; size_t packedLen = com__seagate__kinetic__proto__command__pack(&command, packedCmd); proto.commandbytes = (ProtobufCBinaryData){.data = packedCmd, .len = packedLen}; hmacAuth.identity = 7; hmacAuth.has_identity = true; hmacAuth.hmac = hmac; hmacAuth.has_hmac = true; proto.hmacauth = &hmacAuth; proto.authtype = COM__SEAGATE__KINETIC__PROTO__MESSAGE__AUTH_TYPE__HMACAUTH; proto.has_authtype = true; KineticHMAC_Init(&actual, COM__SEAGATE__KINETIC__PROTO__COMMAND__SECURITY__ACL__HMACALGORITHM__HmacSHA1); KineticHMAC_Populate(&actual, &proto, key); TEST_ASSERT_TRUE(KineticHMAC_Validate(&proto, key)); }
void setUp(void) { NewPinSet = false; Locked = false; SystemTestSetup(1, true); KeyBuffer = ByteBuffer_CreateAndAppendCString(KeyData, sizeof(KeyData), strKey); ExpectedKeyBuffer = ByteBuffer_CreateAndAppendCString(ExpectedKeyData, sizeof(ExpectedKeyData), strKey); TagBuffer = ByteBuffer_CreateAndAppendCString(TagData, sizeof(TagData), "SomeTagValue"); ExpectedTagBuffer = ByteBuffer_CreateAndAppendCString(ExpectedTagData, sizeof(ExpectedTagData), "SomeTagValue"); TestValue = ByteArray_CreateWithCString("lorem ipsum... blah blah blah... etc."); ValueBuffer = ByteBuffer_CreateAndAppendArray(ValueData, sizeof(ValueData), TestValue); // Setup to write some test data KineticEntry putEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_FLUSH, }; KineticStatus status = KineticClient_Put(Fixture.session, &putEntry, NULL); // Validate the object exists initially KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .algorithm = KINETIC_ALGORITHM_SHA1, .value = ValueBuffer, .force = true, .synchronization = KINETIC_SYNCHRONIZATION_WRITETHROUGH, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); TEST_ASSERT_EQUAL_ByteArray(putEntry.key.array, getEntry.key.array); TEST_ASSERT_EQUAL_ByteArray(putEntry.tag.array, getEntry.tag.array); TEST_ASSERT_EQUAL(putEntry.algorithm, getEntry.algorithm); TEST_ASSERT_EQUAL_ByteBuffer(putEntry.value, getEntry.value); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); // Set the erase PIN to something non-empty strcpy(NewPinData, SESSION_PIN); OldPin = ByteArray_Create(OldPinData, 0); NewPin = ByteArray_Create(NewPinData, strlen(NewPinData)); status = KineticAdminClient_SetLockPin(Fixture.adminSession, OldPin, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); NewPinSet = true; } void tearDown(void) { KineticStatus status; // Unlock if for some reason we are still locked in order to // prevent the device from staying in a locked/unusable state if (Locked) { status = KineticAdminClient_UnlockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = false; } // Set the lock PIN back to empty if (NewPinSet) { status = KineticAdminClient_SetLockPin(Fixture.adminSession, NewPin, OldPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); NewPinSet = false; } SystemTestShutDown(); } void test_KineticAdmin_should_lock_and_unlock_a_device(void) { KineticStatus status; status = KineticAdminClient_LockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = true; /* Currently, the device appears to just hang up on us rather than * returning DEVICE_LOCKED (unlike the simulator). Some sort of * command here to confirm that the device lock succeeded would * be a better test. We need to check if the drive has another * interface that exposes this. */ if (SystemTestIsUnderSimulator()) { // Validate the object cannot being accessed while locked KineticEntry getEntry = { .key = KeyBuffer, .tag = TagBuffer, .value = ValueBuffer, .force = true, }; status = KineticClient_Get(Fixture.session, &getEntry, NULL); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_DEVICE_LOCKED, status); } status = KineticAdminClient_UnlockDevice(Fixture.adminSession, NewPin); TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status); Locked = false; }