1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
#include "auth.h"
#include <crypt.h>
#include <string.h>
#include <stdexcept>
#include <iostream>
// crypt specified password
std::string Auth::generate(const std::string& pw)
{
struct crypt_data data;
memset((void *)&data, '\0', sizeof(data));
if (crypt_gensalt_rn("$6$", 2000, nullptr, 0, data.setting, sizeof(data.setting)) == nullptr)
throw std::runtime_error("Error on crypt_gensalt_r()");
strncpy(data.input, pw.data(), sizeof(data.input));
if (crypt_r(data.input, data.setting, &data) == nullptr)
throw std::runtime_error("Error on crypt_r()");
return data.output;
}
// validate specified password against crypted hash
bool Auth::validate(const std::string& crypted, const std::string& pw)
{
struct crypt_data data;
memset((void *)&data, '\0', sizeof(data));
size_t pos = crypted.find_last_of('$');
if (pos == crypted.npos) {
std::cerr << "Warning: Bad password hash configured (format)" << std::endl;
return false;
}
if (sizeof(data.setting) <= pos) {
std::cerr << "Warning: Bad password hash configured (salt size)" << std::endl;
return false;
}
memcpy(&data.setting, crypted.data(), pos);
strncpy(data.input, pw.data(), sizeof(data.input));
if (crypt_r(data.input, data.setting, &data) == nullptr) {
std::cerr << "Warning: Error on crypt_r()" << std::endl;
return false;
}
return crypted == data.output;
}
|