]> git.lizzy.rs Git - dragonfireclient.git/blob - src/util/auth.cpp
HOTFIX: fix too agressive block culling
[dragonfireclient.git] / src / util / auth.cpp
1 /*
2 Minetest
3 Copyright (C) 2015 est31 <MTest31@outlook.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <algorithm>
21 #include <string>
22 #include "auth.h"
23 #include "base64.h"
24 #include "sha1.h"
25 #include "srp.h"
26 #include "string.h"
27 #include "debug.h"
28
29 // Get an sha-1 hash of the player's name combined with
30 // the password entered. That's what the server uses as
31 // their password. (Exception : if the password field is
32 // blank, we send a blank password - this is for backwards
33 // compatibility with password-less players).
34 std::string translatePassword(const std::string &name,
35         const std::string &password)
36 {
37         if (password.length() == 0)
38                 return "";
39
40         std::string slt = name + password;
41         SHA1 sha1;
42         sha1.addBytes(slt.c_str(), slt.length());
43         unsigned char *digest = sha1.getDigest();
44         std::string pwd = base64_encode(digest, 20);
45         free(digest);
46         return pwd;
47 }
48
49 void getSRPVerifier(const std::string &name,
50         const std::string &password, char **salt, size_t *salt_len,
51         char **bytes_v, size_t *len_v)
52 {
53         std::string n_name = lowercase(name);
54         SRP_Result res = srp_create_salted_verification_key(SRP_SHA256, SRP_NG_2048,
55                 n_name.c_str(), (const unsigned char *)password.c_str(),
56                 password.size(), (unsigned char **)salt, salt_len,
57                 (unsigned char **)bytes_v, len_v, NULL, NULL);
58         FATAL_ERROR_IF(res != SRP_OK, "Couldn't create salted SRP verifier");
59 }
60
61 // Get a db-ready SRP verifier
62 // If the salt param is NULL, one is automatically generated.
63 // Please free() it afterwards. You shouldn't use it for other purposes,
64 // as you will need the contents of salt_len too.
65 inline static std::string getSRPVerifier(const std::string &name,
66         const std::string &password, char ** salt, size_t salt_len)
67 {
68         char * bytes_v = NULL;
69         size_t len_v;
70         getSRPVerifier(name, password, salt, &salt_len,
71                 &bytes_v, &len_v);
72         assert(*salt); // usually, srp_create_salted_verification_key promises us to return SRP_ERR when *salt == NULL
73         std::string ret_val = encodeSRPVerifier(std::string(bytes_v, len_v),
74                 std::string(*salt, salt_len));
75         free(bytes_v);
76         return ret_val;
77 }
78
79 // Get a db-ready SRP verifier
80 std::string getSRPVerifier(const std::string &name,
81         const std::string &password)
82 {
83         char * salt = NULL;
84         std::string ret_val = getSRPVerifier(name,
85                 password, &salt, 0);
86         free(salt);
87         return ret_val;
88 }
89
90 // Get a db-ready SRP verifier
91 std::string getSRPVerifier(const std::string &name,
92         const std::string &password, const std::string &salt)
93 {
94         // The implementation won't change the salt if its set,
95         // therefore we can cast.
96         char *salt_cstr = (char *)salt.c_str();
97         return getSRPVerifier(name, password,
98                 &salt_cstr, salt.size());
99 }
100
101 // Make a SRP verifier db-ready
102 std::string encodeSRPVerifier(const std::string &verifier,
103         const std::string &salt)
104 {
105         std::ostringstream ret_str;
106         ret_str << "#1#"
107                 << base64_encode((unsigned char*) salt.c_str(), salt.size()) << "#"
108                 << base64_encode((unsigned char*) verifier.c_str(), verifier.size());
109         return ret_str.str();
110 }
111
112 bool decodeSRPVerifier(const std::string &enc_pwd,
113         std::string *salt, std::string *bytes_v)
114 {
115         std::vector<std::string> pwd_components = str_split(enc_pwd, '#');
116
117         if ((pwd_components.size() != 4)
118                         || (pwd_components[1] != "1") // 1 means srp
119                         || !base64_is_valid(pwd_components[2])
120                         || !base64_is_valid(pwd_components[3]))
121                 return false;
122
123         std::string salt_str = base64_decode(pwd_components[2]);
124         std::string bytes_v_str = base64_decode(pwd_components[3]);
125         *salt = salt_str;
126         *bytes_v = bytes_v_str;
127         return true;
128
129 }