summaryrefslogtreecommitdiffstats
path: root/src/xsasl/xsasl_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xsasl/xsasl_server.c')
-rw-r--r--src/xsasl/xsasl_server.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/xsasl/xsasl_server.c b/src/xsasl/xsasl_server.c
new file mode 100644
index 0000000..e8d7e16
--- /dev/null
+++ b/src/xsasl/xsasl_server.c
@@ -0,0 +1,270 @@
+/*++
+/* NAME
+/* xsasl-server 3
+/* SUMMARY
+/* Postfix SASL server plug-in interface
+/* SYNOPSIS
+/* #include <xsasl.h>
+/*
+/* XSASL_SERVER_IMPL *xsasl_server_init(server_type, path_info)
+/* const char *server_type;
+/* const char *path_info;
+/*
+/* void xsasl_server_done(implementation)
+/* XSASL_SERVER_IMPL *implementation;
+/*
+/* ARGV *xsasl_server_types()
+/*
+/* .in +4
+/* typedef struct XSASL_SERVER_CREATE_ARGS {
+/* VSTREAM *stream;
+/* const char *server_addr;
+/* const char *client_addr;
+/* const char *service;
+/* const char *user_realm;
+/* const char *security_options;
+/* int tls_flag;
+/* } XSASL_SERVER_CREATE_ARGS;
+/* .in -4
+/*
+/* XSASL_SERVER *xsasl_server_create(implementation, args)
+/* XSASL_SERVER_IMPL *implementation;
+/* XSASL_SERVER_CREATE_ARGS *args;
+/*
+/* XSASL_SERVER *XSASL_SERVER_CREATE(implementation, args,
+/* stream = stream_value,
+/* ...,
+/* tls_flag = tls_flag_value)
+/* XSASL_SERVER_IMPL *implementation;
+/* XSASL_SERVER_CREATE_ARGS *args;
+/*
+/* void xsasl_server_free(server)
+/* XSASL_SERVER *server;
+/*
+/* int xsasl_server_first(server, auth_method, init_resp, server_reply)
+/* XSASL_SERVER *server;
+/* const char *auth_method;
+/* const char *init_resp;
+/* VSTRING *server_reply;
+/*
+/* int xsasl_server_next(server, client_request, server_reply)
+/* XSASL_SERVER *server;
+/* const char *client_request;
+/* VSTRING *server_reply;
+/*
+/* const char *xsasl_server_get_mechanism_list(server)
+/* XSASL_SERVER *server;
+/*
+/* const char *xsasl_server_get_username(server)
+/* XSASL_SERVER *server;
+/* DESCRIPTION
+/* The XSASL_SERVER abstraction implements a generic interface
+/* to one or more SASL authentication implementations.
+/*
+/* xsasl_server_init() is called once during process initialization.
+/* It selects a SASL implementation by name, specifies the
+/* location of a configuration file or rendez-vous point, and
+/* returns an implementation handle that can be used to generate
+/* SASL server instances. This function is typically used to
+/* initialize the underlying implementation.
+/*
+/* xsasl_server_done() disposes of an implementation handle,
+/* and allows the underlying implementation to release resources.
+/*
+/* xsasl_server_types() lists the available implementation types.
+/* The result should be destroyed by the caller.
+/*
+/* xsasl_server_create() is called at the start of an SMTP
+/* session. It generates a Postfix SASL plug-in server instance
+/* for the specified service and authentication realm, and
+/* with the specified security properties. Specify a null
+/* pointer when no realm should be used. The stream handle is
+/* stored so that encryption can be turned on after successful
+/* negotiations. Specify zero-length strings when a client or
+/* server address is unavailable.
+/*
+/* XSASL_SERVER_CREATE() is a macro that provides an interface
+/* with named parameters. Named parameters do not have to
+/* appear in a fixed order. The parameter names correspond to
+/* the member names of the XSASL_SERVER_CREATE_ARGS structure.
+/*
+/* xsasl_server_free() is called at the end of an SMTP session.
+/* It destroys a SASL server instance, and disables further
+/* read/write operations if encryption was turned on.
+/*
+/* xsasl_server_first() produces the server response for the
+/* client AUTH command. The client input are an authentication
+/* method, and an optional initial response or null pointer.
+/* The initial response and server non-error replies are BASE64
+/* encoded. Server error replies are 7-bit ASCII text without
+/* control characters, without BASE64 encoding, and without
+/* SMTP reply code or enhanced status code.
+/*
+/* The result is one of the following:
+/* .IP XSASL_AUTH_MORE
+/* More client input is needed. The server reply specifies
+/* what.
+/* .IP XSASL_AUTH_DONE
+/* Authentication completed successfully.
+/* .IP XSASL_AUTH_FORM
+/* The client input is incorrectly formatted. The server error
+/* reply explains why.
+/* .IP XSASL_AUTH_FAIL
+/* Authentication failed. The server error reply explains why.
+/* .PP
+/* xsasl_server_next() supports the subsequent stages of the
+/* client-server AUTH protocol. Both the client input and
+/* server non-error responses are BASE64 encoded. See
+/* xsasl_server_first() for other details.
+/*
+/* xsasl_server_get_mechanism_list() returns the authentication
+/* mechanisms that match the security properties, as a white-space
+/* separated list. This is meant to be used in the SMTP EHLO
+/* reply.
+/*
+/* xsasl_server_get_username() returns the stored username
+/* after successful authentication.
+/*
+/* Arguments:
+/* .IP addr_family
+/* The network address family: AF_INET6 or AF_INET.
+/* .IP auth_method
+/* AUTH command authentication method.
+/* .IP client_addr
+/* IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
+/* or zero-length string if unavailable.
+/* .IP client_port
+/* TCP port or zero-length string if unavailable.
+/* .IP init_resp
+/* AUTH command initial response or null pointer.
+/* .IP implementation
+/* Implementation handle that was obtained with xsasl_server_init().
+/* .IP path_info
+/* The value of the smtpd_sasl_path parameter or equivalent.
+/* This specifies the implementation-dependent location of a
+/* configuration file, rendez-vous point, etc., and is passed
+/* unchanged to the plug-in.
+/* .IP security_options
+/* The value of the smtpd_security_options parameter or
+/* equivalent. This is passed unchanged to the plug-in.
+/* .IP server
+/* SASL plug-in server handle.
+/* .IP server_addr
+/* IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
+/* or zero-length string if unavailable.
+/* .IP server_port
+/* TCP port or zero-length string if unavailable.
+/* .IP server_reply
+/* BASE64 encoded server non-error reply (without SMTP reply
+/* code or enhanced status code), or ASCII error description.
+/* .IP server_type
+/* The name of a Postfix SASL server plug_in implementation.
+/* .IP server_types
+/* Null-terminated array of strings with SASL server plug-in
+/* implementation names.
+/* .IP service
+/* The service that is implemented by the local server, typically
+/* "smtp" or "lmtp".
+/* .IP stream
+/* The connection between client and server. When SASL
+/* encryption is negotiated, the plug-in will transparently
+/* intercept the socket read/write operations.
+/* .IP user_realm
+/* Authentication domain or null pointer.
+/* SECURITY
+/* .ad
+/* .fi
+/* The caller does not sanitize client input. It is the
+/* responsibility of the underlying SASL server implementation
+/* to produce 7-bit ASCII without control characters as server
+/* non-error and error replies, and as the result from
+/* xsasl_server_method() and xsasl_server_username().
+/* DIAGNOSTICS
+/* In case of failure, xsasl_server_init(), xsasl_server_create(),
+/* xsasl_server_get_mechanism_list() and xsasl_server_get_username()
+/* log a warning and return a null pointer.
+/*
+/* Functions that normally return XSASL_AUTH_OK will log a warning
+/* and return an appropriate result value.
+/*
+/* Fatal errors: out of memory.
+/*
+/* Panic: interface violations.
+/* SEE ALSO
+/* cyrus_security(3) Cyrus SASL security features
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this
+/* software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+
+/* SASL implementations. */
+
+#include <xsasl.h>
+#include <xsasl_cyrus.h>
+#include <xsasl_dovecot.h>
+
+ /*
+ * Lookup table for available SASL server implementations.
+ */
+typedef struct {
+ char *server_type;
+ struct XSASL_SERVER_IMPL *(*server_init) (const char *, const char *);
+} XSASL_SERVER_IMPL_INFO;
+
+static const XSASL_SERVER_IMPL_INFO server_impl_info[] = {
+#ifdef XSASL_TYPE_CYRUS
+ {XSASL_TYPE_CYRUS, xsasl_cyrus_server_init},
+#endif
+#ifdef XSASL_TYPE_DOVECOT
+ {XSASL_TYPE_DOVECOT, xsasl_dovecot_server_init},
+#endif
+ {0, 0}
+};
+
+/* xsasl_server_init - look up server implementation by name */
+
+XSASL_SERVER_IMPL *xsasl_server_init(const char *server_type,
+ const char *path_info)
+{
+ const XSASL_SERVER_IMPL_INFO *xp;
+
+ for (xp = server_impl_info; xp->server_type; xp++)
+ if (strcmp(server_type, xp->server_type) == 0)
+ return (xp->server_init(server_type, path_info));
+ msg_warn("unsupported SASL server implementation: %s", server_type);
+ return (0);
+}
+
+/* xsasl_server_types - report available implementation types */
+
+ARGV *xsasl_server_types(void)
+{
+ const XSASL_SERVER_IMPL_INFO *xp;
+ ARGV *argv = argv_alloc(1);
+
+ for (xp = server_impl_info; xp->server_type; xp++)
+ argv_add(argv, xp->server_type, ARGV_END);
+ return (argv);
+}