pwn 0.4.633 → 0.4.634

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8202712f33c7983c86ab5a3573d11619768e5c0903cd56deb5f381d8d906942e
4
- data.tar.gz: e47ac68f8fba7fa2778a8562d67f1e1be5255e93f5e78654aeafa9bd39587f1a
3
+ metadata.gz: 0fb832accac7268a584655b8dba3fb618f58cc8fd7ea9151897c1a164a3d0c23
4
+ data.tar.gz: d87a84d5411d8ab60f526f47a7e8f915358fa7528fc5a9ab741db2d00d8a3744
5
5
  SHA512:
6
- metadata.gz: f8e5fb6a056ba0770a28c21dd3d21f2873d68ac5b9d98179731bd744822870c63225efd17156022f68fe8b705bb8034a6d642c28b04f4d9d813f49b8213a94be
7
- data.tar.gz: 773b6016bb6faea3fd8043d0e82b574a00878704e656dc840311db1f0358b03c1c9b0ae764c30dec410a249798b7b173a1415d8af905e5307b7402b4aad5ef04
6
+ metadata.gz: f59ad00b51892108357b9b6daa0a13c4eef91b1bb31e95d0ab11a2fa31baaee93a83b8415b13c52cdfd40f3edd0649eb73745be549ae008f66e0187a415ff9e8
7
+ data.tar.gz: 86b721306e332d7a3ac2feef0bd583ef88806c86ce7278c5b9ce3a106eb74733cecdf50c73b2d40b60af1f32226246a30bc6e70d5d7d51d26be968679084bc0d
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ rvm use ruby-3.2.2@pwn
37
37
  $ rvm list gemsets
38
38
  $ gem install --verbose pwn
39
39
  $ pwn
40
- pwn[v0.4.633]:001 >>> PWN.help
40
+ pwn[v0.4.634]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](https://youtu.be/G7iLUY4FzsI)
@@ -52,7 +52,7 @@ $ rvm use ruby-3.2.2@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.4.633]:001 >>> PWN.help
55
+ pwn[v0.4.634]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
 
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.4.633'
4
+ VERSION = '0.4.634'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.633
4
+ version: 0.4.634
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -1128,7 +1128,6 @@ executables:
1128
1128
  extensions: []
1129
1129
  extra_rdoc_files: []
1130
1130
  files:
1131
- - ".each do |bytes_matched|"
1132
1131
  - ".github/FUNDING.yml"
1133
1132
  - ".github/ISSUE_TEMPLATE/bug_report.md"
1134
1133
  - ".gitignore"
