pwn 0.4.609 → 0.4.610

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: d266f62ccaadca3ce9efa5c9e1b66ca621588abf5fc69da139627518a4dd5424
4
- data.tar.gz: 01540ec202be3300c1201fa1850003fc70e432174173ab61689e450b3dcdb02b
3
+ metadata.gz: 0446e4910a77fbad2d9cd1741ca3512381159942a04e6e62ac8f20e3c533909e
4
+ data.tar.gz: c52ebec64bb57ab09834bb6b342b0fcd671f798c3b83012146282f7c41ab0ece
5
5
  SHA512:
6
- metadata.gz: 2302c33df731deac43e9e70c37836f908ca68dcee42257052b69cdd9d6826d088640709883357ff9d00c3fadfc1e9f6f39ca2b72a95feda32150c9d910d6cb56
7
- data.tar.gz: bef4e8c1d3cd6c38c580d113ce3f4bc47cfec0ea93673a3062256202d2fcaaae2359b01adc314f677c525ef40cecc60222b08e1363d2be6b6fb9814a75e0c2a7
6
+ metadata.gz: 93ff9c664ff6885e5a8d328dc67ed331692e3d507f7eea7065e602d5decc3e255157c7575a548373fffb8ecf83c7b587b4fde9dbffecda062a9219018f4a651e
7
+ data.tar.gz: ff3d9b90e7dfe11638822dc1e5da4b1d0e67fa9e790c69af935f0828b72a154efe5d6649dd52a54240bd0bbb6ad1926604a1cfdd8a530fed4576ea00ba11583d
@@ -0,0 +1,51 @@
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
+ "}"]]
data/Gemfile CHANGED
@@ -11,16 +11,16 @@ gemspec
11
11
  # In some circumstances custom flags are passed to gems in order
12
12
  # to build appropriately. Defer to ./reinstall_pwn_gemset.sh
13
13
  # to review these custom flags (e.g. pg, serialport, etc).
14
- gem 'activesupport', '7.0.4.1'
14
+ gem 'activesupport', '7.0.4.2'
15
15
  gem 'anemone', '0.7.2'
16
16
  gem 'authy', '3.0.1'
17
17
  gem 'aws-sdk', '3.1.0'
18
18
  gem 'bettercap', '1.6.2'
19
19
  gem 'brakeman', '5.4.0'
20
20
  gem 'bson', '4.15.0'
21
- gem 'bundler', '>=2.4.5'
21
+ gem 'bundler', '>=2.4.6'
22
22
  gem 'bundler-audit', '0.9.1'
23
- gem 'bunny', '2.20.2'
23
+ gem 'bunny', '2.20.3'
24
24
  gem 'colorize', '0.8.1'
25
25
  gem 'credit_card_validations', '6.0.0'
26
26
  gem 'eventmachine', '1.2.7'
@@ -37,16 +37,16 @@ gem 'ipaddress', '0.8.3'
37
37
  gem 'js-beautify', '0.1.8'
38
38
  gem 'json', '2.6.3'
39
39
  gem 'jsonpath', '1.1.2'
40
- gem 'jwt', '2.6.0'
40
+ gem 'jwt', '2.7.0'
41
41
  gem 'luhn', '1.0.2'
42
- gem 'mail', '2.8.0.1'
42
+ gem 'mail', '2.8.1'
43
43
  gem 'mongo', '2.18.2'
44
44
  gem 'msfrpc-client', '1.1.2'
45
45
  gem 'net-ldap', '0.17.1'
46
46
  gem 'net-openvpn', '0.8.7'
47
47
  gem 'net-smtp', '0.3.3'
48
48
  gem 'nexpose', '7.3.0'
49
- gem 'nokogiri', '1.14.0'
49
+ gem 'nokogiri', '1.14.1'
50
50
  gem 'oily_png', '1.2.1'
51
51
  gem 'os', '1.1.4'
52
52
  gem 'packetfu', '1.1.13'
@@ -63,7 +63,7 @@ gem 'rex', '2.0.13'
63
63
  gem 'rmagick', '5.1.0'
64
64
  gem 'rspec', '3.12.0'
65
65
  gem 'rtesseract', '3.1.2'
66
- gem 'rubocop', '1.44.0'
66
+ gem 'rubocop', '1.44.1'
67
67
  gem 'rubocop-rake', '0.6.0'
68
68
  gem 'rubocop-rspec', '2.18.1'
69
69
  gem 'ruby-audio', '1.6.1'
