sasl.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*-------------------------------------------------------------------------
  2. *
  3. * sasl.h
  4. * Defines the SASL mechanism interface for the backend.
  5. *
  6. * Each SASL mechanism defines a frontend and a backend callback structure.
  7. *
  8. * See src/interfaces/libpq/fe-auth-sasl.h for the frontend counterpart.
  9. *
  10. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  11. * Portions Copyright (c) 1994, Regents of the University of California
  12. *
  13. * src/include/libpq/sasl.h
  14. *
  15. *-------------------------------------------------------------------------
  16. */
  17. #ifndef PG_SASL_H
  18. #define PG_SASL_H
  19. #include "lib/stringinfo.h"
  20. #include "libpq/libpq-be.h"
  21. /* Status codes for message exchange */
  22. #define PG_SASL_EXCHANGE_CONTINUE 0
  23. #define PG_SASL_EXCHANGE_SUCCESS 1
  24. #define PG_SASL_EXCHANGE_FAILURE 2
  25. /*
  26. * Backend SASL mechanism callbacks.
  27. *
  28. * To implement a backend mechanism, declare a pg_be_sasl_mech struct with
  29. * appropriate callback implementations. Then pass the mechanism to
  30. * CheckSASLAuth() during ClientAuthentication(), once the server has decided
  31. * which authentication method to use.
  32. */
  33. typedef struct pg_be_sasl_mech
  34. {
  35. /*---------
  36. * get_mechanisms()
  37. *
  38. * Retrieves the list of SASL mechanism names supported by this
  39. * implementation.
  40. *
  41. * Input parameters:
  42. *
  43. * port: The client Port
  44. *
  45. * Output parameters:
  46. *
  47. * buf: A StringInfo buffer that the callback should populate with
  48. * supported mechanism names. The names are appended into this
  49. * StringInfo, each one ending with '\0' bytes.
  50. *---------
  51. */
  52. void (*get_mechanisms) (Port *port, StringInfo buf);
  53. /*---------
  54. * init()
  55. *
  56. * Initializes mechanism-specific state for a connection. This callback
  57. * must return a pointer to its allocated state, which will be passed
  58. * as-is as the first argument to the other callbacks.
  59. *
  60. * Input parameters:
  61. *
  62. * port: The client Port.
  63. *
  64. * mech: The actual mechanism name in use by the client.
  65. *
  66. * shadow_pass: The stored secret for the role being authenticated, or
  67. * NULL if one does not exist. Mechanisms that do not use
  68. * shadow entries may ignore this parameter. If a
  69. * mechanism uses shadow entries but shadow_pass is NULL,
  70. * the implementation must continue the exchange as if the
  71. * user existed and the password did not match, to avoid
  72. * disclosing valid user names.
  73. *---------
  74. */
  75. void *(*init) (Port *port, const char *mech, const char *shadow_pass);
  76. /*---------
  77. * exchange()
  78. *
  79. * Produces a server challenge to be sent to the client. The callback
  80. * must return one of the PG_SASL_EXCHANGE_* values, depending on
  81. * whether the exchange continues, has finished successfully, or has
  82. * failed.
  83. *
  84. * Input parameters:
  85. *
  86. * state: The opaque mechanism state returned by init()
  87. *
  88. * input: The response data sent by the client, or NULL if the
  89. * mechanism is client-first but the client did not send an
  90. * initial response. (This can only happen during the first
  91. * message from the client.) This is guaranteed to be
  92. * null-terminated for safety, but SASL allows embedded
  93. * nulls in responses, so mechanisms must be careful to
  94. * check inputlen.
  95. *
  96. * inputlen: The length of the challenge data sent by the server, or
  97. * -1 if the client did not send an initial response
  98. *
  99. * Output parameters, to be set by the callback function:
  100. *
  101. * output: A palloc'd buffer containing either the server's next
  102. * challenge (if PG_SASL_EXCHANGE_CONTINUE is returned) or
  103. * the server's outcome data (if PG_SASL_EXCHANGE_SUCCESS is
  104. * returned and the mechanism requires data to be sent during
  105. * a successful outcome). The callback should set this to
  106. * NULL if the exchange is over and no output should be sent,
  107. * which should correspond to either PG_SASL_EXCHANGE_FAILURE
  108. * or a PG_SASL_EXCHANGE_SUCCESS with no outcome data.
  109. *
  110. * outputlen: The length of the challenge data. Ignored if *output is
  111. * NULL.
  112. *
  113. * logdetail: Set to an optional DETAIL message to be printed to the
  114. * server log, to disambiguate failure modes. (The client
  115. * will only ever see the same generic authentication
  116. * failure message.) Ignored if the exchange is completed
  117. * with PG_SASL_EXCHANGE_SUCCESS.
  118. *---------
  119. */
  120. int (*exchange) (void *state,
  121. const char *input, int inputlen,
  122. char **output, int *outputlen,
  123. const char **logdetail);
  124. } pg_be_sasl_mech;
  125. /* Common implementation for auth.c */
  126. extern int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port,
  127. char *shadow_pass, const char **logdetail);
  128. #endif /* PG_SASL_H */