~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to plugin/auth_file/auth_file.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
using namespace std;
41
41
using namespace drizzled;
42
42
 
43
 
namespace auth_file
44
 
{
 
43
namespace auth_file {
45
44
 
46
45
static const fs::path DEFAULT_USERS_FILE= SYSCONFDIR "/drizzle.users";
47
46
 
48
 
class AuthFile: public plugin::Authentication
 
47
class AuthFile : public plugin::Authentication
49
48
{
50
 
  const fs::path users_file;
51
 
 
52
49
public:
53
 
 
54
 
  AuthFile(string name_arg, fs::path users_file_arg);
 
50
  AuthFile(fs::path users_file_arg);
55
51
 
56
52
  /**
57
53
   * Retrieve the last error encountered in the class.
58
54
   */
59
 
  string& getError(void);
 
55
  const string& getError() const;
60
56
 
61
57
  /**
62
58
   * Load the users file into a map cache.
64
60
   * @return True on success, false on error. If false is returned an error
65
61
   *  is set and can be retrieved with getError().
66
62
   */
67
 
  bool loadFile(void);
 
63
  bool loadFile();
68
64
 
69
65
private:
70
66
 
89
85
                       const string &scrambled_password);
90
86
 
91
87
  string error;
 
88
  const fs::path users_file;
92
89
 
93
90
  /**
94
91
   * Cache or username:password entries from the file.
95
92
   */
96
 
  std::map<string, string> users;
 
93
  typedef std::map<string, string> users_t;
 
94
  users_t users;
97
95
};
98
96
 
99
 
AuthFile::AuthFile(string name_arg, fs::path users_file_arg):
100
 
  plugin::Authentication(name_arg),
101
 
  users_file(users_file_arg),
102
 
  error(),
103
 
  users()
 
97
AuthFile::AuthFile(fs::path users_file_arg) :
 
98
  plugin::Authentication("auth_file"),
 
99
  users_file(users_file_arg)
104
100
{
105
101
}
106
102
 
107
 
string& AuthFile::getError(void)
 
103
const string& AuthFile::getError() const
108
104
{
109
105
  return error;
110
106
}
111
107
 
112
 
bool AuthFile::loadFile(void)
 
108
bool AuthFile::loadFile()
113
109
{
114
110
  ifstream file(users_file.string().c_str());
115
111
 
116
112
  if (!file.is_open())
117
113
  {
118
 
    error = "Could not open users file: ";
119
 
    error += users_file.string();
 
114
    error = "Could not open users file: " + users_file.string();
120
115
    return false;
121
116
  }
122
117
 
123
 
  while (!file.eof())
 
118
  string line;
 
119
  while (getline(file, line))
124
120
  {
125
 
    string line;
126
 
    getline(file, line);
127
 
 
128
121
    /* Ignore blank lines and lines starting with '#'. */
129
 
    if (line == "" || line[line.find_first_not_of(" \t")] == '#')
 
122
    if (line.empty() || line[line.find_first_not_of(" \t")] == '#')
130
123
      continue;
131
124
 
132
125
    string username;
140
133
      password = string(line, password_offset + 1);
141
134
    }
142
135
 
143
 
    std::pair<std::map<std::string, std::string>::iterator, bool> result=
144
 
      users.insert(std::pair<std::string, std::string>(username, password));
145
 
 
146
 
    if (result.second == false)
 
136
    if (not users.insert(pair<string, string>(username, password)).second)
147
137
    {
148
 
      error = "Duplicate entry found in users file: ";
149
 
      error += username;
150
 
      file.close();
 
138
      error = "Duplicate entry found in users file: " + username;
151
139
      return false;
152
140
    }
153
141
  }
154
 
 
155
 
  file.close();
156
142
  return true;
157
143
}
158
144
 
160
146
                               const string &scramble_bytes,
161
147
                               const string &scrambled_password)
