pwn 0.4.633 → 0.4.634

Sign up to get free protection for your applications and to get access to all the features.
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
- "}"]]