Revamped the read_passwd_file function to resolve issue #114

Add support for mulitple access id/secret access keys in passwd-s3fs file

This change applies to any passwd-s3fs files.

The format of the file is more robust, error checked and extended:

  - as before, any line beginning with # is ignored
  - any empty line is ignored
  - any non-ignored line which contains a space or tab is an error
  - any non-ignored line which does not contain a : separator is an error
  
The format of the file is:

[bucket:]AccessKeyId:SecretAccessKey

The bucket can now be specified to allow for multiple credentials.
A default entry is as before:

AccessKeyId:SecretAccessKey

Only one default entry is allowed, if more than one default entry
is found, that is an error.  A default entry is not required, if the
bucket that is being mounted has its own entry.

If the user's .passwd-s3fs file is present but credentials cannot
be determined from it, then the system-wide /etc/passwd-s3fs will
be consulted (if readable by the current user).

This change is completely backward compatable with the existing
scheme and has been well tested.



git-svn-id: http://s3fs.googlecode.com/svn/trunk@229 df820570-a93a-0410-bd06-b72b767a4274
This commit is contained in:
mooredan@suncup.net 2010-11-08 03:42:16 +00:00
parent a80c900894
commit cc2e440276
2 changed files with 84 additions and 23 deletions

View File

@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_INIT(s3fs, 1.10) AC_INIT(s3fs, 1.11)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View File

@ -1581,26 +1581,81 @@ static int s3fs_utimens(const char *path, const struct timespec ts[2]) {
return put_headers(path, meta); return put_headers(path, meta);
} }
// This function needs to be a little bit more //////////////////////////////////////////////////////////////////
// robust - add support for per bucket credentials // read_passwd_file
//
// Support for per bucket credentials
//
// Format for the credentials file:
// [bucket:]AccessKeyId:SecretAccessKey
//
// Lines beginning with # are considered comments
// and ignored, as are empty lines
//
// Uncommented lines without the ":" character are flagged as
// an error, so are lines with spaces or tabs
//
// only one default key pair is allowed, but not required
//////////////////////////////////////////////////////////////////
static void read_passwd_file (void) { static void read_passwd_file (void) {
string line; string line;
string field1, field2, field3;
size_t first_pos = string::npos;
size_t last_pos = string::npos;
bool default_found = 0;
ifstream PF(passwd_file.c_str()); ifstream PF(passwd_file.c_str());
if (PF.good()) { if (PF.good()) {
while (getline(PF, line)) { while (getline(PF, line)) {
if (line[0]=='#') if (line[0]=='#') {
continue; continue;
}
if (line.size() == 0) {
continue;
}
size_t pos = line.find(':'); first_pos = line.find_first_of(" \t");
if (pos != string::npos) { if (first_pos != string::npos) {
if (AWSAccessKeyId.size() == 0) { printf ("%s: invalid line in passwd file, found whitespace character\n",
AWSAccessKeyId = line.substr(0, pos); program_name.c_str());
exit(1);
} }
if (AWSSecretAccessKey.size() == 0) {
if (line.substr(0, pos) == AWSAccessKeyId) { first_pos = line.find_first_of(":");
AWSSecretAccessKey = line.substr(pos + 1, string::npos); if (first_pos == string::npos) {
printf ("%s: invalid line in passwd file, no \":\" separator found\n",
program_name.c_str());
exit(1);
} }
last_pos = line.find_last_of(":");
if (first_pos != last_pos) {
// bucket specified
field1 = line.substr(0,first_pos);
field2 = line.substr(first_pos + 1, last_pos - first_pos - 1);
field3 = line.substr(last_pos + 1, string::npos);
} else {
// no bucket specified - original style - found default key
if (default_found == 1) {
printf ("%s: more than one default key pair found in passwd file\n",
program_name.c_str());
exit(1);
} }
default_found = 1;
field1.assign("");
field2 = line.substr(0,first_pos);
field3 = line.substr(first_pos + 1, string::npos);
AWSAccessKeyId = field2;
AWSSecretAccessKey = field3;
}
// does the bucket we are mounting match this passwd file entry?
// if so, use that key pair, otherwise use the default key, if found,
// will be used
if (field1.size() != 0 && field1 == bucket) {
AWSAccessKeyId = field2;
AWSSecretAccessKey = field3;
break;
} }
} }
} }
@ -1677,9 +1732,14 @@ static void get_access_keys (void) {
if (PF.good()) { if (PF.good()) {
PF.close(); PF.close();
read_passwd_file(); read_passwd_file();
// It is possible that the user's file was there but
// contained no key pairs i.e. commented out
// in that case, go look in the final location
if (AWSAccessKeyId.size() > 0 && AWSSecretAccessKey.size() > 0) {
return; return;
} }
} }
}
// 5 - from the system default location // 5 - from the system default location
passwd_file.assign("/etc/passwd-s3fs"); passwd_file.assign("/etc/passwd-s3fs");
@ -2017,11 +2077,12 @@ int main(int argc, char *argv[]) {
program_name.c_str()); program_name.c_str());
exit(1); exit(1);
} }
// More error checking on the access key pair can be done
// like checking for appropriate lengths and characters
} }
// There's room for more command line error checking // There's room for more command line error checking
s3fs_oper.getattr = s3fs_getattr; s3fs_oper.getattr = s3fs_getattr;
s3fs_oper.readlink = s3fs_readlink; s3fs_oper.readlink = s3fs_readlink;
s3fs_oper.mknod = s3fs_mknod; s3fs_oper.mknod = s3fs_mknod;