MySQL 8.3.0
Source Code Documentation
http_auth_backend.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2023, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef ROUTER_HTTP_AUTH_BACKEND_INCLUDED
26#define ROUTER_HTTP_AUTH_BACKEND_INCLUDED
27
28#include <map>
29#include <string>
30#include <system_error>
31
32#include "my_rapidjson_size_t.h"
33
34#include <rapidjson/document.h>
35
36#include <sys/stat.h>
37#include <sys/types.h>
38
40
41/**
42 * Base class of all AuthBackends.
43 */
45 public:
46 HttpAuthBackend() = default;
47 HttpAuthBackend(const HttpAuthBackend &) = default;
51
52 /**
53 * authentication username with authdata against backend.
54 */
55 virtual std::error_code authenticate(const std::string &username,
56 const std::string &authdata) = 0;
57
58 /**
59 * destructor.
60 */
61 virtual ~HttpAuthBackend() = 0;
62};
63
64struct FileMeta {
65 using stat_res = std::pair<std::error_code, struct stat>;
66
67 FileMeta() : res{} {}
68 FileMeta(const std::string &filename) : res{stat(filename)} {}
69
70 /**
71 * calls the systems stat().
72 */
73 static stat_res stat(const std::string &filename);
74
76};
77
78/**
79 * check if a file was modified.
80 */
82 public:
83 FileModified() = default;
84 explicit FileModified(const FileMeta &meta) : meta_(meta) {}
85
86 /**
87 * check if two FileModified's are equal.
88 */
89 bool operator==(const FileModified &b) const;
90
91 private:
93};
94
95/**
96 * hashed key store.
97 *
98 * - each line contains username and auth-data, separated by colon
99 * - auth-data should be based on PHC
100 *
101 * PHC
102 * : `$<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]`
103 *
104 * id | name | supported
105 * -------------:|---------------|-----
106 * 1 | md5_crypt | never
107 * 2 | bcrypt | never
108 * 2a | bcrypt | no
109 * 2b | bcrypt | no
110 * 5 | sha256_crypt | yes
111 * 6 | sha512_crypt | yes
112 * pbkdf2-sha256 | pkbdf2_sha256 | no
113 * pbkdf2-sha512 | pkbdf2_sha512 | no
114 * scrypt | scrypt | no
115 * argon2 | argon2 | no
116 * bcrypt | bcrypt | no
117 *
118 * @see
119 * https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
120 */
122 : public HttpAuthBackend {
123 public:
124 using key_type = std::string;
125 using value_type = std::string;
126 using cache_type = std::string;
127
128 /**
129 * iterator
130 */
131 using iterator = std::map<key_type, value_type>::iterator;
132
133 /**
134 * const iterator
135 */
136 using const_iterator = std::map<key_type, value_type>::const_iterator;
137
138 /**
139 * replace cache with content from file.
140 */
141 std::error_code from_file(const std::string &filename);
142
143 /**
144 * replace cache with content of input-stream.
145 *
146 * @returns error-code
147 * @retval false when no error happened
148 */
149 std::error_code from_stream(std::istream &is);
150
151 /**
152 * write cache content to output-stream.
153 */
154 void to_stream(std::ostream &os);
155
156 /**
157 * remove username from credential cache.
158 */
159 size_t erase(const key_type &username) {
160 credentials_cache_.erase(username);
161 return credentials_.erase(username);
162 }
163
164 /**
165 * set username and password in cache.
166 *
167 * if username exists in cache, overwrite entry with password,
168 * otherwise create new entry for username
169 */
170 void set(const key_type &username, const value_type &authdata) {
171 auto res = credentials_.insert({username, authdata});
172 if (!res.second) {
173 auto elem_it = res.first;
174
175 elem_it->second = authdata;
176 }
177 }
178
179 /**
180 * find username in cache.
181 */
182 iterator find(const key_type &username) {
183 return credentials_.find(username);
184 }
185
186 /**
187 * find username in cache.
188 */
189 const_iterator find(const key_type &username) const {
190 return credentials_.find(username);
191 }
192
193 /**
194 * end iterator.
195 */
196 iterator end() noexcept { return credentials_.end(); }
197
198 /**
199 * const end iterator.
200 */
201 const_iterator end() const noexcept { return credentials_.end(); }
202
203 /**
204 * begin iterator.
205 */
206 iterator begin() noexcept { return credentials_.begin(); }
207
208 /**
209 * const begin iterator.
210 */
211 const_iterator begin() const noexcept { return credentials_.begin(); }
212
213 /**
214 * validate user and authdata against backend.
215 *
216 * @returns error
217 * @retval false no authentication error
218 */
219 std::error_code authenticate(const key_type &username,
220 const value_type &authdata) override;
221
222 private:
223 /**
224 * Calculate hash of plain-text password
225 *
226 * The hash generated by this function should be used at http basic
227 * authentication to speed up verification of the transferred credentials
228 * against account information stored in `passwd` file. There are no direct
229 * requirement how the hash should be calculated. Currently it uses following
230 * formula: HASH=SHA256(SHA256(plain-text-password)).
231 */
232 static std::string hash_password(const std::string &password);
233 std::error_code from_stream_(std::istream &is);
234
235 bool is_file_{false};
236 std::string filename_;
238
239 std::map<key_type, value_type> credentials_;
240 std::map<key_type, cache_type> credentials_cache_;
241};
242
243#endif
check if a file was modified.
Definition: http_auth_backend.h:81
FileModified(const FileMeta &meta)
Definition: http_auth_backend.h:84
FileModified()=default
bool operator==(const FileModified &b) const
check if two FileModified's are equal.
Definition: http_auth_backend.cc:69
FileMeta meta_
Definition: http_auth_backend.h:92
hashed key store.
Definition: http_auth_backend.h:122
iterator begin() noexcept
begin iterator.
Definition: http_auth_backend.h:206
std::string cache_type
Definition: http_auth_backend.h:126
const_iterator begin() const noexcept
const begin iterator.
Definition: http_auth_backend.h:211
const_iterator end() const noexcept
const end iterator.
Definition: http_auth_backend.h:201
iterator find(const key_type &username)
find username in cache.
Definition: http_auth_backend.h:182
const_iterator find(const key_type &username) const
find username in cache.
Definition: http_auth_backend.h:189
std::map< key_type, value_type > credentials_
Definition: http_auth_backend.h:239
size_t erase(const key_type &username)
remove username from credential cache.
Definition: http_auth_backend.h:159
std::string key_type
Definition: http_auth_backend.h:124
std::string value_type
Definition: http_auth_backend.h:125
void set(const key_type &username, const value_type &authdata)
set username and password in cache.
Definition: http_auth_backend.h:170
std::map< key_type, value_type >::iterator iterator
iterator
Definition: http_auth_backend.h:131
std::map< key_type, cache_type > credentials_cache_
Definition: http_auth_backend.h:240
iterator end() noexcept
end iterator.
Definition: http_auth_backend.h:196
FileModified file_meta_
Definition: http_auth_backend.h:237
std::string filename_
Definition: http_auth_backend.h:236
std::map< key_type, value_type >::const_iterator const_iterator
const iterator
Definition: http_auth_backend.h:136
Base class of all AuthBackends.
Definition: http_auth_backend.h:44
HttpAuthBackend(HttpAuthBackend &&)=default
HttpAuthBackend & operator=(const HttpAuthBackend &)=default
virtual ~HttpAuthBackend()=0
destructor.
HttpAuthBackend(const HttpAuthBackend &)=default
virtual std::error_code authenticate(const std::string &username, const std::string &authdata)=0
authentication username with authdata against backend.
HttpAuthBackend & operator=(HttpAuthBackend &&)=default
HttpAuthBackend()=default
#define HTTP_AUTH_BACKEND_LIB_EXPORT
Definition: http_auth_backend_lib_export.h:15
Define rapidjson::SizeType to be std::size_t.
static char * password
Definition: mysql_secure_installation.cc:57
int key_type
Definition: http_request.h:49
uint16_t value_type
Definition: vt100.h:183
const char * filename
Definition: pfs_example_component_population.cc:66
Definition: http_auth_backend.h:64
stat_res res
Definition: http_auth_backend.h:75
FileMeta()
Definition: http_auth_backend.h:67
std::pair< std::error_code, struct stat > stat_res
Definition: http_auth_backend.h:65
FileMeta(const std::string &filename)
Definition: http_auth_backend.h:68
static stat_res stat(const std::string &filename)
calls the systems stat().
Definition: http_auth_backend.cc:42