]> diplodocus.org Git - nmh/blob - h/netsec.h
Added mhshow-suffix-text entry.
[nmh] / h / netsec.h
1 /*
2 * Network security library routines for nmh.
3 *
4 * These are a common set of routines to handle network security for
5 * things like SASL and OpenSSL.
6 */
7
8 struct _netsec_context;
9 typedef struct _netsec_context netsec_context;
10
11 /*
12 * Create a network security context. Returns the allocated network
13 * security context. Cannot fail.
14 */
15
16 netsec_context *netsec_init(void);
17
18 /*
19 * Shuts down the security context for a connection and frees all
20 * associated resources.
21 *
22 * Arguments:
23 *
24 * ns_context - Network security context
25 * closeflag - If set to 1, close the socket descriptor as well.
26 */
27
28 void netsec_shutdown(netsec_context *ns_context, int closeflag);
29
30 /*
31 * Sets the file descriptor for this connection. This will be used by
32 * the underlying communication.
33 *
34 * Arguments:
35 *
36 * ns_context - Network security context
37 * readfd - Read file descriptor of remote connection.
38 * writefd - Write file descriptor of remote connection
39 */
40
41 void netsec_set_fd(netsec_context *ns_context, int readfd, int writefd);
42
43 /*
44 * Set the userid used to authenticate to this connection.
45 *
46 * Arguments:
47 *
48 * ns_context - Network security context
49 * userid - Userid to be used for authentication. Cannot be NULL.
50 */
51
52 void netsec_set_userid(netsec_context *ns_context, const char *userid);
53
54 /*
55 * Set the hostname of the server we're connecting to. This is used
56 * by the Cyrus-SASL library and by the TLS code. This must be called
57 * before netsec_negotiate_tls() or netsec_set_sasl_params().
58 *
59 * Arguments:
60 *
61 * ns_context - Network security context
62 * hostname - FQDN of remote host. Cannot be NULL.
63 */
64
65 void netsec_set_hostname(netsec_context *ns_context, const char *hostname);
66
67 /*
68 * Returns "snoop" status on current connection.
69 *
70 * Arguments:
71 *
72 * ns_context - Network security context
73 *
74 * Returns "1" if snoop is enabled, 0 if it is not.
75 */
76
77 int netsec_get_snoop(netsec_context *ns_context);
78
79 /*
80 * Sets "snoop" status; if snoop is set to a nonzero value, network traffic
81 * will be logged on standard error.
82 *
83 * Arguments:
84 *
85 * ns_context - Network security context
86 * snoop - Integer value; set to nonzero to enable traffic logging
87 */
88
89 void netsec_set_snoop(netsec_context *ns_context, int snoop);
90
91 /*
92 * A callback designed to handle the snoop output; it can be used by
93 * a protocol to massage the data in a more user-friendly way.
94 *
95 * Arguments:
96 *
97 * ns_context - Network security context
98 * string - String to output
99 * len - Length of string
100 * context - "Extra" context information to be used by callback.
101 */
102
103 typedef void (netsec_snoop_callback)(netsec_context *ns_context,
104 const char *string, size_t len,
105 void *context);
106
107 /*
108 * Set the snoop callback function; will be used to handle protocol-specific
109 * messages. Set to NULL to disable.
110 *
111 * Arguments:
112 *
113 * ns_context - Network security context
114 * callback - Snoop callback
115 * context - Extra context information to be passed to callback.
116 */
117
118 void netsec_set_snoop_callback(netsec_context *ns_context,
119 netsec_snoop_callback *callback, void *context);
120
121 /*
122 * A sample callback protocols can utilize; decode base64 tokens in the
123 * output. The context is a pointer to an int which contains an offset
124 * into the data to start decoding.
125 */
126
127 extern netsec_snoop_callback netsec_b64_snoop_decoder;
128
129 /*
130 * Set the read timeout for this connection.
131 *
132 * Arguments:
133 *
134 * ns_context - Network security context
135 * timeout - Read timeout, in seconds.
136 */
137
138 void netsec_set_timeout(netsec_context *ns_context, int timeout);
139
140 /*
141 * Read a "line" from the network. This reads one CR/LF terminated line.
142 * Returns a pointer to a NUL-terminated string. This memory is valid
143 * until the next call to any read function. Will return an error if
144 * the line does not terminate with a CR/LF.
145 *
146 * Arguments:
147 *
148 * ns_context - Network security context
149 * length - Returned length of string
150 * errstr - Error string
151 *
152 * Returns pointer to string, or NULL on error.
153 */
154
155 char *netsec_readline(netsec_context *ns_context, size_t *length,
156 char **errstr);
157
158 /*
159 * Read bytes from the network.
160 *
161 * Arguments:
162 *
163 * ns_context - Network security context
164 * buffer - Read buffer
165 * size - Buffer size
166 * errstr - Error size
167 *
168 * Returns number of bytes read, or -1 on error.
169 */
170
171 ssize_t netsec_read(netsec_context *ns_context, void *buffer, size_t size,
172 char **errstr);
173
174 /*
175 * Write data to the network; if encryption is being performed, we will
176 * do it. Data may be buffered; use netsec_flush() to flush any outstanding
177 * data to the network.
178 *
179 * Arguments:
180 *
181 * ns_context - Network security context
182 * buffer - Output buffer to write to network
183 * size - Size of data to write to network
184 * errstr - Error string
185 *
186 * Returns OK on success, NOTOK otherwise.
187 */
188
189 int netsec_write(netsec_context *ns_context, const void *buffer, size_t size,
190 char **errstr);
191
192 /*
193 * Write bytes using printf formatting
194 *
195 * Arguments:
196 *
197 * ns_context - Network security context
198 * errstr - Error string
199 * format - Format string
200 * ... - Arguments for format string
201 *
202 * Returns OK on success, NOTOK on error.
203 */
204
205 int netsec_printf(netsec_context *ns_context, char **errstr,
206 const char *format, ...);
207
208 /*
209 * Write bytes using a va_list argument.
210 *
211 * Arguments:
212 *
213 * ns_context - Network security context
214 * errstr - Error string
215 * format - Format string
216 * ap - stdarg list.
217 *
218 * Returns OK on success, NOTOK on error.
219 */
220
221 int netsec_vprintf(netsec_context *ns_context, char **errstr,
222 const char *format, va_list ap);
223
224 /*
225 * Flush any buffered bytes to the network.
226 *
227 * Arguments:
228 *
229 * ns_context - Network security context
230 * errstr - Error string
231 *
232 * Returns OK on success, NOTOK on error.
233 */
234
235 int netsec_flush(netsec_context *ns_context, char **errstr);
236
237 /*
238 * Enumerated types for the type of message we are sending/receiving.
239 */
240
241 enum sasl_message_type {
242 NETSEC_SASL_START, /* Start of SASL authentication */
243 NETSEC_SASL_READ, /* Reading a message */
244 NETSEC_SASL_WRITE, /* Writing a message */
245 NETSEC_SASL_FINISH, /* Complete SASL exchange */
246 NETSEC_SASL_CANCEL /* Cancel a SASL exchange */
247 };
248
249 /*
250 * The SASL callback; this is designed to parse a protocol-specific
251 * message and return the SASL protocol message back.
252 *
253 * The meaning of the arguments to the callback depend on the mtype
254 * arguments. See below for more detail.
255 *
256 * Arguments:
257 *
258 * mtype - The type of message we are processing (read/write/cancel).
259 * indata - A pointer to any input data.
260 * indatasize - The size of the input data in bytes
261 * outdata - Output data (freed by caller)
262 * outdatasize - Size of output data
263 * errstr - An error string to be returned (freed by caller).
264 *
265 * As a general note, plugins should perform their own I/O. Buffers returned
266 * by NETSEC_SASL_READ should be allocated by the plugins and will be freed
267 * by the netsec package. Error messages returned should be created by
268 * netsec_err().
269 *
270 * Parameter interpretation based on mtype value:
271 *
272 * NETSEC_SASL_START - Create a protocol message that starts SASL
273 * authentication. If an initial response is
274 * supported, indata and indatasize will contain it.
275 * Otherwise they will be set to NULL and 0.
276 * NETSEC_SASL_READ - Parse and decode a protocol message and extract
277 * out the SASL payload data. indata will be set
278 * to NULL; the callback must read in the necessary
279 * data using the appropriate netsec function.
280 * outdata/outdatasize should contain the decoded
281 * SASL message (again, must be free()d by the caller).
282 * NETSEC_SASL_WRITE - Generate a protocol message to send over the
283 * network. indata/indatasize will contain the
284 * SASL payload data.
285 * NETSEC_SASL_FINISH - Process the final SASL message exchange; at
286 * this point SASL exchange should have completed
287 * and we should get a message back from the server
288 * telling us whether or not authentication is
289 * successful. All buffer parameters are NULL.
290 * NETSEC_SASL_CANCEL - Generate a protocol message that cancels the
291 * SASL protocol exchange; outdata/outdatasize
292 * should contain this message.
293 *
294 * The callback should return OK on success, NOTOK on failure. Depending
295 * at the point of the authentication exchange, the callback may be asked
296 * to generate a cancel message.
297 */
298
299 typedef int (*netsec_sasl_callback)(enum sasl_message_type mtype,
300 unsigned const char *indata,
301 unsigned int indatasize,
302 unsigned char **outdata,
303 unsigned int *outdatasize, char **errstr);
304
305 /*
306 * Sets the SASL parameters for this connection. If this function is
307 * not called or is called with NULL for arguments, SASL authentication
308 * will not be attempted for this connection.
309 *
310 * The caller must provide a callback to parse the protocol and return
311 * the SASL protocol messages (see above for callback details).
312 *
313 * Arguments:
314 *
315 * ns_context - Network security context
316 * service - Service name (set to NULL to disable SASL).
317 * mechanism - The mechanism desired by the user. If NULL, the SASL
318 * library will attempt to negotiate the best mechanism.
319 * callback - SASL protocol callbacks
320 * errstr - Error string.
321 *
322 * Returns NOTOK if SASL is not supported.
323 */
324
325 int netsec_set_sasl_params(netsec_context *ns_context, const char *service,
326 const char *mechanism,
327 netsec_sasl_callback callback, char **errstr);
328
329 /*
330 * Start SASL negotiation. The Netsec library will use the callbacks
331 * supplied in netsec_set_sasl_params() to format and parse the protocol
332 * messages.
333 *
334 * Arguments:
335 *
336 * ns_context - Network security context
337 * mechlist - Space-separated list of supported SASL mechanisms
338 * errstr - An error string to be returned upon error.
339 *
340 * Returns OK on success, NOTOK on failure.
341 */
342
343 int netsec_negotiate_sasl(netsec_context *ns_context, const char *mechlist,
344 char **errstr);
345
346 /*
347 * Returns the chosen SASL mechanism by the SASL library or netsec.
348 *
349 * Arguments:
350 *
351 * ns_context - Network security context
352 *
353 * Returns a string containing the chosen mech, or NULL if SASL is not
354 * supported or in use.
355 */
356
357 char *netsec_get_sasl_mechanism(netsec_context *ns_context);
358
359 /*
360 * Set the OAuth service name used to retrieve the OAuth parameters from
361 * user's profile. Just calling this function is not enough to guarantee
362 * that XOAUTH2 authentication will be performed; the appropriate mechanism
363 * name must be passed into netsec_set_sasl_params().
364 *
365 * Arguments:
366 *
367 * ns_context - Network security context
368 * service - OAuth2 service names.
369 *
370 * Returns NOTOK if OAuth2 is not supported.
371 */
372
373 int netsec_set_oauth_service(netsec_context *ns_context, const char *service);
374
375 /*
376 * Controls whether or not TLS will be negotiated for this connection.
377 *
378 * Note: callers still have to call netsec_tls_negotiate() to start
379 * TLS negotiation at the appropriate point in the protocol. The
380 * remote hostname (controlled by netsec_set_hostname()) should have
381 * already been set before this function is called unless certificate
382 * verification is disabled.
383 *
384 * Arguments
385 *
386 * tls - If nonzero, enable TLS. Otherwise disable TLS
387 * negotiation.
388 * noverify - If nonzero, disable server certificate and hostname
389 * validation.
390 *
391 * Returns NOTOK if TLS is not supported or was unable to initialize.
392 */
393
394 int netsec_set_tls(netsec_context *context, int tls, int noverify,
395 char **errstr);
396
397 /*
398 * Start TLS negotiation on this protocol. This connection should have
399 * netsec_set_tls() called on it.
400 *
401 * Arguments:
402 *
403 * ns_context - Network security context
404 * errstr - Error string upon failure.
405 *
406 * Returns OK on success, NOTOK on failure.
407 */
408
409 int netsec_negotiate_tls(netsec_context *ns_context, char **errstr);
410
411 /*
412 * Allocate and format an error string; should be used by plugins
413 * to report errors.
414 *
415 * Arguments:
416 *
417 * errstr - Error string to be returned
418 * format - printf(3) format string
419 * ... - Arguments to printf(3)
420 *
421 */
422
423 void netsec_err(char **errstr, const char *format, ...);