PostgreSQL Source Code git master
Loading...
Searching...
No Matches
crypt.h File Reference
Include dependency graph for crypt.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MAX_ENCRYPTED_PASSWORD_LEN   (512)
 

Typedefs

typedef enum PasswordType PasswordType
 

Enumerations

enum  PasswordType { PASSWORD_TYPE_PLAINTEXT = 0 , PASSWORD_TYPE_MD5 , PASSWORD_TYPE_SCRAM_SHA_256 }
 

Functions

PasswordType get_password_type (const char *shadow_pass)
 
charencrypt_password (PasswordType target_type, const char *role, const char *password)
 
charget_role_password (const char *role, const char **logdetail)
 
int md5_crypt_verify (const char *role, const char *shadow_pass, const char *client_pass, const uint8 *md5_salt, int md5_salt_len, const char **logdetail)
 
int plain_crypt_verify (const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
 

Variables

PGDLLIMPORT int password_expiration_warning_threshold
 
PGDLLIMPORT bool md5_password_warnings
 

Macro Definition Documentation

◆ MAX_ENCRYPTED_PASSWORD_LEN

#define MAX_ENCRYPTED_PASSWORD_LEN   (512)

Definition at line 26 of file crypt.h.

Typedef Documentation

◆ PasswordType

Enumeration Type Documentation

◆ PasswordType

Enumerator
PASSWORD_TYPE_PLAINTEXT 
PASSWORD_TYPE_MD5 
PASSWORD_TYPE_SCRAM_SHA_256 

Definition at line 43 of file crypt.h.

44{
PasswordType
Definition crypt.h:44
@ PASSWORD_TYPE_PLAINTEXT
Definition crypt.h:45
@ PASSWORD_TYPE_SCRAM_SHA_256
Definition crypt.h:47
@ PASSWORD_TYPE_MD5
Definition crypt.h:46

Function Documentation

◆ encrypt_password()

char * encrypt_password ( PasswordType  target_type,
const char role,
const char password 
)
extern

Definition at line 182 of file crypt.c.

184{
186 char *encrypted_password = NULL;
187 const char *errstr = NULL;
188
190 {
191 /*
192 * Cannot convert an already-encrypted password from one format to
193 * another, so return it as it is.
194 */
196 }
197 else
198 {
199 switch (target_type)
200 {
203
204 if (!pg_md5_encrypt(password, (const uint8 *) role, strlen(role),
206 elog(ERROR, "password encryption failed: %s", errstr);
207 break;
208
211 break;
212
214 elog(ERROR, "cannot encrypt password with 'plaintext'");
215 break;
216 }
217 }
218
220
221 /*
222 * Valid password hashes may be very long, but we don't want to store
223 * anything that might need out-of-line storage, since de-TOASTing won't
224 * work during authentication because we haven't selected a database yet
225 * and cannot read pg_class. 512 bytes should be more than enough for all
226 * practical use, so fail for anything longer.
227 */
228 if (encrypted_password && /* keep compiler quiet */
230 {
231 /*
232 * We don't expect any of our own hashing routines to produce hashes
233 * that are too long.
234 */
236
239 errmsg("encrypted password is too long"),
240 errdetail("Encrypted passwords must be no longer than %d bytes.",
242 }
243
248 errmsg("setting an MD5-encrypted password"),
249 errdetail("MD5 password support is deprecated and will be removed in a future release of PostgreSQL."),
250 errhint("Refer to the PostgreSQL documentation for details about migrating to another password type.")));
251
252 return encrypted_password;
253}
char * pg_be_scram_build_secret(const char *password)
Definition auth-scram.c:481
uint8_t uint8
Definition c.h:622
#define Assert(condition)
Definition c.h:943
bool md5_password_warnings
Definition crypt.c:33
PasswordType get_password_type(const char *shadow_pass)
Definition crypt.c:155
#define MAX_ENCRYPTED_PASSWORD_LEN
Definition crypt.h:26
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
char * pstrdup(const char *in)
Definition mcxt.c:1910
void * palloc(Size size)
Definition mcxt.c:1390
#define MD5_PASSWD_LEN
Definition md5.h:26
bool pg_md5_encrypt(const char *passwd, const uint8 *salt, size_t salt_len, char *buf, const char **errstr)
Definition md5_common.c:145
static char * errmsg
static int fb(int x)
static char * password
Definition streamutil.c:51

References Assert, elog, ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, fb(), get_password_type(), MAX_ENCRYPTED_PASSWORD_LEN, MD5_PASSWD_LEN, md5_password_warnings, palloc(), password, PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, PASSWORD_TYPE_SCRAM_SHA_256, pg_be_scram_build_secret(), pg_md5_encrypt(), pstrdup(), and WARNING.

Referenced by AlterRole(), and CreateRole().

◆ get_password_type()

PasswordType get_password_type ( const char shadow_pass)
extern

Definition at line 155 of file crypt.c.

156{
157 char *encoded_salt;
158 int iterations;
159 int key_length = 0;
160 pg_cryptohash_type hash_type;
163
164 if (strncmp(shadow_pass, "md5", 3) == 0 &&
167 return PASSWORD_TYPE_MD5;
168 if (parse_scram_secret(shadow_pass, &iterations, &hash_type, &key_length,
172}
bool parse_scram_secret(const char *secret, int *iterations, pg_cryptohash_type *hash_type, int *key_length, char **salt, uint8 *stored_key, uint8 *server_key)
Definition auth-scram.c:598
pg_cryptohash_type
Definition cryptohash.h:20
#define MD5_PASSWD_CHARSET
Definition md5.h:25
#define SCRAM_MAX_KEY_LEN
int iterations

References fb(), iterations, MD5_PASSWD_CHARSET, MD5_PASSWD_LEN, parse_scram_secret(), PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, PASSWORD_TYPE_SCRAM_SHA_256, and SCRAM_MAX_KEY_LEN.

Referenced by AlterRole(), CheckPWChallengeAuth(), CreateRole(), encrypt_password(), md5_crypt_verify(), plain_crypt_verify(), RenameRole(), and scram_init().

◆ get_role_password()

char * get_role_password ( const char role,
const char **  logdetail 
)
extern

Definition at line 45 of file crypt.c.

46{
49 Datum datum;
50 bool isnull;
51 char *shadow_pass;
52
53 /* Get role info from pg_authid */
56 {
57 *logdetail = psprintf(_("Role \"%s\" does not exist."),
58 role);
59 return NULL; /* no such user */
60 }
61
64 if (isnull)
65 {
67 *logdetail = psprintf(_("User \"%s\" has no password assigned."),
68 role);
69 return NULL; /* user has no password */
70 }
72
75 if (!isnull)
77
79
80 /*
81 * Password OK, but check to be sure we are not past rolvaliduntil or
82 * password_expiration_warning_threshold.
83 */
84 if (!isnull)
85 {
88
89 /*
90 * If we're past rolvaliduntil, the connection attempt should fail, so
91 * update logdetail and return NULL.
92 */
93 if (vuntil < now)
94 {
95 *logdetail = psprintf(_("User \"%s\" has an expired password."),
96 role);
97 return NULL;
98 }
99
100 /*
101 * If we're past the warning threshold, the connection attempt should
102 * succeed, but we still want to emit a warning. To do so, we queue
103 * the warning message using StoreConnectionWarning() so that it will
104 * be emitted at the end of InitPostgres(), and we return normally.
105 */
107 {
108 MemoryContext oldcontext;
109 int days;
110 int hours;
111 int minutes;
112 char *warning;
113 char *detail;
114
116
120
121 warning = pstrdup(_("role password will expire soon"));
122
123 if (days > 0)
124 detail = psprintf(ngettext("The password for role \"%s\" will expire in %d day.",
125 "The password for role \"%s\" will expire in %d days.",
126 days),
127 role, days);
128 else if (hours > 0)
129 detail = psprintf(ngettext("The password for role \"%s\" will expire in %d hour.",
130 "The password for role \"%s\" will expire in %d hours.",
131 hours),
132 role, hours);
133 else if (minutes > 0)
134 detail = psprintf(ngettext("The password for role \"%s\" will expire in %d minute.",
135 "The password for role \"%s\" will expire in %d minutes.",
136 minutes),
137 role, minutes);
138 else
139 detail = psprintf(_("The password for role \"%s\" will expire in less than 1 minute."),
140 role);
141
143
144 MemoryContextSwitchTo(oldcontext);
145 }
146 }
147
148 return shadow_pass;
149}
const char *const days[]
Definition datetime.c:85
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
#define TextDatumGetCString(d)
Definition builtins.h:99
#define ngettext(s, p, n)
Definition c.h:1270
uint64_t uint64
Definition c.h:625
int password_expiration_warning_threshold
Definition crypt.c:30
int64 TimestampTz
Definition timestamp.h:39
#define USECS_PER_HOUR
Definition timestamp.h:132
#define USECS_PER_DAY
Definition timestamp.h:131
#define USECS_PER_SEC
Definition timestamp.h:134
#define USECS_PER_MINUTE
Definition timestamp.h:133
#define _(x)
Definition elog.c:96
#define HeapTupleIsValid(tuple)
Definition htup.h:78
MemoryContext TopMemoryContext
Definition mcxt.c:167
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
uint64_t Datum
Definition postgres.h:70
#define PointerGetDatum(X)
Definition postgres.h:354
void StoreConnectionWarning(char *msg, char *detail, ConnectionWarningFilter filter)
Definition postinit.c:1517
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
static uint64 TimestampDifferenceMicroseconds(TimestampTz start_time, TimestampTz stop_time)
Definition timestamp.h:90
static TimestampTz DatumGetTimestampTz(Datum X)
Definition timestamp.h:34
static void static void static void warning(const char *const string,...) pg_attribute_printf(1
Definition zic.c:533

References _, DatumGetTimestampTz(), days, fb(), GetCurrentTimestamp(), HeapTupleIsValid, MemoryContextSwitchTo(), ngettext, now(), password_expiration_warning_threshold, PointerGetDatum, psprintf(), pstrdup(), ReleaseSysCache(), SearchSysCache1(), StoreConnectionWarning(), SysCacheGetAttr(), TextDatumGetCString, TimestampDifferenceMicroseconds(), TopMemoryContext, USECS_PER_DAY, USECS_PER_HOUR, USECS_PER_MINUTE, USECS_PER_SEC, and warning().

Referenced by CheckPasswordAuth(), and CheckPWChallengeAuth().

◆ md5_crypt_verify()

int md5_crypt_verify ( const char role,
const char shadow_pass,
const char client_pass,
const uint8 md5_salt,
int  md5_salt_len,
const char **  logdetail 
)
extern

Definition at line 267 of file crypt.c.

271{
272 int retval;
273 char crypt_pwd[MD5_PASSWD_LEN + 1];
274 const char *errstr = NULL;
275
276 Assert(md5_salt_len > 0);
277
279 {
280 /* incompatible password hash format. */
281 *logdetail = psprintf(_("User \"%s\" has a password that cannot be used with MD5 authentication."),
282 role);
283 return STATUS_ERROR;
284 }
285
286 /*
287 * Compute the correct answer for the MD5 challenge.
288 */
289 /* stored password already encrypted, only do salt */
290 if (!pg_md5_encrypt(shadow_pass + strlen("md5"),
292 crypt_pwd, &errstr))
293 {
294 *logdetail = errstr;
295 return STATUS_ERROR;
296 }
297
300 {
301 MemoryContext oldcontext;
302 char *warning;
303 char *detail;
304
305 retval = STATUS_OK;
306
308
309 warning = pstrdup(_("authenticated with an MD5-encrypted password"));
310 detail = pstrdup(_("MD5 password support is deprecated and will be removed in a future release of PostgreSQL."));
312
313 MemoryContextSwitchTo(oldcontext);
314 }
315 else
316 {
317 *logdetail = psprintf(_("Password does not match for user \"%s\"."),
318 role);
319 retval = STATUS_ERROR;
320 }
321
322 return retval;
323}
#define STATUS_OK
Definition c.h:1258
#define STATUS_ERROR
Definition c.h:1259
static bool md5_password_warning_enabled(void)
Definition crypt.c:326
int timingsafe_bcmp(const void *b1, const void *b2, size_t n)

References _, Assert, fb(), get_password_type(), MD5_PASSWD_LEN, md5_password_warning_enabled(), MemoryContextSwitchTo(), PASSWORD_TYPE_MD5, pg_md5_encrypt(), psprintf(), pstrdup(), STATUS_ERROR, STATUS_OK, StoreConnectionWarning(), timingsafe_bcmp(), TopMemoryContext, and warning().

Referenced by CheckMD5Auth().

◆ plain_crypt_verify()

int plain_crypt_verify ( const char role,
const char shadow_pass,
const char client_pass,
const char **  logdetail 
)
extern

Definition at line 342 of file crypt.c.

345{
347 const char *errstr = NULL;
348
349 /*
350 * Client sent password in plaintext. If we have an MD5 hash stored, hash
351 * the password the client sent, and compare the hashes. Otherwise
352 * compare the plaintext passwords directly.
353 */
355 {
360 {
361 return STATUS_OK;
362 }
363 else
364 {
365 *logdetail = psprintf(_("Password does not match for user \"%s\"."),
366 role);
367 return STATUS_ERROR;
368 }
369 break;
370
373 (const uint8 *) role,
374 strlen(role),
376 &errstr))
377 {
378 *logdetail = errstr;
379 return STATUS_ERROR;
380 }
383 return STATUS_OK;
384 else
385 {
386 *logdetail = psprintf(_("Password does not match for user \"%s\"."),
387 role);
388 return STATUS_ERROR;
389 }
390 break;
391
393
394 /*
395 * We never store passwords in plaintext, so this shouldn't
396 * happen.
397 */
398 break;
399 }
400
401 /*
402 * This shouldn't happen. Plain "password" authentication is possible
403 * with any kind of stored password hash.
404 */
405 *logdetail = psprintf(_("Password of user \"%s\" is in unrecognized format."),
406 role);
407 return STATUS_ERROR;
408}
bool scram_verify_plain_password(const char *username, const char *password, const char *secret)
Definition auth-scram.c:521

References _, fb(), get_password_type(), MD5_PASSWD_LEN, PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, PASSWORD_TYPE_SCRAM_SHA_256, pg_md5_encrypt(), psprintf(), scram_verify_plain_password(), STATUS_ERROR, STATUS_OK, and timingsafe_bcmp().

Referenced by AlterRole(), check_password(), CheckPasswordAuth(), and CreateRole().

Variable Documentation

◆ md5_password_warnings

PGDLLIMPORT bool md5_password_warnings
extern

Definition at line 33 of file crypt.c.

Referenced by encrypt_password(), and md5_password_warning_enabled().

◆ password_expiration_warning_threshold

PGDLLIMPORT int password_expiration_warning_threshold
extern

Definition at line 30 of file crypt.c.

Referenced by get_role_password().