- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List

# Account.h

    00001 /*
    00002  *  Phusion Passenger - http://www.modrails.com/
    00003  *  Copyright (c) 2010 Phusion
    00004  *
    00005  *  "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
    00006  *
    00007  *  Permission is hereby granted, free of charge, to any person obtaining a copy
    00008  *  of this software and associated documentation files (the "Software"), to deal
    00009  *  in the Software without restriction, including without limitation the rights
    00010  *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00011  *  copies of the Software, and to permit persons to whom the Software is
    00012  *  furnished to do so, subject to the following conditions:
    00013  *
    00014  *  The above copyright notice and this permission notice shall be included in
    00015  *  all copies or substantial portions of the Software.
    00016  *
    00017  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00018  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00019  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    00020  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00021  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00022  *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    00023  *  THE SOFTWARE.
    00024  */
    00025 #ifndef _PASSENGER_ACCOUNT_H_
    00026 #define _PASSENGER_ACCOUNT_H_
    00027
    00028 #include <string>
    00029 #include <vector>
    00030 #include <boost/shared_ptr.hpp>
    00031 #include "StaticString.h"
    00032 #include "Utils.h"
    00033
    00034 namespace Passenger {
    00035
    00036 using namespace boost;
    00037 using namespace std;
    00038
    00039 /*
    00040  * SECURITY NOTES
    00041  *
    00042  * We want to avoid storing plain text passwords in memory, because attackers may be able
    00043  * to read this process's memory, e.g. through core dumps or debuggers. So in this source
    00044  * file, as well as in several others, we follow these guidelines:
    00045  *
    00046  * - Variables and arguments named userSuppliedPassword represent passwords
    00047  *   supplied by a human, i.e. user input. These variables and arguments have the type
    00048  *   'StaticString' instead of 'string', because we want to avoid accidentally copying
    00049  *   the password values.
    00050  * - Variables and arguments named passwordOrHash might also represent passwords. However,
    00051  *   if it is a password, then it is guaranteed NOT to be supplied by a human, e.g. it's
    00052  *   randomly generated. Therefore it's okay for passwordOrHash to be of type 'string'.
    00053  * - If there is a need to copy the password for whatever reason, then it must be cleared
    00054  *   with ZeroMemoryGuard (Utils.h) as soon as possible. Do not use memset(), the code
    00055  *   for ZeroMemoryGuard explains why.
    00056  */
    00057
    00058 class Account {
    00059 public:
    00060         enum Rights {
    00061                 ALL                       = ~0,
    00062                 NONE                      = 0,
    00063
    00064                 // ApplicationPool::Server rights.
    00065                 GET                       = 1 << 0,
    00066                 CLEAR                     = 1 << 1,
    00067                 DETACH                    = 1 << 2,
    00068                 GET_PARAMETERS            = 1 << 3,
    00069                 SET_PARAMETERS            = 1 << 4,
    00070                 INSPECT_BASIC_INFO        = 1 << 5,
    00071                 INSPECT_SENSITIVE_INFO    = 1 << 6,
    00072                 //INSPECT_BACKEND_ADDRESSES = 1 << 6,
    00073                 //INSPECT_DETACH_KEYS       = 1 << 7,
    00074
    00075                 // BacktracesServer rights.
    00076                 INSPECT_BACKTRACES        = 1 << 8,
    00077
    00078                 // Other rights.
    00079                 EXIT                      = 1 << 9
    00080         };
    00081
    00082 private:
    00083         string username;
    00084         string passwordOrHash;
    00085         bool hashGiven;
    00086         Rights rights;
    00087
    00088 public:
    00089         // Urgh, I can't use 'Rights' here as type because apparently bitwise
    00090         // ORing two enums results in an int type.
    00091
    00092         static Rights parseRightsString(const string &str, int defaultValue = NONE) {
    00093                 vector<string> rights_vec;
    00094                 vector<string>::const_iterator it;
    00095                 int result = defaultValue;
    00096
    00097                 split(str, ',', rights_vec);
    00098                 for (it = rights_vec.begin(); it != rights_vec.end(); it++) {
    00099                         if (*it == "all") {
    00100                                 result = ALL;
    00101                         } else if (*it == "none") {
    00102                                 result = NONE;
    00103
    00104                         } else if (*it == "get") {
    00105                                 result |= GET;
    00106                         } else if (*it == "clear") {
    00107                                 result |= CLEAR;
    00108                         } else if (*it == "detach") {
    00109                                 result |= DETACH;
    00110                         } else if (*it == "get_parameters") {
    00111                                 result |= GET_PARAMETERS;
    00112                         } else if (*it == "set_parameters") {
    00113                                 result |= SET_PARAMETERS;
    00114                         } else if (*it == "inspect_basic_info") {
    00115                                 result |= INSPECT_BASIC_INFO;
    00116                         } else if (*it == "inspect_sensitive_info") {
    00117                                 result |= INSPECT_SENSITIVE_INFO;
    00118
    00119                         } else if (*it == "inspect_backtraces") {
    00120                                 result |= INSPECT_BACKTRACES;
    00121
    00122                         } else if (*it == "exit") {
    00123                                 result |= EXIT;
    00124
    00125                         } else if (*it != "") {
    00126                                 throw ArgumentException("Unknown right '" + *it + "'.");
    00127                         }
    00128                 }
    00129
    00130                 return (Rights) result;
    00131         }
    00132
    00133         Account(const string &username, const string &passwordOrHash, bool hashGiven, int rights = ALL) {
    00134                 this->username       = username;
    00135                 this->passwordOrHash = passwordOrHash;
    00136                 this->hashGiven      = hashGiven;
    00137                 this->rights         = (Rights) rights;
    00138         }
    00139
    00140         bool checkPasswordOrHash(const StaticString &userSuppliedPassword) const {
    00141                 if (hashGiven) {
    00142                         return passwordOrHash == createHash(userSuppliedPassword);
    00143                 } else {
    00144                         return userSuppliedPassword == passwordOrHash;
    00145                 }
    00146         }
    00147
    00148         bool hasRights(int rights) const {
    00149                 return this->rights & rights;
    00150         }
    00151
    00152         void setRights(int rights) {
    00153                 this->rights = (Rights) rights;
    00154         }
    00155
    00156         string getUsername() const {
    00157                 return username;
    00158         }
    00159
    00160         string getRawPassword() const {
    00161                 return passwordOrHash;
    00162         }
    00163
    00164         static string createHash(const StaticString &userSuppliedPassword) {
    00165                 // TODO: use bcrypt or something
    00166                 return userSuppliedPassword;
    00167         }
    00168 };
    00169
    00170 typedef shared_ptr<Account> AccountPtr;
    00171
    00172 } // namespace Passenger
    00173
    00174 #endif /* _PASSENGER_ACCOUNT_H_ */