@@ -1,51 +0,0 @@
1
- => [["static const char *hdr2hex(const struct MBuf *data, char *buf, unsigned buflen)\n{\n\tconst uint8_t *bin = data->data + data->read_pos;\n\tunsigned int dlen;\n\n\tdlen = mbuf_avail_for_read(data);\n\treturn bin2hex(bin, dlen, buf, buflen);\n}",
2
- "\n\tconst uint8_t *bin = data->data + data->read_pos;\n\tunsigned int dlen;\n\n\tdlen = mbuf_avail_for_read(data);\n\treturn bin2hex(bin, dlen, buf, buflen);\n",
3
- "}"],
4
- ["PgDatabase *prepare_auth_database(PgSocket *client)\n{\n\tPgDatabase *auth_db = NULL;\n\tconst char *auth_dbname = client->db->auth_dbname ? client->db->auth_dbname : cf_auth_dbname;\n\n\tif (!auth_dbname)\n\t\treturn client->db;\n\n\tauth_db = find_database(auth_dbname);\n\tif (!auth_db) {\n\t\tslog_error(client, \"authentication database \\\"%s\\\" is not configured.\", auth_dbname);\n\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\treturn NULL;\n\t}\n\n\tif (auth_db->db_disabled) {\n\t\tdisconnect_client(\n\t\t\tclient,\n\t\t\ttrue,\n\t\t\t\"authentication database \\\"%s\\\" is disabled\",\n\t\t\tauth_dbname);\n\t\treturn NULL;\n\t}\n\n\treturn auth_db;\n}",
5
- "\n\tPgDatabase *auth_db = NULL;\n\tconst char *auth_dbname = client->db->auth_dbname ? client->db->auth_dbname : cf_auth_dbname;\n\n\tif (!auth_dbname)\n\t\treturn client->db;\n\n\tauth_db = find_database(auth_dbname);\n\tif (!auth_db) {\n\t\tslog_error(client, \"authentication database \\\"%s\\\" is not configured.\", auth_dbname);\n\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\treturn NULL;\n\t}\n\n\tif (auth_db->db_disabled) {\n\t\tdisconnect_client(\n\t\t\tclient,\n\t\t\ttrue,\n\t\t\t\"authentication database \\\"%s\\\" is disabled\",\n\t\t\tauth_dbname);\n\t\treturn NULL;\n\t}\n\n\treturn auth_db;\n",
6
- "}"],
7
- ["static bool check_client_passwd(PgSocket *client, const char *passwd)\n{\n\tPgUser *user = client->login_user;\n\tint auth_type = client->client_auth_type;\n\n\tif (user->mock_auth)\n\t\treturn false;\n\n\t/* disallow empty passwords */\n\tif (!*user->passwd)\n\t\treturn false;\n\n\tswitch (auth_type) {\n\tcase AUTH_PLAIN:\n\t\tswitch (get_password_type(user->passwd)) {\n\t\tcase PASSWORD_TYPE_PLAINTEXT:\n\t\t\treturn strcmp(user->passwd, passwd) == 0;\n\t\tcase PASSWORD_TYPE_MD5: {\n\t\t\tchar md5[MD5_PASSWD_LEN + 1];\n\t\t\tpg_md5_encrypt(passwd, user->name, strlen(user->name), md5);\n\t\t\treturn strcmp(user->passwd, md5) == 0;\n\t\t}\n\t\tcase PASSWORD_TYPE_SCRAM_SHA_256:\n\t\t\treturn scram_verify_plain_password(client, user->name, passwd, user->passwd);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\tcase AUTH_MD5: {\n\t\tchar *stored_passwd;\n\t\tchar md5[MD5_PASSWD_LEN + 1];\n\n\t\tif (strlen(passwd) != MD5_PASSWD_LEN)\n\t\t\treturn false;\n\n\t\t/*\n\t\t * The client sends\n\t\t * 'md5'+md5(md5(password+username)+salt). The stored\n\t\t * password is either 'md5'+md5(password+username) or\n\t\t * plain text. If the latter, we compute the inner\n\t\t * md5() call first.\n\t\t */\n\t\tif (get_password_type(user->passwd) == PASSWORD_TYPE_PLAINTEXT) {\n\t\t\tpg_md5_encrypt(user->passwd, user->name, strlen(user->name), md5);\n\t\t\tstored_passwd = md5;\n\t\t} else {\n\t\t\tstored_passwd = user->passwd;\n\t\t}\n\t\tpg_md5_encrypt(stored_passwd + 3, (char *)client->tmp_login_salt, 4, md5);\n\t\treturn strcmp(md5, passwd) == 0;\n\t}\n\t}\n\treturn false;\n}",
8
- "\n\tPgUser *user = client->login_user;\n\tint auth_type = client->client_auth_type;\n\n\tif (user->mock_auth)\n\t\treturn false;\n\n\t/* disallow empty passwords */\n\tif (!*user->passwd)\n\t\treturn false;\n\n\tswitch (auth_type) {\n\tcase AUTH_PLAIN:\n\t\tswitch (get_password_type(user->passwd)) {\n\t\tcase PASSWORD_TYPE_PLAINTEXT:\n\t\t\treturn strcmp(user->passwd, passwd) == 0;\n\t\tcase PASSWORD_TYPE_MD5: {\n\t\t\tchar md5[MD5_PASSWD_LEN + 1];\n\t\t\tpg_md5_encrypt(passwd, user->name, strlen(user->name), md5);\n\t\t\treturn strcmp(user->passwd, md5) == 0;\n\t\t}\n\t\tcase PASSWORD_TYPE_SCRAM_SHA_256:\n\t\t\treturn scram_verify_plain_password(client, user->name, passwd, user->passwd);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\tcase AUTH_MD5: {\n\t\tchar *stored_passwd;\n\t\tchar md5[MD5_PASSWD_LEN + 1];\n\n\t\tif (strlen(passwd) != MD5_PASSWD_LEN)\n\t\t\treturn false;\n\n\t\t/*\n\t\t * The client sends\n\t\t * 'md5'+md5(md5(password+username)+salt). The stored\n\t\t * password is either 'md5'+md5(password+username) or\n\t\t * plain text. If the latter, we compute the inner\n\t\t * md5() call first.\n\t\t */\n\t\tif (get_password_type(user->passwd) == PASSWORD_TYPE_PLAINTEXT) {\n\t\t\tpg_md5_encrypt(user->passwd, user->name, strlen(user->name), md5);\n\t\t\tstored_passwd = md5;\n\t\t} else {\n\t\t\tstored_passwd = user->passwd;\n\t\t}\n\t\tpg_md5_encrypt(stored_passwd + 3, (char *)client->tmp_login_salt, 4, md5);\n\t\treturn strcmp(md5, passwd) == 0;\n\t}\n\t}\n\treturn false;\n",
9
- "}"],
10
- ["static bool send_client_authreq(PgSocket *client)\n{\n\tint res;\n\tint auth_type = client->client_auth_type;\n\n\tif (auth_type == AUTH_MD5) {\n\t\tuint8_t saltlen = 4;\n\t\tget_random_bytes((void*)client->tmp_login_salt, saltlen);\n\t\tSEND_generic(res, client, 'R', \"ib\", AUTH_MD5, client->tmp_login_salt, saltlen);\n\t} else if (auth_type == AUTH_PLAIN || auth_type == AUTH_PAM) {\n\t\tSEND_generic(res, client, 'R', \"i\", AUTH_PLAIN);\n\t} else if (auth_type == AUTH_SCRAM_SHA_256) {\n\t\tSEND_generic(res, client, 'R', \"iss\", AUTH_SASL, \"SCRAM-SHA-256\", \"\");\n\t} else {\n\t\treturn false;\n\t}\n\n\tif (!res) {\n\t slog_noise(client, \"No authentication response received\");\n\t\tdisconnect_client(client, false, \"failed to send auth req\");\n\t} else {\n\t\tslog_noise(client, \"Auth request sent successfully\");\n\t}\n\treturn res;\n}",
11
- "\n\tint res;\n\tint auth_type = client->client_auth_type;\n\n\tif (auth_type == AUTH_MD5) {\n\t\tuint8_t saltlen = 4;\n\t\tget_random_bytes((void*)client->tmp_login_salt, saltlen);\n\t\tSEND_generic(res, client, 'R', \"ib\", AUTH_MD5, client->tmp_login_salt, saltlen);\n\t} else if (auth_type == AUTH_PLAIN || auth_type == AUTH_PAM) {\n\t\tSEND_generic(res, client, 'R', \"i\", AUTH_PLAIN);\n\t} else if (auth_type == AUTH_SCRAM_SHA_256) {\n\t\tSEND_generic(res, client, 'R', \"iss\", AUTH_SASL, \"SCRAM-SHA-256\", \"\");\n\t} else {\n\t\treturn false;\n\t}\n\n\tif (!res) {\n\t slog_noise(client, \"No authentication response received\");\n\t\tdisconnect_client(client, false, \"failed to send auth req\");\n\t} else {\n\t\tslog_noise(client, \"Auth request sent successfully\");\n\t}\n\treturn res;\n",
12
- "}"],
13
- ["static void start_auth_query(PgSocket *client, const char *username)\n{\n\tint res;\n\tPktBuf *buf;\n\n\t/* have to fetch user info from db */\n\tPgDatabase *auth_db = prepare_auth_database(client);\n\tif (!auth_db)\n\t\treturn;\n\n\tclient->pool = get_pool(auth_db, client->db->auth_user);\n\tif (!find_server(client)) {\n\t\tclient->wait_for_user_conn = true;\n\t\treturn;\n\t}\n\tslog_noise(client, \"doing auth_conn query\");\n\tclient->wait_for_user_conn = false;\n\tclient->wait_for_user = true;\n\tif (!sbuf_pause(&client->sbuf)) {\n\t\trelease_server(client->link);\n\t\tdisconnect_client(client, true, \"pause failed\");\n\t\treturn;\n\t}\n\tclient->link->ready = false;\n\n\tres = 0;\n\tbuf = pktbuf_dynamic(512);\n\tif (buf) {\n\t\tpktbuf_write_ExtQuery(buf, cf_auth_query, 1, username);\n\t\tres = pktbuf_send_immediate(buf, client->link);\n\t\tpktbuf_free(buf);\n\t\t/*\n\t\t * Should do instead:\n\t\t * res = pktbuf_send_queued(buf, client->link);\n\t\t * but that needs better integration with SBuf.\n\t\t */\n\t}\n\tif (!res)\n\t\tdisconnect_server(client->link, false, \"unable to send auth_query\");\n\tclient->expect_rfq_count++;\n}",
14
- "\n\tint res;\n\tPktBuf *buf;\n\n\t/* have to fetch user info from db */\n\tPgDatabase *auth_db = prepare_auth_database(client);\n\tif (!auth_db)\n\t\treturn;\n\n\tclient->pool = get_pool(auth_db, client->db->auth_user);\n\tif (!find_server(client)) {\n\t\tclient->wait_for_user_conn = true;\n\t\treturn;\n\t}\n\tslog_noise(client, \"doing auth_conn query\");\n\tclient->wait_for_user_conn = false;\n\tclient->wait_for_user = true;\n\tif (!sbuf_pause(&client->sbuf)) {\n\t\trelease_server(client->link);\n\t\tdisconnect_client(client, true, \"pause failed\");\n\t\treturn;\n\t}\n\tclient->link->ready = false;\n\n\tres = 0;\n\tbuf = pktbuf_dynamic(512);\n\tif (buf) {\n\t\tpktbuf_write_ExtQuery(buf, cf_auth_query, 1, username);\n\t\tres = pktbuf_send_immediate(buf, client->link);\n\t\tpktbuf_free(buf);\n\t\t/*\n\t\t * Should do instead:\n\t\t * res = pktbuf_send_queued(buf, client->link);\n\t\t * but that needs better integration with SBuf.\n\t\t */\n\t}\n\tif (!res)\n\t\tdisconnect_server(client->link, false, \"unable to send auth_query\");\n\tclient->expect_rfq_count++;\n",
15
- "}"],
16
- ["static bool login_via_cert(PgSocket *client)\n{\n\tstruct tls *tls = client->sbuf.tls;\n\n\tif (!tls) {\n\t\tslog_error(client, \"TLS connection required\");\n\t\tgoto fail;\n\t}\n\tif (!tls_peer_cert_provided(client->sbuf.tls)) {\n\t\tslog_error(client, \"TLS client certificate required\");\n\t\tgoto fail;\n\t}\n\tif (client->login_user->mock_auth)\n\t\tgoto fail;\n\n\tlog_debug(\"TLS cert login: %s\", tls_peer_cert_subject(client->sbuf.tls));\n\tif (!tls_peer_cert_contains_name(client->sbuf.tls, client->login_user->name)) {\n\t\tslog_error(client, \"TLS certificate name mismatch\");\n\t\tgoto fail;\n\t}\n\n\t/* login successful */\n\treturn finish_client_login(client);\nfail:\n\tdisconnect_client(client, true, \"certificate authentication failed\");\n\treturn false;\n}",
17
- "\n\tstruct tls *tls = client->sbuf.tls;\n\n\tif (!tls) {\n\t\tslog_error(client, \"TLS connection required\");\n\t\tgoto fail;\n\t}\n\tif (!tls_peer_cert_provided(client->sbuf.tls)) {\n\t\tslog_error(client, \"TLS client certificate required\");\n\t\tgoto fail;\n\t}\n\tif (client->login_user->mock_auth)\n\t\tgoto fail;\n\n\tlog_debug(\"TLS cert login: %s\", tls_peer_cert_subject(client->sbuf.tls));\n\tif (!tls_peer_cert_contains_name(client->sbuf.tls, client->login_user->name)) {\n\t\tslog_error(client, \"TLS certificate name mismatch\");\n\t\tgoto fail;\n\t}\n\n\t/* login successful */\n\treturn finish_client_login(client);\nfail:\n\tdisconnect_client(client, true, \"certificate authentication failed\");\n\treturn false;\n",
18
- "}"],
19
- ["static bool login_as_unix_peer(PgSocket *client)\n{\n\tif (!pga_is_unix(&client->remote_addr))\n\t\tgoto fail;\n\tif (client->login_user->mock_auth)\n\t\tgoto fail;\n\tif (!check_unix_peer_name(sbuf_socket(&client->sbuf), client->login_user->name))\n\t\tgoto fail;\n\treturn finish_client_login(client);\nfail:\n\tdisconnect_client(client, true, \"unix socket login rejected\");\n\treturn false;\n}",
20
- "\n\tif (!pga_is_unix(&client->remote_addr))\n\t\tgoto fail;\n\tif (client->login_user->mock_auth)\n\t\tgoto fail;\n\tif (!check_unix_peer_name(sbuf_socket(&client->sbuf), client->login_user->name))\n\t\tgoto fail;\n\treturn finish_client_login(client);\nfail:\n\tdisconnect_client(client, true, \"unix socket login rejected\");\n\treturn false;\n",
21
- "}"],
22
- ["static bool finish_set_pool(PgSocket *client, bool takeover)\n{\n\tbool ok = false;\n\tint auth;\n\n\tif (!client->login_user->mock_auth && !client->db->fake) {\n\t\tPgUser *pool_user;\n\n\t\tif (client->db->forced_user)\n\t\t\tpool_user = client->db->forced_user;\n\t\telse\n\t\t\tpool_user = client->login_user;\n\n\t\tclient->pool = get_pool(client->db, pool_user);\n\t\tif (!client->pool) {\n\t\t\tdisconnect_client(client, true, \"no memory for pool\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (cf_log_connections) {\n\t\tif (client->sbuf.tls) {\n\t\t\tchar infobuf[96] = \"\";\n\t\t\ttls_get_connection_info(client->sbuf.tls, infobuf, sizeof infobuf);\n\t\t\tslog_info(client, \"login attempt: db=%s user=%s tls=%s\",\n\t\t\t\t client->db->name, client->login_user->name, infobuf);\n\t\t} else {\n\t\t\tslog_info(client, \"login attempt: db=%s user=%s tls=no\",\n\t\t\t\t client->db->name, client->login_user->name);\n\t\t}\n\t}\n\n\tif (takeover)\n\t\treturn true;\n\n\tif (client->pool && client->pool->db->admin) {\n\t\tif (!admin_post_login(client))\n\t\t\treturn false;\n\t}\n\n\tif (client->own_user)\n\t\treturn finish_client_login(client);\n\n\tauth = cf_auth_type;\n\tif (auth == AUTH_HBA) {\n\t\tauth = hba_eval(parsed_hba, &client->remote_addr, !!client->sbuf.tls,\n\t\t\t\tclient->db->name, client->login_user->name);\n\t}\n\n\tif (auth == AUTH_MD5)\n\t{\n\t\tif (get_password_type(client->login_user->passwd) == PASSWORD_TYPE_SCRAM_SHA_256)\n\t\t\tauth = AUTH_SCRAM_SHA_256;\n\t}\n\n\t/* remember method */\n\tclient->client_auth_type = auth;\n\n\tswitch (auth) {\n\tcase AUTH_ANY:\n\t\tok = finish_client_login(client);\n\t\tbreak;\n\tcase AUTH_TRUST:\n\t\tif (client->login_user->mock_auth)\n\t\t\tdisconnect_client(client, true, \"\\\"trust\\\" authentication failed\");\n\t\telse\n\t\t\tok = finish_client_login(client);\n\t\tbreak;\n\tcase AUTH_PLAIN:\n\tcase AUTH_MD5:\n\tcase AUTH_PAM:\n\tcase AUTH_SCRAM_SHA_256:\n\t\tok = send_client_authreq(client);\n\t\tbreak;\n\tcase AUTH_CERT:\n\t\tok = login_via_cert(client);\n\t\tbreak;\n\tcase AUTH_PEER:\n\t\tok = login_as_unix_peer(client);\n\t\tbreak;\n\tdefault:\n\t\tdisconnect_client(client, true, \"login rejected\");\n\t\tok = false;\n\t}\n\treturn ok;\n}",
23
- "\n\tbool ok = false;\n\tint auth;\n\n\tif (!client->login_user->mock_auth && !client->db->fake) {\n\t\tPgUser *pool_user;\n\n\t\tif (client->db->forced_user)\n\t\t\tpool_user = client->db->forced_user;\n\t\telse\n\t\t\tpool_user = client->login_user;\n\n\t\tclient->pool = get_pool(client->db, pool_user);\n\t\tif (!client->pool) {\n\t\t\tdisconnect_client(client, true, \"no memory for pool\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (cf_log_connections) {\n\t\tif (client->sbuf.tls) {\n\t\t\tchar infobuf[96] = \"\";\n\t\t\ttls_get_connection_info(client->sbuf.tls, infobuf, sizeof infobuf);\n\t\t\tslog_info(client, \"login attempt: db=%s user=%s tls=%s\",\n\t\t\t\t client->db->name, client->login_user->name, infobuf);\n\t\t} else {\n\t\t\tslog_info(client, \"login attempt: db=%s user=%s tls=no\",\n\t\t\t\t client->db->name, client->login_user->name);\n\t\t}\n\t}\n\n\tif (takeover)\n\t\treturn true;\n\n\tif (client->pool && client->pool->db->admin) {\n\t\tif (!admin_post_login(client))\n\t\t\treturn false;\n\t}\n\n\tif (client->own_user)\n\t\treturn finish_client_login(client);\n\n\tauth = cf_auth_type;\n\tif (auth == AUTH_HBA) {\n\t\tauth = hba_eval(parsed_hba, &client->remote_addr, !!client->sbuf.tls,\n\t\t\t\tclient->db->name, client->login_user->name);\n\t}\n\n\tif (auth == AUTH_MD5)\n\t{\n\t\tif (get_password_type(client->login_user->passwd) == PASSWORD_TYPE_SCRAM_SHA_256)\n\t\t\tauth = AUTH_SCRAM_SHA_256;\n\t}\n\n\t/* remember method */\n\tclient->client_auth_type = auth;\n\n\tswitch (auth) {\n\tcase AUTH_ANY:\n\t\tok = finish_client_login(client);\n\t\tbreak;\n\tcase AUTH_TRUST:\n\t\tif (client->login_user->mock_auth)\n\t\t\tdisconnect_client(client, true, \"\\\"trust\\\" authentication failed\");\n\t\telse\n\t\t\tok = finish_client_login(client);\n\t\tbreak;\n\tcase AUTH_PLAIN:\n\tcase AUTH_MD5:\n\tcase AUTH_PAM:\n\tcase AUTH_SCRAM_SHA_256:\n\t\tok = send_client_authreq(client);\n\t\tbreak;\n\tcase AUTH_CERT:\n\t\tok = login_via_cert(client);\n\t\tbreak;\n\tcase AUTH_PEER:\n\t\tok = login_as_unix_peer(client);\n\t\tbreak;\n\tdefault:\n\t\tdisconnect_client(client, true, \"login rejected\");\n\t\tok = false;\n\t}\n\treturn ok;\n",
24
- "}"],
25
- ["bool set_pool(PgSocket *client, const char *dbname, const char *username, const char *password, bool takeover)\n{\n\tAssert((password && takeover) || (!password && !takeover));\n\n\t/* find database */\n\tclient->db = find_database(dbname);\n\tif (!client->db) {\n\t\tclient->db = register_auto_database(dbname);\n\t\tif (client->db)\n\t\t\tslog_info(client, \"registered new auto-database: db=%s\", dbname);\n\t}\n\tif (!client->db) {\n\t\tclient->db = calloc(1, sizeof(*client->db));\n\t\tclient->db->fake = true;\n\t\tstrlcpy(client->db->name, dbname, sizeof(client->db->name));\n\t}\n\n\tif (client->db->admin) {\n\t\tif (admin_pre_login(client, username))\n\t\t\treturn finish_set_pool(client, takeover);\n\t}\n\n\t/* avoid dealing with invalid data below, and give an\n\t * appropriate error message */\n\tif (strlen(username) >= MAX_USERNAME) {\n\t\tdisconnect_client(client, true, \"username too long\");\n\t\tif (cf_log_connections)\n\t\t\tslog_info(client, \"login failed: db=%s user=%s\", dbname, username);\n\t\treturn false;\n\t}\n\tif (password && strlen(password) >= MAX_PASSWORD) {\n\t\tdisconnect_client(client, true, \"password too long\");\n\t\tif (cf_log_connections)\n\t\t\tslog_info(client, \"login failed: db=%s user=%s\", dbname, username);\n\t\treturn false;\n\t}\n\n\t/* find user */\n\tif (cf_auth_type == AUTH_ANY) {\n\t\t/* ignore requested user */\n\t\tif (client->db->forced_user == NULL) {\n\t\t\tslog_error(client, \"auth_type=any requires forced user\");\n\t\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\t\treturn false;\n\t\t}\n\t\tclient->login_user = client->db->forced_user;\n\t} else if (cf_auth_type == AUTH_PAM) {\n\t\tif (client->db->auth_user) {\n\t\t\tslog_error(client, \"PAM can't be used together with database authentication\");\n\t\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\t\treturn false;\n\t\t}\n\t\t/* Password will be set after successful authentication when not in takeover mode */\n\t\tclient->login_user = add_pam_user(username, password);\n\t\tif (!client->login_user) {\n\t\t\tslog_error(client, \"set_pool(): failed to allocate new PAM user\");\n\t\t\tdisconnect_client(client, true, \"bouncer resources exhaustion\");\n\t\t\treturn false;\n\t\t}\n\t} else {\n\t\tclient->login_user = find_user(username);\n\t\tif (!client->login_user) {\n\t\t\t/*\n\t\t\t * If the login user specified by the client\n\t\t\t * does not exist, check if an auth_user is\n\t\t\t * set and if so send off an auth_query. If\n\t\t\t * no auth_user is set for the db, see if the\n\t\t\t * global auth_user is set and use that.\n\t\t\t */\n\t\t\tif (!client->db->auth_user && cf_auth_user) {\n\t\t\t\tclient->db->auth_user = find_user(cf_auth_user);\n\t\t\t\tif (!client->db->auth_user)\n\t\t\t\t\tclient->db->auth_user = add_user(cf_auth_user, \"\");\n\t\t\t}\n\t\t\tif (client->db->auth_user) {\n\t\t\t\tif (client->db->fake)\n\t\t\t\t\tslog_debug(client, \"not running auth_query because database is fake\");\n\t\t\t\telse {\n\t\t\t\t\tif (takeover) {\n\t\t\t\t\t\tclient->login_user = add_db_user(client->db, username, password);\n\t\t\t\t\t\treturn finish_set_pool(client, takeover);\n\t\t\t\t\t}\n\t\t\t\t\tstart_auth_query(client, username);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tslog_info(client, \"no such user: %s\", username);\n\t\t\tclient->login_user = calloc(1, sizeof(*client->login_user));\n\t\t\tclient->login_user->mock_auth = true;\n\t\t\tsafe_strcpy(client->login_user->name, username, sizeof(client->login_user->name));\n\t\t}\n\t}\n\n\treturn finish_set_pool(client, takeover);\n}",
26
- "\n\tAssert((password && takeover) || (!password && !takeover));\n\n\t/* find database */\n\tclient->db = find_database(dbname);\n\tif (!client->db) {\n\t\tclient->db = register_auto_database(dbname);\n\t\tif (client->db)\n\t\t\tslog_info(client, \"registered new auto-database: db=%s\", dbname);\n\t}\n\tif (!client->db) {\n\t\tclient->db = calloc(1, sizeof(*client->db));\n\t\tclient->db->fake = true;\n\t\tstrlcpy(client->db->name, dbname, sizeof(client->db->name));\n\t}\n\n\tif (client->db->admin) {\n\t\tif (admin_pre_login(client, username))\n\t\t\treturn finish_set_pool(client, takeover);\n\t}\n\n\t/* avoid dealing with invalid data below, and give an\n\t * appropriate error message */\n\tif (strlen(username) >= MAX_USERNAME) {\n\t\tdisconnect_client(client, true, \"username too long\");\n\t\tif (cf_log_connections)\n\t\t\tslog_info(client, \"login failed: db=%s user=%s\", dbname, username);\n\t\treturn false;\n\t}\n\tif (password && strlen(password) >= MAX_PASSWORD) {\n\t\tdisconnect_client(client, true, \"password too long\");\n\t\tif (cf_log_connections)\n\t\t\tslog_info(client, \"login failed: db=%s user=%s\", dbname, username);\n\t\treturn false;\n\t}\n\n\t/* find user */\n\tif (cf_auth_type == AUTH_ANY) {\n\t\t/* ignore requested user */\n\t\tif (client->db->forced_user == NULL) {\n\t\t\tslog_error(client, \"auth_type=any requires forced user\");\n\t\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\t\treturn false;\n\t\t}\n\t\tclient->login_user = client->db->forced_user;\n\t} else if (cf_auth_type == AUTH_PAM) {\n\t\tif (client->db->auth_user) {\n\t\t\tslog_error(client, \"PAM can't be used together with database authentication\");\n\t\t\tdisconnect_client(client, true, \"bouncer config error\");\n\t\t\treturn false;\n\t\t}\n\t\t/* Password will be set after successful authentication when not in takeover mode */\n\t\tclient->login_user = add_pam_user(username, password);\n\t\tif (!client->login_user) {\n\t\t\tslog_error(client, \"set_pool(): failed to allocate new PAM user\");\n\t\t\tdisconnect_client(client, true, \"bouncer resources exhaustion\");\n\t\t\treturn false;\n\t\t}\n\t} else {\n\t\tclient->login_user = find_user(username);\n\t\tif (!client->login_user) {\n\t\t\t/*\n\t\t\t * If the login user specified by the client\n\t\t\t * does not exist, check if an auth_user is\n\t\t\t * set and if so send off an auth_query. If\n\t\t\t * no auth_user is set for the db, see if the\n\t\t\t * global auth_user is set and use that.\n\t\t\t */\n\t\t\tif (!client->db->auth_user && cf_auth_user) {\n\t\t\t\tclient->db->auth_user = find_user(cf_auth_user);\n\t\t\t\tif (!client->db->auth_user)\n\t\t\t\t\tclient->db->auth_user = add_user(cf_auth_user, \"\");\n\t\t\t}\n\t\t\tif (client->db->auth_user) {\n\t\t\t\tif (client->db->fake)\n\t\t\t\t\tslog_debug(client, \"not running auth_query because database is fake\");\n\t\t\t\telse {\n\t\t\t\t\tif (takeover) {\n\t\t\t\t\t\tclient->login_user = add_db_user(client->db, username, password);\n\t\t\t\t\t\treturn finish_set_pool(client, takeover);\n\t\t\t\t\t}\n\t\t\t\t\tstart_auth_query(client, username);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tslog_info(client, \"no such user: %s\", username);\n\t\t\tclient->login_user = calloc(1, sizeof(*client->login_user));\n\t\t\tclient->login_user->mock_auth = true;\n\t\t\tsafe_strcpy(client->login_user->name, username, sizeof(client->login_user->name));\n\t\t}\n\t}\n\n\treturn finish_set_pool(client, takeover);\n",
27
- "}"],
28
- ["bool handle_auth_query_response(PgSocket *client, PktHdr *pkt) {\n\tuint16_t columns;\n\tuint32_t length;\n\tconst char *username, *password;\n\tPgUser user;\n\tPgSocket *server = client->link;\n\n\tswitch(pkt->type) {\n\tcase 'T':\t/* RowDescription */\n\t\tif (!mbuf_get_uint16be(&pkt->data, &columns)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (columns != 2u) {\n\t\t\tdisconnect_server(server, false, \"expected 2 columns from auth_query, not %hu\", columns);\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase 'D':\t/* DataRow */\n\t\tmemset(&user, 0, sizeof(user));\n\t\tif (!mbuf_get_uint16be(&pkt->data, &columns)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (columns != 2u) {\n\t\t\tdisconnect_server(server, false, \"expected 2 columns from auth_query, not %hu\", columns);\n\t\t\treturn false;\n\t\t}\n\t\tif (!mbuf_get_uint32be(&pkt->data, &length)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (length == (uint32_t)-1) {\n\t\t\tdisconnect_server(server, false, \"auth_query response contained null user name\");\n\t\t\treturn false;\n\t\t}\n\t\tif (!mbuf_get_chars(&pkt->data, length, &username)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (sizeof(user.name) - 1 < length)\n\t\t\tlength = sizeof(user.name) - 1;\n\t\tmemcpy(user.name, username, length);\n\t\tif (!mbuf_get_uint32be(&pkt->data, &length)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (length == (uint32_t)-1) {\n\t\t\t/*\n\t\t\t * NULL - set an md5 password with an impossible value,\n\t\t\t * so that nothing will ever match\n\t\t\t */\n\t\t\tpassword = \"md5\";\n\t\t\tlength = 3;\n\t\t} else {\n\t\t\tif (!mbuf_get_chars(&pkt->data, length, &password)) {\n\t\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif (sizeof(user.passwd) - 1 < length)\n\t\t\tlength = sizeof(user.passwd) - 1;\n\t\tmemcpy(user.passwd, password, length);\n\n\t\tclient->login_user = add_db_user(client->db, user.name, user.passwd);\n\t\tif (!client->login_user) {\n\t\t\tdisconnect_server(server, false, \"unable to allocate new user for auth\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase 'N':\t/* NoticeResponse */\n\t\tbreak;\n\tcase 'C':\t/* CommandComplete */\n\t\tbreak;\n\tcase '1':\t/* ParseComplete */\n\t\tbreak;\n\tcase '2':\t/* BindComplete */\n\t\tbreak;\n\tcase 'S': /* ParameterStatus */\n\t\tbreak;\n\tcase 'Z':\t/* ReadyForQuery */\n\t\tsbuf_prepare_skip(&client->link->sbuf, pkt->len);\n\t\tif (!client->login_user) {\n\t\t\tif (cf_log_connections)\n\t\t\t\tslog_info(client, \"login failed: db=%s\", client->db->name);\n\t\t\t/*\n\t\t\t * TODO: Currently no mock authentication when\n\t\t\t * using auth_query/auth_user; we just abort\n\t\t\t * with a revealing message to the client.\n\t\t\t * The main problem is that at this point we\n\t\t\t * don't know the original user name anymore\n\t\t\t * to do that. As a workaround, the\n\t\t\t * auth_query could be written in a way that\n\t\t\t * it returns a fake user and password if the\n\t\t\t * requested user doesn't exist.\n\t\t\t */\n\t\t\tdisconnect_client(client, true, \"no such user\");\n\t\t} else {\n\t\t\tslog_noise(client, \"auth query complete\");\n\t\t\tclient->link->resetting = true;\n\t\t\tsbuf_continue(&client->sbuf);\n\t\t}\n\t\t/*\n\t\t * either sbuf_continue or disconnect_client could disconnect the server\n\t\t * way down in their bowels of other callbacks. so check that, and\n\t\t * return appropriately (similar to reuse_on_release)\n\t\t */\n\t\tif (server->state == SV_FREE || server->state == SV_JUSTFREE)\n\t\t\treturn false;\n\t\treturn true;\n\tcase 'E':\t/* ErrorResponse */\n\t\tdisconnect_server(server, false, \"error response from auth_query\");\n\t\treturn false;\n\tdefault:\n\t\tdisconnect_server(server, false, \"unexpected response from auth_query\");\n\t\treturn false;\n\t}\n\tsbuf_prepare_skip(&server->sbuf, pkt->len);\n\treturn true;\n}",
29
- "\n\tuint16_t columns;\n\tuint32_t length;\n\tconst char *username, *password;\n\tPgUser user;\n\tPgSocket *server = client->link;\n\n\tswitch(pkt->type) {\n\tcase 'T':\t/* RowDescription */\n\t\tif (!mbuf_get_uint16be(&pkt->data, &columns)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (columns != 2u) {\n\t\t\tdisconnect_server(server, false, \"expected 2 columns from auth_query, not %hu\", columns);\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase 'D':\t/* DataRow */\n\t\tmemset(&user, 0, sizeof(user));\n\t\tif (!mbuf_get_uint16be(&pkt->data, &columns)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (columns != 2u) {\n\t\t\tdisconnect_server(server, false, \"expected 2 columns from auth_query, not %hu\", columns);\n\t\t\treturn false;\n\t\t}\n\t\tif (!mbuf_get_uint32be(&pkt->data, &length)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (length == (uint32_t)-1) {\n\t\t\tdisconnect_server(server, false, \"auth_query response contained null user name\");\n\t\t\treturn false;\n\t\t}\n\t\tif (!mbuf_get_chars(&pkt->data, length, &username)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (sizeof(user.name) - 1 < length)\n\t\t\tlength = sizeof(user.name) - 1;\n\t\tmemcpy(user.name, username, length);\n\t\tif (!mbuf_get_uint32be(&pkt->data, &length)) {\n\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\treturn false;\n\t\t}\n\t\tif (length == (uint32_t)-1) {\n\t\t\t/*\n\t\t\t * NULL - set an md5 password with an impossible value,\n\t\t\t * so that nothing will ever match\n\t\t\t */\n\t\t\tpassword = \"md5\";\n\t\t\tlength = 3;\n\t\t} else {\n\t\t\tif (!mbuf_get_chars(&pkt->data, length, &password)) {\n\t\t\t\tdisconnect_server(server, false, \"bad packet\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif (sizeof(user.passwd) - 1 < length)\n\t\t\tlength = sizeof(user.passwd) - 1;\n\t\tmemcpy(user.passwd, password, length);\n\n\t\tclient->login_user = add_db_user(client->db, user.name, user.passwd);\n\t\tif (!client->login_user) {\n\t\t\tdisconnect_server(server, false, \"unable to allocate new user for auth\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase 'N':\t/* NoticeResponse */\n\t\tbreak;\n\tcase 'C':\t/* CommandComplete */\n\t\tbreak;\n\tcase '1':\t/* ParseComplete */\n\t\tbreak;\n\tcase '2':\t/* BindComplete */\n\t\tbreak;\n\tcase 'S': /* ParameterStatus */\n\t\tbreak;\n\tcase 'Z':\t/* ReadyForQuery */\n\t\tsbuf_prepare_skip(&client->link->sbuf, pkt->len);\n\t\tif (!client->login_user) {\n\t\t\tif (cf_log_connections)\n\t\t\t\tslog_info(client, \"login failed: db=%s\", client->db->name);\n\t\t\t/*\n\t\t\t * TODO: Currently no mock authentication when\n\t\t\t * using auth_query/auth_user; we just abort\n\t\t\t * with a revealing message to the client.\n\t\t\t * The main problem is that at this point we\n\t\t\t * don't know the original user name anymore\n\t\t\t * to do that. As a workaround, the\n\t\t\t * auth_query could be written in a way that\n\t\t\t * it returns a fake user and password if the\n\t\t\t * requested user doesn't exist.\n\t\t\t */\n\t\t\tdisconnect_client(client, true, \"no such user\");\n\t\t} else {\n\t\t\tslog_noise(client, \"auth query complete\");\n\t\t\tclient->link->resetting = true;\n\t\t\tsbuf_continue(&client->sbuf);\n\t\t}\n\t\t/*\n\t\t * either sbuf_continue or disconnect_client could disconnect the server\n\t\t * way down in their bowels of other callbacks. so check that, and\n\t\t * return appropriately (similar to reuse_on_release)\n\t\t */\n\t\tif (server->state == SV_FREE || server->state == SV_JUSTFREE)\n\t\t\treturn false;\n\t\treturn true;\n\tcase 'E':\t/* ErrorResponse */\n\t\tdisconnect_server(server, false, \"error response from auth_query\");\n\t\treturn false;\n\tdefault:\n\t\tdisconnect_server(server, false, \"unexpected response from auth_query\");\n\t\treturn false;\n\t}\n\tsbuf_prepare_skip(&server->sbuf, pkt->len);\n\treturn true;\n",
30
- "}"],
31
- ["static void set_appname(PgSocket *client, const char *app_name)\n{\n\tchar buf[400], abuf[300];\n\tconst char *details;\n\n\tif (cf_application_name_add_host) {\n\t\t/* give app a name */\n\t\tif (!app_name)\n\t\t\tapp_name = \"app\";\n\n\t\t/* add details */\n\t\tdetails = pga_details(&client->remote_addr, abuf, sizeof(abuf));\n\t\tsnprintf(buf, sizeof(buf), \"%s - %s\", app_name, details);\n\t\tapp_name = buf;\n\t}\n\tif (app_name) {\n\t\tslog_debug(client, \"using application_name: %s\", app_name);\n\t\tvarcache_set(&client->vars, \"application_name\", app_name);\n\t}\n}",
32
- "\n\tchar buf[400], abuf[300];\n\tconst char *details;\n\n\tif (cf_application_name_add_host) {\n\t\t/* give app a name */\n\t\tif (!app_name)\n\t\t\tapp_name = \"app\";\n\n\t\t/* add details */\n\t\tdetails = pga_details(&client->remote_addr, abuf, sizeof(abuf));\n\t\tsnprintf(buf, sizeof(buf), \"%s - %s\", app_name, details);\n\t\tapp_name = buf;\n\t}\n\tif (app_name) {\n\t\tslog_debug(client, \"using application_name: %s\", app_name);\n\t\tvarcache_set(&client->vars, \"application_name\", app_name);\n\t}\n",
33
- "}"],
34
- ["static bool decide_startup_pool(PgSocket *client, PktHdr *pkt)\n{\n\tconst char *username = NULL, *dbname = NULL;\n\tconst char *key, *val;\n\tbool ok;\n\tbool appname_found = false;\n\n\twhile (1) {\n\t\tok = mbuf_get_string(&pkt->data, &key);\n\t\tif (!ok || *key == 0)\n\t\t\tbreak;\n\t\tok = mbuf_get_string(&pkt->data, &val);\n\t\tif (!ok)\n\t\t\tbreak;\n\n\t\tif (strcmp(key, \"database\") == 0) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t\tdbname = val;\n\t\t} else if (strcmp(key, \"user\") == 0) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t\tusername = val;\n\t\t} else if (strcmp(key, \"application_name\") == 0) {\n\t\t\tset_appname(client, val);\n\t\t\tappname_found = true;\n\t\t} else if (varcache_set(&client->vars, key, val)) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t} else if (strlist_contains(cf_ignore_startup_params, key)) {\n\t\t\tslog_debug(client, \"ignoring startup parameter: %s=%s\", key, val);\n\t\t} else {\n\t\t\tslog_warning(client, \"unsupported startup parameter: %s=%s\", key, val);\n\t\t\tdisconnect_client(client, true, \"unsupported startup parameter: %s\", key);\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (!username || !username[0]) {\n\t\tdisconnect_client(client, true, \"no username supplied\");\n\t\treturn false;\n\t}\n\n\t/* if missing dbname, default to username */\n\tif (!dbname || !dbname[0])\n\t\tdbname = username;\n\n\t/* create application_name if requested */\n\tif (!appname_found)\n\t\tset_appname(client, NULL);\n\n\t/* check if limit allows, don't limit admin db\n\t nb: new incoming conn will be attached to PgSocket, thus\n\t get_active_client_count() counts it */\n\tif (get_active_client_count() > cf_max_client_conn) {\n\t\tif (strcmp(dbname, \"pgbouncer\") != 0) {\n\t\t\tdisconnect_client(client, true, \"no more connections allowed (max_client_conn)\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/* find pool */\n\treturn set_pool(client, dbname, username, NULL, false);\n}",
35
- "\n\tconst char *username = NULL, *dbname = NULL;\n\tconst char *key, *val;\n\tbool ok;\n\tbool appname_found = false;\n\n\twhile (1) {\n\t\tok = mbuf_get_string(&pkt->data, &key);\n\t\tif (!ok || *key == 0)\n\t\t\tbreak;\n\t\tok = mbuf_get_string(&pkt->data, &val);\n\t\tif (!ok)\n\t\t\tbreak;\n\n\t\tif (strcmp(key, \"database\") == 0) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t\tdbname = val;\n\t\t} else if (strcmp(key, \"user\") == 0) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t\tusername = val;\n\t\t} else if (strcmp(key, \"application_name\") == 0) {\n\t\t\tset_appname(client, val);\n\t\t\tappname_found = true;\n\t\t} else if (varcache_set(&client->vars, key, val)) {\n\t\t\tslog_debug(client, \"got var: %s=%s\", key, val);\n\t\t} else if (strlist_contains(cf_ignore_startup_params, key)) {\n\t\t\tslog_debug(client, \"ignoring startup parameter: %s=%s\", key, val);\n\t\t} else {\n\t\t\tslog_warning(client, \"unsupported startup parameter: %s=%s\", key, val);\n\t\t\tdisconnect_client(client, true, \"unsupported startup parameter: %s\", key);\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (!username || !username[0]) {\n\t\tdisconnect_client(client, true, \"no username supplied\");\n\t\treturn false;\n\t}\n\n\t/* if missing dbname, default to username */\n\tif (!dbname || !dbname[0])\n\t\tdbname = username;\n\n\t/* create application_name if requested */\n\tif (!appname_found)\n\t\tset_appname(client, NULL);\n\n\t/* check if limit allows, don't limit admin db\n\t nb: new incoming conn will be attached to PgSocket, thus\n\t get_active_client_count() counts it */\n\tif (get_active_client_count() > cf_max_client_conn) {\n\t\tif (strcmp(dbname, \"pgbouncer\") != 0) {\n\t\t\tdisconnect_client(client, true, \"no more connections allowed (max_client_conn)\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/* find pool */\n\treturn set_pool(client, dbname, username, NULL, false);\n",
36
- "}"],
37
- ["static bool scram_client_first(PgSocket *client, uint32_t datalen, const uint8_t *data)\n{\n\tchar *ibuf;\n\tchar *input;\n\tint res;\n\tPgUser *user = client->login_user;\n\n\tibuf = malloc(datalen + 1);\n\tif (ibuf == NULL)\n\t\treturn false;\n\tmemcpy(ibuf, data, datalen);\n\tibuf[datalen] = '\\0';\n\n\tinput = ibuf;\n\tslog_debug(client, \"SCRAM client-first-message = \\\"%s\\\"\", input);\n\tif (!read_client_first_message(client, input,\n\t\t\t\t &client->scram_state.cbind_flag,\n\t\t\t\t &client->scram_state.client_first_message_bare,\n\t\t\t\t &client->scram_state.client_nonce))\n\t\tgoto failed;\n\n\tif (!user->mock_auth) {\n\t\tslog_debug(client, \"stored secret = \\\"%s\\\"\", user->passwd);\n\t\tswitch (get_password_type(user->passwd)) {\n\t\tcase PASSWORD_TYPE_MD5:\n\t\t\tslog_error(client, \"SCRAM authentication failed: user has MD5 secret\");\n\t\t\tgoto failed;\n\t\tcase PASSWORD_TYPE_PLAINTEXT:\n\t\tcase PASSWORD_TYPE_SCRAM_SHA_256:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!build_server_first_message(&client->scram_state, user->name, user->mock_auth ? NULL : user->passwd))\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM server-first-message = \\\"%s\\\"\", client->scram_state.server_first_message);\n\n\tSEND_generic(res, client, 'R', \"ib\",\n\t\t AUTH_SASL_CONT,\n\t\t client->scram_state.server_first_message,\n\t\t strlen(client->scram_state.server_first_message));\n\n\tfree(ibuf);\n\treturn res;\nfailed:\n\tfree(ibuf);\n\treturn false;\n}",
38
- "\n\tchar *ibuf;\n\tchar *input;\n\tint res;\n\tPgUser *user = client->login_user;\n\n\tibuf = malloc(datalen + 1);\n\tif (ibuf == NULL)\n\t\treturn false;\n\tmemcpy(ibuf, data, datalen);\n\tibuf[datalen] = '\\0';\n\n\tinput = ibuf;\n\tslog_debug(client, \"SCRAM client-first-message = \\\"%s\\\"\", input);\n\tif (!read_client_first_message(client, input,\n\t\t\t\t &client->scram_state.cbind_flag,\n\t\t\t\t &client->scram_state.client_first_message_bare,\n\t\t\t\t &client->scram_state.client_nonce))\n\t\tgoto failed;\n\n\tif (!user->mock_auth) {\n\t\tslog_debug(client, \"stored secret = \\\"%s\\\"\", user->passwd);\n\t\tswitch (get_password_type(user->passwd)) {\n\t\tcase PASSWORD_TYPE_MD5:\n\t\t\tslog_error(client, \"SCRAM authentication failed: user has MD5 secret\");\n\t\t\tgoto failed;\n\t\tcase PASSWORD_TYPE_PLAINTEXT:\n\t\tcase PASSWORD_TYPE_SCRAM_SHA_256:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!build_server_first_message(&client->scram_state, user->name, user->mock_auth ? NULL : user->passwd))\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM server-first-message = \\\"%s\\\"\", client->scram_state.server_first_message);\n\n\tSEND_generic(res, client, 'R', \"ib\",\n\t\t AUTH_SASL_CONT,\n\t\t client->scram_state.server_first_message,\n\t\t strlen(client->scram_state.server_first_message));\n\n\tfree(ibuf);\n\treturn res;\nfailed:\n\tfree(ibuf);\n\treturn false;\n",
39
- "}"],
40
- ["static bool scram_client_final(PgSocket *client, uint32_t datalen, const uint8_t *data)\n{\n\tchar *ibuf;\n\tchar *input;\n\tconst char *client_final_nonce = NULL;\n\tchar *proof = NULL;\n\tchar *server_final_message;\n\tint res;\n\n\tibuf = malloc(datalen + 1);\n\tif (ibuf == NULL)\n\t\treturn false;\n\tmemcpy(ibuf, data, datalen);\n\tibuf[datalen] = '\\0';\n\n\tinput = ibuf;\n\tslog_debug(client, \"SCRAM client-final-message = \\\"%s\\\"\", input);\n\tif (!read_client_final_message(client, data, input,\n\t\t\t\t &client_final_nonce,\n\t\t\t\t &proof))\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM client-final-message-without-proof = \\\"%s\\\"\",\n\t\t client->scram_state.client_final_message_without_proof);\n\n\tif (!verify_final_nonce(&client->scram_state, client_final_nonce)) {\n\t\tslog_error(client, \"invalid SCRAM response (nonce does not match)\");\n\t\tgoto failed;\n\t}\n\n\tif (!verify_client_proof(&client->scram_state, proof)\n\t || !client->login_user) {\n\t\tslog_error(client, \"password authentication failed\");\n\t\tgoto failed;\n\t}\n\n\tserver_final_message = build_server_final_message(&client->scram_state);\n\tif (!server_final_message)\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM server-final-message = \\\"%s\\\"\", server_final_message);\n\n\tSEND_generic(res, client, 'R', \"ib\",\n\t\t AUTH_SASL_FIN,\n\t\t server_final_message,\n\t\t strlen(server_final_message));\n\n\tfree(server_final_message);\n\tfree(proof);\n\tfree(ibuf);\n\treturn res;\nfailed:\n\tfree(proof);\n\tfree(ibuf);\n\treturn false;\n}",
41
- "\n\tchar *ibuf;\n\tchar *input;\n\tconst char *client_final_nonce = NULL;\n\tchar *proof = NULL;\n\tchar *server_final_message;\n\tint res;\n\n\tibuf = malloc(datalen + 1);\n\tif (ibuf == NULL)\n\t\treturn false;\n\tmemcpy(ibuf, data, datalen);\n\tibuf[datalen] = '\\0';\n\n\tinput = ibuf;\n\tslog_debug(client, \"SCRAM client-final-message = \\\"%s\\\"\", input);\n\tif (!read_client_final_message(client, data, input,\n\t\t\t\t &client_final_nonce,\n\t\t\t\t &proof))\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM client-final-message-without-proof = \\\"%s\\\"\",\n\t\t client->scram_state.client_final_message_without_proof);\n\n\tif (!verify_final_nonce(&client->scram_state, client_final_nonce)) {\n\t\tslog_error(client, \"invalid SCRAM response (nonce does not match)\");\n\t\tgoto failed;\n\t}\n\n\tif (!verify_client_proof(&client->scram_state, proof)\n\t || !client->login_user) {\n\t\tslog_error(client, \"password authentication failed\");\n\t\tgoto failed;\n\t}\n\n\tserver_final_message = build_server_final_message(&client->scram_state);\n\tif (!server_final_message)\n\t\tgoto failed;\n\tslog_debug(client, \"SCRAM server-final-message = \\\"%s\\\"\", server_final_message);\n\n\tSEND_generic(res, client, 'R', \"ib\",\n\t\t AUTH_SASL_FIN,\n\t\t server_final_message,\n\t\t strlen(server_final_message));\n\n\tfree(server_final_message);\n\tfree(proof);\n\tfree(ibuf);\n\treturn res;\nfailed:\n\tfree(proof);\n\tfree(ibuf);\n\treturn false;\n",
42
- "}"],
43
- ["static bool handle_client_startup(PgSocket *client, PktHdr *pkt)\n{\n\tconst char *passwd;\n\tconst uint8_t *key;\n\tbool ok;\n\tbool is_unix = pga_is_unix(&client->remote_addr);\n\n\tSBuf *sbuf = &client->sbuf;\n\n\t/* don't tolerate partial packets */\n\tif (incomplete_pkt(pkt)) {\n\t\tdisconnect_client(client, true, \"client sent partial pkt in startup phase\");\n\t\treturn false;\n\t}\n\n\tif (client->wait_for_welcome || client->wait_for_auth) {\n\t\tif (finish_client_login(client)) {\n\t\t\t/* the packet was already parsed */\n\t\t\tsbuf_prepare_skip(sbuf, pkt->len);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tswitch (pkt->type) {\n\tcase PKT_SSLREQ:\n\t\tslog_noise(client, \"C: req SSL\");\n\n\t\tif (client->sbuf.tls) {\n\t\t\tdisconnect_client(client, false, \"SSL req inside SSL\");\n\t\t\treturn false;\n\t\t}\n\t\tif (client_accept_sslmode != SSLMODE_DISABLED && !is_unix) {\n\t\t\tslog_noise(client, \"P: SSL ack\");\n\t\t\tif (!sbuf_answer(&client->sbuf, \"S\", 1)) {\n\t\t\t\tdisconnect_client(client, false, \"failed to ack SSL\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!sbuf_tls_accept(&client->sbuf)) {\n\t\t\t\tdisconnect_client(client, false, \"failed to accept SSL\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t/* reject SSL attempt */\n\t\tslog_noise(client, \"P: nak\");\n\t\tif (!sbuf_answer(&client->sbuf, \"N\", 1)) {\n\t\t\tdisconnect_client(client, false, \"failed to nak SSL\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase PKT_GSSENCREQ:\n\t\t/* reject GSS encryption attempt */\n\t\tslog_noise(client, \"C: req GSS enc\");\n\t\tif (!sbuf_answer(&client->sbuf, \"N\", 1)) {\n\t\t\tdisconnect_client(client, false, \"failed to nak GSS enc\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase PKT_STARTUP_V2:\n\t\tdisconnect_client(client, true, \"old V2 protocol not supported\");\n\t\treturn false;\n\tcase PKT_STARTUP:\n\t\t/* require SSL except on unix socket */\n\t\tif (client_accept_sslmode >= SSLMODE_REQUIRE && !client->sbuf.tls && !is_unix) {\n\t\t\tdisconnect_client(client, true, \"SSL required\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->pool && !client->wait_for_user_conn && !client->wait_for_user) {\n\t\t\tdisconnect_client(client, true, \"client re-sent startup pkt\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->wait_for_user) {\n\t\t\tclient->wait_for_user = false;\n\t\t\tif (!finish_set_pool(client, false))\n\t\t\t\treturn false;\n\t\t} else if (!decide_startup_pool(client, pkt)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tbreak;\n\tcase 'p':\t\t/* PasswordMessage, SASLInitialResponse, or SASLResponse */\n\t\t/* too early */\n\t\tif (!client->login_user) {\n\t\t\tdisconnect_client(client, true, \"client password pkt before startup packet\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->client_auth_type == AUTH_SCRAM_SHA_256) {\n\t\t\tconst char *mech;\n\t\t\tuint32_t length;\n\t\t\tconst uint8_t *data;\n\n\t\t\tif (!client->scram_state.server_nonce) {\n\t\t\t\t/* process as SASLInitialResponse */\n\t\t\t\tif (!mbuf_get_string(&pkt->data, &mech))\n\t\t\t\t\treturn false;\n\t\t\t\tslog_debug(client, \"C: selected SASL mechanism: %s\", mech);\n\t\t\t\tif (strcmp(mech, \"SCRAM-SHA-256\") != 0) {\n\t\t\t\t\tdisconnect_client(client, true, \"client selected an invalid SASL authentication mechanism\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!mbuf_get_uint32be(&pkt->data, &length))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!mbuf_get_bytes(&pkt->data, length, &data))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!scram_client_first(client, length, data)) {\n\t\t\t\t\tdisconnect_client(client, true, \"SASL authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* process as SASLResponse */\n\t\t\t\tlength = mbuf_avail_for_read(&pkt->data);\n\t\t\t\tif (!mbuf_get_bytes(&pkt->data, length, &data))\n\t\t\t\t\treturn false;\n\t\t\t\tif (scram_client_final(client, length, data)) {\n\t\t\t\t\t/* save SCRAM keys for user */\n\t\t\t\t\tif (!client->scram_state.adhoc && !client->db->fake) {\n\t\t\t\t\t\tmemcpy(client->pool->user->scram_ClientKey,\n\t\t\t\t\t\t client->scram_state.ClientKey,\n\t\t\t\t\t\t sizeof(client->scram_state.ClientKey));\n\t\t\t\t\t\tmemcpy(client->pool->user->scram_ServerKey,\n\t\t\t\t\t\t client->scram_state.ServerKey,\n\t\t\t\t\t\t sizeof(client->scram_state.ServerKey));\n\t\t\t\t\t\tclient->pool->user->has_scram_keys = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tfree_scram_state(&client->scram_state);\n\t\t\t\t\tif (!finish_client_login(client))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdisconnect_client(client, true, \"SASL authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* process as PasswordMessage */\n\t\t\tok = mbuf_get_string(&pkt->data, &passwd);\n\n\t\t\tif (ok) {\n\t\t\t\t/*\n\t\t\t\t * Don't allow an empty password; see\n\t\t\t\t * PostgreSQL recv_password_packet().\n\t\t\t\t */\n\t\t\t\tif (!*passwd) {\n\t\t\t\t\tdisconnect_client(client, true, \"empty password returned by client\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (client->client_auth_type == AUTH_PAM) {\n\t\t\t\t\tif (!sbuf_pause(&client->sbuf)) {\n\t\t\t\t\t\tdisconnect_client(client, true, \"pause failed\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tpam_auth_begin(client, passwd);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (check_client_passwd(client, passwd)) {\n\t\t\t\t\tif (!finish_client_login(client))\n\t\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tdisconnect_client(client, true, \"password authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase PKT_CANCEL:\n\t\tif (mbuf_avail_for_read(&pkt->data) == BACKENDKEY_LEN\n\t\t && mbuf_get_bytes(&pkt->data, BACKENDKEY_LEN, &key))\n\t\t{\n\t\t\tmemcpy(client->cancel_key, key, BACKENDKEY_LEN);\n\t\t\taccept_cancel_request(client);\n\t\t} else {\n\t\t\tdisconnect_client(client, false, \"bad cancel request\");\n\t\t}\n\t\treturn false;\n\tdefault:\n\t\tdisconnect_client(client, false, \"bad packet\");\n\t\treturn false;\n\t}\n\tsbuf_prepare_skip(sbuf, pkt->len);\n\tclient->request_time = get_cached_time();\n\treturn true;\n}",
44
- "\n\tconst char *passwd;\n\tconst uint8_t *key;\n\tbool ok;\n\tbool is_unix = pga_is_unix(&client->remote_addr);\n\n\tSBuf *sbuf = &client->sbuf;\n\n\t/* don't tolerate partial packets */\n\tif (incomplete_pkt(pkt)) {\n\t\tdisconnect_client(client, true, \"client sent partial pkt in startup phase\");\n\t\treturn false;\n\t}\n\n\tif (client->wait_for_welcome || client->wait_for_auth) {\n\t\tif (finish_client_login(client)) {\n\t\t\t/* the packet was already parsed */\n\t\t\tsbuf_prepare_skip(sbuf, pkt->len);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tswitch (pkt->type) {\n\tcase PKT_SSLREQ:\n\t\tslog_noise(client, \"C: req SSL\");\n\n\t\tif (client->sbuf.tls) {\n\t\t\tdisconnect_client(client, false, \"SSL req inside SSL\");\n\t\t\treturn false;\n\t\t}\n\t\tif (client_accept_sslmode != SSLMODE_DISABLED && !is_unix) {\n\t\t\tslog_noise(client, \"P: SSL ack\");\n\t\t\tif (!sbuf_answer(&client->sbuf, \"S\", 1)) {\n\t\t\t\tdisconnect_client(client, false, \"failed to ack SSL\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!sbuf_tls_accept(&client->sbuf)) {\n\t\t\t\tdisconnect_client(client, false, \"failed to accept SSL\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t/* reject SSL attempt */\n\t\tslog_noise(client, \"P: nak\");\n\t\tif (!sbuf_answer(&client->sbuf, \"N\", 1)) {\n\t\t\tdisconnect_client(client, false, \"failed to nak SSL\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase PKT_GSSENCREQ:\n\t\t/* reject GSS encryption attempt */\n\t\tslog_noise(client, \"C: req GSS enc\");\n\t\tif (!sbuf_answer(&client->sbuf, \"N\", 1)) {\n\t\t\tdisconnect_client(client, false, \"failed to nak GSS enc\");\n\t\t\treturn false;\n\t\t}\n\t\tbreak;\n\tcase PKT_STARTUP_V2:\n\t\tdisconnect_client(client, true, \"old V2 protocol not supported\");\n\t\treturn false;\n\tcase PKT_STARTUP:\n\t\t/* require SSL except on unix socket */\n\t\tif (client_accept_sslmode >= SSLMODE_REQUIRE && !client->sbuf.tls && !is_unix) {\n\t\t\tdisconnect_client(client, true, \"SSL required\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->pool && !client->wait_for_user_conn && !client->wait_for_user) {\n\t\t\tdisconnect_client(client, true, \"client re-sent startup pkt\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->wait_for_user) {\n\t\t\tclient->wait_for_user = false;\n\t\t\tif (!finish_set_pool(client, false))\n\t\t\t\treturn false;\n\t\t} else if (!decide_startup_pool(client, pkt)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tbreak;\n\tcase 'p':\t\t/* PasswordMessage, SASLInitialResponse, or SASLResponse */\n\t\t/* too early */\n\t\tif (!client->login_user) {\n\t\t\tdisconnect_client(client, true, \"client password pkt before startup packet\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (client->client_auth_type == AUTH_SCRAM_SHA_256) {\n\t\t\tconst char *mech;\n\t\t\tuint32_t length;\n\t\t\tconst uint8_t *data;\n\n\t\t\tif (!client->scram_state.server_nonce) {\n\t\t\t\t/* process as SASLInitialResponse */\n\t\t\t\tif (!mbuf_get_string(&pkt->data, &mech))\n\t\t\t\t\treturn false;\n\t\t\t\tslog_debug(client, \"C: selected SASL mechanism: %s\", mech);\n\t\t\t\tif (strcmp(mech, \"SCRAM-SHA-256\") != 0) {\n\t\t\t\t\tdisconnect_client(client, true, \"client selected an invalid SASL authentication mechanism\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!mbuf_get_uint32be(&pkt->data, &length))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!mbuf_get_bytes(&pkt->data, length, &data))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!scram_client_first(client, length, data)) {\n\t\t\t\t\tdisconnect_client(client, true, \"SASL authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* process as SASLResponse */\n\t\t\t\tlength = mbuf_avail_for_read(&pkt->data);\n\t\t\t\tif (!mbuf_get_bytes(&pkt->data, length, &data))\n\t\t\t\t\treturn false;\n\t\t\t\tif (scram_client_final(client, length, data)) {\n\t\t\t\t\t/* save SCRAM keys for user */\n\t\t\t\t\tif (!client->scram_state.adhoc && !client->db->fake) {\n\t\t\t\t\t\tmemcpy(client->pool->user->scram_ClientKey,\n\t\t\t\t\t\t client->scram_state.ClientKey,\n\t\t\t\t\t\t sizeof(client->scram_state.ClientKey));\n\t\t\t\t\t\tmemcpy(client->pool->user->scram_ServerKey,\n\t\t\t\t\t\t client->scram_state.ServerKey,\n\t\t\t\t\t\t sizeof(client->scram_state.ServerKey));\n\t\t\t\t\t\tclient->pool->user->has_scram_keys = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tfree_scram_state(&client->scram_state);\n\t\t\t\t\tif (!finish_client_login(client))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdisconnect_client(client, true, \"SASL authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* process as PasswordMessage */\n\t\t\tok = mbuf_get_string(&pkt->data, &passwd);\n\n\t\t\tif (ok) {\n\t\t\t\t/*\n\t\t\t\t * Don't allow an empty password; see\n\t\t\t\t * PostgreSQL recv_password_packet().\n\t\t\t\t */\n\t\t\t\tif (!*passwd) {\n\t\t\t\t\tdisconnect_client(client, true, \"empty password returned by client\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (client->client_auth_type == AUTH_PAM) {\n\t\t\t\t\tif (!sbuf_pause(&client->sbuf)) {\n\t\t\t\t\t\tdisconnect_client(client, true, \"pause failed\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tpam_auth_begin(client, passwd);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (check_client_passwd(client, passwd)) {\n\t\t\t\t\tif (!finish_client_login(client))\n\t\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tdisconnect_client(client, true, \"password authentication failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase PKT_CANCEL:\n\t\tif (mbuf_avail_for_read(&pkt->data) == BACKENDKEY_LEN\n\t\t && mbuf_get_bytes(&pkt->data, BACKENDKEY_LEN, &key))\n\t\t{\n\t\t\tmemcpy(client->cancel_key, key, BACKENDKEY_LEN);\n\t\t\taccept_cancel_request(client);\n\t\t} else {\n\t\t\tdisconnect_client(client, false, \"bad cancel request\");\n\t\t}\n\t\treturn false;\n\tdefault:\n\t\tdisconnect_client(client, false, \"bad packet\");\n\t\treturn false;\n\t}\n\tsbuf_prepare_skip(sbuf, pkt->len);\n\tclient->request_time = get_cached_time();\n\treturn true;\n",
45
- "}"],
46
- ["static bool handle_client_work(PgSocket *client, PktHdr *pkt)\n{\n\tSBuf *sbuf = &client->sbuf;\n\tint rfq_delta = 0;\n\n\tswitch (pkt->type) {\n\n\t/* one-packet queries */\n\tcase 'Q':\t\t/* Query */\n\t\tif (cf_disable_pqexec) {\n\t\t\tslog_error(client, \"client used 'Q' packet type\");\n\t\t\tdisconnect_client(client, true, \"PQexec disallowed\");\n\t\t\treturn false;\n\t\t}\n\t\trfq_delta++;\n\t\tbreak;\n\tcase 'F':\t\t/* FunctionCall */\n\t\trfq_delta++;\n\t\tbreak;\n\n\t/* request immediate response from server */\n\tcase 'S':\t\t/* Sync */\n\t\trfq_delta++;\n\t\tbreak;\n\tcase 'H':\t\t/* Flush */\n\t\tbreak;\n\n\t/* copy end markers */\n\tcase 'c':\t\t/* CopyDone(F/B) */\n\tcase 'f':\t\t/* CopyFail(F/B) */\n\t\tbreak;\n\n\t/*\n\t * extended protocol allows server (and thus pooler)\n\t * to buffer packets until sync or flush is sent by client\n\t */\n\tcase 'P':\t\t/* Parse */\n\tcase 'E':\t\t/* Execute */\n\tcase 'C':\t\t/* Close */\n\tcase 'B':\t\t/* Bind */\n\tcase 'D':\t\t/* Describe */\n\tcase 'd':\t\t/* CopyData(F/B) */\n\t\tbreak;\n\n\t/* client wants to go away */\n\tdefault:\n\t\tslog_error(client, \"unknown pkt from client: %u/0x%x\", pkt->type, pkt->type);\n\t\tdisconnect_client(client, true, \"unknown pkt\");\n\t\treturn false;\n\tcase 'X': /* Terminate */\n\t\tdisconnect_client(client, false, \"client close request\");\n\t\treturn false;\n\t}\n\n\t/* update stats */\n\tif (!client->query_start) {\n\t\tclient->pool->stats.query_count++;\n\t\tclient->query_start = get_cached_time();\n\t}\n\n\t/* remember timestamp of the first query in a transaction */\n\tif (!client->xact_start) {\n\t\tclient->pool->stats.xact_count++;\n\t\tclient->xact_start = client->query_start;\n\t}\n\n\tif (client->pool->db->admin)\n\t\treturn admin_handle_client(client, pkt);\n\n\t/* acquire server */\n\tif (!find_server(client))\n\t\treturn false;\n\n\t/* postpone rfq change until certain that client will not be paused */\n\tif (rfq_delta) {\n\t\tclient->expect_rfq_count += rfq_delta;\n\t}\n\n\tclient->pool->stats.client_bytes += pkt->len;\n\n\t/* tag the server as dirty */\n\tclient->link->ready = false;\n\tclient->link->idle_tx = false;\n\n\t/* forward the packet */\n\tsbuf_prepare_send(sbuf, &client->link->sbuf, pkt->len);\n\n\treturn true;\n}",
47
- "\n\tSBuf *sbuf = &client->sbuf;\n\tint rfq_delta = 0;\n\n\tswitch (pkt->type) {\n\n\t/* one-packet queries */\n\tcase 'Q':\t\t/* Query */\n\t\tif (cf_disable_pqexec) {\n\t\t\tslog_error(client, \"client used 'Q' packet type\");\n\t\t\tdisconnect_client(client, true, \"PQexec disallowed\");\n\t\t\treturn false;\n\t\t}\n\t\trfq_delta++;\n\t\tbreak;\n\tcase 'F':\t\t/* FunctionCall */\n\t\trfq_delta++;\n\t\tbreak;\n\n\t/* request immediate response from server */\n\tcase 'S':\t\t/* Sync */\n\t\trfq_delta++;\n\t\tbreak;\n\tcase 'H':\t\t/* Flush */\n\t\tbreak;\n\n\t/* copy end markers */\n\tcase 'c':\t\t/* CopyDone(F/B) */\n\tcase 'f':\t\t/* CopyFail(F/B) */\n\t\tbreak;\n\n\t/*\n\t * extended protocol allows server (and thus pooler)\n\t * to buffer packets until sync or flush is sent by client\n\t */\n\tcase 'P':\t\t/* Parse */\n\tcase 'E':\t\t/* Execute */\n\tcase 'C':\t\t/* Close */\n\tcase 'B':\t\t/* Bind */\n\tcase 'D':\t\t/* Describe */\n\tcase 'd':\t\t/* CopyData(F/B) */\n\t\tbreak;\n\n\t/* client wants to go away */\n\tdefault:\n\t\tslog_error(client, \"unknown pkt from client: %u/0x%x\", pkt->type, pkt->type);\n\t\tdisconnect_client(client, true, \"unknown pkt\");\n\t\treturn false;\n\tcase 'X': /* Terminate */\n\t\tdisconnect_client(client, false, \"client close request\");\n\t\treturn false;\n\t}\n\n\t/* update stats */\n\tif (!client->query_start) {\n\t\tclient->pool->stats.query_count++;\n\t\tclient->query_start = get_cached_time();\n\t}\n\n\t/* remember timestamp of the first query in a transaction */\n\tif (!client->xact_start) {\n\t\tclient->pool->stats.xact_count++;\n\t\tclient->xact_start = client->query_start;\n\t}\n\n\tif (client->pool->db->admin)\n\t\treturn admin_handle_client(client, pkt);\n\n\t/* acquire server */\n\tif (!find_server(client))\n\t\treturn false;\n\n\t/* postpone rfq change until certain that client will not be paused */\n\tif (rfq_delta) {\n\t\tclient->expect_rfq_count += rfq_delta;\n\t}\n\n\tclient->pool->stats.client_bytes += pkt->len;\n\n\t/* tag the server as dirty */\n\tclient->link->ready = false;\n\tclient->link->idle_tx = false;\n\n\t/* forward the packet */\n\tsbuf_prepare_send(sbuf, &client->link->sbuf, pkt->len);\n\n\treturn true;\n",
48
- "}"],
49
- ["bool client_proto(SBuf *sbuf, SBufEvent evtype, struct MBuf *data)\n{\n\tbool res = false;\n\tPgSocket *client = container_of(sbuf, PgSocket, sbuf);\n\tPktHdr pkt;\n\n\n\tAssert(!is_server_socket(client));\n\tAssert(client->sbuf.sock);\n\tAssert(client->state != CL_FREE);\n\n\t/* may happen if close failed */\n\tif (client->state == CL_JUSTFREE)\n\t\treturn false;\n\n\tswitch (evtype) {\n\tcase SBUF_EV_CONNECT_OK:\n\tcase SBUF_EV_CONNECT_FAILED:\n\t\t/* ^ those should not happen */\n\tcase SBUF_EV_RECV_FAILED:\n\t\t/*\n\t\t * Don't log error if client disconnects right away,\n\t\t * could be monitoring probe.\n\t\t */\n\t\tif (client->state == CL_LOGIN && mbuf_avail_for_read(data) == 0)\n\t\t\tdisconnect_client(client, false, NULL);\n\t\telse\n\t\t\tdisconnect_client(client, false, \"client unexpected eof\");\n\t\tbreak;\n\tcase SBUF_EV_SEND_FAILED:\n\t\tdisconnect_server(client->link, false, \"server connection closed\");\n\t\tbreak;\n\tcase SBUF_EV_READ:\n\t\t/* Wait until full packet headers is available. */\n\t\tif (incomplete_header(data)) {\n\t\t\tslog_noise(client, \"C: got partial header, trying to wait a bit\");\n\t\t\treturn false;\n\t\t}\n\t\tif (!get_header(data, &pkt)) {\n\t\t\tchar hex[8*2 + 1];\n\t\t\tdisconnect_client(client, true, \"bad packet header: '%s'\",\n\t\t\t\t\t hdr2hex(data, hex, sizeof(hex)));\n\t\t\treturn false;\n\t\t}\n\t\tslog_noise(client, \"read pkt='%c' len=%u\", pkt_desc(&pkt), pkt.len);\n\n\t\t/*\n\t\t * If we are reading an SSL request or GSSAPI\n\t\t * encryption request, we should have no data already\n\t\t * buffered at this point. If we do, it was received\n\t\t * before we performed the SSL or GSSAPI handshake, so\n\t\t * it wasn't encrypted and indeed may have been\n\t\t * injected by a man-in-the-middle. We report this\n\t\t * case to the client.\n\t\t */\n\t\tif (pkt.type == PKT_SSLREQ && mbuf_avail_for_read(data) > 0) {\n\t\t\tdisconnect_client(client, true, \"received unencrypted data after SSL request\");\n\t\t\treturn false;\n\t\t}\n\t\tif (pkt.type == PKT_GSSENCREQ && mbuf_avail_for_read(data) > 0) {\n\t\t\tdisconnect_client(client, true, \"received unencrypted data after GSSAPI encryption request\");\n\t\t\treturn false;\n\t\t}\n\n\t\tclient->request_time = get_cached_time();\n\t\tswitch (client->state) {\n\t\tcase CL_LOGIN:\n\t\t\tres = handle_client_startup(client, &pkt);\n\t\t\tbreak;\n\t\tcase CL_ACTIVE:\n\t\t\tif (client->wait_for_welcome)\n\t\t\t\tres = handle_client_startup(client, &pkt);\n\t\t\telse\n\t\t\t\tres = handle_client_work(client, &pkt);\n\t\t\tbreak;\n\t\tcase CL_WAITING:\n\t\t\tfatal(\"why waiting client in client_proto()\");\n\t\tdefault:\n\t\t\tfatal(\"bad client state: %d\", client->state);\n\t\t}\n\t\tbreak;\n\tcase SBUF_EV_FLUSH:\n\t\t/* client is not interested in it */\n\t\tbreak;\n\tcase SBUF_EV_PKT_CALLBACK:\n\t\t/* unused ATM */\n\t\tbreak;\n\tcase SBUF_EV_TLS_READY:\n\t\tsbuf_continue(&client->sbuf);\n\t\tres = true;\n\t\tbreak;\n\t}\n\treturn res;\n}",
50
- "\n\tbool res = false;\n\tPgSocket *client = container_of(sbuf, PgSocket, sbuf);\n\tPktHdr pkt;\n\n\n\tAssert(!is_server_socket(client));\n\tAssert(client->sbuf.sock);\n\tAssert(client->state != CL_FREE);\n\n\t/* may happen if close failed */\n\tif (client->state == CL_JUSTFREE)\n\t\treturn false;\n\n\tswitch (evtype) {\n\tcase SBUF_EV_CONNECT_OK:\n\tcase SBUF_EV_CONNECT_FAILED:\n\t\t/* ^ those should not happen */\n\tcase SBUF_EV_RECV_FAILED:\n\t\t/*\n\t\t * Don't log error if client disconnects right away,\n\t\t * could be monitoring probe.\n\t\t */\n\t\tif (client->state == CL_LOGIN && mbuf_avail_for_read(data) == 0)\n\t\t\tdisconnect_client(client, false, NULL);\n\t\telse\n\t\t\tdisconnect_client(client, false, \"client unexpected eof\");\n\t\tbreak;\n\tcase SBUF_EV_SEND_FAILED:\n\t\tdisconnect_server(client->link, false, \"server connection closed\");\n\t\tbreak;\n\tcase SBUF_EV_READ:\n\t\t/* Wait until full packet headers is available. */\n\t\tif (incomplete_header(data)) {\n\t\t\tslog_noise(client, \"C: got partial header, trying to wait a bit\");\n\t\t\treturn false;\n\t\t}\n\t\tif (!get_header(data, &pkt)) {\n\t\t\tchar hex[8*2 + 1];\n\t\t\tdisconnect_client(client, true, \"bad packet header: '%s'\",\n\t\t\t\t\t hdr2hex(data, hex, sizeof(hex)));\n\t\t\treturn false;\n\t\t}\n\t\tslog_noise(client, \"read pkt='%c' len=%u\", pkt_desc(&pkt), pkt.len);\n\n\t\t/*\n\t\t * If we are reading an SSL request or GSSAPI\n\t\t * encryption request, we should have no data already\n\t\t * buffered at this point. If we do, it was received\n\t\t * before we performed the SSL or GSSAPI handshake, so\n\t\t * it wasn't encrypted and indeed may have been\n\t\t * injected by a man-in-the-middle. We report this\n\t\t * case to the client.\n\t\t */\n\t\tif (pkt.type == PKT_SSLREQ && mbuf_avail_for_read(data) > 0) {\n\t\t\tdisconnect_client(client, true, \"received unencrypted data after SSL request\");\n\t\t\treturn false;\n\t\t}\n\t\tif (pkt.type == PKT_GSSENCREQ && mbuf_avail_for_read(data) > 0) {\n\t\t\tdisconnect_client(client, true, \"received unencrypted data after GSSAPI encryption request\");\n\t\t\treturn false;\n\t\t}\n\n\t\tclient->request_time = get_cached_time();\n\t\tswitch (client->state) {\n\t\tcase CL_LOGIN:\n\t\t\tres = handle_client_startup(client, &pkt);\n\t\t\tbreak;\n\t\tcase CL_ACTIVE:\n\t\t\tif (client->wait_for_welcome)\n\t\t\t\tres = handle_client_startup(client, &pkt);\n\t\t\telse\n\t\t\t\tres = handle_client_work(client, &pkt);\n\t\t\tbreak;\n\t\tcase CL_WAITING:\n\t\t\tfatal(\"why waiting client in client_proto()\");\n\t\tdefault:\n\t\t\tfatal(\"bad client state: %d\", client->state);\n\t\t}\n\t\tbreak;\n\tcase SBUF_EV_FLUSH:\n\t\t/* client is not interested in it */\n\t\tbreak;\n\tcase SBUF_EV_PKT_CALLBACK:\n\t\t/* unused ATM */\n\t\tbreak;\n\tcase SBUF_EV_TLS_READY:\n\t\tsbuf_continue(&client->sbuf);\n\t\tres = true;\n\t\tbreak;\n\t}\n\treturn res;\n",
51
- "}"]]