summaryrefslogtreecommitdiffstats
path: root/src/include/libpq
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/libpq')
-rw-r--r--src/include/libpq/auth.h31
-rw-r--r--src/include/libpq/be-fsstubs.h32
-rw-r--r--src/include/libpq/be-gssapi-common.h30
-rw-r--r--src/include/libpq/crypt.h47
-rw-r--r--src/include/libpq/hba.h179
-rw-r--r--src/include/libpq/ifaddr.h30
-rw-r--r--src/include/libpq/libpq-be.h343
-rw-r--r--src/include/libpq/libpq-fs.h24
-rw-r--r--src/include/libpq/libpq.h144
-rw-r--r--src/include/libpq/pqcomm.h194
-rw-r--r--src/include/libpq/pqformat.h210
-rw-r--r--src/include/libpq/pqmq.h24
-rw-r--r--src/include/libpq/pqsignal.h42
-rw-r--r--src/include/libpq/sasl.h136
-rw-r--r--src/include/libpq/scram.h30
15 files changed, 1496 insertions, 0 deletions
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
new file mode 100644
index 0000000..d3c189e
--- /dev/null
+++ b/src/include/libpq/auth.h
@@ -0,0 +1,31 @@
+/*-------------------------------------------------------------------------
+ *
+ * auth.h
+ * Definitions for network authentication routines
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/auth.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef AUTH_H
+#define AUTH_H
+
+#include "libpq/libpq-be.h"
+
+extern PGDLLIMPORT char *pg_krb_server_keyfile;
+extern PGDLLIMPORT bool pg_krb_caseins_users;
+extern PGDLLIMPORT char *pg_krb_realm;
+
+extern void ClientAuthentication(Port *port);
+extern void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata,
+ int extralen);
+
+/* Hook for plugins to get control in ClientAuthentication() */
+typedef void (*ClientAuthentication_hook_type) (Port *, int);
+extern PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook;
+
+#endif /* AUTH_H */
diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h
new file mode 100644
index 0000000..130bc30
--- /dev/null
+++ b/src/include/libpq/be-fsstubs.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * be-fsstubs.h
+ *
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/be-fsstubs.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef BE_FSSTUBS_H
+#define BE_FSSTUBS_H
+
+/*
+ * These are not fmgr-callable, but are available to C code.
+ * Probably these should have had the underscore-free names,
+ * but too late now...
+ */
+extern int lo_read(int fd, char *buf, int len);
+extern int lo_write(int fd, const char *buf, int len);
+
+/*
+ * Cleanup LOs at xact commit/abort
+ */
+extern void AtEOXact_LargeObject(bool isCommit);
+extern void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid,
+ SubTransactionId parentSubid);
+
+#endif /* BE_FSSTUBS_H */
diff --git a/src/include/libpq/be-gssapi-common.h b/src/include/libpq/be-gssapi-common.h
new file mode 100644
index 0000000..ae84112
--- /dev/null
+++ b/src/include/libpq/be-gssapi-common.h
@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ *
+ * be-gssapi-common.h
+ * Definitions for GSSAPI authentication and encryption handling
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/be-gssapi-common.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef BE_GSSAPI_COMMON_H
+#define BE_GSSAPI_COMMON_H
+
+#ifdef ENABLE_GSS
+
+#if defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#else
+#include <gssapi/gssapi.h>
+#endif
+
+extern void pg_GSS_error(const char *errmsg,
+ OM_uint32 maj_stat, OM_uint32 min_stat);
+
+#endif /* ENABLE_GSS */
+
+#endif /* BE_GSSAPI_COMMON_H */
diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h
new file mode 100644
index 0000000..3238cf6
--- /dev/null
+++ b/src/include/libpq/crypt.h
@@ -0,0 +1,47 @@
+/*-------------------------------------------------------------------------
+ *
+ * crypt.h
+ * Interface to libpq/crypt.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/crypt.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_CRYPT_H
+#define PG_CRYPT_H
+
+#include "datatype/timestamp.h"
+
+/*
+ * Types of password hashes or secrets.
+ *
+ * Plaintext passwords can be passed in by the user, in a CREATE/ALTER USER
+ * command. They will be encrypted to MD5 or SCRAM-SHA-256 format, before
+ * storing on-disk, so only MD5 and SCRAM-SHA-256 passwords should appear
+ * in pg_authid.rolpassword. They are also the allowed values for the
+ * password_encryption GUC.
+ */
+typedef enum PasswordType
+{
+ PASSWORD_TYPE_PLAINTEXT = 0,
+ PASSWORD_TYPE_MD5,
+ PASSWORD_TYPE_SCRAM_SHA_256
+} PasswordType;
+
+extern PasswordType get_password_type(const char *shadow_pass);
+extern char *encrypt_password(PasswordType target_type, const char *role,
+ const char *password);
+
+extern char *get_role_password(const char *role, const char **logdetail);
+
+extern int md5_crypt_verify(const char *role, const char *shadow_pass,
+ const char *client_pass, const char *md5_salt,
+ int md5_salt_len, const char **logdetail);
+extern int plain_crypt_verify(const char *role, const char *shadow_pass,
+ const char *client_pass,
+ const char **logdetail);
+
+#endif
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
new file mode 100644
index 0000000..d06da81
--- /dev/null
+++ b/src/include/libpq/hba.h
@@ -0,0 +1,179 @@
+/*-------------------------------------------------------------------------
+ *
+ * hba.h
+ * Interface to hba.c
+ *
+ *
+ * src/include/libpq/hba.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef HBA_H
+#define HBA_H
+
+#include "libpq/pqcomm.h" /* pgrminclude ignore */ /* needed for NetBSD */
+#include "nodes/pg_list.h"
+#include "regex/regex.h"
+
+
+/*
+ * The following enum represents the authentication methods that
+ * are supported by PostgreSQL.
+ *
+ * Note: keep this in sync with the UserAuthName array in hba.c.
+ */
+typedef enum UserAuth
+{
+ uaReject,
+ uaImplicitReject, /* Not a user-visible option */
+ uaTrust,
+ uaIdent,
+ uaPassword,
+ uaMD5,
+ uaSCRAM,
+ uaGSS,
+ uaSSPI,
+ uaPAM,
+ uaBSD,
+ uaLDAP,
+ uaCert,
+ uaRADIUS,
+ uaPeer
+#define USER_AUTH_LAST uaPeer /* Must be last value of this enum */
+} UserAuth;
+
+/*
+ * Data structures representing pg_hba.conf entries
+ */
+
+typedef enum IPCompareMethod
+{
+ ipCmpMask,
+ ipCmpSameHost,
+ ipCmpSameNet,
+ ipCmpAll
+} IPCompareMethod;
+
+typedef enum ConnType
+{
+ ctLocal,
+ ctHost,
+ ctHostSSL,
+ ctHostNoSSL,
+ ctHostGSS,
+ ctHostNoGSS,
+} ConnType;
+
+typedef enum ClientCertMode
+{
+ clientCertOff,
+ clientCertCA,
+ clientCertFull
+} ClientCertMode;
+
+typedef enum ClientCertName
+{
+ clientCertCN,
+ clientCertDN
+} ClientCertName;
+
+typedef struct HbaLine
+{
+ int linenumber;
+ char *rawline;
+ ConnType conntype;
+ List *databases;
+ List *roles;
+ struct sockaddr_storage addr;
+ int addrlen; /* zero if we don't have a valid addr */
+ struct sockaddr_storage mask;
+ int masklen; /* zero if we don't have a valid mask */
+ IPCompareMethod ip_cmp_method;
+ char *hostname;
+ UserAuth auth_method;
+ char *usermap;
+ char *pamservice;
+ bool pam_use_hostname;
+ bool ldaptls;
+ char *ldapscheme;
+ char *ldapserver;
+ int ldapport;
+ char *ldapbinddn;
+ char *ldapbindpasswd;
+ char *ldapsearchattribute;
+ char *ldapsearchfilter;
+ char *ldapbasedn;
+ int ldapscope;
+ char *ldapprefix;
+ char *ldapsuffix;
+ ClientCertMode clientcert;
+ ClientCertName clientcertname;
+ char *krb_realm;
+ bool include_realm;
+ bool compat_realm;
+ bool upn_username;
+ List *radiusservers;
+ char *radiusservers_s;
+ List *radiussecrets;
+ char *radiussecrets_s;
+ List *radiusidentifiers;
+ char *radiusidentifiers_s;
+ List *radiusports;
+ char *radiusports_s;
+} HbaLine;
+
+typedef struct IdentLine
+{
+ int linenumber;
+
+ char *usermap;
+ char *ident_user;
+ char *pg_role;
+ regex_t re;
+} IdentLine;
+
+/*
+ * A single string token lexed from an authentication configuration file
+ * (pg_ident.conf or pg_hba.conf), together with whether the token has
+ * been quoted.
+ */
+typedef struct AuthToken
+{
+ char *string;
+ bool quoted;
+} AuthToken;
+
+/*
+ * TokenizedAuthLine represents one line lexed from an authentication
+ * configuration file. Each item in the "fields" list is a sub-list of
+ * AuthTokens. We don't emit a TokenizedAuthLine for empty or all-comment
+ * lines, so "fields" is never NIL (nor are any of its sub-lists).
+ *
+ * Exception: if an error occurs during tokenization, we might have
+ * fields == NIL, in which case err_msg != NULL.
+ */
+typedef struct TokenizedAuthLine
+{
+ List *fields; /* List of lists of AuthTokens */
+ int line_num; /* Line number */
+ char *raw_line; /* Raw line text */
+ char *err_msg; /* Error message if any */
+} TokenizedAuthLine;
+
+/* kluge to avoid including libpq/libpq-be.h here */
+typedef struct Port hbaPort;
+
+extern bool load_hba(void);
+extern bool load_ident(void);
+extern const char *hba_authname(UserAuth auth_method);
+extern void hba_getauthmethod(hbaPort *port);
+extern int check_usermap(const char *usermap_name,
+ const char *pg_role, const char *auth_user,
+ bool case_insensitive);
+extern HbaLine *parse_hba_line(TokenizedAuthLine *tok_line, int elevel);
+extern IdentLine *parse_ident_line(TokenizedAuthLine *tok_line, int elevel);
+extern bool pg_isblank(const char c);
+extern MemoryContext tokenize_auth_file(const char *filename, FILE *file,
+ List **tok_lines, int elevel);
+
+#endif /* HBA_H */
diff --git a/src/include/libpq/ifaddr.h b/src/include/libpq/ifaddr.h
new file mode 100644
index 0000000..b04d093
--- /dev/null
+++ b/src/include/libpq/ifaddr.h
@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ *
+ * ifaddr.h
+ * IP netmask calculations, and enumerating network interfaces.
+ *
+ * Copyright (c) 2003-2022, PostgreSQL Global Development Group
+ *
+ * src/include/libpq/ifaddr.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef IFADDR_H
+#define IFADDR_H
+
+#include "libpq/pqcomm.h" /* pgrminclude ignore */
+
+typedef void (*PgIfAddrCallback) (struct sockaddr *addr,
+ struct sockaddr *netmask,
+ void *cb_data);
+
+extern int pg_range_sockaddr(const struct sockaddr_storage *addr,
+ const struct sockaddr_storage *netaddr,
+ const struct sockaddr_storage *netmask);
+
+extern int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask,
+ char *numbits, int family);
+
+extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data);
+
+#endif /* IFADDR_H */
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
new file mode 100644
index 0000000..351b4f4
--- /dev/null
+++ b/src/include/libpq/libpq-be.h
@@ -0,0 +1,343 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq-be.h
+ * This file contains definitions for structures and externs used
+ * by the postmaster during client authentication.
+ *
+ * Note that this is backend-internal and is NOT exported to clients.
+ * Structs that need to be client-visible are in pqcomm.h.
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/libpq-be.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LIBPQ_BE_H
+#define LIBPQ_BE_H
+
+#include <sys/time.h>
+#ifdef USE_OPENSSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+#ifdef ENABLE_GSS
+#if defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#else
+#include <gssapi/gssapi.h>
+#endif /* HAVE_GSSAPI_H */
+/*
+ * GSSAPI brings in headers that set a lot of things in the global namespace on win32,
+ * that doesn't match the msvc build. It gives a bunch of compiler warnings that we ignore,
+ * but also defines a symbol that simply does not exist. Undefine it again.
+ */
+#ifdef _MSC_VER
+#undef HAVE_GETADDRINFO
+#endif
+#endif /* ENABLE_GSS */
+
+#ifdef ENABLE_SSPI
+#define SECURITY_WIN32
+#if defined(WIN32) && !defined(_MSC_VER)
+#include <ntsecapi.h>
+#endif
+#include <security.h>
+#undef SECURITY_WIN32
+
+#ifndef ENABLE_GSS
+/*
+ * Define a fake structure compatible with GSSAPI on Unix.
+ */
+typedef struct
+{
+ void *value;
+ int length;
+} gss_buffer_desc;
+#endif
+#endif /* ENABLE_SSPI */
+
+#include "datatype/timestamp.h"
+#include "libpq/hba.h"
+#include "libpq/pqcomm.h"
+
+
+typedef enum CAC_state
+{
+ CAC_OK,
+ CAC_STARTUP,
+ CAC_SHUTDOWN,
+ CAC_RECOVERY,
+ CAC_NOTCONSISTENT,
+ CAC_TOOMANY
+} CAC_state;
+
+
+/*
+ * GSSAPI specific state information
+ */
+#if defined(ENABLE_GSS) | defined(ENABLE_SSPI)
+typedef struct
+{
+ gss_buffer_desc outbuf; /* GSSAPI output token buffer */
+#ifdef ENABLE_GSS
+ gss_cred_id_t cred; /* GSSAPI connection cred's */
+ gss_ctx_id_t ctx; /* GSSAPI connection context */
+ gss_name_t name; /* GSSAPI client name */
+ char *princ; /* GSSAPI Principal used for auth, NULL if
+ * GSSAPI auth was not used */
+ bool auth; /* GSSAPI Authentication used */
+ bool enc; /* GSSAPI encryption in use */
+#endif
+} pg_gssinfo;
+#endif
+
+/*
+ * This is used by the postmaster in its communication with frontends. It
+ * contains all state information needed during this communication before the
+ * backend is run. The Port structure is kept in malloc'd memory and is
+ * still available when a backend is running (see MyProcPort). The data
+ * it points to must also be malloc'd, or else palloc'd in TopMemoryContext,
+ * so that it survives into PostgresMain execution!
+ *
+ * remote_hostname is set if we did a successful reverse lookup of the
+ * client's IP address during connection setup.
+ * remote_hostname_resolv tracks the state of hostname verification:
+ * +1 = remote_hostname is known to resolve to client's IP address
+ * -1 = remote_hostname is known NOT to resolve to client's IP address
+ * 0 = we have not done the forward DNS lookup yet
+ * -2 = there was an error in name resolution
+ * If reverse lookup of the client IP address fails, remote_hostname will be
+ * left NULL while remote_hostname_resolv is set to -2. If reverse lookup
+ * succeeds but forward lookup fails, remote_hostname_resolv is also set to -2
+ * (the case is distinguishable because remote_hostname isn't NULL). In
+ * either of the -2 cases, remote_hostname_errcode saves the lookup return
+ * code for possible later use with gai_strerror.
+ */
+
+typedef struct Port
+{
+ pgsocket sock; /* File descriptor */
+ bool noblock; /* is the socket in non-blocking mode? */
+ ProtocolVersion proto; /* FE/BE protocol version */
+ SockAddr laddr; /* local addr (postmaster) */
+ SockAddr raddr; /* remote addr (client) */
+ char *remote_host; /* name (or ip addr) of remote host */
+ char *remote_hostname; /* name (not ip addr) of remote host, if
+ * available */
+ int remote_hostname_resolv; /* see above */
+ int remote_hostname_errcode; /* see above */
+ char *remote_port; /* text rep of remote port */
+ CAC_state canAcceptConnections; /* postmaster connection status */
+
+ /*
+ * Information that needs to be saved from the startup packet and passed
+ * into backend execution. "char *" fields are NULL if not set.
+ * guc_options points to a List of alternating option names and values.
+ */
+ char *database_name;
+ char *user_name;
+ char *cmdline_options;
+ List *guc_options;
+
+ /*
+ * The startup packet application name, only used here for the "connection
+ * authorized" log message. We shouldn't use this post-startup, instead
+ * the GUC should be used as application can change it afterward.
+ */
+ char *application_name;
+
+ /*
+ * Information that needs to be held during the authentication cycle.
+ */
+ HbaLine *hba;
+
+ /*
+ * Authenticated identity. The meaning of this identifier is dependent on
+ * hba->auth_method; it is the identity (if any) that the user presented
+ * during the authentication cycle, before they were assigned a database
+ * role. (It is effectively the "SYSTEM-USERNAME" of a pg_ident usermap
+ * -- though the exact string in use may be different, depending on pg_hba
+ * options.)
+ *
+ * authn_id is NULL if the user has not actually been authenticated, for
+ * example if the "trust" auth method is in use.
+ */
+ const char *authn_id;
+
+ /*
+ * TCP keepalive and user timeout settings.
+ *
+ * default values are 0 if AF_UNIX or not yet known; current values are 0
+ * if AF_UNIX or using the default. Also, -1 in a default value means we
+ * were unable to find out the default (getsockopt failed).
+ */
+ int default_keepalives_idle;
+ int default_keepalives_interval;
+ int default_keepalives_count;
+ int default_tcp_user_timeout;
+ int keepalives_idle;
+ int keepalives_interval;
+ int keepalives_count;
+ int tcp_user_timeout;
+
+ /*
+ * GSSAPI structures.
+ */
+#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
+
+ /*
+ * If GSSAPI is supported and used on this connection, store GSSAPI
+ * information. Even when GSSAPI is not compiled in, store a NULL pointer
+ * to keep struct offsets the same (for extension ABI compatibility).
+ */
+ pg_gssinfo *gss;
+#else
+ void *gss;
+#endif
+
+ /*
+ * SSL structures.
+ */
+ bool ssl_in_use;
+ char *peer_cn;
+ char *peer_dn;
+ bool peer_cert_valid;
+
+ /*
+ * OpenSSL structures. (Keep these last so that the locations of other
+ * fields are the same whether or not you build with SSL enabled.)
+ */
+#ifdef USE_OPENSSL
+ SSL *ssl;
+ X509 *peer;
+#endif
+} Port;
+
+#ifdef USE_SSL
+/*
+ * Hardcoded DH parameters, used in ephemeral DH keying. (See also
+ * README.SSL for more details on EDH.)
+ *
+ * This is the 2048-bit DH parameter from RFC 3526. The generation of the
+ * prime is specified in RFC 2412 Appendix E, which also discusses the
+ * design choice of the generator. Note that when loaded with OpenSSL
+ * this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where
+ * leaking a bit is preferred.
+ */
+#define FILE_DH2048 \
+"-----BEGIN DH PARAMETERS-----\n\
+MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\
+IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\
+awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\
+mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\
+fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\
+5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\
+-----END DH PARAMETERS-----\n"
+
+/*
+ * These functions are implemented by the glue code specific to each
+ * SSL implementation (e.g. be-secure-openssl.c)
+ */
+
+/*
+ * Initialize global SSL context.
+ *
+ * If isServerStart is true, report any errors as FATAL (so we don't return).
+ * Otherwise, log errors at LOG level and return -1 to indicate trouble,
+ * preserving the old SSL state if any. Returns 0 if OK.
+ */
+extern int be_tls_init(bool isServerStart);
+
+/*
+ * Destroy global SSL context, if any.
+ */
+extern void be_tls_destroy(void);
+
+/*
+ * Attempt to negotiate SSL connection.
+ */
+extern int be_tls_open_server(Port *port);
+
+/*
+ * Close SSL connection.
+ */
+extern void be_tls_close(Port *port);
+
+/*
+ * Read data from a secure connection.
+ */
+extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);
+
+/*
+ * Write data to a secure connection.
+ */
+extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor);
+
+/*
+ * Return information about the SSL connection.
+ */
+extern int be_tls_get_cipher_bits(Port *port);
+extern const char *be_tls_get_version(Port *port);
+extern const char *be_tls_get_cipher(Port *port);
+extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len);
+extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len);
+extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);
+
+/*
+ * Get the server certificate hash for SCRAM channel binding type
+ * tls-server-end-point.
+ *
+ * The result is a palloc'd hash of the server certificate with its
+ * size, and NULL if there is no certificate available.
+ *
+ * This is not supported with old versions of OpenSSL that don't have
+ * the X509_get_signature_nid() function.
+ */
+#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO))
+#define HAVE_BE_TLS_GET_CERTIFICATE_HASH
+extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
+#endif
+
+/* init hook for SSL, the default sets the password callback if appropriate */
+#ifdef USE_OPENSSL
+typedef void (*openssl_tls_init_hook_typ) (SSL_CTX *context, bool isServerStart);
+extern PGDLLIMPORT openssl_tls_init_hook_typ openssl_tls_init_hook;
+#endif
+
+#endif /* USE_SSL */
+
+#ifdef ENABLE_GSS
+/*
+ * Return information about the GSSAPI authenticated connection
+ */
+extern bool be_gssapi_get_auth(Port *port);
+extern bool be_gssapi_get_enc(Port *port);
+extern const char *be_gssapi_get_princ(Port *port);
+
+/* Read and write to a GSSAPI-encrypted connection. */
+extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len);
+extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len);
+#endif /* ENABLE_GSS */
+
+extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
+
+/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */
+
+extern int pq_getkeepalivesidle(Port *port);
+extern int pq_getkeepalivesinterval(Port *port);
+extern int pq_getkeepalivescount(Port *port);
+extern int pq_gettcpusertimeout(Port *port);
+
+extern int pq_setkeepalivesidle(int idle, Port *port);
+extern int pq_setkeepalivesinterval(int interval, Port *port);
+extern int pq_setkeepalivescount(int count, Port *port);
+extern int pq_settcpusertimeout(int timeout, Port *port);
+
+#endif /* LIBPQ_BE_H */
diff --git a/src/include/libpq/libpq-fs.h b/src/include/libpq/libpq-fs.h
new file mode 100644
index 0000000..7fa02d2
--- /dev/null
+++ b/src/include/libpq/libpq-fs.h
@@ -0,0 +1,24 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq-fs.h
+ * definitions for using Inversion file system routines (ie, large objects)
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/libpq-fs.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LIBPQ_FS_H
+#define LIBPQ_FS_H
+
+/*
+ * Read/write mode flags for inversion (large object) calls
+ */
+
+#define INV_WRITE 0x00020000
+#define INV_READ 0x00040000
+
+#endif /* LIBPQ_FS_H */
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
new file mode 100644
index 0000000..2de7d9b
--- /dev/null
+++ b/src/include/libpq/libpq.h
@@ -0,0 +1,144 @@
+/*-------------------------------------------------------------------------
+ *
+ * libpq.h
+ * POSTGRES LIBPQ buffer structure definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/libpq.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LIBPQ_H
+#define LIBPQ_H
+
+#include <netinet/in.h>
+
+#include "lib/stringinfo.h"
+#include "libpq/libpq-be.h"
+#include "storage/latch.h"
+
+
+/*
+ * Callers of pq_getmessage() must supply a maximum expected message size.
+ * By convention, if there's not any specific reason to use another value,
+ * use PQ_SMALL_MESSAGE_LIMIT for messages that shouldn't be too long, and
+ * PQ_LARGE_MESSAGE_LIMIT for messages that can be long.
+ */
+#define PQ_SMALL_MESSAGE_LIMIT 10000
+#define PQ_LARGE_MESSAGE_LIMIT (MaxAllocSize - 1)
+
+typedef struct
+{
+ void (*comm_reset) (void);
+ int (*flush) (void);
+ int (*flush_if_writable) (void);
+ bool (*is_send_pending) (void);
+ int (*putmessage) (char msgtype, const char *s, size_t len);
+ void (*putmessage_noblock) (char msgtype, const char *s, size_t len);
+} PQcommMethods;
+
+extern const PGDLLIMPORT PQcommMethods *PqCommMethods;
+
+#define pq_comm_reset() (PqCommMethods->comm_reset())
+#define pq_flush() (PqCommMethods->flush())
+#define pq_flush_if_writable() (PqCommMethods->flush_if_writable())
+#define pq_is_send_pending() (PqCommMethods->is_send_pending())
+#define pq_putmessage(msgtype, s, len) \
+ (PqCommMethods->putmessage(msgtype, s, len))
+#define pq_putmessage_noblock(msgtype, s, len) \
+ (PqCommMethods->putmessage_noblock(msgtype, s, len))
+
+/*
+ * External functions.
+ */
+
+/*
+ * prototypes for functions in pqcomm.c
+ */
+extern PGDLLIMPORT WaitEventSet *FeBeWaitSet;
+
+#define FeBeWaitSetSocketPos 0
+#define FeBeWaitSetLatchPos 1
+#define FeBeWaitSetNEvents 3
+
+extern int StreamServerPort(int family, const char *hostName,
+ unsigned short portNumber, const char *unixSocketDir,
+ pgsocket ListenSocket[], int MaxListen);
+extern int StreamConnection(pgsocket server_fd, Port *port);
+extern void StreamClose(pgsocket sock);
+extern void TouchSocketFiles(void);
+extern void RemoveSocketFiles(void);
+extern void pq_init(void);
+extern int pq_getbytes(char *s, size_t len);
+extern void pq_startmsgread(void);
+extern void pq_endmsgread(void);
+extern bool pq_is_reading_msg(void);
+extern int pq_getmessage(StringInfo s, int maxlen);
+extern int pq_getbyte(void);
+extern int pq_peekbyte(void);
+extern int pq_getbyte_if_available(unsigned char *c);
+extern bool pq_buffer_has_data(void);
+extern int pq_putmessage_v2(char msgtype, const char *s, size_t len);
+extern bool pq_check_connection(void);
+
+/*
+ * prototypes for functions in be-secure.c
+ */
+extern PGDLLIMPORT char *ssl_library;
+extern PGDLLIMPORT char *ssl_cert_file;
+extern PGDLLIMPORT char *ssl_key_file;
+extern PGDLLIMPORT char *ssl_ca_file;
+extern PGDLLIMPORT char *ssl_crl_file;
+extern PGDLLIMPORT char *ssl_crl_dir;
+extern PGDLLIMPORT char *ssl_dh_params_file;
+extern PGDLLIMPORT char *ssl_passphrase_command;
+extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload;
+#ifdef USE_SSL
+extern PGDLLIMPORT bool ssl_loaded_verify_locations;
+#endif
+
+extern int secure_initialize(bool isServerStart);
+extern bool secure_loaded_verify_locations(void);
+extern void secure_destroy(void);
+extern int secure_open_server(Port *port);
+extern void secure_close(Port *port);
+extern ssize_t secure_read(Port *port, void *ptr, size_t len);
+extern ssize_t secure_write(Port *port, void *ptr, size_t len);
+extern ssize_t secure_raw_read(Port *port, void *ptr, size_t len);
+extern ssize_t secure_raw_write(Port *port, const void *ptr, size_t len);
+
+/*
+ * prototypes for functions in be-secure-gssapi.c
+ */
+#ifdef ENABLE_GSS
+extern ssize_t secure_open_gssapi(Port *port);
+#endif
+
+/* GUCs */
+extern PGDLLIMPORT char *SSLCipherSuites;
+extern PGDLLIMPORT char *SSLECDHCurve;
+extern PGDLLIMPORT bool SSLPreferServerCiphers;
+extern PGDLLIMPORT int ssl_min_protocol_version;
+extern PGDLLIMPORT int ssl_max_protocol_version;
+
+enum ssl_protocol_versions
+{
+ PG_TLS_ANY = 0,
+ PG_TLS1_VERSION,
+ PG_TLS1_1_VERSION,
+ PG_TLS1_2_VERSION,
+ PG_TLS1_3_VERSION,
+};
+
+/*
+ * prototypes for functions in be-secure-common.c
+ */
+extern int run_ssl_passphrase_command(const char *prompt, bool is_server_start,
+ char *buf, int size);
+extern bool check_ssl_key_file_permissions(const char *ssl_key_file,
+ bool isServerStart);
+
+#endif /* LIBPQ_H */
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
new file mode 100644
index 0000000..b418283
--- /dev/null
+++ b/src/include/libpq/pqcomm.h
@@ -0,0 +1,194 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqcomm.h
+ * Definitions common to frontends and backends.
+ *
+ * NOTE: for historical reasons, this does not correspond to pqcomm.c.
+ * pqcomm.c's routines are declared in libpq.h.
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/pqcomm.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQCOMM_H
+#define PQCOMM_H
+
+#include <sys/socket.h>
+#include <netdb.h>
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#include <netinet/in.h>
+
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
+#define ss_family __ss_family
+#else
+#error struct sockaddr_storage does not provide an ss_family member
+#endif
+#endif
+
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+#define ss_len __ss_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
+#endif
+#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */
+
+/* Define a struct sockaddr_storage if we don't have one. */
+
+struct sockaddr_storage
+{
+ union
+ {
+ struct sockaddr sa; /* get the system-dependent fields */
+ int64 ss_align; /* ensures struct is properly aligned */
+ char ss_pad[128]; /* ensures struct has desired size */
+ } ss_stuff;
+};
+
+#define ss_family ss_stuff.sa.sa_family
+/* It should have an ss_len field if sockaddr has sa_len. */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+#define ss_len ss_stuff.sa.sa_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
+#endif
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+
+typedef struct
+{
+ struct sockaddr_storage addr;
+ socklen_t salen;
+} SockAddr;
+
+/* Configure the UNIX socket location for the well known port. */
+
+#define UNIXSOCK_PATH(path, port, sockdir) \
+ (AssertMacro(sockdir), \
+ AssertMacro(*(sockdir) != '\0'), \
+ snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \
+ (sockdir), (port)))
+
+/*
+ * The maximum workable length of a socket path is what will fit into
+ * struct sockaddr_un. This is usually only 100 or so bytes :-(.
+ *
+ * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(),
+ * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes.
+ * (Because the standard API for getaddrinfo doesn't allow it to complain in
+ * a useful way when the socket pathname is too long, we have to test for
+ * this explicitly, instead of just letting the subroutine return an error.)
+ */
+#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path)
+
+/*
+ * A host that looks either like an absolute path or starts with @ is
+ * interpreted as a Unix-domain socket address.
+ */
+static inline bool
+is_unixsock_path(const char *path)
+{
+ return is_absolute_path(path) || path[0] == '@';
+}
+
+/*
+ * These manipulate the frontend/backend protocol version number.
+ *
+ * The major number should be incremented for incompatible changes. The minor
+ * number should be incremented for compatible changes (eg. additional
+ * functionality).
+ *
+ * If a backend supports version m.n of the protocol it must actually support
+ * versions m.[0..n]. Backend support for version m-1 can be dropped after a
+ * `reasonable' length of time.
+ *
+ * A frontend isn't required to support anything other than the current
+ * version.
+ */
+
+#define PG_PROTOCOL_MAJOR(v) ((v) >> 16)
+#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff)
+#define PG_PROTOCOL(m,n) (((m) << 16) | (n))
+
+/*
+ * The earliest and latest frontend/backend protocol version supported.
+ * (Only protocol version 3 is currently supported)
+ */
+
+#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0)
+#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0)
+
+typedef uint32 ProtocolVersion; /* FE/BE protocol version number */
+
+typedef ProtocolVersion MsgType;
+
+
+/*
+ * Packet lengths are 4 bytes in network byte order.
+ *
+ * The initial length is omitted from the packet layouts appearing below.
+ */
+
+typedef uint32 PacketLen;
+
+extern PGDLLIMPORT bool Db_user_namespace;
+
+/*
+ * In protocol 3.0 and later, the startup packet length is not fixed, but
+ * we set an arbitrary limit on it anyway. This is just to prevent simple
+ * denial-of-service attacks via sending enough data to run the server
+ * out of memory.
+ */
+#define MAX_STARTUP_PACKET_LENGTH 10000
+
+
+/* These are the authentication request codes sent by the backend. */
+
+#define AUTH_REQ_OK 0 /* User is authenticated */
+#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */
+#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */
+#define AUTH_REQ_PASSWORD 3 /* Password */
+#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */
+#define AUTH_REQ_MD5 5 /* md5 password */
+#define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */
+#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */
+#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */
+#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */
+#define AUTH_REQ_SASL 10 /* Begin SASL authentication */
+#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */
+#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */
+
+typedef uint32 AuthRequest;
+
+
+/*
+ * A client can also send a cancel-current-operation request to the postmaster.
+ * This is uglier than sending it directly to the client's backend, but it
+ * avoids depending on out-of-band communication facilities.
+ *
+ * The cancel request code must not match any protocol version number
+ * we're ever likely to use. This random choice should do.
+ */
+#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)
+
+typedef struct CancelRequestPacket
+{
+ /* Note that each field is stored in network byte order! */
+ MsgType cancelRequestCode; /* code to identify a cancel request */
+ uint32 backendPID; /* PID of client's backend */
+ uint32 cancelAuthCode; /* secret key to authorize cancel */
+} CancelRequestPacket;
+
+
+/*
+ * A client can also start by sending a SSL or GSSAPI negotiation request to
+ * get a secure channel.
+ */
+#define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679)
+#define NEGOTIATE_GSS_CODE PG_PROTOCOL(1234,5680)
+
+#endif /* PQCOMM_H */
diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h
new file mode 100644
index 0000000..cd83482
--- /dev/null
+++ b/src/include/libpq/pqformat.h
@@ -0,0 +1,210 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqformat.h
+ * Definitions for formatting and parsing frontend/backend messages
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/pqformat.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQFORMAT_H
+#define PQFORMAT_H
+
+#include "lib/stringinfo.h"
+#include "mb/pg_wchar.h"
+#include "port/pg_bswap.h"
+
+extern void pq_beginmessage(StringInfo buf, char msgtype);
+extern void pq_beginmessage_reuse(StringInfo buf, char msgtype);
+extern void pq_endmessage(StringInfo buf);
+extern void pq_endmessage_reuse(StringInfo buf);
+
+extern void pq_sendbytes(StringInfo buf, const char *data, int datalen);
+extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen,
+ bool countincludesself);
+extern void pq_sendtext(StringInfo buf, const char *str, int slen);
+extern void pq_sendstring(StringInfo buf, const char *str);
+extern void pq_send_ascii_string(StringInfo buf, const char *str);
+extern void pq_sendfloat4(StringInfo buf, float4 f);
+extern void pq_sendfloat8(StringInfo buf, float8 f);
+
+/*
+ * Append a [u]int8 to a StringInfo buffer, which already has enough space
+ * preallocated.
+ *
+ * The use of pg_restrict allows the compiler to optimize the code based on
+ * the assumption that buf, buf->len, buf->data and *buf->data don't
+ * overlap. Without the annotation buf->len etc cannot be kept in a register
+ * over subsequent pq_writeintN calls.
+ *
+ * The use of StringInfoData * rather than StringInfo is due to MSVC being
+ * overly picky and demanding a * before a restrict.
+ */
+static inline void
+pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
+{
+ uint8 ni = i;
+
+ Assert(buf->len + (int) sizeof(uint8) <= buf->maxlen);
+ memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint8));
+ buf->len += sizeof(uint8);
+}
+
+/*
+ * Append a [u]int16 to a StringInfo buffer, which already has enough space
+ * preallocated.
+ */
+static inline void
+pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
+{
+ uint16 ni = pg_hton16(i);
+
+ Assert(buf->len + (int) sizeof(uint16) <= buf->maxlen);
+ memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint16));
+ buf->len += sizeof(uint16);
+}
+
+/*
+ * Append a [u]int32 to a StringInfo buffer, which already has enough space
+ * preallocated.
+ */
+static inline void
+pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
+{
+ uint32 ni = pg_hton32(i);
+
+ Assert(buf->len + (int) sizeof(uint32) <= buf->maxlen);
+ memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint32));
+ buf->len += sizeof(uint32);
+}
+
+/*
+ * Append a [u]int64 to a StringInfo buffer, which already has enough space
+ * preallocated.
+ */
+static inline void
+pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
+{
+ uint64 ni = pg_hton64(i);
+
+ Assert(buf->len + (int) sizeof(uint64) <= buf->maxlen);
+ memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint64));
+ buf->len += sizeof(uint64);
+}
+
+/*
+ * Append a null-terminated text string (with conversion) to a buffer with
+ * preallocated space.
+ *
+ * NB: The pre-allocated space needs to be sufficient for the string after
+ * converting to client encoding.
+ *
+ * NB: passed text string must be null-terminated, and so is the data
+ * sent to the frontend.
+ */
+static inline void
+pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
+{
+ int slen = strlen(str);
+ char *p;
+
+ p = pg_server_to_client(str, slen);
+ if (p != str) /* actual conversion has been done? */
+ slen = strlen(p);
+
+ Assert(buf->len + slen + 1 <= buf->maxlen);
+
+ memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1);
+ buf->len += slen + 1;
+
+ if (p != str)
+ pfree(p);
+}
+
+/* append a binary [u]int8 to a StringInfo buffer */
+static inline void
+pq_sendint8(StringInfo buf, uint8 i)
+{
+ enlargeStringInfo(buf, sizeof(uint8));
+ pq_writeint8(buf, i);
+}
+
+/* append a binary [u]int16 to a StringInfo buffer */
+static inline void
+pq_sendint16(StringInfo buf, uint16 i)
+{
+ enlargeStringInfo(buf, sizeof(uint16));
+ pq_writeint16(buf, i);
+}
+
+/* append a binary [u]int32 to a StringInfo buffer */
+static inline void
+pq_sendint32(StringInfo buf, uint32 i)
+{
+ enlargeStringInfo(buf, sizeof(uint32));
+ pq_writeint32(buf, i);
+}
+
+/* append a binary [u]int64 to a StringInfo buffer */
+static inline void
+pq_sendint64(StringInfo buf, uint64 i)
+{
+ enlargeStringInfo(buf, sizeof(uint64));
+ pq_writeint64(buf, i);
+}
+
+/* append a binary byte to a StringInfo buffer */
+static inline void
+pq_sendbyte(StringInfo buf, uint8 byt)
+{
+ pq_sendint8(buf, byt);
+}
+
+/*
+ * Append a binary integer to a StringInfo buffer
+ *
+ * This function is deprecated; prefer use of the functions above.
+ */
+static inline void
+pq_sendint(StringInfo buf, uint32 i, int b)
+{
+ switch (b)
+ {
+ case 1:
+ pq_sendint8(buf, (uint8) i);
+ break;
+ case 2:
+ pq_sendint16(buf, (uint16) i);
+ break;
+ case 4:
+ pq_sendint32(buf, (uint32) i);
+ break;
+ default:
+ elog(ERROR, "unsupported integer size %d", b);
+ break;
+ }
+}
+
+
+extern void pq_begintypsend(StringInfo buf);
+extern bytea *pq_endtypsend(StringInfo buf);
+
+extern void pq_puttextmessage(char msgtype, const char *str);
+extern void pq_putemptymessage(char msgtype);
+
+extern int pq_getmsgbyte(StringInfo msg);
+extern unsigned int pq_getmsgint(StringInfo msg, int b);
+extern int64 pq_getmsgint64(StringInfo msg);
+extern float4 pq_getmsgfloat4(StringInfo msg);
+extern float8 pq_getmsgfloat8(StringInfo msg);
+extern const char *pq_getmsgbytes(StringInfo msg, int datalen);
+extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen);
+extern char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes);
+extern const char *pq_getmsgstring(StringInfo msg);
+extern const char *pq_getmsgrawstring(StringInfo msg);
+extern void pq_getmsgend(StringInfo msg);
+
+#endif /* PQFORMAT_H */
diff --git a/src/include/libpq/pqmq.h b/src/include/libpq/pqmq.h
new file mode 100644
index 0000000..6687c8f
--- /dev/null
+++ b/src/include/libpq/pqmq.h
@@ -0,0 +1,24 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqmq.h
+ * Use the frontend/backend protocol for communication over a shm_mq
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/pqmq.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQMQ_H
+#define PQMQ_H
+
+#include "lib/stringinfo.h"
+#include "storage/shm_mq.h"
+
+extern void pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh);
+extern void pq_set_parallel_leader(pid_t pid, BackendId backend_id);
+
+extern void pq_parse_errornotice(StringInfo str, ErrorData *edata);
+
+#endif /* PQMQ_H */
diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h
new file mode 100644
index 0000000..41227a3
--- /dev/null
+++ b/src/include/libpq/pqsignal.h
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------
+ *
+ * pqsignal.h
+ * Backend signal(2) support (see also src/port/pqsignal.c)
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/pqsignal.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PQSIGNAL_H
+#define PQSIGNAL_H
+
+#include <signal.h>
+
+#ifndef WIN32
+#define PG_SETMASK(mask) sigprocmask(SIG_SETMASK, mask, NULL)
+#else
+/* Emulate POSIX sigset_t APIs on Windows */
+typedef int sigset_t;
+
+extern int pqsigsetmask(int mask);
+
+#define PG_SETMASK(mask) pqsigsetmask(*(mask))
+#define sigemptyset(set) (*(set) = 0)
+#define sigfillset(set) (*(set) = ~0)
+#define sigaddset(set, signum) (*(set) |= (sigmask(signum)))
+#define sigdelset(set, signum) (*(set) &= ~(sigmask(signum)))
+#endif /* WIN32 */
+
+extern PGDLLIMPORT sigset_t UnBlockSig;
+extern PGDLLIMPORT sigset_t BlockSig;
+extern PGDLLIMPORT sigset_t StartupBlockSig;
+
+extern void pqinitmask(void);
+
+/* pqsigfunc is declared in src/include/port.h */
+extern pqsigfunc pqsignal_pm(int signo, pqsigfunc func);
+
+#endif /* PQSIGNAL_H */
diff --git a/src/include/libpq/sasl.h b/src/include/libpq/sasl.h
new file mode 100644
index 0000000..39ccf8f
--- /dev/null
+++ b/src/include/libpq/sasl.h
@@ -0,0 +1,136 @@
+/*-------------------------------------------------------------------------
+ *
+ * sasl.h
+ * Defines the SASL mechanism interface for the backend.
+ *
+ * Each SASL mechanism defines a frontend and a backend callback structure.
+ *
+ * See src/interfaces/libpq/fe-auth-sasl.h for the frontend counterpart.
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/sasl.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef PG_SASL_H
+#define PG_SASL_H
+
+#include "lib/stringinfo.h"
+#include "libpq/libpq-be.h"
+
+/* Status codes for message exchange */
+#define PG_SASL_EXCHANGE_CONTINUE 0
+#define PG_SASL_EXCHANGE_SUCCESS 1
+#define PG_SASL_EXCHANGE_FAILURE 2
+
+/*
+ * Backend SASL mechanism callbacks.
+ *
+ * To implement a backend mechanism, declare a pg_be_sasl_mech struct with
+ * appropriate callback implementations. Then pass the mechanism to
+ * CheckSASLAuth() during ClientAuthentication(), once the server has decided
+ * which authentication method to use.
+ */
+typedef struct pg_be_sasl_mech
+{
+ /*---------
+ * get_mechanisms()
+ *
+ * Retrieves the list of SASL mechanism names supported by this
+ * implementation.
+ *
+ * Input parameters:
+ *
+ * port: The client Port
+ *
+ * Output parameters:
+ *
+ * buf: A StringInfo buffer that the callback should populate with
+ * supported mechanism names. The names are appended into this
+ * StringInfo, each one ending with '\0' bytes.
+ *---------
+ */
+ void (*get_mechanisms) (Port *port, StringInfo buf);
+
+ /*---------
+ * init()
+ *
+ * Initializes mechanism-specific state for a connection. This callback
+ * must return a pointer to its allocated state, which will be passed
+ * as-is as the first argument to the other callbacks.
+ *
+ * Input parameters:
+ *
+ * port: The client Port.
+ *
+ * mech: The actual mechanism name in use by the client.
+ *
+ * shadow_pass: The stored secret for the role being authenticated, or
+ * NULL if one does not exist. Mechanisms that do not use
+ * shadow entries may ignore this parameter. If a
+ * mechanism uses shadow entries but shadow_pass is NULL,
+ * the implementation must continue the exchange as if the
+ * user existed and the password did not match, to avoid
+ * disclosing valid user names.
+ *---------
+ */
+ void *(*init) (Port *port, const char *mech, const char *shadow_pass);
+
+ /*---------
+ * exchange()
+ *
+ * Produces a server challenge to be sent to the client. The callback
+ * must return one of the PG_SASL_EXCHANGE_* values, depending on
+ * whether the exchange continues, has finished successfully, or has
+ * failed.
+ *
+ * Input parameters:
+ *
+ * state: The opaque mechanism state returned by init()
+ *
+ * input: The response data sent by the client, or NULL if the
+ * mechanism is client-first but the client did not send an
+ * initial response. (This can only happen during the first
+ * message from the client.) This is guaranteed to be
+ * null-terminated for safety, but SASL allows embedded
+ * nulls in responses, so mechanisms must be careful to
+ * check inputlen.
+ *
+ * inputlen: The length of the challenge data sent by the server, or
+ * -1 if the client did not send an initial response
+ *
+ * Output parameters, to be set by the callback function:
+ *
+ * output: A palloc'd buffer containing either the server's next
+ * challenge (if PG_SASL_EXCHANGE_CONTINUE is returned) or
+ * the server's outcome data (if PG_SASL_EXCHANGE_SUCCESS is
+ * returned and the mechanism requires data to be sent during
+ * a successful outcome). The callback should set this to
+ * NULL if the exchange is over and no output should be sent,
+ * which should correspond to either PG_SASL_EXCHANGE_FAILURE
+ * or a PG_SASL_EXCHANGE_SUCCESS with no outcome data.
+ *
+ * outputlen: The length of the challenge data. Ignored if *output is
+ * NULL.
+ *
+ * logdetail: Set to an optional DETAIL message to be printed to the
+ * server log, to disambiguate failure modes. (The client
+ * will only ever see the same generic authentication
+ * failure message.) Ignored if the exchange is completed
+ * with PG_SASL_EXCHANGE_SUCCESS.
+ *---------
+ */
+ int (*exchange) (void *state,
+ const char *input, int inputlen,
+ char **output, int *outputlen,
+ const char **logdetail);
+} pg_be_sasl_mech;
+
+/* Common implementation for auth.c */
+extern int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port,
+ char *shadow_pass, const char **logdetail);
+
+#endif /* PG_SASL_H */
diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.h
new file mode 100644
index 0000000..c51e848
--- /dev/null
+++ b/src/include/libpq/scram.h
@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ *
+ * scram.h
+ * Interface to libpq/scram.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/scram.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_SCRAM_H
+#define PG_SCRAM_H
+
+#include "lib/stringinfo.h"
+#include "libpq/libpq-be.h"
+#include "libpq/sasl.h"
+
+/* SASL implementation callbacks */
+extern PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech;
+
+/* Routines to handle and check SCRAM-SHA-256 secret */
+extern char *pg_be_scram_build_secret(const char *password);
+extern bool parse_scram_secret(const char *secret, int *iterations, char **salt,
+ uint8 *stored_key, uint8 *server_key);
+extern bool scram_verify_plain_password(const char *username,
+ const char *password, const char *secret);
+
+#endif /* PG_SCRAM_H */