@@ -82,8 +82,7 @@ gem 'thin', '1.8.1'
82
82
  gem 'tty-prompt', '0.23.1'
83
83
  gem 'watir', '7.2.2'
84
84
  gem 'waveform', '0.1.2'
85
- gem 'webrick', '1.7.0'
85
+ gem 'webrick', '1.8.1'
86
86
  gem 'whois', '5.1.0'
87
87
  gem 'whois-parser', '2.0.0'
88
88
  gem 'wicked_pdf', '2.6.3'
89
- gem 'yard', '0.9.28'
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ rvm use ruby-3.2.0@pwn
37
37
  $ rvm list gemsets
38
38
  $ gem install --verbose pwn
39
39
  $ pwn
40
- pwn[v0.4.609]:001 >>> PWN.help
40
+ pwn[v0.4.610]: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.0@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.4.609]:001 >>> PWN.help
55
+ pwn[v0.4.610]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
 
@@ -59,6 +59,7 @@ begin
59
59
  query: query
60
60
  )
61
61
  puts " >>> Matches: #{search_results[:total]}"
62
+ sleep 1
62
63
 
63
64
  raw_results = {}
64
65
  raw_results[:query] = query
data/build_pwn_gem.sh CHANGED
@@ -14,6 +14,8 @@ rvmsudo git config pull.rebase false
14
14
  rvmsudo git pull
15
15
  new_ruby_version=`cat ${pwn_root}/.ruby-version`
16
16
 
17
+ rvmsudo gem update --system
18
+
17
19
  if [[ $old_ruby_version == $new_ruby_version ]]; then
18
20
  export rvmsudo_secure_path=1
19
21
  rvmsudo /bin/bash --login -c "cd ${pwn_root} && ./reinstall_pwn_gemset.sh"
@@ -21,7 +23,6 @@ if [[ $old_ruby_version == $new_ruby_version ]]; then
21
23
  rvmsudo rake
22
24
  rvmsudo rake install
23
25
  rvmsudo rake rerdoc
24
- rvmsudo gem update --system
25
26
  rvmsudo gem rdoc --rdoc --ri --overwrite -V pwn
26
27
  echo "Invoking bundle-audit Gemfile Scanner..."
27
28
  rvmsudo bundle-audit
@@ -1,4 +1,7 @@
1
1
  #!/bin/bash --login
2
+ export rvmsudo_secure_path=1
3
+ rvmsudo gem update --system
4
+
2
5
  cat Gemfile | awk '{print $2}' | grep -E "^'.+$" | grep -v -e rubygems.org | while read gem; do
3
6
  this_gem=`echo $gem | sed "s/'//g" | sed 's/\,//g'`
4
7
  latest_version=`gem search -r $this_gem | grep -E "^${this_gem}\s.+$" | awk '{print $2}' | sed 's/(//g' | sed 's/)//g' | sed 's/,//g'`
@@ -63,6 +63,10 @@ module PWN
63
63
  raise @@logger.error("Unsupported HTTP Method #{http_method} for #{self} Plugin")
64
64
  end
65
65
  response
66
+ rescue RestClient::TooManyRequests
67
+ print 'Too many requests. Sleeping 10s...'
68
+ sleep 10
69
+ retry
66
70
  rescue StandardError => e
67
71
  case e.message
68
72
  when '400 Bad Request', '404 Resource Not Found'
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.609'
4
+ VERSION = '0.4.610'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.609
4
+ version: 0.4.610
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-24 00:00:00.000000000 Z
11
+ date: 2023-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.4.1
19
+ version: 7.0.4.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.4.1
26
+ version: 7.0.4.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: anemone
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: 2.4.5
117
+ version: 2.4.6
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: 2.4.5
124
+ version: 2.4.6
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: bundler-audit
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 2.20.2
145
+ version: 2.20.3
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 2.20.2
152
+ version: 2.20.3
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: colorize
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -366,14 +366,14 @@ dependencies:
366
366
  requirements:
367
367
  - - '='
368
368
  - !ruby/object:Gem::Version
369
- version: 2.6.0
369
+ version: 2.7.0
370
370
  type: :runtime
371
371
  prerelease: false
372
372
  version_requirements: !ruby/object:Gem::Requirement
373
373
  requirements:
374
374
  - - '='
375
375
  - !ruby/object:Gem::Version
376
- version: 2.6.0
376
+ version: 2.7.0
377
377
  - !ruby/object:Gem::Dependency
