Sebastian Kuschel reports that pfd_closing can be called for a socket
[u/mdw/putty] / sshgss.h
index 5aa91bb..32ccb4d 100644 (file)
--- a/sshgss.h
+++ b/sshgss.h
@@ -1,8 +1,12 @@
-#include "puttyps.h"
+#ifndef PUTTY_SSHGSS_H
+#define PUTTY_SSHGSS_H
+#include "putty.h"
+#include "pgssapi.h"
+
+#ifndef NO_GSSAPI
 
 #define SSH2_GSS_OIDTYPE 0x06
 typedef void *Ssh_gss_ctx;
-typedef void *Ssh_gss_name;
 
 typedef enum Ssh_gss_stat {
     SSH_GSS_OK = 0,
@@ -19,46 +23,63 @@ typedef enum Ssh_gss_stat {
     (*buf).value = NULL;                               \
 } while (0)
 
-/* Functions, provided by either wingss.c or uxgss.c */
+typedef gss_buffer_desc Ssh_gss_buf;
+typedef gss_name_t Ssh_gss_name;
+
+/* Functions, provided by either wingss.c or sshgssc.c */
+
+struct ssh_gss_library;
 
 /*
- * Do startup-time initialisation for using GSSAPI. (On Windows,
- * for instance, this dynamically loads the GSSAPI DLL and
- * retrieves some function pointers.)
+ * Prepare a collection of GSSAPI libraries for use in a single SSH
+ * connection. Returns a structure containing a list of libraries,
+ * with their ids (see struct ssh_gss_library below) filled in so
+ * that the client can go through them in the SSH user's preferred
+ * order.
  *
- * Return value is 1 on success, or 0 if initialisation failed.
+ * Must always return non-NULL. (Even if no libraries are available,
+ * it must return an empty structure.)
  *
- * May be called multiple times (since the most convenient place
- * to call it _from_ is the ssh.c setup code), and will harmlessly
- * return success if already initialised.
+ * The free function cleans up the structure, and its associated
+ * libraries (if any).
  */
-int ssh_gss_init(void);
+struct ssh_gss_liblist {
+    struct ssh_gss_library *libraries;
+    int nlibraries;
+};
+struct ssh_gss_liblist *ssh_gss_setup(Conf *conf);
+void ssh_gss_cleanup(struct ssh_gss_liblist *list);
 
 /*
  * Fills in buf with a string describing the GSSAPI mechanism in
  * use. buf->data is not dynamically allocated.
  */
-Ssh_gss_stat ssh_gss_indicate_mech(Ssh_gss_buf *buf);
+typedef Ssh_gss_stat (*t_ssh_gss_indicate_mech)(struct ssh_gss_library *lib,
+                                               Ssh_gss_buf *buf);
 
 /*
  * Converts a name such as a hostname into a GSSAPI internal form,
  * which is placed in "out". The result should be freed by
  * ssh_gss_release_name().
  */
-Ssh_gss_stat ssh_gss_import_name(char *in, Ssh_gss_name *out);
+typedef Ssh_gss_stat (*t_ssh_gss_import_name)(struct ssh_gss_library *lib,
+                                             char *in, Ssh_gss_name *out);
 
 /*
  * Frees the contents of an Ssh_gss_name structure filled in by
  * ssh_gss_import_name().
  */
-Ssh_gss_stat ssh_gss_release_name(Ssh_gss_name *name);
+typedef Ssh_gss_stat (*t_ssh_gss_release_name)(struct ssh_gss_library *lib,
+                                              Ssh_gss_name *name);
 
 /*
  * The main GSSAPI security context setup function. The "out"
  * parameter will need to be freed by ssh_gss_free_tok.
  */
-Ssh_gss_stat ssh_gss_init_sec_context(Ssh_gss_ctx *ctx, Ssh_gss_name name, int delegate,
-                                     Ssh_gss_buf *in, Ssh_gss_buf *out);
+typedef Ssh_gss_stat (*t_ssh_gss_init_sec_context)
+    (struct ssh_gss_library *lib,
+     Ssh_gss_ctx *ctx, Ssh_gss_name name, int delegate,
+     Ssh_gss_buf *in, Ssh_gss_buf *out);
 
 /*
  * Frees the contents of an Ssh_gss_buf filled in by
@@ -67,26 +88,30 @@ Ssh_gss_stat ssh_gss_init_sec_context(Ssh_gss_ctx *ctx, Ssh_gss_name name, int d
  * different free function) or something filled in by any other
  * way.
  */
-Ssh_gss_stat ssh_gss_free_tok(Ssh_gss_buf *);
+typedef Ssh_gss_stat (*t_ssh_gss_free_tok)(struct ssh_gss_library *lib,
+                                          Ssh_gss_buf *);
 
 /*
  * Acquires the credentials to perform authentication in the first
  * place. Needs to be freed by ssh_gss_release_cred().
  */
-Ssh_gss_stat ssh_gss_acquire_cred(Ssh_gss_ctx *);
+typedef Ssh_gss_stat (*t_ssh_gss_acquire_cred)(struct ssh_gss_library *lib,
+                                              Ssh_gss_ctx *);
 
 /*
  * Frees the contents of an Ssh_gss_ctx filled in by
  * ssh_gss_acquire_cred().
  */
-Ssh_gss_stat ssh_gss_release_cred(Ssh_gss_ctx *);
+typedef Ssh_gss_stat (*t_ssh_gss_release_cred)(struct ssh_gss_library *lib,
+                                              Ssh_gss_ctx *);
 
 /*
  * Gets a MIC for some input data. "out" needs to be freed by
  * ssh_gss_free_mic().
  */
-Ssh_gss_stat ssh_gss_get_mic(Ssh_gss_ctx ctx, Ssh_gss_buf *in,
-                            Ssh_gss_buf *out);
+typedef Ssh_gss_stat (*t_ssh_gss_get_mic)(struct ssh_gss_library *lib,
+                                         Ssh_gss_ctx ctx, Ssh_gss_buf *in,
+                 Ssh_gss_buf *out);
 
 /*
  * Frees the contents of an Ssh_gss_buf filled in by
@@ -95,7 +120,8 @@ Ssh_gss_stat ssh_gss_get_mic(Ssh_gss_ctx ctx, Ssh_gss_buf *in,
  * different free function) or something filled in by any other
  * way.
  */
-Ssh_gss_stat ssh_gss_free_mic(Ssh_gss_buf *);
+typedef Ssh_gss_stat (*t_ssh_gss_free_mic)(struct ssh_gss_library *lib,
+                                          Ssh_gss_buf *);
 
 /*
  * Return an error message after authentication failed. The
@@ -104,4 +130,59 @@ Ssh_gss_stat ssh_gss_free_mic(Ssh_gss_buf *);
  * containing one more character which is a trailing NUL.
  * buf->data should be manually freed by the caller. 
  */
-Ssh_gss_stat ssh_gss_display_status(Ssh_gss_ctx, Ssh_gss_buf *buf);
+typedef Ssh_gss_stat (*t_ssh_gss_display_status)(struct ssh_gss_library *lib,
+                                                Ssh_gss_ctx, Ssh_gss_buf *buf);
+
+struct ssh_gss_library {
+    /*
+     * Identifying number in the enumeration used by the
+     * configuration code to specify a preference order.
+     */
+    int id;
+
+    /*
+     * Filled in at initialisation time, if there's anything
+     * interesting to say about how GSSAPI was initialised (e.g.
+     * which of a number of alternative libraries was used).
+     */
+    const char *gsslogmsg;
+
+    /*
+     * Function pointers implementing the SSH wrapper layer on top
+     * of GSSAPI. (Defined in sshgssc, typically, though Windows
+     * provides an alternative layer to sit on top of the annoyingly
+     * different SSPI.)
+     */
+    t_ssh_gss_indicate_mech indicate_mech;
+    t_ssh_gss_import_name import_name;
+    t_ssh_gss_release_name release_name;
+    t_ssh_gss_init_sec_context init_sec_context;
+    t_ssh_gss_free_tok free_tok;
+    t_ssh_gss_acquire_cred acquire_cred;
+    t_ssh_gss_release_cred release_cred;
+    t_ssh_gss_get_mic get_mic;
+    t_ssh_gss_free_mic free_mic;
+    t_ssh_gss_display_status display_status;
+
+    /*
+     * Additional data for the wrapper layers.
+     */
+    union {
+       struct gssapi_functions gssapi;
+       /*
+        * The SSPI wrappers don't need to store their Windows API
+        * function pointers in this structure, because there can't
+        * be more than one set of them available.
+        */
+    } u;
+
+    /*
+     * Wrapper layers will often also need to store a library handle
+     * of some sort for cleanup time.
+     */
+    void *handle;
+};
+
+#endif /* NO_GSSAPI */
+
+#endif /*PUTTY_SSHGSS_H*/