aboutsummaryrefslogtreecommitdiff
path: root/tools/plink/sshgss.h
blob: 5d8fca1b7b68e495fa626abaa53e8d21ae81bcb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#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 enum Ssh_gss_stat {
    SSH_GSS_OK = 0,
    SSH_GSS_S_CONTINUE_NEEDED,
    SSH_GSS_NO_MEM,
    SSH_GSS_BAD_HOST_NAME,
    SSH_GSS_FAILURE
} Ssh_gss_stat;

#define SSH_GSS_S_COMPLETE SSH_GSS_OK

#define SSH_GSS_CLEAR_BUF(buf) do {		\
    (*buf).length = 0;				\
    (*buf).value = NULL;				\
} while (0)

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;

/*
 * 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.
 *
 * Must always return non-NULL. (Even if no libraries are available,
 * it must return an empty structure.)
 *
 * The free function cleans up the structure, and its associated
 * libraries (if any).
 */
struct ssh_gss_liblist {
    struct ssh_gss_library *libraries;
    int nlibraries;
};
struct ssh_gss_liblist *ssh_gss_setup(const Config *cfg);
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.
 */
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().
 */
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().
 */
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.
 */
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
 * ssh_gss_init_sec_context(). Do not accidentally call this on
 * something filled in by ssh_gss_get_mic() (which requires a
 * different free function) or something filled in by any other
 * way.
 */
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().
 */
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().
 */
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().
 */
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
 * ssh_gss_get_mic(). Do not accidentally call this on something
 * filled in by ssh_gss_init_sec_context() (which requires a
 * different free function) or something filled in by any other
 * way.
 */
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
 * message string is returned in "buf", with buf->len giving the
 * number of characters of printable message text and buf->data
 * containing one more character which is a trailing NUL.
 * buf->data should be manually freed by the caller. 
 */
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*/