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