module Azure::ARM::WindowsCredentials
Public Instance Methods
latest_credential_target(targets)
click to toggle source
# File lib/azure/resource_management/windows_credentials.rb, line 156 def latest_credential_target(targets) case targets.size when 0 raise "No Target was found for windows credentials" when 1 targets.first.gsub("Target:", "").strip else latest_target = "" max_expiry_time = Time.new(0) # Using expiry_time to determine the latest credential targets.each do |target| target_obj = target.split("::") expiry_time_obj = target_obj.select { |obj| obj.include? "expiresOn" } expiry_time = expiry_time_obj[0].split("expiresOn:")[1].delete("\\") if Time.parse(expiry_time) > max_expiry_time latest_target = target max_expiry_time = Time.parse(expiry_time) end end latest_target.gsub("Target:", "").strip end end
target_name()
click to toggle source
Todo: For getting the complete refreshToken, both credentials (ending with –0-2 and –1-2) have to be read
# File lib/azure/resource_management/windows_credentials.rb, line 123 def target_name # cmdkey command is used for accessing windows credential manager. # Multiple credentials get created in windows credential manager for a single Azure account in xplat-cli # One of them is for common tenant id, which can't be used # Others end with --0-x,--1-x,--2-x etc, where x represents the total no. of credentials across which the token is divided # The one ending with --0-x has the complete accessToken in the credentialBlob. # Refresh Token is split across both credentials (ending with --0-x and --1-x). # Xplat splits the credentials based on the number of bytes of the tokens. # Hence the access token is always found in the one which start with --0- # So selecting the credential on the basis of --0- xplat_creds_cmd = Mixlib::ShellOut.new('cmdkey /list | findstr AzureXplatCli | findstr \--0- | findstr -v common') result = xplat_creds_cmd.run_command target_names = [] if result.stdout.empty? Chef::Log.debug("Unable to find a credential with --0- and falling back to looking for any credential.") xplat_creds_cmd = Mixlib::ShellOut.new("cmdkey /list | findstr AzureXplatCli | findstr -v common") result = xplat_creds_cmd.run_command if result.stdout.empty? raise "Azure Credentials not found. Please run xplat's 'azure login' command" else target_names = result.stdout.split("\n") end else target_names = result.stdout.split("\n") end # If "azure login" is run for multiple users, there will be multiple credentials # Picking up the latest logged in user's credentials latest_credential_target target_names end
token_details_from_WCM()
click to toggle source
# File lib/azure/resource_management/windows_credentials.rb, line 80 def token_details_from_WCM target = target_name if target && !target.empty? target_pointer = wstring(target) info_ptr = FFI::MemoryPointer.new(:pointer) cred = CREDENTIAL_OBJECT.new info_ptr cred_result = CredReadW(target_pointer, CRED_TYPE_GENERIC, 0, cred) translated_cred = CREDENTIAL_OBJECT.new(info_ptr.read_pointer) target_obj = translated_cred[:TargetName].read_wstring.split("::") if translated_cred[:TargetName].read_wstring cred_blob = translated_cred[:CredentialBlob].get_bytes(0, translated_cred[:CredentialBlobSize]).split("::") tokentype = target_obj.select { |obj| obj.include? "tokenType" } user = target_obj.select { |obj| obj.include? "userId" } clientid = target_obj.select { |obj| obj.include? "clientId" } expiry_time = target_obj.select { |obj| obj.include? "expiresOn" } access_token = cred_blob.select { |obj| obj.include? "a:" } refresh_token = cred_blob.select { |obj| obj.include? "r:" } credential = {} credential[:tokentype] = tokentype[0].split(":")[1] credential[:user] = user[0].split(":")[1] credential[:token] = access_token[0].split(":")[1] # TODO: refresh_token is not complete currently # target_name method needs to be modified for that credential[:refresh_token] = refresh_token[0].split(":")[1] credential[:clientid] = clientid[0].split(":")[1] credential[:expiry_time] = expiry_time[0].split("expiresOn:")[1].delete("\\") # Free memory pointed by info_ptr info_ptr.free else raise "TargetName Not Found" end credential rescue => error ui.error("#{error.message}") Chef::Log.debug("#{error.backtrace.join("\n")}") exit end