summaryrefslogtreecommitdiffstats
path: root/src/include/libpq/sasl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/libpq/sasl.h')
-rw-r--r--src/include/libpq/sasl.h136
1 files changed, 136 insertions, 0 deletions
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 */