PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
sslinfo.c File Reference
#include "postgres.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include "access/htup_details.h"
#include "funcapi.h"
#include "libpq/libpq-be.h"
#include "miscadmin.h"
#include "utils/builtins.h"
Include dependency graph for sslinfo.c:

Go to the source code of this file.

Data Structures

struct  SSLExtensionInfoContext
 

Functions

static Datum X509_NAME_field_to_text (X509_NAME *name, text *fieldName)
 
static Datum X509_NAME_to_text (X509_NAME *name)
 
static Datum ASN1_STRING_to_text (ASN1_STRING *str)
 
 PG_FUNCTION_INFO_V1 (ssl_is_used)
 
Datum ssl_is_used (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_version)
 
Datum ssl_version (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_cipher)
 
Datum ssl_cipher (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_client_cert_present)
 
Datum ssl_client_cert_present (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_client_serial)
 
Datum ssl_client_serial (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_client_dn_field)
 
Datum ssl_client_dn_field (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_issuer_field)
 
Datum ssl_issuer_field (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_client_dn)
 
Datum ssl_client_dn (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_issuer_dn)
 
Datum ssl_issuer_dn (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ssl_extension_info)
 
Datum ssl_extension_info (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

static Datum ASN1_STRING_to_text ( ASN1_STRING *  str)
static

Definition at line 139 of file sslinfo.c.

References cstring_to_text(), elog, ereport, errcode(), errmsg(), ERROR, NULL, pfree(), pg_any_to_server(), PG_RETURN_TEXT_P, and PG_UTF8.

Referenced by X509_NAME_field_to_text().

140 {
141  BIO *membuf;
142  size_t size;
143  char nullterm;
144  char *sp;
145  char *dp;
146  text *result;
147 
148  membuf = BIO_new(BIO_s_mem());
149  if (membuf == NULL)
150  ereport(ERROR,
151  (errcode(ERRCODE_OUT_OF_MEMORY),
152  errmsg("could not create OpenSSL BIO structure")));
153  (void) BIO_set_close(membuf, BIO_CLOSE);
154  ASN1_STRING_print_ex(membuf, str,
155  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
156  | ASN1_STRFLGS_UTF8_CONVERT));
157  /* ensure null termination of the BIO's content */
158  nullterm = '\0';
159  BIO_write(membuf, &nullterm, 1);
160  size = BIO_get_mem_data(membuf, &sp);
161  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
162  result = cstring_to_text(dp);
163  if (dp != sp)
164  pfree(dp);
165  if (BIO_free(membuf) != 1)
166  elog(ERROR, "could not free OpenSSL BIO structure");
167 
168  PG_RETURN_TEXT_P(result);
169 }
int errcode(int sqlerrcode)
Definition: elog.c:575
void pfree(void *pointer)
Definition: mcxt.c:995
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:434
#define elog
Definition: elog.h:218
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:572
PG_FUNCTION_INFO_V1 ( ssl_is_used  )
PG_FUNCTION_INFO_V1 ( ssl_version  )
PG_FUNCTION_INFO_V1 ( ssl_cipher  )
PG_FUNCTION_INFO_V1 ( ssl_client_cert_present  )
PG_FUNCTION_INFO_V1 ( ssl_client_serial  )
PG_FUNCTION_INFO_V1 ( ssl_client_dn_field  )
PG_FUNCTION_INFO_V1 ( ssl_issuer_field  )
PG_FUNCTION_INFO_V1 ( ssl_client_dn  )
PG_FUNCTION_INFO_V1 ( ssl_issuer_dn  )
PG_FUNCTION_INFO_V1 ( ssl_extension_info  )
Datum ssl_cipher ( PG_FUNCTION_ARGS  )

Definition at line 68 of file sslinfo.c.

References cstring_to_text(), MyProcPort, NULL, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

69 {
70  if (MyProcPort->ssl == NULL)
72  PG_RETURN_TEXT_P(cstring_to_text(SSL_get_cipher(MyProcPort->ssl)));
73 }
struct Port * MyProcPort
Definition: globals.c:40
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define NULL
Definition: c.h:226
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_client_cert_present ( PG_FUNCTION_ARGS  )

Definition at line 84 of file sslinfo.c.

References MyProcPort, NULL, and PG_RETURN_BOOL.

85 {
86  PG_RETURN_BOOL(MyProcPort->peer != NULL);
87 }
struct Port * MyProcPort
Definition: globals.c:40
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
#define NULL
Definition: c.h:226
Datum ssl_client_dn ( PG_FUNCTION_ARGS  )

Definition at line 359 of file sslinfo.c.

References MyProcPort, PG_RETURN_NULL, and X509_NAME_to_text().

