in src/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp [113:210]
void ParseStream(Aws::IStream& stream)
{
static const size_t ASSUME_EMPTY_LEN = 3;
State currentState = START;
Aws::String currentSectionName;
Aws::Map<Aws::String, Aws::String> currentKeyValues;
Aws::String rawLine;
while(std::getline(stream, rawLine) && currentState != FAILURE)
{
// Handle CR/LF line endings ("\r\n")
if (!rawLine.empty() && rawLine.back() == '\r') {
rawLine.pop_back(); // Remove carriage return character ('\r')
}
Aws::String line = rawLine.substr(0, rawLine.find_first_of(COMMENT_START)); // ignore comments
if (line.empty() || line.length() < ASSUME_EMPTY_LEN || line.find_first_not_of(WHITESPACE_CHARACTERS) == Aws::String::npos)
{
continue;
}
auto openPos = line.find(LEFT_BRACKET);
auto closePos = line.find(RIGHT_BRACKET);
if(openPos != std::string::npos && closePos != std::string::npos)
{
FlushSection(currentState, currentSectionName, currentKeyValues);
currentKeyValues.clear();
ParseSectionDeclaration(line, currentSectionName, currentState);
continue;
}
if(PROFILE_FOUND == currentState || SSO_SESSION_FOUND == currentState)
{
auto equalsPos = line.find(EQ);
if (equalsPos != std::string::npos)
{
auto key = StringUtils::Trim(line.substr(0, equalsPos).c_str());
auto value = StringUtils::Trim(line.substr(equalsPos + 1).c_str());
currentKeyValues[key] = value;
continue;
}
}
if(UNKNOWN_SECTION_FOUND == currentState)
{
// skip any unknown sections
continue;
}
AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unexpected line in the aws shared profile: " << rawLine);
currentState = FAILURE;
break;
}
FlushSection(currentState, currentSectionName, currentKeyValues);
// Put sso-sessions into profiles
for(auto& profile : m_foundProfiles)
{
const Aws::String& profileSsoSessionName = profile.second.GetValue(SSO_SESSION_KEY);
if(!profileSsoSessionName.empty())
{
auto ssoSessionIt = m_foundSsoSessions.find(profileSsoSessionName);
if(ssoSessionIt == m_foundSsoSessions.end())
{
AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS profile has reference to a missing sso_session: " << profileSsoSessionName);
currentState = FAILURE;
continue;
}
auto ssoSession = ssoSessionIt->second;
auto prof = profile.second;
// If sso session and profile have conflicting start url or region, fail to parse
// the session/sso specific profile properties
auto hasConflictingStartUrls = !ssoSession.GetSsoStartUrl().empty()
&& !prof.GetSsoStartUrl().empty()
&& ssoSession.GetSsoStartUrl() != prof.GetSsoStartUrl();
auto hasConflictingRegions = !ssoSession.GetSsoRegion().empty()
&& !prof.GetSsoRegion().empty()
&& ssoSession.GetSsoRegion() != prof.GetSsoRegion();
if (hasConflictingStartUrls || hasConflictingRegions) {
AWS_LOGSTREAM_ERROR(PARSER_TAG,
"SSO profile has a start url or region conflict with sso session");
prof.SetSsoStartUrl("");
prof.SetSsoRegion("");
prof.SetSsoAccountId("");
prof.SetSsoRoleName("");
continue;
}
profile.second.SetSsoSession(ssoSessionIt->second);
}
}
if(FAILURE == currentState)
{
AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS shared profile config parsing failed");
}
}