#ifndef LIBPQ_BE_H
#define LIBPQ_BE_H
#include <sys/time.h>
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
#include <netinet/tcp.h>
#ifdef ENABLE_GSS
#if defined(HAVE_GSSAPI_H)
#include <gssapi.h>
#else
#include <gssapi/gssapi.h>
#endif
#endif
#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
typedef struct
{
void *value;
int length;
} gss_buffer_desc;
#endif
#endif
#include "datatype/timestamp.h"
#include "libpq/hba.h"
#include "libpq/pqcomm.h"
#if defined(ENABLE_GSS) | defined(ENABLE_SSPI)
typedef struct
{
gss_buffer_desc outbuf;
#ifdef ENABLE_GSS
gss_cred_id_t cred;
gss_ctx_id_t ctx;
gss_name_t name;
char *princ;
bool auth;
bool enc;
bool delegated_creds;
#endif
} pg_gssinfo;
#endif
typedef struct ClientConnectionInfo
{
const char *authn_id;
UserAuth auth_method;
} ClientConnectionInfo;
typedef struct Port
{
pgsocket sock;
bool noblock;
ProtocolVersion proto;
SockAddr laddr;
SockAddr raddr;
char *remote_host;
char *remote_hostname;
int remote_hostname_resolv;
int remote_hostname_errcode;
char *remote_port;
char *database_name;
char *user_name;
char *cmdline_options;
List *guc_options;
char *application_name;
HbaLine *hba;
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;
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
pg_gssinfo *gss;
#else
void *gss;
#endif
bool ssl_in_use;
char *peer_cn;
char *peer_dn;
bool peer_cert_valid;
bool alpn_used;
#ifdef USE_OPENSSL
SSL *ssl;
X509 *peer;
#endif
char *raw_buf;
ssize_t raw_buf_consumed,
raw_buf_remaining;
} Port;
typedef struct ClientSocket
{
pgsocket sock;
SockAddr raddr;
} ClientSocket;
#ifdef USE_SSL
#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"
extern int be_tls_init(bool isServerStart);
extern void be_tls_destroy(void);
extern int be_tls_open_server(Port *port);
extern void be_tls_close(Port *port);
extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);
extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor);
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);
extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
#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
#ifdef ENABLE_GSS
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);
extern bool be_gssapi_get_delegation(Port *port);
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
extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
extern PGDLLIMPORT ClientConnectionInfo MyClientConnectionInfo;
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