360 {
361  if (!(MyProcPort->peer))
362  PG_RETURN_NULL();
363  return X509_NAME_to_text(X509_get_subject_name(MyProcPort->peer));
364 }
struct Port * MyProcPort
Definition: globals.c:40
static Datum X509_NAME_to_text(X509_NAME *name)
Definition: sslinfo.c:290
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_client_dn_field ( PG_FUNCTION_ARGS  )

Definition at line 226 of file sslinfo.c.

References MyProcPort, PG_GETARG_TEXT_P, PG_RETURN_NULL, and X509_NAME_field_to_text().

227 {
228  text *fieldname = PG_GETARG_TEXT_P(0);
229  Datum result;
230 
231  if (!(MyProcPort->peer))
232  PG_RETURN_NULL();
233 
234  result = X509_NAME_field_to_text(X509_get_subject_name(MyProcPort->peer), fieldname);
235 
236  if (!result)
237  PG_RETURN_NULL();
238  else
239  return result;
240 }
struct Port * MyProcPort
Definition: globals.c:40
static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
Definition: sslinfo.c:185
uintptr_t Datum
Definition: postgres.h:374
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:434
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_client_serial ( PG_FUNCTION_ARGS  )

Definition at line 100 of file sslinfo.c.

References CStringGetDatum, DirectFunctionCall3, Int32GetDatum, MyProcPort, NULL, numeric_in(), ObjectIdGetDatum, PG_RETURN_NULL, and port.

101 {
102  Datum result;
103  Port *port = MyProcPort;
104  X509 *peer = port->peer;
105  ASN1_INTEGER *serial = NULL;
106  BIGNUM *b;
107  char *decimal;
108 
109  if (!peer)
110  PG_RETURN_NULL();
111  serial = X509_get_serialNumber(peer);
112  b = ASN1_INTEGER_to_BN(serial, NULL);
113  decimal = BN_bn2dec(b);
114 
115  BN_free(b);
117  CStringGetDatum(decimal),
118  ObjectIdGetDatum(0),
119  Int32GetDatum(-1));
120  OPENSSL_free(decimal);
121  return result;
122 }
struct Port * MyProcPort
Definition: globals.c:40
Definition: libpq-be.h:118
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define CStringGetDatum(X)
Definition: postgres.h:586
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:508
static int port
Definition: pg_regress.c:87
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:552
uintptr_t Datum
Definition: postgres.h:374
#define NULL
Definition: c.h:226
#define Int32GetDatum(X)
Definition: postgres.h:487
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_extension_info ( PG_FUNCTION_ARGS  )

Definition at line 396 of file sslinfo.c.

References BlessTupleDesc(), BoolGetDatum, buf, FuncCallContext::call_cntr, cstring_to_text_with_len(), CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum, FuncCallContext::max_calls, MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, MyProcPort, NULL, palloc(), PointerGetDatum, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, SSLExtensionInfoContext::tupdesc, TYPEFUNC_COMPOSITE, FuncCallContext::user_fctx, and values.

