1/* 2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage 3 * Copyright 2017 MinIO, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package credentials 19 20import ( 21 "os" 22 "path/filepath" 23 24 homedir "github.com/mitchellh/go-homedir" 25 ini "gopkg.in/ini.v1" 26) 27 28// A FileAWSCredentials retrieves credentials from the current user's home 29// directory, and keeps track if those credentials are expired. 30// 31// Profile ini file example: $HOME/.aws/credentials 32type FileAWSCredentials struct { 33 // Path to the shared credentials file. 34 // 35 // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the 36 // env value is empty will default to current user's home directory. 37 // Linux/OSX: "$HOME/.aws/credentials" 38 // Windows: "%USERPROFILE%\.aws\credentials" 39 Filename string 40 41 // AWS Profile to extract credentials from the shared credentials file. If empty 42 // will default to environment variable "AWS_PROFILE" or "default" if 43 // environment variable is also not set. 44 Profile string 45 46 // retrieved states if the credentials have been successfully retrieved. 47 retrieved bool 48} 49 50// NewFileAWSCredentials returns a pointer to a new Credentials object 51// wrapping the Profile file provider. 52func NewFileAWSCredentials(filename string, profile string) *Credentials { 53 return New(&FileAWSCredentials{ 54 Filename: filename, 55 Profile: profile, 56 }) 57} 58 59// Retrieve reads and extracts the shared credentials from the current 60// users home directory. 61func (p *FileAWSCredentials) Retrieve() (Value, error) { 62 if p.Filename == "" { 63 p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE") 64 if p.Filename == "" { 65 homeDir, err := homedir.Dir() 66 if err != nil { 67 return Value{}, err 68 } 69 p.Filename = filepath.Join(homeDir, ".aws", "credentials") 70 } 71 } 72 if p.Profile == "" { 73 p.Profile = os.Getenv("AWS_PROFILE") 74 if p.Profile == "" { 75 p.Profile = "default" 76 } 77 } 78 79 p.retrieved = false 80 81 iniProfile, err := loadProfile(p.Filename, p.Profile) 82 if err != nil { 83 return Value{}, err 84 } 85 86 // Default to empty string if not found. 87 id := iniProfile.Key("aws_access_key_id") 88 // Default to empty string if not found. 89 secret := iniProfile.Key("aws_secret_access_key") 90 // Default to empty string if not found. 91 token := iniProfile.Key("aws_session_token") 92 93 p.retrieved = true 94 return Value{ 95 AccessKeyID: id.String(), 96 SecretAccessKey: secret.String(), 97 SessionToken: token.String(), 98 SignerType: SignatureV4, 99 }, nil 100} 101 102// IsExpired returns if the shared credentials have expired. 103func (p *FileAWSCredentials) IsExpired() bool { 104 return !p.retrieved 105} 106 107// loadProfiles loads from the file pointed to by shared credentials filename for profile. 108// The credentials retrieved from the profile will be returned or error. Error will be 109// returned if it fails to read from the file, or the data is invalid. 110func loadProfile(filename, profile string) (*ini.Section, error) { 111 config, err := ini.Load(filename) 112 if err != nil { 113 return nil, err 114 } 115 iniProfile, err := config.GetSection(profile) 116 if err != nil { 117 return nil, err 118 } 119 return iniProfile, nil 120} 121