162
148
{
163
 
  if (scramble_bytes.size() != SHA1_DIGEST_LENGTH ||
164
 
      scrambled_password.size() != SHA1_DIGEST_LENGTH)
 
149
  if (scramble_bytes.size() != SHA1_DIGEST_LENGTH || scrambled_password.size() != SHA1_DIGEST_LENGTH)
165
150
  {
166
151
    return false;
167
152
  }
173
158
 
174
159
  /* Generate the double SHA1 hash for the password stored locally first. */
175
160
  SHA1Init(&ctx);
176
 
  SHA1Update(&ctx, reinterpret_cast<const uint8_t *>(password.c_str()),
177
 
             password.size());
 
161
  SHA1Update(&ctx, reinterpret_cast<const uint8_t *>(password.c_str()), password.size());
178
162
  SHA1Final(temp_hash, &ctx);
179
163
 
180
164
  SHA1Init(&ctx);
183
167
 
184
168
  /* Hash the scramble that was sent to client with the local password. */
185
169
  SHA1Init(&ctx);
186
 
  SHA1Update(&ctx, reinterpret_cast<const uint8_t*>(scramble_bytes.c_str()),
187
 
             SHA1_DIGEST_LENGTH);
 
170
  SHA1Update(&ctx, reinterpret_cast<const uint8_t*>(scramble_bytes.c_str()), SHA1_DIGEST_LENGTH);
188
171
  SHA1Update(&ctx, local_scrambled_password, SHA1_DIGEST_LENGTH);
189
172
  SHA1Final(temp_hash, &ctx);
190
173
 
204
187
 
205
188
bool AuthFile::authenticate(const identifier::User &sctx, const string &password)
206
189
{
207
 
  std::map<std::string, std::string>::const_iterator user= users.find(sctx.username());
208
 
  if (user == users.end())
 
190
  string* user= find_ptr(users, sctx.username());
 
191
  if (not user)
209
192
    return false;
210
 
 
211
 
  if (sctx.getPasswordType() == identifier::User::MYSQL_HASH)
212
 
    return verifyMySQLHash(user->second, sctx.getPasswordContext(), password);
213
 
 
214
 
  if (password == user->second)
215
 
    return true;
216
 
 
217
 
  return false;
 
193
  return sctx.getPasswordType() == identifier::User::MYSQL_HASH
 
194
    ? verifyMySQLHash(*user, sctx.getPasswordContext(), password)
 
195
    : password == *user;
218
196
}
219
197
 
220
198
static int init(module::Context &context)
221
199
{
222
200
  const module::option_map &vm= context.getOptions();
223
201
 
224
 
  AuthFile *auth_file = new AuthFile("auth_file", fs::path(vm["users"].as<string>()));
 
202
  AuthFile *auth_file = new AuthFile(fs::path(vm["users"].as<string>()));
225
203
  if (not auth_file->loadFile())
226
204
  {
227
 
    errmsg_printf(error::ERROR, _("Could not load auth file: %s\n"),
228
 
                  auth_file->getError().c_str());
 
205
    errmsg_printf(error::ERROR, _("Could not load auth file: %s\n"), auth_file->getError().c_str());
229
206
    delete auth_file;
230
207
    return 1;
231
208
  }
246
223
 
247
224
} /* namespace auth_file */
248
225
 
249
 
DRIZZLE_PLUGIN(auth_file::init, NULL, auth_file::init_options);
 
226
DRIZZLE_DECLARE_PLUGIN
 
227
{
 
228
  DRIZZLE_VERSION_ID,
 
229
  "auth_file",
 
230
  "0.1",
 
231
  "Eric Day",
 
232
  N_("Authentication against a plain text file"),
 
233
  PLUGIN_LICENSE_GPL,
 
234
  auth_file::init,
 
235
  NULL,
 
236
  auth_file::init_options
 
237
}
 
238
DRIZZLE_DECLARE_PLUGIN_END;