summaryrefslogtreecommitdiffhomepage
path: root/auth.cpp
blob: c9c9765da62241fc9ad2b40bafcc70b411c6d7ec (plain)
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;
}