~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/auth_file/auth_file.cc

Merge Monty - Updates to pandora-build to support features of gcc 4.5.

Show diffs side-by-side

added added

removed removed

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