397 {
398  X509 *cert = MyProcPort->peer;
399  FuncCallContext *funcctx;
400  int call_cntr;
401  int max_calls;
402  MemoryContext oldcontext;
404 
405  STACK_OF(X509_EXTENSION) *ext_stack = NULL;
406 
407  if (SRF_IS_FIRSTCALL())
408  {
409 
410  TupleDesc tupdesc;
411 
412  /* create a function context for cross-call persistence */
413  funcctx = SRF_FIRSTCALL_INIT();
414 
415  /*
416  * Switch to memory context appropriate for multiple function calls
417  */
418  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
419 
420  /* Create a user function context for cross-call persistence */
422 
423  /* Construct tuple descriptor */
424  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
425  ereport(ERROR,
426  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
427  errmsg("function returning record called in context that cannot accept type record")));
428  fctx->tupdesc = BlessTupleDesc(tupdesc);
429 
430  /* Get all extensions of certificate */
431  if (cert && cert->cert_info)
432  ext_stack = cert->cert_info->extensions;
433 
434  /* Set max_calls as a count of extensions in certificate */
435  max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
436 
437  if (cert != NULL &&
438  ext_stack != NULL &&
439  max_calls > 0)
440  {
441  /* got results, keep track of them */
442  funcctx->max_calls = max_calls;
443  funcctx->user_fctx = fctx;
444  }
445  else
446  {
447  /* fast track when no results */
448  MemoryContextSwitchTo(oldcontext);
449  SRF_RETURN_DONE(funcctx);
450  }
451 
452  MemoryContextSwitchTo(oldcontext);
453  }
454 
455  /* stuff done on every call of the function */
456  funcctx = SRF_PERCALL_SETUP();
457 
458  /*
459  * Initialize per-call variables.
460  */
461  call_cntr = funcctx->call_cntr;
462  max_calls = funcctx->max_calls;
463  fctx = funcctx->user_fctx;
464 
465  ext_stack = cert->cert_info->extensions;
466 
467  /* do while there are more left to send */
468  if (call_cntr < max_calls)
469  {
470  Datum values[3];
471  bool nulls[3];
472  char *buf;
473  HeapTuple tuple;
474  Datum result;
475  BIO *membuf;
476  X509_EXTENSION *ext;
477  ASN1_OBJECT *obj;
478  int nid;
479  int len;
480 
481  /* need a BIO for this */
482  membuf = BIO_new(BIO_s_mem());
483  if (membuf == NULL)
484  ereport(ERROR,
485  (errcode(ERRCODE_OUT_OF_MEMORY),
486  errmsg("could not create OpenSSL BIO structure")));
487 
488  /* Get the extension from the certificate */
489  ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
490  obj = X509_EXTENSION_get_object(ext);
491 
492  /* Get the extension name */
493  nid = OBJ_obj2nid(obj);
494  if (nid == NID_undef)
495  ereport(ERROR,
496  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
497  errmsg("unknown OpenSSL extension in certificate at position %d",
498  call_cntr)));
499  values[0] = CStringGetTextDatum(OBJ_nid2sn(nid));
500  nulls[0] = false;
501 
502  /* Get the extension value */
503  if (X509V3_EXT_print(membuf, ext, 0, 0) <= 0)
504  ereport(ERROR,
505  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
506  errmsg("could not print extension value in certificate at position %d",
507  call_cntr)));
508  len = BIO_get_mem_data(membuf, &buf);
509  values[1] = PointerGetDatum(cstring_to_text_with_len(buf, len));
510  nulls[1] = false;
511 
512  /* Get critical status */
513  values[2] = BoolGetDatum(X509_EXTENSION_get_critical(ext));
514  nulls[2] = false;
515 
516  /* Build tuple */
517  tuple = heap_form_tuple(fctx->tupdesc, values, nulls);
518  result = HeapTupleGetDatum(tuple);
519 
520  if (BIO_free(membuf) != 1)
521  elog(ERROR, "could not free OpenSSL BIO structure");
522 
523  SRF_RETURN_NEXT(funcctx, result);
524  }
525 
526  /* All done */
527  SRF_RETURN_DONE(funcctx);
528 }
uint64 call_cntr
Definition: funcapi.h:65
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:212
struct Port * MyProcPort
Definition: globals.c:40
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:285
#define PointerGetDatum(X)
Definition: postgres.h:564
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:575
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:289
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:291
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1034
static char * buf
Definition: pg_test_fsync.c:65
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define NULL
Definition: c.h:226
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:109
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
static Datum values[MAXATTR]
Definition: bootstrap.c:160
void * user_fctx
Definition: funcapi.h:90
void * palloc(Size size)
Definition: mcxt.c:894
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CStringGetTextDatum(s)
Definition: builtins.h:808
#define elog
Definition: elog.h:218
uint64 max_calls
Definition: funcapi.h:74
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:309
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:287
Datum ssl_is_used ( PG_FUNCTION_ARGS  )

Definition at line 44 of file sslinfo.c.

References MyProcPort, PG_RETURN_BOOL, and Port::ssl_in_use.

45 {
47 }
struct Port * MyProcPort
Definition: globals.c:40
bool ssl_in_use
Definition: libpq-be.h:184
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
Datum ssl_issuer_dn ( PG_FUNCTION_ARGS  )

Definition at line 378 of file sslinfo.c.

References MyProcPort, PG_RETURN_NULL, and X509_NAME_to_text().

379 {
380  if (!(MyProcPort->peer))
381  PG_RETURN_NULL();
382  return X509_NAME_to_text(X509_get_issuer_name(MyProcPort->peer));
383 }
struct Port * MyProcPort
Definition: globals.c:40
static Datum X509_NAME_to_text(X509_NAME *name)
Definition: sslinfo.c:290
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_issuer_field ( PG_FUNCTION_ARGS  )

Definition at line 261 of file sslinfo.c.

References MyProcPort, PG_GETARG_TEXT_P, PG_RETURN_NULL, and X509_NAME_field_to_text().

262 {
263  text *fieldname = PG_GETARG_TEXT_P(0);
264  Datum result;
265 
266  if (!(MyProcPort->peer))
267  PG_RETURN_NULL();
268 
269  result = X509_NAME_field_to_text(X509_get_issuer_name(MyProcPort->peer), fieldname);
270 
271  if (!result)
272  PG_RETURN_NULL();
273  else
274  return result;
275 }
struct Port * MyProcPort
Definition: globals.c:40
static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
Definition: sslinfo.c:185
uintptr_t Datum
Definition: postgres.h:374
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:434
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum ssl_version ( PG_FUNCTION_ARGS  )

