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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#ifndef PASSWORD_SCHEME_H
#define PASSWORD_SCHEME_H
#define AUTH_LOG_MSG_PASSWORD_MISMATCH "Password mismatch"
struct hash_method;
enum password_encoding {
PW_ENCODING_NONE,
PW_ENCODING_BASE64,
PW_ENCODING_HEX
};
struct password_generate_params {
const char *user;
unsigned int rounds;
};
struct password_scheme {
const char *name;
enum password_encoding default_encoding;
/* If non-zero, this is the expected raw password length.
It can be used to automatically detect encoding between
hex and base64 encoded passwords. */
unsigned int raw_password_len;
int (*password_verify)(const char *plaintext,
const struct password_generate_params *params,
const unsigned char *raw_password, size_t size,
const char **error_r);
void (*password_generate)(const char *plaintext,
const struct password_generate_params *params,
const unsigned char **raw_password_r,
size_t *size_r);
};
ARRAY_DEFINE_TYPE(password_scheme_p, const struct password_scheme *);
void password_schemes_get(ARRAY_TYPE(password_scheme_p) *schemes_r);
extern unsigned int password_scheme_encryption_rounds;
/* Returns 1 = matched, 0 = didn't match, -1 = unknown scheme or invalid
raw_password */
int password_verify(const char *plaintext,
const struct password_generate_params *params,
const char *scheme,
const unsigned char *raw_password, size_t size,
const char **error_r);
/* Extracts scheme from password, or returns NULL if it isn't found.
If auth_request is given, it's used for debug logging. */
const char *password_get_scheme(const char **password);
/* Decode encoded (base64/hex) password to raw form. Returns 1 if ok,
0 if scheme is unknown, -1 if password is invalid. */
int password_decode(const char *password, const char *scheme,
const unsigned char **raw_password_r, size_t *size_r,
const char **error_r);
/* Create password with wanted scheme out of plaintext password and username.
Potential base64/hex directives are ignored in scheme. Returns FALSE if
the scheme is unknown. */
bool password_generate(const char *plaintext,
const struct password_generate_params *params,
const char *scheme,
const unsigned char **raw_password_r, size_t *size_r);
/* Like above, but generate encoded passwords. If hex/base64 directive isn't
specified in the scheme, the default encoding for the scheme is used.
Returns FALSE if the scheme is unknown. */
bool password_generate_encoded(const char *plaintext,
const struct password_generate_params *params,
const char *scheme, const char **password_r);
/* Returns TRUE if schemes are equivalent. */
bool password_scheme_is_alias(const char *scheme1, const char *scheme2);
/* Try to detect in which scheme crypted password is. Returns the scheme name
or NULL if nothing was found. */
const char *
password_scheme_detect(const char *plain_password, const char *crypted_password,
const struct password_generate_params *params);
void password_scheme_register(const struct password_scheme *scheme);
void password_scheme_unregister(const struct password_scheme *scheme);
void password_schemes_init(void);
void password_schemes_deinit(void);
/* some password schemes/algorithms supports a variable number of
encryption rounds. */
void password_set_encryption_rounds(unsigned int rounds);
/* INTERNAL: */
const char *password_generate_salt(size_t len);
const char *password_generate_md5_crypt(const char *pw, const char *salt);
int password_generate_otp(const char *pw, const char *state_data,
unsigned int algo, const char **result_r)
ATTR_NULL(2);
int crypt_verify(const char *plaintext,
const struct password_generate_params *params,
const unsigned char *raw_password, size_t size,
const char **error_r);
int scram_scheme_parse(const struct hash_method *hmethod, const char *name,
const unsigned char *credentials, size_t size,
unsigned int *iter_count_r, const char **salt_r,
unsigned char stored_key_r[],
unsigned char server_key_r[], const char **error_r);
int scram_verify(const struct hash_method *hmethod, const char *scheme_name,
const char *plaintext, const unsigned char *raw_password,
size_t size, const char **error_r);
void scram_generate(const struct hash_method *hmethod, const char *plaintext,
const unsigned char **raw_password_r, size_t *size_r);
int scram_sha1_verify(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char *raw_password, size_t size,
const char **error_r ATTR_UNUSED);
void scram_sha1_generate(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char **raw_password_r, size_t *size_r);
int scram_sha256_verify(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char *raw_password, size_t size,
const char **error_r);
void scram_sha256_generate(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char **raw_password_r, size_t *size_r);
void pbkdf2_generate(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char **raw_password_r, size_t *size_r);
int pbkdf2_verify(const char *plaintext,
const struct password_generate_params *params ATTR_UNUSED,
const unsigned char *raw_password, size_t size,
const char **error_r);
/* check which of the algorithms Blowfish, SHA-256 and SHA-512 are
supported by the used libc's/glibc's crypt() */
void password_scheme_register_crypt(void);
#ifdef HAVE_LIBSODIUM
void password_scheme_register_sodium(void);
#endif
#endif
|