378
378
  name: luhn
379
379
  requirement: !ruby/object:Gem::Requirement
@@ -394,14 +394,14 @@ dependencies:
394
394
  requirements:
395
395
  - - '='
396
396
  - !ruby/object:Gem::Version
397
- version: 2.8.0.1
397
+ version: 2.8.1
398
398
  type: :runtime
399
399
  prerelease: false
400
400
  version_requirements: !ruby/object:Gem::Requirement
401
401
  requirements:
402
402
  - - '='
403
403
  - !ruby/object:Gem::Version
404
- version: 2.8.0.1
404
+ version: 2.8.1
405
405
  - !ruby/object:Gem::Dependency
406
406
  name: mongo
407
407
  requirement: !ruby/object:Gem::Requirement
@@ -492,14 +492,14 @@ dependencies:
492
492
  requirements:
493
493
  - - '='
494
494
  - !ruby/object:Gem::Version
495
- version: 1.14.0
495
+ version: 1.14.1
496
496
  type: :runtime
497
497
  prerelease: false
498
498
  version_requirements: !ruby/object:Gem::Requirement
499
499
  requirements:
500
500
  - - '='
501
501
  - !ruby/object:Gem::Version
502
- version: 1.14.0
502
+ version: 1.14.1
503
503
  - !ruby/object:Gem::Dependency
504
504
  name: oily_png
505
505
  requirement: !ruby/object:Gem::Requirement
@@ -730,14 +730,14 @@ dependencies:
730
730
  requirements:
731
731
  - - '='
732
732
  - !ruby/object:Gem::Version
733
- version: 1.44.0
733
+ version: 1.44.1
734
734
  type: :runtime
735
735
  prerelease: false
736
736
  version_requirements: !ruby/object:Gem::Requirement
737
737
  requirements:
738
738
  - - '='
739
739
  - !ruby/object:Gem::Version
740
- version: 1.44.0
740
+ version: 1.44.1
741
741
  - !ruby/object:Gem::Dependency
742
742
  name: rubocop-rake
743
743
  requirement: !ruby/object:Gem::Requirement
@@ -996,14 +996,14 @@ dependencies:
996
996
  requirements:
997
997
  - - '='
998
998
  - !ruby/object:Gem::Version
999
- version: 1.7.0
999
+ version: 1.8.1
1000
1000
  type: :runtime
1001
1001
  prerelease: false
1002
1002
  version_requirements: !ruby/object:Gem::Requirement
1003
1003
  requirements:
1004
1004
  - - '='
1005
1005
  - !ruby/object:Gem::Version
1006
- version: 1.7.0
1006
+ version: 1.8.1
1007
1007
  - !ruby/object:Gem::Dependency
1008
1008
  name: whois
1009
1009
  requirement: !ruby/object:Gem::Requirement
@@ -1046,20 +1046,6 @@ dependencies:
1046
1046
  - - '='
1047
1047
  - !ruby/object:Gem::Version
1048
1048
  version: 2.6.3
1049
- - !ruby/object:Gem::Dependency
1050
- name: yard
1051
- requirement: !ruby/object:Gem::Requirement
1052
- requirements:
1053
- - - '='
1054
- - !ruby/object:Gem::Version
1055
- version: 0.9.28
1056
- type: :runtime
1057
- prerelease: false
1058
- version_requirements: !ruby/object:Gem::Requirement
1059
- requirements:
1060
- - - '='
1061
- - !ruby/object:Gem::Version
1062
- version: 0.9.28
1063
1049
  description: https://github.com/0dayinc/pwn/README.md
1064
1050
  email:
1065
1051
  - request.pentest@0dayinc.com
@@ -1113,6 +1099,7 @@ executables:
1113
1099
  extensions: []
1114
1100
  extra_rdoc_files: []
1115
1101
  files:
1102
+ - ".each do |bytes_matched|"
1116
1103
  - ".github/FUNDING.yml"
1117
1104
  - ".github/ISSUE_TEMPLATE/bug_report.md"
1118
1105
  - ".gitignore"
@@ -2078,7 +2065,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2078
2065
  - !ruby/object:Gem::Version
2079
2066
  version: '0'
2080
2067
  requirements: []
2081
- rubygems_version: 3.4.5
2068
+ rubygems_version: 3.4.6
2082
2069
  signing_key:
2083
2070
  specification_version: 4
2084
2071
  summary: Automated Security Testing for CI/CD Pipelines & Beyond