Definition at line 55 of file sslinfo.c.

References cstring_to_text(), MyProcPort, NULL, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

56 {
57  if (MyProcPort->ssl == NULL)
59  PG_RETURN_TEXT_P(cstring_to_text(SSL_get_version(MyProcPort->ssl)));
60 }
struct Port * MyProcPort
Definition: globals.c:40
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define NULL
Definition: c.h:226
#define PG_RETURN_NULL()
Definition: fmgr.h:289
static Datum X509_NAME_field_to_text ( X509_NAME *  name,
text fieldName 
)
static

Definition at line 185 of file sslinfo.c.

References ASN1_STRING_to_text(), ereport, errcode(), errmsg(), ERROR, pfree(), and text_to_cstring().

Referenced by ssl_client_dn_field(), and ssl_issuer_field().

186 {
187  char *string_fieldname;
188  int nid,
189  index;
190  ASN1_STRING *data;
191 
192  string_fieldname = text_to_cstring(fieldName);
193  nid = OBJ_txt2nid(string_fieldname);
194  if (nid == NID_undef)
195  ereport(ERROR,
196  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
197  errmsg("invalid X.509 field name: \"%s\"",
198  string_fieldname)));
199  pfree(string_fieldname);
200  index = X509_NAME_get_index_by_NID(name, nid, -1);
201  if (index < 0)
202  return (Datum) 0;
203  data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, index));
204  return ASN1_STRING_to_text(data);
205 }
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: type.h:90
static Datum ASN1_STRING_to_text(ASN1_STRING *str)
Definition: sslinfo.c:139
void pfree(void *pointer)
Definition: mcxt.c:995
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
const char * name
Definition: encode.c:521
char * text_to_cstring(const text *t)
Definition: varlena.c:183
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Datum X509_NAME_to_text ( X509_NAME *  name)
static

Definition at line 290 of file sslinfo.c.

References cstring_to_text(), elog, ereport, errcode(), errmsg(), ERROR, i, NULL, pfree(), pg_any_to_server(), PG_RETURN_TEXT_P, and PG_UTF8.

Referenced by ssl_client_dn(), and ssl_issuer_dn().

291 {
292  BIO *membuf = BIO_new(BIO_s_mem());
293  int i,
294  nid,
295  count = X509_NAME_entry_count(name);
296  X509_NAME_ENTRY *e;
297  ASN1_STRING *v;
298  const char *field_name;
299  size_t size;
300  char nullterm;
301  char *sp;
302  char *dp;
303  text *result;
304 
305  if (membuf == NULL)
306  ereport(ERROR,
307  (errcode(ERRCODE_OUT_OF_MEMORY),
308  errmsg("could not create OpenSSL BIO structure")));
309 
310  (void) BIO_set_close(membuf, BIO_CLOSE);
311  for (i = 0; i < count; i++)
312  {
313  e = X509_NAME_get_entry(name, i);
314  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
315  if (nid == NID_undef)
316  ereport(ERROR,
317  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
318  errmsg("could not get NID for ASN1_OBJECT object")));
319  v = X509_NAME_ENTRY_get_data(e);
320  field_name = OBJ_nid2sn(nid);
321  if (field_name == NULL)
322  field_name = OBJ_nid2ln(nid);
323  if (field_name == NULL)
324  ereport(ERROR,
325  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
326  errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
327  BIO_printf(membuf, "/%s=", field_name);
328  ASN1_STRING_print_ex(membuf, v,
329  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
330  | ASN1_STRFLGS_UTF8_CONVERT));
331  }
332 
333  /* ensure null termination of the BIO's content */
334  nullterm = '\0';
335  BIO_write(membuf, &nullterm, 1);
336  size = BIO_get_mem_data(membuf, &sp);
337  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
338  result = cstring_to_text(dp);
339  if (dp != sp)
340  pfree(dp);
341  if (BIO_free(membuf) != 1)
342  elog(ERROR, "could not free OpenSSL BIO structure");
343 
344  PG_RETURN_TEXT_P(result);
345 }
int errcode(int sqlerrcode)
Definition: elog.c:575
void pfree(void *pointer)
Definition: mcxt.c:995
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define NULL
Definition: c.h:226
const char * name
Definition: encode.c:521
e
Definition: preproc-init.c:82
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: c.h:434
#define elog
Definition: elog.h:218
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:572

Variable Documentation

PG_MODULE_MAGIC

Definition at line 22 of file sslinfo.c.