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