2 * Network security library routines for nmh.
4 * These are a common set of routines to handle network security for
5 * things like SASL and OpenSSL.
8 struct _netsec_context
;
9 typedef struct _netsec_context netsec_context
;
12 * Create a network security context. Returns the allocated network
13 * security context. Cannot fail.
16 netsec_context
*netsec_init(void);
19 * Shuts down the security context for a connection and frees all
20 * associated resources.
24 * ns_context - Network security context
25 * closeflag - If set to 1, close the socket descriptor as well.
28 void netsec_shutdown(netsec_context
*ns_context
, int closeflag
);
31 * Sets the file descriptor for this connection. This will be used by
32 * the underlying communication.
36 * ns_context - Network security context
37 * readfd - Read file descriptor of remote connection.
38 * writefd - Write file descriptor of remote connection
41 void netsec_set_fd(netsec_context
*ns_context
, int readfd
, int writefd
);
44 * Set the userid used to authenticate to this connection.
48 * ns_context - Network security context
49 * userid - Userid to be used for authentication. Cannot be NULL.
52 void netsec_set_userid(netsec_context
*ns_context
, const char *userid
);
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().
61 * ns_context - Network security context
62 * hostname - FQDN of remote host. Cannot be NULL.
65 void netsec_set_hostname(netsec_context
*ns_context
, const char *hostname
);
68 * Returns "snoop" status on current connection.
72 * ns_context - Network security context
74 * Returns "1" if snoop is enabled, 0 if it is not.
77 int netsec_get_snoop(netsec_context
*ns_context
);
80 * Sets "snoop" status; if snoop is set to a nonzero value, network traffic
81 * will be logged on standard error.
85 * ns_context - Network security context
86 * snoop - Integer value; set to nonzero to enable traffic logging
89 void netsec_set_snoop(netsec_context
*ns_context
, int snoop
);
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.
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.
103 typedef void (netsec_snoop_callback
)(netsec_context
*ns_context
,
104 const char *string
, size_t len
,
108 * Set the snoop callback function; will be used to handle protocol-specific
109 * messages. Set to NULL to disable.
113 * ns_context - Network security context
114 * callback - Snoop callback
115 * context - Extra context information to be passed to callback.
118 void netsec_set_snoop_callback(netsec_context
*ns_context
,
119 netsec_snoop_callback
*callback
, void *context
);
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.
127 extern netsec_snoop_callback netsec_b64_snoop_decoder
;
130 * Set the read timeout for this connection.
134 * ns_context - Network security context
135 * timeout - Read timeout, in seconds.
138 void netsec_set_timeout(netsec_context
*ns_context
, int timeout
);
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.
148 * ns_context - Network security context
149 * length - Returned length of string
150 * errstr - Error string
152 * Returns pointer to string, or NULL on error.
155 char *netsec_readline(netsec_context
*ns_context
, size_t *length
,
159 * Read bytes from the network.
163 * ns_context - Network security context
164 * buffer - Read buffer
166 * errstr - Error size
168 * Returns number of bytes read, or -1 on error.
171 ssize_t
netsec_read(netsec_context
*ns_context
, void *buffer
, size_t size
,
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.
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
186 * Returns OK on success, NOTOK otherwise.
189 int netsec_write(netsec_context
*ns_context
, const void *buffer
, size_t size
,
193 * Write bytes using printf formatting
197 * ns_context - Network security context
198 * errstr - Error string
199 * format - Format string
200 * ... - Arguments for format string
202 * Returns OK on success, NOTOK on error.
205 int netsec_printf(netsec_context
*ns_context
, char **errstr
,
206 const char *format
, ...);
209 * Write bytes using a va_list argument.
213 * ns_context - Network security context
214 * errstr - Error string
215 * format - Format string
218 * Returns OK on success, NOTOK on error.
221 int netsec_vprintf(netsec_context
*ns_context
, char **errstr
,
222 const char *format
, va_list ap
);
225 * Flush any buffered bytes to the network.
229 * ns_context - Network security context
230 * errstr - Error string
232 * Returns OK on success, NOTOK on error.
235 int netsec_flush(netsec_context
*ns_context
, char **errstr
);
238 * Enumerated types for the type of message we are sending/receiving.
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 */
250 * The SASL callback; this is designed to parse a protocol-specific
251 * message and return the SASL protocol message back.
253 * The meaning of the arguments to the callback depend on the mtype
254 * arguments. See below for more detail.
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).
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
270 * Parameter interpretation based on mtype value:
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
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.
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.
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
);
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.
310 * The caller must provide a callback to parse the protocol and return
311 * the SASL protocol messages (see above for callback details).
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.
322 * Returns NOTOK if SASL is not supported.
325 int netsec_set_sasl_params(netsec_context
*ns_context
, const char *service
,
326 const char *mechanism
,
327 netsec_sasl_callback callback
, char **errstr
);
330 * Start SASL negotiation. The Netsec library will use the callbacks
331 * supplied in netsec_set_sasl_params() to format and parse the protocol
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.
340 * Returns OK on success, NOTOK on failure.
343 int netsec_negotiate_sasl(netsec_context
*ns_context
, const char *mechlist
,
347 * Returns the chosen SASL mechanism by the SASL library or netsec.
351 * ns_context - Network security context
353 * Returns a string containing the chosen mech, or NULL if SASL is not
354 * supported or in use.
357 char *netsec_get_sasl_mechanism(netsec_context
*ns_context
);
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().
367 * ns_context - Network security context
368 * service - OAuth2 service names.
370 * Returns NOTOK if OAuth2 is not supported.
373 int netsec_set_oauth_service(netsec_context
*ns_context
, const char *service
);
376 * Controls whether or not TLS will be negotiated for this connection.
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.
386 * tls - If nonzero, enable TLS. Otherwise disable TLS
388 * noverify - If nonzero, disable server certificate and hostname
391 * Returns NOTOK if TLS is not supported or was unable to initialize.
394 int netsec_set_tls(netsec_context
*context
, int tls
, int noverify
,
398 * Start TLS negotiation on this protocol. This connection should have
399 * netsec_set_tls() called on it.
403 * ns_context - Network security context
404 * errstr - Error string upon failure.
406 * Returns OK on success, NOTOK on failure.
409 int netsec_negotiate_tls(netsec_context
*ns_context
, char **errstr
);
412 * Allocate and format an error string; should be used by plugins
417 * errstr - Error string to be returned
418 * format - printf(3) format string
419 * ... - Arguments to printf(3)
423 void netsec_err(char **errstr
, const char *format
, ...);