27 #include <boost/program_options.hpp>
28 #include <boost/filesystem.hpp>
30 #include <drizzled/configmake.h>
31 #include <drizzled/plugin/authentication.h>
32 #include <drizzled/identifier.h>
33 #include <drizzled/util/convert.h>
37 namespace po= boost::program_options;
38 namespace fs= boost::filesystem;
41 using namespace drizzled;
45 static const fs::path DEFAULT_USERS_FILE= SYSCONFDIR
"/drizzle.users";
55 const string& getError()
const;
83 bool verifyMySQLHash(
const string &password,
84 const string &scramble_bytes,
85 const string &scrambled_password);
88 const fs::path users_file;
97 AuthFile::AuthFile(fs::path users_file_arg) :
98 plugin::Authentication(
"auth_file"),
99 users_file(users_file_arg)
110 ifstream file(users_file.string().c_str());
114 error =
"Could not open users file: " + users_file.string();
119 while (getline(file, line))
122 if (line.empty() || line[line.find_first_not_of(
" \t")] ==
'#')
127 size_t password_offset = line.find(
":");
128 if (password_offset == string::npos)
132 username = string(line, 0, password_offset);
133 password = string(line, password_offset + 1);
136 if (not users.insert(pair<string, string>(username, password)).second)
138 error =
"Duplicate entry found in users file: " + username;
146 const string &scramble_bytes,
147 const string &scrambled_password)
149 if (scramble_bytes.size() != SHA1_DIGEST_LENGTH || scrambled_password.size() != SHA1_DIGEST_LENGTH)
155 uint8_t local_scrambled_password[SHA1_DIGEST_LENGTH];
156 uint8_t temp_hash[SHA1_DIGEST_LENGTH];
157 uint8_t scrambled_password_check[SHA1_DIGEST_LENGTH];
161 SHA1Update(&ctx, reinterpret_cast<const uint8_t *>(password.c_str()), password.size());
162 SHA1Final(temp_hash, &ctx);
165 SHA1Update(&ctx, temp_hash, SHA1_DIGEST_LENGTH);
166 SHA1Final(local_scrambled_password, &ctx);
170 SHA1Update(&ctx, reinterpret_cast<const uint8_t*>(scramble_bytes.c_str()), SHA1_DIGEST_LENGTH);
171 SHA1Update(&ctx, local_scrambled_password, SHA1_DIGEST_LENGTH);
172 SHA1Final(temp_hash, &ctx);
176 for (
int x= 0; x < SHA1_DIGEST_LENGTH; x++)
177 temp_hash[x]= temp_hash[x] ^ scrambled_password[x];
181 SHA1Update(&ctx, temp_hash, SHA1_DIGEST_LENGTH);
182 SHA1Final(scrambled_password_check, &ctx);
185 return memcmp(local_scrambled_password, scrambled_password_check, SHA1_DIGEST_LENGTH) == 0;
190 string* user= find_ptr(users, sctx.username());
193 return sctx.getPasswordType() == identifier::User::MYSQL_HASH
205 errmsg_printf(error::ERROR, _(
"Could not load auth file: %s\n"), auth_file->
getError().c_str());
210 context.add(auth_file);
220 po::value<string>()->default_value(DEFAULT_USERS_FILE.string()),
221 N_(
"File to load for usernames and passwords"));
226 DRIZZLE_DECLARE_PLUGIN
232 N_(
"Authentication against a plain text file"),
236 auth_file::init_options
238 DRIZZLE_DECLARE_PLUGIN_END;