Aws::String GenerateSummary(time_t now) { time_t tempEndTime = (activeState == COMPLETE) ? endTime : now; time_t tempStartTime = (startTime != 0) ? startTime : now; Aws::String temp; temp = std::to_string(tempEndTime - tempStartTime).c_str(); while (temp.length() < 12) temp = " " + temp; temp += " ms, "; switch (finishState) { case PASSED: temp += "pass: "******"FAILED: "; break; case SKIPPED: temp += "SKIPPED: "; break; case TIMEDOUT: temp += "TIMED OUT: "; break; } temp += testName; if (testResultMsg.length() > 0) { temp += " - "; temp += testResultMsg; } return temp; }
Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& regionName) const { AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); Aws::StringStream ss; //now we do the complicated part of deriving a signing key. Aws::String signingKey(SIGNING_KEY); signingKey.append(credentials.GetAWSSecretKey()); //we use digest only for the derivation process. auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hmac (sha256) date string \"" << simpleDate << "\""); return ""; } auto kDate = hashResult.GetResult(); hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)regionName.c_str(), regionName.length()), kDate); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hmac (sha256) region string \"" << regionName << "\""); return ""; } auto kRegion = hashResult.GetResult(); hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)m_serviceName.c_str(), m_serviceName.length()), kRegion); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hmac (sha256) service string \"" << m_serviceName << "\""); return ""; } auto kService = hashResult.GetResult(); hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) request string \"" << AWS4_REQUEST << "\""); return ""; } auto kSigning = hashResult.GetResult(); hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), kSigning); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string \"" << stringToSign << "\""); return ""; } //now we finally sign our request string with our hex encoded derived hash. auto finalSigningDigest = hashResult.GetResult(); auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); return finalSigningHash; }
void URI::ExtractAndSetPath(const Aws::String& uri) { size_t authorityStart = uri.find(SEPARATOR); if (authorityStart == Aws::String::npos) { authorityStart = 0; } else { authorityStart += 3; } size_t pathEnd = uri.find('?'); if (pathEnd == Aws::String::npos) { pathEnd = uri.length(); } Aws::String authorityAndPath = uri.substr(authorityStart, pathEnd - authorityStart); size_t pathStart = authorityAndPath.find('/'); if (pathStart != Aws::String::npos) { SetPath(authorityAndPath.substr(pathStart, pathEnd - pathStart), false); } else { SetPath("/"); } }
HashResult Sha256CommonCryptoImpl::Calculate(const Aws::String& str) { ByteBuffer hash(CC_SHA256_DIGEST_LENGTH); CC_SHA256(str.c_str(), str.length(), hash.GetUnderlyingData()); return HashResult(std::move(hash)); }
void URI::SetPath(const Aws::String& value, bool shouldEncode) { //we need to url encode the path parts (mainly to take care of spaces that a user might put here) if (shouldEncode) { Aws::Vector<Aws::String> pathParts = StringUtils::Split(value, '/'); Aws::StringStream ss; for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter) { ss << '/' << StringUtils::URLEncode(iter->c_str()); } //if the last character was also a slash, then add that back here. if (value[value.length() - 1] == '/') { ss << '/'; } path = ss.str(); } else { path = value; } }
HashResult MD5CommonCryptoImpl::Calculate(const Aws::String& str) { ByteBuffer hash(CC_MD5_DIGEST_LENGTH); CC_MD5(str.c_str(), static_cast<CC_LONG>(str.length()), hash.GetUnderlyingData()); return HashResult(std::move(hash)); }
size_t CurlHttpClient::WriteHeader(char* ptr, size_t size, size_t nmemb, void* userdata) { if (ptr) { AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, ptr); HttpResponse* response = (HttpResponse*) userdata; Aws::String headerLine(ptr); Aws::Vector<Aws::String> keyValuePair = StringUtils::Split(headerLine, ':'); if (keyValuePair.size() > 1) { Aws::String headerName = keyValuePair[0]; headerName = StringUtils::Trim(headerName.c_str()); Aws::String headerValue = headerLine.substr(headerName.length() + 1).c_str(); headerValue = StringUtils::Trim(headerValue.c_str()); response->AddHeader(headerName, headerValue); } return size * nmemb; } return 0; }
Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment) { Aws::StringStream ss; if (!leftSegment.empty()) { if (leftSegment.back() == delimiter) { ss << leftSegment.substr(0, leftSegment.length() - 1); } else { ss << leftSegment; } } ss << delimiter; if (!rightSegment.empty()) { if (rightSegment.front() == delimiter) { ss << rightSegment.substr(1); } else { ss << rightSegment; } } return ss.str(); }
void JsonValue::WriteCompact(Aws::OStream& ostream, bool treatAsObject) const { if (treatAsObject && m_value.isNull()) { ostream << "{}"; return; } Aws::String compactString = WriteCompact(); ostream.write(compactString.c_str(), compactString.length()); }
UUID::UUID(const Aws::String& uuidToConvert) { //GUID has 2 characters per byte + 4 dashes = 36 bytes assert(uuidToConvert.length() == UUID_STR_SIZE); memset(m_uuid, 0, sizeof(m_uuid)); Aws::String escapedHexStr(uuidToConvert); StringUtils::Replace(escapedHexStr, "-", ""); assert(escapedHexStr.length() == UUID_BINARY_SIZE * 2); ByteBuffer&& rawUuid = HashingUtils::HexDecode(escapedHexStr); memcpy(m_uuid, rawUuid.GetUnderlyingData(), rawUuid.GetLength()); }
TEST_F(QueueOperationTest, TestPermissions) { Aws::String queueUrl = CreateDefaultQueue(PERMISSIONS_QUEUE_NAME); ASSERT_TRUE(queueUrl.find(PERMISSIONS_QUEUE_NAME) != Aws::String::npos); AddPermissionRequest addPermissionRequest; addPermissionRequest.AddAWSAccountIds(m_accountId).AddActions("ReceiveMessage").WithLabel("Test").WithQueueUrl( queueUrl); AddPermissionOutcome permissionOutcome = sqsClient->AddPermission(addPermissionRequest); ASSERT_TRUE(permissionOutcome.IsSuccess()); GetQueueAttributesRequest queueAttributesRequest; queueAttributesRequest.AddAttributeNames(QueueAttributeName::Policy).WithQueueUrl(queueUrl); GetQueueAttributesOutcome queueAttributesOutcome = sqsClient->GetQueueAttributes(queueAttributesRequest); ASSERT_TRUE(queueAttributesOutcome.IsSuccess()); Aws::String policyString = queueAttributesOutcome.GetResult().GetAttributes().find(QueueAttributeName::Policy)->second; EXPECT_TRUE(policyString.length() > 0); JsonValue policy(policyString); EXPECT_EQ(addPermissionRequest.GetLabel(), policy.GetArray("Statement")[0].GetString("Sid")); EXPECT_EQ(m_accountId, policy.GetArray("Statement")[0].GetObject("Principal").GetString("AWS")); EXPECT_EQ("SQS:ReceiveMessage", policy.GetArray("Statement")[0].GetString("Action")); RemovePermissionRequest removePermissionRequest; removePermissionRequest.WithLabel("Test").WithQueueUrl(queueUrl); RemovePermissionOutcome removePermissionOutcome = sqsClient->RemovePermission(removePermissionRequest); ASSERT_TRUE(removePermissionOutcome.IsSuccess()); queueAttributesOutcome = sqsClient->GetQueueAttributes(queueAttributesRequest); ASSERT_TRUE(queueAttributesOutcome.IsSuccess()); policyString = queueAttributesOutcome.GetResult().GetAttributes().find(QueueAttributeName::Policy)->second; EXPECT_TRUE(policyString.length() > 0); JsonValue emptyPolicy(policyString); EXPECT_EQ(0uL, emptyPolicy.GetArray("Statement").GetLength()); DeleteQueueRequest deleteQueueRequest; deleteQueueRequest.WithQueueUrl(queueUrl); DeleteQueueOutcome deleteQueueOutcome = sqsClient->DeleteQueue(deleteQueueRequest); ASSERT_TRUE(deleteQueueOutcome.IsSuccess()); }
TEST(StringUtilsTest, TestWStringNonAsciiToString) { AWS_BEGIN_MEMORY_TEST(16, 10) Aws::WString startString; // Toss in a couple ascii characters to start, then go over 127 const char startVal = 115; int addValue = startVal; const char incrementVal = 10; const char loopCount = 10; for (char i = 0; i < loopCount; ++i) { startString.push_back(static_cast<wchar_t>(addValue)); addValue += incrementVal; } Aws::String outString = StringUtils::FromWString(startString.c_str()); ASSERT_EQ(outString.length(), loopCount); for (size_t i = 0; i < outString.length(); ++i) { char testValue = outString[i]; ASSERT_EQ(testValue, static_cast<char>(startVal + incrementVal * i)); } // This loop will cross the byte limit for (char i = 0; i < loopCount; ++i) { startString.push_back(static_cast<wchar_t>(addValue)); addValue += incrementVal; } // Verify the length, not the values though outString = StringUtils::FromWString(startString.c_str()); ASSERT_EQ(outString.length(), loopCount * 2); AWS_END_MEMORY_TEST }
TEST(UUIDTest, TestPlatformGeneratesUUID) { Aws::Set<Aws::String> generatedUUids; for(size_t i = 0u; i < 1000u; ++i) { UUID uuid = UUID::RandomUUID(); Aws::String uuidStr = uuid; ASSERT_EQ(36u, uuidStr.length()); ByteBuffer rawUUID = uuid; ASSERT_EQ(16u, rawUUID.GetLength()); ASSERT_EQ(0x40u, 0x40u & rawUUID[6]); ASSERT_EQ(0x80u, 0x80u & rawUUID[8]); ASSERT_EQ(generatedUUids.end(), generatedUUids.find(uuidStr)); generatedUUids.insert(uuidStr); } }
Aws::String URI::URLEncodePath(const Aws::String& path) { Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/'); Aws::StringStream ss; for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter) { ss << '/' << StringUtils::URLEncode(iter->c_str()); } //if the last character was also a slash, then add that back here. if (path[path.length() - 1] == '/') { ss << '/'; } return ss.str(); }
HashResult BCryptHashImpl::Calculate(const Aws::String& str) { if (!IsValid()) { return HashResult(); } std::lock_guard<std::mutex> locker(m_algorithmMutex); BCryptHashContext context(m_algorithmHandle, m_hashObject, m_hashObjectLength); if (!context.IsValid()) { AWS_LOG_ERROR(logTag, "Error creating hash handle."); return HashResult(); } return HashData(context, (PBYTE)str.c_str(), static_cast<ULONG>(str.length())); }
Aws::String FileSystemUtils::GetHomeDirectory() { static const char* HOME_DIR_ENV_VAR = "HOME"; AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Checking " << HOME_DIR_ENV_VAR << " for the home directory."); const char* homeEnvDir = std::getenv(HOME_DIR_ENV_VAR); Aws::String homeDir(homeEnvDir ? homeEnvDir : ""); AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Environment value for variable " << HOME_DIR_ENV_VAR << " is " << homeDir); if(homeDir.empty()) { AWS_LOG_WARN(FILE_SYSTEM_UTILS_LOG_TAG, "Home dir not stored in environment, trying to fetch manually from the OS."); passwd pw; passwd *p_pw = nullptr; char pw_buffer[4096]; getpwuid_r(getuid(), &pw, pw_buffer, sizeof(pw_buffer), &p_pw); if(p_pw && p_pw->pw_dir) { homeDir = p_pw->pw_dir; } AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Pulled " << homeDir << " as home directory from the OS."); } Aws::String retVal = homeDir.size() > 0 ? StringUtils::Trim(homeDir.c_str()) : ""; if(!retVal.empty()) { if(retVal.at(retVal.length() - 1) != PATH_DELIM) { AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Home directory is missing the final " << PATH_DELIM << " appending one to normalize"); retVal += PATH_DELIM; } } AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Final Home Directory is " << retVal); return retVal; }
Aws::String GetHomeDirectory() { static const char* HOME_DIR_ENV_VAR = "USERPROFILE"; AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Checking " << HOME_DIR_ENV_VAR << " for the home directory."); Aws::String homeDir = Aws::Environment::GetEnv(HOME_DIR_ENV_VAR); AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Environment value for variable " << HOME_DIR_ENV_VAR << " is " << homeDir); if(homeDir.empty()) { AWS_LOGSTREAM_WARN(FILE_SYSTEM_UTILS_LOG_TAG, "Home dir not stored in environment, trying to fetch manually from the OS."); HANDLE hToken; if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) { DWORD len = MAX_PATH; WCHAR path[MAX_PATH]; if (GetUserProfileDirectoryW(hToken, path, &len)) { homeDir = Aws::Utils::StringUtils::FromWString(path); } CloseHandle(hToken); } AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Pulled " << homeDir << " as home directory from the OS."); } Aws::String retVal = (homeDir.size() > 0) ? Aws::Utils::StringUtils::Trim(homeDir.c_str()) : ""; if (!retVal.empty()) { if (retVal.at(retVal.length() - 1) != Aws::FileSystem::PATH_DELIM) { retVal += Aws::FileSystem::PATH_DELIM; } } return retVal; }
void URI::ExtractAndSetAuthority(const Aws::String& uri) { size_t authorityStart = uri.find(SEPARATOR); if (authorityStart == Aws::String::npos) { authorityStart = 0; } else { authorityStart += 3; } size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart); size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart); size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart); size_t posEndOfAuthority = std::min({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery}); if (posEndOfAuthority == Aws::String::npos) { posEndOfAuthority = uri.length(); } SetAuthority(uri.substr(authorityStart, posEndOfAuthority - authorityStart)); }
Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, const Aws::String& simpleDate) const { AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); Aws::StringStream ss; auto& partialSignature = ComputeLongLivedHash(credentials.GetAWSSecretKey(), simpleDate); auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), partialSignature); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string \"" << stringToSign << "\""); return ""; } //now we finally sign our request string with our hex encoded derived hash. auto finalSigningDigest = hashResult.GetResult(); auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); return finalSigningHash; }
bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, bool signBody) const { AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); //don't sign anonymous requests if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) { return true; } if (!credentials.GetSessionToken().empty()) { request.SetAwsSessionToken(credentials.GetSessionToken()); } Aws::String payloadHash(UNSIGNED_PAYLOAD); if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) { payloadHash.assign(ComputePayloadHash(request)); if (payloadHash.empty()) { return false; } } else { AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << m_signPayloads << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); } if(m_includeSha256HashHeader) { request.SetHeaderValue("x-amz-content-sha256", payloadHash); } //calculate date header to use in internal signature (this also goes into date header). DateTime now = GetSigningTimestamp(); Aws::String dateHeaderValue = now.ToGmtString(LONG_DATE_FORMAT_STR); request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); Aws::StringStream headersStream; Aws::StringStream signedHeadersStream; for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) { if(ShouldSignHeader(header.first)) { headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; signedHeadersStream << header.first.c_str() << ";"; } } Aws::String canonicalHeadersString = headersStream.str(); AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); //calculate signed headers parameter Aws::String signedHeadersValue = signedHeadersStream.str(); //remove that last semi-colon signedHeadersValue.erase(signedHeadersValue.length() - 1); AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue); //generate generalized canonicalized request string. Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); //append v4 stuff to the canonical request string. canonicalRequestString.append(canonicalHeadersString); canonicalRequestString.append(NEWLINE); canonicalRequestString.append(signedHeadersValue); canonicalRequestString.append(NEWLINE); canonicalRequestString.append(payloadHash); AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); //now compute sha256 on that request string auto hashResult = m_hash->Calculate(canonicalRequestString); if (!hashResult.IsSuccess()) { AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string \"" << canonicalRequestString << "\""); return false; } auto sha256Digest = hashResult.GetResult(); Aws::String cannonicalRequestHash = HashingUtils::HexEncode(sha256Digest); Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, cannonicalRequestHash); auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate); Aws::StringStream ss; ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate << "/" << m_region << "/" << m_serviceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ << signedHeadersValue << ", " << SIGNATURE << EQ << finalSignature; auto awsAuthString = ss.str(); AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString); request.SetAwsAuthorization(awsAuthString); return true; }