1 /*
2  * PgBouncer - Lightweight connection pooler for PostgreSQL.
3  *
4  * Copyright (c) 2007-2009  Marko Kreen, Skype Technologies OÜ
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * SCRAM support
21  */
22 
23 #include <usual/crypto/sha256.h>
24 
25 void free_scram_state(ScramState *scram_state);
26 
27 typedef enum PasswordType
28 {
29     PASSWORD_TYPE_PLAINTEXT = 0,
30     PASSWORD_TYPE_MD5,
31     PASSWORD_TYPE_SCRAM_SHA_256
32 } PasswordType;
33 
34 PasswordType get_password_type(const char *shadow_pass);
35 
36 /*
37  * Functions for communicating as a client with the server
38  */
39 
40 char *build_client_first_message(ScramState *scram_state);
41 char *build_client_final_message(ScramState *scram_state,
42 				 const PgUser *user,
43 				 const char *server_nonce,
44 				 const char *salt,
45 				 int saltlen,
46 				 int iterations);
47 
48 bool read_server_first_message(PgSocket *server, char *input,
49 			       char **server_nonce_p, char **salt_p, int *saltlen_p, int *iterations_p);
50 bool read_server_final_message(PgSocket *server, char *input, char *ServerSignature);
51 
52 bool verify_server_signature(ScramState *scram_state, const PgUser *user, const char *ServerSignature);
53 
54 
55 /*
56  * Functions for communicating as a server to the client
57  */
58 
59 bool read_client_first_message(PgSocket *client, char *input,
60 			       char *cbind_flag_p,
61 			       char **client_first_message_bare_p,
62 			       char **client_nonce_p);
63 
64 bool read_client_final_message(PgSocket *client, const uint8_t *raw_input, char *input,
65 			       const char **client_final_nonce_p,
66 			       char **proof_p);
67 
68 char *build_server_first_message(ScramState *scram_state,
69 				 const char *username, const char *stored_secret);
70 
71 char *build_server_final_message(ScramState *scram_state);
72 
73 bool verify_final_nonce(const ScramState *scram_state, const char *client_final_nonce);
74 
75 bool verify_client_proof(ScramState *state, const char *ClientProof);
76 
77 bool scram_verify_plain_password(PgSocket *client,
78 				 const char *username, const char *password,
79 				 const char *verifier);
80