// ----------------------------------------------------------------------
// File: PasswordFileReader.hh
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#ifndef EOS_COMMON_PASSWORD_HANDLER_HH
#define EOS_COMMON_PASSWORD_HANDLER_HH
#include
#include
#include
#include "common/Namespace.hh"
#include "common/Logging.hh"
EOSCOMMONNAMESPACE_BEGIN
//------------------------------------------------------------------------------
//! Helper class to perform common operations related to passwords.
//------------------------------------------------------------------------------
class PasswordHandler {
public:
//----------------------------------------------------------------------------
// Check if file permissions are secure.
//----------------------------------------------------------------------------
static bool areFilePermissionsSecure(mode_t mode)
{
if ((mode & 0077) != 0) {
// Should disallow access to other users/groups
return false;
}
if ((mode & 0700) != 0400) {
// Just read access for user
return false;
}
return true;
}
//----------------------------------------------------------------------------
// Right trim password, remove whitespace
//----------------------------------------------------------------------------
static void rightTrimWhitespace(std::string &src)
{
src.erase(src.find_last_not_of(" \t\n\r\f\v") + 1);
}
//----------------------------------------------------------------------------
// Read a password file, while taking the following into account:
// - Permissions must be 400 - refuse to do anything otherwise.
// - Ending newlines are discarded.
//----------------------------------------------------------------------------
static bool readPasswordFile(const std::string &path, std::string &contents) {
FILE *in = fopen(path.c_str(), "rb");
if(!in) {
eos_static_crit("Could not read pasword file: %s", path.c_str());
return false;
}
// Ensure file permissions are 400.
struct stat sb;
if(fstat(fileno(in), &sb) != 0) {
fclose(in);
eos_static_crit("Could not fstat %s after opening (should never happen?!)", path.c_str());
return false;
}
if(!areFilePermissionsSecure(sb.st_mode)) {
eos_static_crit("Refusing to read %s, bad file permissions, should be 0400.", path.c_str());
fclose(in);
return false;
}
// Do actual read...
std::ostringstream ss;
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
bool retvalue = true;
while(true) {
size_t bytesRead = fread(buffer, 1, BUFFER_SIZE, in);
if(bytesRead > 0) {
ss.write(buffer, bytesRead);
}
// end of file
if(bytesRead != BUFFER_SIZE) {
retvalue = feof(in);
break;
}
}
fclose(in);
contents = ss.str();
rightTrimWhitespace(contents);
return retvalue;
}
};
EOSCOMMONNAMESPACE_END
#endif