diff --git a/.gitignore b/.gitignore index 0a0a1cb7..1ad3eef0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ libtool config.status stamp-h1 Makefile +*.pyc +docsrc/.doctrees/ +docsrc/build/ diff --git a/ChangeLog b/ChangeLog index c7be303c..6a547fa8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2016-10-18 Ken Murchison + * Fixed potential DoS attack on saslauthd/doors (from Oracle) + +2016-06-30 Ken Murchison + * plugins/ntlm.c, otp.c: support OpenSSL 1.1 + +2016-06-14 Ken Murchison + * plugins/digestmd5.c: Fix memory leak in client step 2 + +2016-03-24 Ken Murchison + * auth_rimap.c: Don't hang when IMAP server closes connection + +2016-01-29 Ken Murchison + * Build fixes from Ignacio Casal Quinteiro + +2015-12-26 Ken Murchison + * Build fixes from Ignacio Casal Quinteiro + +2015-11-16 Ken Murchison + * Build fixes from Ignacio Casal Quinteiro + +2015-10-14 Ken Murchison + * Build fixes from Ignacio Casal Quinteiro + +2015-07-17 Ken Murchison + * auth_krb5.c: added krb5_conv_krb4_instance option + +2014-11-17 Ken Murchison + * plugins/digestmd5.c: Fix memory leaks + +2014-11-17 Ken Murchison + * plugins/digestmd5.c: prevent going from step 3 to step 2 + +2013-09-13 Alexey Melnikov + * Fix memory leaks in DIGEST + +2013-08-30 Ken Murchison + * plugins/digestmd5.c: only locate reauth cache when reauth is + enabled + +2013-07-11 Alexey Melnikov + * Treat SCRAM and DIGEST as more secure than PLAIN when selecting + client-side mechanism + +2013-07-11 Alexey Melnikov + * Handle NULL return from crypt() + +2012-11-20 Alexey Melnikov + * Added support for lmdb + 2012-11-19 Alexey Melnikov * Final 2.1.26 tagged and released by Ken. diff --git a/NEWS b/NEWS index b9add573..0821c10e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +New in 2.1.27 +------------- + +* Added support for OpenSSL 1.1 +* Fixed potential DoS attack on saslauthd/doors (from Oracle) +* Added support for lmdb (from Howard Chu) +* Lots of build fixes (from Ignacio Casal Quinteiro) +* DIGEST-MD5 plugin: + - Fixed memory leaks + - Fixed a segfault when looking for non-existent reauth cache + - Prevent client from going from step 3 back to step 2 +* Added krb5_conv_krb4_instance option to saslauthd/kerberos5 +* Treat SCRAM and DIGEST-MD5 as more secure than PLAIN when selecting client mech + New in 2.1.26 ------------- diff --git a/README.rpm b/README.rpm deleted file mode 100644 index 95e0b358..00000000 --- a/README.rpm +++ /dev/null @@ -1,6 +0,0 @@ - -CMU does not provide any binary distributions. - -The following sites are known to have rpms: - -http://home.teleport.ch/simix/ diff --git a/configure.ac b/configure.ac index d3f38af7..929a951c 100644 --- a/configure.ac +++ b/configure.ac @@ -42,17 +42,17 @@ dnl AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING dnl OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl -AC_PREREQ(2.63.2) +AC_PREREQ(2.63) dnl dnl REMINDER: When changing the version number here, please also update dnl the values in win32/include/config.h and include/sasl.h as well. dnl AC_INIT([cyrus-sasl], - [2.1.26], - [https://git.cyrus.foundation/maniphest/], + [2.1.27], + [https://github.com/cyrusimap/cyrus-sasl/issues], [cyrus-sasl], - [https://docs.cyrus.foundation]) + [http://cyrusimap.org]) AC_CONFIG_MACRO_DIR([m4]) @@ -67,7 +67,7 @@ AC_CONFIG_AUX_DIR(config) AC_CANONICAL_HOST AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE([1.11 tar-ustar dist-xz no-dist-gzip -Wno-portability subdir-objects]) +AM_INIT_AUTOMAKE([1.11 tar-ustar dist-bzip2 -Wno-portability subdir-objects]) DIRS="" @@ -226,10 +226,10 @@ AC_SUBST(SASL_DL_LIB) dnl /dev/random ? -AC_ARG_WITH(devrandom, [ --with-devrandom=PATH set the path to /dev/random [[/dev/random]] ], +AC_ARG_WITH(devrandom, [ --with-devrandom=PATH set the path to pseudo random number generator [[/dev/urandom]] ], devrandom=$withval, - devrandom=/dev/random) -AC_MSG_CHECKING(/dev/random to use) + devrandom=/dev/urandom) +AC_MSG_CHECKING(PRNG to use) AC_MSG_RESULT($devrandom) AC_DEFINE_UNQUOTED(SASL_DEV_RANDOM, "$devrandom", [File to use for source of randomness]) @@ -1321,6 +1321,28 @@ IPv6_CHECK_SOCKLEN_T() #AC_FUNC_VPRINTF AC_CHECK_FUNCS(gethostname getdomainname getpwnam getspnam gettimeofday inet_aton memcpy mkdir select socket strchr strdup strerror strspn strstr strtol jrand48 getpassphrase asprintf strlcat strlcpy) +if test $ac_cv_func_getspnam = yes; then + AC_MSG_CHECKING(if getpwnam_r/getspnam_r take 5 arguments) + AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ +struct passwd *pw; +struct passwd pwbuf; +char pwdata[512]; +(void) getpwnam_r("bin", &pwbuf, pwdata, sizeof(pwdata), &pw); + ], + [AC_MSG_RESULT(yes) + AC_DEFINE(GETXXNAM_R_5ARG, 1, + [Define if your getpwnam_r()/getspnam_r() + functions take 5 arguments])], + [AC_MSG_RESULT(no)] + ) +fi + if test $enable_cmulocal = yes; then AC_WARN([enabling CMU local kludges]) AC_DEFINE(KRB4_IGNORE_IP_ADDRESS,[],[Ignore IP Address in Kerberos 4 tickets?]) @@ -1332,6 +1354,25 @@ AC_EGREP_HEADER(sockaddr_storage, sys/socket.h, [ AC_SUBST(DIRS) +dnl documentation generation (sphinx, perl2rst) +AC_ARG_VAR(SPHINX_BUILD, [Location of sphinx-build]) +AC_ARG_WITH([sphinx-build], + AS_HELP_STRING([with-sphinx-build=(yes|no|PATH)], [Look for sphinx-build in PATH]), + [with_sphinx_build=$withval], + [with_sphinx_build=yes]) +AS_CASE([$with_sphinx_build], + [yes], [AC_PATH_PROG(SPHINX_BUILD, sphinx-build)], + [no], [SPHINX_BUILD=''], + [*], [AC_PATH_PROG(SPHINX_BUILD, sphinx-build, [], [$with_sphinx_build])]) +AS_IF([test -z "$SPHINX_BUILD"], + [AC_MSG_WARN([No sphinx-build, won't be able to regenerate docs])]) +AC_SUBST([SPHINX_BUILD]) +AC_PROG_PERL_MODULES([Pod::POM::View::Restructured], + [have_ppvr=yes], + [AC_MSG_WARN([No Pod::POM::View::Restructured, won't be able to regenerate docs])]) +AM_CONDITIONAL([HAVE_SPHINX_BUILD], [ test -n "$SPHINX_BUILD" -a x"$have_ppvr" = xyes]) + + AH_TOP([ /* acconfig.h - autoheader configuration input */ /* diff --git a/doc/Makefile.am b/doc/Makefile.am index 0fac5863..a22bab93 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -43,47 +43,24 @@ # ################################################################ -EXTRA_DIST = rfc1321.txt \ - rfc1939.txt \ - rfc2104.txt \ - rfc2195.txt \ - rfc2222.txt \ - rfc2243.txt \ - rfc2245.txt \ - rfc2289.txt \ - rfc2444.txt \ - rfc2595.txt \ - rfc2831.txt \ - rfc2945.txt \ - rfc3174.txt \ - testing.txt \ - server-plugin-flow.fig \ - draft-burdis-cat-srp-sasl-xx.txt \ - draft-ietf-sasl-anon-xx.txt \ - draft-ietf-sasl-crammd5-xx.txt \ - draft-ietf-sasl-gssapi-xx.txt \ - draft-ietf-sasl-plain-xx.txt \ - draft-ietf-sasl-rfc2222bis-xx.txt \ - draft-ietf-sasl-rfc2831bis-xx.txt \ - draft-ietf-sasl-saslprep-xx.txt \ - draft-murchison-sasl-login-xx.txt \ - draft-newman-sasl-c-api-xx.txt \ - draft-newman-sasl-passdss-xx.txt \ - programming.html \ - sysadmin.html \ +EXTRA_DIST = advanced.html \ + appconvert.html \ + components.html \ gssapi.html \ - advanced.html \ + index.html \ + install.html \ + macosx.html \ + mechanisms.html \ + NTMakefile \ + ONEWS \ options.html \ + os390.html \ plugprog.html \ - appconvert.html \ - macosx.html \ - windows.html \ + programming.html \ readme.html \ - mechanisms.html \ - upgrading.html \ - index.html \ - components.html \ - install.html \ + server-plugin-flow.fig \ + sysadmin.html \ + testing.txt \ TODO \ - ONEWS \ - NTMakefile + upgrading.html \ + windows.html diff --git a/doc/draft-burdis-cat-srp-sasl-xx.txt b/doc/draft-burdis-cat-srp-sasl-xx.txt deleted file mode 100644 index d784f823..00000000 --- a/doc/draft-burdis-cat-srp-sasl-xx.txt +++ /dev/null @@ -1,2858 +0,0 @@ - - - -Network K. Burdis -Internet-Draft Rhodes University -Expires: November 28, 2003 R. Naffah - Forge Research - May 30, 2003 - - - Secure Remote Password Authentication Mechanism - draft-burdis-cat-srp-sasl-08 - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on November 28, 2003. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This document describes an authentication mechanism based on the - Secure Remote Password protocol (SRP-6) and how to use it with the - authentication frameworks Secure Authentication and Security Layer - (SASL), Generic Security Services Application Programming Interface - (GSS-API) and Extensible Authentication Protocol (EAP). This - mechanism performs mutual authentication and can provide a security - layer with replay detection, integrity protection and/or - confidentiality protection. - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 1] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 - 2. Conventions Used in this Document . . . . . . . . . . . . . 5 - 3. Data Element Formats . . . . . . . . . . . . . . . . . . . . 6 - 3.1 Scalar Numbers . . . . . . . . . . . . . . . . . . . . . . . 6 - 3.2 Multi-Precision Integers . . . . . . . . . . . . . . . . . . 6 - 3.3 Octet Sequences . . . . . . . . . . . . . . . . . . . . . . 7 - 3.4 Extended Octet Sequences . . . . . . . . . . . . . . . . . . 7 - 3.5 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 3.6 Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . 8 - 3.7 Data Element Size Limits . . . . . . . . . . . . . . . . . . 8 - 3.8 Unsigned Integers . . . . . . . . . . . . . . . . . . . . . 8 - 4. Protocol Description . . . . . . . . . . . . . . . . . . . . 9 - 4.1 Client Sends its Identity . . . . . . . . . . . . . . . . . 11 - 4.2 Server Agrees to Re-use Parameters of a Previous Session . . 11 - 4.3 Server Sends Protocol Elements . . . . . . . . . . . . . . . 12 - 4.4 Client Sends its Ephemeral Public Key and Evidence . . . . . 15 - 4.5 Server Verifies Client's Evidence and Sends its Evidence . . 17 - 5. Security Layer . . . . . . . . . . . . . . . . . . . . . . . 19 - 5.1 Cryptographic Primitives . . . . . . . . . . . . . . . . . . 20 - 5.1.1 Pseudo Random Number Generator . . . . . . . . . . . . . . . 20 - 5.1.2 Key Derivation Function . . . . . . . . . . . . . . . . . . 22 - 5.2 Confidentiality Protection . . . . . . . . . . . . . . . . . 23 - 5.3 Replay Detection . . . . . . . . . . . . . . . . . . . . . . 24 - 5.4 Integrity Protection . . . . . . . . . . . . . . . . . . . . 25 - 5.5 Summary of Security Layer Output . . . . . . . . . . . . . . 25 - 6. Discussion . . . . . . . . . . . . . . . . . . . . . . . . . 27 - 6.1 Mandatory Algorithms . . . . . . . . . . . . . . . . . . . . 27 - 6.2 Modulus and Generator Values . . . . . . . . . . . . . . . . 27 - 6.3 Replay Detection Sequence Number Counters . . . . . . . . . 27 - 6.4 Re-using the Parameters of a Previous Session . . . . . . . 28 - 7. SASL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 - 7.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 30 - 7.2 Mechanism Name . . . . . . . . . . . . . . . . . . . . . . . 30 - 7.3 Security Layer . . . . . . . . . . . . . . . . . . . . . . . 30 - 7.4 Profile Considerations . . . . . . . . . . . . . . . . . . . 30 - 7.5 Example . . . . . . . . . . . . . . . . . . . . . . . . . . 31 - 8. GSS-API . . . . . . . . . . . . . . . . . . . . . . . . . . 34 - 8.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 34 - 8.2 Terminology . . . . . . . . . . . . . . . . . . . . . . . . 34 - 8.3 Initial Token . . . . . . . . . . . . . . . . . . . . . . . 34 - 8.4 Security Layer . . . . . . . . . . . . . . . . . . . . . . . 35 - 9. EAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 - 9.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 36 - 9.2 Terminology . . . . . . . . . . . . . . . . . . . . . . . . 36 - 9.3 Method Details . . . . . . . . . . . . . . . . . . . . . . . 36 - 9.4 Security Claims . . . . . . . . . . . . . . . . . . . . . . 37 - - - -Burdis & Naffah Expires November 28, 2003 [Page 2] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - 10. Security Considerations . . . . . . . . . . . . . . . . . . 40 - 11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 41 - Normative References . . . . . . . . . . . . . . . . . . . . 42 - Informative References . . . . . . . . . . . . . . . . . . . 44 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 46 - A. Modulus and Generator Values . . . . . . . . . . . . . . . . 47 - B. Changes since the previous draft . . . . . . . . . . . . . . 49 - Intellectual Property and Copyright Statements . . . . . . . 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 3] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -1. Introduction - - The Secure Remote Password (SRP) is a password-based, zero-knowledge, - authentication and key-exchange protocol developed by Thomas Wu. It - has good performance, is not plaintext-equivalent and maintains - perfect forward secrecy. It provides authentication (optionally - mutual authentication) and the negotiation of a shared context key - [SRP]. - - The mechanism described herein is based on the SRP-6 protocol, - described in [SRP-6] and [SRP-6i]. SRP-6 is an improved version of - the original SRP protocol (also called SRP-3) described in - [RFC-2945]. Due to the design of the mechanism, mutual - authentication is MANDATORY. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 4] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -2. Conventions Used in this Document - - o A hex digit is an element of the set: - - {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, A, B, C, D, E, F} - - A hex digit is the representation of a 4-bit string. Examples: - - 7 = 0111 - - A = 1010 - - o An octet is an 8-bit string. In this document an octet may be - written as a pair of hex digits. Examples: - - 7A = 01111010 - - 02 = 00000010 - - o All data is encoded and sent in network byte order (big-endian). - - o The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" - in this document are to be interpreted as described in [RFC-2119]. - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 5] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -3. Data Element Formats - - This section describes the encoding of the data elements used by the - mechanism described in this document. - -3.1 Scalar Numbers - - Scalar numbers are unsigned quantities. Using b[k] to refer to the - k-th octet being processed, the value of a two-octet scalar is: - - ((b[0] << 8) + b[1]), - - where << is the bit left-shift operator. The value of a four-octet - scalar is: - - ((b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]). - - -3.2 Multi-Precision Integers - - Multi-Precision Integers, or MPIs, are positive integers used to hold - large integers used in cryptographic computations. - - MPIs are encoded using a scheme inspired by that used by OpenPGP - - [RFC-2440] (section 3.2) - for encoding such entities: - - The encoded form of an MPI SHALL consist of two pieces: a - two-octet scalar that represents the length of the entity, in - octets, followed by a sequence of octets that contain the actual - integer. - - These octets form a big-endian number; A big-endian number can be - encoded by prefixing it with the appropriate length. - - Examples: (all numbers are in hexadecimal) - - The sequence of octets [00 01 01] encodes an MPI with the value - 1, while the sequence [00 02 01 FF] encodes an MPI with the - value of 511. - - Additional rule: - - * The length field of an encoded MPI describes the octet count - starting from the MPI's first non-zero octet, containing the - most significant non-zero bit. Thus, the encoding [00 02 01] - is not formed correctly; It should be [00 01 01]. - - We shall use the syntax mpi(A) to denote the encoded form of the - - - -Burdis & Naffah Expires November 28, 2003 [Page 6] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - multi-precision integer A. Furthermore, we shall use the syntax - bytes(A) to denote the big-endian sequence of octets forming the - multi-precision integer with the most significant octet being the - first non-zero octet containing the most significant bit of A. - -3.3 Octet Sequences - - This mechanism generates, uses and exchanges sequences of octets; - e.g. output values of message digest algorithm functions. When such - entities travel on the wire, they shall be preceded by a one-octet - scalar quantity representing the count of following octets. - - Note that a zero-length octet sequence is encoded as a single 00 - octet. - - We shall use the syntax os(s) to denote the encoded form of the octet - sequence. Furthermore, we shall use the syntax bytes(s) to denote - the sequence of octets s, in big-endian order. - -3.4 Extended Octet Sequences - - Extended sequences of octets are exchanged when using the security - layer. When these sequences travel on the wire, they shall be - preceded by a four-octet scalar quantity representing the count of - following octets. - - We shall use the syntax eos(s) to denote the encoded form of the - extended octet sequence. Furthermore, we shall use the syntax - bytes(s) to denote the sequence of octets s, in big-endian order. - -3.5 Text - - The only character set for text is the UTF-8 encoding [RFC-2279] of - Unicode characters [ISO-10646]. All text MUST be in Unicode - Normalization Form KC [UNICODE-KC] without NUL characters. - - In addition, to avoid non-interoperability due to incompatible - normalisation techniques, the client MUST prepare strings using the - [SASLprep] profile of [RFC-3454] - - We shall use the syntax utf8(L) to denote the string L in UTF-8 - encoding, preceded by a two-octet scalar quantity representing the - count of following octets. Furthermore, we shall use the syntax - bytes(L) to denote the sequence of octets representing the UTF-8 - encoding of L, in big-endian order. - - Not that the empty string is encoded as the two octet sequence 00 00. - - - - -Burdis & Naffah Expires November 28, 2003 [Page 7] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -3.6 Buffers - - In this mechanism data is exchanged between the client and server - using buffers. A buffer acts as an envelope for the sequence of data - elements sent by one end-point of the exchange, and expected by the - other. - - A buffer MAY NOT contain other buffers. It may only contain zero, - one or more data elements. - - A buffer shall be encoded as two fields: a four-octet scalar quantity - representing the count of following octets, and the concatenation of - the octets of the data element(s) contained in the buffer. - - We shall use the syntax {A|B|C} to denote a buffer containing A, B - and C in that order. For example: - - { mpi(N) | mpi(g) | utf8(L) } - - is a buffer containing, in the designated order, the encoded forms of - an MPI N, an MPI g and a Text L. - -3.7 Data Element Size Limits - - The following table details the size limit, in number of octets, for - each of the data element encodings described earlier. - - Data element type Header Size limit in octets - (octets) (excluding header) - ------------------------------------------------------------ - Octet Sequence 1 255 - MPI 2 65,535 - Text 2 65,535 - Extended Octet Sequence 4 2,147,483,383 - Buffer 4 2,147,483,643 - - An implementation MUST signal an exception if any size constraint is - violated. - -3.8 Unsigned Integers - - This mechanism uses unsigned integer values ranging from zero to - 4,294,967,296. - - When such entities travel on the wire, they shall be encoded as - 4-octet Scalar Numbers. We shall use the syntax uint(n) to denote - the encoding of an Unsigned Integer n. - - - - -Burdis & Naffah Expires November 28, 2003 [Page 8] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -4. Protocol Description - - The following sections describe the sequence of data transmitted - between the client and server for SRP authentication, as well as the - extra control information exchanged to enable a client to request - whether or not replay detection, integrity protection and/or - confidentiality protection should be provided by a security layer. - There are two possible mechanism data exchanges during the - authentication phase: - - The following exchange occurs when a new session is negotiated - between the client and the server. It will also occur when the - client requests re-use of the parameters of a previous session and - either the server does not support such re-use or no longer considers - the previous session to be valid: - - Client Server - - --- { utf8(U) | utf8(I) | utf8(sid) | os(cn) } -------------> - - <------ { 00 | mpi(N) | mpi(g) | os(s) | mpi(B) | utf8(L) } --- - - --- { mpi(A) | os(M1) | utf8(o) | os(cIV) } ----------------> - - <------ { os(M2) | os(sIV) | utf8(sid) | uint(ttl) } --------- - - where: - - U is the authentication identity (username), - - I is the authorisation identity (userid), - - sid is the identifier of a previous session whose parameters the - client wishes to re-use, - - cn is the client's nonce used in deriving a new shared context - key from the shared context key of the previous session, - - 00 is an octet indicating that the previous session parameters - will NOT be re-used, - - N is the safe prime modulus, - - g is the generator, - - s is the user's password salt, - - B is the server's ephemeral public key, - - - -Burdis & Naffah Expires November 28, 2003 [Page 9] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - L is the options list indicating available security services, - - A is the client's ephemeral public key, - - M1 is the client's evidence that the shared key K is known, - - o is the options list indicating chosen security services, - - cIV is the client's initial vector for the chosen encryption - algorithm, - - M2 is the server's evidence that the shared key K is known. - - sIV is the server's initial vector for the chosen encryption - algorithm, - - sid is the identifier the server gives to this session for - possible later re-use of the negotiated parameters, - - ttl is the time period for which this session's parameters may be - re-usable, - - The following exchange occurs when the client requests that the - parameters negotiated in a previous session be re-used in this - session, but with a newly derived shared context key, and the server - agrees: - - Client Server - - --- { utf8(U) | utf8(I) | utf8(sid) | os(cn) } --------------> - - <---------------------------------- { FF | os(sn) } ---------- - - where: - - U is the authentication identity (username), - - I is the authorisation identity (userid), - - sid is the identifier of a previous session whose parameters the - client wishes to re-use, - - cn is the client's nonce used in deriving a new shared context - key from the shared context key of the previous session, - - FF is an octet indicating that the previous session parameters - WILL be re-used, - - - - -Burdis & Naffah Expires November 28, 2003 [Page 10] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - sn is the server's nonce used in deriving a new shared context - key from the shared context key of the previous session, - - -4.1 Client Sends its Identity - - The client determines its authentication identity U and authorisation - identity I, encodes them and sends them to the server. - - The semantics of both U and I are intended to be the same as - described in [SASL]. Specifically, the authentication identity U is - derived from the client's authentication credentials, and the - authorisation identity I is used by the server as the primary - identity for making access policy decisions. - - As a client might not have the same information as the server, - clients SHOULD NOT themselves try to derive authorisation identities - from authentication identities. When an authorisation identity is - not specified by the user the client SHOULD send an empty string - instead. - - If the client does not wish to re-use parameters negotiated in a - previous session then it sets sid to the empty string and cn to a - zero-length octet sequence. - - However, if the client does wish to attempt to re-use the parameters - negotiated in a previous session then it sets sid to the session - identifier for that session, and sets cn as follows: - - cn = prng() - - where: - - prng() is a random number generation function that outputs at - least 16 octets of data. - - See Section 6.4 for more information on re-using negotiated - parameters of a previous session. - - The client sends: - - { utf8(U) | utf8(I) | utf8(sid) | os(cn) } - - -4.2 Server Agrees to Re-use Parameters of a Previous Session - - If the server supports re-using the parameters negotiated in a - previous session and it considers the previous session, identified by - - - -Burdis & Naffah Expires November 28, 2003 [Page 11] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - the session identifier (sid) received from the client, to be valid, - it responds as follows: - - The server sends the octet FF as the first element of the message to - indicate to the client that parameters of the previous session are - being re-used. It also generates a nonce (sn), which is later used - in deriving a new shared context key for this session: - - sn = prng() - - where: - - prng() is a random number generation function that outputs at - least 16 octets of data. - - Note that the server nonce (sn) MUST NOT be the same as the client - nonce (cn). - - The server sends: - - { FF | os(sn) } - - See Section 6.4 for more information on re-using negotiated - parameters of a previous session and deriving the new shared context - key. - -4.3 Server Sends Protocol Elements - - Otherwise, the server receives U and looks up the safe prime modulus - N, the generator g, the salt s, and the verifier v, to be used for - that identity. It uses the this information to generate its - ephemeral public key B as follows: - - b = prng(); - - B = ((3 * v) + (g ** b)) % N; - - where: - - prng() is a random number generation function, - - b is the MPI that will act as the server's private key, - - v is the stored password verifier value, - - g is the generator, - - N is the safe prime modulus, - - - -Burdis & Naffah Expires November 28, 2003 [Page 12] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - * is the multiplication operator, - - + is the addition operator, - - ** is the exponentiation operator, - - % is the modulus operator, - - The server also creates an options list L, which consists of a - comma-separated list of option strings that specify the options the - server supports. This options list MUST NOT contain any whitespace - characters and all alphabetic characters MUST be in lowercase. When - used in digest calculations by the client the options list MUST be - used as received. - - The following option strings are defined: - - o "mda=" indicates that the server supports the designated - hash function as the underlying Message Digest Algorithm for the - designated user to be used for all SRP calculations - to compute - both client-side and server-side digests. The specified algorithm - MUST meet the requirements specified in section 3.2 of [RFC-2945]: - - "Any hash function used with SRP should produce an output of at - least 16 bytes and have the property that small changes in the - input cause significant nonlinear changes in the output." - - Note that in the interests of interoperability between client and - server implementations and with other SRP-based tools, both the - client and the server MUST support SHA-160 as an underlying - Message Digest Algorithm. While the server is not required to - list SHA-160 as an available underlying Message Digest Algorithm, - it must be able to do so. - - o "integrity=hmac-" indicates that the server supports - integrity protection using the HMAC algorithm [RFC-2104] with - as the underlying Message Digest Algorithm. Acceptable - MDA names are chosen from [SCAN] under the MessageDigest section. - A server SHOULD send such an option string for each HMAC algorithm - it supports. The server MUST advertise at least one integrity - protection algorithm and in the interest of interoperability the - server SHOULD advertise support for the HMAC-SHA-160 algorithm. - - o "replay_detection" indicates that the server supports replay - detection using sequence numbers. Replay detection SHALL NOT be - activated without also activating integrity protection. If the - replay detection option is offered (by the server) and/or chosen - (by the client) without explicitly specifying an integrity - - - -Burdis & Naffah Expires November 28, 2003 [Page 13] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - protection option, then the default integrity protection option - "integrity=hmac-sha-160" is implied and SHALL be activated. - - o "confidentiality=" indicates that the server supports - confidentiality protection using the symmetric key block cipher - algorithm . The server SHOULD send such an option - string for each confidentiality protection algorithm it supports. - Note that in the interest of interoperability, if the server - offers confidentiality protection, it MUST send the option string - "confidentiality=aes" since it is then MANDATORY for it to provide - support for the [AES] algorithm. - - o "mandatory=[integrity|replay_detection|confidentiality]" is an - option only available to the server that indicates that the - specified security layer option is MANDATORY and MUST be chosen by - the client for use in the resulting security layer. If a server - specifies an option as mandatory in this way, it MUST abort the - connection if the specified option is not chosen by the client. - It doesn't make sense for the client to send this option since it - is only able to choose options that the server advertises. The - client SHOULD abort the connection if the server does not offer an - option that it requires. If this option is not specified then - this implies that no options are mandatory. The server SHOULD - always send the "mandatory=integrity" option indicating that - integrity protection is required. - - o "maxbuffersize=" indicates to the peer the - maximum number of raw bytes (excluding the buffer header) to be - processed by the security layer at a time, if one is negotiated. - The value of MUST NOT exceed the Buffer size - limit defined in section 3.7. If this option is not detected by a - client or server mechanism, then it shall operate its security - layer on the assumption that the maximum number of bytes that may - be sent, to the peer server or client mechanism respectively, is - the Buffer data size limit indicated in section 3.7. On the other - hand, if a recipient detects this option, it shall break any - octet-sequence longer than the designated limit into two or more - fragments, before sending them separately, in sequence, to the - peer. - - For example, if the server supports integrity protection using the - HMAC-SHA-160 and HMAC-MD5 algorithms, replay detection and no - confidentiality protection, the options list would be: - - mda=sha-1,integrity=hmac-sha-160,integrity=hmac-md5,replay_detection - - The server sends the octet 00 as the first element of the message to - indicate to the client that parameters from a previous session are - - - -Burdis & Naffah Expires November 28, 2003 [Page 14] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - NOT being used. - - The server sends: - - { 00 | mpi(N) | mpi(g) | os(s) | mpi(B) | utf8(L) } - - -4.4 Client Sends its Ephemeral Public Key and Evidence - - The client receives the options list L from the server that specifies - the Message Digest Algorithm(s) available to be used for all SRP - calculations, the security service options the server supports, - including the maximum buffer size the server can handle, and the - server's ephemeral public key B. The client selects options from - this list and creates a new options list o that specifies the - selected Message Digest Algorithm to be used for SRP calculations and - the security services that will be used in the security layer. At - most one available Message Digest Algorithm name, one available - integrity protection algorithm and one available confidentiality - protection algorithm may be selected. In addition the client may - specify the maximum buffer size it can handle. The client MUST - include any option specified by the mandatory option. - - The client SHOULD always select an integrity protection algorithm - even if the server does not make it mandatory to do so. If the - client selects a confidentiality protection algorithm it SHOULD then - also select an integrity protection algorithm. - - The options list o MUST NOT contain any whitespace characters and all - alphabetic characters MUST be in lowercase. When used in digest - calculations by the server the options list MUST be used as received. - - The client generates its ephemeral public key A as follows: - - a = prng(); - - A = (g ** a) % N; - - where: - - a is the MPI that will act as the client's private key, - - The client also calculates the shared context key K, and calculates - the evidence M1 that proves to the server that it knows the shared - context key K, as well as the server's ephemeral public key B, the - user's authorisation identity I and the server's options list L. - - K, on the client's side is computed as follows: - - - -Burdis & Naffah Expires November 28, 2003 [Page 15] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - x = H(s | H(U | ":" | p)); - - u = H(A | B); - - S = ((B - (3 * (g ** x))) ** (a + (u * x))) % N; - - K = H(S); - - where: - - s is the user's password salt, - - U is the authentication identity (username), - - p is the password value. - - A is the client's ephemeral public key, - - B is the server's ephemeral public key, - - g is the generator, - - N is the safe prime modulus, - - H() is the result of digesting the designated input/data with the - chosen underlying Message Digest Algorithm function. - - - is the subtraction operator, - - * is the multiplication operator, - - + is the addition operator, - - ** is the exponentiation operator, - - % is the modulus operator, - - M1 is computed as: - - H( bytes(H( bytes(N) )) ^ bytes( H( bytes(g) )) - | bytes(H( bytes(U) )) - | bytes(s) - | bytes(A) - | bytes(B) - | bytes(K) - | bytes(H( bytes(I) )) - | bytes(H( bytes(L) )) - ) - - - -Burdis & Naffah Expires November 28, 2003 [Page 16] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - where: - - ^ is the bitwise XOR operator. - - All parameters received from the server that are used as input to a - digest operation MUST be used as received. - - If the client chooses to activate the Confidentiality Protection - service in the Security Layer, it MUST send the Initial Vector cIV - that the server will use to set up its encryption context. (See - Section 5.2 for details on the Confidentiality Protection service and - how cIV is generated.) However, this element MAY be a zero-length - octet stream if the server does not advertise the Confidentiality - Protection service or the client decides not to activate it. - - The client sends: - - { mpi(A) | os(M1) | utf8(o) | os(cIV) } - - -4.5 Server Verifies Client's Evidence and Sends its Evidence - - The server calculates the shared context key K, and verifies the - client's evidence M1. - - K, on the server's side is computed as follows: - - u = H(A | B); - - S = ((A * (v ** u)) ** b) % N; - - K = H(S); - - where: - - A is the client's ephemeral public key, - - B is the server's ephemeral public key, - - v is the stored password verifier value, - - b is the server's ephemeral private key, - - N is the safe prime modulus, - - H() is the result of digesting the designated input/data with the - chosen underlying Message Digest Algorithm function. - - - - -Burdis & Naffah Expires November 28, 2003 [Page 17] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - * is the multiplication operator, - - ** is the exponentiation operator, - - % is the modulus operator, - - If the client chose to activate the Confidentiality Protection - service in the Security Layer then the server MUST send the Initial - Vector sIV that the client will use to set up its encryption context. - (See Section 5.2 for details on the Confidentiality Protection - service and how sIV is generated.) However, this element MAY be a - zero-length octet sequence if the client did not choose to activate - the Confidentiality Protection service. - - If the server's policy allows re-using the parameters of this session - then it sets sid to a unique identifier for this session and sets ttl - to the number of seconds for which the session MAY be valid. If the - server does not support re-using the parameters of this session then - it sets sid to the empty string and ttl to any value. See Section - 6.4 for more information on re-using negotiated parameters of a - previous session. - - The server computes its evidence M2, which proves to the client that - it knows the shared context key K, as well as U, I and o, as follows: - - H( bytes(A) - | bytes(M1) - | bytes(K) - | bytes(H( bytes(I) )) - | bytes(H( bytes(o) )) - | bytes(sid) - | ttl - ) - - All parameters received from the client that are used as input to a - digest operation MUST be used as received. - - The server sends: - - { os(M2) | os(sIV) | sid | ttl } - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 18] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -5. Security Layer - - Depending on the options offered by the server and chosen by the - client, the security layer may provide integrity protection, replay - detection, and/or confidentiality protection. - - The security layer can be thought of as a three-stage filter through - which the data flows from the output of one stage to the input of the - following one. The first input is the original data, while the last - output is the data after being subject to the transformations of this - filter. - - The data always passes through this three-stage filter, though any of - the stages may be inactive. Only when a stage is active would the - output be different from the input. In other words, if a stage is - inactive, the octet sequence at the output side is an exact duplicate - of the same sequence at the input side. - - Schematically, the three-stage filter security layer appears as - follows: - - +----------------------------+ - | | I/ p1 - p1 --->| Confidentiality protection |---+ - | | | A/ c - +----------------------------+ | - | - +------------------------------------+ - | - | +----------------------------+ - | | | I/ p2 - p2 +-->| Replay detection |---+ - | | | A/ p2 | q - +----------------------------+ | - | - +------------------------------------+ - | - | +----------------------------+ - | | | I/ p3 - p3 +-->| Integrity protection |---> - | | A/ p3 | C - +----------------------------+ - - where: - - p1, p2 and p3 are the input octet sequences at each stage, - - I/ denotes the output at the end of one stage if/when the stage is - - - -Burdis & Naffah Expires November 28, 2003 [Page 19] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - inactive or disabled, - - A/ denotes the output at the end of one stage if/when the stage is - active or enabled, - - c is the encrypted (sender-side) or decrypted (receiver-side) - octet sequence. c1 shall denote the value computed by the sender, - while c2 shall denote the value computed by the receiver. - - q is a four-octet scalar quantity representing a sequence number, - - C is the Message Authentication Code. C1 shall denote the value - of the MAC as computed by the sender, while C2 shall denote the - value computed by the receiver. - - It is worth noting here that both client and server have their own - distinct security contexts, including distinct encryption and - decryption sub-contexts. In principal, nothing in this specification - should prevent an implementation from supporting asynchronous - connections. - -5.1 Cryptographic Primitives - -5.1.1 Pseudo Random Number Generator - - This mechanism requires random data to be generated for use in: - - 1. The CALG key material for both the client and server when the - Confidentiality Protection service is enabled. - - 2. The IALG key material for both the client and server when the - Integrity Protection service is enabled. - - The PRNG used in this specification is based on the pseudo-random - function described in section 5 of [UMAC]. It uses the [AES] - algorithm, in its 128-bit key size variant, as the underlying - symmetric key block cipher for its operations. - - A formal description of this PRNG follows: - - o Initialisation - - * SK: a 16-octet sequence (seeding key to AES) - - o Input - - * n: a positive integer - - - - -Burdis & Naffah Expires November 28, 2003 [Page 20] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - o Output - - * Y: an n-octet sequence - - o Algorithm - - * (initialisation) - - 1. Initialise an AES instance for encryption with the first 16 - octets of SK as its user-supplied key material. Let "aes" - be that instance; i.e. aes = AES(SK, ENCRYPTION); - - 2. Initialise T to be an all-zero 16-octet long sequence; - - * (for every input) - - 1. Initialise "remaining" to n; - - 2. Initialise Y to be a 0-length octet sequence; - - 3. while (remaining > 0) do - - 1. T = aes(T); - - 2. Append m octets from T to Y, where m is the minimum of - 16 and remaining; - - 3. Subtract 16 from remaining; - - 4. return Y; - - In this document, "PRNG(key,n)" will refer to this algorithm, with - the initialisation parameter SK set to be the octets of the specified - key, returning n bits of pseudo-random data. For example, - "PRNG(K,n)" will refer to this algorithm, with the initialisation - parameters SK set to the shared context key K computed by the SRP - calculations (see Section 4.4 and Section 4.5), returning n bits of - pseudo-random data. - - This algorithm MAY also be used as part of the SRP calculations to - generate the required "a" and "b" parameters used in creating the - client and server ephemeral private keys ("A" and "B"), or to - generate the cn and sn parameters used in session re-use, or to - generate the initial vectors sIV and cIV used to set up the - encryption contexts. In this case the initialisation parameter SK can - be any 16-octet sequence (e.g. multiple representations of the - time-of-day). - - - - -Burdis & Naffah Expires November 28, 2003 [Page 21] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - If the same PRNG instance is used for both these calculations and the - calculations in this specification, it MUST be re-initialised with - the shared context key K before any of the latter calculations are - performed. - -5.1.2 Key Derivation Function - - During the authentication phase, both parties compute the shared - context key K (see Section 4.4 for the client, and Section 4.5 for - the server sides respectively). The length of K is s bits, where "s" - is the output length of the chosen underlying Message Digest - Algorithm used in the SRP calculations (see "mda" option in Section - 4.3). - - When Confidentiality Protection is required, and the length of K is - not equal to the length of the user-supplied key material needed to - initialise the chosen Confidentiality Algorithm (CALG), the peers - MUST apply the Key Derivation Function (KDF) in order to obtain - enough data for this purpose. - - Similarly, when Integrity Protection is required, and the length of K - is not equal to the required length of the key material needed to - initialise the chosen Integrity Algorithm (IALG), the peers MUST - apply the Key Derivation Function (KDF) in order to obtain enough - data for this purpose too. - - If the KDF is required for both the key used with the CALG and the - key used with the IALG then it is first applied for the CALG key and - thereafter for the IALG key. - - We define this KDF as: - - Km = KDF(n) - - where: - - Km is the required key material, - - K is the shared context key, and - - n is the required length of Km. - - The following steps describe the KDF algorithm: - - If length of K is greater than or equal to n, then - - Let Km be the first n bytes of K; - - - - -Burdis & Naffah Expires November 28, 2003 [Page 22] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - Else - - Let Km = PRNG(K, n); - - return Km - - -5.2 Confidentiality Protection - - The plaintext data octet sequence p1 is encrypted using the chosen - confidentiality algorithm (CALG) with key size m, initialised for - encryption with the key material Kc obtained as follows: - - Kc = KDF(m) - - c1 = CALG(Kc, ENCRYPTION)( bytes(p1) ) - - On the receiving side, the ciphertext data octet sequence p1 is - decrypted using the chosen confidentiality algorithm (CALG) - initialised for decryption, with the key Kc obtained by a similar - process: - - Kc = KDF(m) - - c2 = CALG(Kc, DECRYPTION)( bytes(p1) ) - - The designated CALG symmetric-key block cipher MUST be used in OFB - (Output Feedback Block) mode in the ISO variant, as described in - [HAC], algorithm 7.20. - - Let k be the block size of the chosen symmetric key block cipher - algorithm; e.g. for AES this is 128 bits or 16 octets. The OFB mode - used shall have a block size of k. - - It is recommended that block ciphers operating in OFB mode be used - with an Initial Vector (the mode's IV). In such a mode of operation - - OFB with key re-use - the IV need not be secret. For the mechanism - described in this document, the server MUST use cIV received from the - client as the Initial Vector when initialising its encryption - context, and the client MUST use sIV received from the server as the - Initial Vector when initialising its encryption context. These - Initial Vectors are generated as: - - cIV = prng(k); - - sIV = prng(k); - - where: - - - -Burdis & Naffah Expires November 28, 2003 [Page 23] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - prng() is a random number generation function that outputs k - octets of data, - - k is the block size of the chosen symmetric key block cipher - algorithm - - The input data to the confidentiality protection algorithm shall be a - multiple of the symmetric key block cipher block size k. When the - input length is not a multiple of k octets, the data shall be padded - according to the following scheme (described in [PKCS7] which itself - is based on [RFC-1423]): - - Assuming the length of the input is l octets, (k - (l mod k)) - octets, all having the value (k - (l mod k)), shall be appended to - the original data. In other words, the input is padded at the - trailing end with one of the following sequences: - - - - 01 -- if l mod k = k-1 - 02 02 -- if l mod k = k-2 - ... - ... - ... - k k ... k k -- if l mod k = 0 - - The padding can be removed unambiguously since all input is padded - and no padding sequence is a suffix of another. This padding - method is well-defined if and only if k < 256 octets, which is the - case with symmetric block ciphers today, and in the forseeable - future. - - The output of this stage, when it is active, is: - - at the sending side: CALG(Kc, ENCRYPT)( bytes(p1) ) - - at the receiving side: CALG(Kc, DECRYPT)( bytes(p1) ) - - -5.3 Replay Detection - - A sequence number q is incremented every time a message is sent to - the peer. - - The output of this stage, when it is active, is: - - p2 | q - - - - -Burdis & Naffah Expires November 28, 2003 [Page 24] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - At the other end, the receiver increments its instance of the - sequence number. This new value of the sequence number is then used - in the integrity protection transformation, which must also be active - as described in Section 4.3. See Section 6.3 for more details. - -5.4 Integrity Protection - - When the Integrity Protection stage is active, a message - authentication code C is computed using the chosen integrity - protection algorithm (IALG) as follows: - - o the IALG is initialised (once) with the key material Ki of size n - (the required key size of the chosen IALG); i.e. Ki = KDF(n), - - o the IALG is updated with every exchange of the sequence p3, - yielding the value C and a new IALG context for use in the - following exchange. - - At the other end, the receiver computes its version of C, using the - same transformation, and checks that its value is equal to that - received. If the two values do not agree, the receiver MUST signal an - exception and abort. - - The output of this stage, when it is active, is then: - - IALG(Ki)( bytes(p3) ) - - -5.5 Summary of Security Layer Output - - The following table shows the data exchanged by the security layer - peers, depending on the possible legal combinations of the three - security services in operation: - - CP IP RD Peer sends/receives - - I I I { eos(p) } - I A I { eos(p) | os( IALG(Ki)( bytes(p) ) ) } - I A A { eos(p) | os( IALG(Ki)( bytes(p) | bytes(q)) ) } - A I I { eos(c) } - A A I { eos(c) | os( IALG(Ki)( bytes(c) ) ) } - A A A { eos(c) | os( IALG(Ki)((bytes(c) | bytes(q)) )} - - where - - CP Confidentiality protection, - - IP Integrity protection, - - - -Burdis & Naffah Expires November 28, 2003 [Page 25] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - RD Replay detection, - - I Security service is Inactive/disabled, - - A Security service is Active/enabled, - - p The original plaintext, - - q The sequence number. - - c The enciphered input obtained by either: - - CALG(Kc, ENCRYPT)( bytes(p) ) at the sender's side, or - - CALG(Kc, DECRYPT)( bytes(p) ) at the receiver's side - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 26] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -6. Discussion - -6.1 Mandatory Algorithms - - The algorithms specified as mandatory were chosen for utility and - availablity. We felt that a mandatory confidentiality and integrity - protection algorithm for the security layer and a mandatory Message - Digest Algorithm for SRP calculations should be specified to ensure - interoperability between implementations of this mechanism: - - o The SHA-160 Message Digest Algorithm was chosen as an underlying - algorithm for SRP calculations because this allows for easy - interoperability with other SRP-based tools that use the SRP-SHA1 - protocol described in section 3 of [RFC-2945] and create their - password files using this algorithm. - - o The HMAC algorithm was chosen as an integrity algorithm because it - is faster than MAC algorithms based on secret key encryption - algorithms [RFC-2847]. - - o AES was chosen as a symmetric-key block cipher because it has - undergone thorough scrutiny by the best cryptographers in the - world. - - Since confidentiality protection is optional, this mechanism should - be usable in countries that have strict controls on the use of - cryptography. - -6.2 Modulus and Generator Values - - It is RECOMMENDED that the server use values for the modulus N and - generator g chosen from those listed in Appendix A so that the client - can avoid expensive constraint checks, since these predefined values - already meet the constraints described in [RFC-2945]: - - "For maximum security, N should be a safe prime (i.e. a number of - the form N = 2q + 1, where q is also prime). Also, g should be a - generator modulo N (see [SRP] for details), which means that for - any X where 0 < X < N, there exists a value x for which g**x == X - (mod N). - - If other values are used for N and g then these values SHOULD undergo - the specified constraint checks. - -6.3 Replay Detection Sequence Number Counters - - The mechanism described in this document allows the use of a Replay - Detection security service that works by including sequence number - - - -Burdis & Naffah Expires November 28, 2003 [Page 27] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - counters in the message authentication code (MAC) created by the - Integrity Protection service. As noted in Section 4.3 integrity - protection is always activated when the Replay Detection service is - activated. - - Both the client and the server keep two sequence number counters. - Each of these counters is a 32-bit unsigned integer initialised with - a Starting Value and incremented by an Increment Value with every - successful transmission of a data buffer through the security layer. - The Sent counter is incremented for each buffer sent through the - security layer. The Received counter is incremented for each buffer - received through the security layer. If the value of a sequence - number counter exceeds 2**32-1 it wraps around and starts from zero - again. - - When a sender sends a buffer it includes the value of its Sent - counter in the computation of the MAC accompanying each integrity - protected message. When a recipient receives a buffer it uses the - value of it's Received counter in its computation of the integrity - protection MAC for the received message. The recipient's Received - counter must be the same as the sender's Sent counter in order for - the received and computed MACs to match. - - This specification assumes that for each sequence number counter the - Starting Value is ZERO, and that the Increment Value is ONE. These - values do not affect the security or the intended objective of the - replay detection service, since they never travel on the wire. - -6.4 Re-using the Parameters of a Previous Session - - Re-using the parameters of a previous session enables the client and - server to avoid the overhead of the full authentication exchange - where the client and server communicate more than once during a - server-specified time period. - - Servers are not required to support re-using the parameters of the - current session in future sessions. If they do not wish to support - this then they send an empty string for the session identifier (sid). - However, if the server's policy allows for the parameters of the - current session to be re-used later, it generates a session - identifier (sid) that will uniquely identify the session within the - specified time period (ttl). The time period (ttl) is specified in - seconds and only gives an indication to the client how long the - session may be valid. The server is not required to ensure that the - session is valid for this time period. Note that a ttl of 0 indicates - an indeterminate time period. - - To avoid session hijacking, servers SHOULD NOT indicate that a - - - -Burdis & Naffah Expires November 28, 2003 [Page 28] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - session may be re-used unless a security layer with integrity - protection and/or confidentiality protection has been negotiated. - - Clients are not required to support re-using the parameters of - previous sessions. If they do not wish to support it or they do not - wish to re-use the parameters of a previous session then they send - the empty string as the value for the session identifier (sid) and - send a zero-length octet sequence for the nonce (cn). If they do - support it and wish to use the parameters of a previous session then - they send the session identifier for this session that they - previously received from the server and calculate cn as described in - Section 4.1. - - If a client specifies a session id (sid) for a session that the - server still considers valid then the server sends the octet FF, to - indicate to the client that parameters of a previous session are - being re-used, and the nonce (sn) calculated as described in Section - 4.2. The client and server then calculate the new shared context key - Kn for this session as follows: - - Kn = H(K | cn | sn) - - where: - - K is the shared context key for the previous session identified - by sid. - - H() is the result of digesting the designated input/data with the - Message Digest Algorithm function negotiated in the previous - session identified by sid. - - Then, if the confidentiality and/or integrity protection services - were negotiated for the previous session, new keys for these services - are derived using the KDF for use in this session. (See Section - 5.1.2.) - - If the server does not support re-using parameters of previous - sessions or no longer considers the specified previous session to be - valid, it ignores the session id specified by the client and - continues the full authentication exchange. However, the first - element of the next buffer it sends is the octet 00, which indicates - to the client that no parameters of a previous session will be - re-used. - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 29] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -7. SASL - -7.1 Overview - - SASL is described as follows [RFC-2222]: - - The Simple Authentication and Security Layer (SASL) is a method - for adding authentication support to connection-based protocols. - - This document describes a mechanism that can be used within the SASL - authentication framework. - -7.2 Mechanism Name - - The SASL mechanism name associated with this protocol is "SRP". - -7.3 Security Layer - - Section 3 of [RFC-2222] describes the operation of the security layer - as follows: - - "The security layer takes effect immediately following the last - response of the authentication exchange for data sent by the - client and the completion indication for data sent by the server. - Once the security layer is in effect, the protocol stream is - processed by the security layer into buffers of cipher-text. Each - buffer is transferred over the connection as a stream of octets - prepended with a four octet field in network byte order that - represents the length of the following buffer. The length of the - cipher-text buffer must be no larger than the maximum size that - was defined or negotiated by the other side." - - -7.4 Profile Considerations - - As mentioned briefly in [RFC-2222], and detailed in [SASL] a SASL - specification has three layers: (a) a protocol definition using SASL - known as the "Profile", (b) a SASL mechanism definition, and (c) the - SASL framework. - - Point (3) in section 5 of [SASL] ("Protocol profile requirements") - clearly states that it is the responsibility of the Profile to define - "...how the challenges and responses are encoded, how the server - indicates completion or failure of the exchange, how the client - aborts an exchange, and how the exchange method interacts with any - line length limits in the protocol." - - The username entity, referenced as U throughout this document, and - - - -Burdis & Naffah Expires November 28, 2003 [Page 30] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - used by the server to locate the password data, is assumed to travel - "in the clear," meaning that no transformation is applied to its - contents. This assumption was made to allow the same SRP password - files to be used in this mechanism, as those used with other SRP - applications and tools. - - A Profile may decide, for privacy or other reason, to disallow such - information to travel in the clear, and instead use a hashed version - of U, or more generally a transformation function applied to U; i.e. - f(U). Such a Profile would require additional tools to add the - required entries to the SRP password files for the new value(s) of - f(U). It is worth noting too that if this is the case, and the same - user shall access the server through this mechanism as well as - through other SRP tools, then at least two entries, one with U and - the other with f(U) need to be present in the SRP password files if - those same files are to be used for both types of access. - -7.5 Example - - The example below uses SMTP authentication [RFC-2554]. The base64 - encoding of challenges and responses, as well as the reply codes - preceding the responses are part of the SMTP authentication - specification, not part of this SASL mechanism itself. - - "C:" and "S:" indicate lines sent by the client and server - respectively. - - S: 220 smtp.example.com ESMTP server ready - - C: EHLO zaau.example.com - - S: 250-smtp.example.com - S: 250 AUTH SRP CRAM-MD5 DIGEST-MD5 - - C: AUTH SRP AAAADAAEdGVzdAAEdGVzdA== - - with: - - U = "test" - - I = "test" - - S: 334 AAABygEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ - 7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq6Ck - YqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uAFna9IH - pDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+zeGFgJ5AE5 - Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J965DXeI21SX1R1 - m2XjcvzWjvIPpxEfnkr/cwABAgqsi3AvmIqdEbREALhtZGE9U0hBLTEsbWFuZGF0b3J - - - -Burdis & Naffah Expires November 28, 2003 [Page 31] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - 5PXJlcGxheSBkZXRlY3Rpb24scmVwbGF5IGRldGVjdGlvbixpbnRlZ3JpdHk9aG1hYy - 1zaGExLGludGVncml0eT1obWFjLW1kNSxjb25maWRlbnRpYWxpdHk9YWVzLGNvbmZpZ - GVudGlhbGl0eT1jYXN0NSxjb25maWRlbnRpYWxpdHk9Ymxvd2Zpc2gsbWF4YnVmZmVy - c2l6ZT0yMTQ3NDgzNjQz - - with: - - N = "21766174458617435773191008891802753781907668374255538511144 - 6432246898862353838409572109090130860564015713997172358072665816 - 4960647214841029141336415219736447718088739565548373811507267740 - 2235101762521901569820740293149529620419333266262073471054548368 - 7360395197024862265062488610602569718029849535611214426801576680 - 0076142998822245709041387397397017192709399211475176516806361476 - 1119615476233422096442783117971236371647333871414335895773474667 - 3089670508070055093204247996784170368679283167612722742303140675 - 4829113358247958306143957755934710196177140617368437852270348349 - 5337037655006751328447510550299250924469288819" - - g = "2" - - s = "814819216327401865851972" - - L = "mda=sha-1,mandatory=replay_detection,replay_detection,integ - rity=hmac-sha1,integrity=hmac-md5,confidentiality=aes,confidenti - ality=cast5,confidentiality=blowfish,maxbuffersize=2147483643" - - C: AAABYwEAAp5q/4zhXoTUzXBscozN97SWgfDcAImIk3lNHNvd0b+Dr7jEm6upXblZ - T5sL9mPgFsejlIh+B/eCu/HvzWCrXj6ylPZv8dy3LCH3LIORqQ45S7Lsbmrrg/dukDh - 4tZCJMLD4r3evzaY8KVhtJeLMVbeXuh4JljKP42Ll59Lzwf8jfPh4+4Lae1rpWUCL9D - ueKcY+nN+xNHTit/ynLATxwL93P6+GoGY4TkUbUBfjiI1+rAMvyMDMw5XozGy07FOEc - ++U0iPeXCQP4MT5FipOUoz8CYX7J1LbaXp2WJuFHlkyVXF7oCoyHbhld/5CfR3o6q/B - /x9+yZRqaHH+JfllOgBfbWRhPVNIQS0xLHJlcGxheSBkZXRlY3Rpb24saW50ZWdyaXR - 5PWhtYWMtbWQ1LGNvbmZpZGVudGlhbGl0eT1ibG93ZmlzaCxtYXhidWZmZXJzaXplPT - IxNDc0ODM2NDM= - - with: - - A = "33059541846712102497463123211304342021934496372587869281515 - 9695658237779884462777478850394977744553746930451895815615888405 - 0562780707370878253753979367019077142882237029766166623275718227 - 6555389834190840322081091599089081947324537907613924707058150037 - 7802790776231793962143786411792516760030102436603621046541729396 - 6890613394379900527412007068242559299422872893332111365840536495 - 1858834742328835373387573188369956379881606380890675411966073665 - 1106922002294035533470301541999274557200666703389531481794516625 - 4757418442215980634933876533189969562613241499465295849832999091 - 40398081321840949606581251320320995783959866" - - - - -Burdis & Naffah Expires November 28, 2003 [Page 32] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - o = mda=sha-1,replay_detection,integrity=hmac-md5,confidentialit - y=blowfish,maxbuffersize=2147483643" - - S: 334 AAABAgEAOUKbXpnzMhziivGgMwm+FS8sKGSvjh5M3D+80RF/5z9rm0oPoi4+ - pF83fueWn4Hz9M+muF/22PHHZkHtlutDrtapj4OtirdxC21fS9bMtEh3F0whTX+3mPv - thw5sk11turandHiLvcUZOgcrAGIoDKcBPoGyBud+8bMgpkf/uGfyBM2nEX/hV+oGgg - X+LiHjmkxAJ3kewfQPH0eV9ffEuuyu8BUcBXkJsS6l7eWkuERSCttVOi/jS031c+CD/ - nuecUXYiF8IYzW03rbcwYhZzifmTi3VK9C8zG2K1WmGU+cDKlZMkyCPMmtCsxlbgE8z - SHCuCiOgQ35XhcA0Qa0C3Q== - - with: - - B: "722842847565031844205403087285424428589273458129750231766015 - 4465607827529853239240118185263492617243523916106658696965596526 - 8585300845435562962039149169549800169184521786717633959469278439 - 8771344445002432579509292115598435685062882631760796416554562980 - 8475896198325835507901319556929511421472132184990365213059654962 - 7218189966140113906545856088040473723048909402258929560823932725 - 2022154114087913895411927676707073040281136096806681758265221209 - 8822374723416364340410020172215773934302794679034424699999611678 - 9730443114919539575466941344964841591072763617954717789621871251 - 71089179399349194452686682517183909017223901" - - C: AAAAFRTkoju6xGP+zH89iaDWIFjfIKt5Kg== - - S: 235 Authentication successful. - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 33] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -8. GSS-API - -8.1 Overview - - The GSS-API is described as follows: - - The Generic Security Service Application Program Interface - (GSS-API), Version 2, as defined in [RFC-2078], provides security - services to callers in a generic fashion, supportable with a range - of underlying mechanisms and technologies and hence allowing - source-level portability of applications to different - environments. - - According to [RFC-2078] there are certain specifications related to - the GSS-API that are: - - "documents defining token formats, protocols, and procedures to be - implemented in order to realize GSS-API services atop particular - security mechanisms" - - This specification is such a document - it defines a security - mechanism that can be used with the GSS-API authentication framework. - -8.2 Terminology - - The tokens referred to in the GSS-API specification [RFC-2078] are - the same as the buffers referred to in this document. - -8.3 Initial Token - - [RFC-2078] states that: - - The first context-level token obtained from GSS_Init_sec_context() - is required to indicate at its very beginning a - globally-interpretable mechanism identifier, i.e., an Object - Identifier (OID) of the security mechanism. The remaining part of - this token as well as the whole content of all other tokens are - specific to the particular underlying mechanism used to support - the GSS-API. - - To satisfy this requirement and make use of the mechanism described - in this document as a GSS-API mechanism, the following octets must be - prefixed to the first buffer sent as part of the protocol described - in Section 4: - - [ 60 08 06 06 2B 06 01 05 05 08 ] - - Each octet is written as a pair of hex digits - see Section 2. - - - -Burdis & Naffah Expires November 28, 2003 [Page 34] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - These octets represent the encoding of the GSS-API mechanism - identifier as per section 3.1 of [RFC-2078]. The OID for this - mechanism is iso.org.dod.internet.security.mechanisms.srp - (1.3.6.1.5.5.8). - - Note that it is not possible to make this requirement part of the - security protocol itself, because other authentication frameworks - have different requirements for the initial octets in a mechanism - buffer. - -8.4 Security Layer - - This mechanism does not provide distinct replay detection and - sequencing services as part of the security layer. Both of these - services are provided through the use of sequence numbers in - integrity protected messages. If a GSS-API caller sets either the - replay_det_req_flag or the sequence_req_flag (section 1.2.3 of - [RFC-2078]) then this selects the "replay_detection" security - service. - - This mechanism does not make use of any channel binding data (section - 1.1.6 of [RFC-2078]). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 35] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -9. EAP - -9.1 Overview - - The Extensible Authentication Protocol (EAP) [RFC-2284] is an - authentication framework that supports multiple authentication - mechanisms. It is used with link layer protocols such as PPP and the - IEEE-802 wired and wireless protocols. - -9.2 Terminology - - EAP uses the following terms to describe the entities involved in the - authentication exchange [rfc2284bis]: - - Authenticator: The entity that initiates EAP authentication in order - to authenticate a Peer. - - Peer: The entity that responds to requests from the Authenticator. - - In this document, the Server corresponds to the Authenticator and the - Client corresponds to the Peer. - -9.3 Method Details - - The EAP authentication method described in this document has the - following properties: - - Method Name: SRP - - Method Type: 7 - - As described in section 2 of [rfc2284bis] the EAP authentication - exchange is initiated by the Authenticator sending a Request packet - to the peer with a Type field indicating the type of request. The - Peer responds with a corresponding Reply packet, and the - Authenticator and Peer exchange additional corresponding Request and - Reply packets until the Authenticator deems that the authentication - exchange is successful and complete, whereafter the Authenticator - sends a Success packet. However, if at any time the Authenticator - deems the authentication exchange to be unsuccessful it sends a - Failure packet to indicate this. - - When using this authentication method, the Type field in all Request - and Reply packets is set to 7 and the Type Data is as described in - Section 4 and the rest of this document. The diagrams below - illustrate the EAP packet exchanges for this authentication method. - - The following exchange occurs when a new session is negotiated - - - -Burdis & Naffah Expires November 28, 2003 [Page 36] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - between the client and the server. It will also occur when the - client requests re-use of the parameters of a previous session and - either the server does not support such re-use or no longer considers - the previous session to be valid: - - Peer (client) Authenticator (server) - - <------------ Request [ 7, { } ] ---------------------------- - - ---- Reply [ 7, { U, I, sid, cn } ] -------------------------> - - <------------ Request [ 7, { 00, N, g, s, B, L } ] ---------- - - ---- Reply [ 7, { A, M1, o, cIV } ] ------------------------> - - <------------ Request [ 7, { M2, sIV, sid, ttl } ] ---------- - - ---- Reply [ 7, { } ] --------------------------------------> - - The following exchange occurs when the client requests that the - parameters negotiated in a previous session be re-used in this - session, but with a newly derived shared context key, and the server - agrees: - - Peer (client) Authenticator (server) - - <----------------------------- Request [ 7, { } ] ----------- - - --------- Reply [ 7, { U, I, sid, cn } ] -------------------> - - <----------------------------- Request [ 7, { FF, sn } ] ---- - - --------- Reply [ 7, { } ] ---------------------------------> - - If a security layer is negotiated then the payloads of all subsequent - lower layer packets sent over the link are protected using the - negotiated security services. - -9.4 Security Claims - - As required by section 7.2 of [rfc2284bis], these are the security - claims made by this authentication method indicating the level of - security provided: - - Intended Use: Wired networks, including PPP, PPPOE, and IEEE-802 - wired media. Use over the Internet or with wireless media only - when the recommended security layer has been negotiated. - - - - -Burdis & Naffah Expires November 28, 2003 [Page 37] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - Mechanism: Passphrase - - Mutual authentication: Yes. This mechanism requires mutual - authentication. - - Integrity protection: Yes. The calculations of evidence that the - shared context key is known - M1 sent by the client and M2 sent by - the server - include the protocol elements received from the - other party, so any modification by a third party will be - detected. SRP itself is resistent to known active and passive - attacks - see [SRP]. - - Replay protection: Yes. Both the client and the server randomly - generate ephemeral private keys (a and b) that are used in the SRP - calculations, but are not publicly revealed. New ephemeral - private keys are generated for each session making replay attacks - infeasible. - - Confidentiality: No. - - Key Derivation: No. - - Dictionary attack protection: Yes. From [SRP]: "An attacker with - neither the user's password nor the host's password file cannot - mount a dictionary attack on the password". - - Fast reconnect: Yes. An optional, optimised alternate authentication - exchange is available where the parameters of a previously - negotiated session are re-used, but with a newly derived shared - context key - see Section 6.4. - - Man-in-the-Middle resistance: Yes. The calculations of evidence - M1 - sent by the client and M2 sent by the server - include the - protocol elements received from the other party, so any - modification by a third party will be detected. SRP itself is - resistent to known active attacks, including man-in-the-middle - attacks - see [SRP]. - - Acknowledged result indications: Yes. When the client receives M2 - from the server it knows that the server has verified that the - evidence (M1) it presented to prove its knowledge of the shared - context key is correct, so it knows that it is authenticated to - the server. When the server receives the empty response from the - client at the end of the authentication exchange, it knows that - the client has verified that the evidence (M2) it presented to - prove its knowledge of the shared context key is correct, so it - knows that it is authenticated to the client. Similarly for - session re-use where the client receives the server nonce (sn) - - - -Burdis & Naffah Expires November 28, 2003 [Page 38] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - from the server, and the server receives the final empty response - from the client. - - Key hierarchy: N/A - - Key strength: The shared context key (K) negotiated between the - client and server has a length of s, where "s" is the output - length of the chosen underlying Message Digest Algorithm used in - the SRP calculations (see "mda" option in Section 4.3). For - example, the recommended Message Digest Algorithm SHA-160 has an - output length of 160 bits, so in this case the length of K would - be 160 bits. Keys for the confidentiality and integrity - protection services are derived from K - see Section 5.1.2 - and - have sizes appropriate for the algorithms being used. Note that - all Message Digest Algorithms used with this mechanism MUST have - an output of at least 16 bytes (see "mda" option in Section 4.3), - which means that the shared context key will always have a length - of at least 128 bits. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 39] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -10. Security Considerations - - This mechanism relies on the security of SRP, which bases its - security on the difficulty of solving the Diffie-Hellman problem in - the multiplicative field modulo a large safe prime. See section 4 - "Security Considerations" of [RFC-2945], section 4 "Security - analysis" of [SRP], and [SRP-6i]. - - This mechanism also relies on the security of the HMAC algorithm and - the underlying hash function when integrity protection is used. - Section 6 "Security" of [RFC-2104] discusses these security issues in - detail. Weaknesses found in MD5 do not impact HMAC-MD5 [DOBBERTIN]. - - U, I, A and o, sent from the client to the server, and N, g, s, B and - L, sent from the server to the client, could be modified by an - attacker before reaching the other party. For this reason, these - values are included in the respective calculations of evidence (M1 - and M2) to prove that each party knows the shared context key K. - This allows each party to verify that these values were received - unmodified. - - The use of integrity protection is RECOMMENDED to detect message - tampering and to avoid session hijacking after authentication has - taken place. - - Replay attacks may be avoided through the use of sequence numbers, - because sequence numbers make each integrity protected message - exchanged during a session different, and each session uses a - different key. - - Research [KRAWCZYK] shows that the order and way of combining message - encryption (Confidentiality Protection) and message authentication - (Integrity Protection) are important. This mechanism follows the EtA - (encrypt-then-authenticate) method and is "generically secure". - - This mechanism uses a Pseudo-Random Number Generator (PRNG) for - generating some of its parameters. Section 5.1.1 describes a - securely seeded, cryptographically strong PRNG implementation for - this purpose. - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 40] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -11. Acknowledgements - - The following people provided valuable feedback in the preparation of - this document: - - Stephen Farrell - - Sam Hartman - - Timothy Martin - - Alexey Melnikov - - Ken Murchison - - Magnus Nystrom - - David Taylor - - Thomas Wu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 41] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Normative References - - [RFC-2078] - Linn, J., "Generic Security Service Application Program - Interface, Version 2", RFC 2078, January 1997, . - - [RFC-2104] - Krawczyk, H., "HMAC: Keyed-Hashing for Message - Authentication", RFC 2104, February 1997, . - - [RFC-2119] - Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 0014, RFC 2119, March 1997, - . - - [RFC-2222] - Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997, . - - [RFC-2284] - Blunk, L. and J. Vollbrecht, "PPP Extensible - Authentication Protocol (EAP)", RFC 2284, March 1998, - . - - [rfc2284bis] - Blunk, L., Vollbrecht, J., Aboba, B., Carlson, J. and H. - Levkowetz, "Extensible Authentication Protocol (EAP), work - in progress", May 2003, . - - [RFC-2945] - Wu, T., "The SRP Authentication and Key Exchange System", - RFC 2945, September 2000, . - - [RFC-3454] - Hoffman, P. and M. Blanchet, "Preparation of - Internationalized Strings ("stringprep")", RFC 3454, - December 2002, . - - [SASL] Myers, J., "Simple Authentication and Security Layer - (SASL)", April 2002, . - - [SASLprep] - - - -Burdis & Naffah Expires November 28, 2003 [Page 42] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - Zeilenga, K., "SASLprep: Stringprep profile for user names - and passwords, work in progress", May 2003, . - - [SRP] Wu, T., "The Secure Remote Password Protocol, Proceedings - of the 1998 Internet Society Network and Distributed - System Security Symposium, San Diego, CA, Mar 1998, pp. - 97-111", March 1998, . - - [SRP-6i] Wu, T., "SRP-6: Improvements and Refinements to the Secure - Remote Password Protocol", October 2002, . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 43] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Informative References - - [AES] National Institute of Standards and Technology, "Rijndael: - NIST's Selection for the AES", December 2000, . - - [DOBBERTIN] - Dobbertin, H., "The Status of MD5 After a Recent Attack", - December 1996, . - - [HAC] Menezes, A., van Oorschot, P. and S. Vanstone, "Handbook - of Applied Cryptography", CRC Press, Inc., ISBN - 0-8493-8523-7, 1997, . - - [ISO-10646] - International Standards Organization, "International - Standard --Information technology-- Universal - Multiple-Octet Coded Character Set (UCS) -- Part 1 - Architecture and Basic Multilingual Plane. UTF-8 is - described in Annex R, adopted but not yet published. - UTF-16 is described in Annex Q, adopted but not yet - published.", ISO/IEC 10646-1, 1993. - - [KRAWCZYK] - Krawczyk, H., "The order of encryption and authentication - for protecting communications (Or: how secure is SSL?)", - June 2001, . - - [PKCS7] RSA Data Security, Inc., "PKCS #7: Cryptographic Message - Syntax Standard", Version 1.5, November 1993, . - - [RFC-1423] - Balenson, D., "Privacy Enhancement for Internet Electronic - Mail: Part III: Algorithms, Modes, and Identifiers", RFC - 1423, February 1993, . - - [RFC-2279] - Yergeau, F., "UTF-8, a transformation format of Unicode - and ISO 10646", RFC 2279, January 1998, . - - [RFC-2440] - Callas, J., Donnerhacke, L., Finney, H. and R. Thayer, - "OpenPGP Message Format", RFC 2440, November 1998, . - - [RFC-2554] - Myers, J., "SMTP Service Extension for Authentication", - RFC 2554, March 1999. - - [RFC-2629] - Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, - June 1999, . - - [RFC-2847] - Eisler, M., "LIPKEY - A Low Infrastructure Public Key - Mechanism Using SPKM", RFC 2847, June 2000, . - - [SCAN] Hopwood, D., "Standard Cryptographic Algorithm Naming", - June 2000, . - - [SRP-6] Wu, T., "SRP Protocol Design", October 2002, . - - [SRPimpl] Wu, T., "SRP: The Open Source Password Authentication - Standard", March 1998, . - - [UMAC] Black, J., Halevi, S., Krawczyk, H., Krovetz, T. and P. - Rogaway, "UMAC: Fast and Secure Message Authentication, - Advances in Cryptology - CRYPTO '99. Lecture Notes in - Computer Science, vol. 1666, Springer-Verlag, 1999, pp. - 216-233", October 2000, . - - [UNICODE] The Unicode Consortium, "The Unicode Standard, Version - 3.2.0, is defined by The Unicode Standard, Version 3.0, as - amended by the Unicode Standard Annex #27: Unicode 3.1 and - by the Unicode Standard Annex #28: Unicode 3.2.", March - 2002, . - - [UNICODE-KC] - Durst, D., "Unicode Standard Annex #15: Unicode - Normalization Forms.", March 2001, . - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 45] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Authors' Addresses - - Keith Burdis - Rhodes University - Computer Science Department - Grahamstown 6139 - ZA - - EMail: keith@rucus.ru.ac.za - - - Raif S. Naffah - Forge Research Pty. Limited - Suite 116, Bay 9 - Locomotive Workshop, - Australian Technology Park - Cornwallis Street - Eveleigh, NSW 1430 - AU - - EMail: raif@forge.com.au - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 46] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Appendix A. Modulus and Generator Values - - Modulus N and generator g values for various modulus lengths are - given below. In each case the modulus is a large safe prime and the - generator is a primitve root of GF(n) [RFC-2945]. These values are - taken from software developed by Tom Wu and Eugene Jhong for the - Stanford SRP distribution [SRPimpl]. - - [264 bits] - Modulus (base 16) = - 115B8B692E0E045692CF280B436735C77A5A9E8A9E7ED56C965F87DB5B2A2 - ECE3 - Generator = 2 - - [384 bits] - Modulus (base 16) = - 8025363296FB943FCE54BE717E0E2958A02A9672EF561953B2BAA3BAACC3E - D5754EB764C7AB7184578C57D5949CCB41B - Generator = 2 - - [512 bits] - Modulus (base 16) = - D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF75 - 6EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DB - DFCA43 - Generator = 2 - - [640 bits] - Modulus (base 16) = - C94D67EB5B1A2346E8AB422FC6A0EDAEDA8C7F894C9EEEC42F9ED250FD7F0 - 046E5AF2CF73D6B2FA26BB08033DA4DE322E144E7A8E9B12A0E4637F6371F - 34A2071C4B3836CBEEAB15034460FAA7ADF483 - Generator = 2 - - [768 bits] - Modulus (base 16) = - B344C7C4F8C495031BB4E04FF8F84EE95008163940B9558276744D91F7CC9 - F402653BE7147F00F576B93754BCDDF71B636F2099E6FFF90E79575F3D0DE - 694AFF737D9BE9713CEF8D837ADA6380B1093E94B6A529A8C6C2BE33E0867 - C60C3262B - Generator = 2 - - [1024 bits] - Modulus (base 16) = - EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256 - 576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D60 - 89DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F56 - 6660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC6 - - - -Burdis & Naffah Expires November 28, 2003 [Page 47] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - 1D2FC0EB06E3 - Generator = 2 - - [1280 bits] - Modulus (base 16) = - D77946826E811914B39401D56A0A7843A8E7575D738C672A090AB1187D690 - DC43872FC06A7B6A43F3B95BEAEC7DF04B9D242EBDC481111283216CE816E - 004B786C5FCE856780D41837D95AD787A50BBE90BD3A9C98AC0F5FC0DE744 - B1CDE1891690894BC1F65E00DE15B4B2AA6D87100C9ECC2527E45EB849DEB - 14BB2049B163EA04187FD27C1BD9C7958CD40CE7067A9C024F9B7C5A0B4F5 - 003686161F0605B - Generator = 2 - - [1536 bits] - Modulus (base 16) = - 9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19C - C4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A - 22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D4754838 - 1DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2F - D53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87 - F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A23 - 4DCF76E3FED135F9BB - Generator = 2 - - [2048 bits] - Modulus (base 16) = - AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56 - 050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA - 04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A99 - 62F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D28 - 1E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5 - B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3 - 786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D - 0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372 - FCD68EF20FA7111F9E4AFF73 - Generator = 2 - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 48] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Appendix B. Changes since the previous draft - - Removed specific references to SASL in the main document, instead - isolating them to their own section. - - Added sections describing how the mechanism can be used with the - GSS-API and EAP authentication frameworks. - - Adopted SRP-6 exchange for the base protocol. - - Mandated the use of SASLprep profile for text based information. - - Added an optional, optimised alternate authentication exchange where - the parameters of a previously negotiated session are re-used, but - with a newly derived shared context key. - - TODO: Regenerate SASL example. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 49] - -Internet-Draft SRP Authentication Mechanism May 2003 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it - has made any effort to identify any such rights. Information on the - IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such - proprietary rights by implementors or users of this specification can - be obtained from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assignees. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - - - -Burdis & Naffah Expires November 28, 2003 [Page 50] - -Internet-Draft SRP Authentication Mechanism May 2003 - - - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Burdis & Naffah Expires November 28, 2003 [Page 51] - - diff --git a/doc/draft-ietf-sasl-anon-xx.txt b/doc/draft-ietf-sasl-anon-xx.txt deleted file mode 100644 index bcff00a0..00000000 --- a/doc/draft-ietf-sasl-anon-xx.txt +++ /dev/null @@ -1,507 +0,0 @@ - - - - - - -INTERNET-DRAFT Editor: Kurt D. Zeilenga -Intended Category: Standards Track OpenLDAP Foundation -Expires in six months 30 June 2003 -Obsoletes: RFC 2245 - - - The Anonymous SASL Mechanism - - - -Status of Memo - - This document is an Internet-Draft and is in full conformance with all - provisions of Section 10 of RFC2026. - - This document is intended to be, after appropriate review and - revision, submitted to the RFC Editor as a Standards Track document. - Distribution of this memo is unlimited. Technical discussion of this - document will take place on the IETF SASL mailing list - . Please send editorial comments directly to the - document editor . - - Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as ``work in progress.'' - - The list of current Internet-Drafts can be accessed at - . The list of - Internet-Draft Shadow Directories can be accessed at - . - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - Please see the Full Copyright section near the end of this document - for more information. - - -Abstract - - It is common practice on the Internet to permit anonymous access to - various services. Traditionally, this has been done with a plain text - password mechanism using "anonymous" as the user name and optional - trace information, such as an email address, as the password. As - plain text login commands are not permitted in new IETF protocols, a - - - -Zeilenga Anonymous SASL Mechanism [Page 1] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - new way to provide anonymous login is needed within the context of the - Simple Authentication and Security Layer (SASL) framework. - - -Conventions - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [Keywords]. - - -1. Anonymous SASL mechanism - - This document defines an anonymous mechanism for the Simple - Authentication and Security Layer ([SASL]) framework. The name - associated with this mechanism is "ANONYMOUS". - - This document replaces RFC 2245. Changes since RFC 2245 are detailed - in Appendix A. - - The mechanism consists of a single message from the client to the - server. The client sends optional trace information in the form of a - string of [UTF-8] encoded [Unicode] characters prepared in accordance - with [StringPrep] and the "trace" stringprep profile defined in - Section 2 of this document. The trace information, which has no - semantical value, should take one of three forms: an Internet email - address, an opaque string which does not contain the '@' (U+0040) - character and can be interpreted by the system administrator of the - client's domain, or nothing. For privacy reasons, an Internet email - address or other information identifying the user should only be used - with permission from the user. - - A server which permits anonymous access will announce support for the - ANONYMOUS mechanism, and allow anyone to log in using that mechanism, - usually with restricted access. - - This mechanism does not provide a security layer. - - A formal grammar for the client message using Augmented BNF [ABNF] is - provide below as a tool for understanding this technical - specification. - - message = [ email / token ] - ;; MUST be prepared in accordance with Section 2 - - UTF1 = %x00-3F / %x41-7F ;; less '@' (U+0040) - UTF2 = %xC2-DF UTF0 - UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) / - - - -Zeilenga Anonymous SASL Mechanism [Page 2] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - %xED %x80-9F UTF0 / %xEE-EF 2(UTF0) - UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) / - %xF4 %x80-8F 2(UTF0) - UTF0 = %x80-BF - - TCHAR = UTF1 / UTF2 / UTF3 / UTF4 - ;; any UTF-8 encoded Unicode character - ;; except '@' (U+0040) - - email = addr-spec - ;; as defined in [IMAIL], except with no free - ;; insertion of linear-white-space, and the - ;; local-part MUST either be entirely enclosed in - ;; quotes or entirely unquoted - - token = 1*255TCHAR - - Note to implementors: - The production is restricted to 255 UTF-8 encoded Unicode - characters. As the encoding of a characters uses a sequence of 1 - to 4 octets, a token may be long as 1020 octets. - - -2. The "trace" profile of "Stringprep" - - This section defines the "trace" profile of [StringPrep]. This - profile is designed for use with the SASL ANONYMOUS Mechanism. - Specifically, the client MUST prepare the production in - accordance with this profile. - - The character repertoire of this profile is Unicode 3.2 [Unicode]. - - No mapping is required by this profile. - - No Unicode normalization is required by this profile. - - The list of unassigned code points for this profile is that provided - in appendix A of [RFC 3454]. Unassigned code points are not - prohibited. - - Characters from the following tables of [StringPrep] are prohibited: - - C.2.1 (ASCII control characters) - - C.2.2 (Non-ASCII control characters) - - C.3 (Private use characters) - - C.4 (Non-character code points) - - C.5 (Surrogate codes) - - C.6 (Inappropriate for plain text) - - C.8 (Change display properties are deprecated) - - - -Zeilenga Anonymous SASL Mechanism [Page 3] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - - C.9 (Tagging characters) - - No additional characters are prohibited. - - This profile requires bidirectional character checking per Section 6 - of [StringPrep]. - - -3. Example - - Here is a sample ANONYMOUS login between an IMAP client and server. - In this example, "C:" and "S:" indicate lines sent by the client and - server respectively. If such lines are wrapped without a new "C:" or - "S:" label, then the wrapping is for editorial clarity and is not part - of the command. - - Note that this example uses the IMAP profile [IMAP4] of SASL. The - base64 encoding of challenges and responses, as well as the "+ " - preceding the responses are part of the IMAP4 profile, not part of - SASL itself. Newer profiles of SASL will include the client message - with the AUTHENTICATE command itself so the extra round trip below - (the server response with an empty "+ ") can be eliminated. - - In this example, the user's opaque identification token is "sirhc". - - S: * OK IMAP4 server ready - C: A001 CAPABILITY - S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=DIGEST-MD5 AUTH=ANONYMOUS - S: A001 OK done - C: A002 AUTHENTICATE ANONYMOUS - S: + - C: c2lyaGM= - S: A003 OK Welcome, trace information has been logged. - - -4. Security Considerations - - The ANONYMOUS mechanism grants access to information by anyone. For - this reason it should be disabled by default so the administrator can - make an explicit decision to enable it. - - If the anonymous user has any write privileges, a denial of service - attack is possible by filling up all available space. This can be - prevented by disabling all write access by anonymous users. - - If anonymous users have read and write access to the same area, the - server can be used as a communication mechanism to anonymously - exchange information. Servers which accept anonymous submissions - - - -Zeilenga Anonymous SASL Mechanism [Page 4] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - should implement the common "drop box" model which forbids anonymous - read access to the area where anonymous submissions are accepted. - - If the anonymous user can run many expensive operations (e.g., an IMAP - SEARCH BODY command), this could enable a denial of service attack. - Servers are encouraged to reduce the priority of anonymous users or - limit their resource usage. - - While servers may impose a limit on the number of anonymous users, it - is noted that such limits enable denial of service attacks and should - be used with caution. - - The trace information is not authenticated so it can be falsified. - This can be used as an attempt to get someone else in trouble for - access to questionable information. Administrators trying to trace - abuse need to realize this information may be falsified. - - A client which uses the user's correct email address as trace - information without explicit permission may violate that user's - privacy. Information about who accesses an anonymous archive on a - sensitive subject (e.g., sexual abuse) has strong privacy needs. - Clients should not send the email address without explicit permission - of the user and should offer the option of supplying no trace token -- - thus only exposing the source IP address and time. Anonymous proxy - servers could enhance this privacy, but would have to consider the - resulting potential denial of service attacks. - - Anonymous connections are susceptible to man in the middle attacks - which view or alter the data transferred. Clients and servers are - encouraged to support external integrity and encryption mechanisms. - - Protocols which fail to require an explicit anonymous login are more - susceptible to break-ins given certain common implementation - techniques. Specifically, Unix servers which offer user login may - initially start up as root and switch to the appropriate user id after - an explicit login command. Normally such servers refuse all data - access commands prior to explicit login and may enter a restricted - security environment (e.g., the Unix chroot(2) function) for anonymous - users. If anonymous access is not explicitly requested, the entire - data access machinery is exposed to external security attacks without - the chance for explicit protective measures. Protocols which offer - restricted data access should not allow anonymous data access without - an explicit login step. - - General [SASL] security considerations apply to this mechanism. - - [StringPrep] security considerations as well as [Unicode] security - considerations discussed in [StringPrep] apply to this mechanism. - - - -Zeilenga Anonymous SASL Mechanism [Page 5] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - [UTF-8] security considerations also apply. - - -5. IANA Considerations - - It is requested that the SASL Mechanism registry [IANA-SASL] entry for - the ANONYMOUS mechanism be updated to reflect that this document now - provides its technical specification. - - To: iana@iana.org - Subject: Updated Registration of SASL mechanism ANONYMOUS - - SASL mechanism name: ANONYMOUS - Security considerations: See RFC XXXX. - Published specification (optional, recommended): RFC XXXX - Person & email address to contact for further information: - Kurt Zeilenga - Chris Neuman - Intended usage: COMMON - Author/Change controller: IESG - Note: Updates existing entry for ANONYMOUS - - - It is requested that the [Stringprep] profile "trace", first defined - in this RFC, be registered: - - To: iana@iana.org - Subject: Initial Registration of Stringprep "trace" profile - - Stringprep profile: trace - Published specification: RFC XXXX - Person & email address to contact for further information: - Kurt Zeilenga - - -6. Acknowledgment - - This document is a revision of RFC 2245 by Chris Newman. Portions of - the grammar defined in Section 1 were borrowed from [UTF-8] by - Francois Yergeau. - - This document is a product of the IETF SASL WG. - - -7. Normative References - - [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - - -Zeilenga Anonymous SASL Mechanism [Page 6] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - [IMAIL] Crocker, D., "Standard for the Format of Arpa Internet - Text Messages", STD 11, RFC 822, August 1982. - - [Keywords] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997 - - [SASL] Myers, J., "Simple Authentication and Security Layer - (SASL)", draft-myers-saslrev-xx.txt, a work in progress. - - [StringPrep] Hoffman P. and M. Blanchet, "Preparation of - Internationalized Strings ('stringprep')", RFC 3454, - December 2002. - - [Unicode] The Unicode Consortium, "The Unicode Standard, Version - 3.2.0" is defined by "The Unicode Standard, Version 3.0" - (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), - as amended by the "Unicode Standard Annex #27: Unicode - 3.1" (http://www.unicode.org/reports/tr27/) and by the - "Unicode Standard Annex #28: Unicode 3.2" - (http://www.unicode.org/reports/tr28/). - - [UTF-8] Yergeau, F., "UTF-8, a transformation - format of ISO 10646", draft-yergeau-rfc2279bis, a work - in progress. - - -8. Informative References - - [IMAP4] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [IANA-SASL] IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL) - MECHANISMS", http://www.iana.org/assignments/sasl- - mechanisms. - - -9. Editor's Address - - Kurt Zeilenga - OpenLDAP Foundation - - Email: kurt@OpenLDAP.org - - -Appendix A. Changes since RFC 2245 - - This appendix is non-normative. - - - - -Zeilenga Anonymous SASL Mechanism [Page 7] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - RFC 2245 allows the client to send optional trace information in the - form of a human readable string. RFC 2245 restricted this string to - US-ASCII. As the Internet is international, this document uses a - string restricted to UTF-8 encoded Unicode characters. A "stringprep" - profile is defined to precisely define which Unicode characters are - allowed in this string. While the string remains restricted to 255 - characters, the encoded length of each character may now range from 1 - to 4 octets. - - Additionally, a number of editorial changes were made. - - - -Intellectual Property Rights - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to pertain - to the implementation or use of the technology described in this - document or the extent to which any license under such rights might or - might not be available; neither does it represent that it has made any - effort to identify any such rights. Information on the IETF's - procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such proprietary - rights by implementors or users of this specification can be obtained - from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - - -Full Copyright - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - - - -Zeilenga Anonymous SASL Mechanism [Page 8] - -INTERNET-DRAFT draft-ietf-sasl-anon-02.txt 30 June 2003 - - - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be followed, - or as required to translate it into languages other than English. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Zeilenga Anonymous SASL Mechanism [Page 9] - diff --git a/doc/draft-ietf-sasl-crammd5-xx.txt b/doc/draft-ietf-sasl-crammd5-xx.txt deleted file mode 100644 index 85bda721..00000000 --- a/doc/draft-ietf-sasl-crammd5-xx.txt +++ /dev/null @@ -1,434 +0,0 @@ - - -Network Working Group L. Nerenberg, Editor -Internet Draft: The CRAM-MD5 SASL Mechanism Orthanc Systems -Document: draft-ietf-sasl-crammd5-01.txt November 2003 - - - - The CRAM-MD5 SASL Mechanism - - -Status of this Memo - - This document is an Internet Draft and is in full conformance with - all provisions of Section 10 of RFC 2026. - - Internet Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet - Drafts. - - Internet Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other docu- - ments at any time. It is inappropriate to use Internet Drafts as - reference material or to cite them other than as "work in - progress." - - The list of current Internet Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet - Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - Copyright 2003, The Internet Society. All Rights Reserved. - - Please see the Copyright section near the end of this document for - more information. - -Abstract - - This document defines a simple challenge-response authentication - mechanism, using a keyed-hash digest, for use with the Simple - Authentication and Security Layer (SASL). - -1. Conventions Used in this Document - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in [KEYWORD]. - - -2. CRAM-MD5 Authentication Mechanism - - This document defines a simple challenge-response [SASL] authenti- - cation mechanism, using a [KEYED-MD5] digest, for use with [SASL]. - The mechanism name associated with CRAM-MD5 is 'CRAM-MD5'. - - This mechanism does not provide a security layer. - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 1] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - - The data encoded in the challenge contains a presumptively arbi- - trary string of random digits, a time-stamp, and the fully-quali- - fied primary host name of the server. - - The client makes note of the data and then responds with a string - consisting of the user name, a space, and a "digest." The latter - is computed by applying the keyed MD5 algorithm from [KEYED-MD5] - where the key is a shared secret and the digested text is the chal- - lenge (including angle-brackets). The client MUST NOT interpret or - attempt to validate the contents of the challenge in any way. - - This shared secret is a string known only to the client and server. - The "digest" parameter itself is a 16-octet value which is sent in - hexadecimal format, using lower-case US-ASCII characters. - - When the server receives this client response, it verifies the - digest provided. Since the user name may contain the space charac- - ter, the server MUST scan the client response from right to left; - the first space character encountered separates the digest from the - user name. If the digest is correct, the server should consider - the client authenticated and respond appropriately. - - The client MUST prepare the user name and shared secret strings - using the [SASLPrep] profile of the [StringPrep] algorithm. The - resulting values MUST be encoded as UTF-8 [UTF8]. - - -2.1. Formal Syntax - - The following syntax specification uses the augmented Backus-Naur - Form (ABNF) as specified in [ABNF], and incorporates by reference - the Core Rules defined in that document. - - challenge = "<" 1*DIGIT "." 1*DIGIT "@" hostname ">" - - digest = 32(DIGIT / %x61-66) - ; A hexadecimal string using only lower-case - ; letters - - hostname = 1*(ALPHA / DIGIT) *("." / "-" / ALPHA / DIGIT) - - response = user SP digest - - user = 1*OCTET - - -2.2. Examples - - The examples in this section do NOT form part of the specification. - Where conflicts exist between the examples and the formal grammar - or specification text, the latter are authoritative. - - These examples show the use of the CRAM-MD5 mechanism with the - IMAP4 AUTHENTICATE command [IMAP4]. The base64 encoding of the - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 2] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - - challenges and responses is part of the IMAP4 AUTHENTICATE command, - not part of the CRAM-MD5 specification itself. - - S: * OK [CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED AUTH=CRAM-MD5] - C: A0001 AUTHENTICATE CRAM-MD5 - S: + PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+ - C: dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw - S: A0001 OK CRAM-MD5 authentication successful - - In this example, the shared secret is the string - - tanstaaftanstaaf - - Hence, the Keyed MD5 digest is produced by calculating - - MD5((tanstaaftanstaaf XOR opad), - MD5((tanstaaftanstaaf XOR ipad), - <1896.697170952@postoffice.example.net>)) - - where ipad and opad are as defined in [KEYED-MD5] and the string - shown in the challenge is the base64 encoding of - <1896.697170952@postoffice.reston.mci.net>. The shared secret is - null-padded to a length of 64 bytes. If the shared secret is longer - than 64 bytes, the MD5 digest of the shared secret is used as a 16 - byte input to the keyed MD5 calculation. - - This produces a digest value (in hexadecimal) of - - b913a602c7eda7a495b4e6e7334d3890 - - The user name is then prepended to it, forming - - tim b913a602c7eda7a495b4e6e7334d3890 - - Which is then base64 encoded to meet the requirements of the IMAP4 - AUTHENTICATE command (or the similar POP3 AUTH command), yielding - - dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw - - - -3. References - -3.1. Normative References - -[ABNF] - Crocker, D., P. Overell, "Augmented BNF for Syntax Specifications: - ABNF", RFC2234, Internet Mail Consortium and Demon Internet Ltd., - November 1997. - -[KEYED-MD5] - Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for Message - Authentication", RFC 2104, IBM and UCSD, February 1997. - - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 3] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - -[KEYWORD] - Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC2119, Harvard University, March 1997. - -[MD5] - Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321, MIT Labo- - ratory for Computer Science and RSA Data Security, Inc., April - 1992. - -[SASL] - Myers, J., "Simple Authentication and Security Layer (SASL)," RFC - 2222, Netscape Communications, October 1997. - -[SASLPrep] - Zeilenga, K., "SASL String Preparation Profiles", draft-ietf-sasl- - saslprep (work in progress) - -[StringPrep] - Hoffman, P., M. Blanchet, "Preparation of Internationalized Strings - (stringprep)", RFC 3454, IMC and Viagenie, December 2002. - -[UTF8] - Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC - 2279, Alis Technologies, January 1998. - -3.2. Informative References - -[IMAP4] - Crispin, M., "Internet Message Access Protocol - Version 4rev1," - RFC 3501, University of Washington, March 2003. - - -4. Security Considerations - - It is conjectured that use of the CRAM-MD5 authentication mechanism - provides replay protection for a session. - - This mechanism does not obscure the user name in any way. Accord- - ingly, a server that implements both a clear-text password command - and this authentication type should not allow both methods of - access for a given user name. - - Keyed MD5 is chosen for this application because of the greater - security imparted to authentication of short messages. In addition, - the use of the techniques described in [KEYED-MD5] for pre-computa- - tion of intermediate results make it possible to avoid explicit - clear-text storage of the shared secret on the server system by - instead storing the intermediate results which are known as "con- - texts." While the saving, on the server, of the MD5 "context" is - marginally better than saving the shared secrets in clear-text, it - is not sufficient to protect the secrets if the server itself is - compromised. Consequently, servers that store the secrets or con- - texts must both be protected to a level appropriate to the poten- - tial information value in the data and services protected by this - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 4] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - - mechanism. In other words, techniques like this one involve a - trade-off between vulnerability to network sniffing and I/O buffer - snooping and vulnerability of the server host's databases. If one - believes that the host and its databases are subject to compromise, - and the network is not, this technique (and all others like it) is - unattractive. It is perhaps even less attractive than clear-text - passwords, which are typically stored on hosts in one-way hash - form. On the other hand, if the server databases are perceived as - reasonably secure, and one is concerned about client-side or net- - work interception of the passwords (secrets), then this (and simi- - lar) techniques are preferable to clear-text passwords by a wide - margin. - - As the length of the shared secret increases, so does the diffi- - culty of deriving it. - - While there are now suggestions in the literature that the use of - MD5 and keyed MD5 in authentication procedures probably has a lim- - ited effective lifetime, the technique is now widely deployed and - widely understood. It is believed that this general understanding - may assist with the rapid replacement, by CRAM-MD5, of the current - uses of permanent clear-text passwords in many protocols. This - document has been deliberately written to permit easy upgrading to - use SHA (or whatever alternatives emerge) when they are considered - to be widely available and adequately safe. - - Even with the use of CRAM-MD5, users are still vulnerable to active - attacks. An example of an increasingly common active attack is - 'TCP Session Hijacking' as described in CERT Advisory CA-95:01. - - CRAM-MD5 does not authenticate the server and does not include a - client-supplied nonce. As a result, it is possible to construct a - server with a fixed challenge string that has pre-computed the - hashes for all possible passwords up to a certain length (or from a - dictionary). Such a server could then immediately determine the - user's password if it is sufficiently short. - - -5. IANA Considerations - - The SASL Mechanism Registry entry for CRAM-MD5 must be updated to - reference this specification. - - -6. Contributors - - The CRAM-MD5 mechanism was originally specified in RFC 2095, - IMAP/POP AUTHorize Extension for Simple Challenge/Response. The - authors of that document -- John C. Klensin, Paul Krumviede, and - Randy Catoe -- are to be credited with the design and specification - of CRAM-MD5. This memo serves only to re-state CRAM-MD5 within the - formal context of SASL, which specification it preceded by several - months. - - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 5] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - -7. Intellectual Property - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to per- - tain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it - has made any effort to identify any such rights. Information on - the IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances - of licenses to be made available, or the result of an attempt made - to obtain a general license or permission for the use of such pro- - prietary rights by implementers or users of this specification can - be obtained from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Execu- - tive Director. - - -8. Editors' Address - - Lyndon Nerenberg - Orthanc Systems - 1606 - 10770 Winterburn Road - Edmonton, Alberta - Canada T5S 1T6 - Email: lyndon+rfc-crammd5@orthanc.ca - - - - - - - - - - - - - - - - - - - - - - - - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 6] - -Internet Draft CRAM-MD5 SASL Mechanism November 2003 - - -9. Full Copyright Statement - - Copyright 2003, The Internet Society. All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain - it or assist in its implementation may be prepared, copied, pub- - lished and distributed, in whole or in part, without restriction of - any kind, provided that the above copyright notice and this para- - graph are included on all such copies and derivative works. How- - ever, this document itself may not be modified in any way, such as - by removing the copyright notice or references to the Internet - Society or other Internet organizations, except as needed for the - purpose of developing Internet standards in which case the proce- - dures for copyrights defined in the Internet Standards process must - be followed, or as required to translate it into languages other - than English. The limited permissions granted above are perpetual - and will not be revoked by the Internet Society or its successors - or assigns. - - This document and the information contained herein is provided on - an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGI- - NEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WAR- - RANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Nerenberg draft-ietf-sasl-crammd5-01.txt [Page 7] - - diff --git a/doc/draft-ietf-sasl-gssapi-xx.txt b/doc/draft-ietf-sasl-gssapi-xx.txt deleted file mode 100644 index bc37a498..00000000 --- a/doc/draft-ietf-sasl-gssapi-xx.txt +++ /dev/null @@ -1,841 +0,0 @@ - - -SASL Working Group A. Melnikov -Internet-Draft Isode -Expires: May 22, 2004 November 22, 2003 - - - SASL GSSAPI mechanisms - draft-ietf-sasl-gssapi-00 - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on May 22, 2004. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - The Simple Authentication and Security Layer [SASL] is a method for - adding authentication support to connection-based protocols. This - document describes the method for using the Generic Security Service - Application Program Interface [GSSAPI] in the Simple Authentication - and Security Layer [SASL]. - - This document replaces section 7.2 of RFC 2222 [SASL], the definition - of the "GSSAPI" SASL mechanism. - - - - - - - -Melnikov Expires May 22, 2004 [Page 1] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -Table of Contents - - 1. Conventions Used in this Document . . . . . . . . . . . . . . 3 - 2. Introduction and Overview . . . . . . . . . . . . . . . . . . 4 - 2.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 3. SPNEGO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 - 4. Specification common to all GSSAPI mechanisms . . . . . . . . 6 - 4.1 Client side of authentication protocol exchange . . . . . . . 6 - 4.2 Server side of authentication protocol exchange . . . . . . . 7 - 4.3 Security layer . . . . . . . . . . . . . . . . . . . . . . . . 8 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 11 - 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 12 - Normative References . . . . . . . . . . . . . . . . . . . . . 13 - Informative References . . . . . . . . . . . . . . . . . . . . 14 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . 14 - Full Copyright Statement . . . . . . . . . . . . . . . . . . . 15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 2] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -1. Conventions Used in this Document - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [KEYWORDS]. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 3] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -2. Introduction and Overview - - Each and every GSSAPI mechanism used within SASL is implicitly - registered by this specification. - - For backwards compatibility with existing implementations of Kerberos - V5 and SPNEGO under SASL, the SASL mechanism name for the Kerberos V5 - GSSAPI mechanism [KRB5GSS] is "GSSAPI" and the SASL mechanism for the - SPNEGO GSSAPI mechanism [SPNEGO] is "GSS-SPNEGO". The SASL mechanism - name for any other GSSAPI mechanism is the concatenation of "GSS-" - and the Base32 [BASE-ENCODING] encoding of the first ten bytes of the - MD5 hash [MD5] of the ASN.1 DER encoding [ASN1] of the GSSAPI - mechanism's OID. The Base32 rules on padding characters and - characters outside of the base32 alphabet are not relevant to this - use of Base32. - - SASL mechanism names starting with "GSS-" are reserved for SASL - mechanisms which conform to this document. - - The specification of all SASL mechanisms conforming to this document - is in the "Specification common to all GSSAPI mechanisms" section of - this document. - - The IESG is considered to be the owner of all SASL mechanisms which - conform to this document. This does NOT necessarily imply that the - IESG is considered to be the owner of the underlying GSSAPI - mechanism. - -2.1 Example - - The OID for the SPKM-1 mechanism [SPKM1] is 1.3.6.1.5.5.1. The ASN.1 - DER encoding of this OID is 06 06 2b 06 01 05 05 01. The MD5 hash of - the ASN.1 DER encoding is 57 ee 81 82 4e ac 4d b0 e6 50 9f 60 1f 46 - 8a 30. The Base32 encoding of the first ten bytes of this is - "K7XIDASOVRG3BZSQ". Thus the SASL mechanism name for the SPKM-1 - GSSAPI mechanism is "GSS-K7XIDASOVRG3BZSQ". - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 4] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -3. SPNEGO - - Use of the Simple and Protected GSS-API Negotiation Mechanism - [SPNEGO] underneath SASL introduces subtle interoperability problems - and security considerations. To address these, this section places - additional requirements on implementations which support SPNEGO - underneath SASL. - - A client which supports, for example, the Kerberos V5 GSSAPI - mechanism only underneath SPNEGO underneath the "GSS-SPNEGO" SASL - mechanism will not interoperate with a server which supports the - Kerberos V5 GSSAPI mechanism only underneath the "GSSAPI" SASL - mechanism. - - Since SASL is capable of negotiating amongst GSSAPI mechanisms, the - only reason for a server or client to support the "GSS-SPNEGO" - mechanism is to allow a policy of only using mechanisms below a - certain strength if those mechanism's negotiation is protected. In - such a case, a client or server would only want to negotiate those - weaker mechanisms through SPNEGO. In any case, there is no down- - negotiation security consideration with using the strongest mechanism - and set of options the implementation supports, so for - interoperability that mechanism and set of options MUST be negotiable - without using the "GSS-SPNEGO" mechanism. - - If a client's policy is to first prefer GSSAPI mechanism X, then non- - GSSAPI mechanism Y, then GSSAPI mechanism Z, and if a server supports - mechanisms Y and Z but not X, then if the client attempts to - negotiate mechanism X by using the "GSS-SPNEGO" SASL mechanism, it - may end up using mechanism Z when it should have used mechanism Y. - For this reason, implementations MUST exclude from SPNEGO those - GSSAPI mechanisms which are weaker than the strongest non-GSSAPI SASL - mechanism advertised by the server. - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 5] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -4. Specification common to all GSSAPI mechanisms - - Each SASL mechanism which uses a GSSAPI mechanism uses the following - specification. - - The implementation MAY set any GSSAPI flags or arguments not - mentioned in this specification as is necessary for the - implementation to enforce its security policy. - -4.1 Client side of authentication protocol exchange - - The client calls GSS_Init_sec_context, passing in - input_context_handle of 0 (initially), mech_type of the GSSAPI - mechanism for which this SASL mechanism is registered, chan_binding - of NULL, and targ_name equal to output_name from GSS_Import_Name - called with input_name_type of GSS_C_NT_HOSTBASED_SERVICE and - input_name_string of "service@hostname" where "service" is the - service name specified in the protocol's profile, and "hostname" is - the fully qualified host name of the server. If the client will be - requesting a security layer, it MUST also supply to the - GSS_Init_sec_context a mutual_req_flag of TRUE, a sequence_req_flag - of TRUE, and an integ_req_flag of TRUE. If the client will be - requesting a security layer providing confidentiality protection, it - MUST also supply to the GSS_Init_sec_context a conf_req_flag of TRUE. - The client then responds with the resulting output_token. If - GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED, then the client - should expect the server to issue a token in a subsequent challenge. - The client must pass the token to another call to - GSS_Init_sec_context, repeating the actions in this paragraph. - - When GSS_Init_sec_context returns GSS_S_COMPLETE, the client examines - the context to ensure that it provides a level of protection - permitted by the client's security policy. If the context is - acceptable, the client takes the following actions: If the last call - to GSS_Init_sec_context returned an output_token, then the client - responds with the output_token, otherwise the client responds with no - data. The client should then expect the server to issue a token in a - subsequent challenge. The client passes this token to GSS_Unwrap and - interprets the first octet of resulting cleartext as a bit-mask - specifying the security layers supported by the server and the second - through fourth octets as the network byte order maximum size - output_message to send to the server (if the resulting cleartext is - not 4 octets long, the client fails the negotiation). The client - then constructs data, with the first octet containing the bit-mask - specifying the selected security layer, the second through fourth - octets containing in network byte order the maximum size - output_message the client is able to receive, and the remaining - octets containing the authorization identity, encoded according to - - - -Melnikov Expires May 22, 2004 [Page 6] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - - the application profile specification. The authorization identity is - not NUL-terminated. The client passes the data to GSS_Wrap with - conf_flag set to FALSE, and responds with the generated - output_message. The client can then consider the server - authenticated. - -4.2 Server side of authentication protocol exchange - - The server passes the initial client response to - GSS_Accept_sec_context as input_token, setting input_context_handle - to 0 (initially), mech_type of the GSSAPI mechanism for which this - SASL mechanism is registered, chan_binding of NULL, and - acceptor_cred_handle equal to output_cred_handle from - GSS_Acquire_cred called with desired_name equal to output_name from - GSS_Import_name with input_name_type of GSS_C_NT_HOSTBASED_SERVICE - and input_name_string of "service@hostname" where "service" is the - service name specified in the protocol's profile, and "hostname" is - the fully qualified host name of the server. If - GSS_Accept_sec_context returns GSS_S_CONTINUE_NEEDED, the server - returns the generated output_token to the client in challenge and - passes the resulting response to another call to - GSS_Accept_sec_context, repeating the actions in this paragraph. - - When GSS_Accept_sec_context returns GSS_S_COMPLETE, the server - examines the context to ensure that it provides a level of protection - permitted by the server's security policy. If the context is - acceptable, the server takes the following actions: If the last call - to GSS_Accept_sec_context returned an output_token, the server - returns it to the client in a challenge and expects a reply from the - client with no data. Whether or not an output_token was returned - (and after receipt of any response from the client to such an - output_token), the server then constructs 4 octets of data, with the - first octet containing a bit-mask specifying the security layers - supported by the server and the second through fourth octets - containing in network byte order the maximum size output_token the - server is able to receive. The server must then pass the plaintext - to GSS_Wrap with conf_flag set to FALSE and issue the generated - output_message to the client in a challenge. The server must then - pass the resulting response to GSS_Unwrap and interpret the first - octet of resulting cleartext as the bit-mask for the selected - security layer, the second through fourth octets as the network byte - order maximum size output_message to send to the client, and the - remaining octets as the authorization identity. The server must - verify that the src_name is authorized to authenticate as the - authorization identity. After these verifications, the - authentication process is complete. - - - - - -Melnikov Expires May 22, 2004 [Page 7] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -4.3 Security layer - - The security layers and their corresponding bit-masks are as follows: - - 1 No security layer - 2 Integrity protection. - Sender calls GSS_Wrap with conf_flag set to FALSE - 4 Confidentiality protection. - Sender calls GSS_Wrap with conf_flag set to TRUE - - Other bit-masks may be defined in the future; bits which are not - understood must be negotiated off. - - Note that SASL negotiates the maximum size of the output_message to - send. Implementations can use the GSS_Wrap_size_limit call to - determine the corresponding maximum size input_message. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 8] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -5. IANA Considerations - - The IANA is advised that SASL mechanism names starting with "GSS-" - are reserved for SASL mechanisms which conform to this document. The - IANA is directed to place a statement to that effect in the sasl- - mechanisms registry. - - Family of SASL mechanisms: YES - - Prefix: GSS- - - Security considerations: RFC [THIS-DOC] - - Published Specification: RFC [THIS-DOC] - - Person & email address to contact for further information: Alexey - Melnikov - - Intended usage: COMMON - - Author/Change controller: iesg@ietf.org - - The IANA is directed to modify the existing registration for "GSSAPI" - as follows. - - Family of SASL mechanisms: NO - - SASL mechanism name: GSSAPI - - Security considerations: ? - - Published Specification: RFC [THIS-DOC] - - Person & email address to contact for further information: Alexey - Melnikov - - Intended usage: COMMON - - Author/Change controller: iesg@ietf.org - - Additional Information: This mechanism is for the Kerberos V5 - mechanism of GSSAPI. Other GSSAPI mechanisms use other SASL - mechanism names, as described in this mechanism's published - specification. - - The IANA is directed to modify the existing registration for "GSS- - SPNEGO" as follows. - - - - -Melnikov Expires May 22, 2004 [Page 9] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - - Family of SASL mechanisms: NO - - SASL mechanism name: GSS-SPNEGO - - Security considerations: See the "SPNEGO" section of RFC [THIS-DOC]. - - Published Specification: RFC [THIS-DOC] - - Person & email address to contact for further information: Alexey - Melnikov - - Intended usage: LIMITED USE - - Author/Change controller: iesg@ietf.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 10] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -6. Security Considerations - - Security issues are discussed throughout this memo. - - When a server or client supports multiple authentication mechanisms, - each of which has a different security strength, it is possible for - an active attacker to cause a party to use the least secure mechanism - supported. To protect against this sort of attack, a client or - server which supports mechanisms of different strengths should have a - configurable minimum strength that it will use. It is not sufficient - for this minimum strength check to only be on the server, since an - active attacker can change which mechanisms the client sees as being - supported, causing the client to send authentication credentials for - its weakest supported mechanism. - - The client's selection of a SASL mechanism is done in the clear and - may be modified by an active attacker. It is important for any new - SASL mechanisms to be designed such that an active attacker cannot - obtain an authentication with weaker security properties by modifying - the SASL mechanism name and/or the challenges and responses. - - [SPNEGO] has protection against many of these down-negotiation - attacks, SASL does not itself have such protection. The section - titled "SPNEGO" mentions considerations of choosing negotiation - through SASL versus SPNEGO. - - The integrity protection provided by the security layer is useless to - the client unless the client also requests mutual authentication. - Therefore, a client wishing to benefit from the integrity protection - of a security layer MUST pass to the GSS_Init_sec_context call a - mutual_req_flag of TRUE. - - When constructing the input_name_string, the client should not - canonicalize the server's fully qualified domain name using an - insecure or untrusted directory service. - - Additional security considerations are in the [SASL] and [GSSAPI] - specifications. - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 11] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -7. Acknowledgements - - This document is a revision of RFC 2222 written by John G. Myers. - He also contributed significantly to this revision. - - Thank you to Lawrence Greenfield for converting text of this draft to - XML format. - - Contributions of many members of the SASL mailing list are gratefully - acknowledged. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 12] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -Normative References - - [ASN1] International Organization for Standardization, - "Information Processing Systems - Open Systems - Interconnection - Specification of Abstract Syntax - Notation One (ASN.1)", ISO Standard 8824, December - 1990. - - [BASE-ENCODING] Josefsson, S., "The Base16, Base32, and Base64 Data - Encodings", RFC 3548, July 2003. - - [GSSAPI] Linn, J., "Generic Security Service Application - Program Interface Version 2, Update 1", RFC 2743, - January 2000. - - [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [KRB5GSS] Linn, J., "The Kerberos Version 5 GSS-API - Mechanism", RFC 1964, June 1996. - - [MD5] Rivest, R., "The MD5 Message-Digest Algorithm", RFC - 1321, April 1992. - - [SASL] Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997. - - [SASL(rev)] Melnikov, A., "Simple Authentication and Security - Layer (SASL)", draft-ietf-sasl-rfc2222bis (work in - progress), October 2003. - - [SPNEGO] Baize, E. and D. Pinkas, "The Simple and Protected - GSS-API Negotiation Mechanism", RFC 2478, December - 1998. - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 13] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -Informative References - - [SPKM1] Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", - RFC 2025, October 1996. - - [UTF8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", - RFC 2279, January 1998. - - -Author's Address - - Alexey Melnikov (Ed.) - Isode Limited - 5 Castle Business Village - 36 Station Road - Hampton, Middlesex TW12 2BX - UK - - EMail: Alexey.Melnikov@isode.com - URI: http://www.melnikov.ca/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 14] - -Internet-Draft SASL GSSAPI mechanisms November 2003 - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Melnikov Expires May 22, 2004 [Page 15] - - diff --git a/doc/draft-ietf-sasl-plain-xx.txt b/doc/draft-ietf-sasl-plain-xx.txt deleted file mode 100644 index fa1fbce7..00000000 --- a/doc/draft-ietf-sasl-plain-xx.txt +++ /dev/null @@ -1,507 +0,0 @@ - - - - - - -INTERNET-DRAFT Editor: Kurt D. Zeilenga -Intended Category: Standards Track OpenLDAP Foundation -Expires in six months 27 October 2003 -Updates: RFC 2595 - - - The Plain SASL Mechanism - - - -Status of Memo - - This document is an Internet-Draft and is in full conformance with all - provisions of Section 10 of RFC2026. - - This document is intended to be, after appropriate review and - revision, submitted to the RFC Editor as a Standards Track document. - Distribution of this memo is unlimited. Technical discussion of this - document will take place on the IETF SASL mailing list - . Please send editorial comments directly to the - document editor . - - Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as ``work in progress.'' - - The list of current Internet-Drafts can be accessed at - . The list of - Internet-Draft Shadow Directories can be accessed at - . - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - Please see the Full Copyright section near the end of this document - for more information. - - -Abstract - - This document defines a simple clear-text user/password Simple - Authentication and Security Layer (SASL) mechanism called the PLAIN - mechanism. The PLAIN mechanism is intended to be used, in combination - with data confidentiality services provided by a lower layer, in - protocols which lack a simple password authentication command. - - - -Zeilenga Plain SASL Mechanism [Page 1] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - -Conventions - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [Keywords]. - - -1. Background and Intended Usage - - Clear-text passwords are simple, interoperate with almost all existing - operating system authentication databases, and are useful for a smooth - transition to a more secure password-based authentication mechanism. - The drawback is that they are unacceptable for use over an unencrypted - network connection. - - This document defines the PLAIN Simple Authentication and Security - Layer ([SASL]) mechanism for use in protocols with no clear-text login - command (e.g., [ACAP] or [SMTP-AUTH]). - - The name associated with this mechanism is "PLAIN". - - The PLAIN SASL mechanism does not provide a security layer. This - mechanism MUST NOT be used without adequate security protection as the - mechanism affords no integrity nor confidentiality protection itself. - The PLAIN SASL mechanism MUST NOT be advertised unless a strong - encryption layer, such as provided by Transport Layer Security - ([TLS]), is active or backwards compatibility dictates otherwise. - - This document updates RFC 2595, replacing Section 6. Changes since - RFC 2595 are detailed in Appendix A. - - -2. PLAIN SASL mechanism - - The mechanism consists of a single message from the client to the - server. The client sends the authorization identity (identity to - login as), followed by a NUL (U+0000) character, followed by the - authentication identity (identity whose password will be used), - followed by a NUL (U+0000) character, followed by the clear-text - password. The client leaves the authorization identity empty if it - wishes the server to derive the authorization identity from the - authentication identity. - - The formal grammar for the client message using Augmented BNF [ABNF] - follows. - - message = [authzid] NUL authcid NUL passwd - authcid = 1*SAFE ; MUST accept up to 255 octets - - - -Zeilenga Plain SASL Mechanism [Page 2] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - authzid = 1*SAFE ; MUST accept up to 255 octets - passwd = 1*SAFE ; MUST accept up to 255 octets - NUL = %x00 - - SAFE = UTF1 / UTF2 / UTF3 / UTF4 - ;; any UTF-8 encoded Unicode character except NUL - - UTF1 = %x01-7F ;; except NULL - UTF2 = %xC2-DF UTF0 - UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) / - %xED %x80-9F UTF0 / %xEE-EF 2(UTF0) - UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) / - %xF4 %x80-8F 2(UTF0) - UTF0 = %x80-BF - - The authorization identity (authzid), authentication identity - (authcid) and password (passwd) SHALL be transferred as [UTF-8] - encoded strings of [Unicode] characters. As NUL (U+0000) is used as a - deliminator, the NUL (U+0000) MUST NOT appear in authzid, authcid, or - passwd productions. - - The form of the authzid production is specific to the - application-level protocol's SASL profile [SASL]. The authcid and - passwd productions are form-free. Use of non-visible characters or - characters which a user may be unable to enter on some keyboards is - discouraged. - - Servers MUST be capable of accepting authzid, authcid, and passwd - productions up to and including 255 octets. It is noted that the - UTF-8 encoding of a Unicode character may be as long as 4 octets. - - Upon receipt of the message, the server will verify the presented - authentication identity (authcid) and password (passwd) with the - system authentication database and verify the authentication - credentials permit the client to login as the (presented or derived) - authorization identity. If both steps succeed, the user is - authenticated. - - The presented authentication identity and password strings are not to - be compared directly with stored strings. The server SHALL first - prepare authentication identity and password strings using the - [SASLPrep] profile of the [StringPrep] algorithm. If preparation - fails or results in an empty string, verification SHALL fail. If the - server stores only the hash of expected string, that string MUST be - prepared before generation of the hash. - - When the no authorization identity is provided, the server SHALL - derive the authorization identity from the prepared representation of - - - -Zeilenga Plain SASL Mechanism [Page 3] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - the provided authentication identity string. This ensures that the - derivation of different representations of the authentication identity - produce the same authorization identity. - - The verification function (using hashed password) can be written (in - pseudo-code): - - boolean Verify(string authzid, string authcid, string passwd) { - string pAuthcid = SASLprep(authcid); # prepare authcid - string pPasswd = SASLprep(passwd); # prepare passwd - if (pAuthcid == NULL || pPasswd == NULL) { - return false; # preparation failed - } - if (pAuthcid == "" || pPasswd == "") { - return false; # empty prepared string - } - - storedHash = FetchPasswordHash(pAuthcid); - if (storedHash == NULL || storedHash == "") { - return false; # error or unknown authcid - } - - if (!Compare(storedHash, Hash(pPassword))) { - return false; # incorrect password - } - - if (authzid == NULL) { - authzid = DeriveAuthzid(pAuthcid); - if (authzid == NULL || authzid == "") { - return false; # could not derive authzid - } - } - - if (!Authorize(pAuthcid, authzid)) { - return false; # not authorized - } - - return true; - } - - Also note that the second parameter provided to the Authorize function - is not prepared by this code. The application-level SASL profile - should be consulted to determine what, if any, preparation is - necessary. - - The server MAY also use the credentials to initialize any new - authentication database, such as one suitable for [CRAM-MD5] or - [DIGEST-MD5]. - - - -Zeilenga Plain SASL Mechanism [Page 4] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - -4. Example - - Here is an example of how this might be used to initialize a CRAM-MD5 - authentication database using the Application Configuration Access - Protocol ([ACAP]). "C:" and "S:" indicate lines sent by the client - and server respectively and represents a single NUL (U+0000) - character. - - S: * ACAP (SASL "CRAM-MD5") (STARTTLS) - C: a001 AUTHENTICATE "CRAM-MD5" - S: + "<1896.697170952@postoffice.reston.mci.net>" - C: "tim b913a602c7eda7a495b4e6e7334d3890" - S: a001 NO (TRANSITION-NEEDED) - "Please change your password, or use TLS to login" - C: a002 STARTTLS - S: a002 OK "Begin TLS negotiation now" - - S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL") - C: a003 AUTHENTICATE "PLAIN" {21+} - C: timtanstaaftanstaaf - S: a003 OK CRAM-MD5 password initialized - - - -5. Security Considerations - - The PLAIN mechanism relies on the TLS encryption layer for security. - When used without TLS, it is vulnerable to a common network - eavesdropping attack. Therefore PLAIN MUST NOT be advertised or used - unless a suitable TLS encryption layer is active or backwards - compatibility dictates otherwise. - - When the PLAIN mechanism is used, the server gains the ability to - impersonate the user to all services with the same password regardless - of any encryption provided by TLS or other network privacy mechanisms. - While many other authentication mechanisms have similar weaknesses, - stronger SASL mechanisms address this issue. Clients are encouraged - to have an operational mode where all mechanisms which are likely to - reveal the user's password to the server are disabled. - - General SASL security considerations apply to this mechanism. - "stringprep" and Unicode [StringPrep] security considerations also - apply, as do [UTF-8] security considerations. - - -6. IANA Considerations - - It is requested that the SASL Mechanism registry [IANA-SASL] entry for - - - -Zeilenga Plain SASL Mechanism [Page 5] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - the PLAIN mechanism be updated to reflect that this document now - provides its technical specification. - - To: iana@iana.org - Subject: Updated Registration of SASL mechanism PLAIN - - SASL mechanism name: PLAIN - Security considerations: See RFC XXXX. - Published specification (optional, recommended): RFC XXXX - Person & email address to contact for further information: - Kurt Zeilenga - IETF SASL WG - Intended usage: COMMON - Author/Change controller: IESG - Note: Updates existing entry for PLAIN - - -7. Acknowledgment - - This document is a revision of RFC 2595 by Chris Newman. Portions of - the grammar defined in Section 2 were borrowed from [UTF-8] by - Francois Yergeau. - - This document is a product of the IETF SASL WG. - - -8. Normative References - - [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [Keywords] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997 - - [SASL] Melnikov, A. (Editor), "Simple Authentication and - Security Layer (SASL)", - draft-ietf-sasl-rfc2222bis-xx.txt, a work in progress. - - [StringPrep] Hoffman P. and M. Blanchet, "Preparation of - Internationalized Strings ('stringprep')", - draft-hoffman-rfc3454bis-xx.txt, a work in progress. - - [Unicode] The Unicode Consortium, "The Unicode Standard, Version - 3.2.0" is defined by "The Unicode Standard, Version 3.0" - (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), - as amended by the "Unicode Standard Annex #27: Unicode - 3.1" (http://www.unicode.org/reports/tr27/) and by the - "Unicode Standard Annex #28: Unicode 3.2" - - - -Zeilenga Plain SASL Mechanism [Page 6] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - (http://www.unicode.org/reports/tr28/). - - [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", draft-yergeau-rfc2279bis-xx.txt, a work in - progress. - - [TLS] Dierks, T. and, E. Rescorla, "The TLS Protocol Version - 1.1", draft-ietf-tls-rfc2246-bis-xx.txt, a work in - progress. - - -9. Informative References - - [ACAP] Newman, C. and J. Myers, "ACAP -- Application - Configuration Access Protocol", RFC 2244, November 1997. - [CRAM-MD5] Nerenberg, L., "The CRAM-MD5 SASL Mechanism", - draft-ietf-sasl-crammd5-xx.txt, a work in progress. - - [DIGEST-MD5] Leach, P., C. Newman, and A. Melnikov, "Using Digest - Authentication as a SASL Mechanism", - draft-ietf-sasl-rfc2831bis-xx.txt, a work in progress. - - [IANA-SASL] IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL) - MECHANISMS", http://www.iana.org/assignments/sasl- - mechanisms. - - [SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication", - RFC 2554, March 1999. - - - -10. Editor's Address - - Kurt Zeilenga - OpenLDAP Foundation - - Email: kurt@OpenLDAP.org - - -Appendix A. Changes since RFC 2595 - - This appendix is non-normative. - - This document replaces Section 6 of RFC 2595. - - The specification details how the server is to compare client-provided - character strings with stored character strings. - - - - -Zeilenga Plain SASL Mechanism [Page 7] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - The ABNF grammar was updated. In particular, the grammar now allows - LINE FEED (U+000A) and CARRIAGE RETURN (U+000D) characters in the - authzid, authcid, passwd productions. However, whether these control - characters may be used depends on the string preparation rules - applicable to the production. For passwd and authcid productions, - control characters are prohibited. For authzid, one must consult the - application-level SASL profile. - - - -Intellectual Property Rights - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to pertain - to the implementation or use of the technology described in this - document or the extent to which any license under such rights might or - might not be available; neither does it represent that it has made any - effort to identify any such rights. Information on the IETF's - procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such proprietary - rights by implementors or users of this specification can be obtained - from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - - -Full Copyright - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - - - -Zeilenga Plain SASL Mechanism [Page 8] - -INTERNET-DRAFT draft-ietf-sasl-plain-03.txt 27 October 2003 - - - copyrights defined in the Internet Standards process must be followed, - or as required to translate it into languages other than English. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Zeilenga Plain SASL Mechanism [Page 9] - diff --git a/doc/draft-ietf-sasl-rfc2222bis-xx.txt b/doc/draft-ietf-sasl-rfc2222bis-xx.txt deleted file mode 100644 index ecadd4bf..00000000 --- a/doc/draft-ietf-sasl-rfc2222bis-xx.txt +++ /dev/null @@ -1,1320 +0,0 @@ - - - - - - -Network Working Group A. Melnikov -Internet Draft Editor -Document: draft-ietf-sasl-rfc2222bis-03.txt October 2003 - Expires in six months - - - Simple Authentication and Security Layer (SASL) - -Status of this Memo - - This document is an Internet Draft and is in full conformance with - all provisions of Section 10 of RFC 2026. - - Internet Drafts are working documents of the Internet Engineering - Task Force (IETF), its Areas, and its Working Groups. Note that - other groups may also distribute working documents as Internet - Drafts. Internet Drafts are draft documents valid for a maximum of - six months. Internet Drafts may be updated, replaced, or obsoleted - by other documents at any time. It is not appropriate to use - Internet Drafts as reference material or to cite them other than as - ``work in progress''. - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - A revised version of this draft document will be submitted to the RFC - editor as a Draft Standard for the Internet Community. Discussion - and suggestions for improvement are requested. Distribution of this - draft is unlimited. - - When published as an RFC this document will obsolete RFC 2222. - - - - - - - - - - - - - - - - - -A. Melnikov FORMFEED[Page i] - - - - - -Internet DRAFT SASL 18 October 2003 - - -1. Abstract - - The Simple Authentication and Security Layer (SASL) provides a method - for adding authentication support with an optional security layer to - connection-based protocols. It also describes a structure for - authentication mechanisms. The result is an abstraction layer - between protocols and authentication mechanisms such that any SASL- - compatible authentication mechanism can be used with any SASL- - compatible protocol. - - This document describes how a SASL authentication mechanism is - structured, describes how a protocol adds support for SASL, defines - the protocol for carrying a security layer over a connection, and - defines the EXTERNAL SASL authentication mechanism. - -2. Organization of this document - -2.1. How to read this document - - This document is written to serve two different audiences, protocol - designers using this specification to support authentication in their - protocol, and implementors of clients or servers for those protocols - using this specification. - - The sections "Overview", "Authentication Mechanisms", "Protocol - Profile Requirements", "Specific Issues", and "Security - Considerations" cover issues that protocol designers need to - understand and address in profiling this specification for use in a - specific protocol. - - Implementors of a protocol using this specification need the - protocol-specific profiling information in addition to the - information in this document. - -2.2. Conventions used in this document - - In examples, "C:" and "S:" indicate lines sent by the client and - server respectively. - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [KEYWORDS]. - - Character names in this document use the notation for code points and - names from the Unicode Standard [Unicode]. For example, the letter - "a" may be represented as either or . - - - - - -A. Melnikov FORMFEED[Page 2] - - - - - -Internet DRAFT SASL 18 October 2003 - - -3. Overview - - The Simple Authentication and Security Layer (SASL) is a method for - adding authentication support to connection-based protocols. - - The SASL specification has three layers, as indicated in the diagram - below. At the top, a protocol definition using SASL specifies a - profile, including a command for identifying and authenticating a - user to a server and for optionally negotiating a security layer for - subsequent protocol interactions. At the bottom, a SASL mechanism - definition specifies an authentication mechanism. The SASL - framework, specified by this document, constrains the behavior of - protocol profiles and mechanisms, separating protocol from mechanism - and defining how they interact. - - SMTP Protocol LDAP Protocol Etc - Profile Profile . . . - ----- | -----// - | // - SASL framework - / | \ - /----- | -----\ - EXTERNAL DIGEST-MD5 Etc - SASL mechanism SASL mechanism . . . - - This separation between the definition of protocols and the - definition of authentication mechanisms is crucial. It permits an - authentication mechanism to be defined once, making it usable by any - SASL protocol profile. In many implementations, the same SASL - mechanism code is used for multiple protocols. - -4. Authentication mechanisms - - SASL mechanisms are named by strings, from 1 to 20 characters in - length, consisting of upper-case ASCII [ASCII] letters, digits, - hyphens, and/or underscores. SASL mechanism names must be registered - with the Internet Assigned Numbers Authority (IANA). IETF standards - track documents may direct the IANA to reserve a portion of the SASL - mechanism namespace and may specify different registration criteria - for the reserved portion; the GSSAPI mechanism specification [SASL- - GSSAPI] does this. Procedures for registering new SASL mechanisms are - given in the section 8. - - The "sasl-mech" rule below defines the syntax of a SASL mechanism - name. This uses the Augmented Backus-Naur Form (ABNF) notation as - specified in [ABNF] and the ABNF core rules as specified in Appendix - A of the ABNF specification [ABNF]. - - - - -A. Melnikov FORMFEED[Page 3] - - - - - -Internet DRAFT SASL 18 October 2003 - - - sasl-mech = 1*20mech-char - mech-char = %x41-5A / DIGIT / "-" / "_" - ; mech names restricted to uppercase ASCII letters, - ; digits, "-" and "_" - - -4.1. Authentication protocol exchange - - A SASL mechanism is responsible for conducting an authentication - protocol exchange. This consists of a series of server challenges - and client responses, the contents of which are specific to and - defined by the mechanism. To the protocol, the challenges and - responses are opaque binary tokens of arbitrary length. The - protocol's profile then specifies how these binary tokens are then - encoded for transfer over the connection. - - After receiving an authentication command or any client response, a - server mechanism may issue a challenge, indicate failure, or indicate - completion. The server mechanism may return additional data with a - completion indication. The protocol's profile specifies how each of - these is then represented over the connection. - - After receiving a challenge, a client mechanism may issue a response - or abort the exchange. The protocol's profile specifies how each of - these is then represented over the connection. - - During the authentication protocol exchange, the mechanism performs - authentication, transmits an authorization identity (frequently known - as a userid) from the client to server, and negotiates the use of a - mechanism-specific security layer. If the use of a security layer is - agreed upon, then the mechanism must also define or negotiate the - maximum security layer buffer size that each side is able to receive. - -4.2. Authorization identities and proxy authentication - - An authorization identity is a string of zero or more ISO 10646 - [ISO-10646] coded characters. The NUL character is not - permitted in authorization identities. The meaning of an - authorization identity of the empty string (zero length) is defined - below in this section. The authorization identity is used by the - server as the primary identity for making access policy decisions. - - The character encoding scheme used (see [CHARSET-POLICY] for IETF - policy regarding character sets in IETF protocols) for transmitting - an authorization identity over protocol is specified in each - authentication mechanism (with the authentication mechanism's data - being further restricted/encoded by the protocol profile). - Authentication mechanisms SHOULD encode these and other strings in - - - -A. Melnikov FORMFEED[Page 4] - - - - - -Internet DRAFT SASL 18 October 2003 - - - UTF-8 [UTF-8]. While some legacy mechanisms are incapable of - transmitting an authorization identity other than the empty string, - newly defined mechanisms are expected to be capable of carrying the - entire Unicode repertoire (with the exception of the NUL character). - An authorization identity of the empty string and an absent - authorization identity MUST be treated as equivalent. However, - mechanisms SHOULD NOT allow both. That is, a mechanism which provides - an optional field for an authorization identity, SHOULD NOT allow - that field, when present, to be empty. - - The identity derived from the client's authentication credentials is - known as the "authentication identity". With any mechanism, - transmitting an authorization identity of the empty string directs - the server to derive an authorization identity from the client's - authentication identity. - - If the authorization identity transmitted during the authentication - protocol exchange is not the empty string, this is typically referred - to as "proxy authentication". This feature permits agents such as - proxy servers to authenticate using their own credentials, yet - request the access privileges of the identity for which they are - proxying. - - The server makes an implementation defined policy decision as to - whether the authentication identity is permitted to have the access - privileges of the authorization identity and whether the - authorization identity is permitted to receive service. If it is - not, the server indicates failure of the authentication protocol - exchange. - - As a client might not have the same information as the server, - clients SHOULD NOT derive authorization identities from - authentication identities. Instead, clients SHOULD provide no (or - empty) authorization identity when the user has not provided an - authorization identity. - - The server MUST verify that a received authorization identity is in - the correct form. Profiles whose authorization identities are simple - user names (e.g. IMAP [RFC 3501]) SHOULD use "SASLPrep" profile - [SASLPrep] of the "stringprep" algorithm [StringPrep] to prepare - these names for matching. The profiles MAY use a stringprep profile - that is more strict than "SASLPrep". If the preparation of the - authorization identity fails or results in an empty string, the - server MUST fail the authentication exchange. The only exception to - this rule is when the received authorization identity is already the - empty string. - - - - - -A. Melnikov FORMFEED[Page 5] - - - - - -Internet DRAFT SASL 18 October 2003 - - -4.3. Security layers - - If use of a security layer is negotiated by the authentication - protocol exchange, the security layer is applied to all subsequent - data sent over the connection (until another security layer or no - security layer is negotiated; see also section 6.3). The security - layer takes effect immediately following the last response of the - authentication exchange for data sent by the client and the - completion indication for data sent by the server. - - Once the security layer is in effect, the protocol stream is - processed by the security layer into buffers of security encoded - data. Each buffer of security encoded data is transferred over the - connection as a stream of octets prepended with a four octet field in - network byte order that represents the length of the following - buffer. The length of the security encoded data buffer MUST be no - larger than the maximum size that was either defined in the mechanism - specification or negotiated by the other side during the - authentication protocol exchange. Upon the receipt of a data buffer - which is larger than the defined/negotiated maximal buffer size, the - receiver SHOULD close the connection. This might be a sign of an - attack or a buggy implementation. - -4.4. Character string issues - - Authentication mechanisms SHOULD encode character strings in UTF-8 - [UTF-8] (see [CHARSET-POLICY] for IETF policy regarding character - sets in IETF protocols). In order to avoid noninteroperability due - to differing normalizations, when a mechanism specifies that a string - authentication identity or password used as input to a cryptographic - function (or used for comparison) it SHOULD specify that the string - first be prepared using the "SASLPrep" profile [SASLPrep] of the - "stringprep" algorithm [StringPrep]. There are three entities that - has to deal with this issue: a client (upon getting user input or - retrieving a value from configuration), a server (upon receiving the - value from the client) and a utility that is able to store - passwords/hashes in a database that can be later used by the server. - The preparation must be done by the client and the utility and may be - done by the server. If preparation fails or results in an empty - string, the entity doing the preparation SHALL fail the - authentication exchange. - - -5. Protocol profile requirements - - In order to use this specification, a protocol definition MUST supply - the following information: - - - - -A. Melnikov FORMFEED[Page 6] - - - - - -Internet DRAFT SASL 18 October 2003 - - - A service name, to be selected from the IANA registry of "service" - elements for the GSSAPI host-based service name form [GSSAPI]. This - service name is made available to the authentication mechanism. - - The registry is available at the URL - . - - A definition of the command to initiate the authentication protocol - exchange. This command must have as a parameter the name of the - mechanism being selected by the client. - - The command SHOULD have an optional parameter giving an initial - response. This optional parameter allows the client to avoid a round - trip when using a mechanism which is defined to have the client send - data first. When this initial response is sent by the client and the - selected mechanism is defined to have the server start with an - initial challenge, the command fails. See section 6.1 of this - document for further information. - - A definition of the method by which the authentication protocol - exchange is carried out, including how the challenges and responses - are encoded, how the server indicates completion or failure of the - exchange, how the client aborts an exchange, and how the exchange - method interacts with any line length limits in the protocol. - - The exchange method SHOULD allow the server to include an optional - data ("optional challenge") with a success notification. This allows - the server to avoid a round trip when using a mechanism which is - defined to have the server send additional data along with the - indication of successful completion. See section 6.2 of this - document for further information. - - In addition, a protocol profile SHOULD specify a mechanism through - which a client may obtain the names of the SASL mechanisms available - to it. This is typically done through the protocol's extensions or - capabilities mechanism. - - Identification of the octet where any negotiated security layer - starts to take effect, in both directions. - - Specify if the protocol supports "multiple authentications" (see - section 6.3). - - If both TLS and SASL security layer are allowed to be negotiated by - the protocol, the protocol profile MUST define in which order they - are applied to a cleartext data sent over the connection. - - A protocol profile MAY further refine the definition of an - - - -A. Melnikov FORMFEED[Page 7] - - - - - -Internet DRAFT SASL 18 October 2003 - - - authorization identity by adding additional syntactic restrictions - and protocol-specific semantics. A protocol profile MUST specify the - form of the authorization identity (since it is protocol specific, as - opposed to the authentication identity, which is mechanism specific) - and how authorization identities are to be compared. Profiles whose - authorization identities are simple user names (e.g. IMAP [RFC 3501]) - SHOULD use "SASLPrep" profile [SASLPrep] of the "stringprep" - algorithm [StringPrep] to prepare these names for matching. The - profiles MAY use a stringprep profile that is more strict than - SASLPrep. - - A protocol profile SHOULD NOT attempt to amend the definition of - mechanisms or make mechanism-specific encodings. This breaks the - separation between protocol and mechanism that is fundamental to the - design of SASL. Likewise, SASL mechanisms SHOULD be profile neutral. - -6. Specific issues - -6.1. Client sends data first - - Some mechanisms specify that the first data sent in the - authentication protocol exchange is from the client to the server. - - If a protocol's profile permits the command which initiates an - authentication protocol exchange to contain an initial client - response, this parameter SHOULD be used with such mechanisms. - - If the initial client response parameter is not given, or if a - protocol's profile does not permit the command which initiates an - authentication protocol exchange to contain an initial client - response, then the server issues a challenge with no data. The - client's response to this challenge is then used as the initial - client response. (The server then proceeds to send the next - challenge, indicates completion, or indicates failure.) - -6.2. Server returns success with additional data - - Some mechanisms may specify that additional data be sent to the - client along with an indication of successful completion of the - exchange. This data would, for example, authenticate the server to - the client. - - If a protocol's profile does not permit this additional data to be - returned with a success indication, then the server issues the data - as a server challenge, without an indication of successful - completion. The client then responds with no data. After receiving - this empty response, the server then indicates successful completion - (with no additional data). - - - -A. Melnikov FORMFEED[Page 8] - - - - - -Internet DRAFT SASL 18 October 2003 - - - Client implementors should be aware of an additional failure case - that might occur when the profile supports sending the additional - data with success. Imagine that an active attacker is trying to - impersonate the server and sends faked data, which should be used to - authenticate the server to the client, with success. (A similar - situation can happen when either the server and/or the client has a - bug and they calculate different responses.) After checking the data, - the client will think that the authentication exchange has failed, - however the server will think that the authentication exchange has - completed successfully. At this point the client can not abort the - authentication exchange, it SHOULD close the connection instead. - However, if the profile did not support sending of additional data - with success, the client could have aborted the exchange at the very - last step of the authentication exchange. - -6.3. Multiple authentications - - Unless otherwise stated by the protocol's profile, only one - successful SASL negotiation may occur in a protocol session. In this - case, once an authentication protocol exchange has successfully - completed, further attempts to initiate an authentication protocol - exchange fail. - - If a profile explicitly permits multiple successful SASL negotiations - to occur, then in no case may multiple security layers be - simultaneously in effect. If a security layer is in effect and a - subsequent SASL negotiation selects a second security layer, then the - second security layer replaces the first. If a security layer is in - effect and a subsequent SASL negotiation selects no security layer, - the original security layer MUST be removed. The next paragraphs - explain why this is important. - - Let's assume that the protected resources on a server are partitioned - into a set of protection spaces, each with its own authentication - mechanisms and/or authorization database. Let's use the term "realm" - to reference any such protected space. Conceptually, realm is a named - collection of user's accounts. For example, a proxy/frontend can use - different realms for different servers/backends it represents. - - Now consider the following scenario. A client has already - authenticated and established a security layer with "Realm A" which - is managed by the server AA. Now the same client authenticates to - "Realm B" (managed by the server BB) without negotiating a new - security layer, while the security layer negotiated with "Realm A" - remains in effect. The server BB is now able observe how known - cleartext is encrypted. This scenario enables the server BB to make - guesses about previously observed ciphertext between the client and - the server AA using the server's SASL engine as an oracle. This - - - -A. Melnikov FORMFEED[Page 9] - - - - - -Internet DRAFT SASL 18 October 2003 - - - scenario is illustrated below: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -A. Melnikov FORMFEED[Page 10] - - - - - -Internet DRAFT SASL 18 October 2003 - - - +---------+ +---------+ - | | | | - | Realm B | | Realm A | - | | | | - +---------+ +---------+ - | ^ | - | : +-----------+ | - Traffic from | : | Encryption| | Traffic from A - B to client +-------->| end point |<-------+ to client - : | (SSL/SASL)| - : +-----------+ - : | - : | - : +---+ - : | | - : | | - : | | Encryption tunnel, e.g. SASL or SSL, - : | | between the server - (1) Recording +---------:| | and a single client only. - encrypted | | Separate tunnels to different - traffic between | | clients. - Realm A and client +---+ - | - | - +-----------> Traffic to clients - -7. The EXTERNAL mechanism - - The mechanism name associated with external authentication is - "EXTERNAL". - - The client sends an initial response with the UTF-8 encoding of the - authorization identity. The form of the authorization identity is - further restricted by the application-level protocol's SASL profile. - - The server uses information, external to SASL, to determine whether - the client is authorized to authenticate as the authorization - identity. If the client is so authorized, the server indicates - successful completion of the authentication exchange; otherwise the - server indicates failure. - - The system providing this external information may be, for example, - IPSec or TLS. However, the client can make no assumptions as to what - information the server can use in determining client authorization. - E.g., just because TLS was established, doesn't mean that the server - will use the information provided by TLS. - - If the client sends the empty string as the authorization identity - - - -A. Melnikov FORMFEED[Page 11] - - - - - -Internet DRAFT SASL 18 October 2003 - - - (thus requesting that the authorization identity be derived from the - client's authentication credentials), the authorization identity is - to be derived from authentication credentials which exist in the - system that is providing the external authentication. - -7.1. Formal syntax - - The following syntax specification uses the augmented Backus-Naur - Form (BNF) notation as specified in [ABNF]. This uses the ABNF core - rules as specified in Appendix A of the ABNF specification [ABNF]. - Non-terminals referenced but not defined below are as defined by - [UTF-8]. - - The "extern-init-resp" rule below defines the initial response sent - from client to server. - - extern-init-resp = *( UTF8-char-no-nul ) - - UTF8-char-no-nul = UTF8-1-no-nul / UTF8-2 / UTF8-3 / UTF8-4 - - UTF8-1-no-nul = %x01-7F - - -7.2. Example - - The following is an example of an EXTERNAL authentication in the SMTP - protocol [SMTP]. In this example, the client is proxy - authenticating, sending the authorization id "fred". The server has - determined the client's identity through IPsec and has a security - policy that permits that identity to proxy authenticate as any other - identity. - - To the protocol profile, the four octet sequence "fred" is an opaque - binary data. The SASL protocol profile for SMTP [SMTP-AUTH] specifies - that server challenges and client responses are encoded in BASE64 - [BASE64]; the BASE64 encoding of "fred" is "ZnJlZA==". - - S: 220 smtp.example.com ESMTP server ready - C: EHLO jgm.example.com - S: 250-smtp.example.com - S: 250 AUTH DIGEST-MD5 EXTERNAL - C: AUTH EXTERNAL ZnJlZA== - S: 235 Authentication successful. - -8. IANA Considerations - - - - - - -A. Melnikov FORMFEED[Page 12] - - - - - -Internet DRAFT SASL 18 October 2003 - - -8.1. Guidelines for IANA - - - It is requested that IANA updates the SASL mechanisms registry as - follows: - - - Change the "Intended usage" of the KERBEROS_V4 and SKEY mechanism - registrations to OBSOLETE. Change the "Published specification" - of the EXTERNAL mechanism to this document. Updated registration - is provided in Section 8.6. - -8.2. Registration procedure - - - Registration of a SASL mechanism is done by filling in the template - in section 8.5 and sending it via electronic mail to . - IANA has the right to reject obviously bogus registrations, but will - perform no review of claims made in the registration form. SASL - mechanism registrations are currently available at the URL - . - - There is no naming convention for SASL mechanisms; any name that - conforms to the syntax of a SASL mechanism name can be registered. - An IETF Standards Track document may reserve a portion of the SASL - mechanism namespace ("family of SASL mechanisms") for its own use, - amending the registration rules for that portion of the namespace. - Each family of SASL mechanisms MUST be identified by a prefix. - - While the registration procedures do not require it, authors of SASL - mechanisms are encouraged to seek community review and comment - whenever that is feasible. Authors may seek community review by - posting a specification of their proposed mechanism as an Internet- - Draft. SASL mechanisms intended for widespread use should be - standardized through the normal IETF process, when appropriate. - -8.3. Comments on SASL mechanism registrations - - Comments on registered SASL mechanisms should first be sent to the - "owner" of the mechanism and/or to the SASL WG mailing list. - Submitters of comments may, after a reasonable attempt to contact the - owner, request IANA to attach their comment to the SASL mechanism - registration itself. If IANA approves of this, the comment will be - made accessible in conjunction with the SASL mechanism registration - itself. - - - - - - -A. Melnikov FORMFEED[Page 13] - - - - - -Internet DRAFT SASL 18 October 2003 - - -8.4. Change control - - Once a SASL mechanism registration has been published by IANA, the - author may request a change to its definition. The change request - follows the same procedure as the registration request. - - The owner of a SASL mechanism may pass responsibility for the SASL - mechanism to another person or agency by informing IANA; this can be - done without discussion or review. - - The IESG may reassign responsibility for a SASL mechanism. The most - common case of this will be to enable changes to be made to - mechanisms where the author of the registration has died, moved out - of contact or is otherwise unable to make changes that are important - to the community. - - SASL mechanism registrations may not be deleted; mechanisms which are - no longer believed appropriate for use can be declared OBSOLETE by a - change to their "intended use" field; such SASL mechanisms will be - clearly marked in the lists published by IANA. - - The IESG is considered to be the owner of all SASL mechanisms which - are on the IETF standards track. - -8.5. Registration template - - - Subject: Registration of SASL mechanism X - - Family of SASL mechanisms: (YES or NO) - - SASL mechanism name (or prefix for the family): - - Security considerations: - - Published specification (optional, recommended): - - Person & email address to contact for further information: - - Intended usage: - - (One of COMMON, LIMITED USE or OBSOLETE) - - Owner/Change controller: - - (Any other information that the author deems interesting may be - added below this line.) - - - - -A. Melnikov FORMFEED[Page 14] - - - - - -Internet DRAFT SASL 18 October 2003 - - -8.6. The EXTERNAL mechanism registration - - It is requested that the SASL Mechanism registry [IANA-SASL] entry - for the EXTERNAL mechanism be updated to reflect that this document - now provides its technical specification. - - - Subject: Updated Registration of SASL mechanism EXTERNAL - - Family of SASL mechanisms: NO - - SASL mechanism name: EXTERNAL - - Security considerations: See RFC XXXX, section 9. - - Published specification (optional, recommended): RFC XXXX - - Person & email address to contact for further information: - Alexey Melnikov - - Intended usage: COMMON - - Owner/Change controller: IESG - - Note: Updates existing entry for EXTERNAL - -9. Security considerations - - Security issues are discussed throughout this memo. - - The mechanisms that support integrity protection are designed such - that the negotiation of the security layer and authorization identity - is integrity protected. When the client selects a security layer - with at least integrity protection, this protects against an active - attacker hijacking the connection and modifying the authentication - exchange to negotiate a plaintext connection. - - When a server or client supports multiple authentication mechanisms, - each of which has a different security strength, it is possible for - an active attacker to cause a party to use the least secure mechanism - supported. To protect against this sort of attack, a client or - server which supports mechanisms of different strengths should have a - configurable minimum strength that it will use. It is not sufficient - for this minimum strength check to only be on the server, since an - active attacker can change which mechanisms the client sees as being - supported, causing the client to send authentication credentials for - its weakest supported mechanism. - - - - -A. Melnikov FORMFEED[Page 15] - - - - - -Internet DRAFT SASL 18 October 2003 - - - The client's selection of a SASL mechanism is done in the clear and - may be modified by an active attacker. It is important for any new - SASL mechanisms to be designed such that an active attacker cannot - obtain an authentication with weaker security properties by modifying - the SASL mechanism name and/or the challenges and responses. - - Any protocol interactions prior to authentication are performed in - the clear and may be modified by an active attacker. In the case - where a client selects integrity protection, it is important that any - security-sensitive protocol negotiations be performed after - authentication is complete. Protocols should be designed such that - negotiations performed prior to authentication should be either - ignored or revalidated once authentication is complete. - - When use of a security layer is negotiated by the authentication - protocol exchange, the receiver should handle gracefully any security - encoded data buffer larger than the defined/negotiated maximal size. - In particular, it must not blindly allocate the amount of memory - specified in the buffer size field, as this might cause the "out of - memory" condition. If the receiver detects a large block, it SHOULD - close the connection. - - "stringprep" and Unicode security considerations apply to - authentication identities, authorization identities and passwords. - - The EXTERNAL mechanism provides no security protection; it is - vulnerable to spoofing by either client or server, active attack, and - eavesdropping. It should only be used when external security - mechanisms are present and have sufficient strength. - -10. References - -10.1. Normative References - - [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications: - ABNF", RFC 2234, November 1997 - - [ASCII] American National Standards Institute, "Code Extension - Techniques for Use with the 7-bit Coded Character Set of American - National Standard Code (ASCII) for Information Interchange", FIPS PUB - 35, 1974 - - [CHARSET-POLICY] Alvestrand, "IETF Policy on Character Sets and - Languages", RFC 2277, January 1998 - - [GSSAPI] Linn, "Generic Security Service Application Program - Interface, Version 2, Update 1", RFC 2743, January 2000 - - - - -A. Melnikov FORMFEED[Page 16] - - - - - -Internet DRAFT SASL 18 October 2003 - - - [ISO-10646] "Universal Multiple-Octet Coded Character Set (UCS) - - Architecture and Basic Multilingual Plane", ISO/IEC 10646-1 : 1993. - - [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, March 1997 - - [Unicode] The Unicode Consortium, "The Unicode Standard, Version - 3.2.0" is defined by "The Unicode Standard, Version 3.0" (Reading, - MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), as amended by the - "Unicode Standard Annex #27: Unicode 3.1" - (http://www.unicode.org/reports/tr27/) and by the "Unicode Standard - Annex #28: Unicode 3.2" (http://www.unicode.org/reports/tr28/). - - [Stringprep] P. Hoffman, M. Blanchet, "Preparation of - Internationalized Strings ("stringprep")", RFC 3454, December 2002. - - [SASLPrep] Zeilenga, K., "SASLprep: Stringprep profile for user names - and passwords", Work in progress, draft-ietf-sasl-saslprep-XX.txt. - - [UTF-8] Yergeau, "UTF-8, a transformation format of ISO 10646", work - in progress (draft-yergeau-rfc2279bis-XX) that replaces RFC 2279, - Janyary 1998 - -10.2. Informative References - - <> [SASL-GSSAPI] Myers, J., "SASL GSSAPI - mechanisms", work in progress, draft-ietf-cat-sasl-gssapi-XX.txt, - September 2000 - - [SASL-DIGEST] Leach, P., Newman, C., Melnikov, A., "Using Digest - Authentication as a SASL Mechanism", work in progress, draft-ietf- - sasl-rfc2831bis-XX.txt, replaces RFC 2831 - - [SASL-OTP] Newman, C., "The One-Time-Password SASL Mechanism", RFC - 2444, October 1998 - - [SMTP] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, April - 2001 - - [SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication", - RFC 2554, March 1999 - - [BASE64] Josefsson, S., "The Base16, Base32, and Base64 Data - Encodings", RFC 3548, July 2003 - - [RFC-INSTRUCTIONS] Postel, Reynolds, "Instructions to RFC Authors", - RFC 2223, October 1997 - - - - -A. Melnikov FORMFEED[Page 17] - - - - - -Internet DRAFT SASL 18 October 2003 - - - [IANA-SASL] IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL) - MECHANISMS", http://www.iana.org/assignments/sasl-mechanisms. - -11. Editor's Address - - Alexey Melnikov - Isode - - Email: Alexey.Melnikov@isode.com - -12. Acknowledgments - - This document is a revision of RFC 2222 written by John G. Myers. He - also contributed significantly to this revision. - - Magnus Nystrom provided the ASCII art used in Section 6.3. - - Definition of realm was extracted from RFC 2617 ("HTTP - Authentication: Basic and Digest Access Authentication"). - - Contributions of many members of the SASL mailing list are gratefully - acknowledged, in particular Kurt D. Zeilenga, Peter Saint-Andre, Rob - Siemborski, Jeffrey Hutzelman and Hallvard B Furuseth for - proofreading the document and various editorial suggestions. - - -13. Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - - - -A. Melnikov FORMFEED[Page 18] - - - - - -Internet DRAFT SASL 18 October 2003 - - - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - -Appendix A. Relation of SASL to transport security - - Questions have been raised about the relationship between SASL and - various services (such as IPsec and TLS) which provide a secured - connection. - - Two of the key features of SASL are: - - The separation of the authorization identity from the identity in - the client's credentials. This permits agents such as proxy - servers to authenticate using their own credentials, yet request - the access privileges of the identity for which they are proxying. - - Upon successful completion of an authentication exchange, the - server knows the authorization identity the client wishes to use. - This allows servers to move to a "user is authenticated" state in - the protocol. - - These features are extremely important to some application protocols, - yet Transport Security services do not always provide them. To - define SASL mechanisms based on these services would be a very messy - task, as the framing of these services would be redundant with the - framing of SASL and some method of providing these important SASL - features would have to be devised. - - Sometimes it is desired to enable within an existing connection the - use of a security service which does not fit the SASL model. (TLS is - an example of such a service.) This can be done by adding a command, - for example "STARTTLS", to the protocol. Such a command is outside - the scope of SASL, and should be different from the command which - starts a SASL authentication protocol exchange. - - In certain situations, it is reasonable to use SASL underneath one of - these Transport Security services. The transport service would - secure the connection, either service would authenticate the client, - and SASL would negotiate the authorization identity. The SASL - negotiation would be what moves the protocol from "unauthenticated" - - - -A. Melnikov FORMFEED[Page 19] - - - - - -Internet DRAFT SASL 18 October 2003 - - - to "authenticated" state. The "EXTERNAL" SASL mechanism is - explicitly intended to handle the case where the transport service - secures the connection and authenticates the client and SASL - negotiates the authorization identity. - -Appendix B. Changes since RFC 2222 - - The GSSAPI mechanism was removed. It is now specified in a separate - document [SASL-GSSAPI]. - - The "KERBEROS_V4" mechanism defined in RFC 2222 is obsolete and has - been removed. - - The "SKEY" mechanism described in RFC 2222 is obsolete and has been - removed. It has been replaced by the OTP mechanism [SASL-OTP]. - - The overview has been substantially reorganized and clarified. - - Clarified the definition and semantics of the authorization identity. - - Prohibited the NUL character in authorization identities. - - Added a section on character string issues. - - The word "must" in the first paragraph of the "Protocol profile - requirements" section was changed to "MUST". - - Specified that protocol profiles SHOULD provide a way for clients to - discover available SASL mechanisms. - - Made the requirement that protocol profiles specify the semantics of - the authorization identity optional to the protocol profile. - Clarified that such a specification is a refinement of the definition - in the base SASL spec. - - Added a requirement discouraging protocol profiles from breaking the - separation between protocol and mechanism. - - Mentioned that standards track documents may carve out their own - portions of the SASL mechanism namespace and may amend registration - rules for the portion. However registration of individual SASL - mechanisms is still required. - - Specified that the authorization identity in the EXTERNAL mechanism - is encoded in UTF-8. - - Added a statement that a protocol profile SHOULD allow challenge data - to be sent with a success indication. - - - -A. Melnikov FORMFEED[Page 20] - - - - - -Internet DRAFT SASL 18 October 2003 - - - Added a security consideration for the EXTERNAL mechansim. - - Clarified sections concerning success with additional data. - - Cleaned up IANA considerations/registrations and assembled them in - one place. - - Updated references and split them into Informative and Normative. - - Added text to the Security Considerations section regarding handling - of extremely large SASL blocks. - - Replaced UTF-8 ABNF with the reference to the UTF-8 document. - - Added text about SASLPrep for authentication identities and - passwords. Described where SASLPrep preparation should take place. - - Added paragraph about verifying authorization identities. - - This document requires to drop a security layer on reauthentication - when no security layer is negotiated. This differs from RFC 2222, - which required to keep the last security layer in this case. - - Added a protocol profile requirement to specify interaction between - SASL and TLS security layers. - - Added a protocol profile requirement to specify if it supports - reauthentication. - - Removed the text that seemed to suggest that SASL security layer must - not be used when TLS is available. - - - - - - - - - - - - - - - - - - - - -A. Melnikov FORMFEED[Page 21] - - - - - -Internet DRAFT SASL 18 October 2003 - - - Status of this Memo .......................................... i - 1. Abstract ............................................... 2 - 2. Organization of this document .......................... 2 - 2.1. How to read this document .............................. 2 - 2.2. Conventions used in this document ...................... 2 - 3. Overview ............................................... 3 - 4. Authentication mechanisms .............................. 3 - 4.1. Authentication protocol exchange ....................... 4 - 4.2. Authorization identities and proxy authentication ...... 4 - 4.3. Security layers ........................................ 6 - 4.4. Character string issues ................................ 6 - 5. Protocol profile requirements .......................... 6 - 6. Specific issues ........................................ 8 - 6.1. Client sends data first ................................ 8 - 6.2. Server returns success with additional data ............ 8 - 6.3. Multiple authentications ............................... 9 - 7. The EXTERNAL mechanism ................................ 11 - 7.1. Formal syntax ......................................... 12 - 7.2. Example ............................................... 12 - 8. IANA Considerations ................................... 12 - 8.1. Guidelines for IANA ................................... 13 - 8.2. Registration procedure ................................ 13 - 8.3. Comments on SASL mechanism registrations .............. 13 - 8.4. Change control ........................................ 14 - 8.5. Registration template ................................. 14 - 8.6. The EXTERNAL mechanism registration ................... 15 - 9. Security considerations ................................ 15 - 10. References ........................................... 16 - 10.1. Normative References ................................. 16 - 10.2. Informative References ............................... 17 - 11. Editor's Address ...................................... 18 - 12. Acknowledgments ....................................... 18 - 13. Full Copyright Statement .............................. 18 - Appendix A. Relation of SASL to transport security .......... 19 - Appendix B. Changes since RFC 2222 .......................... 20 - - - - - - - - - - - - - - - - -A. Melnikov FORMFEED[Page ii] - - diff --git a/doc/draft-ietf-sasl-rfc2831bis-xx.txt b/doc/draft-ietf-sasl-rfc2831bis-xx.txt deleted file mode 100644 index dd3b9b0f..00000000 --- a/doc/draft-ietf-sasl-rfc2831bis-xx.txt +++ /dev/null @@ -1,2340 +0,0 @@ - - - - - - -INTERNET-DRAFT P. Leach -Obsoletes: 2831 Microsoft -Intended category: Standards track C. Newman - Sun Microsystems - A. Melnikov - Isode - June 2003 - - Using Digest Authentication as a SASL Mechanism - draft-ietf-sasl-rfc2831bis-02.txt - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC 2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This specification defines how HTTP Digest Authentication [Digest] - can be used as a SASL [RFC 2222] mechanism for any protocol that has - a SASL profile. It is intended both as an improvement over CRAM-MD5 - [RFC 2195] and as a convenient way to support a single authentication - mechanism for web, mail, LDAP, and other protocols. - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 1] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -Table of Contents - - 1 INTRODUCTION.....................................................3 - 1.1 CONVENTIONS AND NOTATION......................................3 - 1.2 REQUIREMENTS..................................................4 - 2 AUTHENTICATION...................................................5 - 2.1 INITIAL AUTHENTICATION........................................5 - 2.1.1 Step One...................................................5 - 2.1.2 Step Two...................................................9 - 2.1.3 Step Three................................................16 - 2.2 SUBSEQUENT AUTHENTICATION....................................17 - 2.2.1 Step one..................................................17 - 2.2.2 Step Two..................................................17 - 2.3 INTEGRITY PROTECTION.........................................18 - 2.4 CONFIDENTIALITY PROTECTION...................................18 - 3 SECURITY CONSIDERATIONS.........................................21 - 3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........21 - 3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................21 - 3.3 REPLAY ATTACKS...............................................21 - 3.4 ONLINE DICTIONARY ATTACKS....................................22 - 3.5 OFFLINE DICTIONARY ATTACKS...................................22 - 3.6 MAN IN THE MIDDLE............................................22 - 3.7 CHOSEN PLAINTEXT ATTACKS.....................................22 - 3.8 CBC MODE ATTACKS............................................. - 3.9 SPOOFING BY COUNTERFEIT SERVERS..............................23 - 3.10 STORING PASSWORDS...........................................23 - 3.11 MULTIPLE REALMS.............................................24 - 3.12 SUMMARY.....................................................24 - 4 EXAMPLE.........................................................24 - 5 REFERENCES......................................................26 - 5.1 NORMATIVE REFERENCES.........................................26 - 5.2 INFORMATIVE REFERENCES.......................................27 - 6 AUTHORS' ADDRESSES..............................................28 - 7 ABNF............................................................29 - 7.1 AUGMENTED BNF................................................29 - 7.2 BASIC RULES..................................................31 - 8 SAMPLE CODE.....................................................33 - 9 INTEROPERABILITY CONSIDERATIONS.................................34 - 9.1 Implementing DES cipher in CBC mode..........................34 - 10 ACKNOWLEDGEMENTS..............................................34 - 11 FULL COPYRIGHT STATEMENT.......................................35 - Appendix A: Changes from 2831.....................................36 - Appendix B: Open Issues...........................................37 - - - - - - - - -Leach & Newman Expires: December 2003 [Page 2] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -1 Introduction - - This specification describes the use of HTTP Digest Access - Authentication as a SASL mechanism. The authentication type - associated with the Digest SASL mechanism is "DIGEST-MD5". - - This specification is intended to be upward compatible with the - "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication - specified in [Digest]. The only difference in the "md5-sess" - algorithm is that some directives not needed in a SASL mechanism have - had their values defaulted. - - There is one new feature for use as a SASL mechanism: integrity - protection on application protocol messages after an authentication - exchange. - - Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext - attacks, and permits the use of third party authentication servers, - mutual authentication, and optimized reauthentication if a client has - recently authenticated to a server. - -1.1 Conventions and Notation - - This specification uses the same ABNF notation and lexical - conventions as HTTP/1.1 specification; see section 7. - - Let { a, b, ... } be the concatenation of the octet strings a, b, ... - - Let ** denote the power operation. - - Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s. - - Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string - k, a colon and the string s. - - Let HEX(n) be the representation of the 16 octet MD5 hash n as a - string of 32 hex digits (with alphabetic characters always in lower - case, since MD5 is case sensitive). - - Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet - string s using the octet string k as a key. - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 3] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - Let unq(X) be the value of the quoted-string X without the - surrounding quotes and with all escape characters "\\" removed. For - example for the quoted-string "Babylon" the value of unq("Babylon") - is Babylon; for the quoted string "ABC\"123\\" the value of - unq("ABC\"123\\") is ABC"123\. - - The value of a quoted string constant as an octet string does not - include any terminating null character. - -1.2 Requirements - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [RFC 2119]. - - An implementation is not compliant if it fails to satisfy one or more - of the MUST level requirements for the protocols it implements. An - implementation that satisfies all the MUST level and all the SHOULD - level requirements for its protocols is said to be "unconditionally - compliant"; one that satisfies all the MUST level requirements but - not all the SHOULD level requirements for its protocols is said to be - "conditionally compliant." - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 4] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -2 Authentication - - The following sections describe how to use Digest as a SASL - authentication mechanism. - -2.1 Initial Authentication - - If the client has not recently authenticated to the server, then it - must perform "initial authentication", as defined in this section. If - it has recently authenticated, then a more efficient form is - available, defined in the next section. - -2.1.1 Step One - - The server starts by sending a challenge. The data encoded in the - challenge contains a string formatted according to the rules for a - "digest-challenge" defined as follows: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 5] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - digest-challenge = - 1#( realm | nonce | qop-options | stale | server_maxbuf | charset - algorithm | cipher-opts | auth-param ) - - realm = "realm" "=" <"> realm-value <"> - realm-value = qdstr-val - nonce = "nonce" "=" <"> nonce-value <"> - nonce-value = *qdtext - qop-options = "qop" "=" <"> qop-list <"> - qop-list = 1#qop-value - qop-value = "auth" | "auth-int" | "auth-conf" | - token - stale = "stale" "=" "true" - server_maxbuf = "maxbuf" "=" maxbuf-value - maxbuf-value = 1*DIGIT - charset = "charset" "=" "utf-8" - algorithm = "algorithm" "=" "md5-sess" - cipher-opts = "cipher" "=" <"> 1#cipher-value <"> - cipher-value = "3des" | "des" | "rc4-40" | "rc4" | - "rc4-56" | "aes" | token - auth-param = token "=" ( token | quoted-string ) - - The meanings of the values of the directives used above are as - follows: - - realm - Mechanistically, a string which can enable users to know which - username and password to use, in case they might have different - ones for different servers. Conceptually, it is the name of a - collection of accounts that might include the user's account. This - string should contain at least the name of the host performing the - authentication and might additionally indicate the collection of - users who might have access. An example might be - "registered_users@gotham.news.example.com". This directive is - optional; if not present, the client SHOULD solicit it from the - user or be able to compute a default; a plausible default might be - the realm supplied by the user when they logged in to the client - system. Multiple realm directives are allowed, in which case the - user or client must choose one as the realm for which to supply to - username and password. - - If at least one realm is present and the charset directive is also - specified (which means that realm(s) are encoded as UTF-8), the - client should prepare each instance of realm using the "SASLPrep" - profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If - preparation of a realm instance fails or results in an empty - string, the client should abort the authentication exchange. - - - - -Leach & Newman Expires: December 2003 [Page 6] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - nonce - A server-specified data string which MUST be different each time a - digest-challenge is sent as part of initial authentication. It is - recommended that this string be base64 or hexadecimal data. Note - that since the string is passed as a quoted string, the - double-quote character is not allowed unless escaped (see section - 7.2). The contents of the nonce are implementation dependent. The - security of the implementation depends on a good choice. It is - RECOMMENDED that it contain at least 64 bits of entropy. The nonce - is opaque to the client. This directive is required and MUST - appear exactly once; if not present, or if multiple instances are - present, the client should abort the authentication exchange. - - qop-options - A quoted string of one or more tokens indicating the "quality of - protection" values supported by the server. The value "auth" - indicates authentication; the value "auth-int" indicates - authentication with integrity protection; the value "auth-conf" - indicates authentication with integrity protection and encryption. - This directive is optional; if not present it defaults to "auth". - The client MUST ignore unrecognized options; if the client - recognizes no option, it should abort the authentication exchange. - - stale - The "stale" directive is not used in initial authentication. See - the next section for its use in subsequent authentications. This - directive may appear at most once; if multiple instances are - present, the client should abort the authentication exchange. - - server_maxbuf ("maximal ciphertext buffer size") - A number indicating the size of the largest buffer the server is - able to receive when using "auth-int" or "auth-conf". The value - MUST be bigger than 16 and smaller or equal to 16777215 (i.e. - 2**24-1). If this directive is missing, the default value is - 65536. This directive may appear at most once; if multiple - instances are present, the client MUST abort the authentication - exchange. - - Let call "maximal cleartext buffer size" (or "maximal sender - size") the maximal size of a cleartext buffer that, after being - transformed by integrity (section 2.3) or confidentiality (section - 2.4) protection function, will produce a SASL block of the maxbuf - size. As it should be clear from the name, the sender MUST never - pass a block of data bigger than the "maximal sender size" through - the selected protection function. This will guaranty that the - receiver will never get a block bigger than the maxbuf. - - - - - -Leach & Newman Expires: December 2003 [Page 7] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - charset - This directive, if present, specifies that the server supports - UTF-8 [UTF-8] encoding for the username, realm and password. If - present, the username, realm and password are in Unicode, prepared - using the "SASLPrep" profile [SASLPrep] of the "stringprep" - algorithm [StringPrep] and than encoded as UTF-8 [UTF-8]. If not - present, the username, realm and password MUST be encoded in ISO - 8859-1 [ISO-8859] (of which US-ASCII [USASCII] is a subset). The - directive is needed for backwards compatibility with HTTP Digest, - which only supports ISO 8859-1. This directive may appear at most - once; if multiple instances are present, the client should abort - the authentication exchange. - - Note, that this directive doesn't affect authorization id - ("authzid"). - - algorithm - This directive is required for backwards compatibility with HTTP - Digest, which supports other algorithms. This directive is - required and MUST appear exactly once; if not present, or if - multiple instances are present, the client should abort the - authentication exchange. - - cipher-opts - A list of ciphers that the server supports. This directive must be - present exactly once if "auth-conf" is offered in the - "qop-options" directive, in which case the "3des" cipher is - mandatory-to-implement. The client MUST ignore unrecognized - options; if the client recognizes no option, it should abort the - authentication exchange. See section 2.4 for more detailed - description of the ciphers. - - des - the Data Encryption Standard (DES) cipher [FIPS] in cipher - block chaining (CBC) mode with a 56 bit key. - - 3des - the "triple DES" cipher in CBC mode with EDE - (Encrypt,Decrypt,Encrypt) with the same key for each E stage - (aka "two keys mode") for a total key length of 112 bits. - - rc4, rc4-40, rc4-56 - the RC4 cipher with a 128 bit, 40 bit, and 56 bit key, - respectively. - - aes - the Advanced Encryption Standard (AES) cipher [AES] in cipher - block chaining (CBC) mode with a 128 bit key. This mode - - - -Leach & Newman Expires: December 2003 [Page 8] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - requires an Initialization Vector (IV) that has the same size - as the block size. - - auth-param - This construct allows for future extensions; it may appear more - than once. The client MUST ignore any unrecognized directives. - - For use as a SASL mechanism, note that the following changes are made - to "digest-challenge" from HTTP: the following Digest options (called - "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent, - and MUST be ignored if received): - - opaque - domain - - The size of a digest-challenge MUST be less than 2048 bytes. - -2.1.2 Step Two - - The client makes note of the "digest-challenge" and then responds - with a string formatted and computed according to the rules for a - "digest-response" defined as follows: - - digest-response = 1#( username | realm | nonce | cnonce | - nonce-count | qop | digest-uri | response | - client_maxbuf | charset | cipher | authzid | - auth-param ) - - username = "username" "=" <"> username-value <"> - username-value = qdstr-val - cnonce = "cnonce" "=" <"> cnonce-value <"> - cnonce-value = *qdtext - nonce-count = "nc" "=" nc-value - nc-value = 8LHEX - client_maxbuf = "maxbuf" "=" maxbuf-value - qop = "qop" "=" qop-value - digest-uri = "digest-uri" "=" <"> digest-uri-value <"> - digest-uri-value = serv-type "/" host [ "/" serv-name ] - serv-type = 1*ALPHA - serv-name = host - response = "response" "=" response-value - response-value = 32LHEX - LHEX = "0" | "1" | "2" | "3" | - "4" | "5" | "6" | "7" | - "8" | "9" | "a" | "b" | - "c" | "d" | "e" | "f" - cipher = "cipher" "=" cipher-value - authzid = "authzid" "=" <"> authzid-value <"> - - - -Leach & Newman Expires: December 2003 [Page 9] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - authzid-value = qdstr-val - - The 'host' non-terminal is defined in [RFC 2732] as - - host = hostname | IPv4address | IPv6reference - ipv6reference = "[" IPv6address "]" - - where IPv6address and IPv4address are defined in [RFC 2373] - and 'hostname' is defined in [RFC 2396]. - - username - The user's name in the specified realm, encoded according to the - value of the "charset" directive. This directive is required and - MUST be present exactly once; otherwise, authentication fails. - - Upon the receipt of this value and if the charset directive is - also specified (which means that the username is encoded as - UTF-8), the server MUST prepare the username using the "SASLPrep" - profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If - preparation of the username fails or results in an empty string, - the server MUST fail the authentication exchange. - - realm - The realm containing the user's account, encoded according to the - value of the "charset" directive. This directive is required if - the server provided any realms in the - "digest-challenge", in which case it may appear exactly once and - its value SHOULD be one of those realms. If the directive is - missing, "realm-value" will set to the empty string when computing - A1 (see below for details). - - If realm was provided by the client and if the charset directive - was also specified (which means that the realm is encoded as - UTF-8), the server MUST prepare the realm using the "SASLPrep" - profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If - preparation of the realm fails or results in an empty string, the - server MUST fail the authentication exchange. - - nonce - The server-specified data string received in the preceding digest- - challenge. This directive is required and MUST be present exactly - once; otherwise, authentication fails. - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 10] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - cnonce - A client-specified data string which MUST be different each time a - digest-response is sent as part of initial authentication. The - cnonce-value is an opaque quoted string value provided by the - client and used by both client and server to avoid chosen - plaintext attacks, and to provide mutual authentication. The - security of the implementation depends on a good choice. It is - RECOMMENDED that it contain at least 64 bits of entropy. This - directive is required and MUST be present exactly once; otherwise, - authentication fails. - - nonce-count - The nc-value is the hexadecimal count of the number of requests - (including the current request) that the client has sent with the - nonce value in this request. For example, in the first request - sent in response to a given nonce value, the client sends - "nc=00000001". The purpose of this directive is to allow the - server to detect request replays by maintaining its own copy of - this count - if the same nc-value is seen twice, then the request - is a replay. See the description below of the construction of the - response value. This directive is required and MUST be present - exactly once; otherwise, authentication fails. - - qop - Indicates what "quality of protection" the client accepted. If - present, it may appear exactly once and its value MUST be one of - the alternatives in qop-options. If not present, it defaults to - "auth". These values affect the computation of the response. Note - that this is a single token, not a quoted list of alternatives. - - serv-type - Indicates the type of service, such as "http" for web service, - "ftp" for FTP service, "smtp" for mail delivery service, etc. The - service name as defined in the SASL profile for the protocol see - section 4 of [RFC 2222], registered in the IANA registry of - "service" elements for the GSSAPI host-based service name form - [RFC 2078]. - - host - The DNS host name or IP (IPv4 or IPv6) address for the service - requested. The DNS host name must be the fully-qualified - canonical name of the host. The DNS host name is the preferred - form; see notes on server processing of the digest-uri. - - - - - - - - -Leach & Newman Expires: December 2003 [Page 11] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - serv-name - Indicates the name of the service if it is replicated. The service - is considered to be replicated if the client's service-location - process involves resolution using standard DNS lookup operations, - and if these operations involve DNS records (such as SRV [RFC - 2052], or MX) which resolve one DNS name into a set of other DNS - names. In this case, the initial name used by the client is the - "serv-name", and the final name is the "host" component. For - example, the incoming mail service for "example.com" may be - replicated through the use of MX records stored in the DNS, one of - which points at an SMTP server called "mail3.example.com"; it's - "serv-name" would be "example.com", it's "host" would be - "mail3.example.com". If the service is not replicated, or the - serv-name is identical to the host, then the serv-name component - MUST be omitted. - - digest-uri - Indicates the principal name of the service with which the client - wishes to connect, formed from the serv-type, host, and serv-name. - For example, the FTP service on "ftp.example.com" would have a - "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from - the example above would have a "digest-uri" value of - "SMTP/mail3.example.com/example.com". - - Servers SHOULD check that the supplied value is correct. This will - detect accidental connection to the incorrect server, as well as some - redirection attacks. It is also so that clients will be trained to - provide values that will work with implementations that use a shared - back-end authentication service that can provide server - authentication. - - The serv-type component should match the service being offered. The - host component should match one of the host names of the host on - which the service is running, or it's IP address. Servers SHOULD NOT - normally support the IP address form, because server authentication - by IP address is not very useful; they should only do so if the DNS - is unavailable or unreliable. The serv-name component should match - one of the service's configured service names. - - This directive may appear at most once; if multiple instances are - present, the client should abort the authentication exchange. - - Note: In the HTTP use of Digest authentication, the digest-uri is the - URI (usually a URL) of the resource requested -- hence the name of - the directive. - - - - - - -Leach & Newman Expires: December 2003 [Page 12] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - response - A string of 32 hex digits computed as defined below, which proves - that the user knows a password. This directive is required and - MUST be present exactly once; otherwise, authentication fails. - - client_maxbuf - A number indicating the size of the largest ciphertext buffer the - client is able to receive when using "auth-int" or "auth-conf". If - this directive is missing, the default value is 65536. This - directive may appear at most once; if multiple instances are - present, the server MUST abort the authentication exchange. If the - value is less or equal to 16 or bigger than 16777215 (i.e. - 2**24-1), the server MUST abort the authentication exchange. - - Upon processing/sending of the client_maxbuf value both the server - and the client calculate their "maximal ciphertext buffer size" as - the minimum of the server_maxbuf (Step One) and the client_maxbuf - (Step Two). The "maximal sender size" can be calculated by - subtracting 16 from the calculated "maximal ciphertext buffer - size". - - When sending a block of data the client/server MUST NOT pass more - than the "maximal sender size" bytes of data to the selected - protection function (2.3 or 2.4). - - charset - This directive, if present, specifies that the client has used - UTF-8 [UTF-8] encoding for the username, realm and password. If - present, the username, realm and password are in Unicode, prepared - using the "SASLPrep" profile [SASLPrep] of the "stringprep" - algorithm [StringPrep] and than encoded as UTF-8 [UTF-8]. If not - present, the username and password must be encoded in ISO 8859-1 - [ISO-8859] (of which - US-ASCII [USASCII] is a subset). The client should send this - directive only if the server has indicated it supports UTF-8 - [UTF-8]. The directive is needed for backwards compatibility with - HTTP Digest, which only supports ISO 8859-1. - - Note, that this directive doesn't affect authorization id - ("authzid"). - - LHEX - 32 hex digits, where the alphabetic characters MUST be lower case, - because MD5 is not case insensitive. - - cipher - The cipher chosen by the client. This directive MUST appear - exactly once if "auth-conf" is negotiated; if required and not - - - -Leach & Newman Expires: December 2003 [Page 13] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - present, authentication fails. - - authzid - The "authorization ID" directive is optional. If present, and the - authenticating user has sufficient privilege, and the server - supports it, then after authentication the server will use this - identity for making all accesses and access checks. If the client - specifies it, and the server does not support it, then the - response-value calculated on the server will not match the one - calculated on the client and authentication will fail. - - The authzid MUST NOT be an empty string. - - The authorization identifier MUST NOT be converted to ISO 8859-1 - even if the authentication identifier ("username") is converted - for compatibility as directed by "charset" directive. - - The server SHOULD verify the correctness of an authzid as - specified by the corresponding SASL protocol profile. - - The size of a digest-response MUST be less than 4096 bytes. - -2.1.2.1 Response-value - - The definition of "response-value" above indicates the encoding for - its value -- 32 lower case hex characters. The following definitions - show how the value is computed. - - Although qop-value and components of digest-uri-value may be - case-insensitive, the case which the client supplies in step two is - preserved for the purpose of computing and verifying the - response-value. - - response-value = - HEX( KD ( HEX(H(A1)), - { nonce-value, ":" nc-value, ":", - cnonce-value, ":", qop-value, ":", HEX(H(A2)) })) - - If authzid is specified, then A1 is - - - A1 = { H( { unq(username-value), ":", unq(realm-value), ":", passwd } ), - ":", nonce-value, ":", cnonce-value, ":", unq(authzid-value) } - - If authzid is not specified, then A1 is - - - A1 = { H( { unq(username-value), ":", unq(realm-value), ":", passwd } ), - - - -Leach & Newman Expires: December 2003 [Page 14] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - ":", nonce-value, ":", cnonce-value } - - where - - passwd = *OCTET - - The "username-value", "realm-value" and "passwd" are encoded - according to the value of the "charset" directive. If "charset=UTF-8" - is present, and all the characters of "username-value" are, after - preparing using the "SASLPrep" profile [SASLPrep] of the "stringprep" - algorithm [StringPrep], in the ISO 8859-1 character set, then it must - be converted to ISO 8859-1 before being hashed. The same - transformation has to be done for "realm-value" and "passwd". This is - so that authentication databases that store the hashed username, - realm and password (which is common) can be shared compatibly with - HTTP, which specifies ISO 8859-1. A sample implementation of this - conversion is in section 8. - - If the "qop" directive's value is "auth", then A2 is: - - A2 = { "AUTHENTICATE:", digest-uri-value } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 15] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - If the "qop" value is "auth-int" or "auth-conf" then A2 is: - - A2 = { "AUTHENTICATE:", digest-uri-value, - ":00000000000000000000000000000000" } - - Note that "AUTHENTICATE:" must be in upper case, and the second - string constant is a string with a colon followed by 32 zeros. - - These apparently strange values of A2 are for compatibility with - HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and - the hash of the entity body to zero in the HTTP digest calculation of - A2. - - Also, in the HTTP usage of Digest, several directives in the - "digest-challenge" sent by the server have to be returned by the - client in the "digest-response". These are: - - opaque - algorithm - - These directives are not needed when Digest is used as a SASL - mechanism (i.e., MUST NOT be sent, and MUST be ignored if received). - -2.1.3 Step Three - - The server receives and validates the "digest-response". The server - checks that the nonce-count is "00000001". If it supports subsequent - authentication (see section 2.2), it saves the value of the nonce and - the nonce-count. It sends a message formatted as follows: - - response-auth = "rspauth" "=" response-value - - where response-value is calculated as above, using the values sent in - step two, except that if qop is "auth", then A2 is - - A2 = { ":", digest-uri-value } - - And if qop is "auth-int" or "auth-conf" then A2 is - - A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" } - - Compared to its use in HTTP, the following Digest directives in the - "digest-response" are unused: - - nextnonce - qop - cnonce - nonce-count - - - -Leach & Newman Expires: December 2003 [Page 16] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -2.2 Subsequent Authentication - - If the client has previously authenticated to the server, and - remembers the values of username, realm, nonce, nonce-count, cnonce, - and qop that it used in that authentication, and the SASL profile for - a protocol permits an initial client response, then it MAY perform - "subsequent authentication", as defined in this section. - -2.2.1 Step one - - The client uses the values from the previous authentication and sends - an initial response with a string formatted and computed according to - the rules for a "digest-response", as defined above, but with a - nonce-count one greater than used in the last "digest-response". - -2.2.2 Step Two - - The server receives the "digest-response". If the server does not - support subsequent authentication, then it sends a - "digest-challenge", and authentication proceeds as in initial - authentication. If the server has no saved nonce and nonce-count from - a previous authentication, then it sends a "digest-challenge", and - authentication proceeds as in initial authentication. Otherwise, the - server validates the "digest-response", checks that the nonce-count - is one greater than that used in the previous authentication using - that nonce, and saves the new value of nonce-count. - - If the response is invalid, then the server sends a - "digest-challenge", and authentication proceeds as in initial - authentication (and should be configurable to log an authentication - failure in some sort of security audit log, since the failure may be - a symptom of an attack). The nonce-count MUST NOT be incremented in - this case: to do so would allow a denial of service attack by sending - an out-of-order nonce-count. - - If the response is valid, the server MAY choose to deem that - authentication has succeeded. However, if it has been too long since - the previous authentication, or for any o including the next - subsequent authentication, between the client and the server MUST be - integrity protected. Using as a base session key the value of H(A1) - as defined above the client and server calculate a pair of message - integrity keys as follows. - - The key for integrity protecting messages from client to server is: - - Kic = MD5({H(A1), - "Digest session key to client-to-server signing key magic constant"}) - - - - -Leach & Newman Expires: December 2003 [Page 17] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - The key for integrity protecting messages from server to client is: - - Kis = MD5({H(A1), - "Digest session key to server-to-client signing key magic constant"}) - - where MD5 is as specified in [RFC 1321]. If message integrity is - negotiated, a MAC block for each message is appended to the message. - The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC - 2104] of the message, a 2-byte message type number in network byte - order with value 1, and the 4-byte sequence number in network byte - order. The message type is to allow for future extensions such as - rekeying. - - MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001, - SeqNum) - - where Ki is Kic for messages sent by the client and Kis for those - sent by the server. The sequence number (SeqNum) is an unsigned - number initialized to zero after initial or subsequent - authentication, and incremented by one for each message - sent/successfully verified. (Note, that there are two independent - counters for sending and receiving.) The sequence number wraps around - to 0 after 2**32-1. - - Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the - received value; the message is discarded if they differ. The - receiver's sequence counter is incremented if they match. - -2.4 Confidentiality Protection - - If the server sent a "cipher-opts" directive and the client responded - with a "cipher" directive, then subsequent messages between the - client and the server MUST be confidentiality protected. Using as a - base session key the value of H(A1) as defined above the client and - server calculate a pair of message integrity keys as follows. - - The key for confidentiality protecting messages from client to server - is: - - Kcc = MD5({H(A1)[0..n-1], - "Digest H(A1) to client-to-server sealing key magic constant"}) - - The key for confidentiality protecting messages from server to client - is: - - Kcs = MD5({H(A1)[0..n-1], - "Digest H(A1) to server-to-client sealing key magic constant"}) - - - - -Leach & Newman Expires: December 2003 [Page 18] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5; - for "rc4-56" n is 7; for the rest n is 16. The key for the "rc4-*" - and "aes" ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is - the first 7 bytes; the key for "3des" is the first 14 bytes. - - The IV used to send/receive the initial buffer of security encoded - data for "des" and "3des" is the last 8 bytes of Kcc or Kcs. For all - subsequent buffers the last 8 bytes of the ciphertext of the buffer - NNN is used as the IV for the buffer (NNN + 1). - - The IV for the "aes" cipher in CBC mode for messages going from the - client to the server (IVc) consists of 16 bytes calculated as - follows: - - IVc = MD5({Kcc, "aes-128"}) - - The IV for the "aes" cipher in CBC mode for messages going from the - server to the client (IVs) consists of 16 bytes calculated as - follows: - - IVs = MD5({Kcs, "aes-128"}) - - The IV is XOR'd with the first plaintext block before it is encrypted - with "aes". Then for successive blocks, the previous ciphertext - block is XOR'd with the current plaintext, before it is encrypted. - - rc4 cipher state MUST NOT be reset before sending/receiving a next - buffer of security encoded data. - - The MAC block is a variable length padding prefix followed by 16 - bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC - 2104] of the message, a 2-byte message type number in network byte - order with value 1, and the 4-byte sequence number in network byte - order. If the blocksize of the chosen cipher is not 1 byte, the - padding prefix is one or more octets each containing the number of - padding bytes, such that total length of the encrypted part of the - message is a multiple of the blocksize. The padding and first 10 - bytes of the MAC block are encrypted with the chosen cipher along - with the message. - - SEAL(Ki, Kc, SeqNum, msg) = - {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9]}), 0x0001, - SeqNum} - - where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for - messages sent by the client and Kis and Kcs for those sent by the - server. The sequence number (SeqNum) is an unsigned number - initialized to zero after initial or subsequent authentication, and - - - -Leach & Newman Expires: December 2003 [Page 19] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - incremented by one for each message sent/successfully verified. - (Note, that there are two independent counters for sending and - receiving.) The sequence number wraps around to 0 after 2**32-1. - - Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is - computed and compared with the received value; the padding is - verified. The message is discarded if the received and the - calculated HMACs differ and/or the padding is invalid. See also - section 3.8 for important information about MAC and padding - verification. The receiver's sequence counter is then compared with - the received SeqNum value; the message is discarded if they differ. - The receiver's sequence counter is incremented if they match. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 20] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -3 Security Considerations - - General SASL security considerations apply to this mechanism. - "stringprep" and Unicode security considerations also apply. - - Detailed discussion of other DIGEST-MD5 specific security issues is - below. - -3.1 Authentication of Clients using Digest Authentication - - Digest Authentication does not provide a strong authentication - mechanism, when compared to public key based mechanisms, for example. - However, since it prevents chosen plaintext attacks, it is stronger - than (e.g.) CRAM-MD5, which has been proposed for use with ACAP [RFC - 2244], POP and IMAP [RFC 2195]. It is intended to replace the much - weaker and even more dangerous use of plaintext passwords; however, - since it is still a password based mechanism it avoids some of the - potential deployabilty issues with public-key, OTP or similar - mechanisms. - - Digest Authentication offers no confidentiality protection beyond - protecting the actual password. All of the rest of the challenge and - response are available to an eavesdropper, including the user's name - and authentication realm. - -3.2 Comparison of Digest with Plaintext Passwords - - The greatest threat to the type of transactions for which these - protocols are used is network snooping. This kind of transaction - might involve, for example, online access to a mail service whose use - is restricted to paying subscribers. With plaintext password - authentication an eavesdropper can obtain the password of the user. - This not only permits him to access anything in the database, but, - often worse, will permit access to anything else the user protects - with the same password. - -3.3 Replay Attacks - - Replay attacks are defeated if the client or the server chooses a - fresh nonce for each authentication, as this specification requires. - - As a security precaution, the server, when verifying a response from - the client, must use the original server nonce ("nonce") it sent, not - the one returned by the client in the response, as it might have been - modified by an attacker. - - To prevent some redirection attacks it is recommended that the server - verifies that the "serv-type" part of the "digest-uri" matches the - - - -Leach & Newman Expires: December 2003 [Page 21] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - service name and that the hostname/IP address belongs to the server. - -3.4 Online dictionary attacks - - If the attacker can eavesdrop, then it can test any overheard - nonce/response pairs against a (potentially very large) list of - common words. Such a list is usually much smaller than the total - number of possible passwords. The cost of computing the response for - each password on the list is paid once for each challenge. - - The server can mitigate this attack by not allowing users to select - passwords that are in a dictionary. - -3.5 Offline dictionary attacks - - If the attacker can choose the challenge, then it can precompute the - possible responses to that challenge for a list of common words. Such - a list is usually much smaller than the total number of possible - passwords. The cost of computing the response for each password on - the list is paid just once. - - Offline dictionary attacks are defeated if the client chooses a fresh - nonce for each authentication, as this specification requires. - -3.6 Man in the Middle - - Digest authentication is vulnerable to "man in the middle" (MITM) - attacks. Clearly, a MITM would present all the problems of - eavesdropping. But it also offers some additional opportunities to - the attacker. - - A possible man-in-the-middle attack would be to substitute a weaker - qop scheme for the one(s) sent by the server; the server will not be - able to detect this attack. For this reason, the client should always - use the strongest scheme that it understands from the choices - offered, and should never choose a scheme that does not meet its - minimum requirements. - - A man-in-the-middle attack may also make the client and the server - that agreed to use confidentiality protection to use different (and - possibly weaker) cipher's. This is because the chosen cipher is not - used in the shared secret calculation. - -3.7 Chosen plaintext attacks - - A chosen plaintext attack is where a MITM or a malicious server can - arbitrarily choose the challenge that the client will use to compute - the response. The ability to choose the challenge is known to make - - - -Leach & Newman Expires: December 2003 [Page 22] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - cryptanalysis much easier [MD5]. - - However, Digest does not permit the attack to choose the challenge as - long as the client chooses a fresh nonce for each authentication, as - this specification requires. - -3.8 CBC Mode attacks - - The following attack can be launched when the connection uses - Confidentiality protection with ciphers in CBC mode. If bad padding - is treated differently from bad MACs when decrypting a DIGEST-MD5 - buffer of security encoded data, the attacker may be able to launch - Vaudenay's attack on padding. - - An error logfile will suffice to launch the attack if it reveals the - type of error -- even if file permissions prevent the attacker from - actually reading the file (the file length increase cause by the - attack is likely to reveal which of the two errors occured). - - A different approach to distinguish these two error cases and launch - the attack is to examine the timing of error responses: if the MAC - verification is skipped when bad padding has been found, the error - will appear quicker in the case of incorrect block cipher padding - than in the case of an incorrect MAC. - - A countermeasure is to compute a MAC of the plaintext anyway, even if - the usual padding removal step fails because of incorrect padding, to - obtain (nearly) uniform timing. - -3.9 Spoofing by Counterfeit Servers - - If a user can be led to believe that she is connecting to a host - containing information protected by a password she knows, when in - fact she is connecting to a hostile server, then the hostile server - can obtain challenge/response pairs where it was able to partly - choose the challenge. There is no known way that this can be - exploited. - -3.10 Storing passwords - - Digest authentication requires that the authenticating agent (usually - the server) store some data derived from the user's name and password - in a "password file" associated with a given realm. Normally this - might contain pairs consisting of username and H({ username-value, - ":", realm-value, ":", passwd }), which is adequate to compute H(A1) - as described above without directly exposing the user's password. - - The security implications of this are that if this password file is - - - -Leach & Newman Expires: December 2003 [Page 23] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - compromised, then an attacker gains immediate access to documents on - the server using this realm. Unlike, say a standard UNIX password - file, this information need not be decrypted in order to access - documents in the server realm associated with this file. On the other - hand, decryption, or more likely a brute force attack, would be - necessary to obtain the user's password. This is the reason that the - realm is part of the digested data stored in the password file. It - means that if one Digest authentication password file is compromised, - it does not automatically compromise others with the same username - and password (though it does expose them to brute force attack). - - There are two important security consequences of this. First the - password file must be protected as if it contained plaintext - passwords, because for the purpose of accessing documents in its - realm, it effectively does. - - A second consequence of this is that the realm string should be - unique among all realms that any single user is likely to use. In - particular a realm string should include the name of the host doing - the authentication. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 24] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -3.11 Multiple realms - - Use of multiple realms may mean both that compromise of a the - security database for a single realm does not compromise all - security, and that there are more things to protect in order to keep - the whole system secure. - -3.11 Summary - - By modern cryptographic standards Digest Authentication is weak, - compared to (say) public key based mechanisms. But for a large range - of purposes it is valuable as a replacement for plaintext passwords. - Its strength may vary depending on the implementation. - - -4 Example - - This example shows the use of the Digest SASL mechanism with the - IMAP4 AUTHENTICATE command [RFC 3501]. - - In this example, "C:" and "S:" represent a line sent by the client or - server respectively including a CRLF at the end. Linebreaks and - indentation within a "C:" or "S:" are editorial and not part of the - protocol. The password in this example was "secret". Note that the - base64 encoding of the challenges and responses is part of the IMAP4 - AUTHENTICATE command, not part of the Digest specification itself. - - S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9 - C: c CAPABILITY - S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA - UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN - S: c OK Completed - C: a AUTHENTICATE DIGEST-MD5 - S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0 - RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh - cnNldD11dGYtOA== - C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2 - QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw - MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im - ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw - ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg= - S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA== - C: - S: a OK User logged in - --- - - The base64-decoded version of the SASL exchange is: - - - - -Leach & Newman Expires: December 2003 [Page 25] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth", - algorithm=md5-sess,charset=utf-8 - C: charset=utf-8,username="chris",realm="elwood.innosoft.com", - nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk", - digest-uri="imap/elwood.innosoft.com", - response=d388dad90d4bbd760a152321f2143af7,qop=auth - S: rspauth=ea40f60335c427b5527b84dbabcdfffd - - The password in this example was "secret". - - This example shows the use of the Digest SASL mechanism with the - ACAP, using the same notational conventions and password as in the - previous example. Note that ACAP does not base64 encode and uses - fewer round trips that IMAP4. - - S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5" - "DIGEST-MD5" "PLAIN") - C: a AUTHENTICATE "DIGEST-MD5" - S: + {94} - S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth", - algorithm=md5-sess,charset=utf-8 - C: {206} - C: charset=utf-8,username="chris",realm="elwood.innosoft.com", - nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m", - digest-uri="acap/elwood.innosoft.com", - response=6084c6db3fede7352c551284490fd0fc,qop=auth - S: a OK (SASL {40} - S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE - Completed" - --- - - The server uses the values of all the directives, plus knowledge of - the users password (or the hash of the user's name, server's realm - and the user's password) to verify the computations above. If they - check, then the user has authenticated. - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 26] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -5 References - -5.1 Normative references - - [Digest] Franks, J., et al., "HTTP Authentication: Basic and Digest - Access Authentication", RFC 2617, June 1999. - - [ISO-8859] ISO-8859. International Standard--Information Processing-- - 8-bit Single-Byte Coded Graphic Character Sets -- - Part 1: Latin alphabet No. 1, ISO-8859-1:1987. - Part 2: Latin alphabet No. 2, ISO-8859-2, 1987. - Part 3: Latin alphabet No. 3, ISO-8859-3, 1988. - Part 4: Latin alphabet No. 4, ISO-8859-4, 1988. - Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988. - Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987. - Part 7: Latin/Greek alphabet, ISO-8859-7, 1987. - Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988. - Part 9: Latin alphabet No. 5, ISO-8859-9, 1990. - - [RFC 822] Crocker, D., "Standard for The Format of ARPA Internet - Text Messages," STD 11, RFC 822, August 1982. - - [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, - April 1992. - - [RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the - location of services (DNS SRV)", RFC 2052, October 1996. - - [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- - Hashing for Message Authentication", RFC 2104, February - 1997. - - [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC 2222] Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997. - - [Stringprep] Hoffman, P., Blanchet, M., "Preparation of - Internationalized Strings ("stringprep")", RFC 3454, - December 2002. - - [Unicode] The Unicode Consortium, "The Unicode Standard, Version - 3.2.0", defined by: The Unicode Standard, Version 3.0 - (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), - as amended by the Unicode Standard Annex #28: Unicode 3.2 - (http://www.unicode.org/reports/tr28/tr28-3.html). - - - - -Leach & Newman Expires: December 2003 [Page 27] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - [UTF-8] Yergeau, "UTF-8, a transformation format of ISO 10646", RFC - 2279, Janyary 1998. - - [USASCII] US-ASCII. Coded Character Set - 7-Bit American Standard - Code for Information Interchange. Standard ANSI X3.4-1986, - ANSI, 1986. - - [SASLPrep] Zeilenga, K., "SASLprep: Stringprep profile for user names - and passwords", Work in progress, draft-ietf-sasl- - saslprep-XX.txt. - - [RFC 2732] Hinden, R., Carpenter, B., Masinter, L., "Format for - Literal IPv6 Addresses in URL's", RFC 2732, December 1999. - - [RFC 2373] Hinden, R., Deering, S., "IP Version 6 Addressing - Architecture", RFC 2373, July 1998. - - [RFC 2396] Berners-Lee, T., Fielding, R., Masinter, L., "Uniform - Resource Identifiers (URI): Generic Syntax", RFC 2396, - August 1998. - - [FIPS] National Institute of Standards and Technology, "DES Modes of - Operation", http://www.itl.nist.gov/fipspubs/fip81.htm, - December 1980. - - [AES] Daemen, J., Rijmen, V., "The Rijndael Block Cipher", - http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf, - 3rd September 1999. - - -5.2 Informative references - - [RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP - AUTHorize Extension for Simple Challenge/Response", RFC - 2195, September 1997. - - [MD5] Kaliski, B.,Robshaw, M., "Message Authentication with MD5", - CryptoBytes, Sping 1995, RSA Inc, - (http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm) - - [RFC 2078] Linn, J., "Generic Security Service Application Program - Interface, Version 2", RFC 2078, January 1997. - - [RFC 3501] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 3501, March 2003. - - [RFC 2244] Newman, C., Myers, J., "ACAP -- Application Configuration - Access Protocol", RFC 2244, November 1997. - - - -Leach & Newman Expires: December 2003 [Page 28] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - [RFC 2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., - Masinter, L., Leach, P., Berners-Lee, T., "Hypertext - Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999. - - [TLS-CBC] Moeller, B., "Security of CBC Ciphersuites in SSL/TLS: - Problems and Countermeasures", - http://www.openssl.org/~bodo/tls-cbc.txt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 29] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -6 Authors' Addresses - - Paul Leach - Microsoft - 1 Microsoft Way - Redmond, WA 98052, USA - - EMail: paulle@microsoft.com - - - Chris Newman - Sun Microsystems - 1050 Lakes Drive - West Covina, CA 91790, USA - - EMail: Chris.Newman@Sun.COM - - - Alexey Melnikov - Isode - 28 Gloucester Road, - Teddington, Middlesex, TW11 0NU, UK - - Email: mel@isode.com - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 30] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -7 ABNF - - What follows is the definition of the notation as is used in the - HTTP/1.1 specification [RFC 2616] and the HTTP authentication - specification [Digest]; it is reproduced here for ease of reference. - Since it is intended that a single Digest implementation can support - both HTTP and SASL-based protocols, the same notation is used in both - to facilitate comparison and prevention of unwanted differences. - Since it is cut-and-paste from the HTTP specifications, not all - productions may be used in this specification. It is also not quite - legal ABNF; again, the errors were copied from the HTTP - specifications. - -7.1 Augmented BNF - - All of the mechanisms specified in this document are described in - both prose and an augmented Backus-Naur Form (BNF) similar to that - used by RFC 822 [RFC 822]. Implementers will need to be familiar with - the notation in order to understand this specification. - - The augmented BNF includes the following constructs: - - name = definition - The name of a rule is simply the name itself (without any - enclosing "<" and ">") and is separated from its definition by the - equal "=" character. White space is only significant in that - indentation of continuation lines is used to indicate a rule - definition that spans more than one line. Certain basic rules are - in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle - brackets are used within definitions whenever their presence will - facilitate discerning the use of rule names. - - "literal" - Quotation marks surround literal text. Unless stated otherwise, - the text is case-insensitive. - - rule1 | rule2 - Elements separated by a bar ("|") are alternatives, e.g., "yes | - no" will accept yes or no. - - (rule1 rule2) - Elements enclosed in parentheses are treated as a single element. - Thus, "(elem (foo | bar) elem)" allows the token sequences - "elem foo elem" and "elem bar elem". - - *rule - The character "*" preceding an element indicates repetition. The - full form is "*element" indicating at least and at most - - - -Leach & Newman Expires: December 2003 [Page 31] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - occurrences of element. Default values are 0 and infinity so - that "*(element)" allows any number, including zero; "1*element" - requires at least one; and "1*2element" allows one or two. - - [rule] - Square brackets enclose optional elements; "[foo bar]" is - equivalent to "*1(foo bar)". - - N rule - Specific repetition: "(element)" is equivalent to - "*(element)"; that is, exactly occurrences of (element). - Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three - alphabetic characters. - - #rule - A construct "#" is defined, similar to "*", for defining lists of - elements. The full form is "#element" indicating at least - and at most elements, each separated by one or more commas - (",") and OPTIONAL linear white space (LWS). This makes the usual - form of lists very easy; a rule such as - ( *LWS element *( *LWS "," *LWS element )) - can be shown as - 1#element - Wherever this construct is used, null elements are allowed, but do - not contribute to the count of elements present. That is, - "(element), , (element) " is permitted, but counts as only two - elements. Therefore, where at least one element is required, at - least one non-null element MUST be present. Default values are 0 - and infinity so that "#element" allows any number, including zero; - "1#element" requires at least one; and "1#2element" allows one or - two. - - ; comment - A semi-colon, set off some distance to the right of rule text, - starts a comment that continues to the end of line. This is a - simple way of including useful notes in parallel with the - specifications. - - implied *LWS - The grammar described by this specification is word-based. Except - where noted otherwise, linear white space (LWS) can be included - between any two adjacent words (token or quoted-string), and - between adjacent words and separators, without changing the - interpretation of a field. At least one delimiter (LWS and/or - separators) MUST exist between any two tokens (for the definition - of "token" below), since they would otherwise be interpreted as a - single token. - - - - -Leach & Newman Expires: December 2003 [Page 32] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -7.2 Basic Rules - - The following rules are used throughout this specification to - describe basic parsing constructs. The US-ASCII coded character set - is defined by ANSI X3.4-1986 [USASCII]. - - OCTET = - CHAR = - UPALPHA = - LOALPHA = - ALPHA = UPALPHA | LOALPHA - DIGIT = - CTL = - CR = - LF = - SP = - HT = - <"> = - TEXTCHAR = - CRLF = CR LF - - All linear white space, including folding, has the same semantics as - SP. A recipient MAY replace any linear white space with a single SP - before interpreting the field value or forwarding the message - downstream. - - LWS = [CRLF] 1*( SP | HT ) - - The TEXT rule is only used for descriptive field contents and values - that are not intended to be interpreted by the message parser. Words - of TEXT contains characters either from ISO-8859-1 [ISO-8859] - character set or UTF-8 [UTF-8]. - - TEXT = - - A CRLF is allowed in the definition of TEXT only as part of a header - field continuation. It is expected that the folding LWS will be - replaced with a single SP before interpretation of the TEXT value. - - Hexadecimal numeric characters are used in several protocol elements. - - HEX = "A" | "B" | "C" | "D" | "E" | "F" - | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT - - Many HTTP/1.1 header field values consist of words separated by LWS - or special characters. These special characters MUST be in a quoted - - - -Leach & Newman Expires: December 2003 [Page 33] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - string to be used within a parameter value. - - token = 1*TOKENCHAR - separators = "(" | ")" | "<" | ">" | "@" - | "," | ";" | ":" | "\" | <"> - | "/" | "[" | "]" | "?" | "=" - | "{" | "}" | SP | HT - TOKENCHAR = - - A string of text is parsed as a single word if it is quoted using - double-quote marks. - - quoted-string = ( <"> qdstr-val <"> ) - qdstr-val = *( qdtext | quoted-pair ) - qdtext = and "\"> - - Note that LWS is NOT implicit between the double-quote marks (<">) - surrounding a qdstr-val and the qdstr-val; any LWS will be considered - part of the qdstr-val. This is also the case for quotation marks - surrounding any other construct. - - The backslash character ("\") MAY be used as a single-character - quoting mechanism only within qdstr-val and comment constructs. - - quoted-pair = "\" CHAR - - The value of this construct is CHAR. Note that an effect of this rule - is that backslash itself MUST be quoted. - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 34] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -8 Sample Code - - The sample implementation in [Digest] also applies to DIGEST-MD5. - - The following code implements the conversion from UTF-8 to 8859-1 if - necessary. - - /* if the string is entirely in the 8859-1 subset of UTF-8, then - * translate to 8859-1 prior to MD5 - */ - void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base, - int len) - { - const unsigned char *scan, *end; - unsigned char cbuf; - - end = base + len; - for (scan = base; scan < end; ++scan) { - if (*scan > 0xC3) break; /* abort if outside 8859-1 */ - if (*scan >= 0xC0 && *scan <= 0xC3) { - if (++scan == end || *scan < 0x80 || *scan > 0xBF) - break; - } - } - /* if we found a character outside 8859-1, don't alter string - */ - if (scan < end) { - MD5Update(ctx, base, len); - return; - } - - /* convert to 8859-1 prior to applying hash - */ - do { - for (scan = base; scan < end && *scan < 0xC0; ++scan) - ; - if (scan != base) MD5Update(ctx, base, scan - base); - if (scan + 1 >= end) break; - cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f); - MD5Update(ctx, &cbuf, 1); - base = scan + 2; - } while (base < end); - } - - - - - - - - -Leach & Newman Expires: December 2003 [Page 35] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -9 Interoperability considerations - - 9.1 Implementing DES cipher in CBC mode - - Several cryptographic libraries (Ebones, OpenSSL) provide a convenience - function des_cbc_encrypt for implementing DES cipher in CBC mode. - There is a documented bug in this function: the function doesn't update - IV before returning. If an implementation uses this function to implement - DES cipher in CBC mode, it MUST update IV by copying the last 8 bytes of - the des_cbc_encrypt's output to the IV buffer. - Note that the function des_ede2_cbc_encrypt that may be used to implement - 3DES (in "two keys mode") in CBC mode works as expected. - - Care must be taken when configuring the DES keys for most DES - libraries. This specification gives 56 bits for the DES key (or 112 - bits for the 3DES key); libraries generally expect the key to be given - in a 64 bit (128 bit for 3DES) form. - - The following C function can be used to convert a 56 bit DES key into a - form acceptable for the libraries. The low order bit in each byte - would contain parity information and will be corrected by the library. - - /* slide the first 7 bytes of 'inbuf' into the high seven bits of the - first 8 bytes of 'keybuf'. 'keybuf' better be 8 bytes long or longer. */ - void slidebits(unsigned char *keybuf, unsigned char *inbuf) - { - keybuf[0] = inbuf[0]; - keybuf[1] = (inbuf[0]<<7) | (inbuf[1]>>1); - keybuf[2] = (inbuf[1]<<6) | (inbuf[2]>>2); - keybuf[3] = (inbuf[2]<<5) | (inbuf[3]>>3); - keybuf[4] = (inbuf[3]<<4) | (inbuf[4]>>4); - keybuf[5] = (inbuf[4]<<3) | (inbuf[5]>>5); - keybuf[6] = (inbuf[5]<<2) | (inbuf[6]>>6); - keybuf[7] = (inbuf[6]<<1); - } - -10 Acknowledgements - - The following people had substantial contributions to the development - and/or refinement of this document: - - Lawrence Greenfield John Gardiner Myers Simon Josefsson RL Bob Morgan - Jeff Hodges Claus Assmann Tony Hansen Sam Hartman - - as well as other members of the SASL mailing list. - - The text used is section 3.8 was taken from [TLS-CBC] by Bodo - Moeller. - - - -Leach & Newman Expires: December 2003 [Page 36] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -11 Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 37] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - -Appendix A: Changes from 2831 - - 1). Fixed various typos in formulas. - - 2). Dropped DES as mandatory to implement cipher (3DES is mandatory - to implement). - - 3). Tighten ABNF. Fixed some bugs. - - 4). Clarified nc-value verification and which side is aborting - exchange. - - 5). Added text saying that for interoperability - username/password/realm MUST be prepared using the "SASLPrep" profile - [SASLPrep] of the "stringprep" algorithm [StringPrep]. - - 6). Clarified that unquoted version of the username, etc. used in A1 - calculation. - - 7). Various cleanup to References section. Split all references to - Normative and Informative. - - 8). Added minimal and maximal limits on maxbuf. Clarified how to - calculate max sender size. - - 9). Change ABNF for host to allow for IPv6 addresses. ABNF now - references RFC 2373 and RFC 2396. - - 10). Added DES cipher interoperability section. - - 11). Added man-in-the-middle considerations for ciphers. - - 12). Clarified how sequence counters are modified. - - 13). Addition warnings about preventing reply/redirection attacks. - - 14). Specified that "charset" directive affects "realm" and doesn't - affect - "authzid". - - 15). Removed text that described that "authzid" is in Unicode in - Normalization - Form KC, encoded as UTF-8. - - 16). Clarified that rc4 state is not reset between two sent/received - buffers - of encoded data. - - - - -Leach & Newman Expires: December 2003 [Page 38] - - - - - -INTERNET DRAFT Digest SASL Mechanism June 2003 - - - 17). Clarified that for DES/3DES the IV for the next buffer of - encoded data is - the last 8 bytes of the ciphertext. - - 18). Clarified how "maximal sender size" is calculated. - - 19). Prohibit an empty authzid. - - 20). Added AES cipher defined in "AES Ciphersuite for DIGEST-MD5 SASL - mechanism" - document (expired draft-ietf-sasl-digest-aes-00.txt). - - 21). Minor text clarifications. - -Appendix B: Open Issues/ToDo List - - 1). The latest revision prohibits escaped characters in nonce/cnonce. - This is different - from HTTP Digest. Any objections? - - 2). Do we need/want a new stringprep profile for "realm"? - - 3). What to do about CBC mode attack that affects TLS document and - DIGEST-MD5 as well? - - One of the proposals is to drop DES/3DES ciphers and define a new one - (e.g. AES) in such a way that is not susceptible to this kind of - attack. - - AES cipher has to be fixed to prevent this attack. - - 4). Add reference to CBC mode attack: - - This problem is described in LASEC Memo "Password Interception in a - SSL/TLS Channel" by Brice Canvel, published 2003-02-20: - http://lasecwww.epfl.ch/memo_ssl.shtml - - 5). Normative vs. Informative references must be carefully rechecked. - - - - - - - - - - - - - -Leach & Newman Expires: December 2003 [Page 39] - - diff --git a/doc/draft-ietf-sasl-saslprep-xx.txt b/doc/draft-ietf-sasl-saslprep-xx.txt deleted file mode 100644 index fd0f6b86..00000000 --- a/doc/draft-ietf-sasl-saslprep-xx.txt +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - -INTERNET-DRAFT Kurt D. Zeilenga -Intended Category: Standards Track OpenLDAP Foundation -Expires in six months 27 October 2003 - - - SASLprep: Stringprep profile for user names and passwords - - - -Status of Memo - - This document is an Internet-Draft and is in full conformance with all - provisions of Section 10 of RFC 2026. - - This document is intended to be, after appropriate review and - revision, submitted to the RFC Editor as a Standards Track document. - Distribution of this memo is unlimited. Technical discussion of this - document will take place on the IETF SASL mailing list - . Please send editorial comments directly to the - document editor . - - Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as ``work in progress.'' - - The list of current Internet-Drafts can be accessed at - . The list of - Internet-Draft Shadow Directories can be accessed at - . - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - Please see the Full Copyright section near the end of this document - for more information. - - -Abstract - - This document describes how to prepare Unicode strings representing - user names and passwords for comparison. The document defines the - "SASLprep" profile of the "stringprep" algorithm to be used for both - user names and passwords. This profile is intended to be used by - Simple Authentication and Security Layer (SASL) mechanisms (such as - PLAIN, CRAM-MD5, and DIGEST-MD5) as well as other protocols exchanging - - - -Zeilenga SASLprep [Page 1] - -INTERNET-DRAFT draft-ietf-sasl-saslprep-04.txt 27 October 2003 - - - user names and/or passwords. - - -1. Introduction - - The use of simple user names and passwords in authentication and - authorization is pervasive on the Internet. To increase the - likelihood that user name and password input and comparison work in - ways that make sense for typical users throughout the world, this - document defines rules for preparing internationalized user names and - passwords for comparison. For simplicity and implementation ease, a - single algorithm is defined for both user names and passwords. - - This document defines the "SASLprep" profile of the "stringprep" - algorithm [StringPrep]. - - The profile is designed for use in Simple Authentication and Security - Layer ([SASL]) mechanisms such as [PLAIN]. It may be applicable - elsewhere simple user names and passwords are used. This profile is - not intended to be used for arbitrary text. This profile is also not - intended to be used to prepare identity strings which are not simple - user names (e.g., e-mail addresses, domain names, distinguished - names). - - -2. The SASLprep profile - - This section defines the "SASLprep" profile. This profile is intended - to be used to prepare strings representing simple user names and - passwords. - - This profile uses Unicode 3.2, as defined in [StringPrep, A.1]. - - Character names in this document use the notation for code points and - names from the Unicode Standard [Unicode]. For example, the letter - "a" may be represented as either or . - In the lists of mappings and the prohibited characters, the "U+" is - left off to make the lists easier to read. The comments for character - ranges are shown in square brackets (such as "[CONTROL CHARACTERS]") - and do not come from the standard. - - Note: a glossary of terms used in Unicode can be found in [Glossary]. - Information on the Unicode character encoding model can be found in - [CharModel]. - - -2.1. Mapping - - - - -Zeilenga SASLprep [Page 2] - -INTERNET-DRAFT draft-ietf-sasl-saslprep-04.txt 27 October 2003 - - - This profile specifies: - - non-ASCII space characters [StringPrep, C.1.2] be mapped to SPACE - (U+0020), and - - - the "commonly mapped to nothing" characters [StringPrep, B.1] be - mapped to nothing. - - - -2.2. Normalization - - This profile specifies using Unicode normalization form KC, as - described in Section 4 of [StringPrep]. - - -2.3. Prohibited Output - - This profile specifies the following characters: - - - Non-ASCII space characters [StringPrep, C.1.2], - - ASCII control characters [StringPrep, C.2.1], - - Non-ASCII control characters [StringPrep, C.2.2], - - Private Use [StringPrep, C.3], - - Non-character code points [StringPrep, C.4], - - Surrogate code points [StringPrep, C.5], - - Inappropriate for plain text [StringPrep, C.6], - - Inappropriate for canonical representation [StringPrep, C.7], - - Change display properties or are deprecated [StringPrep, C.8], and - - Tagging characters [StringPrep, C.9]. - - are prohibited output. - - -2.4. Bidirectional characters - - This profile specifies checking bidirectional strings as described in - [StringPrep, Section 6]. - - -2.5. Unassigned Code Points - - This profile specifies [StringPrep, A.1] table as its list of - unassigned code points. - - -3. Security Considerations - - This profile is intended to used to prepare simple user names and - - - -Zeilenga SASLprep [Page 3] - -INTERNET-DRAFT draft-ietf-sasl-saslprep-04.txt 27 October 2003 - - - passwords for comparison. It is not intended to be used for to - prepare identities which are not simple user names (e.g., - distinguished names and domain names). Nor is the profile intended to - be used for simple user names which require different handling. - Protocols (or applications of those protocols) which have - application-specific identity forms and/or comparison algorithms - should use mechanisms specifically designed for these forms and - algorithms. - - User names and passwords should be protected from eavesdropping. - - General "stringprep" and Unicode security considerations apply. Both - are discussed in [StringPrep]. - - -4. IANA Considerations - - This document details the "SASLprep" profile of [StringPrep] protocol. - Upon Standards Action the profile should be registered in the - stringprep profile registry. - - Name of this profile: SASLprep - RFC in which the profile is defined: This RFC - Indicator whether or not this is the newest version of the - profile: This is the first version of the SASPprep profile. - - -5. Acknowledgment - - This document borrows text from "Preparation of Internationalized - Strings ('stringprep')" and "Nameprep: A Stringprep Profile for - Internationalized Domain Names", both by Paul Hoffman and Marc - Blanchet. - - This document is a product of the IETF SASL WG. - - -6. Normative References - - [StringPrep] Hoffman P. and M. Blanchet, "Preparation of - Internationalized Strings ('stringprep')", - draft-hoffman-rfc3454bis-xx.txt, a work in progress. - - [SASL] Melnikov, A. (Editor), "Simple Authentication and - Security Layer (SASL)", - draft-ietf-sasl-rfc2222bis-xx.txt, a work in progress. - - [Unicode] The Unicode Consortium, "The Unicode Standard, Version - - - -Zeilenga SASLprep [Page 4] - -INTERNET-DRAFT draft-ietf-sasl-saslprep-04.txt 27 October 2003 - - - 3.2.0" is defined by "The Unicode Standard, Version 3.0" - (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), - as amended by the "Unicode Standard Annex #27: Unicode - 3.1" (http://www.unicode.org/reports/tr27/) and by the - "Unicode Standard Annex #28: Unicode 3.2" - (http://www.unicode.org/reports/tr28/). - - -7. Informative References - - [Glossary] The Unicode Consortium, "Unicode Glossary", - . - - [CharModel] Whistler, K. and M. Davis, "Unicode Technical Report - #17, Character Encoding Model", UTR17, - , August - 2000. - - [CRAM-MD5] Nerenberg, L., "The CRAM-MD5 SASL Mechanism", - draft-ietf-sasl-crammd5-xx.txt, a work in progress. - - [DIGEST-MD5] Leach, P., C. Newman, and A. Melnikov, "Using Digest - Authentication as a SASL Mechanism", - draft-ietf-sasl-rfc2831bis-xx.txt, a work in progress. - - [PLAIN] Zeilenga, K. (Editor), "The Plain SASL Mechanism", - draft-ietf-sasl-plain-xx.txt, a work in progress. - - -8. Editor's Address - - Kurt Zeilenga - OpenLDAP Foundation - - Email: kurt@OpenLDAP.org - - -Intellectual Property Rights - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to pertain - to the implementation or use of the technology described in this - document or the extent to which any license under such rights might or - might not be available; neither does it represent that it has made any - effort to identify any such rights. Information on the IETF's - procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - - - -Zeilenga SASLprep [Page 5] - -INTERNET-DRAFT draft-ietf-sasl-saslprep-04.txt 27 October 2003 - - - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such proprietary - rights by implementors or users of this specification can be obtained - from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - -Full Copyright - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be followed, - or as required to translate it into languages other than English. - - - - - - - - - - - - - - - - - - - - - - - -Zeilenga SASLprep [Page 6] - diff --git a/doc/draft-murchison-sasl-login-xx.txt b/doc/draft-murchison-sasl-login-xx.txt deleted file mode 100644 index e6ffc297..00000000 --- a/doc/draft-murchison-sasl-login-xx.txt +++ /dev/null @@ -1,396 +0,0 @@ - - - - - - - -Internet Draft K. Murchison -Category: Informational M. Crispin -Expires: March 2, 2004 28 August 2003 - - - The LOGIN SASL Mechanism - - - - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Copyright Notice - - Copyright (C) The Internet Society 2003. All Rights Reserved. - - -Abstract - - This document documents the obsolete clear-text user/password Simple - Authentication and Security Layer (SASL) mechanism called the LOGIN - mechanism. The LOGIN mechanism was intended to be used, in - combination with data confidentiality services provided by a lower - layer, in protocols which lack a simple password authentication - command. - - - - - - -Expires: March 2, 2004 Murchison [Page 1] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - - -Conventions Used in the Document - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [KEYWORDS]. - - -1. Background and Intended Usage - - This document documents the obsolete LOGIN Simple Authentication and - Security Layer ([SASL]) mechanism which was in use in protocols with - no clear-text login command (e.g., [SMTP-AUTH]). - - Note: The LOGIN SASL mechanism is obsoleted in favor of the PLAIN - SASL mechanism ([PLAIN]). The LOGIN mechanism is documented here - only for the purpose of backwards compatibility with legacy software. - Clients SHOULD implement the PLAIN SASL mechanism and use it whenever - offered by a server. The LOGIN SASL mechanism SHOULD NOT be used by - a client when other plaintext mechanisms are offered by a server. - - The name associated with this mechanism is "LOGIN". - - The LOGIN SASL mechanism does not provide a security layer. This - mechanism MUST NOT be used without adequate security protection as - the mechanism affords no integrity nor confidentiality protection - itself. The LOGIN SASL mechanism MUST NOT be advertised or used in - any configuration that prohibits the PLAIN mechanism or plaintext - LOGIN (or USER/PASS) command that sends passwords in the clear. - - -2. LOGIN SASL Mechanism - - The authorization identity is the same string as the "username" in - the traditional (non-SASL) LOGIN or USER commands; the authorization - authenticator is the same string as the traditional "password". The - authentication identity is the same as the authorization identity in - this mechanism. - - Only US-ASCII printable characters SHOULD be used in the username and - password to permit maximal interoperability. If non-US-ASCII - characters are used in a username, they MUST use UTF-8. Passwords - MAY contain arbitrary binary data excluding NUL, CR and LF - characters. However, if a password is supplied to the client as a - sequence of characters (e.g., a password dialog box), those - characters MUST be encoded as UTF-8. - - The username MUST be less than 64 characters in length. - - - -Expires: March 2, 2004 Murchison [Page 2] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - -2.1. Client side of authentication protocol exchange - - The client expects the server to issue a challenge. The client then - responds with the authorization identity. The client then expects - the server to issue a second challenge. The client then responds - with the authorization authenticator. The contents of both - challenges SHOULD be ignored. - - -2.2. Server side of authentication protocol exchange - - The server issues the string "User Name" in challenge, and receives a - client response. This response is recorded as the authorization - identity. The server then issues the string "Password" in challenge, - and receives a client response. This response is recorded as the - authorization authenticator. The server must verify that the - authorization authenticator permits login as the authorization - identity. - - Note: There is at least one widely deployed client which requires - that the challenge strings transmitted by the server be "Username:" - and "Password:" respectively. For this reason, server - implementations MAY send these challenge strings instead of those - listed above. - - -2.3. Example - - This example shows the use of the LOGIN mechanism with the SMTP AUTH - command [SMTP-AUTH] under the protection of SMTP STARTTLS [SMTP-TLS]. - The user name is "tim" and the password is "tanstaaftanstaaf". The - base64 encoding of the challenges and responses is part of the SMTP - AUTH command, not part of the LOGIN specification itself. "C:" and - "S:" indicate lines sent by the client and server respectively. - - S: 220 smtp.example.com ESMTP server ready - C: EHLO test.example.com - S: 250-smtp.example.com - S: 250-STARTTLS - S: 250 AUTH CRAM-MD5 - C: STARTTLS - S: 220 Ready to start TLS - - C: EHLO test.example.com - S: 250-smtp.example.com - S: 250 AUTH LOGIN CRAM-MD5 - C: AUTH LOGIN - S: 334 VXNlciBOYW1lAA== - - - -Expires: March 2, 2004 Murchison [Page 3] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - - C: dGlt - S: 334 UGFzc3dvcmQA - C: dGFuc3RhYWZ0YW5zdGFhZg== - S: 235 Authentication successful. - - -3. - Security Considerations - - The LOGIN mechanism relies upon an underlying encryption layer or - other secure channel for security. When used without an encryption - layer or secure channel, it is vulnerable to a common network - eavesdropping attack. Therefore the LOGIN mechanism MUST NOT be - advertised or used in any configuration that prohibits the PLAIN - mechanism or a plaintext LOGIN (or USER/PASS) command that sends - passwords in the clear. - - -4. - IANA Considerations - - The registration for the LOGIN SASL mechanism follows: - - SASL mechanism name: LOGIN - Security Considerations: See section 3 of this memo - Published specification: this memo - Person & email address to contact for futher information: - See section 7 of this memo - Intended usage: OBSOLETE - Owner/Change controller: See section 7 of this memo - - -5. - References - - -5.1. - Normative References - - - [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", Harvard University, RFC 2119, March 1997. - - - [SASL] Melnikov, A., Ed., "Simple Authentication and Security Layer - (SASL)", Isode, draft-ietf-sasl-rfc2222bis-xx.txt, Work In - Progress. - - - - -Expires: March 2, 2004 Murchison [Page 4] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - -5.2. Informative References - - - [PLAIN] Zeilenga, Kurt D., Ed., "The Plain SASL Mechanism", - OpenLDAP Foundation, draft-ietf-sasl-plain-xx.txt, Work In - Progress. - - - [SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication", - Netscape Communications, RFC 2554, March 1999. - - - [SMTP-TLS] Hoffman, P., "SMTP Service Extension for Secure SMTP - over Transport Layer Security", Internet Mail Consortium, RFC - 3207, February 2002. - - - -6. Acknowledgments - - Thanks to Rob Siemborski for his input and feedback on this document. - - -7. - Author's Address - - Kenneth Murchison - Oceana Matrix Ltd. - 21 Princeton Place - Orchard Park, NY 14127 - - Phone: (716) 662-8973 - - EMail: ken@oceana.com - - - - - Mark R. Crispin - Networks and Distributed Computing - University of Washington - 4545 15th Avenue NE - Seattle, WA 98105-4527 - - Phone: (206) 543-5762 - - EMail: MRC@CAC.Washington.EDU - - - - -Expires: March 2, 2004 Murchison [Page 5] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - -8. - Intellectual Property Considerations - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it has - made any effort to identify any such rights. Information on the - IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such proprietary - rights by implementors or users of this specification can be obtained - from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Expires: March 2, 2004 Murchison [Page 6] - -Internet Draft LOGIN SASL Mechanism August 28, 2004 - - -9. - Full Copyright Statement - - Copyright (C) The Internet Society 2003. All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be followed, - or as required to translate it into languages other than English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Expires: March 2, 2004 Murchison [Page 7] - diff --git a/doc/draft-newman-sasl-c-api-xx.txt b/doc/draft-newman-sasl-c-api-xx.txt deleted file mode 100644 index 1ad37dd2..00000000 --- a/doc/draft-newman-sasl-c-api-xx.txt +++ /dev/null @@ -1,1681 +0,0 @@ - - - - - - -Network Working Group C. Newman -Internet Draft: SASL C API Innosoft -Document: draft-newman-sasl-c-api-01.txt A. Melnikov - MessagingDirect - February 2003 - Expires in six months - - - Simple Authentication and Security Layer C API - - -Status of this memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026 [RFC2026]. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - -Abstract - - Almost every protocol needs authentication. However, there does not - exist an authentication mechanism suitable for all organizations, nor - is it likely that a small fixed set of authentication mechanisms will - remain suitable. SASL [SASL] provides the on-the-wire framework for - authentication (and a security layer) which separates the design of - authentication mechanisms from the protocols in which they're used. - - The SASL protocol model suggests a software architecture where - application protocols call a generic API to authenticate which in - turn calls a generic plug-in interface for extensible authentication - modules. This memo documents the API used in one implementation of - this architecture in the hope that it will be useful to others. An - associated memo documenting the plug-in interface is forthcoming. - -1. Conventions Used in this Memo - - - -Newman et al. Expires: August 2003 FORMFEED[Page 1] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [KEYWORDS]. - - This assumes familiarity the SASL [SASL] specification. - - 1.1. Concepts - - The following concepts are necessary to understand this - specification. - -realm - A realm is a name (usually a domain-style name) associated with a - set of users on a server. One realm may span multiple servers. - Alternatively, a single server may have multiple realms. Thus - there may be multiple users with the username "chris" on the same - server, each in a different realm. Some authentication mechanisms - have a special field for the realm (e.g., DIGEST-MD5). For other - mechanisms, a realm can be specified by the client by using the - syntax "username@realm" in the username field. - -service - A service is a basic function provided by one or more protocols. - The GSSAPI service name [GSSAPI] registry is available at: - - - - This registry is used by SASL and the SASL API. The service name - may be used for service-specific passwords for advanced users, or - advanced authentication mechanisms may restrict the services a - given server may offer. - - -virtual domain - When a single server has multiple realms and there is a DNS server - entry for each realm pointing to the same server IP address, then - those realms are "virtual domains". Virtual domains are extremely - popular with web hosting services and are becoming more popular - with POP mail services. The key to providing virtual domain sup- - port is that the client informs the server of the domain it - believes it is speaking to either through a special protocol ele- - ment or by using a username of the form "user@realm". - - -2. Overview of the SASL C API - - The SASL API is initialized once at process startup. The - sasl_server_init() and sasl_client_init() functions provide basic - - - -Newman et al. Expires: August 2003 FORMFEED[Page 2] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - initialization. - - When a network connection occurs where SASL will be used, a connec- - tion-specific context is created for authentication with - sasl_client_new() or sasl_server_new(). The API implementation must - support multi-threaded servers and clients by creating the connection - context in a thread-safe fashion permitting multiple contexts in a - given process. At this point, the caller may adjust security policy - for the context, and the set of mechanisms which are enabled is - determined by requirements from the configuration or by the caller. - - The server end of the API may request a list of enabled authentica- - tion mechanisms either in general or for a specific user. The client - may either select a single mechanism or request a list from the - server (if the SASL profile for the protocol in question supports - that) and pass the list to the API for automated mechanism selection - by configured policy. - - The SASL exchange begins with sasl_client_start() which determines if - one of the desired mechanisms is available on the client and may gen- - erate an initial client response. The client then sends the appro- - priate protocol message to initiate the SASL exchange that the server - passes to sasl_server_start(). - - The SASL exchange continues with calls to sasl_client_step() and - sasl_server_step(), until the server indicates completion or the - client cancels the exchange. - - The server queries the user name and user realm resulting from the - exchange with the sasl_getprop() routine. - - A connection context is released with sasl_dispose() and process ter- - mination is indicated with sasl_done(). - - There are a number of utility functions and customization functions - available in the API for additional services. - - Note, that all functions described in this documen can be implemented - as macroses, so an application using this API MUST NOT assume that - they are functions. - - An application or library trying to use SASL API described in this - document must include "sasl.h" include file. - -3. Basic SASL API Routines - - This section describes the types and functions likely to be used by - every caller of the SASL API. - - - -Newman et al. Expires: August 2003 FORMFEED[Page 3] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - 3.1. Basic SASL API Data Structures - - The following datastructures are basic to the SASL API. - - 3.1.1. sasl_callback_t - - The sasl_callback_t structure is used for the caller of the SASL API - to provide services to both the core SASL API and SASL plug-ins via - callbacks. The most important callback is the "getopt" callback (see - section 3.3.3) which is used to retrieve security policy option set- - tings from the caller's preferences. - - typedef struct sasl_callback { - unsigned long id; - int (*proc)(); - void *context; - } sasl_callback_t; - - id is the label for the callback (XXX IANA registry needed), proc is - a function pointer whose exact type is determined by the id, and con- - text is a context variable which will be passed to the callback (usu- - ally as the first argument). The last callback in the list of call- - backs is indicated with an id of SASL_CB_LIST_END. - - If proc is NULL, this means that the application doesn't want to - specify a corresponding callback, but would provide the necessary - data via interaction. See also section 3.1.4. - - 3.1.2. sasl_secret_t - - The sasl_secret_t structure is used to hold text or binary passwords - for the client API. - - typedef struct sasl_secret { - unsigned long len; - unsigned char data[1]; - } sasl_secret_t; - - The len field holds the length of the password, while the data field - holds the actual data. The structure is variable sized: enough space - must be reserved after the data field to hold the desired password. - An additional that binary passwords are permitted to contain '\0' - characters. - - 3.1.3. sasl_conn_t - - The sasl_conn_t data type is an opaque data type which reflects the - SASL context for a single server connection. Only one SASL API call - - - -Newman et al. Expires: August 2003 FORMFEED[Page 4] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - using a given sasl_conn_t as an argument may be active at a time. - However, each sasl_conn_t is independent and thus the SASL API may be - used in a true multi-processor multi-threaded environment. - - 3.1.4. sasl_interact_t - - The sasl_interact_t structure is used by sasl_client_start and - sasl_client_step to request certain information from the application, - when the application did not provide corresponding callbacks. For - example, an application may choose to present a single dialog to the - user in order to collect all required information interactively. - - typedef struct sasl_interact { - unsigned long id; - const char *challenge; - const char *prompt; - const char *defresult; - const void *result; - unsigned len; - } sasl_interact_t; - - The id field holds the value of the callback ID. The prompt field - contains a string that should be presented to the user. If non-NULL, - challenge is a NUL-terminated string that will allow the user to pre- - sent a specific credential when prompted. This is different from the - prompt in that the prompt is more like a label for a text box (for - example "Response:" while challenge is a string that tells the user - what specifically is required by the response (for example, an OTP - challenge string). The defresult field contains a default value, if - any. Upon return from sasl_client_* the "result" field points to the - defresult. The client must present the information in the challenge - and the prompt to the user and store the result and its length in the - result and the len fields respectively. - - For example, SASL_CB_PASS interaction may contain the following - information: - id - SASL_CB_PASS - challenge - NULL - prompt - "Password:" - defresult - NULL (no default). - - 3.2. Basic SASL API Client Routines - - This section discusses the functions likely to be used by every - client caller of the SASL API. - - 3.2.1. sasl_client_init function - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 5] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_callback_t *callbacks - -Results: - SASL_OK -- Success - SASL_NOMEM -- Not enough memory - SASL_BADVERS -- Mechanism version mismatch - SASL_BADPARAM -- Error in config file - - This function initializes the client routines for the SASL API. - - The callbacks argument is the default list of callbacks (see sec- - tion 3.1.1 for definition of sasl_callback_t structure) and SHOULD - include the sasl_getopt_t callback (see section 3.3.3). The call- - backs may be NULL. On success, SASL_OK is returned, and on fail- - ure a SASL C API error code such as the ones listed above is - returned. This function may be called a second time to change the - default callbacks used for new connections, but the first call - must be made in a single-threaded environment. The data refer- - enced by the sasl_callback_t structure must persist until - sasl_done() is called. - - 3.2.2. sasl_client_new function - -Arguments: - const char *service, - const char *server_name, - const char *iplocalport, - const char *ipremoteport, - const sasl_callback_t *prompt_supp, - unsigned int flags, - sasl_conn_t **pconn - -Results: - SASL_OK -- Success - SASL_NOTINIT -- SASL API not initialized - SASL_NOMECH -- No mechanisms available - SASL_NOMEM -- Not enough memory - - This function creates a client connection context variable. As - long as each thread uses its own connection context, the SASL C - API is thread-safe. - - The service argument is an IANA registered GSSAPI service element - as defined in section 1.1. It MUST NOT be NULL. - - The server_name is the host name or IP address of the server to - which the client is connecting. NULL may be used for server_name, - - - -Newman et al. Expires: August 2003 FORMFEED[Page 6] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - but may result in advanced mechanisms such as Kerberos being - unavailable. - - The iplocalport is the string with the client IPv4/IPv6 address, - followed by ":" and than by port number. An IPv6 address must be - enclosed in "[" and "]". NULL may be used for iplocalport, but may - result in mechanisms requiring IP address being unavailable. - - The ipremoteport is the string with the server IPv4/IPv6 address, - followed by ":" and than by port number. An IPv6 address must be - enclosed in "[" and "]". NULL may be used for ipremoteport, but - may result in mechanisms requiring IP address being unavailable. - - User input to the SASL C API may be provided in two ways: either - by supplying callbacks (prompt_supp) to this function, or by using - an interaction model with the sasl_client_start/sasl_client_step - functions. Callbacks are more convenient to obtain information - programmatically, such as pulling authentication information - directly from a configuration file. Interactions are more conve- - nient if one wants to get all the data in parallel, for example by - displaying a single dialog box instead of a separate popup for - authentication name, authorization, password, etc. - - The prompt_supp is a list of supported user prompting callbacks - discussed in the section 3.1.1. The prompt_supp argument MAY be - NULL, which means that interactions (i.e. prompt_need parameter to - sasl_client_start (see 3.2.3) and sasl_client_step (see 3.2.4)) - are used instead of callbacks. If prompt_supp is NULL, the - prompt_need argument to sasl_client_start (see 3.2.3) and - sasl_client_step (see 3.2.4) MUST NOT be NULL. - - The flags argument represents client-supported security flags. - The only values currently supported are SASL_SECURITY_LAYER to - indicate the client supports the SASL security layer, or 0 to - indicate it doesn't. - - The pconn argument is set to point to the newly created connection - context. The sasl_conn_t type is opaque to the calling applica- - tion. - - 3.2.3. sasl_client_start function - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 7] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn, - const char *mechlist, - sasl_interact_t **prompt_need, - const char **clientout, - unsigned int *clientoutlen, - const char **mech - -Results: - SASL_NOTINIT -- SASL API not initialized - SASL_BADPARAM -- conn or mechlist is NULL - SASL_NOMECH -- No matching mechanisms available - SASL_NOMEM -- Not enough memory - SASL_INTERACT -- User interaction needed to continue - (see prompt_need description below) - SASL_OK -- Success - - This selects an authentication mechanism to use and optionally - generates an initial client response. - - The conn argument is the connection context from sasl_client_new. - - The mechlist argument is a '\0' terminated string containing one - or more SASL mechanism names. All characters in the string that - are not permitted in a SASL mechanism name [SASL] are ignored - except for the purposes of delimiting mechanism names (this per- - mits passing direct results from many protocol capability lists - unparsed). Unknown mechanism names are ignored (although - SASL_NOMECH is returned if no known mechanisms are found). Mecha- - nisms are tried in an implementation-dependent order. Implementa- - tions SHOULD try to use the most secure mechanism possible, within - the constraints specified by the application (e.g. SSF value). - - For applications which support interactions, the prompt_need argu- - ment should initially point to a NULL pointer. If the selected - mechanism needs information from the user (for example, username - or password), then prompt_need will be set to point to an array of - sasl_interact_t structures (terminated by an entry with id equal - to SASL_CB_LIST_END), and sasl_client_start will return - SASL_INTERACT. After that the client must fill in the requested - information and call this function again with the same parameters. - - Applications that do not support interactions MUST pass NULL for - prompt_need. - - The clientout and clientoutlen parameters are set to the initial - client response, if any. If a protocol's SASL profile uses base64 - encoding, this represents the data prior to the encoding (see - - - -Newman et al. Expires: August 2003 FORMFEED[Page 8] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - sasl_encode64). If a protocol's SASL profile doesn't include an - optional initial client response, then these may be NULL and 0 - respectively. The memory used by clientout is interally managed by - the SASL API and may be overwritten on the next call to - sasl_client_step or a call to sasl_dispose. - - The mech argument is set to point to a '\0' terminated string - specifying the mechanism actually selected using all uppercase - letters. It may be NULL if the client does not care which mecha- - nism was selected from mechlist. - - If sasl_client_start is called a second time using the same con- - nection context, it will discard any cached information (e.g., the - username and password) and restart the exchange from the begin- - ning. <> - - 3.2.4. sasl_client_step function - -Arguments: - sasl_conn_t *conn, - const char *serverin, - unsigned int serverinlen, - sasl_interact_t **prompt_need, - const char **clientout, - unsigned int *clientoutlen - -Results: - SASL_NOTINIT -- SASL API not initialized - SASL_NOMECH -- sasl_client_start not called - SASL_BADPROT -- server protocol incorrect/cancelled - SASL_BADSERV -- server failed mutual auth - SASL_INTERACT -- user interaction needed - SASL_OK -- success - - This routine performs one step in an authentication sequence. - - The conn argument must be a connection context created by - sasl_client_new and used in a previous call to sasl_client_start. - - The serverin and serverinlen parameters hold the SASL octet string - received from the server. Note that for those SASL profiles which - base64 encode the exchange, this is the result after the removal - of the base64 encoding (see the sasl_decode64 routine below). The - serverin MUST have a terminating NUL character not counted by - serverinlen - - The prompt_need argument is the same as for sasl_client_start. - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 9] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - The clientout and clientoutlen parameters hold the SASL octet - string to encode (if necessary) and send to the server. - - 3.3. Basic SASL API Callback Routines - - This section describes the basic callback functions needed for a - simple client implementation. See the definition of sasl_call- - back_t in section 3.1.1 for a description of the basic callback - structure. - - 3.3.1. sasl_getsimple_t - -Arguments: - void *context, - int id, - const char **result, - unsigned *len - -Results: - SASL_OK -- success - SASL_FAIL -- error - - This callback is used by the SASL API to request a simple constant - string from the application. This is used with id SASL_CB_USER - for the username, SASL_CB_AUTHNAME for the authentication name (if - different), and SASL_CB_LANGUAGE for a comma separated list of RFC - 1766 language tags. - - The context is the context variable from the sasl_callback_t - structure, the id is the id from the sasl_callback_t structure, - and the callback is expected to set the result to a constant - string and the len to the length of that string. The result and - len parameters are never NULL. - - 3.3.2. sasl_getsecret_t - -Arguments: - sasl_conn_t *conn, - void *context, - int id, - sasl_secret_t **psecret - -Results: - SASL_OK -- success - SASL_FAIL -- error - - This callback is expected to create, prompt or locate a secret and - set it in the connection context with sasl_setprop. The conn - - - -Newman et al. Expires: August 2003 FORMFEED[Page 10] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - argument is the connection context, the context and id parameters - are from the sasl_callback_t structure. The id SASL_CB_PASS is - used to request a clear text password. - - 3.3.3. sasl_getopt_t - -Arguments: - void *context, - const char *plugin_name, - const char *option, - const char **result, - unsigned int *len - -Results: - SASL_OK -- success - SASL_FAIL -- error - - This callback is used by the SASL API to read options from the - application. This allows a SASL configuration to be encapsulated - in the caller's configuration system. Configuration items may be - mechanism-specific and are arbitrary strings. If the application - does not provide a sasl_getopt_t callback, then the API MAY obtain - configuration information from other sources, for example from a - config file. - - The context is the context variable from the sasl_callback_t - structure, the plugin_name is the name of plugin (or NULL), the - option is the option name, and the callback is expected to set the - result to a string valid till next call to sasl_getopt_t in the - same thread and the len to the length of that string. The result - and len parameters are never NULL. If the name of plugin is NULL, - a general SASL option is requested, otherwise a plugin specific - version. - - 3.4. Basic SASL C API Utility Routines - - This section describes utility functions provided as part of the - SASL API which may be used both by clients and servers. - - 3.4.1. sasl_decode64 function - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 11] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - const char *in, - unsigned int inlen, - char *out, - unsigned int outmax, - unsigned int *outlen - -Results: - SASL_BUFOVER -- output buffer too small - SASL_BADPROT -- invalid base64 string - SASL_OK -- successful decode - - This utility routine converts a base64 string of length inlen - pointed by in into an octet string. It is useful for SASL profiles - which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] pro- - files. The output is copied to the buffer specified by the out - parameter. It is NUL terminated and the length of the output is - placed in the outlen parameter if outlen is non-NULL. The lenght - doesn't include the terminating NUL character. - - When the size of the output buffer, as specified by outmax, is too - small, the function returns SASL_BUFOVER error code and the - required length is stored in the outlen parameter if it is not - NULL. - - The function may also return SASL_BADPROT error code when it - encounters an invalid base64 character. - - 3.4.2. sasl_encode64 function - -Arguments: - const char *in, - unsigned int inlen, - char *out, - unsigned int outmax, - unsigned int *outlen - -Results: - SASL_BUFOVER -- output buffer too small - SASL_OK -- successful decode - - This utility routine converts an octet string of length inlen - pointed by in into a base64 string. It is useful for SASL profiles - which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] pro- - files. - - The output is copied to the buffer specified by the out parameter. - It is NUL terminated and the length of the output is placed in the - - - -Newman et al. Expires: August 2003 FORMFEED[Page 12] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - outlen parameter if outlen is non-NULL. The lenght doesn't include - the terminating NUL character. - - When the size of the output buffer, as specified by outmax, is too - small, the function returns SASL_BUFOVER error code and the - required length is stored in the outlen parameter if it is not - NULL. - - 3.4.3. sasl_errstring function - -Arguments: - int saslerr, - const char *langlist, - const char **outlang - -Results: - const char * - - This converts a SASL error number into a constant string. The - second argument MAY be NULL for the default language, or a comma- - separated list of RFC 1766 language tags. The final parameter is - set to the RFC 1766 language tag of the string returned which will - be "i-default" if no matching language is found. The strings are - UTF-8. This requires no context so it may be used for the result - of an sasl_*_init or sasl_*_new result code. - - 3.4.4. sasl_errdetail function - -Arguments: - sasl_conn_t *conn - -Results: - const char * - - This converts the last SASL error code that occured on a connec- - tion to UTF8 string. It uses the SASL_CB_LANGUAGE callback (see - section 3.3.1) to determine the language to use. It may return - more detailed information than sasl_errstring does. - - 3.4.5. sasl_seterror function - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 13] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn - unsigned flags, - const char *fmt, - ... - -Results: - none - - This function sets sets the error string which will be returned by - sasl_errdetail. It uses syslog()-style formatting (i.e. printf- - style with %m as the string form of an errno error). - - Messages should be sensitive to the current language setting. If - there is no SASL_CB_LANGUAGE callback for the connection, text - MUST be in US-ASCII. Otherwise UTF-8 is used and use of RFC 2482 - for mixed-language text is encouraged. - - <> - - This function may be used by server callbacks. - - If conn is NULL, the function does nothing. - - 3.4.6. sasl_erasebuffer function - -Arguments: - char *buf, - unsigned len - -Results: - none - - This function fills the buffer buf of the lenght len with '\0' - characters. The function may be used to clear from memory sensi- - tive informations, like passwords. - - 3.5. Basic SASL C API Server Routines - - This section describes the basic routines for a server implementa- - tion of a SASL profile. - - 3.5.1. sasl_server_init function - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 14] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - const sasl_callback_t *callbacks, - const char *appname - -Results: - SASL_BADPARAM -- error in config file - SASL_NOMEM -- out of memory - SASL_BADVERS -- Plug-in version mismatch - SASL_OK -- success - - This function initializes the server routines for the SASL C API. - - The callbacks argument is the default list of callbacks (see sec- - tion 3.1.1 for definition of sasl_callback_t structure) and SHOULD - include the sasl_getopt_t callback (see section 3.3.3). The call- - backs may be NULL. The appname argument is the name of the calling - application and may be used by server plug-ins for logging. On - success, SASL_OK is returned, and on failure a SASL C API error - code is returned. This function may be called a second time to - change the default callbacks, but the first call must be made in a - single-threaded environment. The data referenced by the - sasl_callback_t structure must persist until sasl_done() is - called. - - appname specifies the application name. SASL API may use it, for - example, for logging or to read an application specific configura- - tion. A library must pass NULL as appname. appname can be also be - set with sasl_setprop function, and can be queried with sasl_get- - prop. <> - - 3.5.2. sasl_server_new function - - - - - - - - - - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 15] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - const char *service, - const char *serverFQDN, - const char *user_realm, - const char *iplocalport, - const char *ipremoteport, - const sasl_callback_t *callbacks, - unsigned int flags, - sasl_conn_t **pconn - -Results: - SASL_OK -- success - SASL_NOTINIT -- SASL API not initialized - SASL_BADPARAM -- Invalid parameter supplied - SASL_NOMECH -- No mechanisms available - SASL_NOMEM -- Not enough memory - - This function creates a server connection context variable. As - long as each thread uses its own connection context, the SASL C - API is thread-safe. - - The service argument is an IANA registered GSSAPI service element - as defined in section 1.1. It MUST NOT be NULL. - - The serverFQDN is the fully qualified name of the server. It MUST - NOT be NULL. - - The user_realm specifies the default realm. A realm defines a set - of users on the system for systems which support multiple user - communities ("realms"). If user_realm is NULL, the value of - serverFQDN is used as the default realm. - - The iplocalport is the string with the server IPv4/IPv6 address, - followed by ":" and than by port number. An IPv6 address must be - enclosed in "[" and "]". NULL may be used for iplocalport, but may - result in mechanisms requiring IP address being unavailable. - - The ipremoteport is the string with the client IPv4/IPv6 address, - followed by ":" and than by port number. An IPv6 address must be - enclosed in "[" and "]". NULL may be used for ipremoteport, but - may result in mechanisms requiring IP address being unavailable. - - The callbacks argument is a set of server callbacks which may - include a connection-specific sasl_getopt_t and/or an authoriza- - tion routine. - - The flags argument represents server-supported security flags. The - only values currently supported are SASL_SECURITY_LAYER to - - - -Newman et al. Expires: August 2003 FORMFEED[Page 16] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - indicate the server supports the SASL security layer, or 0 to - indicate it doesn't. - - The pconn argument is set to point to the newly created connection - context. - - 3.5.3. sasl_server_start function - -Arguments: - sasl_conn_t *conn, - const char *mech, - const char *clientin, - insigned int clientinlen, - const char **serverout, - unsigned int *serveroutlen - -Results: - SASL_CONTINUE -- Another authentication step required - SASL_OK -- Authentication Complete - SASL_NOTINIT -- SASL API not initialized - SASL_BADPARAM -- Invalid parameter supplied - SASL_BADPROT -- Client protocol error - SASL_NOMECH -- Mechanism not supported - SASL_NOVERIFY -- User exists, but no verifier exists for - the mechanism - SASL_TRANS -- A password transition is needed to use mechanism - - This begins an authentication exchange and is called after the - client sends the initial authentication command. The mech argu- - ment is the mechanism name the client is requesting. If the - client includes an optional initial-response, it is passed in the - clientin and clientinlen fields. Otherwise NULL and 0 are passed - for those arguments. The serverout and serveroutlen are filled in - with the server response, if any. If SASL_CONTINUE is returned, - the server will need to wait for another client message and call - sasl_server_step. If SASL_OK is returned, the authentication is - completed successfully, although server out data may be supplied. - - 3.5.4. sasl_server_step function - - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 17] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn, - const char *clientin, - insigned int clientinlen, - const char **serverout, - unsigned int *serveroutlen - -Results: - SASL_CONTINUE -- Another authentication step required - SASL_OK -- Authentication Complete - SASL_NOTINIT -- SASL API not initialized - SASL_NOMECH -- sasl_server_start not called - SASL_BADPARAM -- Invalid parameter supplied - SASL_BADPROT -- Client protocol error - SASL_NOVERIFY -- User exists, but no verifier exists for - the mechanism - SASL_TRANS -- A password transition is needed to use mechanism - - This routine performs one step in an authentication sequence. - - The conn argument must be a connection context created by - sasl_server_new and used in a previous call to sasl_server_start. - - The clientin and clientinlen parameters hold the SASL octet string - received from the client. Note that for those SASL profiles which - base64 encode the exchange, this is the result after the removal - of the base64 encoding (see the sasl_decode64 routine). The cli- - entin MUST have a terminating NUL character not counted by - serverinlen. - - The serverout and serveroutlen parameters hold the SASL octet - string to encode (if necessary) and send to the client. If - SASL_CONTINUE is returned, the server will need to wait for - another client message and call sasl_server_step. If SASL_OK is - returned, the authentication is completed successfully, although - server out data may be supplied. - - 3.6. Common SASL API Routines - - This section describes the routines that are common to both - clients and servers. - - 3.6.1. sasl_listmech function - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 18] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn, - const char *user, - const char *prefix, - const char *sep, - const char *suffix, - char **result, - unsigned int *plen, - unsigned *pcount - -Results: - SASL_OK -- Success - SASL_NOMEM -- Not enough memory - SASL_NOMECH -- No enabled mechanisms - - This returns a list of enabled SASL mechanisms in a NUL-terminated - string. The list is constructed by placing the prefix string at - the beginning, placing the sep string between any pair of mecha- - nisms and placing the suffix string at the end. - - When calling this function plen and pcount MAY be NULL. - - This function returns the list of client side SASL mechanisms, if - the conn was created by sasl_client_new and the list of server - side mechanisms, if the conn was created by sasl_server_new. The - list returned by this function must persist till a next call to - sasl_free_listmech or sasl_listmech. - - 3.6.2. sasl_free_listmech function - -Arguments: - sasl_conn_t *conn, - char **result - -Results: - none - - This disposes of the result string returned by sasl_listmech. - - 3.6.3. sasl_setprop function - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 19] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn, - int propnum, - const void *value - -Results: - SASL_OK -- property set - SASL_BADPARAM -- invalid propnum or value - SASL_NOMEM -- not enough memory to perform operation - - This sets a property in a connection context. Commonly used prop- - erties with their descriptions are listed below: - - SASL_SSF_EXTERNAL - - Security layer strength factor (SSF) -- an unsigned integer usable - by the caller to specify approximate security layer strength - desired. It roughly corresponds to the effective key length for - encryption, e.g. - 0 = no protection - 1 = integrity protection only >1 = key lenght of the cipher - - SASL_SSF_EXTERNAL property denotes SSF of the external security - layer (e.g. provided by TLS). The value parameter points to - sasl_ssf_t, that is described as follows: - - typedef unsigned sasl_ssf_t; - - - - SASL_SEC_PROPS - - The value parameter for SASL_SEC_PROPS points to sasl_secu- - rity_properties_t structure defined below. A particular implemen- - tation may extend it with additional fields. - - typedef struct sasl_security_properties - { - sasl_ssf_t min_ssf; - sasl_ssf_t max_ssf; - - unsigned maxbufsize; - - /* bitfield for attacks to protect against */ - unsigned security_flags; - } sasl_security_properties_t; - - The min_ssf and the max_ssf define the minimal and the maximal - - - -Newman et al. Expires: August 2003 FORMFEED[Page 20] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - acceptable SSF. - - The maxbufsize specifies the biggest buffer size that the - client/server is able to decode. 0 means that security layer is - not supported. - - The security_flags is a bitmask of the various security flags - described below: - - SASL_SEC_NOPLAINTEXT -- don't permit mechanisms susceptible to simple - passive attack (e.g., PLAIN, LOGIN) - SASL_SEC_NOACTIVE -- protection from active (non-dictionary) attacks - during authentication exchange. - Authenticates server. - SASL_SEC_NODICTIONARY -- don't permit mechanisms susceptible to passive - dictionary attack - SASL_SEC_FORWARD_SECRECY -- require forward secrecy between sessions - (breaking one won't help break next) - SASL_SEC_NOANONYMOUS -- don't permit mechanisms that allow anonymous login - SASL_SEC_PASS_CREDENTIALS -- require mechanisms which pass client - credentials, and allow mechanisms which can pass - credentials to do so - SASL_SEC_MUTUAL_AUTH -- require mechanisms which provide mutual - authentication - - SASL_AUTH_EXTERNAL - - The value parameter for SASL_AUTH_EXTERNAL property points to the - external authentication ID as provided by external authentication - method, e.g. TLS, PPP or IPSec. - - 3.6.4. sasl_getprop function - -Arguments: - sasl_conn_t *conn, - int propnum, - const void **pvalue - -Results: - SASL_OK -- Success - SASL_NOTDONE -- Authentication exchange must complete prior to - retrieving this attribute - SASL_BADPARAM -- bad property number - - This requests a pointer to a constant property available through - the SASL API. The most common use by servers is to get the - SASL_USERNAME property which returns the authorization identity - (user to login as) from the SASL mechanism as a UTF-8 string in - - - -Newman et al. Expires: August 2003 FORMFEED[Page 21] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - the pvalue parameter. Additional properties are listed in section - 6. - - 3.6.5. sasl_dispose function - -Arguments: - sasl_conn_t **pconn - -Results: - none - - This function disposes of the connection state created with - sasl_client_new or sasl_server_new, and sets the pointer to NULL. - If the pconn is already NULL the function does nothing. - - 3.6.6. sasl_done function - -Arguments: - none - -Results: - none - - A SASL application that is finished with the SASL API must call - this function. This function frees any memory allocated by the - SASL library or any other library state. After this call most of - the SASL API function will again return the SASL_NOTINIT error - code. - - There must be a call to sasl_done for every successful call to - sasl_server_init or sasl_client_init made. Only the final - sasl_done does the actual cleanup; the preceding calls simply - decrement an internal reference count. - - Connection states MUST be disposed of with sasl_dispose before - calling this function. - -4. SASL Security Layer Routines - - This section describes the routines need to support a security - layer. - - 4.1. sasl_encode function - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 22] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_conn_t *conn, - const char *input, - unsigned int inputlen, - const char **output, - unsigned int *outputlen - -Results: - SASL_OK -- Success (returns input if no layer negotiated) - SASL_NOTDONE -- Security layer negotiation not finished - SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF property - - This function encodes a block of data for transmission using secu- - rity layer (if any). The output and outputlen are filled in with - the encoded data and its length respectively. If there is no secu- - rity layer the input buffer is returned in the output. Otherwise, - the output is only valid until a next call to sasl_encode or - sasl_dispose. - - 4.1. sasl_decode function - -Arguments: - sasl_conn_t *conn, - const char *input, - unsigned int inputlen, - const char **output, - unsigned int *outputlen - -Results: - SASL_OK -- Success (returns input if no layer negotiated) - SASL_NOTDONE -- Security layer negotiation not finished - SASL_BADMAC -- Bad message integrity check - - This function decodes a block of data received using security - layer (if any). The output and outputlen are filled in with the - decoded data and its length respectively. If there is no security - layer the input buffer is returned in the output. Otherwise, the - output is only valid until a next call to sasl_decode or sasl_dis- - pose. - -5. Advanced SASL API Routines - - This section describes the less frequently used functions avail- - able in the SASL API. - - 5.1. Additional Initialization Routines - - 5.1.1. sasl_set_mutex function - - - -Newman et al. Expires: August 2003 FORMFEED[Page 23] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_mutex_alloc_t *mutex_alloc, - sasl_mutex_lock_t *mutex_lock, - sasl_mutex_unlock_t *mutex_unlock, - sasl_mutex_free_t *mutex_free - -Results: - None - - The sasl_set_mutex call sets the callbacks which the SASL API and - plug-ins will use whenever exclusive access to a process shared - resource is needed. A single-threaded client or server need not - call this. The types are designed to be compatible with the LDAP - API [LDAP-API]: - - typedef void *sasl_mutex_alloc_t(void); - - On success, this returns a pointer to an allocated and initialized - mutex structure. On failure, it returns NULL. - - typedef int sasl_mutex_lock_t(void *mutex); - - This will block the current thread until it is possible to get an - exclusive lock on a mutex allocated by the mutex_alloc callback. - On success it returns 0, on failure due to deadlock or bad parame- - ter, it returns -1. - - typedef int sasl_mutex_unlock_t(void *mutex); - - This releases a lock on a mutex allocated by the mutex_alloc call- - back. On success it returns 0, on failure due to an already - unlocked mutex, or bad parameter, it returns -1. - - typedef void sasl_mutex_free_t(void *mutex); - - This disposes of a mutex allocated by mutex_alloc. - - 5.1.2. sasl_set_alloc function - - - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 24] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -Arguments: - sasl_malloc_t *malloc, - sasl_calloc_t *calloc, - sasl_realloc_t *realloc, - sasl_free_t *free - -Results: - None - - This sets the memory allocation functions which the SASL API will - use. The SASL API will use its own routines (usually the standard - C library) if these are not set. - - typedef void *sasl_malloc_t(unsigned long mem_size); - - This allocates memory mem_size bytes of memory. The memory is not - initialized to any particular value. It returns NULL on a fail- - ure, or when mem_size is 0. - - typedef void *sasl_calloc_t(unsigned long elem_size, - unsigned long num_elem); - - This allocates elem_size * num_elem bytes of memory. The memory - is initialized to 0. It returns NULL on a failure or when either - elem_size and/or num_elem is 0. - - typedef void *sasl_realloc_t(void *mem_ptr, unsigned long - new_size); - - This changes the size of a memory block previously allocated by - malloc or calloc, and returns a pointer to the new location (which - may be different from mem_ptr). If mem_ptr is NULL, it is identi- - cal to the malloc function. - - It returns NULL on a failure or when new_size is 0. On failure the - original block is unchanged. When new_size is 0 the function works - as the free function. - - typedef void sasl_free_t(void *mem_ptr); - - This releases the memory in mem_ptr that was allocated by the mal- - loc or the calloc or resized by the realloc. If mem_ptr is NULL, - the function does nothing and returns immediately. The contents of - the memory may be altered by this call. - -6. Additional Properties - - <> - - - -Newman et al. Expires: August 2003 FORMFEED[Page 25] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - SASL_SSF -- security layer security strength factor, - if 0, call to sasl_encode, sasl_decode unnecessary - SASL_MAXOUTBUF -- security layer max output buf unsigned - SASL_DEFUSERREALM -- default realm passed to sasl_server_new or set with - sasl_setprop - SASL_GETOPTCTX -- context for getopt callback - SASL_CALLBACK -- current callback function list - SASL_IPLOCALPORT -- iplocalport string passed to sasl_server_new/ - sasl_client_new - SASL_IPREMOTEPORT -- ipremoteport string passed to sasl_server_new/ - sasl_client_new - SASL_SERVICE -- service passed to sasl_*_new - SASL_SERVERFQDN -- serverFQDN passed to sasl_*_new - SASL_AUTHSOURCE -- name of the active plugin, if any - SASL_MECHNAME -- active SASL mechanism name, if any - SASL_AUTHUSER -- authentication/admin user (authorization id?) - -7. References - - [IMAP4] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, University of Washington, December 1996. - - [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, Harvard University, March 1997. - - [POP3] Myers, J., Rose, M., "Post Office Protocol - Version 3", - RFC 1939, Carnegie Mellon, Dover Beach Consulting, Inc., May 1996. - - [POP-AUTH] Myers, "POP3 AUTHentication command", RFC 1734, - Carnegie Mellon, December 1994. - - [SASL] Myers, "Simple Authentication and Security Layer (SASL)", - RFC 2222, Netscape Communications, October 1997. - - [GSSAPI] - -8. Acknowledgements - - The editor would like to thank Rob Siemborski and Ken Murchison - for providing useful feedback and suggestions. - -9. Author's and Editor's Addresses - - - Author: - - Chris Newman - Innosoft International, Inc. - - - -Newman et al. Expires: August 2003 FORMFEED[Page 26] - - - - - -INTERNET DRAFT SASL C API February 2003 - - - 1050 Lakes Drive - West Covina, CA 91790 USA - - Email: chris.newman@innosoft.com - - - Editor: - - Alexey Melnikov - ACI WorldWide/MessagingDirect - 59 Clarendon Road - Watford, Hertfordshire, WD17 1FQ, UK - - Email: mel@messagingdirect.com - - -10. Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this doc- - ument itself may not be modified in any way, such as by removing the - copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of develop- - ing Internet standards in which case the procedures for copyrights - defined in the Internet Standards process must be followed, or as - required to translate it into languages other than English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MER- - CHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 27] - - - - - -INTERNET DRAFT SASL C API February 2003 - - -A. Appendix A -- Design Goals - - The design goals of the SASL C API are as follows: - - -o To be simple and practical to use. - -o To provide related utility services in addition to core SASL func- - tionality. - -o To be reasonably extensible. - -o To be suitable for use in a multi-threaded server or client. - -o To avoid dependancies on a specific memory allocation system, thread - package or network model. - -o To be an independent service rather than a new layer. - - -B. SASL API Index - -<> - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Newman et al. Expires: August 2003 FORMFEED[Page 28] - - - diff --git a/doc/draft-newman-sasl-passdss-xx.txt b/doc/draft-newman-sasl-passdss-xx.txt deleted file mode 100644 index 4aa7cb81..00000000 --- a/doc/draft-newman-sasl-passdss-xx.txt +++ /dev/null @@ -1,1122 +0,0 @@ - - - - - - -Network Working Group C. Newman -Internet Draft: PASSDSS-3DES-1 SASL Mechanism Innosoft -Document: draft-newman-sasl-passdss-01.txt March 1998 - Expires in six months - - - DSS Secured Password Authentication Mechanism - - -Status of this memo - - This document is an Internet-Draft. Internet-Drafts are working - documents of the Internet Engineering Task Force (IETF), its areas, - and its working groups. Note that other groups may also distribute - working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - To view the entire list of current Internet-Drafts, please check - the "1id-abstracts.txt" listing contained in the Internet-Drafts - Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net - (Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East - Coast), or ftp.isi.edu (US West Coast). - - -Abstract - - Some system administrators are faced with a choice between - deploying a new authentication infrastructure or sending - unencrypted passwords in the clear over the Internet. Deploying a - new authentication infrastructure often involves modifying - operating system services or keeping parallel authentication - databases up to date and is thus unacceptable to many - administrators. - - Solutions which encrypt the entire session are often crippled with - weak keys (due to government restrictions) which are unsuitable for - passwords. In addition, such solutions often reduce performance of - the entire session to an unacceptable level. This specification - defines a SASL [SASL] mechanism which is compatible with existing - password-based authentication databases and does not require a - security layer for the remainder of the session. - - [NOTE: Public discussion of this mechanism may take place on the - - - -Newman [Page 1] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - ietf-sasl@imc.org mailing list with a subscription address of - ietf-sasl-request@imc.org. Private comments may be sent to the - author]. - -1. How to Read This Document - - This document is intended primarily for a programmer. If - successful, it should be possible for a competent programmer to - write a client implementation using this specification, the SASL - [SASL] specification, an understanding of how to generate random - numbers [RANDOM], a description or implementation of the DES and - SHA1 [SHA1] algorithms and a multi-precision integer math library. - A cryptographic library or a copy of "Applied Cryptography" - [SCHNEIER] or similar reference is helpful for any implementation - and necessary for server DSS key generation. - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [KEYWORDS]. - -1.1. Data Types Used in this Document - - A list of data types used in this document follows. Note that the - majority of this section is copied from the secure shell - specification [SSH-ARCH]. - - octet A basic 8-bit unit of data. - - uint32 A 32-bit unsigned integer. Stored as four octets in - network byte order (also known as big endian or most - significant byte [MSB] first). For example, the decimal - value 699921578 (hexadecimal 29b7f4aa) is represented with - the hexadecimal octet sequence 29 b7 f4 aa. - - string A string is a length-prefixed octet string. The length is - represented as a uint32 with the data immediately - following. A length of 0 indicates an empty string. The - string MAY contain NUL or 8-bit octets. When used to - represent textual strings, the characters are interpreted - in UTF-8 [UTF-8]. Other character encoding schemes MUST - NOT be used. - - mpint Represents multiple precision integers in two's complement - format, stored as a string, most significant octet first. - Negative numbers have one in the most significant bit of - the first octet of the string data. If the most significant - bit would be set for a positive number, the number MUST be - preceded by a zero byte. Unnecessary leading zero or 255 - - - -Newman [Page 2] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - bytes MUST NOT be included. The value zero MUST be stored - as a string with zero bytes of data. - - By convention, a number that is used in modular - computations in the field of integers mod n SHOULD be - represented in the range 0 <= x < n. - - Examples: - - value (hex) representation (hex) - ----------------------------------------------------------- - 0 00 00 00 00 - 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7 - 80 00 00 00 02 00 80 - -1234 00 00 00 02 ed cc - -deadbeef 00 00 00 05 ff 21 52 41 11 - -1.2. Glossary - - This section includes some acronyms used in this document. - - DES The U.S. Government Data Encryption Standard is a symmetric - encryption algorithm introduced in 1975 which uses a 56 bit - key. The algorithm is documented in [SCHNEIER]. - - DSA The U.S. Government Digital Signature Algorithm standard. A - public key signature algorithm available for unrestricted use - without a license. - - DSS The U.S. Government Digital Signature Standard [DSS] which - employs the DSA algorithm. - - HMAC A hash-based message authentication code [HMAC] summarized in - Appendix A.4. Test cases are available in [HMAC-TEST]. - - SHA The Secure Hash Algorithm (version 1) which is part of the DSS - standard. - - triple-DES - Use of the DES algorithm three times in an encrypt-decrypt- - encrypt mode with three independent keys as described in - appendix A.3. - -2. Overview - - This section includes a brief discussion of design goals, intended - use and an overview for this SASL mechanism. An overview of some - of the algorithms used is in Appendix A. - - - -Newman [Page 3] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - -2.1. Design Goals - - The ideal authentication mechanism would be simple, fast, fully - secure, freely distributable without restrictions and backwards - compatible with deployed back-end authentication databases. - Unfortunately, it is not possible to achieve all these goals so - priorities and tradeoffs are necessary. This mechanism has - compatibility with deployed back-end authentication databases and - protection from passive and active attacks on the underlying - connection as primary design goals. Simplicity and unrestricted - binary distribution are secondary design goals. - - Backwards compatibility is achieved by using plain-text - passphrases. Protection from passive and active attacks is - achieved by using public and symmetric key technology to encrypt - the passphrase and optionally protect the remainder of the session. - Some simplicity is achieved by avoiding complicated public key - certification issues and formats as well as making the SASL session - security layer and certification by the client optional. - Unrestricted binary distribution is hopefully achieved by using - unencumbered algorithms and making the SASL privacy layer optional. - -2.2. Intended Use - - This is intended as a plug-and-play mechanism for services layered - on top of deployed passphrase-based back-end authentication - databases. When no security layer is implemented it can be added - to a SASL-based protocol without modifying or substituting network - read and write APIs. When the optional session privacy protection - is omitted, the author speculates that it may be possible to make a - binary implementation which would be exportable from the United - States. - - For cases where simplicity, speed or unrestricted source code - distribution is more desirable than backwards compatibility or - security, a mechanism such as CRAM-MD5 [CRAM-MD5] or SCRAM [SCRAM] - is preferred. - - The optional SASL integrity and privacy protection is provided as a - simple alternative to full service security layers such as TLS - [TLS] or Secure Shell [SSH-ARCH]. However, there are many - advantages to full service security layers such as compression, - faster symmetric cipher options, and the ability to leverage other - public key infrastructures. An implementation which supports TLS - may have no incentive to support SASL security layers at all. The - complexity verses functionality tradeoff is significant enough that - these mechanisms do not compete. - - - - -Newman [Page 4] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - -2.3. Mechanism Overview - - The PASSDSS-3DES-1 mechanism uses three components to perform a - secure authentication against a legacy passphrase database. - - In order to protect against active attacks, a DSS public key in a - format compatible with Secure Shell [SSH-TRANS] is used to - authenticate the server to the client. The client is presumed to - have the server's public key or a SHA-1 hash thereof stored locally - in a secure database. If the client is willing to risk exposure to - active attacks, it may skip the public key certification step - altogether or do a one-time initialization of its local database, - perhaps with user interaction. - - In addition to the DSS public key, a Diffie-Hellman key exchange is - used to generate a key for encrypting the passphrase. The - "PASSDSS-3DES-1" variant of this mechanism uses the same fixed - Diffie-Hellman group used by Secure Shell's diffie-hellman-group1- - sha1 key exchange [SSH-TRANS]. If more groups are necessary, they - will be assigned to mechanism variants "PASSDSS-3DES-2" and so - forth. - - Finally, the triple-DES algorithm is used to encrypt the client's - passphrase and send it to the server. - -2.4. Message Format Overview - - This section provides a quick overview of the format of the - messages. The formal definition of the syntax for these messages - is in section 6. A detailed discussion of their implementation on - clients and servers is in sections 3 and 4 respectively. - - First message from client to server: - string azname ; the user name to login as, may be empty if - same as authentication name - string authname ; the authentication name - mpint X ; Diffie-Hellman parameter X - - The challenge from server to client is as follows: - uint32 pklength ; length of SSH-style DSA server public key - string "ssh-dss" ; constant string "ssh-dss" (lower case) - mpint p ; DSA public key parameters - mpint q - mpint g - mpint y - mpint Y ; Diffie-Hellman parameter Y - OCTET ssecmask ; SASL security layers offered - 3 OCTET sbuflen ; maximum server security layer block size - - - -Newman [Page 5] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - uint32 siglength ; length of SSH-style dss signature - string "ssh-dss" ; constant string "ssh-dss" (lower case) - mpint r ; DSA signature parameters - mpint s - - The client then sends the following message encrypted with - triple-DES: - OCTET csecmask ; SASL security layer selection - 3 OCTET cbuflen ; maximum client block size - string passphrase ; the user's passphrase - 20 OCTET cli-hmac ; a client HMAC-SHA-1 signature - -3. Client Implementation of PASSDSS-3DES-1 - - This section includes a step-by-step guide for client implementors. - Although section 6 contains the formal definition of the syntax and - is the authoritative reference in case of errors here, this section - should be sufficient to build a correct implementation. - - The SASL mechanism name is "PASSDSS-3DES-1". - - The value of n used for the Diffie-Hellman exchange is as follows - (represented as an unsigned hexadecimal integer): - - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 - FFFFFFFF FFFFFFFF. - - When represented as an "mpint", this would have a prefix of - "0000008100." The value of g is 2. This group was taken from the - ISAKMP/Oakley specification, and was originally generated by - Richard Schroeppel at the University of Arizona. Properties of - this prime are described in [Orm96]. - - The client begins by doing the following: - - (A) Generate the Diffie-Hellman private value "x". This should be - less than (n - 1)/2. The number of bits of entropy to use in "x" - is an important decision, as shorter lengths will be less secure - and longer lengths will noticeably reduce performance. At the time - this was written, 192 bits of entropy [RANDOM] is probably - sufficient. For more information on this topic, see [SHORT-EXP]. - - - - - - -Newman [Page 6] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - (B) Compute the Diffie-Hellman public value "X" as follows. If X - has a value of 0, repeat step (A). - x - X = 2 mod n - - The client then sends the following three pieces of information to - the server: - - (1) An authorization identity represented as a string. When the - empty string is used, this defaults to the authentication identity. - This is used by system administrators or proxy servers to login - with a different user identity. - - (2) An authentication identity represented as a string. This is - the identity whose passphrase will be used. - - (3) The "X" result from step (B) represented as an mpint. - - The server responds by sending a message containing the following - information: - - (4) An "ssh-dss" public key compatible with Secure Shell, including - the 32-bit length prefix in network byte order, the Secure Shell - string "ssh-dss" and mpints for "p", "q", "g" and "y" (see Appendix - A.1). - - (5) The mpint "Y" as defined for the Diffie-Hellman key exchange - (see Appendix A.2). - - (6) A single octet bit mask representing the security layers - available in the same format used by the KERBEROS_V4 mechanism - [SASL]. Bit 0 (value 1) indicates it is permissible to have no - security layer. Bit 1 (value 2) indicates integrity protection is - permissible. Bit 2 (value 4) indicates privacy protection for the - rest of the session is available. The remaining bits are reserved - for future use. - - (7) A three octet unsigned integer in network byte order - representing the maximum cipher-text buffer size the server is able - to receive. If this is less than 32, it indicates that a SASL - security layer is not supported. - - (8) A DSA signature, including a 32-bit length, the Secure Shell - string "ssh-dss" and mpints for "r" and "s". - - The client then does the following: - - (C) Verify that "Y" is between 1 and n - 1 inclusive. If "Y" is - - - -Newman [Page 7] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - outside this range, the client MUST cancel the authentication. - - (D) Verify that the public key from step (4) belongs to the server. - This can be done either with a database of SSH public keys or with - a database of SHA1 hashes of such public keys. If the client does - not have a matching entry for the server or does not have a public - key database, it MAY skip this step although it SHOULD alert the - user that the connection is susceptible to active attacks if it - does so. It MAY also record the public key (or SHA1 hash thereof) - in its database with permission from the user. - - (E) Compute the Diffie-Hellman key K as follows. It may be - necessary to mask timing attacks [TIMING]. - x - K = Y mod n - - (F) Create a buffer containing data from steps (1) through (7) in - order immediately followed by K represented as an mpint. - - (G) Compute the SHA1 hash of the buffer from (F). This produces a - 20 octet result. - - (H) If the public key from step (4) was not certified, this step - MAY be skipped. Otherwise, verify that the DSS signature is a - signature of (G). This computation is done as defined in appendix - A.1 where the output of step (G) represents the message "m" (note - that this results in SHA1 being applied twice). - - (I) Compute the following 20-octet values. K represents the output - of step (E) in mpint format. H represents the output of step (G). - The || symbol represents string concatenation. "A" represents a - single octet containing the US-ASCII value of capital letter A. - cs-encryption-iv = SHA1( K || "A" || H ) - sc-encryption-iv = SHA1( K || "B" || H ) - cs-encryption-key-1 = SHA1( K || "C" || H ) - cs-encryption-key-2 = SHA1( K || cs-encryption-key-1 ) - cs-encryption-key = cs-encryption-key-1 || cs-encryption-key-2 - sc-encryption-key-1 = SHA1( K || "D" || H ) - sc-encryption-key-2 = SHA1( K || sc-encryption-key-1 ) - sc-encryption-key = sc-encryption-key-1 || sc-encryption-key-2 - cs-integrity-key = SHA1( K || "E" || H ) - sc-integrity-key = SHA1( K || "F" || H ) - - (J) Create a buffer beginning with a bit mask for the selected - security layer (it MUST be one offered in 6) followed by three - octets representing the maximum cipher-text buffer size (at least - 32) the client can accept in network byte order. This is followed - by a string containing the passphrase. Note that integrity - - - -Newman [Page 8] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - protection is pointless unless the public key was certified in - step (D) and the signature was verified in step (H). - - (K) Create a buffer containing items (1) through (7) immediately - followed by the first four octets of (J). - - (L) Compute HMAC-SHA-1 with (K) as the data and the cs-integrity- - key from step (I) as the key. This produces a 20 octet result. A - summary of the HMAC-SHA-1 algorithm [HMAC] is in appendix A.4. - - (M) Create a buffer containing (J) followed by (L) followed by an - arbitrary number of zero octets as necessary to reach the block - size of DES and conceal the passphrase length from an eavesdropper. - - (N) Apply the triple-DES algorithm to (M) with the first 8 octets - of cs-encryption-iv from step (I) as the initialization vector and - the first 24 octets of cs-encryption-key as the key. If optional - privacy protection is negotiated on, the triple-DES state is not - reset. - - The client then sends a message to the server containing the - following: - - (9) The output of step (N). - - If a SASL security layer is negotiated on, the following steps are - used when sending a message: - - (O) Create a buffer containing a uint32 client packet number - (starting from 0) immediately followed by the cs-integrity-key from - step (I). - - (P) Compute HMAC-SHA-1 with (O) as the key and the data to transmit - as the data. - - (Q) Create a buffer containing the data to transmit followed by the - 20-octet output of (P). If privacy was negotiated on, this is - followed by zero to seven padding octets followed by one more octet - indicating the number of padding octets. The total size MUST be a - multiple of the DES block size. - - (R) The result of step (Q) is encrypted with triple-DES if privacy - was negotiated and is sent prefixed by a uint32 length, as required - by SASL. - - If a SASL security layer was negotiated on, the following steps are - taken when receiving a message: - - - - -Newman [Page 9] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - (S) If privacy was negotiated on, the message is decrypted using - triple-DES with the first 24 octets of sc-encryption-key as the - key. The value of the last octet plus one indicates the number of - octets to ignore at the end of the output. The sc-encryption-iv is - used to initialize triple-DES state the first time this is done. - - (T) Create a buffer containing a uint32 server packet number - (starting from 0) immediately followed by the sc-integrity-key. - - (U) Compute HMAC-SHA-1 with (T) as the key over the portion of the - data excluding the 20 octet signature and any encryption padding. - If this is the same as the 20 octet signature, then the data is not - corrupted. - -4. Server Implementation of PASSDSS-3DES-1 - - The section includes a step-by-step guide for server implementors. - It is intended to be read in conjunction with section 3. - - The server MUST have a persistent DSS-SSH public key. Mechanisms - for generating such keys are described in [SCHNEIER] and [DSS]. - - IMPORTANT NOTE: The server MUST be able to process any message from - the client, including messages of any size, messages with invalid - content and messages with NULs in the middle of strings. When - input is illegal, the server MUST gracefully reject authentication - or in extreme cases gracefully terminate the connection. - Particular care to avoid buffer overruns is important if the user - name or passphrase strings are copied. - - The server performs the following computations prior to or during - the connection by the client: - - (a) Select a random number k less than (p - 1)/2. It is important - to generate a good random number [RANDOM]. - - (b) Compute signature component "r" as follows: - k - r = (g mod p) mod q - - (c) Optionally pre-compute the group inverse of k, mod q and the - value xr. - - (d) Select a random Diffie-Hellman private key y less than (n - - 1)/2. Follow the same guidance as in (A) above. - - - - - - -Newman [Page 10] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - (e) Compute the Diffie-Hellman public value Y as follows. If Y has - a value of 0, repeat step (d) above. - y - Y = 2 mod n - - (f) Verify that the value X from the client is between 1 and (n - - 1). If it isn't, fail the authentication. - - (g) Compute the Diffie-Hellman shared key K as follows. It may be - necessary to mask timing attacks [TIMING]. - y - K = X mod n - - (h) Create a buffer containing items (1) through (7) above followed - by K represented as an mpint. - - (i) Compute the SHA-1 hash of the buffer from (h). This produces a - 20 octet result. - - (j) Generate a DSS signature of (i). The signature is made up of - "r" from step (b) and the result following computation (partially - completed in step c): - -1 - s = (k (SHA1(h) + xr)) mod q - - (k) Create a buffer containing items (4) through (8) and send it to - the client. - - (l) Perform the computations as described in step (I) where K is - the result of step (g) in mpint format and H is the result of step - (i). - - (m) Decrypt message (9) from the client using triple-DES with cs- - encryption-iv as the initialization vector and the first 24 octets - of cs-encryption-key as the key. - - (n) Verify the passphrase from the output of step (m) against the - authentication database. Fail the authentication if verification - fails. - - (o) Verify that the selected security layer is permitted and the - cipher text buffer size is at least 32. If not, fail the - authentication. - - (p) Create a buffer containing steps (1) through (7) followed by - the first four octets of the result from (m). - - (q) Compute the HMAC-SHA-1 of (p) with cs-integrity-key as the key. - - - -Newman [Page 11] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - This produces a 20-octet result. - - (r) Compare the output of (q) with the 20 octet signature after the - passphrase in the output of (m). If they don't match, fail the - authentication. - - If a SASL security layer is negotiated on, sending and receiving - procedures are similar to steps (O)-(U), with client and server - roles exchanged (and thus sc-* values and cs-* value exchanged). - Note that triple-DES state from step (m) is not reset. - -5. Example - - The following is an example of the PASSDSS-3DES-1 mechanism using - the IMAP [IMAP4] profile of SASL. Note that base64 encoding and - the lack of an initial client response with the first command are - characteristics of the IMAP profile of SASL and not characteristics - of SASL or this mechanism. - - In this example, "C:" represents lines sent from the client to the - server and "S:" represents lines sent from the server to the - client. The wrapped lines are for editorial clarity -- there are - no actual newlines in the middle of the messages. - - C: a001 AUTHENTICATE PASSDSS-3DES-1 - S: + - C: AAAAAAAAAAVjaHJpcwAAAIEAhuVbMxdLxrAQVyUWbAp+X09h6QmZ2Jebz - H7YhtcbQyLbB9AGi1eIdojZYtAuVeE+PYkKUANLHI9XzWSFliIGMeUvBc - bflHr+s9tZ5/5YZh9blb33km3tUYVKyB5XP530bDn+lY1lAv6tXHKZPrx - b0zPhc+JGgpWGlmT5k9vx2Wk= - S: + AAAA8gAAAAdzc2gtZHNzAAAAQQDPVlO6nFefrq6fA/dQKIoNj75Jjpp - kVv3DkyILABCox2dMql0bnO48rHFuo167y6oukT/ocKupIw6bgKmdofgd - AAAAFQDRpB6FrxemUGRuLjY/oiH/Qef14QAAAEEAkVr9rOlB58k5XoqmP - NYTrVGZKWbCPcYtaL92ANxgWyjyRo49+m0+fHPNhNibQoLddEZF8lHPKW - gb7z7qz0QMdgAAAEARcIEiMz5jTZo8COf2njL3BTWRND5NGAgZY7s1YOm - 2BfjVyf1/MkOiQMiXeonrsfMc0sWQGgpRYRtJWpe56cc2AAAAgQDoV5Uk - bcy3Gjf16MZwPLlJlvmjpSNv2dSSApoddd4+BgZr01zyt7hzb0yRruaN5 - fG43DbJLkk7mtL1Hw8aYXBMQQzrPpHtx+anpCDoN2jlersCGFY2cnjxTf - HqY139ohA8vVXYpapeXxKXR4//Ib/ApTGmwlOeIikKDrBmEGX/JgEAAAA - AAAA8AAAAB3NzaC1kc3MAAAAVAI7j3HG8HyjCOxaGFOUTwZqe0xSHAAAA - FHSqU41vPHTCRTqmxNFwXqazPlJH - C: Obp6vQ83q1O/OnQDifZB1rWOci9LaSck8VxNB4UAFhRI56BAs4XPLqOWI - CoB3LYZ - S: a001 OK Authentication Completed - - The following private values were used in this example. These - values are all represented as an mpint in hexadecimal (msb first). - - - - -Newman [Page 12] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - The client private Diffie-Hellman "x" value: - - 00000018 666E35B4 3BF4BF2B 40E31359 7A5D3AD0 61FD4F6F 736A6114 - - The server private Diffie-Hellman "y" value: - - 00000018 587BDFD6 800D101C 8E82E233 3B5A07AA DB87B8F1 68DC194D - - The Diffie-Hellman shared secret: - - 00000080 3B46D3A8 D2163930 1C33D9FE EAFA528D F4B881CF DF906A03 - 33249A88 42547FF6 49FDC149 1A5084B1 B425A105 CE571283 AC61D896 - AF8F7AF7 F95643F3 00A91E57 BCB8CFD7 77A25CBD 35F59A9E 59E98BEA - EA866339 7F0F9AA0 2F0F335C 8C6AAFF7 76BDB668 DF4D51AF 5B4FB807 - 81A70901 F478FB86 BF42055C BAF46094 EC72E98A - - The DSA private key value (the public key is in the exchange): - - 00000014 252BCBFA 5634D706 6ED43128 972E181E 66BF9C30 - - The SHA-1 hash value used to compute the keys: - - 26 75 97 06 EB FE E3 69 C9 03 7D 49 64 19 D5 D2 97 66 E8 CE - -6. Formal Syntax of PASSDSS-3DES-1 Messages - - This is the formal syntactic definition of the client and server - messages. This uses ABNF [ABNF] notation including the core rules. - The first three rules define the formal exchange. The later rules - define the elements of the exchange. - - client-msg-1 = [azname] authname diffie-hellman-X - - server-msg-1 = dss-public-key diffie-hellman-Y - ssecmask sbuflen dss-signature - - client-msg-2 = client-blob - - - authname = string - ;; interpreted as UTF-8 [UTF-8] - - azname = string - ;; interpreted as UTF-8 [UTF-8] - - cbuflen = 3OCTET - ;; Big endian binary unsigned integer - ;; max length of client read buffer - - - -Newman [Page 13] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - cli-hmac = 20OCTET - - client-blob = 8*OCTET - ;; encrypted version of client-encrypted - - client-encrypted = csecmask cbuflen passphrase cli-hmac *NUL - ;; MUST be multiple of DES block size - - csecmask = OCTET - ;; client selected protection layer - - diffie-hellman-X = mpint - - diffie-hellman-Y = mpint - - dss-g = mpint - - dss-p = mpint - - dss-public-key = length NUL NUL NUL %x07 "ssh-dss" - dss-p dss-q dss-g dss-y - ;; length is total length of remainder - ;; as defined in [SSH-TRANS] - - dss-q = mpint - - dss-r = mpint - - dss-signature = length NUL NUL NUL %x07 "ssh-dss" - dss-r dss-s - ;; length is total length of remainder - - dss-s = mpint - - dss-y = mpint - - length = 4OCTET - ;; binary number, big endian format (MSB first) - - mpint = length *OCTET - ;; length specifies number of octets - ;; see section 1 for detailed mpint definition - - passphrase = string - ;; At least 64 octets MUST be supported - - - - - - -Newman [Page 14] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - sbuflen = 3OCTET - ;; Big endian binary unsigned integer - ;; max length of server read buffer - - ssecmask = OCTET - ;; server protection layer mask - - string = length *OCTET - ;; the length determines the number of octets - ;; OCTETs are interpreted as UTF-8 - - NUL = %x00 ;; US-ASCII NUL character - -7. Security Considerations - - Security considerations are discussed throughout this memo. - - This mechanism supplies the server with the plain-text passphrase, - so the server gains the ability to masquerade as the user to any - other services which share the same passphrase. - - If the public key certification step is skipped, then an active - attacker can gain the client's passphrase and thus the ability to - masquerade as the user to any other services which share the same - passphrase. Negotiating a security layer will fail to provide - protection from an active attacker in this case. - - If no security layer is negotiated, the rest of the protocol - session is subject to active and passive attacks. - - If an integrity-only layer is negotiated, the rest of the protocol - is subject to passive eavesdropping. - - The quality of this mechanism depends on the quality of the random - number generator used. See [RANDOM] for more information. - -8. Multinational Considerations - - As remote access is a crucial service, users are encouraged to - restrict user names and passphrases to the US-ASCII character set. - However, if characters outside the US-ASCII character set are used - in user names and passphrases, then they are interpreted according - to UTF-8 [UTF-8] and it is a protocol error to include any octet - sequences not legal for UTF-8. Servers are encouraged to enforce - this restriction to discourage clients from using non-interoperable - local character sets in this context. - - - - - -Newman [Page 15] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - -9. Intellectual Property Issues and Acknowledgments - - David Kravitz holds U.S. Patent #5,231,668 on the DSA algorithm. - NIST has made this patent available world-wide on a royalty-free - basis. - - Diffie-Hellman was first published in 1976 [DIFFIE-HELLMAN]. U.S. - Patent #4,200,770 granted April 1980 has expired. Canada Patent - #1,121,480 was granted April 6, 1982 and may still apply at this - time. - - DES is covered under U.S. Patent #3,962,539 granted June 1978, - which has expired. - - The majority of the constructions in this specification were copied - from the Secure Shell specifications [SSH-ARCH, SSH-TRANS]. - Additional information is paraphrased from "Applied Cryptography" - [SCHNEIER]. - -10. References - - [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications: - ABNF", RFC 2234, Internet Mail Consortium, Demon Internet Ltd, - November 1997. - - [CRAM-MD5] Klensin, Catoe, Krumviede, "IMAP/POP AUTHorize Extension - for Simple Challenge/Response", RFC 2195, MCI, September 1997. - - [DIFFIE-HELLMAN] Diffie, W., Hellman, M.E., "Privacy and - Authentication: An introduction to Cryptography," Proceedings of - the IEEE, v. 67, n. 3, March 1979, pp. 397-427. - - [DSS] National Institute of Standards and Technology, "Digital - Signature Standard," NIST FIPS PUB 186, U.S. Department of - Commerce, May 1994. - - [HMAC] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for Message - Authentication", RFC 2104, IBM, UCSD, February 1997. - - [HMAC-TEST] Cheng, Glenn, "Test Cases for HMAC-MD5 and HMAC-SHA-1", - RFC 2202, IBM, NIST, September 1997. - - [IMAP4] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, University of Washington, December 1996. - - [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, Harvard University, March 1997. - - - - -Newman [Page 16] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - [Orm96] Orman, H., "The Oakley Key Determination Protocol", version - 1, TR97-92, Department of Computer Science Technical Report, - University of Arizona. - - [RANDOM] Eastlake, Crocker, Schiller, "Randomness Recommendations - for Security", RFC 1750, DEC, Cybercash, MIT, December 1994. - - [SASL] Myers, "Simple Authentication and Security Layer (SASL)", - RFC 2222, Netscape Communications, October 1997. - - [SCHNEIER] Schneier, B., "Applied Cryptography: Protocols, - Algorithms and Source Code in C," John Wiley and Sons, Inc., 1996. - - [SCRAM] Newman, "Salted Challenge Response Authentication Mechanism - (SCRAM)", work in progress, January 1998. - - [SHA1] NIST FIPS PUB 180-1, "Secure Hash Standard," National - Institute of Standards and Technology, U.S. Department of Commerce, - April 1995. - - [SHORT-EXP] van Oorschot, P., Wiener, M., "On Diffie-Hellman Key - Agreement with Short Exponents", Advances in Cryptography -- - EUROCRYPT Springer-Verlag, ISBN 3-540-61186-X, pp. 332-343. - - [SSH-ARCH] Ylonen, Kivinen, Saarinen, "SSH Protocol Architecture", - Work in progress, SSH, October 1997. - - [SSH-TRANS] Ylonen, Kivinen, Saarinen, "SSH Transport Layer - Protocol", Work in progress, SSH, October 1997. - - [TIMING] Kocher, P., "Timing Attacks on Implementations of Diffie- - Hellman, RSA, DSS and Other Systems", Advances in Cryptography -- - CRYPTO '96 Proceedings, Lecture Notes in Computer Science, Vol - 1109, Springer-Verlag, ISBN 3-540-61512-1, pp. 104-113. - - [TLS] Dierks, Allen, "The TLS Protocol Version 1.0", Work in - progress. - - [UTF8] Yergeau, "UTF-8, a transformation format of ISO 10646", - RFC 2279, Alis Technologies, January 1998. - - - - - - - - - - - -Newman [Page 17] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - -11. Author's Address - - Chris Newman - Innosoft International, Inc. - 1050 Lakes Drive - West Covina, CA 91790 USA - - Email: chris.newman@innosoft.com - -Appendix A. Algorithm Overview - - This section provides a quick overview of the algorithms used. For - a full understanding, the reader is encouraged to read "Applied - Cryptography" [SCHNEIER]. The follow descriptions are paraphrased - from that source. - - Note that an overview of the DES algorithm is not included as - publicly available implementations and descriptions are very - common. - -Appendix A.1. DSA Algorithm - - The DSA algorithm is a public key algorithm which can be used to - sign messages such that the source can be verified using a public - key. The algorithm has the following parameters: - - p is a prime number L bits long. Implementations MUST support L - between 512 and 1024 bits. - - q is a 160-bit prime factor of (p - 1). - - (p - 1)/q - g = h mod p where h is any number less than p - 1 such - - (p - 1)/q - that h is greater than 1. - - x is a number less than q and represents the private key. - - x - y = g mod p and represents the public key. - - To sign a message m, the client generates a random number k less - than q and computes: - - k - r = (g mod p) mod q - - - - -Newman [Page 18] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - -1 - s = (k (SHA1(m) + xr)) mod q - - The signature is represented as r and s, and is verified as - follows: - - -1 - w = s mod q - - u1 = (SHA1(m) * w) mod q - - u2 = (rw) mod q - - u1 u2 - v = ((g * y ) mod p) mod q - - If v = r then the signature is verified. - -Appendix A.2. Diffie-Hellman Algorithm - - The Diffie-Hellman algorithm is a key-exchange algorithm. It - allows two ends of a communications channel to establish a shared - secret which a passive eavesdropper can not easily determine. This - key can then be used in a symmetric algorithm such as triple-DES. - The two ends have a prior agreement on two numbers: - - n a large prime number - - g a primitive mod n. - - The client chooses a random large integer x and computes: - - x - X = g mod n - - and sends X to the server. The server chooses a random large - integer y and computes: - - y - Y = g mod n - - y - K = X mod n - - The server sends Y to the client. The client computes: - - x - K = Y mod n - - - -Newman [Page 19] - -Internet Draft PASSDSS-3DES-1 SASL Mechanism March 1998 - - - At this point, the client and server share the same secret K. - -Appendix A.3. Triple-DES Algorithm in EDE/outer-CBC Mode - - The DES algorithm uses an 8 octet (64 bit) key of which 56 bits are - significant. The triple-DES EDE algorithm uses a 24 octet (192 - bit) key of which roughly 112 bits are significant see [SCHNEIER] - for more details. The "EDE" refers to encrypt-decrypt-encrypt, and - the "CBC" refers to cipher-block-chaining where each cipher block - affects future cipher blocks. If E() is the DES encryption - function, D() is the DES decryption function, C is a cipher text - block and P is a plain-text block, then triple-DES EDE in CBC mode - with outer chaining is: - - C = E (D (E (P XOR C ))) - i K3 K2 K1 i i-1 - - NOTE: C is the initialization vector - 0 - - and the decryption function is: - - P = C XOR D (E (D (C ))) - i i-1 K3 K2 K1 i - - K1 is the first 8 octets of the triple-DES key, K2 is the second 8 - octets and K3 is the final 8 octets. - -Appendix A.4. HMAC-SHA-1 Keyed hash function - - HMAC-SHA-1 uses the SHA-1 hash function to create a keyed hash - function suitable for use as an integrity protection function. A - more complete description is in [HMAC]. A brief summary of the - algorithm follows: - - (A) If the key is longer than 64 octets, it is run through the - SHA-1 function to produce a 20 octet key. - - (B) The key is exclusive-ored with a 64 octet buffer filled with - the octet value 0x36. - - (C) SHA-1 is computed over (B) followed by the input text. - - (D) The key is exclusive-ored with a 64 octet buffer filled with - the octet value 0x5C. - - (E) SHA-1 is computed over (D) followed by the output of (C). - - - - -Newman [Page 20] diff --git a/doc/index.html b/doc/index.html index b09a8823..36824b61 100644 --- a/doc/index.html +++ b/doc/index.html @@ -47,58 +47,47 @@

Documentation

RFCs and drafts Other Documentation & Resources diff --git a/doc/install.html b/doc/install.html index fe99995e..4d93c412 100644 --- a/doc/install.html +++ b/doc/install.html @@ -19,7 +19,7 @@

Quick and Dirty

If you're checking this directly out of GIT, you'll need to run "sh -./SMakefile" to build the configure script first. +./autogen.sh" to build the configure script first.

Read the System Administrator's Guide to learn how to configure libsasl in depth. There is also a Slower and Cleaner perform user verification?

diff --git a/doc/options.html b/doc/options.html index beb76ae7..0fb2c79d 100644 --- a/doc/options.html +++ b/doc/options.html @@ -366,7 +366,7 @@

Notes on sasldb with LMDB

distributions and it is distributed under the terms of the OpenLDAP Public License.

Full documentation, plus papers and presentations are available on -the LMDB page.

+the LMDB page.


Back to the index diff --git a/doc/rfc1321.txt b/doc/rfc1321.txt deleted file mode 100644 index 68af27d2..00000000 --- a/doc/rfc1321.txt +++ /dev/null @@ -1,1179 +0,0 @@ - - - - - - -Network Working Group R. Rivest -Request for Comments: 1321 MIT Laboratory for Computer Science - and RSA Data Security, Inc. - April 1992 - - - The MD5 Message-Digest Algorithm - -Status of this Memo - - This memo provides information for the Internet community. It does - not specify an Internet standard. Distribution of this memo is - unlimited. - -Acknowlegements - - We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle, - David Chaum, and Noam Nisan for numerous helpful comments and - suggestions. - -Table of Contents - - 1. Executive Summary 1 - 2. Terminology and Notation 2 - 3. MD5 Algorithm Description 3 - 4. Summary 6 - 5. Differences Between MD4 and MD5 6 - References 7 - APPENDIX A - Reference Implementation 7 - Security Considerations 21 - Author's Address 21 - -1. Executive Summary - - This document describes the MD5 message-digest algorithm. The - algorithm takes as input a message of arbitrary length and produces - as output a 128-bit "fingerprint" or "message digest" of the input. - It is conjectured that it is computationally infeasible to produce - two messages having the same message digest, or to produce any - message having a given prespecified target message digest. The MD5 - algorithm is intended for digital signature applications, where a - large file must be "compressed" in a secure manner before being - encrypted with a private (secret) key under a public-key cryptosystem - such as RSA. - - - - - - - -Rivest [Page 1] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - The MD5 algorithm is designed to be quite fast on 32-bit machines. In - addition, the MD5 algorithm does not require any large substitution - tables; the algorithm can be coded quite compactly. - - The MD5 algorithm is an extension of the MD4 message-digest algorithm - 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in - design. MD5 was designed because it was felt that MD4 was perhaps - being adopted for use more quickly than justified by the existing - critical review; because MD4 was designed to be exceptionally fast, - it is "at the edge" in terms of risking successful cryptanalytic - attack. MD5 backs off a bit, giving up a little in speed for a much - greater likelihood of ultimate security. It incorporates some - suggestions made by various reviewers, and contains additional - optimizations. The MD5 algorithm is being placed in the public domain - for review and possible adoption as a standard. - - For OSI-based applications, MD5's object identifier is - - md5 OBJECT IDENTIFIER ::= - iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5} - - In the X.509 type AlgorithmIdentifier [3], the parameters for MD5 - should have type NULL. - -2. Terminology and Notation - - In this document a "word" is a 32-bit quantity and a "byte" is an - eight-bit quantity. A sequence of bits can be interpreted in a - natural manner as a sequence of bytes, where each consecutive group - of eight bits is interpreted as a byte with the high-order (most - significant) bit of each byte listed first. Similarly, a sequence of - bytes can be interpreted as a sequence of 32-bit words, where each - consecutive group of four bytes is interpreted as a word with the - low-order (least significant) byte given first. - - Let x_i denote "x sub i". If the subscript is an expression, we - surround it in braces, as in x_{i+1}. Similarly, we use ^ for - superscripts (exponentiation), so that x^i denotes x to the i-th - power. - - Let the symbol "+" denote addition of words (i.e., modulo-2^32 - addition). Let X <<< s denote the 32-bit value obtained by circularly - shifting (rotating) X left by s bit positions. Let not(X) denote the - bit-wise complement of X, and let X v Y denote the bit-wise OR of X - and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY - denote the bit-wise AND of X and Y. - - - - - -Rivest [Page 2] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -3. MD5 Algorithm Description - - We begin by supposing that we have a b-bit message as input, and that - we wish to find its message digest. Here b is an arbitrary - nonnegative integer; b may be zero, it need not be a multiple of - eight, and it may be arbitrarily large. We imagine the bits of the - message written down as follows: - - m_0 m_1 ... m_{b-1} - - The following five steps are performed to compute the message digest - of the message. - -3.1 Step 1. Append Padding Bits - - The message is "padded" (extended) so that its length (in bits) is - congruent to 448, modulo 512. That is, the message is extended so - that it is just 64 bits shy of being a multiple of 512 bits long. - Padding is always performed, even if the length of the message is - already congruent to 448, modulo 512. - - Padding is performed as follows: a single "1" bit is appended to the - message, and then "0" bits are appended so that the length in bits of - the padded message becomes congruent to 448, modulo 512. In all, at - least one bit and at most 512 bits are appended. - -3.2 Step 2. Append Length - - A 64-bit representation of b (the length of the message before the - padding bits were added) is appended to the result of the previous - step. In the unlikely event that b is greater than 2^64, then only - the low-order 64 bits of b are used. (These bits are appended as two - 32-bit words and appended low-order word first in accordance with the - previous conventions.) - - At this point the resulting message (after padding with bits and with - b) has a length that is an exact multiple of 512 bits. Equivalently, - this message has a length that is an exact multiple of 16 (32-bit) - words. Let M[0 ... N-1] denote the words of the resulting message, - where N is a multiple of 16. - -3.3 Step 3. Initialize MD Buffer - - A four-word buffer (A,B,C,D) is used to compute the message digest. - Here each of A, B, C, D is a 32-bit register. These registers are - initialized to the following values in hexadecimal, low-order bytes - first): - - - - -Rivest [Page 3] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - word A: 01 23 45 67 - word B: 89 ab cd ef - word C: fe dc ba 98 - word D: 76 54 32 10 - -3.4 Step 4. Process Message in 16-Word Blocks - - We first define four auxiliary functions that each take as input - three 32-bit words and produce as output one 32-bit word. - - F(X,Y,Z) = XY v not(X) Z - G(X,Y,Z) = XZ v Y not(Z) - H(X,Y,Z) = X xor Y xor Z - I(X,Y,Z) = Y xor (X v not(Z)) - - In each bit position F acts as a conditional: if X then Y else Z. - The function F could have been defined using + instead of v since XY - and not(X)Z will never have 1's in the same bit position.) It is - interesting to note that if the bits of X, Y, and Z are independent - and unbiased, the each bit of F(X,Y,Z) will be independent and - unbiased. - - The functions G, H, and I are similar to the function F, in that they - act in "bitwise parallel" to produce their output from the bits of X, - Y, and Z, in such a manner that if the corresponding bits of X, Y, - and Z are independent and unbiased, then each bit of G(X,Y,Z), - H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that - the function H is the bit-wise "xor" or "parity" function of its - inputs. - - This step uses a 64-element table T[1 ... 64] constructed from the - sine function. Let T[i] denote the i-th element of the table, which - is equal to the integer part of 4294967296 times abs(sin(i)), where i - is in radians. The elements of the table are given in the appendix. - - Do the following: - - /* Process each 16-word block. */ - For i = 0 to N/16-1 do - - /* Copy block i into X. */ - For j = 0 to 15 do - Set X[j] to M[i*16+j]. - end /* of loop on j */ - - /* Save A as AA, B as BB, C as CC, and D as DD. */ - AA = A - BB = B - - - -Rivest [Page 4] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - CC = C - DD = D - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] - [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] - [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] - [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] - [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] - [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28] - [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32] - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36] - [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] - [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] - [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48] - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] - [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] - [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] - [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - A = A + AA - B = B + BB - C = C + CC - D = D + DD - - end /* of loop on i */ - - - -Rivest [Page 5] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -3.5 Step 5. Output - - The message digest produced as output is A, B, C, D. That is, we - begin with the low-order byte of A, and end with the high-order byte - of D. - - This completes the description of MD5. A reference implementation in - C is given in the appendix. - -4. Summary - - The MD5 message-digest algorithm is simple to implement, and provides - a "fingerprint" or message digest of a message of arbitrary length. - It is conjectured that the difficulty of coming up with two messages - having the same message digest is on the order of 2^64 operations, - and that the difficulty of coming up with any message having a given - message digest is on the order of 2^128 operations. The MD5 algorithm - has been carefully scrutinized for weaknesses. It is, however, a - relatively new algorithm and further security analysis is of course - justified, as is the case with any new proposal of this sort. - -5. Differences Between MD4 and MD5 - - The following are the differences between MD4 and MD5: - - 1. A fourth round has been added. - - 2. Each step now has a unique additive constant. - - 3. The function g in round 2 was changed from (XY v XZ v YZ) to - (XZ v Y not(Z)) to make g less symmetric. - - 4. Each step now adds in the result of the previous step. This - promotes a faster "avalanche effect". - - 5. The order in which input words are accessed in rounds 2 and - 3 is changed, to make these patterns less like each other. - - 6. The shift amounts in each round have been approximately - optimized, to yield a faster "avalanche effect." The shifts in - different rounds are distinct. - - - - - - - - - - -Rivest [Page 6] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -References - - [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and - RSA Data Security, Inc., April 1992. - - [2] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes - and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90 - Proceedings, pages 303-311, Springer-Verlag, 1991. - - [3] CCITT Recommendation X.509 (1988), "The Directory - - Authentication Framework." - -APPENDIX A - Reference Implementation - - This appendix contains the following files taken from RSAREF: A - Cryptographic Toolkit for Privacy-Enhanced Mail: - - global.h -- global header file - - md5.h -- header file for MD5 - - md5c.c -- source code for MD5 - - For more information on RSAREF, send email to . - - The appendix also includes the following file: - - mddriver.c -- test driver for MD2, MD4 and MD5 - - The driver compiles for MD5 by default but can compile for MD2 or MD4 - if the symbol MD is defined on the C compiler command line as 2 or 4. - - The implementation is portable and should work on many different - plaforms. However, it is not difficult to optimize the implementation - on particular platforms, an exercise left to the reader. For example, - on "little-endian" platforms where the lowest-addressed byte in a 32- - bit word is the least significant and there are no alignment - restrictions, the call to Decode in MD5Transform can be replaced with - a typecast. - -A.1 global.h - -/* GLOBAL.H - RSAREF types and constants - */ - -/* PROTOTYPES should be set to one if and only if the compiler supports - function argument prototyping. -The following makes PROTOTYPES default to 0 if it has not already - - - -Rivest [Page 7] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - been defined with C compiler flags. - */ -#ifndef PROTOTYPES -#define PROTOTYPES 0 -#endif - -/* POINTER defines a generic pointer type */ -typedef unsigned char *POINTER; - -/* UINT2 defines a two byte word */ -typedef unsigned short int UINT2; - -/* UINT4 defines a four byte word */ -typedef unsigned long int UINT4; - -/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. -If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it - returns an empty list. - */ -#if PROTOTYPES -#define PROTO_LIST(list) list -#else -#define PROTO_LIST(list) () -#endif - -A.2 md5.h - -/* MD5.H - header file for MD5C.C - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - - - - -Rivest [Page 8] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -/* MD5 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CTX; - -void MD5Init PROTO_LIST ((MD5_CTX *)); -void MD5Update PROTO_LIST - ((MD5_CTX *, unsigned char *, unsigned int)); -void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); - -A.3 md5c.c - -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#include "global.h" -#include "md5.h" - -/* Constants for MD5Transform routine. - */ - - - -Rivest [Page 9] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); -static void Encode PROTO_LIST - ((unsigned char *, UINT4 *, unsigned int)); -static void Decode PROTO_LIST - ((UINT4 *, unsigned char *, unsigned int)); -static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); -static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - - - -Rivest [Page 10] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -void MD5Init (context) -MD5_CTX *context; /* context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -void MD5Update (context, input, inputLen) -MD5_CTX *context; /* context */ -unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ -{ - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - - - -Rivest [Page 11] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - index; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD5Transform (context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - index = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -void MD5Final (digest, context) -unsigned char digest[16]; /* message digest */ -MD5_CTX *context; /* context */ -{ - unsigned char bits[8]; - unsigned int index, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - - - -Rivest [Page 12] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform (state, block) -UINT4 state[4]; -unsigned char block[64]; -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - - - -Rivest [Page 13] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. - - - -Rivest [Page 14] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -*/ - MD5_memset ((POINTER)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode (output, input, len) -unsigned char *output; -UINT4 *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode (output, input, len) -UINT4 *output; -unsigned char *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} - -/* Note: Replace "for loop" with standard memcpy if possible. - */ - -static void MD5_memcpy (output, input, len) -POINTER output; -POINTER input; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - - - -Rivest [Page 15] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - output[i] = input[i]; -} - -/* Note: Replace "for loop" with standard memset if possible. - */ -static void MD5_memset (output, value, len) -POINTER output; -int value; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; -} - -A.4 mddriver.c - -/* MDDRIVER.C - test driver for MD2, MD4 and MD5 - */ - -/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All -rights reserved. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -/* The following makes MD default to MD5 if it has not already been - defined with C compiler flags. - */ -#ifndef MD -#define MD MD5 -#endif - -#include -#include -#include -#include "global.h" -#if MD == 2 -#include "md2.h" -#endif -#if MD == 4 - - - -Rivest [Page 16] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -#include "md4.h" -#endif -#if MD == 5 -#include "md5.h" -#endif - -/* Length of test block, number of test blocks. - */ -#define TEST_BLOCK_LEN 1000 -#define TEST_BLOCK_COUNT 1000 - -static void MDString PROTO_LIST ((char *)); -static void MDTimeTrial PROTO_LIST ((void)); -static void MDTestSuite PROTO_LIST ((void)); -static void MDFile PROTO_LIST ((char *)); -static void MDFilter PROTO_LIST ((void)); -static void MDPrint PROTO_LIST ((unsigned char [16])); - -#if MD == 2 -#define MD_CTX MD2_CTX -#define MDInit MD2Init -#define MDUpdate MD2Update -#define MDFinal MD2Final -#endif -#if MD == 4 -#define MD_CTX MD4_CTX -#define MDInit MD4Init -#define MDUpdate MD4Update -#define MDFinal MD4Final -#endif -#if MD == 5 -#define MD_CTX MD5_CTX -#define MDInit MD5Init -#define MDUpdate MD5Update -#define MDFinal MD5Final -#endif - -/* Main driver. - -Arguments (may be any combination): - -sstring - digests string - -t - runs time trial - -x - runs test script - filename - digests file - (none) - digests standard input - */ -int main (argc, argv) -int argc; - - - -Rivest [Page 17] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - -char *argv[]; -{ - int i; - - if (argc > 1) - for (i = 1; i < argc; i++) - if (argv[i][0] == '-' && argv[i][1] == 's') - MDString (argv[i] + 2); - else if (strcmp (argv[i], "-t") == 0) - MDTimeTrial (); - else if (strcmp (argv[i], "-x") == 0) - MDTestSuite (); - else - MDFile (argv[i]); - else - MDFilter (); - - return (0); -} - -/* Digests a string and prints the result. - */ -static void MDString (string) -char *string; -{ - MD_CTX context; - unsigned char digest[16]; - unsigned int len = strlen (string); - - MDInit (&context); - MDUpdate (&context, string, len); - MDFinal (digest, &context); - - printf ("MD%d (\"%s\") = ", MD, string); - MDPrint (digest); - printf ("\n"); -} - -/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte - blocks. - */ -static void MDTimeTrial () -{ - MD_CTX context; - time_t endTime, startTime; - unsigned char block[TEST_BLOCK_LEN], digest[16]; - unsigned int i; - - - - -Rivest [Page 18] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - printf - ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, - TEST_BLOCK_LEN, TEST_BLOCK_COUNT); - - /* Initialize block */ - for (i = 0; i < TEST_BLOCK_LEN; i++) - block[i] = (unsigned char)(i & 0xff); - - /* Start timer */ - time (&startTime); - - /* Digest blocks */ - MDInit (&context); - for (i = 0; i < TEST_BLOCK_COUNT; i++) - MDUpdate (&context, block, TEST_BLOCK_LEN); - MDFinal (digest, &context); - - /* Stop timer */ - time (&endTime); - - printf (" done\n"); - printf ("Digest = "); - MDPrint (digest); - printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); - printf - ("Speed = %ld bytes/second\n", - (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime)); -} - -/* Digests a reference suite of strings and prints the results. - */ -static void MDTestSuite () -{ - printf ("MD%d test suite:\n", MD); - - MDString (""); - MDString ("a"); - MDString ("abc"); - MDString ("message digest"); - MDString ("abcdefghijklmnopqrstuvwxyz"); - MDString - ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); - MDString - ("1234567890123456789012345678901234567890\ -1234567890123456789012345678901234567890"); -} - -/* Digests a file and prints the result. - - - -Rivest [Page 19] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - */ -static void MDFile (filename) -char *filename; -{ - FILE *file; - MD_CTX context; - int len; - unsigned char buffer[1024], digest[16]; - - if ((file = fopen (filename, "rb")) == NULL) - printf ("%s can't be opened\n", filename); - - else { - MDInit (&context); - while (len = fread (buffer, 1, 1024, file)) - MDUpdate (&context, buffer, len); - MDFinal (digest, &context); - - fclose (file); - - printf ("MD%d (%s) = ", MD, filename); - MDPrint (digest); - printf ("\n"); - } -} - -/* Digests the standard input and prints the result. - */ -static void MDFilter () -{ - MD_CTX context; - int len; - unsigned char buffer[16], digest[16]; - - MDInit (&context); - while (len = fread (buffer, 1, 16, stdin)) - MDUpdate (&context, buffer, len); - MDFinal (digest, &context); - - MDPrint (digest); - printf ("\n"); -} - -/* Prints a message digest in hexadecimal. - */ -static void MDPrint (digest) -unsigned char digest[16]; -{ - - - -Rivest [Page 20] - -RFC 1321 MD5 Message-Digest Algorithm April 1992 - - - unsigned int i; - - for (i = 0; i < 16; i++) - printf ("%02x", digest[i]); -} - -A.5 Test suite - - The MD5 test suite (driver option "-x") should print the following - results: - -MD5 test suite: -MD5 ("") = d41d8cd98f00b204e9800998ecf8427e -MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 -MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 -MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 -MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b -MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = -d174ab98d277d9f5a5611c2c9f419d9f -MD5 ("123456789012345678901234567890123456789012345678901234567890123456 -78901234567890") = 57edf4a22be3c955ac49da2e2107b67a - -Security Considerations - - The level of security discussed in this memo is considered to be - sufficient for implementing very high security hybrid digital- - signature schemes based on MD5 and a public-key cryptosystem. - -Author's Address - - Ronald L. Rivest - Massachusetts Institute of Technology - Laboratory for Computer Science - NE43-324 - 545 Technology Square - Cambridge, MA 02139-1986 - - Phone: (617) 253-5880 - EMail: rivest@theory.lcs.mit.edu - - - - - - - - - - - - -Rivest [Page 21] - \ No newline at end of file diff --git a/doc/rfc1939.txt b/doc/rfc1939.txt deleted file mode 100644 index b11350e9..00000000 --- a/doc/rfc1939.txt +++ /dev/null @@ -1,1291 +0,0 @@ - - - - - - -Network Working Group J. Myers -Request for Comments: 1939 Carnegie Mellon -STD: 53 M. Rose -Obsoletes: 1725 Dover Beach Consulting, Inc. -Category: Standards Track May 1996 - - - Post Office Protocol - Version 3 - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Table of Contents - - 1. Introduction ................................................ 2 - 2. A Short Digression .......................................... 2 - 3. Basic Operation ............................................. 3 - 4. The AUTHORIZATION State ..................................... 4 - QUIT Command ................................................ 5 - 5. The TRANSACTION State ....................................... 5 - STAT Command ................................................ 6 - LIST Command ................................................ 6 - RETR Command ................................................ 8 - DELE Command ................................................ 8 - NOOP Command ................................................ 9 - RSET Command ................................................ 9 - 6. The UPDATE State ............................................ 10 - QUIT Command ................................................ 10 - 7. Optional POP3 Commands ...................................... 11 - TOP Command ................................................. 11 - UIDL Command ................................................ 12 - USER Command ................................................ 13 - PASS Command ................................................ 14 - APOP Command ................................................ 15 - 8. Scaling and Operational Considerations ...................... 16 - 9. POP3 Command Summary ........................................ 18 - 10. Example POP3 Session ....................................... 19 - 11. Message Format ............................................. 19 - 12. References ................................................. 20 - 13. Security Considerations .................................... 20 - 14. Acknowledgements ........................................... 20 - 15. Authors' Addresses ......................................... 21 - Appendix A. Differences from RFC 1725 .......................... 22 - - - -Myers & Rose Standards Track [Page 1] - -RFC 1939 POP3 May 1996 - - - Appendix B. Command Index ...................................... 23 - -1. Introduction - - On certain types of smaller nodes in the Internet it is often - impractical to maintain a message transport system (MTS). For - example, a workstation may not have sufficient resources (cycles, - disk space) in order to permit a SMTP server [RFC821] and associated - local mail delivery system to be kept resident and continuously - running. Similarly, it may be expensive (or impossible) to keep a - personal computer interconnected to an IP-style network for long - amounts of time (the node is lacking the resource known as - "connectivity"). - - Despite this, it is often very useful to be able to manage mail on - these smaller nodes, and they often support a user agent (UA) to aid - the tasks of mail handling. To solve this problem, a node which can - support an MTS entity offers a maildrop service to these less endowed - nodes. The Post Office Protocol - Version 3 (POP3) is intended to - permit a workstation to dynamically access a maildrop on a server - host in a useful fashion. Usually, this means that the POP3 protocol - is used to allow a workstation to retrieve mail that the server is - holding for it. - - POP3 is not intended to provide extensive manipulation operations of - mail on the server; normally, mail is downloaded and then deleted. A - more advanced (and complex) protocol, IMAP4, is discussed in - [RFC1730]. - - For the remainder of this memo, the term "client host" refers to a - host making use of the POP3 service, while the term "server host" - refers to a host which offers the POP3 service. - -2. A Short Digression - - This memo does not specify how a client host enters mail into the - transport system, although a method consistent with the philosophy of - this memo is presented here: - - When the user agent on a client host wishes to enter a message - into the transport system, it establishes an SMTP connection to - its relay host and sends all mail to it. This relay host could - be, but need not be, the POP3 server host for the client host. Of - course, the relay host must accept mail for delivery to arbitrary - recipient addresses, that functionality is not required of all - SMTP servers. - - - - - -Myers & Rose Standards Track [Page 2] - -RFC 1939 POP3 May 1996 - - -3. Basic Operation - - Initially, the server host starts the POP3 service by listening on - TCP port 110. When a client host wishes to make use of the service, - it establishes a TCP connection with the server host. When the - connection is established, the POP3 server sends a greeting. The - client and POP3 server then exchange commands and responses - (respectively) until the connection is closed or aborted. - - Commands in the POP3 consist of a case-insensitive keyword, possibly - followed by one or more arguments. All commands are terminated by a - CRLF pair. Keywords and arguments consist of printable ASCII - characters. Keywords and arguments are each separated by a single - SPACE character. Keywords are three or four characters long. Each - argument may be up to 40 characters long. - - Responses in the POP3 consist of a status indicator and a keyword - possibly followed by additional information. All responses are - terminated by a CRLF pair. Responses may be up to 512 characters - long, including the terminating CRLF. There are currently two status - indicators: positive ("+OK") and negative ("-ERR"). Servers MUST - send the "+OK" and "-ERR" in upper case. - - Responses to certain commands are multi-line. In these cases, which - are clearly indicated below, after sending the first line of the - response and a CRLF, any additional lines are sent, each terminated - by a CRLF pair. When all lines of the response have been sent, a - final line is sent, consisting of a termination octet (decimal code - 046, ".") and a CRLF pair. If any line of the multi-line response - begins with the termination octet, the line is "byte-stuffed" by - pre-pending the termination octet to that line of the response. - Hence a multi-line response is terminated with the five octets - "CRLF.CRLF". When examining a multi-line response, the client checks - to see if the line begins with the termination octet. If so and if - octets other than CRLF follow, the first octet of the line (the - termination octet) is stripped away. If so and if CRLF immediately - follows the termination character, then the response from the POP - server is ended and the line containing ".CRLF" is not considered - part of the multi-line response. - - A POP3 session progresses through a number of states during its - lifetime. Once the TCP connection has been opened and the POP3 - server has sent the greeting, the session enters the AUTHORIZATION - state. In this state, the client must identify itself to the POP3 - server. Once the client has successfully done this, the server - acquires resources associated with the client's maildrop, and the - session enters the TRANSACTION state. In this state, the client - requests actions on the part of the POP3 server. When the client has - - - -Myers & Rose Standards Track [Page 3] - -RFC 1939 POP3 May 1996 - - - issued the QUIT command, the session enters the UPDATE state. In - this state, the POP3 server releases any resources acquired during - the TRANSACTION state and says goodbye. The TCP connection is then - closed. - - A server MUST respond to an unrecognized, unimplemented, or - syntactically invalid command by responding with a negative status - indicator. A server MUST respond to a command issued when the - session is in an incorrect state by responding with a negative status - indicator. There is no general method for a client to distinguish - between a server which does not implement an optional command and a - server which is unwilling or unable to process the command. - - A POP3 server MAY have an inactivity autologout timer. Such a timer - MUST be of at least 10 minutes' duration. The receipt of any command - from the client during that interval should suffice to reset the - autologout timer. When the timer expires, the session does NOT enter - the UPDATE state--the server should close the TCP connection without - removing any messages or sending any response to the client. - -4. The AUTHORIZATION State - - Once the TCP connection has been opened by a POP3 client, the POP3 - server issues a one line greeting. This can be any positive - response. An example might be: - - S: +OK POP3 server ready - - The POP3 session is now in the AUTHORIZATION state. The client must - now identify and authenticate itself to the POP3 server. Two - possible mechanisms for doing this are described in this document, - the USER and PASS command combination and the APOP command. Both - mechanisms are described later in this document. Additional - authentication mechanisms are described in [RFC1734]. While there is - no single authentication mechanism that is required of all POP3 - servers, a POP3 server must of course support at least one - authentication mechanism. - - Once the POP3 server has determined through the use of any - authentication command that the client should be given access to the - appropriate maildrop, the POP3 server then acquires an exclusive- - access lock on the maildrop, as necessary to prevent messages from - being modified or removed before the session enters the UPDATE state. - If the lock is successfully acquired, the POP3 server responds with a - positive status indicator. The POP3 session now enters the - TRANSACTION state, with no messages marked as deleted. If the - maildrop cannot be opened for some reason (for example, a lock can - not be acquired, the client is denied access to the appropriate - - - -Myers & Rose Standards Track [Page 4] - -RFC 1939 POP3 May 1996 - - - maildrop, or the maildrop cannot be parsed), the POP3 server responds - with a negative status indicator. (If a lock was acquired but the - POP3 server intends to respond with a negative status indicator, the - POP3 server must release the lock prior to rejecting the command.) - After returning a negative status indicator, the server may close the - connection. If the server does not close the connection, the client - may either issue a new authentication command and start again, or the - client may issue the QUIT command. - - After the POP3 server has opened the maildrop, it assigns a message- - number to each message, and notes the size of each message in octets. - The first message in the maildrop is assigned a message-number of - "1", the second is assigned "2", and so on, so that the nth message - in a maildrop is assigned a message-number of "n". In POP3 commands - and responses, all message-numbers and message sizes are expressed in - base-10 (i.e., decimal). - - Here is the summary for the QUIT command when used in the - AUTHORIZATION state: - - QUIT - - Arguments: none - - Restrictions: none - - Possible Responses: - +OK - - Examples: - C: QUIT - S: +OK dewey POP3 server signing off - -5. The TRANSACTION State - - Once the client has successfully identified itself to the POP3 server - and the POP3 server has locked and opened the appropriate maildrop, - the POP3 session is now in the TRANSACTION state. The client may now - issue any of the following POP3 commands repeatedly. After each - command, the POP3 server issues a response. Eventually, the client - issues the QUIT command and the POP3 session enters the UPDATE state. - - - - - - - - - - -Myers & Rose Standards Track [Page 5] - -RFC 1939 POP3 May 1996 - - - Here are the POP3 commands valid in the TRANSACTION state: - - STAT - - Arguments: none - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - The POP3 server issues a positive response with a line - containing information for the maildrop. This line is - called a "drop listing" for that maildrop. - - In order to simplify parsing, all POP3 servers are - required to use a certain format for drop listings. The - positive response consists of "+OK" followed by a single - space, the number of messages in the maildrop, a single - space, and the size of the maildrop in octets. This memo - makes no requirement on what follows the maildrop size. - Minimal implementations should just end that line of the - response with a CRLF pair. More advanced implementations - may include other information. - - NOTE: This memo STRONGLY discourages implementations - from supplying additional information in the drop - listing. Other, optional, facilities are discussed - later on which permit the client to parse the messages - in the maildrop. - - Note that messages marked as deleted are not counted in - either total. - - Possible Responses: - +OK nn mm - - Examples: - C: STAT - S: +OK 2 320 - - - LIST [msg] - - Arguments: - a message-number (optional), which, if present, may NOT - refer to a message marked as deleted - - - - - -Myers & Rose Standards Track [Page 6] - -RFC 1939 POP3 May 1996 - - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - If an argument was given and the POP3 server issues a - positive response with a line containing information for - that message. This line is called a "scan listing" for - that message. - - If no argument was given and the POP3 server issues a - positive response, then the response given is multi-line. - After the initial +OK, for each message in the maildrop, - the POP3 server responds with a line containing - information for that message. This line is also called a - "scan listing" for that message. If there are no - messages in the maildrop, then the POP3 server responds - with no scan listings--it issues a positive response - followed by a line containing a termination octet and a - CRLF pair. - - In order to simplify parsing, all POP3 servers are - required to use a certain format for scan listings. A - scan listing consists of the message-number of the - message, followed by a single space and the exact size of - the message in octets. Methods for calculating the exact - size of the message are described in the "Message Format" - section below. This memo makes no requirement on what - follows the message size in the scan listing. Minimal - implementations should just end that line of the response - with a CRLF pair. More advanced implementations may - include other information, as parsed from the message. - - NOTE: This memo STRONGLY discourages implementations - from supplying additional information in the scan - listing. Other, optional, facilities are discussed - later on which permit the client to parse the messages - in the maildrop. - - Note that messages marked as deleted are not listed. - - Possible Responses: - +OK scan listing follows - -ERR no such message - - Examples: - C: LIST - S: +OK 2 messages (320 octets) - S: 1 120 - - - -Myers & Rose Standards Track [Page 7] - -RFC 1939 POP3 May 1996 - - - S: 2 200 - S: . - ... - C: LIST 2 - S: +OK 2 200 - ... - C: LIST 3 - S: -ERR no such message, only 2 messages in maildrop - - - RETR msg - - Arguments: - a message-number (required) which may NOT refer to a - message marked as deleted - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - If the POP3 server issues a positive response, then the - response given is multi-line. After the initial +OK, the - POP3 server sends the message corresponding to the given - message-number, being careful to byte-stuff the termination - character (as with all multi-line responses). - - Possible Responses: - +OK message follows - -ERR no such message - - Examples: - C: RETR 1 - S: +OK 120 octets - S: - S: . - - - DELE msg - - Arguments: - a message-number (required) which may NOT refer to a - message marked as deleted - - Restrictions: - may only be given in the TRANSACTION state - - - - - - -Myers & Rose Standards Track [Page 8] - -RFC 1939 POP3 May 1996 - - - Discussion: - The POP3 server marks the message as deleted. Any future - reference to the message-number associated with the message - in a POP3 command generates an error. The POP3 server does - not actually delete the message until the POP3 session - enters the UPDATE state. - - Possible Responses: - +OK message deleted - -ERR no such message - - Examples: - C: DELE 1 - S: +OK message 1 deleted - ... - C: DELE 2 - S: -ERR message 2 already deleted - - - NOOP - - Arguments: none - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - The POP3 server does nothing, it merely replies with a - positive response. - - Possible Responses: - +OK - - Examples: - C: NOOP - S: +OK - - - RSET - - Arguments: none - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - If any messages have been marked as deleted by the POP3 - server, they are unmarked. The POP3 server then replies - - - -Myers & Rose Standards Track [Page 9] - -RFC 1939 POP3 May 1996 - - - with a positive response. - - Possible Responses: - +OK - - Examples: - C: RSET - S: +OK maildrop has 2 messages (320 octets) - -6. The UPDATE State - - When the client issues the QUIT command from the TRANSACTION state, - the POP3 session enters the UPDATE state. (Note that if the client - issues the QUIT command from the AUTHORIZATION state, the POP3 - session terminates but does NOT enter the UPDATE state.) - - If a session terminates for some reason other than a client-issued - QUIT command, the POP3 session does NOT enter the UPDATE state and - MUST not remove any messages from the maildrop. - - QUIT - - Arguments: none - - Restrictions: none - - Discussion: - The POP3 server removes all messages marked as deleted - from the maildrop and replies as to the status of this - operation. If there is an error, such as a resource - shortage, encountered while removing messages, the - maildrop may result in having some or none of the messages - marked as deleted be removed. In no case may the server - remove any messages not marked as deleted. - - Whether the removal was successful or not, the server - then releases any exclusive-access lock on the maildrop - and closes the TCP connection. - - Possible Responses: - +OK - -ERR some deleted messages not removed - - Examples: - C: QUIT - S: +OK dewey POP3 server signing off (maildrop empty) - ... - C: QUIT - - - -Myers & Rose Standards Track [Page 10] - -RFC 1939 POP3 May 1996 - - - S: +OK dewey POP3 server signing off (2 messages left) - ... - -7. Optional POP3 Commands - - The POP3 commands discussed above must be supported by all minimal - implementations of POP3 servers. - - The optional POP3 commands described below permit a POP3 client - greater freedom in message handling, while preserving a simple POP3 - server implementation. - - NOTE: This memo STRONGLY encourages implementations to support - these commands in lieu of developing augmented drop and scan - listings. In short, the philosophy of this memo is to put - intelligence in the part of the POP3 client and not the POP3 - server. - - TOP msg n - - Arguments: - a message-number (required) which may NOT refer to to a - message marked as deleted, and a non-negative number - of lines (required) - - Restrictions: - may only be given in the TRANSACTION state - - Discussion: - If the POP3 server issues a positive response, then the - response given is multi-line. After the initial +OK, the - POP3 server sends the headers of the message, the blank - line separating the headers from the body, and then the - number of lines of the indicated message's body, being - careful to byte-stuff the termination character (as with - all multi-line responses). - - Note that if the number of lines requested by the POP3 - client is greater than than the number of lines in the - body, then the POP3 server sends the entire message. - - Possible Responses: - +OK top of message follows - -ERR no such message - - Examples: - C: TOP 1 10 - S: +OK - - - -Myers & Rose Standards Track [Page 11] - -RFC 1939 POP3 May 1996 - - - S: - S: . - ... - C: TOP 100 3 - S: -ERR no such message - - - UIDL [msg] - - Arguments: - a message-number (optional), which, if present, may NOT - refer to a message marked as deleted - - Restrictions: - may only be given in the TRANSACTION state. - - Discussion: - If an argument was given and the POP3 server issues a positive - response with a line containing information for that message. - This line is called a "unique-id listing" for that message. - - If no argument was given and the POP3 server issues a positive - response, then the response given is multi-line. After the - initial +OK, for each message in the maildrop, the POP3 server - responds with a line containing information for that message. - This line is called a "unique-id listing" for that message. - - In order to simplify parsing, all POP3 servers are required to - use a certain format for unique-id listings. A unique-id - listing consists of the message-number of the message, - followed by a single space and the unique-id of the message. - No information follows the unique-id in the unique-id listing. - - The unique-id of a message is an arbitrary server-determined - string, consisting of one to 70 characters in the range 0x21 - to 0x7E, which uniquely identifies a message within a - maildrop and which persists across sessions. This - persistence is required even if a session ends without - entering the UPDATE state. The server should never reuse an - unique-id in a given maildrop, for as long as the entity - using the unique-id exists. - - Note that messages marked as deleted are not listed. - - While it is generally preferable for server implementations - to store arbitrarily assigned unique-ids in the maildrop, - - - -Myers & Rose Standards Track [Page 12] - -RFC 1939 POP3 May 1996 - - - this specification is intended to permit unique-ids to be - calculated as a hash of the message. Clients should be able - to handle a situation where two identical copies of a - message in a maildrop have the same unique-id. - - Possible Responses: - +OK unique-id listing follows - -ERR no such message - - Examples: - C: UIDL - S: +OK - S: 1 whqtswO00WBw418f9t5JxYwZ - S: 2 QhdPYR:00WBw1Ph7x7 - S: . - ... - C: UIDL 2 - S: +OK 2 QhdPYR:00WBw1Ph7x7 - ... - C: UIDL 3 - S: -ERR no such message, only 2 messages in maildrop - - - USER name - - Arguments: - a string identifying a mailbox (required), which is of - significance ONLY to the server - - Restrictions: - may only be given in the AUTHORIZATION state after the POP3 - greeting or after an unsuccessful USER or PASS command - - Discussion: - To authenticate using the USER and PASS command - combination, the client must first issue the USER - command. If the POP3 server responds with a positive - status indicator ("+OK"), then the client may issue - either the PASS command to complete the authentication, - or the QUIT command to terminate the POP3 session. If - the POP3 server responds with a negative status indicator - ("-ERR") to the USER command, then the client may either - issue a new authentication command or may issue the QUIT - command. - - The server may return a positive response even though no - such mailbox exists. The server may return a negative - response if mailbox exists, but does not permit plaintext - - - -Myers & Rose Standards Track [Page 13] - -RFC 1939 POP3 May 1996 - - - password authentication. - - Possible Responses: - +OK name is a valid mailbox - -ERR never heard of mailbox name - - Examples: - C: USER frated - S: -ERR sorry, no mailbox for frated here - ... - C: USER mrose - S: +OK mrose is a real hoopy frood - - - PASS string - - Arguments: - a server/mailbox-specific password (required) - - Restrictions: - may only be given in the AUTHORIZATION state immediately - after a successful USER command - - Discussion: - When the client issues the PASS command, the POP3 server - uses the argument pair from the USER and PASS commands to - determine if the client should be given access to the - appropriate maildrop. - - Since the PASS command has exactly one argument, a POP3 - server may treat spaces in the argument as part of the - password, instead of as argument separators. - - Possible Responses: - +OK maildrop locked and ready - -ERR invalid password - -ERR unable to lock maildrop - - Examples: - C: USER mrose - S: +OK mrose is a real hoopy frood - C: PASS secret - S: -ERR maildrop already locked - ... - C: USER mrose - S: +OK mrose is a real hoopy frood - C: PASS secret - S: +OK mrose's maildrop has 2 messages (320 octets) - - - -Myers & Rose Standards Track [Page 14] - -RFC 1939 POP3 May 1996 - - - APOP name digest - - Arguments: - a string identifying a mailbox and a MD5 digest string - (both required) - - Restrictions: - may only be given in the AUTHORIZATION state after the POP3 - greeting or after an unsuccessful USER or PASS command - - Discussion: - Normally, each POP3 session starts with a USER/PASS - exchange. This results in a server/user-id specific - password being sent in the clear on the network. For - intermittent use of POP3, this may not introduce a sizable - risk. However, many POP3 client implementations connect to - the POP3 server on a regular basis -- to check for new - mail. Further the interval of session initiation may be on - the order of five minutes. Hence, the risk of password - capture is greatly enhanced. - - An alternate method of authentication is required which - provides for both origin authentication and replay - protection, but which does not involve sending a password - in the clear over the network. The APOP command provides - this functionality. - - A POP3 server which implements the APOP command will - include a timestamp in its banner greeting. The syntax of - the timestamp corresponds to the `msg-id' in [RFC822], and - MUST be different each time the POP3 server issues a banner - greeting. For example, on a UNIX implementation in which a - separate UNIX process is used for each instance of a POP3 - server, the syntax of the timestamp might be: - - - - where `process-ID' is the decimal value of the process's - PID, clock is the decimal value of the system clock, and - hostname is the fully-qualified domain-name corresponding - to the host where the POP3 server is running. - - The POP3 client makes note of this timestamp, and then - issues the APOP command. The `name' parameter has - identical semantics to the `name' parameter of the USER - command. The `digest' parameter is calculated by applying - the MD5 algorithm [RFC1321] to a string consisting of the - timestamp (including angle-brackets) followed by a shared - - - -Myers & Rose Standards Track [Page 15] - -RFC 1939 POP3 May 1996 - - - secret. This shared secret is a string known only to the - POP3 client and server. Great care should be taken to - prevent unauthorized disclosure of the secret, as knowledge - of the secret will allow any entity to successfully - masquerade as the named user. The `digest' parameter - itself is a 16-octet value which is sent in hexadecimal - format, using lower-case ASCII characters. - - When the POP3 server receives the APOP command, it verifies - the digest provided. If the digest is correct, the POP3 - server issues a positive response, and the POP3 session - enters the TRANSACTION state. Otherwise, a negative - response is issued and the POP3 session remains in the - AUTHORIZATION state. - - Note that as the length of the shared secret increases, so - does the difficulty of deriving it. As such, shared - secrets should be long strings (considerably longer than - the 8-character example shown below). - - Possible Responses: - +OK maildrop locked and ready - -ERR permission denied - - Examples: - S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us> - C: APOP mrose c4c9334bac560ecc979e58001b3e22fb - S: +OK maildrop has 1 message (369 octets) - - In this example, the shared secret is the string `tan- - staaf'. Hence, the MD5 algorithm is applied to the string - - <1896.697170952@dbc.mtview.ca.us>tanstaaf - - which produces a digest value of - - c4c9334bac560ecc979e58001b3e22fb - -8. Scaling and Operational Considerations - - Since some of the optional features described above were added to the - POP3 protocol, experience has accumulated in using them in large- - scale commercial post office operations where most of the users are - unrelated to each other. In these situations and others, users and - vendors of POP3 clients have discovered that the combination of using - the UIDL command and not issuing the DELE command can provide a weak - version of the "maildrop as semi-permanent repository" functionality - normally associated with IMAP. Of course the other capabilities of - - - -Myers & Rose Standards Track [Page 16] - -RFC 1939 POP3 May 1996 - - - IMAP, such as polling an existing connection for newly arrived - messages and supporting multiple folders on the server, are not - present in POP3. - - When these facilities are used in this way by casual users, there has - been a tendency for already-read messages to accumulate on the server - without bound. This is clearly an undesirable behavior pattern from - the standpoint of the server operator. This situation is aggravated - by the fact that the limited capabilities of the POP3 do not permit - efficient handling of maildrops which have hundreds or thousands of - messages. - - Consequently, it is recommended that operators of large-scale multi- - user servers, especially ones in which the user's only access to the - maildrop is via POP3, consider such options as: - - * Imposing a per-user maildrop storage quota or the like. - - A disadvantage to this option is that accumulation of messages may - result in the user's inability to receive new ones into the - maildrop. Sites which choose this option should be sure to inform - users of impending or current exhaustion of quota, perhaps by - inserting an appropriate message into the user's maildrop. - - * Enforce a site policy regarding mail retention on the server. - - Sites are free to establish local policy regarding the storage and - retention of messages on the server, both read and unread. For - example, a site might delete unread messages from the server after - 60 days and delete read messages after 7 days. Such message - deletions are outside the scope of the POP3 protocol and are not - considered a protocol violation. - - Server operators enforcing message deletion policies should take - care to make all users aware of the policies in force. - - Clients must not assume that a site policy will automate message - deletions, and should continue to explicitly delete messages using - the DELE command when appropriate. - - It should be noted that enforcing site message deletion policies - may be confusing to the user community, since their POP3 client - may contain configuration options to leave mail on the server - which will not in fact be supported by the server. - - One special case of a site policy is that messages may only be - downloaded once from the server, and are deleted after this has - been accomplished. This could be implemented in POP3 server - - - -Myers & Rose Standards Track [Page 17] - -RFC 1939 POP3 May 1996 - - - software by the following mechanism: "following a POP3 login by a - client which was ended by a QUIT, delete all messages downloaded - during the session with the RETR command". It is important not to - delete messages in the event of abnormal connection termination - (ie, if no QUIT was received from the client) because the client - may not have successfully received or stored the messages. - Servers implementing a download-and-delete policy may also wish to - disable or limit the optional TOP command, since it could be used - as an alternate mechanism to download entire messages. - -9. POP3 Command Summary - - Minimal POP3 Commands: - - USER name valid in the AUTHORIZATION state - PASS string - QUIT - - STAT valid in the TRANSACTION state - LIST [msg] - RETR msg - DELE msg - NOOP - RSET - QUIT - - Optional POP3 Commands: - - APOP name digest valid in the AUTHORIZATION state - - TOP msg n valid in the TRANSACTION state - UIDL [msg] - - POP3 Replies: - - +OK - -ERR - - Note that with the exception of the STAT, LIST, and UIDL commands, - the reply given by the POP3 server to any command is significant - only to "+OK" and "-ERR". Any text occurring after this reply - may be ignored by the client. - - - - - - - - - -Myers & Rose Standards Track [Page 18] - -RFC 1939 POP3 May 1996 - - -10. Example POP3 Session - - S: - C: - S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us> - C: APOP mrose c4c9334bac560ecc979e58001b3e22fb - S: +OK mrose's maildrop has 2 messages (320 octets) - C: STAT - S: +OK 2 320 - C: LIST - S: +OK 2 messages (320 octets) - S: 1 120 - S: 2 200 - S: . - C: RETR 1 - S: +OK 120 octets - S: - S: . - C: DELE 1 - S: +OK message 1 deleted - C: RETR 2 - S: +OK 200 octets - S: - S: . - C: DELE 2 - S: +OK message 2 deleted - C: QUIT - S: +OK dewey POP3 server signing off (maildrop empty) - C: - S: - -11. Message Format - - All messages transmitted during a POP3 session are assumed to conform - to the standard for the format of Internet text messages [RFC822]. - - It is important to note that the octet count for a message on the - server host may differ from the octet count assigned to that message - due to local conventions for designating end-of-line. Usually, - during the AUTHORIZATION state of the POP3 session, the POP3 server - can calculate the size of each message in octets when it opens the - maildrop. For example, if the POP3 server host internally represents - end-of-line as a single character, then the POP3 server simply counts - each occurrence of this character in a message as two octets. Note - that lines in the message which start with the termination octet need - not (and must not) be counted twice, since the POP3 client will - remove all byte-stuffed termination characters when it receives a - multi-line response. - - - -Myers & Rose Standards Track [Page 19] - -RFC 1939 POP3 May 1996 - - -12. References - - [RFC821] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC - 821, USC/Information Sciences Institute, August 1982. - - [RFC822] Crocker, D., "Standard for the Format of ARPA-Internet Text - Messages", STD 11, RFC 822, University of Delaware, August 1982. - - [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, - MIT Laboratory for Computer Science, April 1992. - - [RFC1730] Crispin, M., "Internet Message Access Protocol - Version - 4", RFC 1730, University of Washington, December 1994. - - [RFC1734] Myers, J., "POP3 AUTHentication command", RFC 1734, - Carnegie Mellon, December 1994. - -13. Security Considerations - - It is conjectured that use of the APOP command provides origin - identification and replay protection for a POP3 session. - Accordingly, a POP3 server which implements both the PASS and APOP - commands should not allow both methods of access for a given user; - that is, for a given mailbox name, either the USER/PASS command - sequence or the APOP command is allowed, but not both. - - Further, note that as the length of the shared secret increases, so - does the difficulty of deriving it. - - Servers that answer -ERR to the USER command are giving potential - attackers clues about which names are valid. - - Use of the PASS command sends passwords in the clear over the - network. - - Use of the RETR and TOP commands sends mail in the clear over the - network. - - Otherwise, security issues are not discussed in this memo. - -14. Acknowledgements - - The POP family has a long and checkered history. Although primarily - a minor revision to RFC 1460, POP3 is based on the ideas presented in - RFCs 918, 937, and 1081. - - In addition, Alfred Grimstad, Keith McCloghrie, and Neil Ostroff - provided significant comments on the APOP command. - - - -Myers & Rose Standards Track [Page 20] - -RFC 1939 POP3 May 1996 - - -15. Authors' Addresses - - John G. Myers - Carnegie-Mellon University - 5000 Forbes Ave - Pittsburgh, PA 15213 - - EMail: jgm+@cmu.edu - - - Marshall T. Rose - Dover Beach Consulting, Inc. - 420 Whisman Court - Mountain View, CA 94043-2186 - - EMail: mrose@dbc.mtview.ca.us - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Myers & Rose Standards Track [Page 21] - -RFC 1939 POP3 May 1996 - - -Appendix A. Differences from RFC 1725 - - This memo is a revision to RFC 1725, a Draft Standard. It makes the - following changes from that document: - - - clarifies that command keywords are case insensitive. - - - specifies that servers must send "+OK" and "-ERR" in - upper case. - - - specifies that the initial greeting is a positive response, - instead of any string which should be a positive response. - - - clarifies behavior for unimplemented commands. - - - makes the USER and PASS commands optional. - - - clarified the set of possible responses to the USER command. - - - reverses the order of the examples in the USER and PASS - commands, to reduce confusion. - - - clarifies that the PASS command may only be given immediately - after a successful USER command. - - - clarified the persistence requirements of UIDs and added some - implementation notes. - - - specifies a UID length limitation of one to 70 octets. - - - specifies a status indicator length limitation - of 512 octets, including the CRLF. - - - clarifies that LIST with no arguments on an empty mailbox - returns success. - - - adds a reference from the LIST command to the Message Format - section - - - clarifies the behavior of QUIT upon failure - - - clarifies the security section to not imply the use of the - USER command with the APOP command. - - - adds references to RFCs 1730 and 1734 - - - clarifies the method by which a UA may enter mail into the - transport system. - - - -Myers & Rose Standards Track [Page 22] - -RFC 1939 POP3 May 1996 - - - - clarifies that the second argument to the TOP command is a - number of lines. - - - changes the suggestion in the Security Considerations section - for a server to not accept both PASS and APOP for a given user - from a "must" to a "should". - - - adds a section on scaling and operational considerations - -Appendix B. Command Index - - APOP ....................................................... 15 - DELE ....................................................... 8 - LIST ....................................................... 6 - NOOP ....................................................... 9 - PASS ....................................................... 14 - QUIT ....................................................... 5 - QUIT ....................................................... 10 - RETR ....................................................... 8 - RSET ....................................................... 9 - STAT ....................................................... 6 - TOP ........................................................ 11 - UIDL ....................................................... 12 - USER ....................................................... 13 - - - - - - - - - - - - - - - - - - - - - - - - - - - -Myers & Rose Standards Track [Page 23] - diff --git a/doc/rfc2104.txt b/doc/rfc2104.txt deleted file mode 100644 index 1fb8fe11..00000000 --- a/doc/rfc2104.txt +++ /dev/null @@ -1,619 +0,0 @@ - - - - - - -Network Working Group H. Krawczyk -Request for Comments: 2104 IBM -Category: Informational M. Bellare - UCSD - R. Canetti - IBM - February 1997 - - - HMAC: Keyed-Hashing for Message Authentication - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -Abstract - - This document describes HMAC, a mechanism for message authentication - using cryptographic hash functions. HMAC can be used with any - iterative cryptographic hash function, e.g., MD5, SHA-1, in - combination with a secret shared key. The cryptographic strength of - HMAC depends on the properties of the underlying hash function. - -1. Introduction - - Providing a way to check the integrity of information transmitted - over or stored in an unreliable medium is a prime necessity in the - world of open computing and communications. Mechanisms that provide - such integrity check based on a secret key are usually called - "message authentication codes" (MAC). Typically, message - authentication codes are used between two parties that share a secret - key in order to validate information transmitted between these - parties. In this document we present such a MAC mechanism based on - cryptographic hash functions. This mechanism, called HMAC, is based - on work by the authors [BCK1] where the construction is presented and - cryptographically analyzed. We refer to that work for the details on - the rationale and security analysis of HMAC, and its comparison to - other keyed-hash methods. - - - - - - - - - - - -Krawczyk, et. al. Informational [Page 1] - -RFC 2104 HMAC February 1997 - - - HMAC can be used in combination with any iterated cryptographic hash - function. MD5 and SHA-1 are examples of such hash functions. HMAC - also uses a secret key for calculation and verification of the - message authentication values. The main goals behind this - construction are - - * To use, without modifications, available hash functions. - In particular, hash functions that perform well in software, - and for which code is freely and widely available. - - * To preserve the original performance of the hash function without - incurring a significant degradation. - - * To use and handle keys in a simple way. - - * To have a well understood cryptographic analysis of the strength of - the authentication mechanism based on reasonable assumptions on the - underlying hash function. - - * To allow for easy replaceability of the underlying hash function in - case that faster or more secure hash functions are found or - required. - - This document specifies HMAC using a generic cryptographic hash - function (denoted by H). Specific instantiations of HMAC need to - define a particular hash function. Current candidates for such hash - functions include SHA-1 [SHA], MD5 [MD5], RIPEMD-128/160 [RIPEMD]. - These different realizations of HMAC will be denoted by HMAC-SHA1, - HMAC-MD5, HMAC-RIPEMD, etc. - - Note: To the date of writing of this document MD5 and SHA-1 are the - most widely used cryptographic hash functions. MD5 has been recently - shown to be vulnerable to collision search attacks [Dobb]. This - attack and other currently known weaknesses of MD5 do not compromise - the use of MD5 within HMAC as specified in this document (see - [Dobb]); however, SHA-1 appears to be a cryptographically stronger - function. To this date, MD5 can be considered for use in HMAC for - applications where the superior performance of MD5 is critical. In - any case, implementers and users need to be aware of possible - cryptanalytic developments regarding any of these cryptographic hash - functions, and the eventual need to replace the underlying hash - function. (See section 6 for more information on the security of - HMAC.) - - - - - - - - -Krawczyk, et. al. Informational [Page 2] - -RFC 2104 HMAC February 1997 - - -2. Definition of HMAC - - The definition of HMAC requires a cryptographic hash function, which - we denote by H, and a secret key K. We assume H to be a cryptographic - hash function where data is hashed by iterating a basic compression - function on blocks of data. We denote by B the byte-length of such - blocks (B=64 for all the above mentioned examples of hash functions), - and by L the byte-length of hash outputs (L=16 for MD5, L=20 for - SHA-1). The authentication key K can be of any length up to B, the - block length of the hash function. Applications that use keys longer - than B bytes will first hash the key using H and then use the - resultant L byte string as the actual key to HMAC. In any case the - minimal recommended length for K is L bytes (as the hash output - length). See section 3 for more information on keys. - - We define two fixed and different strings ipad and opad as follows - (the 'i' and 'o' are mnemonics for inner and outer): - - ipad = the byte 0x36 repeated B times - opad = the byte 0x5C repeated B times. - - To compute HMAC over the data `text' we perform - - H(K XOR opad, H(K XOR ipad, text)) - - Namely, - - (1) append zeros to the end of K to create a B byte string - (e.g., if K is of length 20 bytes and B=64, then K will be - appended with 44 zero bytes 0x00) - (2) XOR (bitwise exclusive-OR) the B byte string computed in step - (1) with ipad - (3) append the stream of data 'text' to the B byte string resulting - from step (2) - (4) apply H to the stream generated in step (3) - (5) XOR (bitwise exclusive-OR) the B byte string computed in - step (1) with opad - (6) append the H result from step (4) to the B byte string - resulting from step (5) - (7) apply H to the stream generated in step (6) and output - the result - - For illustration purposes, sample code based on MD5 is provided as an - appendix. - - - - - - - -Krawczyk, et. al. Informational [Page 3] - -RFC 2104 HMAC February 1997 - - -3. Keys - - The key for HMAC can be of any length (keys longer than B bytes are - first hashed using H). However, less than L bytes is strongly - discouraged as it would decrease the security strength of the - function. Keys longer than L bytes are acceptable but the extra - length would not significantly increase the function strength. (A - longer key may be advisable if the randomness of the key is - considered weak.) - - Keys need to be chosen at random (or using a cryptographically strong - pseudo-random generator seeded with a random seed), and periodically - refreshed. (Current attacks do not indicate a specific recommended - frequency for key changes as these attacks are practically - infeasible. However, periodic key refreshment is a fundamental - security practice that helps against potential weaknesses of the - function and keys, and limits the damage of an exposed key.) - -4. Implementation Note - - HMAC is defined in such a way that the underlying hash function H can - be used with no modification to its code. In particular, it uses the - function H with the pre-defined initial value IV (a fixed value - specified by each iterative hash function to initialize its - compression function). However, if desired, a performance - improvement can be achieved at the cost of (possibly) modifying the - code of H to support variable IVs. - - The idea is that the intermediate results of the compression function - on the B-byte blocks (K XOR ipad) and (K XOR opad) can be precomputed - only once at the time of generation of the key K, or before its first - use. These intermediate results are stored and then used to - initialize the IV of H each time that a message needs to be - authenticated. This method saves, for each authenticated message, - the application of the compression function of H on two B-byte blocks - (i.e., on (K XOR ipad) and (K XOR opad)). Such a savings may be - significant when authenticating short streams of data. We stress - that the stored intermediate values need to be treated and protected - the same as secret keys. - - Choosing to implement HMAC in the above way is a decision of the - local implementation and has no effect on inter-operability. - - - - - - - - - -Krawczyk, et. al. Informational [Page 4] - -RFC 2104 HMAC February 1997 - - -5. Truncated output - - A well-known practice with message authentication codes is to - truncate the output of the MAC and output only part of the bits - (e.g., [MM, ANSI]). Preneel and van Oorschot [PV] show some - analytical advantages of truncating the output of hash-based MAC - functions. The results in this area are not absolute as for the - overall security advantages of truncation. It has advantages (less - information on the hash result available to an attacker) and - disadvantages (less bits to predict for the attacker). Applications - of HMAC can choose to truncate the output of HMAC by outputting the t - leftmost bits of the HMAC computation for some parameter t (namely, - the computation is carried in the normal way as defined in section 2 - above but the end result is truncated to t bits). We recommend that - the output length t be not less than half the length of the hash - output (to match the birthday attack bound) and not less than 80 bits - (a suitable lower bound on the number of bits that need to be - predicted by an attacker). We propose denoting a realization of HMAC - that uses a hash function H with t bits of output as HMAC-H-t. For - example, HMAC-SHA1-80 denotes HMAC computed using the SHA-1 function - and with the output truncated to 80 bits. (If the parameter t is not - specified, e.g. HMAC-MD5, then it is assumed that all the bits of the - hash are output.) - -6. Security - - The security of the message authentication mechanism presented here - depends on cryptographic properties of the hash function H: the - resistance to collision finding (limited to the case where the - initial value is secret and random, and where the output of the - function is not explicitly available to the attacker), and the - message authentication property of the compression function of H when - applied to single blocks (in HMAC these blocks are partially unknown - to an attacker as they contain the result of the inner H computation - and, in particular, cannot be fully chosen by the attacker). - - These properties, and actually stronger ones, are commonly assumed - for hash functions of the kind used with HMAC. In particular, a hash - function for which the above properties do not hold would become - unsuitable for most (probably, all) cryptographic applications, - including alternative message authentication schemes based on such - functions. (For a complete analysis and rationale of the HMAC - function the reader is referred to [BCK1].) - - - - - - - - -Krawczyk, et. al. Informational [Page 5] - -RFC 2104 HMAC February 1997 - - - Given the limited confidence gained so far as for the cryptographic - strength of candidate hash functions, it is important to observe the - following two properties of the HMAC construction and its secure use - for message authentication: - - 1. The construction is independent of the details of the particular - hash function H in use and then the latter can be replaced by any - other secure (iterative) cryptographic hash function. - - 2. Message authentication, as opposed to encryption, has a - "transient" effect. A published breaking of a message authentication - scheme would lead to the replacement of that scheme, but would have - no adversarial effect on information authenticated in the past. This - is in sharp contrast with encryption, where information encrypted - today may suffer from exposure in the future if, and when, the - encryption algorithm is broken. - - The strongest attack known against HMAC is based on the frequency of - collisions for the hash function H ("birthday attack") [PV,BCK2], and - is totally impractical for minimally reasonable hash functions. - - As an example, if we consider a hash function like MD5 where the - output length equals L=16 bytes (128 bits) the attacker needs to - acquire the correct message authentication tags computed (with the - _same_ secret key K!) on about 2**64 known plaintexts. This would - require the processing of at least 2**64 blocks under H, an - impossible task in any realistic scenario (for a block length of 64 - bytes this would take 250,000 years in a continuous 1Gbps link, and - without changing the secret key K during all this time). This attack - could become realistic only if serious flaws in the collision - behavior of the function H are discovered (e.g. collisions found - after 2**30 messages). Such a discovery would determine the immediate - replacement of the function H (the effects of such failure would be - far more severe for the traditional uses of H in the context of - digital signatures, public key certificates, etc.). - - Note: this attack needs to be strongly contrasted with regular - collision attacks on cryptographic hash functions where no secret key - is involved and where 2**64 off-line parallelizable (!) operations - suffice to find collisions. The latter attack is approaching - feasibility [VW] while the birthday attack on HMAC is totally - impractical. (In the above examples, if one uses a hash function - with, say, 160 bit of output then 2**64 should be replaced by 2**80.) - - - - - - - - -Krawczyk, et. al. Informational [Page 6] - -RFC 2104 HMAC February 1997 - - - A correct implementation of the above construction, the choice of - random (or cryptographically pseudorandom) keys, a secure key - exchange mechanism, frequent key refreshments, and good secrecy - protection of keys are all essential ingredients for the security of - the integrity verification mechanism provided by HMAC. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Krawczyk, et. al. Informational [Page 7] - -RFC 2104 HMAC February 1997 - - -Appendix -- Sample Code - - For the sake of illustration we provide the following sample code for - the implementation of HMAC-MD5 as well as some corresponding test - vectors (the code is based on MD5 code as described in [MD5]). - -/* -** Function: hmac_md5 -*/ - -void -hmac_md5(text, text_len, key, key_len, digest) -unsigned char* text; /* pointer to data stream */ -int text_len; /* length of data stream */ -unsigned char* key; /* pointer to authentication key */ -int key_len; /* length of authentication key */ -caddr_t digest; /* caller digest to be filled in */ - -{ - MD5_CTX context; - unsigned char k_ipad[65]; /* inner padding - - * key XORd with ipad - */ - unsigned char k_opad[65]; /* outer padding - - * key XORd with opad - */ - unsigned char tk[16]; - int i; - /* if key is longer than 64 bytes reset it to key=MD5(key) */ - if (key_len > 64) { - - MD5_CTX tctx; - - MD5Init(&tctx); - MD5Update(&tctx, key, key_len); - MD5Final(tk, &tctx); - - key = tk; - key_len = 16; - } - - /* - * the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - - - -Krawczyk, et. al. Informational [Page 8] - -RFC 2104 HMAC February 1997 - - - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in pads */ - bzero( k_ipad, sizeof k_ipad); - bzero( k_opad, sizeof k_opad); - bcopy( key, k_ipad, key_len); - bcopy( key, k_opad, key_len); - - /* XOR key with ipad and opad values */ - for (i=0; i<64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - /* - * perform inner MD5 - */ - MD5Init(&context); /* init context for 1st - * pass */ - MD5Update(&context, k_ipad, 64) /* start with inner pad */ - MD5Update(&context, text, text_len); /* then text of datagram */ - MD5Final(digest, &context); /* finish up 1st pass */ - /* - * perform outer MD5 - */ - MD5Init(&context); /* init context for 2nd - * pass */ - MD5Update(&context, k_opad, 64); /* start with outer pad */ - MD5Update(&context, digest, 16); /* then results of 1st - * hash */ - MD5Final(digest, &context); /* finish up 2nd pass */ -} - -Test Vectors (Trailing '\0' of a character string not included in test): - - key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b - key_len = 16 bytes - data = "Hi There" - data_len = 8 bytes - digest = 0x9294727a3638bb1c13f48ef8158bfc9d - - key = "Jefe" - data = "what do ya want for nothing?" - data_len = 28 bytes - digest = 0x750c783e6ab0b503eaa86e310a5db738 - - key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - - - -Krawczyk, et. al. Informational [Page 9] - -RFC 2104 HMAC February 1997 - - - key_len 16 bytes - data = 0xDDDDDDDDDDDDDDDDDDDD... - ..DDDDDDDDDDDDDDDDDDDD... - ..DDDDDDDDDDDDDDDDDDDD... - ..DDDDDDDDDDDDDDDDDDDD... - ..DDDDDDDDDDDDDDDDDDDD - data_len = 50 bytes - digest = 0x56be34521d144c88dbb8c733f0e8b3f6 - -Acknowledgments - - Pau-Chen Cheng, Jeff Kraemer, and Michael Oehler, have provided - useful comments on early drafts, and ran the first interoperability - tests of this specification. Jeff and Pau-Chen kindly provided the - sample code and test vectors that appear in the appendix. Burt - Kaliski, Bart Preneel, Matt Robshaw, Adi Shamir, and Paul van - Oorschot have provided useful comments and suggestions during the - investigation of the HMAC construction. - -References - - [ANSI] ANSI X9.9, "American National Standard for Financial - Institution Message Authentication (Wholesale)," American - Bankers Association, 1981. Revised 1986. - - [Atk] Atkinson, R., "IP Authentication Header", RFC 1826, August - 1995. - - [BCK1] M. Bellare, R. Canetti, and H. Krawczyk, - "Keyed Hash Functions and Message Authentication", - Proceedings of Crypto'96, LNCS 1109, pp. 1-15. - (http://www.research.ibm.com/security/keyed-md5.html) - - [BCK2] M. Bellare, R. Canetti, and H. Krawczyk, - "Pseudorandom Functions Revisited: The Cascade Construction", - Proceedings of FOCS'96. - - [Dobb] H. Dobbertin, "The Status of MD5 After a Recent Attack", - RSA Labs' CryptoBytes, Vol. 2 No. 2, Summer 1996. - http://www.rsa.com/rsalabs/pubs/cryptobytes.html - - [PV] B. Preneel and P. van Oorschot, "Building fast MACs from hash - functions", Advances in Cryptology -- CRYPTO'95 Proceedings, - Lecture Notes in Computer Science, Springer-Verlag Vol.963, - 1995, pp. 1-14. - - [MD5] Rivest, R., "The MD5 Message-Digest Algorithm", - RFC 1321, April 1992. - - - -Krawczyk, et. al. Informational [Page 10] - -RFC 2104 HMAC February 1997 - - - [MM] Meyer, S. and Matyas, S.M., Cryptography, New York Wiley, - 1982. - - [RIPEMD] H. Dobbertin, A. Bosselaers, and B. Preneel, "RIPEMD-160: A - strengthened version of RIPEMD", Fast Software Encryption, - LNCS Vol 1039, pp. 71-82. - ftp://ftp.esat.kuleuven.ac.be/pub/COSIC/bosselae/ripemd/. - - [SHA] NIST, FIPS PUB 180-1: Secure Hash Standard, April 1995. - - [Tsu] G. Tsudik, "Message authentication with one-way hash - functions", In Proceedings of Infocom'92, May 1992. - (Also in "Access Control and Policy Enforcement in - Internetworks", Ph.D. Dissertation, Computer Science - Department, University of Southern California, April 1991.) - - [VW] P. van Oorschot and M. Wiener, "Parallel Collision - Search with Applications to Hash Functions and Discrete - Logarithms", Proceedings of the 2nd ACM Conf. Computer and - Communications Security, Fairfax, VA, November 1994. - -Authors' Addresses - - Hugo Krawczyk - IBM T.J. Watson Research Center - P.O.Box 704 - Yorktown Heights, NY 10598 - - EMail: hugo@watson.ibm.com - - Mihir Bellare - Dept of Computer Science and Engineering - Mail Code 0114 - University of California at San Diego - 9500 Gilman Drive - La Jolla, CA 92093 - - EMail: mihir@cs.ucsd.edu - - Ran Canetti - IBM T.J. Watson Research Center - P.O.Box 704 - Yorktown Heights, NY 10598 - - EMail: canetti@watson.ibm.com - - - - - - -Krawczyk, et. al. Informational [Page 11] - diff --git a/doc/rfc2195.txt b/doc/rfc2195.txt deleted file mode 100644 index 4a2725bf..00000000 --- a/doc/rfc2195.txt +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - -Network Working Group J. Klensin -Request for Comments: 2195 R. Catoe -Category: Standards Track P. Krumviede -Obsoletes: 2095 MCI - September 1997 - - - IMAP/POP AUTHorize Extension for Simple Challenge/Response - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Abstract - - While IMAP4 supports a number of strong authentication mechanisms as - described in RFC 1731, it lacks any mechanism that neither passes - cleartext, reusable passwords across the network nor requires either - a significant security infrastructure or that the mail server update - a mail-system-wide user authentication file on each mail access. - This specification provides a simple challenge-response - authentication protocol that is suitable for use with IMAP4. Since - it utilizes Keyed-MD5 digests and does not require that the secret be - stored in the clear on the server, it may also constitute an - improvement on APOP for POP3 use as specified in RFC 1734. - -1. Introduction - - Existing Proposed Standards specify an AUTHENTICATE mechanism for the - IMAP4 protocol [IMAP, IMAP-AUTH] and a parallel AUTH mechanism for - the POP3 protocol [POP3-AUTH]. The AUTHENTICATE mechanism is - intended to be extensible; the four methods specified in [IMAP-AUTH] - are all fairly powerful and require some security infrastructure to - support. The base POP3 specification [POP3] also contains a - lightweight challenge-response mechanism called APOP. APOP is - associated with most of the risks associated with such protocols: in - particular, it requires that both the client and server machines have - access to the shared secret in cleartext form. CRAM offers a method - for avoiding such cleartext storage while retaining the algorithmic - simplicity of APOP in using only MD5, though in a "keyed" method. - - - - - - - -Klensin, Catoe & Krumviede Standards Track [Page 1] - -RFC 2195 IMAP/POP AUTHorize Extension September 1997 - - - At present, IMAP [IMAP] lacks any facility corresponding to APOP. - The only alternative to the strong mechanisms identified in [IMAP- - AUTH] is a presumably cleartext username and password, supported - through the LOGIN command in [IMAP]. This document describes a - simple challenge-response mechanism, similar to APOP and PPP CHAP - [PPP], that can be used with IMAP (and, in principle, with POP3). - - This mechanism also has the advantage over some possible alternatives - of not requiring that the server maintain information about email - "logins" on a per-login basis. While mechanisms that do require such - per-login history records may offer enhanced security, protocols such - as IMAP, which may have several connections between a given client - and server open more or less simultaneous, may make their - implementation particularly challenging. - -2. Challenge-Response Authentication Mechanism (CRAM) - - The authentication type associated with CRAM is "CRAM-MD5". - - The data encoded in the first ready response contains an - presumptively arbitrary string of random digits, a timestamp, and the - fully-qualified primary host name of the server. The syntax of the - unencoded form must correspond to that of an RFC 822 'msg-id' - [RFC822] as described in [POP3]. - - The client makes note of the data and then responds with a string - consisting of the user name, a space, and a 'digest'. The latter is - computed by applying the keyed MD5 algorithm from [KEYED-MD5] where - the key is a shared secret and the digested text is the timestamp - (including angle-brackets). - - This shared secret is a string known only to the client and server. - The `digest' parameter itself is a 16-octet value which is sent in - hexadecimal format, using lower-case ASCII characters. - - When the server receives this client response, it verifies the digest - provided. If the digest is correct, the server should consider the - client authenticated and respond appropriately. - - Keyed MD5 is chosen for this application because of the greater - security imparted to authentication of short messages. In addition, - the use of the techniques described in [KEYED-MD5] for precomputation - of intermediate results make it possible to avoid explicit cleartext - storage of the shared secret on the server system by instead storing - the intermediate results which are known as "contexts". - - - - - - -Klensin, Catoe & Krumviede Standards Track [Page 2] - -RFC 2195 IMAP/POP AUTHorize Extension September 1997 - - - CRAM does not support a protection mechanism. - - Example: - - The examples in this document show the use of the CRAM mechanism with - the IMAP4 AUTHENTICATE command [IMAP-AUTH]. The base64 encoding of - the challenges and responses is part of the IMAP4 AUTHENTICATE - command, not part of the CRAM specification itself. - - S: * OK IMAP4 Server - C: A0001 AUTHENTICATE CRAM-MD5 - S: + PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+ - C: dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw - S: A0001 OK CRAM authentication successful - - In this example, the shared secret is the string - 'tanstaaftanstaaf'. Hence, the Keyed MD5 digest is produced by - calculating - - MD5((tanstaaftanstaaf XOR opad), - MD5((tanstaaftanstaaf XOR ipad), - <1896.697170952@postoffice.reston.mci.net>)) - - where ipad and opad are as defined in the keyed-MD5 Work in - Progress [KEYED-MD5] and the string shown in the challenge is the - base64 encoding of <1896.697170952@postoffice.reston.mci.net>. The - shared secret is null-padded to a length of 64 bytes. If the - shared secret is longer than 64 bytes, the MD5 digest of the - shared secret is used as a 16 byte input to the keyed MD5 - calculation. - - This produces a digest value (in hexadecimal) of - - b913a602c7eda7a495b4e6e7334d3890 - - The user name is then prepended to it, forming - - tim b913a602c7eda7a495b4e6e7334d3890 - - Which is then base64 encoded to meet the requirements of the IMAP4 - AUTHENTICATE command (or the similar POP3 AUTH command), yielding - - dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw - - - - - - - - -Klensin, Catoe & Krumviede Standards Track [Page 3] - -RFC 2195 IMAP/POP AUTHorize Extension September 1997 - - -3. References - - [CHAP] Lloyd, B., and W. Simpson, "PPP Authentication Protocols", - RFC 1334, October 1992. - - [IMAP] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, University of Washington, December 1996. - - [IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanisms", - RFC 1731, Carnegie Mellon, December 1994. - - [KEYED-MD5] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for - Message Authentication", RFC 2104, February 1997. - - [MD5] Rivest, R., "The MD5 Message Digest Algorithm", - RFC 1321, MIT Laboratory for Computer Science, April 1992. - - [POP3] Myers, J., and M. Rose, "Post Office Protocol - Version 3", - STD 53, RFC 1939, Carnegie Mellon, May 1996. - - [POP3-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734, - Carnegie Mellon, December, 1994. - -4. Security Considerations - - It is conjectured that use of the CRAM authentication mechanism - provides origin identification and replay protection for a session. - Accordingly, a server that implements both a cleartext password - command and this authentication type should not allow both methods of - access for a given user. - - While the saving, on the server, of "contexts" (see section 2) is - marginally better than saving the shared secrets in cleartext as is - required by CHAP [CHAP] and APOP [POP3], it is not sufficient to - protect the secrets if the server itself is compromised. - Consequently, servers that store the secrets or contexts must both be - protected to a level appropriate to the potential information value - in user mailboxes and identities. - - As the length of the shared secret increases, so does the difficulty - of deriving it. - - While there are now suggestions in the literature that the use of MD5 - and keyed MD5 in authentication procedures probably has a limited - effective lifetime, the technique is now widely deployed and widely - understood. It is believed that this general understanding may - assist with the rapid replacement, by CRAM-MD5, of the current uses - of permanent cleartext passwords in IMAP. This document has been - - - -Klensin, Catoe & Krumviede Standards Track [Page 4] - -RFC 2195 IMAP/POP AUTHorize Extension September 1997 - - - deliberately written to permit easy upgrading to use SHA (or whatever - alternatives emerge) when they are considered to be widely available - and adequately safe. - - Even with the use of CRAM, users are still vulnerable to active - attacks. An example of an increasingly common active attack is 'TCP - Session Hijacking' as described in CERT Advisory CA-95:01 [CERT95]. - - See section 1 above for additional discussion. - -5. Acknowledgements - - This memo borrows ideas and some text liberally from [POP3] and - [RFC-1731] and thanks are due the authors of those documents. Ran - Atkinson made a number of valuable technical and editorial - contributions to the document. - -6. Authors' Addresses - - John C. Klensin - MCI Telecommunications - 800 Boylston St, 7th floor - Boston, MA 02199 - USA - - EMail: klensin@mci.net - Phone: +1 617 960 1011 - - Randy Catoe - MCI Telecommunications - 2100 Reston Parkway - Reston, VA 22091 - USA - - EMail: randy@mci.net - Phone: +1 703 715 7366 - - Paul Krumviede - MCI Telecommunications - 2100 Reston Parkway - Reston, VA 22091 - USA - - EMail: paul@mci.net - Phone: +1 703 715 7251 - - - - - - -Klensin, Catoe & Krumviede Standards Track [Page 5] - diff --git a/doc/rfc2222.txt b/doc/rfc2222.txt deleted file mode 100644 index 2b0a2abc..00000000 --- a/doc/rfc2222.txt +++ /dev/null @@ -1,899 +0,0 @@ - - - - - - -Network Working Group J. Myers -Request for Comments: 2222 Netscape Communications -Category: Standards Track October 1997 - - - Simple Authentication and Security Layer (SASL) - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1997). All Rights Reserved. - -Table of Contents - - 1. Abstract .............................................. 2 - 2. Organization of this Document ......................... 2 - 2.1. How to Read This Document ............................. 2 - 2.2. Conventions Used in this Document ..................... 2 - 2.3. Examples .............................................. 3 - 3. Introduction and Overview ............................. 3 - 4. Profiling requirements ................................ 4 - 5. Specific issues ....................................... 5 - 5.1. Client sends data first ............................... 5 - 5.2. Server returns success with additional data ........... 5 - 5.3. Multiple authentications .............................. 5 - 6. Registration procedures ............................... 6 - 6.1. Comments on SASL mechanism registrations .............. 6 - 6.2. Location of Registered SASL Mechanism List ............ 6 - 6.3. Change Control ........................................ 7 - 6.4. Registration Template ................................. 7 - 7. Mechanism definitions ................................. 8 - 7.1. Kerberos version 4 mechanism .......................... 8 - 7.2. GSSAPI mechanism ...................................... 9 - 7.2.1 Client side of authentication protocol exchange ....... 9 - 7.2.2 Server side of authentication protocol exchange ....... 10 - 7.2.3 Security layer ........................................ 11 - 7.3. S/Key mechanism ....................................... 11 - 7.4. External mechanism .................................... 12 - 8. References ............................................ 13 - 9. Security Considerations ............................... 13 - 10. Author's Address ...................................... 14 - - - -Myers Standards Track [Page 1] - -RFC 2222 SASL October 1997 - - - Appendix A. Relation of SASL to Transport Security .......... 15 - Full Copyright Statement .................................... 16 - -1. Abstract - - This document describes a method for adding authentication support to - connection-based protocols. To use this specification, a protocol - includes a command for identifying and authenticating a user to a - server and for optionally negotiating protection of subsequent - protocol interactions. If its use is negotiated, a security layer is - inserted between the protocol and the connection. This document - describes how a protocol specifies such a command, defines several - mechanisms for use by the command, and defines the protocol used for - carrying a negotiated security layer over the connection. - -2. Organization of this Document - -2.1. How to Read This Document - - This document is written to serve two different audiences, protocol - designers using this specification to support authentication in their - protocol, and implementors of clients or servers for those protocols - using this specification. - - The sections "Introduction and Overview", "Profiling requirements", - and "Security Considerations" cover issues that protocol designers - need to understand and address in profiling this specification for - use in a specific protocol. - - Implementors of a protocol using this specification need the - protocol-specific profiling information in addition to the - information in this document. - -2.2. Conventions Used in this Document - - In examples, "C:" and "S:" indicate lines sent by the client and - server respectively. - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [RFC 2119]. - - - - - - - - - - -Myers Standards Track [Page 2] - -RFC 2222 SASL October 1997 - - -2.3. Examples - - Examples in this document are for the IMAP profile [RFC 2060] of this - specification. The base64 encoding of challenges and responses, as - well as the "+ " preceding the responses are part of the IMAP4 - profile, not part of the SASL specification itself. - -3. Introduction and Overview - - The Simple Authentication and Security Layer (SASL) is a method for - adding authentication support to connection-based protocols. To use - this specification, a protocol includes a command for identifying and - authenticating a user to a server and for optionally negotiating a - security layer for subsequent protocol interactions. - - The command has a required argument identifying a SASL mechanism. - SASL mechanisms are named by strings, from 1 to 20 characters in - length, consisting of upper-case letters, digits, hyphens, and/or - underscores. SASL mechanism names must be registered with the IANA. - Procedures for registering new SASL mechanisms are given in the - section "Registration procedures" - - If a server supports the requested mechanism, it initiates an - authentication protocol exchange. This consists of a series of - server challenges and client responses that are specific to the - requested mechanism. The challenges and responses are defined by the - mechanisms as binary tokens of arbitrary length. The protocol's - profile then specifies how these binary tokens are then encoded for - transfer over the connection. - - After receiving the authentication command or any client response, a - server may issue a challenge, indicate failure, or indicate - completion. The protocol's profile specifies how the server - indicates which of the above it is doing. - - After receiving a challenge, a client may issue a response or abort - the exchange. The protocol's profile specifies how the client - indicates which of the above it is doing. - - During the authentication protocol exchange, the mechanism performs - authentication, transmits an authorization identity (frequently known - as a userid) from the client to server, and negotiates the use of a - mechanism-specific security layer. If the use of a security layer is - agreed upon, then the mechanism must also define or negotiate the - maximum cipher-text buffer size that each side is able to receive. - - - - - - -Myers Standards Track [Page 3] - -RFC 2222 SASL October 1997 - - - The transmitted authorization identity may be different than the - identity in the client's authentication credentials. This permits - agents such as proxy servers to authenticate using their own - credentials, yet request the access privileges of the identity for - which they are proxying. With any mechanism, transmitting an - authorization identity of the empty string directs the server to - derive an authorization identity from the client's authentication - credentials. - - If use of a security layer is negotiated, it is applied to all - subsequent data sent over the connection. The security layer takes - effect immediately following the last response of the authentication - exchange for data sent by the client and the completion indication - for data sent by the server. Once the security layer is in effect, - the protocol stream is processed by the security layer into buffers - of cipher-text. Each buffer is transferred over the connection as a - stream of octets prepended with a four octet field in network byte - order that represents the length of the following buffer. The length - of the cipher-text buffer must be no larger than the maximum size - that was defined or negotiated by the other side. - -4. Profiling requirements - - In order to use this specification, a protocol definition must supply - the following information: - - 1. A service name, to be selected from the IANA registry of "service" - elements for the GSSAPI host-based service name form [RFC 2078]. - - 2. A definition of the command to initiate the authentication - protocol exchange. This command must have as a parameter the - mechanism name being selected by the client. - - The command SHOULD have an optional parameter giving an initial - response. This optional parameter allows the client to avoid a - round trip when using a mechanism which is defined to have the - client send data first. When this initial response is sent by the - client and the selected mechanism is defined to have the server - start with an initial challenge, the command fails. See section - 5.1 of this document for further information. - - 3. A definition of the method by which the authentication protocol - exchange is carried out, including how the challenges and - responses are encoded, how the server indicates completion or - failure of the exchange, how the client aborts an exchange, and - how the exchange method interacts with any line length limits in - the protocol. - - - - -Myers Standards Track [Page 4] - -RFC 2222 SASL October 1997 - - - 4. Identification of the octet where any negotiated security layer - starts to take effect, in both directions. - - 5. A specification of how the authorization identity passed from the - client to the server is to be interpreted. - -5. Specific issues - -5.1. Client sends data first - - Some mechanisms specify that the first data sent in the - authentication protocol exchange is from the client to the server. - - If a protocol's profile permits the command which initiates an - authentication protocol exchange to contain an initial client - response, this parameter SHOULD be used with such mechanisms. - - If the initial client response parameter is not given, or if a - protocol's profile does not permit the command which initiates an - authentication protocol exchange to contain an initial client - response, then the server issues a challenge with no data. The - client's response to this challenge is then used as the initial - client response. (The server then proceeds to send the next - challenge, indicates completion, or indicates failure.) - -5.2. Server returns success with additional data - - Some mechanisms may specify that server challenge data be sent to the - client along with an indication of successful completion of the - exchange. This data would, for example, authenticate the server to - the client. - - If a protocol's profile does not permit this server challenge to be - returned with a success indication, then the server issues the server - challenge without an indication of successful completion. The client - then responds with no data. After receiving this empty response, the - server then indicates successful completion. - -5.3. Multiple authentications - - Unless otherwise stated by the protocol's profile, only one - successful SASL negotiation may occur in a protocol session. In this - case, once an authentication protocol exchange has successfully - completed, further attempts to initiate an authentication protocol - exchange fail. - - - - - - -Myers Standards Track [Page 5] - -RFC 2222 SASL October 1997 - - - In the case that a profile explicitly permits multiple successful - SASL negotiations to occur, then in no case may multiple security - layers be simultaneously in effect. If a security layer is in effect - and a subsequent SASL negotiation selects no security layer, the - original security layer remains in effect. If a security layer is in - effect and a subsequent SASL negotiation selects a second security - layer, then the second security layer replaces the first. - -6. Registration procedures - - Registration of a SASL mechanism is done by filling in the template - in section 6.4 and sending it in to iana@isi.edu. IANA has the right - to reject obviously bogus registrations, but will perform no review - of clams made in the registration form. - - There is no naming convention for SASL mechanisms; any name that - conforms to the syntax of a SASL mechanism name can be registered. - - While the registration procedures do not require it, authors of SASL - mechanisms are encouraged to seek community review and comment - whenever that is feasible. Authors may seek community review by - posting a specification of their proposed mechanism as an internet- - draft. SASL mechanisms intended for widespread use should be - standardized through the normal IETF process, when appropriate. - -6.1. Comments on SASL mechanism registrations - - Comments on registered SASL mechanisms should first be sent to the - "owner" of the mechanism. Submitters of comments may, after a - reasonable attempt to contact the owner, request IANA to attach their - comment to the SASL mechanism registration itself. If IANA approves - of this the comment will be made accessible in conjunction with the - SASL mechanism registration itself. - -6.2. Location of Registered SASL Mechanism List - - SASL mechanism registrations will be posted in the anonymous FTP - directory "ftp://ftp.isi.edu/in-notes/iana/assignments/sasl- - mechanisms/" and all registered SASL mechanisms will be listed in the - periodically issued "Assigned Numbers" RFC [currently STD 2, RFC - 1700]. The SASL mechanism description and other supporting material - may also be published as an Informational RFC by sending it to "rfc- - editor@isi.edu" (please follow the instructions to RFC authors [RFC - 2223]). - - - - - - - -Myers Standards Track [Page 6] - -RFC 2222 SASL October 1997 - - -6.3. Change Control - - Once a SASL mechanism registration has been published by IANA, the - author may request a change to its definition. The change request - follows the same procedure as the registration request. - - The owner of a SASL mechanism may pass responsibility for the SASL - mechanism to another person or agency by informing IANA; this can be - done without discussion or review. - - The IESG may reassign responsibility for a SASL mechanism. The most - common case of this will be to enable changes to be made to - mechanisms where the author of the registration has died, moved out - of contact or is otherwise unable to make changes that are important - to the community. - - SASL mechanism registrations may not be deleted; mechanisms which are - no longer believed appropriate for use can be declared OBSOLETE by a - change to their "intended use" field; such SASL mechanisms will be - clearly marked in the lists published by IANA. - - The IESG is considered to be the owner of all SASL mechanisms which - are on the IETF standards track. - -6.4. Registration Template - - To: iana@iana.org - Subject: Registration of SASL mechanism X - - SASL mechanism name: - - Security considerations: - - Published specification (optional, recommended): - - Person & email address to contact for further information: - - Intended usage: - - (One of COMMON, LIMITED USE or OBSOLETE) - - Author/Change controller: - - (Any other information that the author deems interesting may be - added below this line.) - - - - - - -Myers Standards Track [Page 7] - -RFC 2222 SASL October 1997 - - -7. Mechanism definitions - - The following mechanisms are hereby defined. - -7.1. Kerberos version 4 mechanism - - The mechanism name associated with Kerberos version 4 is - "KERBEROS_V4". - - The first challenge consists of a random 32-bit number in network - byte order. The client responds with a Kerberos ticket and an - authenticator for the principal "service.hostname@realm", where - "service" is the service name specified in the protocol's profile, - "hostname" is the first component of the host name of the server with - all letters in lower case, and where "realm" is the Kerberos realm of - the server. The encrypted checksum field included within the - Kerberos authenticator contains the server provided challenge in - network byte order. - - Upon decrypting and verifying the ticket and authenticator, the - server verifies that the contained checksum field equals the original - server provided random 32-bit number. Should the verification be - successful, the server must add one to the checksum and construct 8 - octets of data, with the first four octets containing the incremented - checksum in network byte order, the fifth octet containing a bit-mask - specifying the security layers supported by the server, and the sixth - through eighth octets containing, in network byte order, the maximum - cipher-text buffer size the server is able to receive. The server - must encrypt using DES ECB mode the 8 octets of data in the session - key and issue that encrypted data in a second challenge. The client - considers the server authenticated if the first four octets of the - un-encrypted data is equal to one plus the checksum it previously - sent. - - The client must construct data with the first four octets containing - the original server-issued checksum in network byte order, the fifth - octet containing the bit-mask specifying the selected security layer, - the sixth through eighth octets containing in network byte order the - maximum cipher-text buffer size the client is able to receive, and - the following octets containing the authorization identity. The - client must then append from one to eight zero-valued octets so that - the length of the data is a multiple of eight octets. The client must - then encrypt using DES PCBC mode the data with the session key and - respond with the encrypted data. The server decrypts the data and - verifies the contained checksum. The server must verify that the - principal identified in the Kerberos ticket is authorized to connect - as that authorization identity. After this verification, the - authentication process is complete. - - - -Myers Standards Track [Page 8] - -RFC 2222 SASL October 1997 - - - The security layers and their corresponding bit-masks are as follows: - - 1 No security layer - 2 Integrity (krb_mk_safe) protection - 4 Privacy (krb_mk_priv) protection - - Other bit-masks may be defined in the future; bits which are not - understood must be negotiated off. - - EXAMPLE: The following are two Kerberos version 4 login scenarios to - the IMAP4 protocol (note that the line breaks in the sample - authenticators are for editorial clarity and are not in real - authenticators) - - S: * OK IMAP4 Server - C: A001 AUTHENTICATE KERBEROS_V4 - S: + AmFYig== - C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT - +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd - WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh - S: + or//EoAADZI= - C: DiAF5A4gA+oOIALuBkAAmw== - S: A001 OK Kerberos V4 authentication successful - - - S: * OK IMAP4 Server - C: A001 AUTHENTICATE KERBEROS_V4 - S: + gcfgCA== - C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT - +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd - WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh - S: A001 NO Kerberos V4 authentication failed - -7.2. GSSAPI mechanism - - The mechanism name associated with all mechanisms employing the - GSSAPI [RFC 2078] is "GSSAPI". - -7.2.1 Client side of authentication protocol exchange - - The client calls GSS_Init_sec_context, passing in 0 for - input_context_handle (initially) and a targ_name equal to output_name - from GSS_Import_Name called with input_name_type of - GSS_C_NT_HOSTBASED_SERVICE and input_name_string of - "service@hostname" where "service" is the service name specified in - the protocol's profile, and "hostname" is the fully qualified host - name of the server. The client then responds with the resulting - output_token. If GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED, - - - -Myers Standards Track [Page 9] - -RFC 2222 SASL October 1997 - - - then the client should expect the server to issue a token in a - subsequent challenge. The client must pass the token to another call - to GSS_Init_sec_context, repeating the actions in this paragraph. - - When GSS_Init_sec_context returns GSS_S_COMPLETE, the client takes - the following actions: If the last call to GSS_Init_sec_context - returned an output_token, then the client responds with the - output_token, otherwise the client responds with no data. The client - should then expect the server to issue a token in a subsequent - challenge. The client passes this token to GSS_Unwrap and interprets - the first octet of resulting cleartext as a bit-mask specifying the - security layers supported by the server and the second through fourth - octets as the maximum size output_message to send to the server. The - client then constructs data, with the first octet containing the - bit-mask specifying the selected security layer, the second through - fourth octets containing in network byte order the maximum size - output_message the client is able to receive, and the remaining - octets containing the authorization identity. The client passes the - data to GSS_Wrap with conf_flag set to FALSE, and responds with the - generated output_message. The client can then consider the server - authenticated. - -7.2.2 Server side of authentication protocol exchange - - The server passes the initial client response to - GSS_Accept_sec_context as input_token, setting input_context_handle - to 0 (initially). If GSS_Accept_sec_context returns - GSS_S_CONTINUE_NEEDED, the server returns the generated output_token - to the client in challenge and passes the resulting response to - another call to GSS_Accept_sec_context, repeating the actions in this - paragraph. - - When GSS_Accept_sec_context returns GSS_S_COMPLETE, the client takes - the following actions: If the last call to GSS_Accept_sec_context - returned an output_token, the server returns it to the client in a - challenge and expects a reply from the client with no data. Whether - or not an output_token was returned (and after receipt of any - response from the client to such an output_token), the server then - constructs 4 octets of data, with the first octet containing a bit- - mask specifying the security layers supported by the server and the - second through fourth octets containing in network byte order the - maximum size output_token the server is able to receive. The server - must then pass the plaintext to GSS_Wrap with conf_flag set to FALSE - and issue the generated output_message to the client in a challenge. - The server must then pass the resulting response to GSS_Unwrap and - interpret the first octet of resulting cleartext as the bit-mask for - the selected security layer, the second through fourth octets as the - maximum size output_message to send to the client, and the remaining - - - -Myers Standards Track [Page 10] - -RFC 2222 SASL October 1997 - - - octets as the authorization identity. The server must verify that - the src_name is authorized to authenticate as the authorization - identity. After these verifications, the authentication process is - complete. - -7.2.3 Security layer - - The security layers and their corresponding bit-masks are as follows: - - 1 No security layer - 2 Integrity protection. - Sender calls GSS_Wrap with conf_flag set to FALSE - 4 Privacy protection. - Sender calls GSS_Wrap with conf_flag set to TRUE - - Other bit-masks may be defined in the future; bits which are not - understood must be negotiated off. - -7.3. S/Key mechanism - - The mechanism name associated with S/Key [RFC 1760] using the MD4 - digest algorithm is "SKEY". - - The client sends an initial response with the authorization identity. - - The server then issues a challenge which contains the decimal - sequence number followed by a single space and the seed string for - the indicated authorization identity. The client responds with the - one-time-password, as either a 64-bit value in network byte order or - encoded in the "six English words" format. - - The server must verify the one-time-password. After this - verification, the authentication process is complete. - - S/Key authentication does not provide for any security layers. - - EXAMPLE: The following are two S/Key login scenarios in the IMAP4 - protocol. - - S: * OK IMAP4 Server - C: A001 AUTHENTICATE SKEY - S: + - C: bW9yZ2Fu - S: + OTUgUWE1ODMwOA== - C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA== - S: A001 OK S/Key authentication successful - - - - - -Myers Standards Track [Page 11] - -RFC 2222 SASL October 1997 - - - S: * OK IMAP4 Server - C: A001 AUTHENTICATE SKEY - S: + - C: c21pdGg= - S: + OTUgUWE1ODMwOA== - C: BsAY3g4gBNo= - S: A001 NO S/Key authentication failed - - The following is an S/Key login scenario in an IMAP4-like protocol - which has an optional "initial response" argument to the AUTHENTICATE - command. - - S: * OK IMAP4-Like Server - C: A001 AUTHENTICATE SKEY bW9yZ2Fu - S: + OTUgUWE1ODMwOA== - C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA== - S: A001 OK S/Key authentication successful - -7.4. External mechanism - - The mechanism name associated with external authentication is - "EXTERNAL". - - The client sends an initial response with the authorization identity. - - The server uses information, external to SASL, to determine whether - the client is authorized to authenticate as the authorization - identity. If the client is so authorized, the server indicates - successful completion of the authentication exchange; otherwise the - server indicates failure. - - The system providing this external information may be, for example, - IPsec or TLS. - - If the client sends the empty string as the authorization identity - (thus requesting the authorization identity be derived from the - client's authentication credentials), the authorization identity is - to be derived from authentication credentials which exist in the - system which is providing the external authentication. - - - - - - - - - - - - -Myers Standards Track [Page 12] - -RFC 2222 SASL October 1997 - - -8. References - - [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [RFC 2078] Linn, J., "Generic Security Service Application Program - Interface, Version 2", RFC 2078, January 1997. - - [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, March 1997. - - [RFC 2223] Postel, J., and J. Reynolds, "Instructions to RFC - Authors", RFC 2223, October 1997. - - [RFC 1760] Haller, N., "The S/Key One-Time Password System", RFC - 1760, February 1995. - - [RFC 1700] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, - RFC 1700, October 1994. - -9. Security Considerations - - Security issues are discussed throughout this memo. - - The mechanisms that support integrity protection are designed such - that the negotiation of the security layer and authorization identity - is integrity protected. When the client selects a security layer - with at least integrity protection, this protects against an active - attacker hijacking the connection and modifying the authentication - exchange to negotiate a plaintext connection. - - When a server or client supports multiple authentication mechanisms, - each of which has a different security strength, it is possible for - an active attacker to cause a party to use the least secure mechanism - supported. To protect against this sort of attack, a client or - server which supports mechanisms of different strengths should have a - configurable minimum strength that it will use. It is not sufficient - for this minimum strength check to only be on the server, since an - active attacker can change which mechanisms the client sees as being - supported, causing the client to send authentication credentials for - its weakest supported mechanism. - - - - - - - - - - -Myers Standards Track [Page 13] - -RFC 2222 SASL October 1997 - - - The client's selection of a SASL mechanism is done in the clear and - may be modified by an active attacker. It is important for any new - SASL mechanisms to be designed such that an active attacker cannot - obtain an authentication with weaker security properties by modifying - the SASL mechanism name and/or the challenges and responses. - - Any protocol interactions prior to authentication are performed in - the clear and may be modified by an active attacker. In the case - where a client selects integrity protection, it is important that any - security-sensitive protocol negotiations be performed after - authentication is complete. Protocols should be designed such that - negotiations performed prior to authentication should be either - ignored or revalidated once authentication is complete. - -10. Author's Address - - John G. Myers - Netscape Communications - 501 E. Middlefield Road - Mail Stop MV-029 - Mountain View, CA 94043-4042 - - EMail: jgmyers@netscape.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Myers Standards Track [Page 14] - -RFC 2222 SASL October 1997 - - -Appendix A. Relation of SASL to Transport Security - - Questions have been raised about the relationship between SASL and - various services (such as IPsec and TLS) which provide a secured - connection. - - Two of the key features of SASL are: - - 1. The separation of the authorization identity from the identity in - the client's credentials. This permits agents such as proxy - servers to authenticate using their own credentials, yet request - the access privileges of the identity for which they are proxying. - - 2. Upon successful completion of an authentication exchange, the - server knows the authorization identity the client wishes to use. - This allows servers to move to a "user is authenticated" state in - the protocol. - - These features are extremely important to some application protocols, - yet Transport Security services do not always provide them. To - define SASL mechanisms based on these services would be a very messy - task, as the framing of these services would be redundant with the - framing of SASL and some method of providing these important SASL - features would have to be devised. - - Sometimes it is desired to enable within an existing connection the - use of a security service which does not fit the SASL model. (TLS is - an example of such a service.) This can be done by adding a command, - for example "STARTTLS", to the protocol. Such a command is outside - the scope of SASL, and should be different from the command which - starts a SASL authentication protocol exchange. - - In certain situations, it is reasonable to use SASL underneath one of - these Transport Security services. The transport service would - secure the connection, either service would authenticate the client, - and SASL would negotiate the authorization identity. The SASL - negotiation would be what moves the protocol from "unauthenticated" - to "authenticated" state. The "EXTERNAL" SASL mechanism is - explicitly intended to handle the case where the transport service - secures the connection and authenticates the client and SASL - negotiates the authorization identity. - - When using SASL underneath a sufficiently strong Transport Security - service, a SASL security layer would most likely be redundant. The - client and server would thus probably want to negotiate off the use - of a SASL security layer. - - - - - -Myers Standards Track [Page 15] - -RFC 2222 SASL October 1997 - - -Full Copyright Statement - - Copyright (C) The Internet Society (1997). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published - andand distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Myers Standards Track [Page 16] - diff --git a/doc/rfc2243.txt b/doc/rfc2243.txt deleted file mode 100644 index 0ad5a637..00000000 --- a/doc/rfc2243.txt +++ /dev/null @@ -1,563 +0,0 @@ - - - - - - -Network Working Group C. Metz -Request for Comments: 2243 The Inner Net -Category: Standards Track November 1997 - - - - - OTP Extended Responses - - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1997). All Rights Reserved. - -Abstract - - This document provides a specification for a type of response to an - OTP [RFC 1938] challenge that carries explicit indication of the - response's encoding. Codings for the two mandatory OTP data formats - using this new type of response are presented. - - This document also provides a specification for a response that - allows an OTP generator to request that a server re-initialize a - sequence and change parameters such as the secret pass phrase. - -1. Conventions, Terms, and Notation - - This document specifies the data formats and software behaviors - needed to use OTP extended responses. The data formats are described - three ways: using an ad-hoc UNIX manual page style syntax, using - augmented BNF described in sections two and three of RFC 822, and by - examples. Should there be any conflict between these descriptions, - the augmented BNF takes precedence. The software behaviors are - described in words, and specific behavior compliance requirements are - itemized using the requirements terminology (specifically, the words - MUST, SHOULD, and MAY) defined in RFC 2119. - - - - - - - -Metz Standards Track [Page 1] - -RFC 2243 OTP Extended Responses November 1997 - - -2. Extended Challenges and Extended Responses - - This document builds on the protocol and terminology specified in RFC - 1938 and assumes that you have already read this document and - understand its contents. - - An extended challenge is a single line of printable text terminated - by either a new line sequence appropriate for the context of its use - (e.g., ASCII CR followed by ASCII LF) or a whitespace character. It - contains a standard OTP challenge, a whitespace character, and a list - that generators use to determine which extended responses are - supported by a server. - - An extended response is a single line of printable text terminated by - a new line sequence appropriate for the context of its use. It - contains two or more tokens that are separated with a single colon - (':') character. The first token contains a type specifier that - indicates the format of the rest of the response. The tokens that - follow are argument data for the OTP extended response. At least one - token of data MUST be present. - -2.1. Syntax - - In UNIX manual page like syntax, the general form of an extended - challenge could be described as: - - ext[,[, ...]] - - And the general form of an extended response could be described as: - - :[:[:...]] - - In augmented BNF syntax, the syntax of the general form of an - extended challenge and an extended response is: - - extended-challenge = otp-challenge 1*LWSP-char capability-list - (NL / *LWSP-char) - otp-challenge = - capability-list = "ext" *("," extension-set-id) - extension-set-id = * - extended-response = type 1*(":" argument) NL - type = token - argument = token - token = 1* - NL = - - - - - -Metz Standards Track [Page 2] - -RFC 2243 OTP Extended Responses November 1997 - - - An example of an extended challenge indicating support for OTP - extended responses and for a mythical response set "foo" is: - - otp-md5 123 mi1234 ext,foo - - An example of an extended response using a mythical type named "foo" - is: - - foo:some data:some more data:12345 - -2.2. Requirements - - A server compliant with this specification: - - 1. MUST be able to receive and parse the general form of an - extended response - 2. MUST be able to receive, parse, and correctly process all - extended responses specified in this document - 3. MUST process the type field in a case-insensitive manner - 4. MUST reject any authentication attempt using an extended - response if it does not support that type of response - 5. SHOULD provide an appropriate indication to the generator - if the response was rejected because of (4) - 6. MUST limit the length of the input reasonably - 7. MUST accept otherwise arbitrary amounts of whitespace - wherever a response allows it - 8. MUST be able to receive and correctly process standard OTP - responses - - A generator compliant with this specification: - - 1. MUST be able to generate standard OTP responses - 2. MUST use standard responses unless an extended challenge - has been received for the particular server AND seed - 3. MUST generate the type field in lower case - 4. MUST NOT send a response type for which the server has not - indicated support through an extended challenge - - Extension set identifiers and extension type identifiers named with - the prefix "x-" are reserved for private use among mutually - consenting implementations. Implementations that do not recognise a - particular "x-" extension MUST ignore that extension. This means that - all "x-" extensions are likely to be non-interoperable with other - extensions. Careful consideration should be given to the possibility - of a server interacting with with a generator implementation which, - although it recognizes a given "x-" extension, uses it for a - different purpose. All of the remaining extension namespace is - reserved to IANA, which will only officially assign the extension - - - -Metz Standards Track [Page 3] - -RFC 2243 OTP Extended Responses November 1997 - - - into this namespace after the IESG approves of such an assignment. - During the lifetime of the OTP WG, it is recommended that the IESG - consult with the OTP WG prior to approving such an assignment. - -3. The "hex" and "word" Responses - - There exists a very rare case in which a standard OTP response could - be a valid coding in both the hexadecimal and six-word formats. An - example of this is the response "ABE ACE ADA ADD BAD A." The - solution to this problem mandated by the OTP specification is that - compliant servers MUST attempt to parse and verify a standard - response in both hexadecimal and six-word formats and must consider - the authentication successful if either succeeds. - - This problem can be solved easily using extended responses. The "hex" - response and the "word" response are two response types that encode - an OTP in an extended response that explicitly describes the - encoding. These responses start with a type label of "hex" for a - hexadecimal OTP and "word" for a six-word coded OTP. These responses - contain one argument field that contains a standard OTP response - coded in the indicated format. - -3.1. Syntax - - In UNIX manual page like syntax, the format of these responses could - be described as: - - hex: - word: - - In augmented BNF syntax and with the definitions already provided, - the syntax of these responses is: - - hex-response = "hex:" hex-64bit NL - hex-64bit = 16(hex-char *LWSP-char) - hex-char = ("A" / "B" / "C" / "D" / "E" / "F" / - "a" / "b" / "c" / "d" / "e" / "f" / - "0" / "1" / "2" / "3" / "4" / "5" / - "6" / "7" / "8" / "9") - - word-response = "word:" word-64bit NL - word-64bit = 6(otp-word 1*LWSP-char) - otp-word = - - - - - - - -Metz Standards Track [Page 4] - -RFC 2243 OTP Extended Responses November 1997 - - - Examples of these responses are: - - hex:8720 33d4 6202 9172 - word:VAST SAUL TAKE SODA SUCH BOLT - -3.2. Requirements - - A server compliant with this specification: - - 1. MUST process all arguments in a case-insensitive manner - - A generator compliant with this specification: - - 1. SHOULD generate otp-word tokens in upper case with single - spaces separating them - 2. SHOULD generate hexadecimal numbers using only lower case - for letters - -4. The "init-hex" and "init-word" Responses - - The OTP specification requires that implementations provide a means - for a client to re-initialize or change its OTP information with a - server but does not require any specific protocol for doing it. - Implementations that support the OTP extended responses described in - this document MUST support the response with the "init-hex" and - "init-word" type specifiers, which provide a standard way for a - client to re-initialize its OTP information with a server. This - response is intended to be used only by automated clients. Because of - this, the recommended form of this response uses the hexadecimal - encoding for binary data. It is possible for a user to type an "init- - hex" or "init-word" response. - -4.1. Syntax - - In UNIX manual page like syntax, the format of these responses could - be described as: - - init-hex::: - init-word::: - - In augmented BNF syntax and with the definitions already provided, - the syntax of the "init-hex" response is: - - init-hex-response = "init-hex:" current-OTP ":" new-params ":" - new-OTP NL - - current-OTP = hex-64bit - new-OTP = hex-64bit - - - -Metz Standards Track [Page 5] - -RFC 2243 OTP Extended Responses November 1997 - - - new-params = algorithm SPACE sequence-number SPACE seed - algorithm = "md4" / "md5" / "sha1" - sequence-number = 4*3DIGIT - seed = 16*1(ALPHA / DIGIT) - - In augmented BNF syntax and with the definitions already provided, - the syntax of the "init-word" response is: - - init-word-response = "init-word:" current-OTP ":" new-params ":" - new-OTP NL - - current-OTP = word-64bit - new-OTP = word-64bit - - new-params = algorithm SPACE sequence-number SPACE seed - algorithm = "md4" / "md5" / "sha1" - sequence-number = 4*3DIGIT - seed = 16*1(ALPHA / DIGIT) - - Note that all appropriate fields for the "init-hex" response MUST be - hexadecimally coded and that all appropriate fields for the "init- - word" response MUST be six-word coded. - - Examples of these responses are: - - init-hex:f6bd 6b33 89b8 7203:md5 499 ke6118:23d1 b253 5ae0 2b7e - init-hex:c9b2 12bb 6425 5a0f:md5 499 ke0986:fd17 cef1 b4df 093e - - init-word:MOOD SOFT POP COMB BOLO LIFE:md5 499 ke1235: - ARTY WEAR TAD RUG HALO GIVE - init-word:END KERN BALM NICK EROS WAVY:md5 499 ke1235: - BABY FAIN OILY NIL TIDY DADE - - (Note that all of these responses are one line. Due to their length, - they had to be split into multiple lines in order to be included - here. These responses MUST NOT span more than one line in actual use) - -4.2. Description of Fields - - The current-OTP field contains the (RFC 1938) response to the OTP - challenge. The new-params field contains the parameters for the - client's new requested challenge and the new-OTP field contains a - response to that challenge. If the re-initialization is successful, a - server MUST store the new OTP in its database as the last successful - OTP received and the sequence number in the next challenge presented - by the server MUST be one less than the sequence number specified in - the new-params field. - - - - -Metz Standards Track [Page 6] - -RFC 2243 OTP Extended Responses November 1997 - - - The new-params field is hashed as a string the same way that a seed - or secret pass phrase would be. All other field values are hashed in - their uncoded binary forms, in network byte order and without any - padding. - -4.3. Requirements - - A server compliant with this specification: - - 1. SHOULD NOT allow a user to use the same value for their - seed and secret pass phrase. - 2. MUST disable all OTP access to any principal whose - sequence number would be less than one - 3. MUST decrement the sequence number if a reinitialization - response includes a valid current-OTP, but the server is - unable to successfully process the new-params or new-OTP for - any reason. - - A generator compliant with this specification: - - 1. SHOULD NOT allow a user to use the same value for their - seed and secret pass phrase - 2. MUST take specific steps to prevent infinite loops of - re-initialization attempts in case of failure - 3. SHOULD provide the user with some indication that the - re-initialization is taking place - 4. SHOULD NOT do a re-initialization without the user's - permission, either for that specific instance or as a - configuration option - 5. SHOULD NOT retry a failed re-initialization without a user's - permission - 6. SHOULD warn the user if the sequence number falls below ten - 7. MUST refuse to generate OTPs with a sequence number below one - -5. Security Considerations - - All of the security considerations for the OTP system also apply to - the OTP system with extended responses. - - These extended responses, like OTP itself, do not protect the user - against active attacks. The IPsec Authentication Header (RFC-1826) - (or another technique with at least as much strength as IPsec AH) - SHOULD be used to protect against such attacks. - - The consequences of a successful active attack on the re- - initialization response may be more severe than simply hijacking a - single session. An attacker could substitute his own response for - - - - -Metz Standards Track [Page 7] - -RFC 2243 OTP Extended Responses November 1997 - - - that of a legitimate user. The attacker may then be able to use the - OTP system to authenticate himself as the user at will (at least - until detected). - - Failure to implement server requirement 3 in section 4.3 opens an - implementation to an attack based on replay of the current-OTP part - of the response. - -6. Acknowledgments - - Like RFC 1938, the protocol described in this document was created by - contributors in the IETF OTP working group. Specific contributions - were made by Neil Haller, who provided input on the overall design - requirements of a re-initialization protocol, Denis Pinkas, who - suggested several modifications to the originally proposed re- - initialization protocol, and Phil Servita, who opened the debate with - the first real protocol proposal and provided lots of specific input - on the design of this and earlier protocols. The extensions to the - OTP challenge were suggested by Chris Newman and John Valdes. - - Randall Atkinson and Ted T'so also contributed their views to - discussions about details of the protocol extensions in this - document. - -References - - [RFC 822] Crocker, D., "Standard for the Format of ARPA Internet - Text Messages," RFC 822, August 1982. - - [RFC 1825] Atkinson, R., "Security Architecture for the Internet - Protocol," RFC 1825, August 1995. - - [RFC 1938] Haller, N. and C. Metz, "A One-Time Password System," - RFC 1938, May 1996. - - [RFC 2119] Bradner, S., "Key words for use in RFCs to - Indicate Requirement Level," RFC 2119, - March 1997. - -Author's Address - - Craig Metz - The Inner Net - Box 10314-1936 - Blacksburg, VA 24062-0314 - (DSN) 354-8590 - cmetz@inner.net - - - - -Metz Standards Track [Page 8] - -RFC 2243 OTP Extended Responses November 1997 - - -Appendix: Reference Responses - - The following responses were generated by a development version of - the One-Time Passwords in Everything (OPIE) implementation of this - specification. - - All of these are responses to the challenge: - - otp-md5 499 ke1234 ext - - Note that the re-initialization responses use the same secret pass - phrase for new and current and a new seed of "ke1235". Also, these - responses have been split for formatting purposes into multiple - lines; they MUST NOT be multiple lines in actual use. - - The secret pass phrase for these responses is: - - This is a test. - - The OTP standard hexadecimal response is: - - 5bf0 75d9 959d 036f - - The OTP standard six-word response is: - - BOND FOGY DRAB NE RISE MART - - The OTP extended "hex" response is: - - hex:5Bf0 75d9 959d 036f - - The OTP extended "word" response is: - - word:BOND FOGY DRAB NE RISE MART - - The OTP extended "init-hex" response is: - - init-hex:5bf0 75d9 959d 036f:md5 499 ke1235:3712 dcb4 aa53 16c1 - - The OTP extended "init-word" response is: - - init-word:BOND FOGY DRAB NE RISE MART:md5 499 ke1235: RED HERD - NOW BEAN PA BURG - - - - - - - - -Metz Standards Track [Page 9] - -RFC 2243 OTP Extended Responses November 1997 - - -Full Copyright Statement - - Copyright (C) The Internet Society (1997). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Metz Standards Track [Page 10] - diff --git a/doc/rfc2245.txt b/doc/rfc2245.txt deleted file mode 100644 index 1025a906..00000000 --- a/doc/rfc2245.txt +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - -Network Working Group C. Newman -Request for Comments: 2245 Innosoft -Category: Standards Track November 1997 - - - Anonymous SASL Mechanism - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1997). All Rights Reserved. - -Abstract - - It is common practice on the Internet to permit anonymous access to - various services. Traditionally, this has been done with a plain - text password mechanism using "anonymous" as the user name and - optional trace information, such as an email address, as the - password. As plaintext login commands are not permitted in new IETF - protocols, a new way to provide anonymous login is needed within the - context of the SASL [SASL] framework. - -1. Conventions Used in this Document - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" - in this document are to be interpreted as defined in "Key words for - use in RFCs to Indicate Requirement Levels" [KEYWORDS]. - -2. Anonymous SASL mechanism - - The mechanism name associated with anonymous access is "ANONYMOUS". - The mechanism consists of a single message from the client to the - server. The client sends optional trace information in the form of a - human readable string. The trace information should take one of - three forms: an Internet email address, an opaque string which does - not contain the '@' character and can be interpreted by the system - administrator of the client's domain, or nothing. For privacy - reasons, an Internet email address should only be used with - permission from the user. - - - - - -Newman Standards Track [Page 1] - -RFC 2245 Anonymous SASL Mechanism November 1997 - - - A server which permits anonymous access will announce support for the - ANONYMOUS mechanism, and allow anyone to log in using that mechanism, - usually with restricted access. - - The formal grammar for the client message using Augmented BNF [ABNF] - follows. - - message = [email / token] - - TCHAR = %x20-3F / %x41-7E - ;; any printable US-ASCII character except '@' - - email = addr-spec - ;; as defined in [IMAIL], except with no free - ;; insertion of linear-white-space, and the - ;; local-part MUST either be entirely enclosed in - ;; quotes or entirely unquoted - - token = 1*255TCHAR - -3. Example - - - Here is a sample anonymous login between an IMAP client and server. - In this example, "C:" and "S:" indicate lines sent by the client and - server respectively. If such lines are wrapped without a new "C:" or - "S:" label, then the wrapping is for editorial clarity and is not - part of the command. - - Note that this example uses the IMAP profile [IMAP4] of SASL. The - base64 encoding of challenges and responses, as well as the "+ " - preceding the responses are part of the IMAP4 profile, not part of - SASL itself. Newer profiles of SASL will include the client message - with the AUTHENTICATE command itself so the extra round trip below - (the server response with an empty "+ ") can be eliminated. - - In this example, the user's opaque identification token is "sirhc". - - S: * OK IMAP4 server ready - C: A001 CAPABILITY - S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=CRAM-MD5 AUTH=ANONYMOUS - S: A001 OK done - C: A002 AUTHENTICATE ANONYMOUS - S: + - C: c2lyaGM= - S: A003 OK Welcome, trace information has been logged. - - - - - -Newman Standards Track [Page 2] - -RFC 2245 Anonymous SASL Mechanism November 1997 - - -4. Security Considerations - - The anonymous mechanism grants access to information by anyone. For - this reason it should be disabled by default so the administrator can - make an explicit decision to enable it. - - If the anonymous user has any write privileges, a denial of service - attack is possible by filling up all available space. This can be - prevented by disabling all write access by anonymous users. - - If anonymous users have read and write access to the same area, the - server can be used as a communication mechanism to anonymously - exchange information. Servers which accept anonymous submissions - should implement the common "drop box" model which forbids anonymous - read access to the area where anonymous submissions are accepted. - - If the anonymous user can run many expensive operations (e.g., an - IMAP SEARCH BODY command), this could enable a denial of service - attack. Servers are encouraged to limit the number of anonymous - users and reduce their priority or limit their resource usage. - - If there is no idle timeout for the anonymous user and there is a - limit on the number of anonymous users, a denial of service attack is - enabled. Servers should implement an idle timeout for anonymous - users. - - The trace information is not authenticated so it can be falsified. - This can be used as an attempt to get someone else in trouble for - access to questionable information. Administrators trying to trace - abuse need to realize this information may be falsified. - - A client which uses the user's correct email address as trace - information without explicit permission may violate that user's - privacy. Information about who accesses an anonymous archive on a - sensitive subject (e.g., sexual abuse) has strong privacy needs. - Clients should not send the email address without explicit permission - of the user and should offer the option of supplying no trace token - -- thus only exposing the source IP address and time. Anonymous - proxy servers could enhance this privacy, but would have to consider - the resulting potential denial of service attacks. - - Anonymous connections are susceptible to man in the middle attacks - which view or alter the data transferred. Clients and servers are - encouraged to support external integrity and encryption mechanisms. - - Protocols which fail to require an explicit anonymous login are more - susceptible to break-ins given certain common implementation - techniques. Specifically, Unix servers which offer user login may - - - -Newman Standards Track [Page 3] - -RFC 2245 Anonymous SASL Mechanism November 1997 - - - initially start up as root and switch to the appropriate user id - after an explicit login command. Normally such servers refuse all - data access commands prior to explicit login and may enter a - restricted security environment (e.g., the Unix chroot function) for - anonymous users. If anonymous access is not explicitly requested, - the entire data access machinery is exposed to external security - attacks without the chance for explicit protective measures. - Protocols which offer restricted data access should not allow - anonymous data access without an explicit login step. - -5. References - - [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [IMAIL] Crocker, D., "Standard for the Format of Arpa Internet Text - Messages", STD 11, RFC 822, August 1982. - - [IMAP4] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, March 1997. - - [SASL] Myers, J., "Simple Authentication and Security Layer (SASL)", - RFC 2222, October 1997. - -6. Author's Address - - Chris Newman - Innosoft International, Inc. - 1050 Lakes Drive - West Covina, CA 91790 USA - - Email: chris.newman@innosoft.com - - - - - - - - - - - - - - - - -Newman Standards Track [Page 4] - -RFC 2245 Anonymous SASL Mechanism November 1997 - - -7. Full Copyright Statement - - Copyright (C) The Internet Society (1997). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Newman Standards Track [Page 5] - diff --git a/doc/rfc2289.txt b/doc/rfc2289.txt deleted file mode 100644 index 8d1d7222..00000000 --- a/doc/rfc2289.txt +++ /dev/null @@ -1,1403 +0,0 @@ - - - - - - -Network Working Group N. Haller -Request for Comments: 2289 Bellcore -Obsoletes: 1938 C. Metz -Category: Standards Track Kaman Sciences Corporation - P. Nesser - Nesser & Nesser Consulting - M. Straw - Bellcore - February 1998 - - - A One-Time Password System - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1998). All Rights Reserved. - -1.0 ABSTRACT - - This document describes a one-time password authentication system - (OTP). The system provides authentication for system access (login) - and other applications requiring authentication that is secure - against passive attacks based on replaying captured reusable - passwords. OTP evolved from the S/KEY (S/KEY is a trademark of - Bellcore) One-Time Password System that was released by Bellcore and - is described in references [3] and [5]. - -2.0 OVERVIEW - - One form of attack on networked computing systems is eavesdropping on - network connections to obtain authentication information such as the - login IDs and passwords of legitimate users. Once this information is - captured, it can be used at a later time to gain access to the - system. One-time password systems are designed to counter this type - of attack, called a "replay attack" [4]. - - The authentication system described in this document uses a secret - pass-phrase to generate a sequence of one-time (single use) - passwords. With this system, the user's secret pass-phrase never - needs to cross the network at any time such as during authentication - - - -Haller Standards Track [Page 1] - -RFC 2289 A One-Time Password System February 1998 - - - or during pass-phrase changes. Thus, it is not vulnerable to replay - attacks. Added security is provided by the property that no secret - information need be stored on any system, including the server being - protected. - - The OTP system protects against external passive attacks against the - authentication subsystem. It does not prevent a network eavesdropper - from gaining access to private information and does not provide - protection against either "social engineering" or active attacks [9]. - -3.0 INTRODUCTION - - There are two entities in the operation of the OTP one-time password - system. The generator must produce the appropriate one-time password - from the user's secret pass-phrase and from information provided in - the challenge from the server. The server must send a challenge that - includes the appropriate generation parameters to the generator, must - verify the one-time password received, must store the last valid - one-time password it received, and must store the corresponding one- - time password sequence number. The server must also facilitate the - changing of the user's secret pass-phrase in a secure manner. - - The OTP system generator passes the user's secret pass-phrase, along - with a seed received from the server as part of the challenge, - through multiple iterations of a secure hash function to produce a - one-time password. After each successful authentication, the number - of secure hash function iterations is reduced by one. Thus, a unique - sequence of passwords is generated. The server verifies the one-time - password received from the generator by computing the secure hash - function once and comparing the result with the previously accepted - one-time password. This technique was first suggested by Leslie - Lamport [1]. - -4.0 REQUIREMENTS TERMINOLOGY - - In this document, the words that are used to define the significance - of each particular requirement are usually capitalized. These words - are: - - - MUST - - This word or the adjective "REQUIRED" means that the item is an - absolute requirement of the specification. - - - - - - - - -Haller Standards Track [Page 2] - -RFC 2289 A One-Time Password System February 1998 - - - - SHOULD - - This word or the adjective "RECOMMENDED" means that there might - exist valid reasons in particular circumstances to ignore this - item, but the full implications should be understood and the case - carefully weighed before taking a different course. - - - MAY - - This word or the adjective "OPTIONAL" means that this item is - truly optional. One vendor might choose to include the item - because a particular marketplace requires it or because it - enhances the product, for example; another vendor may omit the - same item. - -5.0 SECURE HASH FUNCTION - - The security of the OTP system is based on the non-invertability of a - secure hash function. Such a function must be tractable to compute in - the forward direction, but computationally infeasible to invert. - - The interfaces are currently defined for three such hash algorithms, - MD4 [2] and MD5 [6] by Ronald Rivest, and SHA [7] by NIST. All - conforming implementations of both server and generators MUST support - MD5. They SHOULD support SHA and MAY also support MD4. Clearly, the - generator and server must use the same algorithm in order to - interoperate. Other hash algorithms may be specified for use with - this system by publishing the appropriate interfaces. - - The secure hash algorithms listed above have the property that they - accept an input that is arbitrarily long and produce a fixed size - output. The OTP system folds this output to 64 bits using the - algorithms in the Appendix A. 64 bits is also the length of the one- - time passwords. This is believed to be long enough to be secure and - short enough to be entered manually (see below, Form of Output) when - necessary. - -6.0 GENERATION OF ONE-TIME PASSWORDS - - This section describes the generation of the one-time passwords. - This process consists of an initial step in which all inputs are - combined, a computation step where the secure hash function is - applied a specified number of times, and an output function where the - 64 bit one-time password is converted to a human readable form. - - Appendix C contains examples of the outputs given a collection of - inputs. It provides implementors with a means of verification the - use of these algorithms. - - - -Haller Standards Track [Page 3] - -RFC 2289 A One-Time Password System February 1998 - - - Initial Step - - In principle, the user's secret pass-phrase may be of any length. To - reduce the risk from techniques such as exhaustive search or - dictionary attacks, character string pass-phrases MUST contain at - least 10 characters (see Form of Inputs below). All implementations - MUST support a pass-phrases of at least 63 characters. The secret - pass-phrase is frequently, but is not required to be, textual - information provided by a user. - - In this step, the pass phrase is concatenated with a seed that is - transmitted from the server in clear text. This non-secret seed - allows clients to use the same secret pass-phrase on multiple - machines (using different seeds) and to safely recycle their secret - pass-phrases by changing the seed. - - The result of the concatenation is passed through the secure hash - function and then is reduced to 64 bits using one of the function - dependent algorithms shown in Appendix A. - - Computation Step - - A sequence of one-time passwords is produced by applying the secure - hash function multiple times to the output of the initial step - (called S). That is, the first one-time password to be used is - produced by passing S through the secure hash function a number of - times (N) specified by the user. The next one-time password to be - used is generated by passing S though the secure hash function N-1 - times. An eavesdropper who has monitored the transmission of a one- - time password would not be able to generate the next required - password because doing so would mean inverting the hash function. - - Form of Inputs - - The secret pass-phrase is seen only by the OTP generator. To allow - interchangeability of generators, all generators MUST support a - secret pass-phrase of 10 to 63 characters. Implementations MAY - support a longer pass-phrase, but such implementations risk the loss - of interchangeability with implementations supporting only the - minimum. - - The seed MUST consist of purely alphanumeric characters and MUST be - of one to 16 characters in length. The seed is a string of characters - that MUST not contain any blanks and SHOULD consist of strictly - alphanumeric characters from the ISO-646 Invariant Code Set. The - seed MUST be case insensitive and MUST be internally converted to - lower case before it is processed. - - - - -Haller Standards Track [Page 4] - -RFC 2289 A One-Time Password System February 1998 - - - The sequence number and seed together constitute a larger unit of - data called the challenge. The challenge gives the generator the - parameters it needs to calculate the correct one-time password from - the secret pass-phrase. The challenge MUST be in a standard syntax so - that automated generators can recognize the challenge in context and - extract these parameters. The syntax of the challenge is: - - otp- - - The three tokens MUST be separated by a white space (defined as any - number of spaces and/or tabs) and the entire challenge string MUST be - terminated with either a space or a new line. The string "otp-" MUST - be in lower case. The algorithm identifier is case sensitive (the - existing identifiers are all lower case), and the seed is case - insensitive and converted before use to lower case. If additional - algorithms are defined, appropriate identifiers (short, but not - limited to three or four characters) must be defined. The currently - defined algorithm identifiers are: - - md4 MD4 Message Digest - md5 MD5 Message Digest - sha1 NIST Secure Hash Algorithm Revision 1 - - An example of an OTP challenge is: otp-md5 487 dog2 - - Form of Output - - The one-time password generated by the above procedure is 64 bits in - length. Entering a 64 bit number is a difficult and error prone - process. Some generators insert this password into the input stream - and some others make it available for system "cut and paste." Still - other arrangements require the one-time password to be entered - manually. The OTP system is designed to facilitate this manual entry - without impeding automatic methods. The one-time password therefore - MAY be converted to, and all servers MUST be capable of accepting it - as, a sequence of six short (1 to 4 letter) easily typed words that - only use characters from ISO-646 IVCS. Each word is chosen from a - dictionary of 2048 words; at 11 bits per word, all one-time passwords - may be encoded. - - The two extra bits in this encoding are used to store a checksum. - The 64 bits of key are broken down into pairs of bits, then these - pairs are summed together. The two least significant bits of this sum - are encoded in the last two bits of the six word sequence with the - least significant bit of the sum as the last bit encoded. All OTP - generators MUST calculate this checksum and all OTP servers MUST - verify this checksum explicitly as part of the operation of decoding - this representation of the one-time password. - - - -Haller Standards Track [Page 5] - -RFC 2289 A One-Time Password System February 1998 - - - Generators that produce the six-word format MUST present the words in - upper case with single spaces used as separators. All servers MUST - accept six-word format without regard to case and white space used as - a separator. The two lines below represent the same one-time - password. The first is valid as output from a generator and as input - a server, the second is valid only as human input to a server. - - OUST COAT FOAL MUG BEAK TOTE - oust coat foal mug beak tote - - Interoperability requires that all OTP servers and generators use - the same dictionary. The standard dictionary was originally - specified in the "S/KEY One Time Password System" that is described - in RFC 1760 [5]. This dictionary is included in this document as - Appendix D. - - To facilitate the implementation of smaller generators, hexadecimal - output is an acceptable alternative for the presentation of the - one-time password. All implementations of the server software MUST - accept case-insensitive hexadecimal as well as six-word format. The - hexadecimal digits may be separated by white space so servers are - REQUIRED to ignore all white space. If the representation is - partitioned by white space, leading zeros must be retained. - Examples of hexadecimal format are: - - Representation Value - - 3503785b369cda8b 0x3503785b369cda8b - e5cc a1b8 7c13 096b 0xe5cca1b87c13096b - C7 48 90 F4 27 7B A1 CF 0xc74890f4277ba1cf - 47 9 A68 28 4C 9D 0 1BC 0x479a68284c9d01bc - - In addition to accepting six-word and hexadecimal encodings of the - 64 bit one-time password, servers SHOULD accept the alternate - dictionary encoding described in Appendix B. The six words in this - encoding MUST not overlap the set of words in the standard - dictionary. To avoid ambiguity with the hexadecimal representation, - words in the alternate dictionary MUST not be comprised solely of - the letters A-F. Decoding words thus encoded does not require any - knowledge of the alternative dictionary used so the acceptance of - any alternate dictionary implies the acceptance of all alternate - dictionaries. Words in the alternative dictionaries are case - sensitive. Generators and servers MUST preserve the case in the - processing of these words. - - In summary, all conforming servers MUST accept six-word input that - uses the Standard Dictionary (RFC 1760 and Appendix D), MUST accept - hexadecimal encoding, and SHOULD accept six-word input that uses the - - - -Haller Standards Track [Page 6] - -RFC 2289 A One-Time Password System February 1998 - - - Alternative Dictionary technique (Appendix B). As there is a remote - possibility that a hexadecimal encoding of a one-time password will - look like a valid six-word standard dictionary encoding, all - implementations MUST use the following scheme. If a six-word - encoded one-time password is valid, it is accepted. Otherwise, if - the one-time password can be interpreted as hexadecimal, and with - that decoding it is valid, then it is accepted. - -7.0 VERIFICATION OF ONE-TIME PASSWORDS - - An application on the server system that requires OTP authentication - is expected to issue an OTP challenge as described above. Given the - parameters from this challenge and the secret pass-phrase, the - generator can compute (or lookup) the one-time password that is - passed to the server to be verified. - - The server system has a database containing, for each user, the - one-time password from the last successful authentication or the - first OTP of a newly initialized sequence. To authenticate the user, - the server decodes the one-time password received from the generator - into a 64-bit key and then runs this key through the secure hash - function once. If the result of this operation matches the stored - previous OTP, the authentication is successful and the accepted - one-time password is stored for future use. - -8.0 PASS-PHRASE CHANGES - - Because the number of hash function applications executed by the - generator decreases by one each time, at some point the user must - reinitialize the system or be unable to authenticate. - - Although some installations may not permit users to initialize - remotely, implementations MUST provide a means to do so that does - not reveal the user's secret pass-phrase. One way is to provide a - means to reinitialize the sequence through explicit specification - of the first one-time password. - - When the sequence of one-time passwords is reinitialized, - implementations MUST verify that the seed or the pass-phrase is - changed. Installations SHOULD discourage any operation that sends - the secret pass-phrase over a network in clear-text as such practice - defeats the concept of a one-time password. - - Implementations MAY use the following technique for - [re]initialization: - - - - - - -Haller Standards Track [Page 7] - -RFC 2289 A One-Time Password System February 1998 - - - o The user picks a new seed and hash count (default values may - be offered). The user provides these, along with the - corresponding generated one-time password, to the host system. - - o The user MAY also provide the corresponding generated one - time password for count-1 as an error check. - - o The user SHOULD provide the generated one-time password for - the old seed and old hash count to protect an idle terminal - or workstation (this implies that when the count is 1, the - user can login but cannot then change the seed or count). - - In the future a specific protocol may be defined for - reinitialization that will permit smooth and possibly automated - interoperation of all hosts and generators. - -9.0 PROTECTION AGAINST RACE ATTACK - - All conforming server implementations MUST protect against the race - condition described in this section. A defense against this attack - is outlined; implementations MAY use this approach or MAY select an - alternative defense. - - It is possible for an attacker to listen to most of a one-time - password, guess the remainder, and then race the legitimate user to - complete the authentication. Multiple guesses against the last word - of the six-word format are likely to succeed. - - One possible defense is to prevent a user from starting multiple - simultaneous authentication sessions. This means that once the - legitimate user has initiated authentication, an attacker would be - blocked until the first authentication process has completed. In - this approach, a timeout is necessary to thwart a denial of service - attack. - -10.0 SECURITY CONSIDERATIONS - - This entire document discusses an authentication system that - improves security by limiting the danger of eavesdropping/replay - attacks that have been used against simple password systems [4]. - - The use of the OTP system only provides protections against passive - eavesdropping/replay attacks. It does not provide for the privacy - of transmitted data, and it does not provide protection against - active attacks such as session hijacking that are known to be - present in the current Internet [9]. The use of IP Security - (IPsec), see [10], [11], and [12] is recommended to protect against - TCP session hijacking. - - - -Haller Standards Track [Page 8] - -RFC 2289 A One-Time Password System February 1998 - - - The success of the OTP system to protect host systems is dependent - on the non-invertability of the secure hash functions used. To our - knowledge, none of the hash algorithms have been broken, but it is - generally believed [6] that MD4 is not as strong as MD5. If a - server supports multiple hash algorithms, it is only as secure as - the weakest algorithm. - -11.0 ACKNOWLEDGMENTS - - The idea behind OTP authentication was first proposed by Leslie - Lamport [1]. Bellcore's S/KEY system, from which OTP is derived, was - proposed by Phil Karn, who also wrote most of the Bellcore reference - implementation. - -12.0 REFERENCES - - [1] Leslie Lamport, "Password Authentication with Insecure - Communication", Communications of the ACM 24.11 (November - 1981), 770-772 - - [2] Rivest, R., "The MD4 Message-Digest Algorithm", RFC 1320, - April 1992. - - [3] Neil Haller, "The S/KEY One-Time Password System", Proceedings - of the ISOC Symposium on Network and Distributed System - Security, February 1994, San Diego, CA - - [4] Haller, N., and R. Atkinson, "On Internet Authentication", - RFC 1704, October 1994. - - [5] Haller, N., "The S/KEY One-Time Password System", - RFC 1760, February 1995. - - [6] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, - April 1992. - - [7] National Institute of Standards and Technology (NIST), - "Announcing the Secure Hash Standard", FIPS 180-1, U.S. - Department of Commerce, April 1995. - - [8] International Standard - Information Processing -- ISO 7-bit - coded character set for information interchange (Invariant Code - Set), ISO-646, International Standards Organization, Geneva, - Switzerland, 1983 - - - - - - - -Haller Standards Track [Page 9] - -RFC 2289 A One-Time Password System February 1998 - - - [9] Computer Emergency Response Team (CERT), "IP Spoofing and - Hijacked Terminal Connections", CA-95:01, January 1995. - Available via anonymous ftp from info.cert.org in - /pub/cert_advisories. - - [10] Atkinson, R., "Security Architecture for the Internet Protocol", - RFC 1825, August 1995. - - [11] Atkinson, R., "IP Authentication Header", RFC 1826, August - 1995. - - [12] Atkinson, R., "IP Encapsulating Security Payload (ESP)", RFC - 1827, August 1995. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Haller Standards Track [Page 10] - -RFC 2289 A One-Time Password System February 1998 - - -13.0 AUTHORS' ADDRESSES - - Neil Haller - Bellcore - MCC 1C-265B - 445 South Street - Morristown, NJ, 07960-6438, USA - - Phone: +1 201 829-4478 - Fax: +1 201 829-2504 - EMail: nmh@bellcore.com - - - Craig Metz - Kaman Sciences Corporation - For NRL Code 5544 - 4555 Overlook Avenue, S.W. - Washington, DC, 20375-5337, USA - - Phone: +1 202 404-7122 - Fax: +1 202 404-7942 - EMail: cmetz@cs.nrl.navy.mil - - - Philip J. Nesser II - Nesser & Nesser Consulting - 13501 100th Ave NE - Suite 5202 - Kirkland, WA 98034, USA - - Phone: +1 206 481 4303 - EMail: pjnesser@martigny.ai.mit.edu - - - Mike Straw - Bellcore - RRC 1A-225 - 445 Hoes Lane - Piscataway, NJ 08854-4182 - - Phone: +1 908 699-5212 - EMail: mess@bellcore.com - - - - - - - - - -Haller Standards Track [Page 11] - -RFC 2289 A One-Time Password System February 1998 - - -Appendix A - Interfaces to Secure Hash Algorithms - - Original interoperability tests provided valuable insights into the - subtle problems which occur when converting protocol specifications - into running code. In particular, the manipulation of bit ordered - data is dependent on the architecture of the hardware, specifically - the way in which a computer stores multi-byte data. The method is - typically called big or little "endian." A big endian machine stores - data with the most significant byte first, while a little endian - machine stores the least significant byte first. Thus, on a big - endian machine data is stored left to right, while little endian - machines store data right to left. - - For example, the four byte value 0x11AABBCC is stored in a big endian - machine as the following series of four bytes, "0x11", "0xAA", - "0xBB", and "0xCC", while on a little endian machine the value would - be stored as "0xCC", "0xBB", "0xAA", and "0x11". - - For historical reasons, and to promote interoperability with existing - implementations, it was decided that ALL hashes incorporated into the - OTP protocol MUST store the output of their hash function in LITTLE - ENDIAN format BEFORE the bit folding to 64 bits occurs. This is done - in the implementations of MD4 and MD5 (see references [2] and [6]), - while it must be explicitly done for the implementation of SHA1 (see - reference [7]). - - Any future hash functions implemented into the OTP protocol SHOULD - provide a similar reference fragment of code to allow independent - implementations to operate successfully. - - - MD4 Message Digest (see reference [2]) - - MD4_CTX md; - unsigned char result[16]; - - strcpy(buf, seed); /* seed must be in lower case */ - strcat(buf, passwd); - MD4Init(&md); - MD4Update(&md, (unsigned char *)buf, strlen(buf)); - MD4Final(result, &md); - - /* Fold the 128 bit result to 64 bits */ - for (i = 0; i < 8; i++) - result[i] ^= result[i+8]; - - - - - - -Haller Standards Track [Page 12] - -RFC 2289 A One-Time Password System February 1998 - - -MD5 Message Digest (see reference [6]) - - MD5_CTX md; - unsigned char result[16]; - strcpy(buf, seed); /* seed must be in lower case */ - strcat(buf, passwd); - MD5Init(&md); - MD5Update(&md, (unsigned char *)buf, strlen(buf)); - MD5Final(result, &md); - - /* Fold the 128 bit result to 64 bits */ - for (i = 0; i < 8; i++) - result[i] ^= result[i+8]; - - -SHA Secure Hash Algorithm (see reference [7]) - - SHA_INFO sha; - unsigned char result[16]; - strcpy(buf, seed); /* seed must be in lower case */ - strcat(buf, passwd); - sha_init(&sha); - sha_update(&sha, (unsigned char *)buf, strlen(buf)); - sha_final(&sha); /* NOTE: no result buffer */ - - /* Fold the 160 bit result to 64 bits */ - sha.digest[0] ^= sha.digest[2]; - sha.digest[1] ^= sha.digest[3]; - sha.digest[0] ^= sha.digest[4]; - - /* - * copy the resulting 64 bits to the result buffer in little endian - * fashion (analogous to the way MD4Final() and MD5Final() do). - */ - for (i = 0, j = 0; j < 8; i++, j += 4) - { - result[j] = (unsigned char)(sha.digest[i] & 0xff); - result[j+1] = (unsigned char)((sha.digest[i] >> 8) & 0xff); - result[j+2] = (unsigned char)((sha.digest[i] >> 16) & 0xff); - result[j+3] = (unsigned char)((sha.digest[i] >> 24) & 0xff); - } - - - - - - - - - - -Haller Standards Track [Page 13] - -RFC 2289 A One-Time Password System February 1998 - - -Appendix B - Alternative Dictionary Algorithm - - The purpose of alternative dictionary encoding of the OTP one-time - password is to allow the use of language specific or friendly words. - As case translation is not always well defined, the alternative - dictionary encoding is case sensitive. Servers SHOULD accept this - encoding in addition to the standard 6-word and hexadecimal - encodings. - - - GENERATOR ENCODING USING AN ALTERNATE DICTIONARY - - The standard 6-word encoding uses the placement of a word in the - dictionary to represent an 11-bit number. The 64-bit one-time - password can then be represented by six words. - - An alternative dictionary of 2048 words may be created such that - each word W and position of the word in the dictionary N obey the - relationship: - - alg( W ) % 2048 == N - where - alg is the hash algorithm used (e.g. MD4, MD5, SHA1). - - In addition, no words in the standard dictionary may be chosen. - - The generator expands the 64-bit one-time password to 66 bits by - computing parity as with the standard 6-word encoding. The six 11- - bit numbers are then converted to words using the dictionary that - was created such that the above relationship holds. - - SERVER DECODING OF ALTERNATE DICTIONARY ONE-TIME PASSWORDS - - The server accepting alternative dictionary encoding converts each - word to an 11-bit number using the above encoding. These numbers - are then used in the same way as the decoded standard dictionary - words to form the 66-bit one-time password. - - The server does not need to have access to the alternate dictionary - that was used to create the one-time password it is authenticating. - This is because the decoding from word to 11-bit number does not - make any use of the dictionary. As a result of the independence of - the dictionary, a server accepting one alternate dictionary accept - all alternate dictionaries. - - - - - - - -Haller Standards Track [Page 14] - -RFC 2289 A One-Time Password System February 1998 - - -Appendix C - OTP Verification Examples - - This appendix provides a series of inputs and correct outputs for all - three of the defined OTP cryptographic hashes, specifically MD4, MD5, - and SHA1. This document is intended to be used by developers for - interoperability checks when creating generators or servers. Output - is provided in both hexadecimal notation and the six word encoding - documented in Appendix D. - - GENERAL CHECKS - - Note that the output given for these checks is not intended to be - taken literally, but describes the type of action that should be - taken. - - Pass Phrase Length - - Input: - Pass Phrase: Too_short - Seed: iamvalid - Count: 99 - Hash: ANY - Output: - ERROR: Pass Phrase too short - - Input: - Pass Phrase: - 1234567890123456789012345678901234567890123456789012345678901234 - Seed: iamvalid - Count: 99 - Hash: ANY - Output: - WARNING: Pass Phrase longer than the recommended maximum length of -63 - -Seed Values - - Input: - Pass Phrase: A_Valid_Pass_Phrase - Seed: Length_Okay - Count: 99 - Hash: ANY - Output: - ERROR: Seed must be purely alphanumeric - - Input: - Pass Phrase: A_Valid_Pass_Phrase - Seed: LengthOfSeventeen - - - -Haller Standards Track [Page 15] - -RFC 2289 A One-Time Password System February 1998 - - - Count: 99 - Hash: ANY - - Output: - ERROR: Seed must be between 1 and 16 characters in length - - Input: - Pass Phrase: A_Valid_Pass_Phrase - Seed: A Seed - Count: 99 - Hash: ANY - Output: - ERROR: Seed must not contain any spaces - -Parity Calculations - - Input: - Pass Phrase: A_Valid_Pass_Phrase - Seed: AValidSeed - Count: 99 - Hash: MD5 - Output: - Hex: 85c43ee03857765b - Six Word(CORRECT): FOWL KID MASH DEAD DUAL OAF - Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL NUT - Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL O - Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL OAK - - - - - - - - - - - - - - - - - - - - - - - - -Haller Standards Track [Page 16] - -RFC 2289 A One-Time Password System February 1998 - - -MD4 ENCODINGS - -Pass Phrase Seed Cnt Hex Six Word Format -======================================================================== -This is a test. TeSt 0 D185 4218 EBBB 0B51 - ROME MUG FRED SCAN LIVE LACE -This is a test. TeSt 1 6347 3EF0 1CD0 B444 - CARD SAD MINI RYE COL KIN -This is a test. TeSt 99 C5E6 1277 6E6C 237A - NOTE OUT IBIS SINK NAVE MODE -AbCdEfGhIjK alpha1 0 5007 6F47 EB1A DE4E - AWAY SEN ROOK SALT LICE MAP -AbCdEfGhIjK alpha1 1 65D2 0D19 49B5 F7AB - CHEW GRIM WU HANG BUCK SAID -AbCdEfGhIjK alpha1 99 D150 C82C CE6F 62D1 - ROIL FREE COG HUNK WAIT COCA -OTP's are good correct 0 849C 79D4 F6F5 5388 - FOOL STEM DONE TOOL BECK NILE -OTP's are good correct 1 8C09 92FB 2508 47B1 - GIST AMOS MOOT AIDS FOOD SEEM -OTP's are good correct 99 3F3B F4B4 145F D74B - TAG SLOW NOV MIN WOOL KENO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Haller Standards Track [Page 17] - -RFC 2289 A One-Time Password System February 1998 - - -MD5 ENCODINGS - -Pass Phrase Seed Cnt Hex Six Word Format -======================================================================== -This is a test. TeSt 0 9E87 6134 D904 99DD - INCH SEA ANNE LONG AHEM TOUR -This is a test. TeSt 1 7965 E054 36F5 029F - EASE OIL FUM CURE AWRY AVIS -This is a test. TeSt 99 50FE 1962 C496 5880 - BAIL TUFT BITS GANG CHEF THY -AbCdEfGhIjK alpha1 0 8706 6DD9 644B F206 - FULL PEW DOWN ONCE MORT ARC -AbCdEfGhIjK alpha1 1 7CD3 4C10 40AD D14B - FACT HOOF AT FIST SITE KENT -AbCdEfGhIjK alpha1 99 5AA3 7A81 F212 146C - BODE HOP JAKE STOW JUT RAP -OTP's are good correct 0 F205 7539 43DE 4CF9 - ULAN NEW ARMY FUSE SUIT EYED -OTP's are good correct 1 DDCD AC95 6F23 4937 - SKIM CULT LOB SLAM POE HOWL -OTP's are good correct 99 B203 E28F A525 BE47 - LONG IVY JULY AJAR BOND LEE - - -SHA1 ENCODINGS - -Pass Phrase Seed Cnt Hex Six Word Format -======================================================================== -This is a test. TeSt 0 BB9E 6AE1 979D 8FF4 - MILT VARY MAST OK SEES WENT -This is a test. TeSt 1 63D9 3663 9734 385B - CART OTTO HIVE ODE VAT NUT -This is a test. TeSt 99 87FE C776 8B73 CCF9 - GAFF WAIT SKID GIG SKY EYED -AbCdEfGhIjK alpha1 0 AD85 F658 EBE3 83C9 - LEST OR HEEL SCOT ROB SUIT -AbCdEfGhIjK alpha1 1 D07C E229 B5CF 119B - RITE TAKE GELD COST TUNE RECK -AbCdEfGhIjK alpha1 99 27BC 7103 5AAF 3DC6 - MAY STAR TIN LYON VEDA STAN -OTP's are good correct 0 D51F 3E99 BF8E 6F0B - RUST WELT KICK FELL TAIL FRAU -OTP's are good correct 1 82AE B52D 9437 74E4 - FLIT DOSE ALSO MEW DRUM DEFY -OTP's are good correct 99 4F29 6A74 FE15 67EC - AURA ALOE HURL WING BERG WAIT - - - - - -Haller Standards Track [Page 18] - -RFC 2289 A One-Time Password System February 1998 - - -Appendix D - Dictionary for Converting Between 6-Word and Binary Formats - - This dictionary is from the module put.c in the original Bellcore - reference distribution. - -{ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", -"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", -"AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", -"APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", -"ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", -"AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", -"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", -"BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", -"BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", -"BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", -"BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", -"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", -"COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", -"DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", -"DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", -"DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", -"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", -"EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", -"EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", -"FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", -"FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", -"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", -"GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", -"GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", -"GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", -"HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", -"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", -"HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", -"HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", -"I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", -"IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", -"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", -"JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", -"JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", -"KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", -"LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", -"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", -"LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", -"LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", -"MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", -"MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", -"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", -"MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", - - - -Haller Standards Track [Page 19] - -RFC 2289 A One-Time Password System February 1998 - - -"NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", -"NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", -"NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", -"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", -"OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", -"ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", -"OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", -"PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", -"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", -"PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", -"POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", -"QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", -"REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", -"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", -"ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", -"SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", -"SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", -"SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", -"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", -"SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", -"TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", -"TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", -"TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", -"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", -"UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", -"WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", -"WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", -"WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", -"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", -"ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", -"ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", -"AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", -"ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", -"AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", -"ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", -"AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", -"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", -"AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", -"BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", -"BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", -"BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", -"BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", -"BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", -"BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", -"BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", -"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", -"BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", -"BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", - - - -Haller Standards Track [Page 20] - -RFC 2289 A One-Time Password System February 1998 - - -"BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", -"BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", -"BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", -"BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", -"BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", -"BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", -"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", -"CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", -"CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", -"CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", -"CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", -"CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", -"CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", -"CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", -"CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", -"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", -"COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", -"CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", -"CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD", -"CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA", -"DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH", -"DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", -"DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER", -"DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", -"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", -"DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", -"DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", -"DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", -"DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", -"DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST", -"DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN", -"ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN", -"ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", -"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", -"FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", -"FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", -"FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF", -"FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE", -"FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK", -"FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC", -"FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", -"FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", -"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", -"FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", -"FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", -"GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL", -"GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL", -"GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM", - - - -Haller Standards Track [Page 21] - -RFC 2289 A One-Time Password System February 1998 - - -"GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", -"GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", -"GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", -"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", -"GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", -"GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", -"GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN", -"GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", -"HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", -"HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL", -"HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE", -"HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", -"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", -"HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", -"HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", -"HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", -"HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK", -"HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK", -"HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS", -"ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS", -"IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", -"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", -"JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", -"JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", -"JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", -"JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN", -"KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO", -"KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING", -"KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", -"KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", -"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", -"LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", -"LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", -"LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", -"LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", -"LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", -"LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", -"LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", -"LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", -"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", -"LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", -"LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", -"LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", -"MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", -"MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", -"MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", -"MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", -"MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", - - - -Haller Standards Track [Page 22] - -RFC 2289 A One-Time Password System February 1998 - - -"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", -"MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", -"MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", -"MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", -"MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", -"MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", -"MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", -"NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", -"NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", -"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", -"NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", -"NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", -"OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", -"OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", -"ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", -"OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", -"QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", -"RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", -"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", -"REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", -"REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", -"RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR", -"ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", -"ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", -"ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY", -"RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK", -"RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", -"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", -"SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", -"SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", -"SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", -"SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE", -"SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH", -"SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK", -"SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM", -"SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", -"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", -"SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", -"SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", -"SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL", -"SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM", -"STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT", -"SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG", -"SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", -"TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", -"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", -"TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", -"THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", - - - -Haller Standards Track [Page 23] - -RFC 2289 A One-Time Password System February 1998 - - -"THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL", -"TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD", -"TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", -"TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", -"TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO", -"TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", -"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", -"TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", -"VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", -"VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", -"VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", -"WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT", -"WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART", -"WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK", -"WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", -"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", -"WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", -"WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", -"WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK", -"WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK", -"YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA", -"YOKE" }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Haller Standards Track [Page 24] - -RFC 2289 A One-Time Password System February 1998 - - -Full Copyright Statement - - Copyright (C) The Internet Society (1998). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Haller Standards Track [Page 25] - diff --git a/doc/rfc2444.txt b/doc/rfc2444.txt deleted file mode 100644 index 80a65a2a..00000000 --- a/doc/rfc2444.txt +++ /dev/null @@ -1,395 +0,0 @@ - - - - - - -Network Working Group C. Newman -Request for Comments: 2444 Innosoft -Updates: 2222 October 1998 -Category: Standards Track - - - The One-Time-Password SASL Mechanism - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1998). All Rights Reserved. - -Abstract - - OTP [OTP] provides a useful authentication mechanism for situations - where there is limited client or server trust. Currently, OTP is - added to protocols in an ad-hoc fashion with heuristic parsing. This - specification defines an OTP SASL [SASL] mechanism so it can be - easily and formally integrated into many application protocols. - -1. How to Read This Document - - The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", - "RECOMMENDED" and "MAY" in this document are to be interpreted as - defined in "Key words for use in RFCs to Indicate Requirement Levels" - [KEYWORDS]. - - This memo assumes the reader is familiar with OTP [OTP], OTP extended - responses [OTP-EXT] and SASL [SASL]. - -2. Intended Use - - The OTP SASL mechanism replaces the SKEY SASL mechanism [SASL]. OTP - is a good choice for usage scenarios where the client is untrusted - (e.g., a kiosk client), as a one-time password will only give the - client a single opportunity to act on behalf of the user. OTP is - also a good choice for situations where interactive logins are - permitted to the server, as a compromised OTP authentication database - is only subject to dictionary attacks, unlike authentication - databases for other simple mechanisms such as CRAM-MD5 [CRAM-MD5]. - - - -Newman Standards Track [Page 1] - -RFC 2444 OTP SASL Mechanism October 1998 - - - It is important to note that each use of the OTP mechanism causes the - authentication database entry for a user to be updated. - - This SASL mechanism provides a formal way to integrate OTP into - SASL-enabled protocols including IMAP [IMAP4], ACAP [ACAP], POP3 - [POP-AUTH] and LDAPv3 [LDAPv3]. - -3. Profiling OTP for SASL - - OTP [OTP] and OTP extended responses [OTP-EXT] offer a number of - options. However, for authentication to succeed, the client and - server need compatible option sets. This specification defines a - single SASL mechanism: OTP. The following rules apply to this - mechanism: - - o The extended response syntax MUST be used. - - o Servers MUST support the following four OTP extended responses: - "hex", "word", "init-hex" and "init-word". Servers MUST support - the "word" and "init-word" responses for the standard dictionary - and SHOULD support alternate dictionaries. Servers MUST NOT - require use of any additional OTP extensions or options. - - o Clients SHOULD support display of the OTP challenge to the user - and entry of an OTP in multi-word format. Clients MAY also - support direct entry of the pass phrase and compute the "hex" or - "word" response. - - o Clients MUST indicate when authentication fails due to the - sequence number getting too low and SHOULD offer the user the - option to reset the sequence using the "init-hex" or "init-word" - response. - - Support for the MD5 algorithm is REQUIRED, and support for the SHA1 - algorithm is RECOMMENDED. - -4. OTP Authentication Mechanism - - The mechanism does not provide any security layer. - - The client begins by sending a message to the server containing the - following two pieces of information. - - (1) An authorization identity. When the empty string is used, this - defaults to the authentication identity. This is used by system - administrators or proxy servers to login with a different user - identity. This field may be up to 255 octets and is terminated by a - NUL (0) octet. US-ASCII printable characters are preferred, although - - - -Newman Standards Track [Page 2] - -RFC 2444 OTP SASL Mechanism October 1998 - - - UTF-8 [UTF-8] printable characters are permitted to support - international names. Use of character sets other than US-ASCII and - UTF-8 is forbidden. - - (2) An authentication identity. The identity whose pass phrase will - be used. This field may be up to 255 octets. US-ASCII printable - characters are preferred, although UTF-8 [UTF-8] printable characters - are permitted to support international names. Use of character sets - other than US-ASCII and UTF-8 is forbidden. - - The server responds by sending a message containing the OTP challenge - as described in OTP [OTP] and OTP extended responses [OTP-EXT]. - - If a client sees an unknown hash algorithm name it will not be able - to process a pass phrase input by the user. In this situation the - client MAY prompt for the six-word format, issue the cancel sequence - as specified by the SASL profile for the protocol in use and try a - different SASL mechanism, or close the connection and refuse to - authenticate. As a result of this behavior, a server is restricted - to one OTP hash algorithm per user. - - On success, the client generates an extended response in the "hex", - "word", "init-hex" or "init-word" format. The client is not required - to terminate the response with a space or a newline and SHOULD NOT - include unnecessary whitespace. - - Servers MUST tolerate input of arbitrary length, but MAY fail the - authentication if the length of client input exceeds reasonable size. - -5. Examples - - In these example, "C:" represents lines sent from the client to the - server and "S:" represents lines sent from the server to the client. - The user name is "tim" and no authorization identity is provided. - The "" below represents an ASCII NUL octet. - - The following is an example of the OTP mechanism using the ACAP - [ACAP] profile of SASL. The pass phrase used in this example is: - This is a test. - - C: a001 AUTHENTICATE "OTP" {4} - C: tim - S: + "otp-md5 499 ke1234 ext" - C: "hex:5bf075d9959d036f" - S: a001 OK "AUTHENTICATE completed" - - - - - - -Newman Standards Track [Page 3] - -RFC 2444 OTP SASL Mechanism October 1998 - - - Here is the same example using the six-words response: - - C: a001 AUTHENTICATE "OTP" {4} - C: tim - S: + "otp-md5 499 ke1234 ext" - C: "word:BOND FOGY DRAB NE RISE MART" - S: a001 OK "AUTHENTICATE completed" - - Here is the same example using the OTP-SHA1 mechanism: - - C: a001 AUTHENTICATE "OTP" {4} - C: tim - S: + "otp-sha1 499 ke1234 ext" - C: "hex:c90fc02cc488df5e" - S: a001 OK "AUTHENTICATE completed" - - Here is the same example with the init-hex extended response - - C: a001 AUTHENTICATE "OTP" {4} - C: tim - S: + "otp-md5 499 ke1234 ext" - C: "init-hex:5bf075d9959d036f:md5 499 ke1235:3712dcb4aa5316c1" - S: a001 OK "OTP sequence reset, authentication complete" - - The following is an example of the OTP mechanism using the IMAP - [IMAP4] profile of SASL. The pass phrase used in this example is: - this is a test - - C: a001 AUTHENTICATE OTP - S: + - C: AHRpbQ== - S: + b3RwLW1kNSAxMjMga2UxMjM0IGV4dA== - C: aGV4OjExZDRjMTQ3ZTIyN2MxZjE= - S: a001 OK AUTHENTICATE completed - - Note that the lack of an initial client response and the base64 - encoding are characteristics of the IMAP profile of SASL. The server - challenge is "otp-md5 123 ke1234 ext" and the client response is - "hex:11d4c147e227c1f1". - -6. Security Considerations - - This specification introduces no security considerations beyond those - those described in SASL [SASL], OTP [OTP] and OTP extended responses - [OTP-EXT]. A brief summary of these considerations follows: - - This mechanism does not provide session privacy, server - authentication or protection from active attacks. - - - -Newman Standards Track [Page 4] - -RFC 2444 OTP SASL Mechanism October 1998 - - - This mechanism is subject to passive dictionary attacks. The - severity of this attack can be reduced by choosing pass phrases well. - - The server authentication database necessary for use with OTP need - not be plaintext-equivalent. - - Server implementations MUST protect against the race attack [OTP]. - -7. Multinational Considerations - - As remote access is a crucial service, users are encouraged to - restrict user names and pass phrases to the US-ASCII character set. - However, if characters outside the US-ASCII chracter set are used in - user names and pass phrases, then they are interpreted according to - UTF-8 [UTF-8]. - - Server support for alternate dictionaries is strongly RECOMMENDED to - permit use of the six-word format with non-English words. - -8. IANA Considerations - - Here is the registration template for the OTP SASL mechanism: - - SASL mechanism name: OTP - Security Considerations: See section 6 of this memo - Published specification: this memo - Person & email address to contact for futher information: - see author's address section below - Intended usage: COMMON - Author/Change controller: see author's address section below - - This memo also amends the SKEY SASL mechanism registration [SASL] by - changing its intended usage to OBSOLETE. - -9. References - - [ACAP] Newman, C. and J. Myers, "ACAP -- Application - Configuration Access Protocol", RFC 2244, November 1997. - - [CRAM-MD5] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP - AUTHorize Extension for Simple Challenge/Response", RFC - 2195, September 1997. - - [IMAP4] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - - -Newman Standards Track [Page 5] - -RFC 2444 OTP SASL Mechanism October 1998 - - - [LDAPv3] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory - Access Protocol (v3)", RFC 2251, December 1997. - - [MD5] Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321, - April 1992. - - [OTP] Haller, N., Metz, C., Nesser, P. and M. Straw, "A One-Time - Password System", RFC 2289, February 1998. - - [OTP-EXT] Metz, C., "OTP Extended Responses", RFC 2243, November - 1997. - - [POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734, - December 1994. - - [SASL] Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997. - - [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", RFC 2279, January 1998. - -10. Author's Address - - Chris Newman - Innosoft International, Inc. - 1050 Lakes Drive - West Covina, CA 91790 USA - - EMail: chris.newman@innosoft.com - - - - - - - - - - - - - - - - - - - - - - -Newman Standards Track [Page 6] - -RFC 2444 OTP SASL Mechanism October 1998 - - -11. Full Copyright Statement - - Copyright (C) The Internet Society (1998). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Newman Standards Track [Page 7] - diff --git a/doc/rfc2595.txt b/doc/rfc2595.txt deleted file mode 100644 index 3b2b4c5d..00000000 --- a/doc/rfc2595.txt +++ /dev/null @@ -1,843 +0,0 @@ - - - - - - -Network Working Group C. Newman -Request for Comments: 2595 Innosoft -Category: Standards Track June 1999 - - - Using TLS with IMAP, POP3 and ACAP - - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1999). All Rights Reserved. - -1. Motivation - - The TLS protocol (formerly known as SSL) provides a way to secure an - application protocol from tampering and eavesdropping. The option of - using such security is desirable for IMAP, POP and ACAP due to common - connection eavesdropping and hijacking attacks [AUTH]. Although - advanced SASL authentication mechanisms can provide a lightweight - version of this service, TLS is complimentary to simple - authentication-only SASL mechanisms or deployed clear-text password - login commands. - - Many sites have a high investment in authentication infrastructure - (e.g., a large database of a one-way-function applied to user - passwords), so a privacy layer which is not tightly bound to user - authentication can protect against network eavesdropping attacks - without requiring a new authentication infrastructure and/or forcing - all users to change their password. Recognizing that such sites will - desire simple password authentication in combination with TLS - encryption, this specification defines the PLAIN SASL mechanism for - use with protocols which lack a simple password authentication - command such as ACAP and SMTP. (Note there is a separate RFC for the - STARTTLS command in SMTP [SMTPTLS].) - - There is a strong desire in the IETF to eliminate the transmission of - clear-text passwords over unencrypted channels. While SASL can be - used for this purpose, TLS provides an additional tool with different - deployability characteristics. A server supporting both TLS with - - - - -Newman Standards Track [Page 1] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - simple passwords and a challenge/response SASL mechanism is likely to - interoperate with a wide variety of clients without resorting to - unencrypted clear-text passwords. - - The STARTTLS command rectifies a number of the problems with using a - separate port for a "secure" protocol variant. Some of these are - mentioned in section 7. - -1.1. Conventions Used in this Document - - The key words "REQUIRED", "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", - "MAY", and "OPTIONAL" in this document are to be interpreted as - described in "Key words for use in RFCs to Indicate Requirement - Levels" [KEYWORDS]. - - Terms related to authentication are defined in "On Internet - Authentication" [AUTH]. - - Formal syntax is defined using ABNF [ABNF]. - - In examples, "C:" and "S:" indicate lines sent by the client and - server respectively. - -2. Basic Interoperability and Security Requirements - - The following requirements apply to all implementations of the - STARTTLS extension for IMAP, POP3 and ACAP. - -2.1. Cipher Suite Requirements - - Implementation of the TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [TLS] cipher - suite is REQUIRED. This is important as it assures that any two - compliant implementations can be configured to interoperate. - - All other cipher suites are OPTIONAL. - -2.2. Privacy Operational Mode Security Requirements - - Both clients and servers SHOULD have a privacy operational mode which - refuses authentication unless successful activation of an encryption - layer (such as that provided by TLS) occurs prior to or at the time - of authentication and which will terminate the connection if that - encryption layer is deactivated. Implementations are encouraged to - have flexibility with respect to the minimal encryption strength or - cipher suites permitted. A minimalist approach to this - recommendation would be an operational mode where the - TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite is mandatory prior to - permitting authentication. - - - -Newman Standards Track [Page 2] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - Clients MAY have an operational mode which uses encryption only when - it is advertised by the server, but authentication continues - regardless. For backwards compatibility, servers SHOULD have an - operational mode where only the authentication mechanisms required by - the relevant base protocol specification are needed to successfully - authenticate. - -2.3. Clear-Text Password Requirements - - Clients and servers which implement STARTTLS MUST be configurable to - refuse all clear-text login commands or mechanisms (including both - standards-track and nonstandard mechanisms) unless an encryption - layer of adequate strength is active. Servers which allow - unencrypted clear-text logins SHOULD be configurable to refuse - clear-text logins both for the entire server, and on a per-user - basis. - -2.4. Server Identity Check - - During the TLS negotiation, the client MUST check its understanding - of the server hostname against the server's identity as presented in - the server Certificate message, in order to prevent man-in-the-middle - attacks. Matching is performed according to these rules: - - - The client MUST use the server hostname it used to open the - connection as the value to compare against the server name as - expressed in the server certificate. The client MUST NOT use any - form of the server hostname derived from an insecure remote source - (e.g., insecure DNS lookup). CNAME canonicalization is not done. - - - If a subjectAltName extension of type dNSName is present in the - certificate, it SHOULD be used as the source of the server's - identity. - - - Matching is case-insensitive. - - - A "*" wildcard character MAY be used as the left-most name - component in the certificate. For example, *.example.com would - match a.example.com, foo.example.com, etc. but would not match - example.com. - - - If the certificate contains multiple names (e.g. more than one - dNSName field), then a match with any one of the fields is - considered acceptable. - - If the match fails, the client SHOULD either ask for explicit user - confirmation, or terminate the connection and indicate the server's - identity is suspect. - - - -Newman Standards Track [Page 3] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - -2.5. TLS Security Policy Check - - Both the client and server MUST check the result of the STARTTLS - command and subsequent TLS negotiation to see whether acceptable - authentication or privacy was achieved. Ignoring this step - completely invalidates using TLS for security. The decision about - whether acceptable authentication or privacy was achieved is made - locally, is implementation-dependent, and is beyond the scope of this - document. - -3. IMAP STARTTLS extension - - When the TLS extension is present in IMAP, "STARTTLS" is listed as a - capability in response to the CAPABILITY command. This extension - adds a single command, "STARTTLS" to the IMAP protocol which is used - to begin a TLS negotiation. - -3.1. STARTTLS Command - - Arguments: none - - Responses: no specific responses for this command - - Result: OK - begin TLS negotiation - BAD - command unknown or arguments invalid - - A TLS negotiation begins immediately after the CRLF at the end of - the tagged OK response from the server. Once a client issues a - STARTTLS command, it MUST NOT issue further commands until a - server response is seen and the TLS negotiation is complete. - - The STARTTLS command is only valid in non-authenticated state. - The server remains in non-authenticated state, even if client - credentials are supplied during the TLS negotiation. The SASL - [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS - client credentials are successfully exchanged, but servers - supporting the STARTTLS command are not required to support the - EXTERNAL mechanism. - - Once TLS has been started, the client MUST discard cached - information about server capabilities and SHOULD re-issue the - CAPABILITY command. This is necessary to protect against - man-in-the-middle attacks which alter the capabilities list prior - to STARTTLS. The server MAY advertise different capabilities - after STARTTLS. - - The formal syntax for IMAP is amended as follows: - - - - -Newman Standards Track [Page 4] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - command_any =/ "STARTTLS" - - Example: C: a001 CAPABILITY - S: * CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED - S: a001 OK CAPABILITY completed - C: a002 STARTTLS - S: a002 OK Begin TLS negotiation now - - C: a003 CAPABILITY - S: * CAPABILITY IMAP4rev1 AUTH=EXTERNAL - S: a003 OK CAPABILITY completed - C: a004 LOGIN joe password - S: a004 OK LOGIN completed - -3.2. IMAP LOGINDISABLED capability - - The current IMAP protocol specification (RFC 2060) requires the - implementation of the LOGIN command which uses clear-text passwords. - Many sites may choose to disable this command unless encryption is - active for security reasons. An IMAP server MAY advertise that the - LOGIN command is disabled by including the LOGINDISABLED capability - in the capability response. Such a server will respond with a tagged - "NO" response to any attempt to use the LOGIN command. - - An IMAP server which implements STARTTLS MUST implement support for - the LOGINDISABLED capability on unencrypted connections. - - An IMAP client which complies with this specification MUST NOT issue - the LOGIN command if this capability is present. - - This capability is useful to prevent clients compliant with this - specification from sending an unencrypted password in an environment - subject to passive attacks. It has no impact on an environment - subject to active attacks as a man-in-the-middle attacker can remove - this capability. Therefore this does not relieve clients of the need - to follow the privacy mode recommendation in section 2.2. - - Servers advertising this capability will fail to interoperate with - many existing compliant IMAP clients and will be unable to prevent - those clients from disclosing the user's password. - -4. POP3 STARTTLS extension - - The POP3 STARTTLS extension adds the STLS command to POP3 servers. - If this is implemented, the POP3 extension mechanism [POP3EXT] MUST - also be implemented to avoid the need for client probing of multiple - commands. The capability name "STLS" indicates this command is - present and permitted in the current state. - - - -Newman Standards Track [Page 5] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - STLS - - Arguments: none - - Restrictions: - Only permitted in AUTHORIZATION state. - - Discussion: - A TLS negotiation begins immediately after the CRLF at the - end of the +OK response from the server. A -ERR response - MAY result if a security layer is already active. Once a - client issues a STLS command, it MUST NOT issue further - commands until a server response is seen and the TLS - negotiation is complete. - - The STLS command is only permitted in AUTHORIZATION state - and the server remains in AUTHORIZATION state, even if - client credentials are supplied during the TLS negotiation. - The AUTH command [POP-AUTH] with the EXTERNAL mechanism - [SASL] MAY be used to authenticate once TLS client - credentials are successfully exchanged, but servers - supporting the STLS command are not required to support the - EXTERNAL mechanism. - - Once TLS has been started, the client MUST discard cached - information about server capabilities and SHOULD re-issue - the CAPA command. This is necessary to protect against - man-in-the-middle attacks which alter the capabilities list - prior to STLS. The server MAY advertise different - capabilities after STLS. - - Possible Responses: - +OK -ERR - - Examples: - C: STLS - S: +OK Begin TLS negotiation - - ... - C: STLS - S: -ERR Command not permitted when TLS active - - - - - - - - - - -Newman Standards Track [Page 6] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - -5. ACAP STARTTLS extension - - When the TLS extension is present in ACAP, "STARTTLS" is listed as a - capability in the ACAP greeting. No arguments to this capability are - defined at this time. This extension adds a single command, - "STARTTLS" to the ACAP protocol which is used to begin a TLS - negotiation. - -5.1. STARTTLS Command - - Arguments: none - - Responses: no specific responses for this command - - Result: OK - begin TLS negotiation - BAD - command unknown or arguments invalid - - A TLS negotiation begins immediately after the CRLF at the end of - the tagged OK response from the server. Once a client issues a - STARTTLS command, it MUST NOT issue further commands until a - server response is seen and the TLS negotiation is complete. - - The STARTTLS command is only valid in non-authenticated state. - The server remains in non-authenticated state, even if client - credentials are supplied during the TLS negotiation. The SASL - [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS - client credentials are successfully exchanged, but servers - supporting the STARTTLS command are not required to support the - EXTERNAL mechanism. - - After the TLS layer is established, the server MUST re-issue an - untagged ACAP greeting. This is necessary to protect against - man-in-the-middle attacks which alter the capabilities list prior - to STARTTLS. The client MUST discard cached capability - information and replace it with the information from the new ACAP - greeting. The server MAY advertise different capabilities after - STARTTLS. - - The formal syntax for ACAP is amended as follows: - - command_any =/ "STARTTLS" - - Example: S: * ACAP (SASL "CRAM-MD5") (STARTTLS) - C: a002 STARTTLS - S: a002 OK "Begin TLS negotiation now" - - S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL") - - - - -Newman Standards Track [Page 7] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - -6. PLAIN SASL mechanism - - Clear-text passwords are simple, interoperate with almost all - existing operating system authentication databases, and are useful - for a smooth transition to a more secure password-based - authentication mechanism. The drawback is that they are unacceptable - for use over an unencrypted network connection. - - This defines the "PLAIN" SASL mechanism for use with ACAP and other - protocols with no clear-text login command. The PLAIN SASL mechanism - MUST NOT be advertised or used unless a strong encryption layer (such - as the provided by TLS) is active or backwards compatibility dictates - otherwise. - - The mechanism consists of a single message from the client to the - server. The client sends the authorization identity (identity to - login as), followed by a US-ASCII NUL character, followed by the - authentication identity (identity whose password will be used), - followed by a US-ASCII NUL character, followed by the clear-text - password. The client may leave the authorization identity empty to - indicate that it is the same as the authentication identity. - - The server will verify the authentication identity and password with - the system authentication database and verify that the authentication - credentials permit the client to login as the authorization identity. - If both steps succeed, the user is logged in. - - The server MAY also use the password to initialize any new - authentication database, such as one suitable for CRAM-MD5 - [CRAM-MD5]. - - Non-US-ASCII characters are permitted as long as they are represented - in UTF-8 [UTF-8]. Use of non-visible characters or characters which - a user may be unable to enter on some keyboards is discouraged. - - The formal grammar for the client message using Augmented BNF [ABNF] - follows. - - message = [authorize-id] NUL authenticate-id NUL password - authenticate-id = 1*UTF8-SAFE ; MUST accept up to 255 octets - authorize-id = 1*UTF8-SAFE ; MUST accept up to 255 octets - password = 1*UTF8-SAFE ; MUST accept up to 255 octets - NUL = %x00 - UTF8-SAFE = %x01-09 / %x0B-0C / %x0E-7F / UTF8-2 / - UTF8-3 / UTF8-4 / UTF8-5 / UTF8-6 - UTF8-1 = %x80-BF - UTF8-2 = %xC0-DF UTF8-1 - UTF8-3 = %xE0-EF 2UTF8-1 - - - -Newman Standards Track [Page 8] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - UTF8-4 = %xF0-F7 3UTF8-1 - UTF8-5 = %xF8-FB 4UTF8-1 - UTF8-6 = %xFC-FD 5UTF8-1 - - Here is an example of how this might be used to initialize a CRAM-MD5 - authentication database for ACAP: - - Example: S: * ACAP (SASL "CRAM-MD5") (STARTTLS) - C: a001 AUTHENTICATE "CRAM-MD5" - S: + "<1896.697170952@postoffice.reston.mci.net>" - C: "tim b913a602c7eda7a495b4e6e7334d3890" - S: a001 NO (TRANSITION-NEEDED) - "Please change your password, or use TLS to login" - C: a002 STARTTLS - S: a002 OK "Begin TLS negotiation now" - - S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL") - C: a003 AUTHENTICATE "PLAIN" {21+} - C: timtanstaaftanstaaf - S: a003 OK CRAM-MD5 password initialized - - Note: In this example, represents a single ASCII NUL octet. - -7. imaps and pop3s ports - - Separate "imaps" and "pop3s" ports were registered for use with SSL. - Use of these ports is discouraged in favor of the STARTTLS or STLS - commands. - - A number of problems have been observed with separate ports for - "secure" variants of protocols. This is an attempt to enumerate some - of those problems. - - - Separate ports lead to a separate URL scheme which intrudes into - the user interface in inappropriate ways. For example, many web - pages use language like "click here if your browser supports SSL." - This is a decision the browser is often more capable of making than - the user. - - - Separate ports imply a model of either "secure" or "not secure." - This can be misleading in a number of ways. First, the "secure" - port may not in fact be acceptably secure as an export-crippled - cipher suite might be in use. This can mislead users into a false - sense of security. Second, the normal port might in fact be - secured by using a SASL mechanism which includes a security layer. - Thus the separate port distinction makes the complex topic of - security policy even more confusing. One common result of this - confusion is that firewall administrators are often misled into - - - -Newman Standards Track [Page 9] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - permitting the "secure" port and blocking the standard port. This - could be a poor choice given the common use of SSL with a 40-bit - key encryption layer and plain-text password authentication is less - secure than strong SASL mechanisms such as GSSAPI with Kerberos 5. - - - Use of separate ports for SSL has caused clients to implement only - two security policies: use SSL or don't use SSL. The desirable - security policy "use TLS when available" would be cumbersome with - the separate port model, but is simple with STARTTLS. - - - Port numbers are a limited resource. While they are not yet in - short supply, it is unwise to set a precedent that could double (or - worse) the speed of their consumption. - - -8. IANA Considerations - - This constitutes registration of the "STARTTLS" and "LOGINDISABLED" - IMAP capabilities as required by section 7.2.1 of RFC 2060 [IMAP]. - - The registration for the POP3 "STLS" capability follows: - - CAPA tag: STLS - Arguments: none - Added commands: STLS - Standard commands affected: May enable USER/PASS as a side-effect. - CAPA command SHOULD be re-issued after successful completion. - Announced states/Valid states: AUTHORIZATION state only. - Specification reference: this memo - - The registration for the ACAP "STARTTLS" capability follows: - - Capability name: STARTTLS - Capability keyword: STARTTLS - Capability arguments: none - Published Specification(s): this memo - Person and email address for further information: - see author's address section below - - The registration for the PLAIN SASL mechanism follows: - - SASL mechanism name: PLAIN - Security Considerations: See section 9 of this memo - Published specification: this memo - Person & email address to contact for further information: - see author's address section below - Intended usage: COMMON - Author/Change controller: see author's address section below - - - -Newman Standards Track [Page 10] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - -9. Security Considerations - - TLS only provides protection for data sent over a network connection. - Messages transferred over IMAP or POP3 are still available to server - administrators and usually subject to eavesdropping, tampering and - forgery when transmitted through SMTP or NNTP. TLS is no substitute - for an end-to-end message security mechanism using MIME security - multiparts [MIME-SEC]. - - A man-in-the-middle attacker can remove STARTTLS from the capability - list or generate a failure response to the STARTTLS command. In - order to detect such an attack, clients SHOULD warn the user when - session privacy is not active and/or be configurable to refuse to - proceed without an acceptable level of security. - - A man-in-the-middle attacker can always cause a down-negotiation to - the weakest authentication mechanism or cipher suite available. For - this reason, implementations SHOULD be configurable to refuse weak - mechanisms or cipher suites. - - Any protocol interactions prior to the TLS handshake are performed in - the clear and can be modified by a man-in-the-middle attacker. For - this reason, clients MUST discard cached information about server - capabilities advertised prior to the start of the TLS handshake. - - Clients are encouraged to clearly indicate when the level of - encryption active is known to be vulnerable to attack using modern - hardware (such as encryption keys with 56 bits of entropy or less). - - The LOGINDISABLED IMAP capability (discussed in section 3.2) only - reduces the potential for passive attacks, it provides no protection - against active attacks. The responsibility remains with the client - to avoid sending a password over a vulnerable channel. - - The PLAIN mechanism relies on the TLS encryption layer for security. - When used without TLS, it is vulnerable to a common network - eavesdropping attack. Therefore PLAIN MUST NOT be advertised or used - unless a suitable TLS encryption layer is active or backwards - compatibility dictates otherwise. - - When the PLAIN mechanism is used, the server gains the ability to - impersonate the user to all services with the same password - regardless of any encryption provided by TLS or other network privacy - mechanisms. While many other authentication mechanisms have similar - weaknesses, stronger SASL mechanisms such as Kerberos address this - issue. Clients are encouraged to have an operational mode where all - mechanisms which are likely to reveal the user's password to the - server are disabled. - - - -Newman Standards Track [Page 11] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - The security considerations for TLS apply to STARTTLS and the - security considerations for SASL apply to the PLAIN mechanism. - Additional security requirements are discussed in section 2. - -10. References - - [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [ACAP] Newman, C. and J. Myers, "ACAP -- Application - Configuration Access Protocol", RFC 2244, November 1997. - - [AUTH] Haller, N. and R. Atkinson, "On Internet Authentication", - RFC 1704, October 1994. - - [CRAM-MD5] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP - AUTHorize Extension for Simple Challenge/Response", RFC - 2195, September 1997. - - [IMAP] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [MIME-SEC] Galvin, J., Murphy, S., Crocker, S. and N. Freed, - "Security Multiparts for MIME: Multipart/Signed and - Multipart/Encrypted", RFC 1847, October 1995. - - [POP3] Myers, J. and M. Rose, "Post Office Protocol - Version 3", - STD 53, RFC 1939, May 1996. - - [POP3EXT] Gellens, R., Newman, C. and L. Lundblade, "POP3 Extension - Mechanism", RFC 2449, November 1998. - - [POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734, - December 1994. - - [SASL] Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997. - - [SMTPTLS] Hoffman, P., "SMTP Service Extension for Secure SMTP over - TLS", RFC 2487, January 1999. - - [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", - RFC 2246, January 1999. - - - - - -Newman Standards Track [Page 12] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", RFC 2279, January 1998. - - -11. Author's Address - - Chris Newman - Innosoft International, Inc. - 1050 Lakes Drive - West Covina, CA 91790 USA - - EMail: chris.newman@innosoft.com - - -A. Appendix -- Compliance Checklist - - An implementation is not compliant if it fails to satisfy one or more - of the MUST requirements for the protocols it implements. An - implementation that satisfies all the MUST and all the SHOULD - requirements for its protocols is said to be "unconditionally - compliant"; one that satisfies all the MUST requirements but not all - the SHOULD requirements for its protocols is said to be - "conditionally compliant". - - Rules Section - ----- ------- - Mandatory-to-implement Cipher Suite 2.1 - SHOULD have mode where encryption required 2.2 - server SHOULD have mode where TLS not required 2.2 - MUST be configurable to refuse all clear-text login - commands or mechanisms 2.3 - server SHOULD be configurable to refuse clear-text - login commands on entire server and on per-user basis 2.3 - client MUST check server identity 2.4 - client MUST use hostname used to open connection 2.4 - client MUST NOT use hostname from insecure remote lookup 2.4 - client SHOULD support subjectAltName of dNSName type 2.4 - client SHOULD ask for confirmation or terminate on fail 2.4 - MUST check result of STARTTLS for acceptable privacy 2.5 - client MUST NOT issue commands after STARTTLS - until server response and negotiation done 3.1,4,5.1 - client MUST discard cached information 3.1,4,5.1,9 - client SHOULD re-issue CAPABILITY/CAPA command 3.1,4 - IMAP server with STARTTLS MUST implement LOGINDISABLED 3.2 - IMAP client MUST NOT issue LOGIN if LOGINDISABLED 3.2 - POP server MUST implement POP3 extensions 4 - ACAP server MUST re-issue ACAP greeting 5.1 - - - - -Newman Standards Track [Page 13] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - - client SHOULD warn when session privacy not active and/or - refuse to proceed without acceptable security level 9 - SHOULD be configurable to refuse weak mechanisms or - cipher suites 9 - - The PLAIN mechanism is an optional part of this specification. - However if it is implemented the following rules apply: - - Rules Section - ----- ------- - MUST NOT use PLAIN unless strong encryption active - or backwards compatibility dictates otherwise 6,9 - MUST use UTF-8 encoding for characters in PLAIN 6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Newman Standards Track [Page 14] - -RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999 - - -Full Copyright Statement - - Copyright (C) The Internet Society (1999). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Newman Standards Track [Page 15] - diff --git a/doc/rfc2831.txt b/doc/rfc2831.txt deleted file mode 100644 index c1a54c49..00000000 --- a/doc/rfc2831.txt +++ /dev/null @@ -1,1515 +0,0 @@ - - - - - - -Network Working Group P. Leach -Request for Comments: 2831 Microsoft -Category: Standards Track C. Newman - Innosoft - May 2000 - - - Using Digest Authentication as a SASL Mechanism - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2000). All Rights Reserved. - -Abstract - - This specification defines how HTTP Digest Authentication [Digest] - can be used as a SASL [RFC 2222] mechanism for any protocol that has - a SASL profile. It is intended both as an improvement over CRAM-MD5 - [RFC 2195] and as a convenient way to support a single authentication - mechanism for web, mail, LDAP, and other protocols. - -Table of Contents - - 1 INTRODUCTION.....................................................2 - 1.1 CONVENTIONS AND NOTATION......................................2 - 1.2 REQUIREMENTS..................................................3 - 2 AUTHENTICATION...................................................3 - 2.1 INITIAL AUTHENTICATION........................................3 - 2.1.1 Step One...................................................3 - 2.1.2 Step Two...................................................6 - 2.1.3 Step Three................................................12 - 2.2 SUBSEQUENT AUTHENTICATION....................................12 - 2.2.1 Step one..................................................13 - 2.2.2 Step Two..................................................13 - 2.3 INTEGRITY PROTECTION.........................................13 - 2.4 CONFIDENTIALITY PROTECTION...................................14 - 3 SECURITY CONSIDERATIONS.........................................15 - 3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........15 - 3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................16 - 3.3 REPLAY ATTACKS...............................................16 - - - -Leach & Newman Standards Track [Page 1] - -RFC 2831 Digest SASL Mechanism May 2000 - - - 3.4 ONLINE DICTIONARY ATTACKS....................................16 - 3.5 OFFLINE DICTIONARY ATTACKS...................................16 - 3.6 MAN IN THE MIDDLE............................................17 - 3.7 CHOSEN PLAINTEXT ATTACKS.....................................17 - 3.8 SPOOFING BY COUNTERFEIT SERVERS..............................17 - 3.9 STORING PASSWORDS............................................17 - 3.10 MULTIPLE REALMS.............................................18 - 3.11 SUMMARY.....................................................18 - 4 EXAMPLE.........................................................18 - 5 REFERENCES......................................................20 - 6 AUTHORS' ADDRESSES..............................................21 - 7 ABNF............................................................21 - 7.1 AUGMENTED BNF................................................21 - 7.2 BASIC RULES..................................................23 - 8 SAMPLE CODE.....................................................25 - 9 FULL COPYRIGHT STATEMENT........................................27 - -1 Introduction - - This specification describes the use of HTTP Digest Access - Authentication as a SASL mechanism. The authentication type - associated with the Digest SASL mechanism is "DIGEST-MD5". - - This specification is intended to be upward compatible with the - "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication - specified in [Digest]. The only difference in the "md5-sess" - algorithm is that some directives not needed in a SASL mechanism have - had their values defaulted. - - There is one new feature for use as a SASL mechanism: integrity - protection on application protocol messages after an authentication - exchange. - - Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext - attacks, and permits the use of third party authentication servers, - mutual authentication, and optimized reauthentication if a client has - recently authenticated to a server. - -1.1 Conventions and Notation - - This specification uses the same ABNF notation and lexical - conventions as HTTP/1.1 specification; see appendix A. - - Let { a, b, ... } be the concatenation of the octet strings a, b, ... - - Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s. - - - - - -Leach & Newman Standards Track [Page 2] - -RFC 2831 Digest SASL Mechanism May 2000 - - - Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string - k, a colon and the string s. - - Let HEX(n) be the representation of the 16 octet MD5 hash n as a - string of 32 hex digits (with alphabetic characters always in lower - case, since MD5 is case sensitive). - - Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet - string s using the octet string k as a key. - - The value of a quoted string constant as an octet string does not - include any terminating null character. - -1.2 Requirements - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [RFC 2119]. - - An implementation is not compliant if it fails to satisfy one or more - of the MUST level requirements for the protocols it implements. An - implementation that satisfies all the MUST level and all the SHOULD - level requirements for its protocols is said to be "unconditionally - compliant"; one that satisfies all the MUST level requirements but - not all the SHOULD level requirements for its protocols is said to be - "conditionally compliant." - -2 Authentication - - The following sections describe how to use Digest as a SASL - authentication mechanism. - -2.1 Initial Authentication - - If the client has not recently authenticated to the server, then it - must perform "initial authentication", as defined in this section. If - it has recently authenticated, then a more efficient form is - available, defined in the next section. - -2.1.1 Step One - - The server starts by sending a challenge. The data encoded in the - challenge contains a string formatted according to the rules for a - "digest-challenge" defined as follows: - - - - - - - -Leach & Newman Standards Track [Page 3] - -RFC 2831 Digest SASL Mechanism May 2000 - - - digest-challenge = - 1#( realm | nonce | qop-options | stale | maxbuf | charset - algorithm | cipher-opts | auth-param ) - - realm = "realm" "=" <"> realm-value <"> - realm-value = qdstr-val - nonce = "nonce" "=" <"> nonce-value <"> - nonce-value = qdstr-val - qop-options = "qop" "=" <"> qop-list <"> - qop-list = 1#qop-value - qop-value = "auth" | "auth-int" | "auth-conf" | - token - stale = "stale" "=" "true" - maxbuf = "maxbuf" "=" maxbuf-value - maxbuf-value = 1*DIGIT - charset = "charset" "=" "utf-8" - algorithm = "algorithm" "=" "md5-sess" - cipher-opts = "cipher" "=" <"> 1#cipher-value <"> - cipher-value = "3des" | "des" | "rc4-40" | "rc4" | - "rc4-56" | token - auth-param = token "=" ( token | quoted-string ) - - The meanings of the values of the directives used above are as - follows: - - realm - Mechanistically, a string which can enable users to know which - username and password to use, in case they might have different - ones for different servers. Conceptually, it is the name of a - collection of accounts that might include the user's account. This - string should contain at least the name of the host performing the - authentication and might additionally indicate the collection of - users who might have access. An example might be - "registered_users@gotham.news.example.com". This directive is - optional; if not present, the client SHOULD solicit it from the - user or be able to compute a default; a plausible default might be - the realm supplied by the user when they logged in to the client - system. Multiple realm directives are allowed, in which case the - user or client must choose one as the realm for which to supply to - username and password. - - nonce - A server-specified data string which MUST be different each time a - digest-challenge is sent as part of initial authentication. It is - recommended that this string be base64 or hexadecimal data. Note - that since the string is passed as a quoted string, the - double-quote character is not allowed unless escaped (see section - 7.2). The contents of the nonce are implementation dependent. The - - - -Leach & Newman Standards Track [Page 4] - -RFC 2831 Digest SASL Mechanism May 2000 - - - security of the implementation depends on a good choice. It is - RECOMMENDED that it contain at least 64 bits of entropy. The nonce - is opaque to the client. This directive is required and MUST - appear exactly once; if not present, or if multiple instances are - present, the client should abort the authentication exchange. - - qop-options - A quoted string of one or more tokens indicating the "quality of - protection" values supported by the server. The value "auth" - indicates authentication; the value "auth-int" indicates - authentication with integrity protection; the value "auth-conf" - indicates authentication with integrity protection and encryption. - This directive is optional; if not present it defaults to "auth". - The client MUST ignore unrecognized options; if the client - recognizes no option, it should abort the authentication exchange. - - stale - The "stale" directive is not used in initial authentication. See - the next section for its use in subsequent authentications. This - directive may appear at most once; if multiple instances are - present, the client should abort the authentication exchange. - - maxbuf - A number indicating the size of the largest buffer the server is - able to receive when using "auth-int" or "auth-conf". If this - directive is missing, the default value is 65536. This directive - may appear at most once; if multiple instances are present, the - client should abort the authentication exchange. - - charset - This directive, if present, specifies that the server supports - UTF-8 encoding for the username and password. If not present, the - username and password must be encoded in ISO 8859-1 (of which - US-ASCII is a subset). The directive is needed for backwards - compatibility with HTTP Digest, which only supports ISO 8859-1. - This directive may appear at most once; if multiple instances are - present, the client should abort the authentication exchange. - - algorithm - This directive is required for backwards compatibility with HTTP - Digest., which supports other algorithms. . This directive is - required and MUST appear exactly once; if not present, or if - multiple instances are present, the client should abort the - authentication exchange. - - - - - - - -Leach & Newman Standards Track [Page 5] - -RFC 2831 Digest SASL Mechanism May 2000 - - - cipher-opts - A list of ciphers that the server supports. This directive must be - present exactly once if "auth-conf" is offered in the - "qop-options" directive, in which case the "3des" and "des" modes - are mandatory-to-implement. The client MUST ignore unrecognized - options; if the client recognizes no option, it should abort the - authentication exchange. - - des - the Data Encryption Standard (DES) cipher [FIPS] in cipher - block chaining (CBC) mode with a 56 bit key. - - 3des - the "triple DES" cipher in CBC mode with EDE with the same key - for each E stage (aka "two keys mode") for a total key length - of 112 bits. - - rc4, rc4-40, rc4-56 - the RC4 cipher with a 128 bit, 40 bit, and 56 bit key, - respectively. - - auth-param This construct allows for future extensions; it may appear - more than once. The client MUST ignore any unrecognized - directives. - - For use as a SASL mechanism, note that the following changes are made - to "digest-challenge" from HTTP: the following Digest options (called - "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent, - and MUST be ignored if received): - - opaque - domain - - The size of a digest-challenge MUST be less than 2048 bytes. - -2.1.2 Step Two - - The client makes note of the "digest-challenge" and then responds - with a string formatted and computed according to the rules for a - "digest-response" defined as follows: - - - - - - - - - - - -Leach & Newman Standards Track [Page 6] - -RFC 2831 Digest SASL Mechanism May 2000 - - - digest-response = 1#( username | realm | nonce | cnonce | - nonce-count | qop | digest-uri | response | - maxbuf | charset | cipher | authzid | - auth-param ) - - username = "username" "=" <"> username-value <"> - username-value = qdstr-val - cnonce = "cnonce" "=" <"> cnonce-value <"> - cnonce-value = qdstr-val - nonce-count = "nc" "=" nc-value - nc-value = 8LHEX - qop = "qop" "=" qop-value - digest-uri = "digest-uri" "=" <"> digest-uri-value <"> - digest-uri-value = serv-type "/" host [ "/" serv-name ] - serv-type = 1*ALPHA - host = 1*( ALPHA | DIGIT | "-" | "." ) - serv-name = host - response = "response" "=" response-value - response-value = 32LHEX - LHEX = "0" | "1" | "2" | "3" | - "4" | "5" | "6" | "7" | - "8" | "9" | "a" | "b" | - "c" | "d" | "e" | "f" - cipher = "cipher" "=" cipher-value - authzid = "authzid" "=" <"> authzid-value <"> - authzid-value = qdstr-val - - - username - The user's name in the specified realm, encoded according to the - value of the "charset" directive. This directive is required and - MUST be present exactly once; otherwise, authentication fails. - - realm - The realm containing the user's account. This directive is - required if the server provided any realms in the - "digest-challenge", in which case it may appear exactly once and - its value SHOULD be one of those realms. If the directive is - missing, "realm-value" will set to the empty string when computing - A1 (see below for details). - - nonce - The server-specified data string received in the preceding - digest-challenge. This directive is required and MUST be present - exactly once; otherwise, authentication fails. - - - - - - -Leach & Newman Standards Track [Page 7] - -RFC 2831 Digest SASL Mechanism May 2000 - - - cnonce - A client-specified data string which MUST be different each time a - digest-response is sent as part of initial authentication. The - cnonce-value is an opaque quoted string value provided by the - client and used by both client and server to avoid chosen - plaintext attacks, and to provide mutual authentication. The - security of the implementation depends on a good choice. It is - RECOMMENDED that it contain at least 64 bits of entropy. This - directive is required and MUST be present exactly once; otherwise, - authentication fails. - - nonce-count - The nc-value is the hexadecimal count of the number of requests - (including the current request) that the client has sent with the - nonce value in this request. For example, in the first request - sent in response to a given nonce value, the client sends - "nc=00000001". The purpose of this directive is to allow the - server to detect request replays by maintaining its own copy of - this count - if the same nc-value is seen twice, then the request - is a replay. See the description below of the construction of - the response value. This directive may appear at most once; if - multiple instances are present, the client should abort the - authentication exchange. - - qop - Indicates what "quality of protection" the client accepted. If - present, it may appear exactly once and its value MUST be one of - the alternatives in qop-options. If not present, it defaults to - "auth". These values affect the computation of the response. Note - that this is a single token, not a quoted list of alternatives. - - serv-type - Indicates the type of service, such as "www" for web service, - "ftp" for FTP service, "smtp" for mail delivery service, etc. The - service name as defined in the SASL profile for the protocol see - section 4 of [RFC 2222], registered in the IANA registry of - "service" elements for the GSSAPI host-based service name form - [RFC 2078]. - - host - The DNS host name or IP address for the service requested. The - DNS host name must be the fully-qualified canonical name of the - host. The DNS host name is the preferred form; see notes on server - processing of the digest-uri. - - - - - - - -Leach & Newman Standards Track [Page 8] - -RFC 2831 Digest SASL Mechanism May 2000 - - - serv-name - Indicates the name of the service if it is replicated. The service - is considered to be replicated if the client's service-location - process involves resolution using standard DNS lookup operations, - and if these operations involve DNS records (such as SRV, or MX) - which resolve one DNS name into a set of other DNS names. In this - case, the initial name used by the client is the "serv-name", and - the final name is the "host" component. For example, the incoming - mail service for "example.com" may be replicated through the use - of MX records stored in the DNS, one of which points at an SMTP - server called "mail3.example.com"; it's "serv-name" would be - "example.com", it's "host" would be "mail3.example.com". If the - service is not replicated, or the serv-name is identical to the - host, then the serv-name component MUST be omitted. - - digest-uri - Indicates the principal name of the service with which the client - wishes to connect, formed from the serv-type, host, and serv-name. - For example, the FTP service on "ftp.example.com" would have a - "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from - the example above would have a "digest-uri" value of - "smtp/mail3.example.com/example.com". - - Servers SHOULD check that the supplied value is correct. This will - detect accidental connection to the incorrect server. It is also so - that clients will be trained to provide values that will work with - implementations that use a shared back-end authentication service - that can provide server authentication. - - The serv-type component should match the service being offered. The - host component should match one of the host names of the host on - which the service is running, or it's IP address. Servers SHOULD NOT - normally support the IP address form, because server authentication - by IP address is not very useful; they should only do so if the DNS - is unavailable or unreliable. The serv-name component should match - one of the service's configured service names. - - This directive may appear at most once; if multiple instances are - present, the client should abort the authentication exchange. - - Note: In the HTTP use of Digest authentication, the digest-uri is the - URI (usually a URL) of the resource requested -- hence the name of - the directive. - - response - A string of 32 hex digits computed as defined below, which proves - that the user knows a password. This directive is required and - MUST be present exactly once; otherwise, authentication fails. - - - -Leach & Newman Standards Track [Page 9] - -RFC 2831 Digest SASL Mechanism May 2000 - - - maxbuf - A number indicating the size of the largest buffer the client is - able to receive. If this directive is missing, the default value - is 65536. This directive may appear at most once; if multiple - instances are present, the server should abort the authentication - exchange. - - charset - This directive, if present, specifies that the client has used - UTF-8 encoding for the username and password. If not present, the - username and password must be encoded in ISO 8859-1 (of which - US-ASCII is a subset). The client should send this directive only - if the server has indicated it supports UTF-8. The directive is - needed for backwards compatibility with HTTP Digest, which only - supports ISO 8859-1. - - LHEX - 32 hex digits, where the alphabetic characters MUST be lower case, - because MD5 is not case insensitive. - - cipher - The cipher chosen by the client. This directive MUST appear - exactly once if "auth-conf" is negotiated; if required and not - present, authentication fails. - - authzid - The "authorization ID" as per RFC 2222, encoded in UTF-8. This - directive is optional. If present, and the authenticating user has - sufficient privilege, and the server supports it, then after - authentication the server will use this identity for making all - accesses and access checks. If the client specifies it, and the - server does not support it, then the response-value will be - incorrect, and authentication will fail. - - The size of a digest-response MUST be less than 4096 bytes. - -2.1.2.1 Response-value - - The definition of "response-value" above indicates the encoding for - its value -- 32 lower case hex characters. The following definitions - show how the value is computed. - - Although qop-value and components of digest-uri-value may be - case-insensitive, the case which the client supplies in step two is - preserved for the purpose of computing and verifying the - response-value. - - response-value = - - - -Leach & Newman Standards Track [Page 10] - -RFC 2831 Digest SASL Mechanism May 2000 - - - HEX( KD ( HEX(H(A1)), - { nonce-value, ":" nc-value, ":", - cnonce-value, ":", qop-value, ":", HEX(H(A2)) })) - - If authzid is specified, then A1 is - - - A1 = { H( { username-value, ":", realm-value, ":", passwd } ), - ":", nonce-value, ":", cnonce-value, ":", authzid-value } - - If authzid is not specified, then A1 is - - - A1 = { H( { username-value, ":", realm-value, ":", passwd } ), - ":", nonce-value, ":", cnonce-value } - - where - - passwd = *OCTET - - The "username-value", "realm-value" and "passwd" are encoded - according to the value of the "charset" directive. If "charset=UTF-8" - is present, and all the characters of either "username-value" or - "passwd" are in the ISO 8859-1 character set, then it must be - converted to ISO 8859-1 before being hashed. This is so that - authentication databases that store the hashed username, realm and - password (which is common) can be shared compatibly with HTTP, which - specifies ISO 8859-1. A sample implementation of this conversion is - in section 8. - - If the "qop" directive's value is "auth", then A2 is: - - A2 = { "AUTHENTICATE:", digest-uri-value } - - If the "qop" value is "auth-int" or "auth-conf" then A2 is: - - A2 = { "AUTHENTICATE:", digest-uri-value, - ":00000000000000000000000000000000" } - - Note that "AUTHENTICATE:" must be in upper case, and the second - string constant is a string with a colon followed by 32 zeros. - - These apparently strange values of A2 are for compatibility with - HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and - the hash of the entity body to zero in the HTTP digest calculation of - A2. - - Also, in the HTTP usage of Digest, several directives in the - - - -Leach & Newman Standards Track [Page 11] - -RFC 2831 Digest SASL Mechanism May 2000 - - - "digest-challenge" sent by the server have to be returned by the - client in the "digest-response". These are: - - opaque - algorithm - - These directives are not needed when Digest is used as a SASL - mechanism (i.e., MUST NOT be sent, and MUST be ignored if received). - -2.1.3 Step Three - - The server receives and validates the "digest-response". The server - checks that the nonce-count is "00000001". If it supports subsequent - authentication (see section 2.2), it saves the value of the nonce and - the nonce-count. It sends a message formatted as follows: - - response-auth = "rspauth" "=" response-value - - where response-value is calculated as above, using the values sent in - step two, except that if qop is "auth", then A2 is - - A2 = { ":", digest-uri-value } - - And if qop is "auth-int" or "auth-conf" then A2 is - - A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" } - - Compared to its use in HTTP, the following Digest directives in the - "digest-response" are unused: - - nextnonce - qop - cnonce - nonce-count - -2.2 Subsequent Authentication - - If the client has previously authenticated to the server, and - remembers the values of username, realm, nonce, nonce-count, cnonce, - and qop that it used in that authentication, and the SASL profile for - a protocol permits an initial client response, then it MAY perform - "subsequent authentication", as defined in this section. - - - - - - - - - -Leach & Newman Standards Track [Page 12] - -RFC 2831 Digest SASL Mechanism May 2000 - - -2.2.1 Step one - - The client uses the values from the previous authentication and sends - an initial response with a string formatted and computed according to - the rules for a "digest-response", as defined above, but with a - nonce-count one greater than used in the last "digest-response". - -2.2.2 Step Two - - The server receives the "digest-response". If the server does not - support subsequent authentication, then it sends a - "digest-challenge", and authentication proceeds as in initial - authentication. If the server has no saved nonce and nonce-count from - a previous authentication, then it sends a "digest-challenge", and - authentication proceeds as in initial authentication. Otherwise, the - server validates the "digest-response", checks that the nonce-count - is one greater than that used in the previous authentication using - that nonce, and saves the new value of nonce-count. - - If the response is invalid, then the server sends a - "digest-challenge", and authentication proceeds as in initial - authentication (and should be configurable to log an authentication - failure in some sort of security audit log, since the failure may be - a symptom of an attack). The nonce-count MUST NOT be incremented in - this case: to do so would allow a denial of service attack by sending - an out-of-order nonce-count. - - If the response is valid, the server MAY choose to deem that - authentication has succeeded. However, if it has been too long since - the previous authentication, or for any other reason, the server MAY - send a new "digest-challenge" with a new value for nonce. The - challenge MAY contain a "stale" directive with value "true", which - says that the client may respond to the challenge using the password - it used in the previous response; otherwise, the client must solicit - the password anew from the user. This permits the server to make sure - that the user has presented their password recently. (The directive - name refers to the previous nonce being stale, not to the last use of - the password.) Except for the handling of "stale", after sending the - "digest-challenge" authentication proceeds as in the case of initial - authentication. - -2.3 Integrity Protection - - If the server offered "qop=auth-int" and the client responded - "qop=auth-int", then subsequent messages, up to but not including the - next subsequent authentication, between the client and the server - - - - - -Leach & Newman Standards Track [Page 13] - -RFC 2831 Digest SASL Mechanism May 2000 - - - MUST be integrity protected. Using as a base session key the value of - H(A1) as defined above the client and server calculate a pair of - message integrity keys as follows. - - The key for integrity protecting messages from client to server is: - - Kic = MD5({H(A1), - "Digest session key to client-to-server signing key magic constant"}) - - The key for integrity protecting messages from server to client is: - - Kis = MD5({H(A1), - "Digest session key to server-to-client signing key magic constant"}) - - where MD5 is as specified in [RFC 1321]. If message integrity is - negotiated, a MAC block for each message is appended to the message. - The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC - 2104] of the message, a 2-byte message type number in network byte - order with value 1, and the 4-byte sequence number in network byte - order. The message type is to allow for future extensions such as - rekeying. - - MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001, - SeqNum) - - where Ki is Kic for messages sent by the client and Kis for those - sent by the server. The sequence number is initialized to zero, and - incremented by one for each message sent. - - Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the - received value; the message is discarded if they differ. - -2.4 Confidentiality Protection - - If the server sent a "cipher-opts" directive and the client responded - with a "cipher" directive, then subsequent messages between the - client and the server MUST be confidentiality protected. Using as a - base session key the value of H(A1) as defined above the client and - server calculate a pair of message integrity keys as follows. - - The key for confidentiality protecting messages from client to server - is: - - Kcc = MD5({H(A1)[0..n], - "Digest H(A1) to client-to-server sealing key magic constant"}) - - The key for confidentiality protecting messages from server to client - is: - - - -Leach & Newman Standards Track [Page 14] - -RFC 2831 Digest SASL Mechanism May 2000 - - - Kcs = MD5({H(A1)[0..n], - "Digest H(A1) to server-to-client sealing key magic constant"}) - - where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5; - for "rc4-56" n is 7; for the rest n is 16. The key for the "rc-*" - ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is the first - 7 bytes; the key for "3des" is the first 14 bytes. The IV for "des" - and "3des" is the last 8 bytes of Kcc or Kcs. - - If message confidentiality is negotiated, each message is encrypted - with the chosen cipher and a MAC block is appended to the message. - - The MAC block is a variable length padding prefix followed by 16 - bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC - 2104] of the message, a 2-byte message type number in network byte - order with value 1, and the 4-byte sequence number in network byte - order. If the blocksize of the chosen cipher is not 1 byte, the - padding prefix is one or more octets each containing the number of - padding bytes, such that total length of the encrypted part of the - message is a multiple of the blocksize. The padding and first 10 - bytes of the MAC block are encrypted along with the message. - - SEAL(Ki, Kc, SeqNum, msg) = - {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001, - SeqNum} - - where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for - messages sent by the client and Kis and Kcs for those sent by the - server. The sequence number is initialized to zero, and incremented - by one for each message sent. - - Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is - computed and compared with the received value; the message is - discarded if they differ. - -3 Security Considerations - -3.1 Authentication of Clients using Digest Authentication - - Digest Authentication does not provide a strong authentication - mechanism, when compared to public key based mechanisms, for example. - However, since it prevents chosen plaintext attacks, it is stronger - than (e.g.) CRAM-MD5, which has been proposed for use with LDAP [10], - POP and IMAP (see RFC 2195 [9]). It is intended to replace the much - weaker and even more dangerous use of plaintext passwords; however, - since it is still a password based mechanism it avoids some of the - potential deployabilty issues with public-key, OTP or similar - mechanisms. - - - -Leach & Newman Standards Track [Page 15] - -RFC 2831 Digest SASL Mechanism May 2000 - - - Digest Authentication offers no confidentiality protection beyond - protecting the actual password. All of the rest of the challenge and - response are available to an eavesdropper, including the user's name - and authentication realm. - -3.2 Comparison of Digest with Plaintext Passwords - - The greatest threat to the type of transactions for which these - protocols are used is network snooping. This kind of transaction - might involve, for example, online access to a mail service whose use - is restricted to paying subscribers. With plaintext password - authentication an eavesdropper can obtain the password of the user. - This not only permits him to access anything in the database, but, - often worse, will permit access to anything else the user protects - with the same password. - -3.3 Replay Attacks - - Replay attacks are defeated if the client or the server chooses a - fresh nonce for each authentication, as this specification requires. - -3.4 Online dictionary attacks - - If the attacker can eavesdrop, then it can test any overheard - nonce/response pairs against a (potentially very large) list of - common words. Such a list is usually much smaller than the total - number of possible passwords. The cost of computing the response for - each password on the list is paid once for each challenge. - - The server can mitigate this attack by not allowing users to select - passwords that are in a dictionary. - -3.5 Offline dictionary attacks - - If the attacker can choose the challenge, then it can precompute the - possible responses to that challenge for a list of common words. Such - a list is usually much smaller than the total number of possible - passwords. The cost of computing the response for each password on - the list is paid just once. - - Offline dictionary attacks are defeated if the client chooses a fresh - nonce for each authentication, as this specification requires. - - - - - - - - - -Leach & Newman Standards Track [Page 16] - -RFC 2831 Digest SASL Mechanism May 2000 - - -3.6 Man in the Middle - - Digest authentication is vulnerable to "man in the middle" (MITM) - attacks. Clearly, a MITM would present all the problems of - eavesdropping. But it also offers some additional opportunities to - the attacker. - - A possible man-in-the-middle attack would be to substitute a weaker - qop scheme for the one(s) sent by the server; the server will not be - able to detect this attack. For this reason, the client should always - use the strongest scheme that it understands from the choices - offered, and should never choose a scheme that does not meet its - minimum requirements. - -3.7 Chosen plaintext attacks - - A chosen plaintext attack is where a MITM or a malicious server can - arbitrarily choose the challenge that the client will use to compute - the response. The ability to choose the challenge is known to make - cryptanalysis much easier [8]. - - However, Digest does not permit the attack to choose the challenge as - long as the client chooses a fresh nonce for each authentication, as - this specification requires. - -3.8 Spoofing by Counterfeit Servers - - If a user can be led to believe that she is connecting to a host - containing information protected by a password she knows, when in - fact she is connecting to a hostile server, then the hostile server - can obtain challenge/response pairs where it was able to partly - choose the challenge. There is no known way that this can be - exploited. - -3.9 Storing passwords - - Digest authentication requires that the authenticating agent (usually - the server) store some data derived from the user's name and password - in a "password file" associated with a given realm. Normally this - might contain pairs consisting of username and H({ username-value, - ":", realm-value, ":", passwd }), which is adequate to compute H(A1) - as described above without directly exposing the user's password. - - The security implications of this are that if this password file is - compromised, then an attacker gains immediate access to documents on - the server using this realm. Unlike, say a standard UNIX password - file, this information need not be decrypted in order to access - documents in the server realm associated with this file. On the other - - - -Leach & Newman Standards Track [Page 17] - -RFC 2831 Digest SASL Mechanism May 2000 - - - hand, decryption, or more likely a brute force attack, would be - necessary to obtain the user's password. This is the reason that the - realm is part of the digested data stored in the password file. It - means that if one Digest authentication password file is compromised, - it does not automatically compromise others with the same username - and password (though it does expose them to brute force attack). - - There are two important security consequences of this. First the - password file must be protected as if it contained plaintext - passwords, because for the purpose of accessing documents in its - realm, it effectively does. - - A second consequence of this is that the realm string should be - unique among all realms that any single user is likely to use. In - particular a realm string should include the name of the host doing - the authentication. - -3.10 Multiple realms - - Use of multiple realms may mean both that compromise of a the - security database for a single realm does not compromise all - security, and that there are more things to protect in order to keep - the whole system secure. - -3.11 Summary - - By modern cryptographic standards Digest Authentication is weak, - compared to (say) public key based mechanisms. But for a large range - of purposes it is valuable as a replacement for plaintext passwords. - Its strength may vary depending on the implementation. - -4 Example - - This example shows the use of the Digest SASL mechanism with the - IMAP4 AUTHENTICATE command [RFC 2060]. - - In this example, "C:" and "S:" represent a line sent by the client or - server respectively including a CRLF at the end. Linebreaks and - indentation within a "C:" or "S:" are editorial and not part of the - protocol. The password in this example was "secret". Note that the - base64 encoding of the challenges and responses is part of the IMAP4 - AUTHENTICATE command, not part of the Digest specification itself. - - S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9 - C: c CAPABILITY - S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA - UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN - S: c OK Completed - - - -Leach & Newman Standards Track [Page 18] - -RFC 2831 Digest SASL Mechanism May 2000 - - - C: a AUTHENTICATE DIGEST-MD5 - S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0 - RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh - cnNldD11dGYtOA== - C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2 - QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw - MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im - ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw - ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg= - S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA== - C: - S: a OK User logged in - --- - - The base64-decoded version of the SASL exchange is: - - S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth", - algorithm=md5-sess,charset=utf-8 - C: charset=utf-8,username="chris",realm="elwood.innosoft.com", - nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk", - digest-uri="imap/elwood.innosoft.com", - response=d388dad90d4bbd760a152321f2143af7,qop=auth - S: rspauth=ea40f60335c427b5527b84dbabcdfffd - - The password in this example was "secret". - - This example shows the use of the Digest SASL mechanism with the - ACAP, using the same notational conventions and password as in the - previous example. Note that ACAP does not base64 encode and uses - fewer round trips that IMAP4. - - S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5" - "DIGEST-MD5" "PLAIN") - C: a AUTHENTICATE "DIGEST-MD5" - S: + {94} - S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth", - algorithm=md5-sess,charset=utf-8 - C: {206} - C: charset=utf-8,username="chris",realm="elwood.innosoft.com", - nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m", - digest-uri="acap/elwood.innosoft.com", - response=6084c6db3fede7352c551284490fd0fc,qop=auth - S: a OK (SASL {40} - S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE - Completed" - --- - - - - - -Leach & Newman Standards Track [Page 19] - -RFC 2831 Digest SASL Mechanism May 2000 - - - The server uses the values of all the directives, plus knowledge of - the users password (or the hash of the user's name, server's realm - and the user's password) to verify the computations above. If they - check, then the user has authenticated. - -5 References - - [Digest] Franks, J., et al., "HTTP Authentication: Basic and Digest - Access Authentication", RFC 2617, June 1999. - - [ISO-8859] ISO-8859. International Standard--Information Processing-- - 8-bit Single-Byte Coded Graphic Character Sets -- - Part 1: Latin alphabet No. 1, ISO-8859-1:1987. - Part 2: Latin alphabet No. 2, ISO-8859-2, 1987. - Part 3: Latin alphabet No. 3, ISO-8859-3, 1988. - Part 4: Latin alphabet No. 4, ISO-8859-4, 1988. - Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988. - Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987. - Part 7: Latin/Greek alphabet, ISO-8859-7, 1987. - Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988. - Part 9: Latin alphabet No. 5, ISO-8859-9, 1990. - - [RFC 822] Crocker, D., "Standard for The Format of ARPA Internet - Text Messages," STD 11, RFC 822, August 1982. - - [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, - April 1992. - - [RFC 2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) - Part Three: Message Header Extensions for Non-ASCII Text", - RFC 2047, November 1996. - - [RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the - location of services (DNS SRV)", RFC 2052, October 1996. - - [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version - 4rev1", RFC 2060, December 1996. - - [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- - Hashing for Message Authentication", RFC 2104, February - 1997. - - [RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP - AUTHorize Extension for Simple Challenge/Response", RFC - 2195, September 1997. - - - - - - -Leach & Newman Standards Track [Page 20] - -RFC 2831 Digest SASL Mechanism May 2000 - - - [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC 2222] Myers, J., "Simple Authentication and Security Layer - (SASL)", RFC 2222, October 1997. - - [USASCII] US-ASCII. Coded Character Set - 7-Bit American Standard - Code for Information Interchange. Standard ANSI X3.4-1986, - ANSI, 1986. - -6 Authors' Addresses - - Paul Leach - Microsoft - 1 Microsoft Way - Redmond, WA 98052 - - EMail: paulle@microsoft.com - - - Chris Newman - Innosoft International, Inc. - 1050 Lakes Drive - West Covina, CA 91790 USA - - EMail: chris.newman@innosoft.com - -7 ABNF - - What follows is the definition of the notation as is used in the - HTTP/1.1 specification (RFC 2616) and the HTTP authentication - specification (RFC 2617); it is reproduced here for ease of - reference. Since it is intended that a single Digest implementation - can support both HTTP and SASL-based protocols, the same notation is - used in both to facilitate comparison and prevention of unwanted - differences. Since it is cut-and-paste from the HTTP specifications, - not all productions may be used in this specification. It is also not - quite legal ABNF; again, the errors were copied from the HTTP - specifications. - -7.1 Augmented BNF - - All of the mechanisms specified in this document are described in - both prose and an augmented Backus-Naur Form (BNF) similar to that - used by RFC 822 [RFC 822]. Implementers will need to be familiar with - the notation in order to understand this specification. - - - - - -Leach & Newman Standards Track [Page 21] - -RFC 2831 Digest SASL Mechanism May 2000 - - - The augmented BNF includes the following constructs: - - name = definition - The name of a rule is simply the name itself (without any - enclosing "<" and ">") and is separated from its definition by the - equal "=" character. White space is only significant in that - indentation of continuation lines is used to indicate a rule - definition that spans more than one line. Certain basic rules are - in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle - brackets are used within definitions whenever their presence will - facilitate discerning the use of rule names. - - "literal" - Quotation marks surround literal text. Unless stated otherwise, - the text is case-insensitive. - - rule1 | rule2 - Elements separated by a bar ("|") are alternatives, e.g., "yes | - no" will accept yes or no. - - (rule1 rule2) - Elements enclosed in parentheses are treated as a single element. - Thus, "(elem (foo | bar) elem)" allows the token sequences - "elem foo elem" and "elem bar elem". - - *rule - The character "*" preceding an element indicates repetition. The - full form is "*element" indicating at least and at most - occurrences of element. Default values are 0 and infinity so - that "*(element)" allows any number, including zero; "1*element" - requires at least one; and "1*2element" allows one or two. - - [rule] - Square brackets enclose optional elements; "[foo bar]" is - equivalent to "*1(foo bar)". - - N rule - Specific repetition: "(element)" is equivalent to - "*(element)"; that is, exactly occurrences of (element). - Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three - alphabetic characters. - - #rule - A construct "#" is defined, similar to "*", for defining lists of - elements. The full form is "#element" indicating at least - and at most elements, each separated by one or more commas - (",") and OPTIONAL linear white space (LWS). This makes the usual - form of lists very easy; a rule such as - - - -Leach & Newman Standards Track [Page 22] - -RFC 2831 Digest SASL Mechanism May 2000 - - - ( *LWS element *( *LWS "," *LWS element )) - can be shown as - 1#element - Wherever this construct is used, null elements are allowed, but do - not contribute to the count of elements present. That is, - "(element), , (element) " is permitted, but counts as only two - elements. Therefore, where at least one element is required, at - least one non-null element MUST be present. Default values are 0 - and infinity so that "#element" allows any number, including zero; - "1#element" requires at least one; and "1#2element" allows one or - two. - - ; comment - A semi-colon, set off some distance to the right of rule text, - starts a comment that continues to the end of line. This is a - simple way of including useful notes in parallel with the - specifications. - - implied *LWS - The grammar described by this specification is word-based. Except - where noted otherwise, linear white space (LWS) can be included - between any two adjacent words (token or quoted-string), and - between adjacent words and separators, without changing the - interpretation of a field. At least one delimiter (LWS and/or - separators) MUST exist between any two tokens (for the definition - of "token" below), since they would otherwise be interpreted as a - single token. - -7.2 Basic Rules - - The following rules are used throughout this specification to - describe basic parsing constructs. The US-ASCII coded character set - is defined by ANSI X3.4-1986 [USASCII]. - - OCTET = - CHAR = - UPALPHA = - LOALPHA = - ALPHA = UPALPHA | LOALPHA - DIGIT = - CTL = - CR = - LF = - SP = - HT = - <"> = - CRLF = CR LF - - - -Leach & Newman Standards Track [Page 23] - -RFC 2831 Digest SASL Mechanism May 2000 - - - - All linear white space, including folding, has the same semantics as - SP. A recipient MAY replace any linear white space with a single SP - before interpreting the field value or forwarding the message - downstream. - - LWS = [CRLF] 1*( SP | HT ) - - The TEXT rule is only used for descriptive field contents and values - that are not intended to be interpreted by the message parser. Words - of *TEXT MAY contain characters from character sets other than - ISO-8859-1 [ISO 8859] only when encoded according to the rules of RFC - 2047 [RFC 2047]. - - TEXT = - - A CRLF is allowed in the definition of TEXT only as part of a header - field continuation. It is expected that the folding LWS will be - replaced with a single SP before interpretation of the TEXT value. - - Hexadecimal numeric characters are used in several protocol elements. - - HEX = "A" | "B" | "C" | "D" | "E" | "F" - | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT - - Many HTTP/1.1 header field values consist of words separated by LWS - or special characters. These special characters MUST be in a quoted - string to be used within a parameter value. - - token = 1* - separators = "(" | ")" | "<" | ">" | "@" - | "," | ";" | ":" | "\" | <"> - | "/" | "[" | "]" | "?" | "=" - | "{" | "}" | SP | HT - - A string of text is parsed as a single word if it is quoted using - double-quote marks. - - quoted-string = ( <"> qdstr-val <"> ) - qdstr-val = *( qdtext | quoted-pair ) - qdtext = > - - Note that LWS is NOT implicit between the double-quote marks (<">) - surrounding a qdstr-val and the qdstr-val; any LWS will be considered - part of the qdstr-val. This is also the case for quotation marks - surrounding any other construct. - - - - -Leach & Newman Standards Track [Page 24] - -RFC 2831 Digest SASL Mechanism May 2000 - - - The backslash character ("\") MAY be used as a single-character - quoting mechanism only within qdstr-val and comment constructs. - - quoted-pair = "\" CHAR - - The value of this construct is CHAR. Note that an effect of this rule - is that backslash must be quoted. - -8 Sample Code - - The sample implementation in [Digest] also applies to DIGEST-MD5. - - The following code implements the conversion from UTF-8 to 8859-1 if - necessary. - - /* if the string is entirely in the 8859-1 subset of UTF-8, then - * translate to 8859-1 prior to MD5 - */ - void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base, - int len) - { - const unsigned char *scan, *end; - unsigned char cbuf; - - end = base + len; - for (scan = base; scan < end; ++scan) { - if (*scan > 0xC3) break; /* abort if outside 8859-1 */ - if (*scan >= 0xC0 && *scan <= 0xC3) { - if (++scan == end || *scan < 0x80 || *scan > 0xBF) - break; - } - } - /* if we found a character outside 8859-1, don't alter string - */ - if (scan < end) { - MD5Update(ctx, base, len); - return; - } - - /* convert to 8859-1 prior to applying hash - */ - do { - for (scan = base; scan < end && *scan < 0xC0; ++scan) - ; - if (scan != base) MD5Update(ctx, base, scan - base); - if (scan + 1 >= end) break; - cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f); - MD5Update(ctx, &cbuf, 1); - - - -Leach & Newman Standards Track [Page 25] - -RFC 2831 Digest SASL Mechanism May 2000 - - - base = scan + 2; - } while (base < end); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Leach & Newman Standards Track [Page 26] - -RFC 2831 Digest SASL Mechanism May 2000 - - -9 Full Copyright Statement - - Copyright (C) The Internet Society (2000). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Leach & Newman Standards Track [Page 27] - diff --git a/doc/rfc2945.txt b/doc/rfc2945.txt deleted file mode 100644 index 983c441c..00000000 --- a/doc/rfc2945.txt +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - -Network Working Group T. Wu -Request for Comments: 2945 Stanford University -Category: Standards Track September 2000 - - - The SRP Authentication and Key Exchange System - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2000). All Rights Reserved. - -Abstract - - This document describes a cryptographically strong network - authentication mechanism known as the Secure Remote Password (SRP) - protocol. This mechanism is suitable for negotiating secure - connections using a user-supplied password, while eliminating the - security problems traditionally associated with reusable passwords. - This system also performs a secure key exchange in the process of - authentication, allowing security layers (privacy and/or integrity - protection) to be enabled during the session. Trusted key servers - and certificate infrastructures are not required, and clients are not - required to store or manage any long-term keys. SRP offers both - security and deployment advantages over existing challenge-response - techniques, making it an ideal drop-in replacement where secure - password authentication is needed. - -1. Introduction - - The lack of a secure authentication mechanism that is also easy to - use has been a long-standing problem with the vast majority of - Internet protocols currently in use. The problem is two-fold: Users - like to use passwords that they can remember, but most password-based - authentication systems offer little protection against even passive - attackers, especially if weak and easily-guessed passwords are used. - - Eavesdropping on a TCP/IP network can be carried out very easily and - very effectively against protocols that transmit passwords in the - clear. Even so-called "challenge-response" techniques like the one - described in [RFC 2095] and [RFC 1760], which are designed to defeat - - - -Wu Standards Track [Page 1] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - simple sniffing attacks, can be compromised by what is known as a - "dictionary attack". This occurs when an attacker captures the - messages exchanged during a legitimate run of the protocol and uses - that information to verify a series of guessed passwords taken from a - precompiled "dictionary" of common passwords. This works because - users often choose simple, easy-to-remember passwords, which - invariably are also easy to guess. - - Many existing mechanisms also require the password database on the - host to be kept secret because the password P or some private hash - h(P) is stored there and would compromise security if revealed. That - approach often degenerates into "security through obscurity" and goes - against the UNIX convention of keeping a "public" password file whose - contents can be revealed without destroying system security. - - SRP meets the strictest requirements laid down in [RFC 1704] for a - non-disclosing authentication protocol. It offers complete - protection against both passive and active attacks, and accomplishes - this efficiently using a single Diffie-Hellman-style round of - computation, making it feasible to use in both interactive and non- - interactive authentication for a wide range of Internet protocols. - Since it retains its security when used with low-entropy passwords, - it can be seamlessly integrated into existing user applications. - -2. Conventions and Terminology - - The protocol described by this document is sometimes referred to as - "SRP-3" for historical purposes. This particular protocol is - described in [SRP] and is believed to have very good logical and - cryptographic resistance to both eavesdropping and active attacks. - - This document does not attempt to describe SRP in the context of any - particular Internet protocol; instead it describes an abstract - protocol that can be easily fitted to a particular application. For - example, the specific format of messages (including padding) is not - specified. Those issues have been left to the protocol implementor - to decide. - - The one implementation issue worth specifying here is the mapping - between strings and integers. Internet protocols are byte-oriented, - while SRP performs algebraic operations on its messages, so it is - logical to define at least one method by which integers can be - converted into a string of bytes and vice versa. - - An n-byte string S can be converted to an integer as follows: - - i = S[n-1] + 256 * S[n-2] + 256^2 * S[n-3] + ... + 256^(n-1) * S[0] - - - - -Wu Standards Track [Page 2] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - where i is the integer and S[x] is the value of the x'th byte of S. - In human terms, the string of bytes is the integer expressed in base - 256, with the most significant digit first. When converting back to - a string, S[0] must be non-zero (padding is considered to be a - separate, independent process). This conversion method is suitable - for file storage, in-memory representation, and network transmission - of large integer values. Unless otherwise specified, this mapping - will be assumed. - - If implementations require padding a string that represents an - integer value, it is recommended that they use zero bytes and add - them to the beginning of the string. The conversion back to integer - automatically discards leading zero bytes, making this padding scheme - less prone to error. - - The SHA hash function, when used in this document, refers to the - SHA-1 message digest algorithm described in [SHA1]. - -3. The SRP-SHA1 mechanism - - This section describes an implementation of the SRP authentication - and key-exchange protocol that employs the SHA hash function to - generate session keys and authentication proofs. - - The host stores user passwords as triplets of the form - - { , , } - - Password entries are generated as follows: - - = random() - x = SHA( | SHA( | ":" | )) - = v = g^x % N - - The | symbol indicates string concatenation, the ^ operator is the - exponentiation operation, and the % operator is the integer remainder - operation. Most implementations perform the exponentiation and - remainder in a single stage to avoid generating unwieldy intermediate - results. Note that the 160-bit output of SHA is implicitly converted - to an integer before it is operated upon. - - Authentication is generally initiated by the client. - - Client Host - -------- ------ - U = --> - <-- s = - - - - -Wu Standards Track [Page 3] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - Upon identifying himself to the host, the client will receive the - salt stored on the host under his username. - - a = random() - A = g^a % N --> - v = - b = random() - <-- B = (v + g^b) % N - - p = - x = SHA(s | SHA(U | ":" | p)) - - S = (B - g^x) ^ (a + u * x) % N S = (A * v^u) ^ b % N - K = SHA_Interleave(S) K = SHA_Interleave(S) - (this function is described - in the next section) - - The client generates a random number, raises g to that power modulo - the field prime, and sends the result to the host. The host does the - same thing and also adds the public verifier before sending it to the - client. Both sides then construct the shared session key based on - the respective formulae. - - The parameter u is a 32-bit unsigned integer which takes its value - from the first 32 bits of the SHA1 hash of B, MSB first. - - The client MUST abort authentication if B % N is zero. - - The host MUST abort the authentication attempt if A % N is zero. The - host MUST send B after receiving A from the client, never before. - - At this point, the client and server should have a common session key - that is secure (i.e. not known to an outside party). To finish - authentication, they must prove to each other that their keys are - identical. - - M = H(H(N) XOR H(g) | H(U) | s | A | B | K) - --> - <-- H(A | M | K) - - The server will calculate M using its own K and compare it against - the client's response. If they do not match, the server MUST abort - and signal an error before it attempts to answer the client's - challenge. Not doing so could compromise the security of the user's - password. - - - - - - -Wu Standards Track [Page 4] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - If the server receives a correct response, it issues its own proof to - the client. The client will compute the expected response using its - own K to verify the authenticity of the server. If the client - responded correctly, the server MUST respond with its hash value. - - The transactions in this protocol description do not necessarily have - a one-to-one correspondence with actual protocol messages. This - description is only intended to illustrate the relationships between - the different parameters and how they are computed. It is possible, - for example, for an implementation of the SRP-SHA1 mechanism to - consolidate some of the flows as follows: - - Client Host - -------- ------ - U, A --> - <-- s, B - H(H(N) XOR H(g) | H(U) | s | A | B | K) - --> - <-- H(A | M | K) - - The values of N and g used in this protocol must be agreed upon by - the two parties in question. They can be set in advance, or the host - can supply them to the client. In the latter case, the host should - send the parameters in the first message along with the salt. For - maximum security, N should be a safe prime (i.e. a number of the form - N = 2q + 1, where q is also prime). Also, g should be a generator - modulo N (see [SRP] for details), which means that for any X where 0 - < X < N, there exists a value x for which g^x % N == X. - -3.1. Interleaved SHA - - The SHA_Interleave function used in SRP-SHA1 is used to generate a - session key that is twice as long as the 160-bit output of SHA1. To - compute this function, remove all leading zero bytes from the input. - If the length of the resulting string is odd, also remove the first - byte. Call the resulting string T. Extract the even-numbered bytes - into a string E and the odd-numbered bytes into a string F, i.e. - - E = T[0] | T[2] | T[4] | ... - F = T[1] | T[3] | T[5] | ... - - Both E and F should be exactly half the length of T. Hash each one - with regular SHA1, i.e. - - G = SHA(E) - H = SHA(F) - - - - - -Wu Standards Track [Page 5] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - Interleave the two hashes back together to form the output, i.e. - - result = G[0] | H[0] | G[1] | H[1] | ... | G[19] | H[19] - - The result will be 40 bytes (320 bits) long. - -3.2. Other Hash Algorithms - - SRP can be used with hash functions other than SHA. If the hash - function produces an output of a different length than SHA (20 - bytes), it may change the length of some of the messages in the - protocol, but the fundamental operation will be unaffected. - - Earlier versions of the SRP mechanism used the MD5 hash function, - described in [RFC 1321]. Keyed hash transforms are also recommended - for use with SRP; one possible construction uses HMAC [RFC 2104], - using K to key the hash in each direction instead of concatenating it - with the other parameters. - - Any hash function used with SRP should produce an output of at least - 16 bytes and have the property that small changes in the input cause - significant nonlinear changes in the output. [SRP] covers these - issues in more depth. - -4. Security Considerations - - This entire memo discusses an authentication and key-exchange system - that protects passwords and exchanges keys across an untrusted - network. This system improves security by eliminating the need to - send cleartext passwords over the network and by enabling encryption - through its secure key-exchange mechanism. - - The private values for a and b correspond roughly to the private - values in a Diffie-Hellman exchange and have similar constraints of - length and entropy. Implementations may choose to increase the - length of the parameter u, as long as both client and server agree, - but it is not recommended that it be shorter than 32 bits. - - SRP has been designed not only to counter the threat of casual - password-sniffing, but also to prevent a determined attacker equipped - with a dictionary of passwords from guessing at passwords using - captured network traffic. The SRP protocol itself also resists - active network attacks, and implementations can use the securely - exchanged keys to protect the session against hijacking and provide - confidentiality. - - - - - - -Wu Standards Track [Page 6] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - - SRP also has the added advantage of permitting the host to store - passwords in a form that is not directly useful to an attacker. Even - if the host's password database were publicly revealed, the attacker - would still need an expensive dictionary search to obtain any - passwords. The exponential computation required to validate a guess - in this case is much more time-consuming than the hash currently used - by most UNIX systems. Hosts are still advised, though, to try their - best to keep their password files secure. - -5. References - - [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, - April 1992. - - [RFC 1704] Haller, N. and R. Atkinson, "On Internet Authentication", - RFC 1704, October 1994. - - [RFC 1760] Haller, N., "The S/Key One-Time Password System", RFC - 1760, Feburary 1995. - - [RFC 2095] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP - AUTHorize Extension for Simple Challenge/Response", RFC - 2095, January 1997. - - [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- - Hashing for Message Authentication", RFC 2104, February - 1997. - - [SHA1] National Institute of Standards and Technology (NIST), - "Announcing the Secure Hash Standard", FIPS 180-1, U.S. - Department of Commerce, April 1995. - - [SRP] T. Wu, "The Secure Remote Password Protocol", In - Proceedings of the 1998 Internet Society Symposium on - Network and Distributed Systems Security, San Diego, CA, - pp. 97-111. - -6. Author's Address - - Thomas Wu - Stanford University - Stanford, CA 94305 - - EMail: tjw@cs.Stanford.EDU - - - - - - - -Wu Standards Track [Page 7] - -RFC 2945 SRP Authentication & Key Exchange System September 2000 - - -7. Full Copyright Statement - - Copyright (C) The Internet Society (2000). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Wu Standards Track [Page 8] - diff --git a/doc/rfc3174.txt b/doc/rfc3174.txt deleted file mode 100644 index ebe515d3..00000000 --- a/doc/rfc3174.txt +++ /dev/null @@ -1,1235 +0,0 @@ - - - - - - -Network Working Group D. Eastlake, 3rd -Request for Comments: 3174 Motorola -Category: Informational P. Jones - Cisco Systems - September 2001 - - - US Secure Hash Algorithm 1 (SHA1) - -Status of this Memo - - This memo provides information for the Internet community. It does - not specify an Internet standard of any kind. Distribution of this - memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2001). All Rights Reserved. - -Abstract - - The purpose of this document is to make the SHA-1 (Secure Hash - Algorithm 1) hash algorithm conveniently available to the Internet - community. The United States of America has adopted the SHA-1 hash - algorithm described herein as a Federal Information Processing - Standard. Most of the text herein was taken by the authors from FIPS - 180-1. Only the C code implementation is "original". - -Acknowledgements - - Most of the text herein was taken from [FIPS 180-1]. Only the C code - implementation is "original" but its style is similar to the - previously published MD4 and MD5 RFCs [RFCs 1320, 1321]. - - The SHA-1 is based on principles similar to those used by Professor - Ronald L. Rivest of MIT when designing the MD4 message digest - algorithm [MD4] and is modeled after that algorithm [RFC 1320]. - - Useful comments from the following, which have been incorporated - herein, are gratefully acknowledged: - - Tony Hansen - Garrett Wollman - - - - - - - - -Eastlake & Jones Informational [Page 1] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -Table of Contents - - 1. Overview of Contents........................................... 2 - 2. Definitions of Bit Strings and Integers........................ 3 - 3. Operations on Words............................................ 3 - 4. Message Padding................................................ 4 - 5. Functions and Constants Used................................... 6 - 6. Computing the Message Digest................................... 6 - 6.1 Method 1...................................................... 6 - 6.2 Method 2...................................................... 7 - 7. C Code......................................................... 8 - 7.1 .h file....................................................... 8 - 7.2 .c file....................................................... 10 - 7.3 Test Driver................................................... 18 - 8. Security Considerations........................................ 20 - References........................................................ 21 - Authors' Addresses................................................ 21 - Full Copyright Statement.......................................... 22 - -1. Overview of Contents - - NOTE: The text below is mostly taken from [FIPS 180-1] and assertions - therein of the security of SHA-1 are made by the US Government, the - author of [FIPS 180-1], and not by the authors of this document. - - This document specifies a Secure Hash Algorithm, SHA-1, for computing - a condensed representation of a message or a data file. When a - message of any length < 2^64 bits is input, the SHA-1 produces a - 160-bit output called a message digest. The message digest can then, - for example, be input to a signature algorithm which generates or - verifies the signature for the message. Signing the message digest - rather than the message often improves the efficiency of the process - because the message digest is usually much smaller in size than the - message. The same hash algorithm must be used by the verifier of a - digital signature as was used by the creator of the digital - signature. Any change to the message in transit will, with very high - probability, result in a different message digest, and the signature - will fail to verify. - - The SHA-1 is called secure because it is computationally infeasible - to find a message which corresponds to a given message digest, or to - find two different messages which produce the same message digest. - Any change to a message in transit will, with very high probability, - result in a different message digest, and the signature will fail to - verify. - - - - - - -Eastlake & Jones Informational [Page 2] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - Section 2 below defines the terminology and functions used as - building blocks to form SHA-1. - -2. Definitions of Bit Strings and Integers - - The following terminology related to bit strings and integers will be - used: - - a. A hex digit is an element of the set {0, 1, ... , 9, A, ... , F}. - A hex digit is the representation of a 4-bit string. Examples: 7 - = 0111, A = 1010. - - b. A word equals a 32-bit string which may be represented as a - sequence of 8 hex digits. To convert a word to 8 hex digits each - 4-bit string is converted to its hex equivalent as described in - (a) above. Example: - - 1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23. - - c. An integer between 0 and 2^32 - 1 inclusive may be represented as - a word. The least significant four bits of the integer are - represented by the right-most hex digit of the word - representation. Example: the integer 291 = 2^8+2^5+2^1+2^0 = - 256+32+2+1 is represented by the hex word, 00000123. - - If z is an integer, 0 <= z < 2^64, then z = (2^32)x + y where 0 <= - x < 2^32 and 0 <= y < 2^32. Since x and y can be represented as - words X and Y, respectively, z can be represented as the pair of - words (X,Y). - - d. block = 512-bit string. A block (e.g., B) may be represented as a - sequence of 16 words. - -3. Operations on Words - - The following logical operators will be applied to words: - - a. Bitwise logical word operations - - X AND Y = bitwise logical "and" of X and Y. - - X OR Y = bitwise logical "inclusive-or" of X and Y. - - X XOR Y = bitwise logical "exclusive-or" of X and Y. - - NOT X = bitwise logical "complement" of X. - - - - - -Eastlake & Jones Informational [Page 3] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - Example: - - 01101100101110011101001001111011 - XOR 01100101110000010110100110110111 - -------------------------------- - = 00001001011110001011101111001100 - - b. The operation X + Y is defined as follows: words X and Y - represent integers x and y, where 0 <= x < 2^32 and 0 <= y < 2^32. - For positive integers n and m, let n mod m be the remainder upon - dividing n by m. Compute - - z = (x + y) mod 2^32. - - Then 0 <= z < 2^32. Convert z to a word, Z, and define Z = X + - Y. - - c. The circular left shift operation S^n(X), where X is a word and n - is an integer with 0 <= n < 32, is defined by - - S^n(X) = (X << n) OR (X >> 32-n). - - In the above, X << n is obtained as follows: discard the left-most - n bits of X and then pad the result with n zeroes on the right - (the result will still be 32 bits). X >> n is obtained by - discarding the right-most n bits of X and then padding the result - with n zeroes on the left. Thus S^n(X) is equivalent to a - circular shift of X by n positions to the left. - -4. Message Padding - - SHA-1 is used to compute a message digest for a message or data file - that is provided as input. The message or data file should be - considered to be a bit string. The length of the message is the - number of bits in the message (the empty message has length 0). If - the number of bits in a message is a multiple of 8, for compactness - we can represent the message in hex. The purpose of message padding - is to make the total length of a padded message a multiple of 512. - SHA-1 sequentially processes blocks of 512 bits when computing the - message digest. The following specifies how this padding shall be - performed. As a summary, a "1" followed by m "0"s followed by a 64- - bit integer are appended to the end of the message to produce a - padded message of length 512 * n. The 64-bit integer is the length - of the original message. The padded message is then processed by the - SHA-1 as n 512-bit blocks. - - - - - - -Eastlake & Jones Informational [Page 4] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - Suppose a message has length l < 2^64. Before it is input to the - SHA-1, the message is padded on the right as follows: - - a. "1" is appended. Example: if the original message is "01010000", - this is padded to "010100001". - - b. "0"s are appended. The number of "0"s will depend on the original - length of the message. The last 64 bits of the last 512-bit block - are reserved - - for the length l of the original message. - - Example: Suppose the original message is the bit string - - 01100001 01100010 01100011 01100100 01100101. - - After step (a) this gives - - 01100001 01100010 01100011 01100100 01100101 1. - - Since l = 40, the number of bits in the above is 41 and 407 "0"s - are appended, making the total now 448. This gives (in hex) - - 61626364 65800000 00000000 00000000 - 00000000 00000000 00000000 00000000 - 00000000 00000000 00000000 00000000 - 00000000 00000000. - - c. Obtain the 2-word representation of l, the number of bits in the - original message. If l < 2^32 then the first word is all zeroes. - Append these two words to the padded message. - - Example: Suppose the original message is as in (b). Then l = 40 - (note that l is computed before any padding). The two-word - representation of 40 is hex 00000000 00000028. Hence the final - padded message is hex - - 61626364 65800000 00000000 00000000 - 00000000 00000000 00000000 00000000 - 00000000 00000000 00000000 00000000 - 00000000 00000000 00000000 00000028. - - The padded message will contain 16 * n words for some n > 0. - The padded message is regarded as a sequence of n blocks M(1) , - M(2), first characters (or bits) of the message. - - - - - - -Eastlake & Jones Informational [Page 5] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -5. Functions and Constants Used - - A sequence of logical functions f(0), f(1),..., f(79) is used in - SHA-1. Each f(t), 0 <= t <= 79, operates on three 32-bit words B, C, - D and produces a 32-bit word as output. f(t;B,C,D) is defined as - follows: for words B, C, D, - - f(t;B,C,D) = (B AND C) OR ((NOT B) AND D) ( 0 <= t <= 19) - - f(t;B,C,D) = B XOR C XOR D (20 <= t <= 39) - - f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D) (40 <= t <= 59) - - f(t;B,C,D) = B XOR C XOR D (60 <= t <= 79). - - A sequence of constant words K(0), K(1), ... , K(79) is used in the - SHA-1. In hex these are given by - - K(t) = 5A827999 ( 0 <= t <= 19) - - K(t) = 6ED9EBA1 (20 <= t <= 39) - - K(t) = 8F1BBCDC (40 <= t <= 59) - - K(t) = CA62C1D6 (60 <= t <= 79). - -6. Computing the Message Digest - - The methods given in 6.1 and 6.2 below yield the same message digest. - Although using method 2 saves sixty-four 32-bit words of storage, it - is likely to lengthen execution time due to the increased complexity - of the address computations for the { W[t] } in step (c). There are - other computation methods which give identical results. - -6.1 Method 1 - - The message digest is computed using the message padded as described - in section 4. The computation is described using two buffers, each - consisting of five 32-bit words, and a sequence of eighty 32-bit - words. The words of the first 5-word buffer are labeled A,B,C,D,E. - The words of the second 5-word buffer are labeled H0, H1, H2, H3, H4. - The words of the 80-word sequence are labeled W(0), W(1),..., W(79). - A single word buffer TEMP is also employed. - - To generate the message digest, the 16-word blocks M(1), M(2),..., - M(n) defined in section 4 are processed in order. The processing of - each M(i) involves 80 steps. - - - - -Eastlake & Jones Informational [Page 6] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - Before processing any blocks, the H's are initialized as follows: in - hex, - - H0 = 67452301 - - H1 = EFCDAB89 - - H2 = 98BADCFE - - H3 = 10325476 - - H4 = C3D2E1F0. - - Now M(1), M(2), ... , M(n) are processed. To process M(i), we - proceed as follows: - - a. Divide M(i) into 16 words W(0), W(1), ... , W(15), where W(0) - is the left-most word. - - b. For t = 16 to 79 let - - W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). - - c. Let A = H0, B = H1, C = H2, D = H3, E = H4. - - d. For t = 0 to 79 do - - TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t); - - E = D; D = C; C = S^30(B); B = A; A = TEMP; - - e. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 - + E. - - After processing M(n), the message digest is the 160-bit string - represented by the 5 words - - H0 H1 H2 H3 H4. - -6.2 Method 2 - - The method above assumes that the sequence W(0), ... , W(79) is - implemented as an array of eighty 32-bit words. This is efficient - from the standpoint of minimization of execution time, since the - addresses of W(t-3), ... ,W(t-16) in step (b) are easily computed. - If space is at a premium, an alternative is to regard { W(t) } as a - - - - - -Eastlake & Jones Informational [Page 7] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - circular queue, which may be implemented using an array of sixteen - 32-bit words W[0], ... W[15]. In this case, in hex let - - MASK = 0000000F. Then processing of M(i) is as follows: - - a. Divide M(i) into 16 words W[0], ... , W[15], where W[0] is the - left-most word. - - b. Let A = H0, B = H1, C = H2, D = H3, E = H4. - - c. For t = 0 to 79 do - - s = t AND MASK; - - if (t >= 16) W[s] = S^1(W[(s + 13) AND MASK] XOR W[(s + 8) AND - MASK] XOR W[(s + 2) AND MASK] XOR W[s]); - - TEMP = S^5(A) + f(t;B,C,D) + E + W[s] + K(t); - - E = D; D = C; C = S^30(B); B = A; A = TEMP; - - d. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 - + E. - -7. C Code - - Below is a demonstration implementation of SHA-1 in C. Section 7.1 - contains the header file, 7.2 the C code, and 7.3 a test driver. - -7.1 .h file - -/* - * sha1.h - * - * Description: - * This is the header file for code which implements the Secure - * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published - * April 17, 1995. - * - * Many of the variable names in this code, especially the - * single character names, were used because those were the names - * used in the publication. - * - * Please read the file sha1.c for more information. - * - */ - - - - - -Eastlake & Jones Informational [Page 8] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -#ifndef _SHA1_H_ -#define _SHA1_H_ - -#include -/* - * If you do not have the ISO standard stdint.h header file, then you - * must typdef the following: - * name meaning - * uint32_t unsigned 32 bit integer - * uint8_t unsigned 8 bit integer (i.e., unsigned char) - * int_least16_t integer of >= 16 bits - * - */ - -#ifndef _SHA_enum_ -#define _SHA_enum_ -enum -{ - shaSuccess = 0, - shaNull, /* Null pointer parameter */ - shaInputTooLong, /* input data too long */ - shaStateError /* called Input after Result */ -}; -#endif -#define SHA1HashSize 20 - -/* - * This structure will hold context information for the SHA-1 - * hashing operation - */ -typedef struct SHA1Context -{ - uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ - - uint32_t Length_Low; /* Message length in bits */ - uint32_t Length_High; /* Message length in bits */ - - /* Index into message block array */ - int_least16_t Message_Block_Index; - uint8_t Message_Block[64]; /* 512-bit message blocks */ - - int Computed; /* Is the digest computed? */ - int Corrupted; /* Is the message digest corrupted? */ -} SHA1Context; - -/* - * Function Prototypes - */ - - - -Eastlake & Jones Informational [Page 9] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -int SHA1Reset( SHA1Context *); -int SHA1Input( SHA1Context *, - const uint8_t *, - unsigned int); -int SHA1Result( SHA1Context *, - uint8_t Message_Digest[SHA1HashSize]); - -#endif - -7.2 .c file - -/* - * sha1.c - * - * Description: - * This file implements the Secure Hashing Algorithm 1 as - * defined in FIPS PUB 180-1 published April 17, 1995. - * - * The SHA-1, produces a 160-bit message digest for a given - * data stream. It should take about 2**n steps to find a - * message with the same digest as a given message and - * 2**(n/2) to find any two messages with the same digest, - * when n is the digest size in bits. Therefore, this - * algorithm can serve as a means of providing a - * "fingerprint" for a message. - * - * Portability Issues: - * SHA-1 is defined in terms of 32-bit "words". This code - * uses (included via "sha1.h" to define 32 and 8 - * bit unsigned integer types. If your C compiler does not - * support 32 bit unsigned integers, this code is not - * appropriate. - * - * Caveats: - * SHA-1 is designed to work with messages less than 2^64 bits - * long. Although SHA-1 allows a message digest to be generated - * for messages of any number of bits less than 2^64, this - * implementation only works with messages with a length that is - * a multiple of the size of an 8-bit character. - * - */ - - - - - - - - - - -Eastlake & Jones Informational [Page 10] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -#include "sha1.h" - -/* - * Define the SHA1 circular left shift macro - */ -#define SHA1CircularShift(bits,word) \ - (((word) << (bits)) | ((word) >> (32-(bits)))) - -/* Local Function Prototyptes */ -void SHA1PadMessage(SHA1Context *); -void SHA1ProcessMessageBlock(SHA1Context *); - -/* - * SHA1Reset - * - * Description: - * This function will initialize the SHA1Context in preparation - * for computing a new SHA1 message digest. - * - * Parameters: - * context: [in/out] - * The context to reset. - * - * Returns: - * sha Error Code. - * - */ -int SHA1Reset(SHA1Context *context) -{ - if (!context) - { - return shaNull; - } - - context->Length_Low = 0; - context->Length_High = 0; - context->Message_Block_Index = 0; - - context->Intermediate_Hash[0] = 0x67452301; - context->Intermediate_Hash[1] = 0xEFCDAB89; - context->Intermediate_Hash[2] = 0x98BADCFE; - context->Intermediate_Hash[3] = 0x10325476; - context->Intermediate_Hash[4] = 0xC3D2E1F0; - - context->Computed = 0; - context->Corrupted = 0; - - - - - -Eastlake & Jones Informational [Page 11] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - return shaSuccess; -} - -/* - * SHA1Result - * - * Description: - * This function will return the 160-bit message digest into the - * Message_Digest array provided by the caller. - * NOTE: The first octet of hash is stored in the 0th element, - * the last octet of hash in the 19th element. - * - * Parameters: - * context: [in/out] - * The context to use to calculate the SHA-1 hash. - * Message_Digest: [out] - * Where the digest is returned. - * - * Returns: - * sha Error Code. - * - */ -int SHA1Result( SHA1Context *context, - uint8_t Message_Digest[SHA1HashSize]) -{ - int i; - - if (!context || !Message_Digest) - { - return shaNull; - } - - if (context->Corrupted) - { - return context->Corrupted; - } - - if (!context->Computed) - { - SHA1PadMessage(context); - for(i=0; i<64; ++i) - { - /* message may be sensitive, clear it out */ - context->Message_Block[i] = 0; - } - context->Length_Low = 0; /* and clear length */ - context->Length_High = 0; - context->Computed = 1; - - - -Eastlake & Jones Informational [Page 12] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - } - - for(i = 0; i < SHA1HashSize; ++i) - { - Message_Digest[i] = context->Intermediate_Hash[i>>2] - >> 8 * ( 3 - ( i & 0x03 ) ); - } - - return shaSuccess; -} - -/* - * SHA1Input - * - * Description: - * This function accepts an array of octets as the next portion - * of the message. - * - * Parameters: - * context: [in/out] - * The SHA context to update - * message_array: [in] - * An array of characters representing the next portion of - * the message. - * length: [in] - * The length of the message in message_array - * - * Returns: - * sha Error Code. - * - */ -int SHA1Input( SHA1Context *context, - const uint8_t *message_array, - unsigned length) -{ - if (!length) - { - return shaSuccess; - } - - if (!context || !message_array) - { - return shaNull; - } - - if (context->Computed) - { - context->Corrupted = shaStateError; - - - -Eastlake & Jones Informational [Page 13] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - return shaStateError; - } - - if (context->Corrupted) - { - return context->Corrupted; - } - while(length-- && !context->Corrupted) - { - context->Message_Block[context->Message_Block_Index++] = - (*message_array & 0xFF); - - context->Length_Low += 8; - if (context->Length_Low == 0) - { - context->Length_High++; - if (context->Length_High == 0) - { - /* Message is too long */ - context->Corrupted = 1; - } - } - - if (context->Message_Block_Index == 64) - { - SHA1ProcessMessageBlock(context); - } - - message_array++; - } - - return shaSuccess; -} - -/* - * SHA1ProcessMessageBlock - * - * Description: - * This function will process the next 512 bits of the message - * stored in the Message_Block array. - * - * Parameters: - * None. - * - * Returns: - * Nothing. - * - * Comments: - - - -Eastlake & Jones Informational [Page 14] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - * Many of the variable names in this code, especially the - * single character names, were used because those were the - * names used in the publication. - * - * - */ -void SHA1ProcessMessageBlock(SHA1Context *context) -{ - const uint32_t K[] = { /* Constants defined in SHA-1 */ - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; /* Loop counter */ - uint32_t temp; /* Temporary word value */ - uint32_t W[80]; /* Word sequence */ - uint32_t A, B, C, D, E; /* Word buffers */ - - /* - * Initialize the first 16 words in the array W - */ - for(t = 0; t < 16; t++) - { - W[t] = context->Message_Block[t * 4] << 24; - W[t] |= context->Message_Block[t * 4 + 1] << 16; - W[t] |= context->Message_Block[t * 4 + 2] << 8; - W[t] |= context->Message_Block[t * 4 + 3]; - } - - for(t = 16; t < 80; t++) - { - W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = context->Intermediate_Hash[0]; - B = context->Intermediate_Hash[1]; - C = context->Intermediate_Hash[2]; - D = context->Intermediate_Hash[3]; - E = context->Intermediate_Hash[4]; - - for(t = 0; t < 20; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - - - -Eastlake & Jones Informational [Page 15] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - B = A; - A = temp; - } - - for(t = 20; t < 40; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 40; t < 60; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 60; t < 80; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - context->Intermediate_Hash[0] += A; - context->Intermediate_Hash[1] += B; - context->Intermediate_Hash[2] += C; - context->Intermediate_Hash[3] += D; - context->Intermediate_Hash[4] += E; - - context->Message_Block_Index = 0; -} - - -/* - * SHA1PadMessage - * - - - -Eastlake & Jones Informational [Page 16] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - * Description: - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 - * bits represent the length of the original message. All bits in - * between should be 0. This function will pad the message - * according to those rules by filling the Message_Block array - * accordingly. It will also call the ProcessMessageBlock function - * provided appropriately. When it returns, it can be assumed that - * the message digest has been computed. - * - * Parameters: - * context: [in/out] - * The context to pad - * ProcessMessageBlock: [in] - * The appropriate SHA*ProcessMessageBlock function - * Returns: - * Nothing. - * - */ - -void SHA1PadMessage(SHA1Context *context) -{ - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second - * block. - */ - if (context->Message_Block_Index > 55) - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 64) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - - SHA1ProcessMessageBlock(context); - - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - else - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 56) - { - - - -Eastlake & Jones Informational [Page 17] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - - /* - * Store the message length as the last 8 octets - */ - context->Message_Block[56] = context->Length_High >> 24; - context->Message_Block[57] = context->Length_High >> 16; - context->Message_Block[58] = context->Length_High >> 8; - context->Message_Block[59] = context->Length_High; - context->Message_Block[60] = context->Length_Low >> 24; - context->Message_Block[61] = context->Length_Low >> 16; - context->Message_Block[62] = context->Length_Low >> 8; - context->Message_Block[63] = context->Length_Low; - - SHA1ProcessMessageBlock(context); -} - -7.3 Test Driver - - The following code is a main program test driver to exercise the code - in sha1.c. - -/* - * sha1test.c - * - * Description: - * This file will exercise the SHA-1 code performing the three - * tests documented in FIPS PUB 180-1 plus one which calls - * SHA1Input with an exact multiple of 512 bits, plus a few - * error test checks. - * - * Portability Issues: - * None. - * - */ - -#include -#include -#include -#include "sha1.h" - -/* - * Define patterns for testing - */ -#define TEST1 "abc" -#define TEST2a "abcdbcdecdefdefgefghfghighijhi" - - - -Eastlake & Jones Informational [Page 18] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -#define TEST2b "jkijkljklmklmnlmnomnopnopq" -#define TEST2 TEST2a TEST2b -#define TEST3 "a" -#define TEST4a "01234567012345670123456701234567" -#define TEST4b "01234567012345670123456701234567" - /* an exact multiple of 512 bits */ -#define TEST4 TEST4a TEST4b -char *testarray[4] = -{ - TEST1, - TEST2, - TEST3, - TEST4 -}; -long int repeatcount[4] = { 1, 1, 1000000, 10 }; -char *resultarray[4] = -{ - "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D", - "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1", - "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F", - "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52" -}; - -int main() -{ - SHA1Context sha; - int i, j, err; - uint8_t Message_Digest[20]; - - /* - * Perform SHA-1 tests - */ - for(j = 0; j < 4; ++j) - { - printf( "\nTest %d: %d, '%s'\n", - j+1, - repeatcount[j], - testarray[j]); - - err = SHA1Reset(&sha); - if (err) - { - fprintf(stderr, "SHA1Reset Error %d.\n", err ); - break; /* out of for j loop */ - } - - for(i = 0; i < repeatcount[j]; ++i) - { - - - -Eastlake & Jones Informational [Page 19] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - - err = SHA1Input(&sha, - (const unsigned char *) testarray[j], - strlen(testarray[j])); - if (err) - { - fprintf(stderr, "SHA1Input Error %d.\n", err ); - break; /* out of for i loop */ - } - } - - err = SHA1Result(&sha, Message_Digest); - if (err) - { - fprintf(stderr, - "SHA1Result Error %d, could not compute message digest.\n", - err ); - } - else - { - printf("\t"); - for(i = 0; i < 20 ; ++i) - { - printf("%02X ", Message_Digest[i]); - } - printf("\n"); - } - printf("Should match:\n"); - printf("\t%s\n", resultarray[j]); - } - - /* Test some error returns */ - err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1); - printf ("\nError %d. Should be %d.\n", err, shaStateError ); - err = SHA1Reset(0); - printf ("\nError %d. Should be %d.\n", err, shaNull ); - return 0; -} - -8. Security Considerations - - This document is intended to provide convenient open source access by - the Internet community to the United States of America Federal - Information Processing Standard Secure Hash Function SHA-1 [FIPS - 180-1]. No independent assertion of the security of this hash - function by the authors for any particular use is intended. - - - - - - -Eastlake & Jones Informational [Page 20] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -References - - [FIPS 180-1] "Secure Hash Standard", United States of American, - National Institute of Science and Technology, Federal - Information Processing Standard (FIPS) 180-1, April - 1993. - - [MD4] "The MD4 Message Digest Algorithm," Advances in - Cryptology - CRYPTO '90 Proceedings, Springer-Verlag, - 1991, pp. 303-311. - - [RFC 1320] Rivest, R., "The MD4 Message-Digest Algorithm", RFC - 1320, April 1992. - - [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC - 1321, April 1992. - - [RFC 1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness - Requirements for Security", RFC 1750, December 1994. - -Authors' Addresses - - Donald E. Eastlake, 3rd - Motorola - 155 Beaver Street - Milford, MA 01757 USA - - Phone: +1 508-634-2066 (h) - +1 508-261-5434 (w) - Fax: +1 508-261-4777 - EMail: Donald.Eastlake@motorola.com - - - Paul E. Jones - Cisco Systems, Inc. - 7025 Kit Creek Road - Research Triangle Park, NC 27709 USA - - Phone: +1 919 392 6948 - EMail: paulej@packetizer.com - - - - - - - - - - - -Eastlake & Jones Informational [Page 21] - -RFC 3174 US Secure Hash Algorithm 1 (SHA1) September 2001 - - -Full Copyright Statement - - Copyright (C) The Internet Society (2001). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Eastlake & Jones Informational [Page 22] - diff --git a/docsrc/Makefile b/docsrc/Makefile new file mode 100644 index 00000000..82fd68d2 --- /dev/null +++ b/docsrc/Makefile @@ -0,0 +1,186 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = -n +SPHINXBUILD = sphinx-build +PAPER = +SOURCEDIR = . +BUILDDIR = build + +# Only need Perl2RST if building docs from Perl modules, which cyrus-sasl doesn't have +#PERL2RST = ../tools/perl2rst + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# User-friendly check for perl2rst +#ifeq ($(shell which $(PERL2RST) >/dev/null 2>&1; echo $$?), 1) +#$(error The '$(PERL2RST)' command was not found. Make sure you have perl2rst installed, then set the PERL2RST environment variable to point to #the full path of the '$(PERL2RST)' script. It relies on Perl module Pod::POM::View::Restructured) +#endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR) +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR) + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CyrusIMAP.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CyrusIMAP.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/CyrusIMAP" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CyrusIMAP" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b cyrman $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docsrc/_static/cyrus.css b/docsrc/_static/cyrus.css new file mode 100644 index 00000000..7ec3d497 --- /dev/null +++ b/docsrc/_static/cyrus.css @@ -0,0 +1,224 @@ +a { + color: #1f8fc0; +} + +a tt { + color: #1f8fc0; +} + +a.internal em { + font-style: normal; +} + +blockquote.epigraph div p { + font-style: italic; +} + +body { + font-family: sans-serif; + letter-spacing: 0; +} + +cite, code, pre, tt { + font-family: "Liberation Mono", "Consolas","Deja Vu Sans Mono","Bitstream Vera Sans Mono", monospace; +} + +div.admonition { + border-left: 0.5em solid #59bc00; + border-top: none; + border-right: none; + border-bottom: none; + margin-bottom: 1em; + padding-bottom: 0.5em; + padding-left: 1.5em; + padding-top: 0.5em; +} + +div.admonition > div:last-child > *:last-child { + margin-bottom: 0; +} + +div.admonition p { + margin: 1em 0 0.5em 0.5em; + padding: 0; +} + +div.admonition p.admonition-title { + color: black; + margin: 1em 0 0.5em 0.5em; + padding: 0; + font-weight: bold; + display: block; + background-color: inherit; + border-bottom: none; +} + +/* Green 'note' box */ +div.admonition.note { + border-left: 0.5em solid #59bc00; +} + +div.admonition.important { + border-color: #ffc200; +} + +div.admonition.warning { + border-color: #ff0000; +} + +div.admonition.tip { + border-color: #1e90ff; +} + +div.admonition-todo { + border-color: #cccccc; +} + +div.admonition.caution { + border-color: #950000; +} + +div.body a { + text-decoration: none; + color: #1F8FC0; +} + +div.body h1, div.body h2, div.body h3 { + color: #002e50; +} + +div.highlight { +/* border-left: 0.5em solid #666666; */ + padding: 0; + margin: 1em 0 0.5em 0; +} + +.highlight { + background: #eeeeee; +} + +div.highlight pre { + border: 0px solid; + margin: 1em 0.5em 0.5em 0.5em; + padding-bottom: 0.5em; + padding-left: 1.5em; + padding-top: 0.5em; +} + +div.linenodiv pre { + padding: 0.5em 0 0; +} + +div.related { + background-color: #1F8FC0; +} + +div.related ul li a { + color: white; +} + + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + background-color: #002e50; + border: 1px solid white; + color: white; +} + +div.sphinxsidebar h3 a { + color: white; +} + +ol.arabic li { + margin-top: 0.5em; + line-height: 110% +} + +p.caption { + font-style: italic; +} + +.caption-text { + font-size: 60% +} + +nav.wy-nav-side p.caption { + font-size: 150% +} + +/* For bold-italic and italic inside other formatting styles */ +/* ``command line `` :italic:`with italics` + */ + +.bolditalic { + font-weight: bold; + font-style: italic; +} + +.italic { + font-style: italic; +} + +.pageheader { + background-image: url(headimg.gif); + text-align: left; + padding: 10px 15px; +} + +.pageheader ul { + float: right; + color: white; + list-style-type: none; + padding-left: 0; + margin-top: 30px; + margin-right: 10px; +} + +.pageheader li { + float: left; + margin: 0 0 0 10px; +} + +.pageheader li a { + border-radius: 1px; + padding: 8px 12px; + color: #f9f9f0; + text-shadow: 0 0 5px rgba(0, 0, 0, 0.5); +} + +.pageheader li a:hover { + background-color: #f9f9f0; + color: #0a507a; + text-shadow: none; +} + +.wy-nav-content { + max-width: 100% +} + +.wy-nav-side { + background-color: #2d9dcb; + color: white; +} + +.wy-nav-side li a { + color: white; +} + +.wy-side-nav-search { + background-color: #2d9dcb; +} + +.wy-side-nav-search a img { + margin-bottom: 0px; +} + +.wy-side-nav-search a:hover { + background-color: #2d9dcb; +} + +.wy-side-nav-search img { + border-radius: initial; + width: 100%; + height: 100%; + background-color: #2d9dcb; +} \ No newline at end of file diff --git a/docsrc/_static/event_notifications/AclChange.json b/docsrc/_static/event_notifications/AclChange.json new file mode 100644 index 00000000..474e3243 --- /dev/null +++ b/docsrc/_static/event_notifications/AclChange.json @@ -0,0 +1,12 @@ +{ + "aclRights": "lrs", + "aclSubject": "jane@example.org", + "event": "AclChange", + "mailboxID": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "pid": 8048, + "service": "imap", + "timestamp": "2015-02-23T14:57:59.736+01:00", + "uri": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-8048-1424699879-1-8051832424702584527" +} diff --git a/docsrc/_static/event_notifications/ApplePushService.json b/docsrc/_static/event_notifications/ApplePushService.json new file mode 100644 index 00000000..8c1f084e --- /dev/null +++ b/docsrc/_static/event_notifications/ApplePushService.json @@ -0,0 +1,9 @@ +{ + "event":"ApplePushService", + "user": "john@example.org", + "apsVersion": "", + "apsAccountId": "", + "apsDeviceToken": "", + "apsSubtopic": "", + "mailboxes": "[array of mailboxIDs]" +} diff --git a/docsrc/_static/event_notifications/CalendarAlarm.json b/docsrc/_static/event_notifications/CalendarAlarm.json new file mode 100644 index 00000000..706e5447 --- /dev/null +++ b/docsrc/_static/event_notifications/CalendarAlarm.json @@ -0,0 +1,22 @@ +{ + "event":"CalendarAlarm", + "pid":3164225, + "serverFQDN":"sloti30t15", + "alarmTime":"20151119T063000Z", + "alarmRecipients":["mailto:mary@example.org"], + "userId":"mary@example.org", + "calendarName":"Calendar", + "uid":"49ba20f5-cb44-4863-aea7-255f37ffc2e7", + "action":"email", + "summary":"Here's a lovely event. Remind me", + "description":"", + "location":"", + "timezone":"Australia/Melbourne", + "start":"20151119T073000Z", + "end":"20151119T083000Z", + "allDay":0, + "attendeeNames":[], + "attendeeEmails":[], + "attendeeStatus":[], + "organizer":"" +} \ No newline at end of file diff --git a/docsrc/_static/event_notifications/FlagsClear.json b/docsrc/_static/event_notifications/FlagsClear.json new file mode 100644 index 00000000..4a7691b1 --- /dev/null +++ b/docsrc/_static/event_notifications/FlagsClear.json @@ -0,0 +1,18 @@ +{ + "event": "FlagsClear", + "flagNames": "\\Flagged", + "messages": 1, + "modseq": 43, + "pid": 7721, + "service": "imap", + "timestamp": "2015-02-23T14:50:43.640+01:00", + "uidnext": 4, + "uidset": "3", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.sessionId": "imap.example.org-7721-1424699443-1-8479002111695998134", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/FlagsSet.json b/docsrc/_static/event_notifications/FlagsSet.json new file mode 100644 index 00000000..97d76a2e --- /dev/null +++ b/docsrc/_static/event_notifications/FlagsSet.json @@ -0,0 +1,18 @@ +{ + "event": "FlagsSet", + "flagNames": "\\Flagged", + "messages": 1, + "modseq": 42, + "pid": 7649, + "service": "imap", + "timestamp": "2015-02-23T14:50:21.858+01:00", + "uidnext": 4, + "uidset": "3", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.sessionId": "imap.example.org-7649-1424699421-1-11813528620713894618", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/Login.json b/docsrc/_static/event_notifications/Login.json new file mode 100644 index 00000000..2a955951 --- /dev/null +++ b/docsrc/_static/event_notifications/Login.json @@ -0,0 +1,13 @@ +{ + "clientIP": "::1", + "clientPort": 46461, + "event": "Login", + "pid": 7629, + "serverDomain": "::1", + "serverPort": 143, + "service": "imap", + "timestamp": "2015-02-23T14:47:36.097+01:00", + "uri": "imap://imap.example.org", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-7629-1424699256-1-3981462903180119079" +} diff --git a/docsrc/_static/event_notifications/Logout.json b/docsrc/_static/event_notifications/Logout.json new file mode 100644 index 00000000..7d897137 --- /dev/null +++ b/docsrc/_static/event_notifications/Logout.json @@ -0,0 +1,13 @@ +{ + "clientIP": "::1", + "clientPort": 46461, + "event": "Logout", + "pid": 7629, + "serverDomain": "::1", + "serverPort": 143, + "service": "imap", + "timestamp": "2015-02-23T14:47:36.183+01:00", + "uri": "imap://imap.example.org", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-7629-1424699256-1-3981462903180119079" +} diff --git a/docsrc/_static/event_notifications/MailboxCreate.json b/docsrc/_static/event_notifications/MailboxCreate.json new file mode 100644 index 00000000..f4b8f79d --- /dev/null +++ b/docsrc/_static/event_notifications/MailboxCreate.json @@ -0,0 +1,10 @@ +{ + "event": "MailboxCreate", + "mailboxID": "imap://john@example.org@imap.example.org/Testfolder;UIDVALIDITY=1424690388", + "pid": 7721, + "service": "imap", + "timestamp": "2015-02-23T14:55:57.621+01:00", + "uri": "imap://john@example.org@imap.example.org/Testfolder;UIDVALIDITY=1424690388", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-7721-1424699757-1-18345110432907898457" +} diff --git a/docsrc/_static/event_notifications/MailboxDelete.json b/docsrc/_static/event_notifications/MailboxDelete.json new file mode 100644 index 00000000..8dc5d2e6 --- /dev/null +++ b/docsrc/_static/event_notifications/MailboxDelete.json @@ -0,0 +1,10 @@ +{ + "event": "MailboxDelete", + "mailboxID": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "pid": 8070, + "service": "imap", + "timestamp": "2015-02-23T14:58:37.145+01:00", + "uri": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-8070-1424699917-1-11277155374959916506" +} diff --git a/docsrc/_static/event_notifications/MailboxRename.json b/docsrc/_static/event_notifications/MailboxRename.json new file mode 100644 index 00000000..1d954eea --- /dev/null +++ b/docsrc/_static/event_notifications/MailboxRename.json @@ -0,0 +1,11 @@ +{ + "event": "MailboxRename", + "mailboxID": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "oldMailboxID": "imap://john@example.org@imap.example.org/Testfolder;UIDVALIDITY=1424690388", + "pid": 8026, + "service": "imap", + "timestamp": "2015-02-23T14:56:47.466+01:00", + "uri": "imap://john@example.org@imap.example.org/Testfolder_renamed;UIDVALIDITY=1424699807", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-8026-1424699807-1-3097981731339369225" +} diff --git a/docsrc/_static/event_notifications/MailboxSubscribe.json b/docsrc/_static/event_notifications/MailboxSubscribe.json new file mode 100644 index 00000000..2bfd014c --- /dev/null +++ b/docsrc/_static/event_notifications/MailboxSubscribe.json @@ -0,0 +1,9 @@ +{ + "event": "MailboxSubscribe", + "pid": 3004, + "service": "imap", + "timestamp": "2015-02-23T18:37:02.344+01:00", + "uri": "imap://john@example.org@imap.example.org/Archive", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-3004-1424713022-1-7149274646509524617" +} diff --git a/docsrc/_static/event_notifications/MailboxUnSubscribe.json b/docsrc/_static/event_notifications/MailboxUnSubscribe.json new file mode 100644 index 00000000..31fc9a57 --- /dev/null +++ b/docsrc/_static/event_notifications/MailboxUnSubscribe.json @@ -0,0 +1,9 @@ +{ + "event": "MailboxUnSubscribe", + "pid": 3003, + "service": "imap", + "timestamp": "2015-02-23T18:37:19.482+01:00", + "uri": "imap://john@example.org@imap.example.org/Testfolder_renamed", + "user": "john@example.org", + "vnd.cmu.sessionId": "imap.example.org-3003-1424713039-1-2806700531460584176" +} diff --git a/docsrc/_static/event_notifications/MessageAppend.json b/docsrc/_static/event_notifications/MessageAppend.json new file mode 100644 index 00000000..e6e01511 --- /dev/null +++ b/docsrc/_static/event_notifications/MessageAppend.json @@ -0,0 +1,19 @@ +{ + "bodyStructure": "((\"TEXT\" \"PLAIN\" (\"CHARSET\" \"ISO-8859-1\") NIL NIL \"QUOTED-PRINTABLE\" 206 4 NIL NIL NIL NIL)(\"APPLICATION\" \"CALENDAR+XML\" (\"CHARSET\" \"UTF-8\" \"NAME\" \"kolab.xml\") NIL NIL \"8BIT\" 2030 NIL (\"ATTACHMENT\" (\"FILENAME\" \"kolab.xml\" \"SIZE\" \"2030\")) NIL NIL) \"MIXED\" (\"BOUNDARY\" \"=_d9aa3c2dd73a9166113254d4ebe07bc8\") NIL NIL NIL)", + "event": "MessageAppend", + "messageSize": 2992, + "messages": 3, + "modseq": 12, + "pid": 7721, + "service": "imap", + "timestamp": "2015-02-23T14:51:29.008+01:00", + "uidnext": 6, + "uri": "imap://john@example.org@imap.example.org/Calendar;UIDVALIDITY=1424683684/;UID=5", + "user": "john@example.org", + "vnd.cmu.envelope": "(\"Mon, 23 Feb 2015 13:51:28 +0000\" \"BBA47B13E4839F49AB1C8047EE7B4FDB-A4BF5BBB9FEAA271\" ((NIL NIL \"john\" \"example.org\")) ((NIL NIL \"john\" \"example.org\")) ((NIL NIL \"john\" \"example.org\")) ((NIL NIL \"john\" \"example.org\")) NIL NIL NIL NIL)", + "vnd.cmu.midset": [ + "NIL" + ], + "vnd.cmu.sessionId": "imap.example.org-7721-1424699488-1-10167054345787041319", + "vnd.cmu.unseenMessages": 3 +} diff --git a/docsrc/_static/event_notifications/MessageCopy.json b/docsrc/_static/event_notifications/MessageCopy.json new file mode 100644 index 00000000..7bf3e539 --- /dev/null +++ b/docsrc/_static/event_notifications/MessageCopy.json @@ -0,0 +1,19 @@ +{ + "event": "vnd.cmu.MessageCopy", + "messages": 1, + "modseq": 9, + "oldMailboxID": "imap://john@example.org@imap.example.org/Sent;UIDVALIDITY=1424683683", + "pid": 8107, + "service": "imap", + "timestamp": "2015-02-23T14:59:49.717+01:00", + "uidnext": 5, + "uidset": "4", + "uri": "imap://john@example.org@imap.example.org/Archive;UIDVALIDITY=1424683684", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.oldUidset": "2", + "vnd.cmu.sessionId": "imap.example.org-8107-1424699989-1-8439907626481649843", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/MessageExpunge.json b/docsrc/_static/event_notifications/MessageExpunge.json new file mode 100644 index 00000000..bf189e06 --- /dev/null +++ b/docsrc/_static/event_notifications/MessageExpunge.json @@ -0,0 +1,17 @@ +{ + "event": "MessageExpunge", + "messages": 0, + "modseq": 53, + "pid": 7813, + "service": "imap", + "timestamp": "2015-02-23T14:55:20.562+01:00", + "uidnext": 5, + "uidset": "4", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.sessionId": "imap.example.org-7813-1424699720-1-13590468293654033744", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/MessageMove.json b/docsrc/_static/event_notifications/MessageMove.json new file mode 100644 index 00000000..9961afcc --- /dev/null +++ b/docsrc/_static/event_notifications/MessageMove.json @@ -0,0 +1,19 @@ +{ + "event": "vnd.cmu.MessageMove", + "messages": 2, + "modseq": 5, + "oldMailboxID": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "pid": 7685, + "service": "imap", + "timestamp": "2015-02-23T14:52:41.676+01:00", + "uidnext": 4, + "uidset": "3", + "uri": "imap://john@example.org@imap.example.org/Archive;UIDVALIDITY=1424683684", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.oldUidset": "3", + "vnd.cmu.sessionId": "imap.example.org-7685-1424699561-1-7444588115769591371", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/MessageNew.json b/docsrc/_static/event_notifications/MessageNew.json new file mode 100644 index 00000000..4d4d400b --- /dev/null +++ b/docsrc/_static/event_notifications/MessageNew.json @@ -0,0 +1,46 @@ +{ + "event": "MessageNew", + "messageContent": { + "6": "Return-Path: \r\nReceived: from imap.example.org ([unix socket])\r\n\t by imap.example.org (Cyrus git2.5+0-Kolab-2.5-67.el6.kolab_3.4) with LMTPA;\r\n\t Mon, 20 Oct 2014 13:34:14 +0200\r\nX-Sieve: CMU Sieve 2.4\r\nX-Virus-Scanned: amavisd-new at example.org\r\nX-Spam-Flag: NO\r\nX-Spam-Score: -0.002\r\nX-Spam-Level: \r\nX-Spam-Status: No, score=-0.002 tagged_above=-10 required=6.2\r\n\ttests=[NO_RECEIVED=-0.001, NO_RELAYS=-0.001] autolearn=ham\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=US-ASCII;\r\n format=flowed\r\nContent-Transfer-Encoding: 7bit\r\nDate: Mon, 20 Oct 2014 13:32:41 +0200\r\nFrom: =?UTF-8?Q?Br=C3=BCederli=2C_Thomas?= \r\nTo: \"Doe, John\" \r\nSubject: MessageNew event test\r\nMessage-ID: \r\nX-Sender: john@example.org\r\n\r\nThis message should trigger the MessageNew event for john...\r\n...and MessageAppend to /Sent for the sender.\r\n" + }, + "messageHeaders": { + "6": { + "Content-Transfer-Encoding": "7bit", + "Content-Type": "text/plain", + "Date": "2014-10-20T11:32:41Z", + "From": [ + "Br\u00fcederli, Thomas " + ], + "MIME-Version": "1.0", + "Message-ID": "", + "Received": "from imap.example.org ([unix socket])\r\n\t by imap.example.org (Cyrus git2.5+0-Kolab-2.5-67.el6.kolab_3.4) with LMTPA;\r\n\t Mon, 20 Oct 2014 13:34:14 +0200", + "Return-Path": "", + "Subject": "MessageNew event test", + "To": [ + "Doe, John " + ], + "X-Sender": "john@example.org", + "X-Sieve": "CMU Sieve 2.4", + "X-Spam-Flag": "NO", + "X-Spam-Level": "", + "X-Spam-Score": "-0.002", + "X-Spam-Status": "No, score=-0.002 tagged_above=-10 required=6.2\r\n\ttests=[NO_RECEIVED=-0.001, NO_RELAYS=-0.001] autolearn=ham", + "X-Virus-Scanned": "amavisd-new at example.org" + } + }, + "messageSize": 976, + "messages": 6, + "modseq": 20, + "pid": 2340, + "service": "lmtpunix", + "timestamp": "2014-10-20T13:34:14.966+02:00", + "uidnext": 7, + "uidset": "6", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1411487714/;UID=6", + "user": "john@example.org", + "vnd.cmu.midset": [ + "" + ], + "vnd.cmu.sessionId": "imap.example.org-2340-1413804854-1", + "vnd.cmu.unseenMessages": 3 +} diff --git a/docsrc/_static/event_notifications/MessageRead.json b/docsrc/_static/event_notifications/MessageRead.json new file mode 100644 index 00000000..b6139a78 --- /dev/null +++ b/docsrc/_static/event_notifications/MessageRead.json @@ -0,0 +1,17 @@ +{ + "event": "MessageRead", + "messages": 1, + "modseq": 47, + "pid": 7685, + "service": "imap", + "timestamp": "2015-02-23T14:53:44.476+01:00", + "uidnext": 5, + "uidset": "4", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.sessionId": "imap.example.org-7685-1424699624-1-9701853636551497828", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/MessageTrash.json b/docsrc/_static/event_notifications/MessageTrash.json new file mode 100644 index 00000000..1dc14928 --- /dev/null +++ b/docsrc/_static/event_notifications/MessageTrash.json @@ -0,0 +1,17 @@ +{ + "event": "MessageTrash", + "messages": 1, + "modseq": 48, + "pid": 7809, + "service": "imap", + "timestamp": "2015-02-23T14:54:02.616+01:00", + "uidnext": 5, + "uidset": "4", + "uri": "imap://john@example.org@imap.example.org/INBOX;UIDVALIDITY=1424683682", + "user": "john@example.org", + "vnd.cmu.midset": [ + "<4d9618acd0aea6b33683766358351459@example.org>" + ], + "vnd.cmu.sessionId": "imap.example.org-7809-1424699642-1-2896189896878960640", + "vnd.cmu.unseenMessages": 0 +} diff --git a/docsrc/_static/event_notifications/QuotaChange.json b/docsrc/_static/event_notifications/QuotaChange.json new file mode 100644 index 00000000..d000b58a --- /dev/null +++ b/docsrc/_static/event_notifications/QuotaChange.json @@ -0,0 +1,13 @@ +{ + "diskQuota": 123456789, + "diskUsed": 2, + "event": "QuotaChange", + "maxMessages": -1, + "messages": 3, + "pid": 8140, + "service": "imaps", + "timestamp": "2015-03-10T16:16:19.255+01:00", + "uri": "imap://john.doe@example.org@kolab.example.org/INBOX", + "user": "john.doe@example.org", + "vnd.cmu.sessionId": "kolab.example.org-8140-1426000578-1-14068443041501787710" +} diff --git a/docsrc/_static/event_notifications/QuotaExceed.json b/docsrc/_static/event_notifications/QuotaExceed.json new file mode 100644 index 00000000..654023ea --- /dev/null +++ b/docsrc/_static/event_notifications/QuotaExceed.json @@ -0,0 +1,13 @@ +{ + "diskQuota": 2, + "diskUsed": 2, + "event": "QuotaExceed", + "maxMessages": -1, + "messages": 3, + "pid": 8210, + "service": "lmtpunix", + "timestamp": "2015-03-10T16:13:40.218+01:00", + "uri": "imap://john.doe@example.org@kolab.example.org/INBOX", + "user": "john.doe@example.org", + "vnd.cmu.sessionId": "kolab.example.org-8210-1426000420-4-9494635035963533515" +} diff --git a/docsrc/_static/event_notifications/QuotaWithin.json b/docsrc/_static/event_notifications/QuotaWithin.json new file mode 100644 index 00000000..de643273 --- /dev/null +++ b/docsrc/_static/event_notifications/QuotaWithin.json @@ -0,0 +1,13 @@ +{ + "diskQuota": 123456789, + "diskUsed": 2, + "event": "QuotaWithin", + "maxMessages": -1, + "messages": 3, + "pid": 8140, + "service": "imaps", + "timestamp": "2015-03-10T16:16:19.255+01:00", + "uri": "imap://john.doe@example.org@kolab.example.org/INBOX", + "user": "john.doe@example.org", + "vnd.cmu.sessionId": "kolab.example.org-8140-1426000578-1-14068443041501787710" +} diff --git a/docsrc/_static/favicon.ico b/docsrc/_static/favicon.ico new file mode 100644 index 00000000..d1fb35c8 Binary files /dev/null and b/docsrc/_static/favicon.ico differ diff --git a/docsrc/_static/headimg.gif b/docsrc/_static/headimg.gif new file mode 100644 index 00000000..deba4847 Binary files /dev/null and b/docsrc/_static/headimg.gif differ diff --git a/docsrc/_static/logo.gif b/docsrc/_static/logo.gif new file mode 100644 index 00000000..25c0534d Binary files /dev/null and b/docsrc/_static/logo.gif differ diff --git a/docsrc/_templates/layout.html b/docsrc/_templates/layout.html new file mode 100644 index 00000000..afd5929d --- /dev/null +++ b/docsrc/_templates/layout.html @@ -0,0 +1,26 @@ +{% extends "!layout.html" %} +{% set css_files = css_files + [ '_static/cyrus.css' ] %} + + +{% block header %} + +
+{% endblock %} + + +{% block footer %} +{{ super() }} + +{% endblock %} diff --git a/docsrc/conf.py b/docsrc/conf.py new file mode 100644 index 00000000..90d3a89f --- /dev/null +++ b/docsrc/conf.py @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +# +# Cyrus SASL documentation build configuration file, created by +# sphinx-quickstart on Fri Jun 6 19:23:19 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('exts')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = '1.2' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.coverage', + 'sphinx.ext.extlinks', + 'sphinx.ext.graphviz', + 'sphinx.ext.ifconfig', + 'sphinx.ext.mathjax', + 'sphinx.ext.todo', + 'sphinx.ext.intersphinx', +] + +extensions.append('sphinxlocal.builders.manpage') + +intersphinx_mapping = {'cyrusimap': ('http://www.cyrusimap.org/dev', None)} + +mathjax_path = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js' + +todo_include_todos = False + +locale_dirs = [ 'locale/' ] +gettext_compact = False + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Cyrus SASL' +copyright = u'1993-2016, The Cyrus Team' + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# This is used in breadcrumbs.html to flag the version of the docs the user +# is on. It is NOT the latest version: it is the version of the branch this +# file is in. +# +# Needs to be kept in sync with the rst_prolog imap_*_version replacements +# below as branches increment version numbers. +# May need to also update toplevel index.rst to point to other versions. +# +# The short X.Y version. +version = '2.1.27' +# The full version, including alpha/beta/rc tags. +release = '2.1.27' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +show_authors = True + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. + +html_theme = 'cyrus' + +# This gets used to generate the 'Edit in Github' link in the breadcrumbs header +# Used to form the url https://github.com/github_user/github_repo/blob/github_version/conf_py_path/.source_suffix +# +html_context = { + "display_github": True, # Add 'Edit on Github' link instead of 'View page source' + "github_user": "cyrusimap", + "github_repo": "cyrus-sasl", + "github_version": "master", + "conf_py_path": "/docsrc/", + "source_suffix": source_suffix, +} + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ["exts/themes"] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = "themes/images/logo.gif" + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = "_static/favicon.ico" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +html_sidebars = {'**' : ['localtoc.html', 'searchbox.html']} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Cyrusdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'Cyrus.tex', u'Cyrus Documentation', + u'The Cyrus Team', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'SASL', u'Cyrus SASL Documentation', + u'The Cyrus Team', 'Cyrus', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'Cyrus' +epub_author = u'The Cyrus Team' +epub_publisher = u'The Cyrus Team' +epub_copyright = u'2016, The Cyrus Team' + +# The basename for the epub file. It defaults to the project name. +epub_basename = u'Cyrus' + +# The HTML theme for the epub output. Since the default themes are not optimized +# for small screen space, using the same theme for HTML and epub output is +# usually not wise. This defaults to 'epub', a theme designed to save visual +# space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the PIL. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True + + +# When this is updated, you may also need to update the version and release +# definitions listed above to stay up to date. +rst_prolog = """ +.. |imap_last_stable_version| replace:: 2.4.18 +.. |imap_last_stable_branch| replace:: `cyrus-imapd-2.4` +.. |imap_last_stable_next_version| replace:: 2.4.18 + patches +.. |imap_current_stable_version| replace:: 2.5.10 +.. |imap_current_stable_next_version| replace:: 2.5.10 + patches +.. |imap_current_stable_branch| replace:: `cyrus-imapd-2.5` +.. |imap_latest_development_version| replace:: 3.0.0-beta3 +.. |imap_latest_development_branch| replace:: master +.. |sasl_current_stable_version| replace:: 2.1.26 +.. |imap_stable_release_notes| raw:: html + + 2.5.10 + +.. |imap_development_release_notes| raw:: html + + 3.0.0-beta3 + +""" + +rst_prolog += """ +.. |git_cyrus_imapd_url| replace:: https://github.com/cyrusimap/cyrus-imapd.git +""" + +rst_prolog += """ +.. |AMS| replace:: :abbr:`AMS (Andrew Mail System)` +.. |CMU| replace:: :abbr:`CMU (Carnegie Mellon University)` +""" + +# Use this as :task:`18` +extlinks = { + 'task':('https://git.cyrus.foundation/T%s', 'Task #'), + 'issue':('https://github.com/cyrusimap/cyrus-imapd/issues/%s', 'Issue #'), + 'cyrus-stable':('http://www.cyrusimap.org/stable%s',None), + 'cyrus-dev':('http://www.cyrusimap.org/dev%s',None), + } diff --git a/docsrc/contribute.rst b/docsrc/contribute.rst new file mode 100644 index 00000000..f925de56 --- /dev/null +++ b/docsrc/contribute.rst @@ -0,0 +1,33 @@ +.. _contribute: + +=================== +Contributor Guide +=================== + +We want your help. No really, we do. In fact, it's bigger than that: we **need** your help. + +You might think that you're not ready; that you need to be an expert in mail systems, or learn another library, or have been involved with the mailing lists or be a professional tester or someone who writes perfectly designed code first time every time. You might think that your idea isn't useful, that nobody else experiences the bug you've noticed, that maybe it's just you that doesn't understand the documentation. + +We'd like to assure you that's not the case. + +All contributions are welcome, no matter how small. + +Cyrus has a :ref:`Contributor Guide ` that you can read. The contribution guidelines outline the process that you'll need to follow to get a code patch merged. By making expectations and process explicit, we hope to make it easier for you to contribute. + +And you don't just have to write code. You can help out by writing documentation, writing tests, lodging bug reports, or even by giving feedback about this work. (And yes, that includes giving feedback about the contribution guidelines.) + +Website Content Contributions +============================= + +Keeping documentation current alongside the code is a task in and of itself. :ref:`Join us! `. + + +Contribute Code +=============== + +The Cyrus Team always welcomes patches sent to the appropriate :ref:`Cyrus Mailing Lists `. + +IRC +=== + +Find us on **#cyrus** at **irc.freenode.net**. More information on clients at :ref:`Cyrus IMAPd IRC `. diff --git a/docsrc/download.rst b/docsrc/download.rst new file mode 100644 index 00000000..fa33c8be --- /dev/null +++ b/docsrc/download.rst @@ -0,0 +1,8 @@ +======== +Download +======== + + +.. toctree:: + + sasl/installation diff --git a/docsrc/exts/sphinxlocal/__init__.py b/docsrc/exts/sphinxlocal/__init__.py new file mode 100644 index 00000000..6d36d4bc --- /dev/null +++ b/docsrc/exts/sphinxlocal/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal + ~~~~~~~~~~~ + + Custom docutils components. + + :copyright: Copywrite 2015 by Nic Bernstein + :license: BSD, see LICENSE for details. +""" diff --git a/docsrc/exts/sphinxlocal/builders/__init__.py b/docsrc/exts/sphinxlocal/builders/__init__.py new file mode 100644 index 00000000..7297ea18 --- /dev/null +++ b/docsrc/exts/sphinxlocal/builders/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal.builders + ~~~~~~~~~~~~~~~ + + Custom docutils builders. + + :copyright: Copywrite 2015 by Nic Bernstein + :license: BSD, see LICENSE for details. +""" diff --git a/docsrc/exts/sphinxlocal/builders/manpage.py b/docsrc/exts/sphinxlocal/builders/manpage.py new file mode 100644 index 00000000..a6281f79 --- /dev/null +++ b/docsrc/exts/sphinxlocal/builders/manpage.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal.builders.manpage + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + A replacement for the manpage builder which come bundled with Sphinx. + + :version: 0.1 + :author: Nic Bernstein + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from os import path + +from six import string_types +from docutils.io import FileOutput +from docutils.frontend import OptionParser + +from sphinx import addnodes +from sphinx.errors import SphinxError +from sphinx.builders import Builder +from sphinx.environment import NoUri +from sphinx.util.nodes import inline_all_toctrees +from sphinx.util.console import bold, darkgreen +from sphinx.writers.manpage import ManualPageWriter +from sphinx.builders.manpage import ManualPageBuilder + +## +# Import our customized version of the stock Writer, which has the +# Translater in it. +from sphinxlocal.writers.manpage import CyrusManualPageWriter + +class CyrusManualPageBuilder(ManualPageBuilder): + """ + Builds groff output in manual page format. + """ + name = 'cyrman' + format = 'man' + supported_image_types = [] + + #settings_spec = (u'No options defined.', u'', ()) + #settings_defaults = {} + + def init(self): + if not self.config.man_pages: + self.warn('no "man_pages" config value found; no manual pages ' + 'will be written') + + def write(self, *ignored): + # overwritten -- use our own version of the Writer + docwriter = CyrusManualPageWriter(self) + docsettings = OptionParser( + defaults=self.env.settings, + components=(docwriter,), + read_config_files=True).get_default_values() + + self.info(bold('writing... '), nonl=True) + + for info in self.config.man_pages: + docname, name, description, authors, section = info + if isinstance(authors, string_types): + if authors: + authors = [authors] + else: + authors = [] + + targetname = '%s.%s' % (name, section) + self.info(darkgreen(targetname) + ' { ', nonl=True) + destination = FileOutput( + destination_path=path.join(self.outdir, targetname), + encoding='utf-8') + + tree = self.env.get_doctree(docname) + docnames = set() + largetree = inline_all_toctrees(self, docnames, docname, tree, + darkgreen, [docname]) + self.info('} ', nonl=True) + self.env.resolve_references(largetree, docname, self) + # remove pending_xref nodes + for pendingnode in largetree.traverse(addnodes.pending_xref): + pendingnode.replace_self(pendingnode.children) + + largetree.settings = docsettings + largetree.settings.title = name + largetree.settings.subtitle = description + largetree.settings.authors = authors + largetree.settings.section = section + + docwriter.write(largetree, destination) + self.info() + +def setup(app): + app.add_builder(CyrusManualPageBuilder) + + return {'version': '0.1'} diff --git a/docsrc/exts/sphinxlocal/roles/__init__.py b/docsrc/exts/sphinxlocal/roles/__init__.py new file mode 100644 index 00000000..6d36d4bc --- /dev/null +++ b/docsrc/exts/sphinxlocal/roles/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal + ~~~~~~~~~~~ + + Custom docutils components. + + :copyright: Copywrite 2015 by Nic Bernstein + :license: BSD, see LICENSE for details. +""" diff --git a/docsrc/exts/sphinxlocal/writers/__init__.py b/docsrc/exts/sphinxlocal/writers/__init__.py new file mode 100644 index 00000000..6de61d24 --- /dev/null +++ b/docsrc/exts/sphinxlocal/writers/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal.writers + ~~~~~~~~~~~~~~ + + Custom docutils writers. + + :copyright: Copyright 2015 by Nic Bernstein + :license: BSD, see LICENSE for details. +""" diff --git a/docsrc/exts/sphinxlocal/writers/manpage.py b/docsrc/exts/sphinxlocal/writers/manpage.py new file mode 100644 index 00000000..463524a4 --- /dev/null +++ b/docsrc/exts/sphinxlocal/writers/manpage.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +""" + sphinxlocal.writers.manpage + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + A replacement for the manpage builder which come bundled with Sphinx. + + :version: 0.1 + :author: Nic Bernstein + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import nodes +from sphinx.writers.manpage import ( + MACRO_DEF, + ManualPageWriter, + ManualPageTranslator as BaseTranslator +) + + +from sphinx import addnodes +from sphinx.locale import admonitionlabels, _ +from sphinx.util.osutil import ustrftime +from sphinx.util.compat import docutils_version + +class CyrusManualPageWriter(ManualPageWriter): + + #settings_spec = (u'No options defined.', u'', ()) + #settings_defaults = {} + + def __init__(self, builder): + ManualPageWriter.__init__(self, builder) + self.builder = builder + + def translate(self): + visitor = CyrusManualPageTranslator(self.builder, self.document) + self.visitor = visitor + self.document.walkabout(visitor) + self.output = visitor.astext() + + +class CyrusManualPageTranslator(BaseTranslator): + """ + Custom translator. + """ + + def __init__(self, builder, *args, **kwds): + BaseTranslator.__init__(self, builder, *args, **kwds) + self.builder = builder + + self.in_productionlist = 0 + + # first title is the manpage title + self.section_level = -1 + + # docinfo set by man_pages config value + self._docinfo['title'] = self.document.settings.title + self._docinfo['subtitle'] = self.document.settings.subtitle + if self.document.settings.authors: + # don't set it if no author given + self._docinfo['author'] = self.document.settings.authors + self._docinfo['manual_section'] = self.document.settings.section + + # docinfo set by other config values + self._docinfo['title_upper'] = self._docinfo['title'].upper() + if builder.config.today: + self._docinfo['date'] = builder.config.today + else: + self._docinfo['date'] = ustrftime(builder.config.today_fmt + or _('%B %d, %Y')) + self._docinfo['copyright'] = builder.config.copyright + self._docinfo['version'] = builder.config.version + self._docinfo['manual_group'] = builder.config.project + + # since self.append_header() is never called, need to do this here + self.body.append(MACRO_DEF) + + # overwritten -- don't wrap literal_block with font calls + self.defs['literal_block'] = ('.sp\n.nf\n', '\n.fi\n') + + + # overwritten -- don't assume indentation + def visit_literal_block(self, node): + self.body.append(self.defs['literal_block'][0]) + self._in_literal = True + + + def depart_literal_block(self, node): + self._in_literal = False + self.body.append(self.defs['literal_block'][1]) diff --git a/docsrc/exts/themes/cyrus/__init__.py b/docsrc/exts/themes/cyrus/__init__.py new file mode 100644 index 00000000..95ddc52a --- /dev/null +++ b/docsrc/exts/themes/cyrus/__init__.py @@ -0,0 +1,17 @@ +"""Sphinx ReadTheDocs theme. + +From https://github.com/ryan-roemer/sphinx-bootstrap-theme. + +""" +import os + +VERSION = (0, 1, 8) + +__version__ = ".".join(str(v) for v in VERSION) +__version_full__ = __version__ + + +def get_html_theme_path(): + """Return list of HTML theme paths.""" + cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + return cur_dir diff --git a/docsrc/exts/themes/cyrus/breadcrumbs.html b/docsrc/exts/themes/cyrus/breadcrumbs.html new file mode 100644 index 00000000..b0a43ef8 --- /dev/null +++ b/docsrc/exts/themes/cyrus/breadcrumbs.html @@ -0,0 +1,23 @@ +
+ +
+
diff --git a/docsrc/exts/themes/cyrus/footer.html b/docsrc/exts/themes/cyrus/footer.html new file mode 100644 index 00000000..8bd79145 --- /dev/null +++ b/docsrc/exts/themes/cyrus/footer.html @@ -0,0 +1,36 @@ +
+ {% if next or prev %} + + {% endif %} + +
+ +
+

+ {%- if show_copyright %} + {%- if hasdoc('copyright') %} + {% trans path=pathto('copyright'), copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %} + {%- else %} + {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %} + {%- endif %} + {%- endif %} + + {%- if last_updated %} + {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} + {%- endif %} +

+
+ + {%- if show_sphinx %} + {% trans sphinx_version=sphinx_version|e %}Built with Sphinx {{ sphinx_version }} using a modified Read the Docs theme{% endtrans %}. + {%- endif %} + +
+ diff --git a/docsrc/exts/themes/cyrus/layout.html b/docsrc/exts/themes/cyrus/layout.html new file mode 100644 index 00000000..6181a42f --- /dev/null +++ b/docsrc/exts/themes/cyrus/layout.html @@ -0,0 +1,188 @@ +{# TEMPLATE VAR SETTINGS #} +{%- set url_root = pathto('', 1) %} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + + + + + + + {{ metatags }} + + {% block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {% endblock %} + + {# FAVICON #} + {% if favicon %} + + {% endif %} + + {# CSS #} + + {# OPENSEARCH #} + {% if not embedded %} + {% if use_opensearch %} + + {% endif %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {% for cssfile in css_files %} + + {% endfor %} + + {% for cssfile in extra_css_files %} + + {% endfor %} + + {%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} + {%- endblock %} + {%- block extrahead %} {% endblock %} + + {# Keep modernizr in head - http://modernizr.com/docs/#installing #} + {# I don't think this theme even uses modernizr, commenting out. NNye #} + {# #} + + + + + + + {% block header %} + {% endblock %} + +
+ + {# SIDE NAV, TOGGLES ON MOBILE #} + + +
+ + {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #} + + + + {# PAGE CONTENT #} +
+
+ + {% include "breadcrumbs.html" %} +
+ {% block body %}{% endblock %} +
+ {% include "footer.html" %} +
+
+ +
+ +
+ {% include "versions.html" %} + + {% if not embedded %} + + + {%- for scriptfile in script_files %} + + {%- endfor %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {# STICKY NAVIGATION #} + {% if theme_sticky_navigation %} + + {% endif %} + + {%- block footer %} {% endblock %} + + + diff --git a/docsrc/exts/themes/cyrus/layout_old.html b/docsrc/exts/themes/cyrus/layout_old.html new file mode 100644 index 00000000..deb8df2a --- /dev/null +++ b/docsrc/exts/themes/cyrus/layout_old.html @@ -0,0 +1,205 @@ +{# + basic/layout.html + ~~~~~~~~~~~~~~~~~ + + Master layout template for Sphinx themes. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- block doctype -%} + +{%- endblock %} +{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} +{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} +{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and + (sidebars != []) %} +{%- set url_root = pathto('', 1) %} +{# XXX necessary? #} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + +{%- macro relbar() %} + +{%- endmacro %} + +{%- macro sidebar() %} + {%- if render_sidebar %} +
+
+ {%- block sidebarlogo %} + {%- if logo %} + + {%- endif %} + {%- endblock %} + {%- if sidebars != None %} + {#- new style sidebar: explicitly include/exclude templates #} + {%- for sidebartemplate in sidebars %} + {%- include sidebartemplate %} + {%- endfor %} + {%- else %} + {#- old style sidebars: using blocks -- should be deprecated #} + {%- block sidebartoc %} + {%- include "localtoc.html" %} + {%- endblock %} + {%- block sidebarrel %} + {%- include "relations.html" %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- include "sourcelink.html" %} + {%- endblock %} + {%- if customsidebar %} + {%- include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- include "searchbox.html" %} + {%- endblock %} + {%- endif %} +
+
+ {%- endif %} +{%- endmacro %} + +{%- macro script() %} + + {%- for scriptfile in script_files %} + + {%- endfor %} +{%- endmacro %} + +{%- macro css() %} + + + {%- for cssfile in css_files %} + + {%- endfor %} +{%- endmacro %} + + + + + {{ metatags }} + {%- block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {%- endblock %} + {{ css() }} + {%- if not embedded %} + {{ script() }} + {%- if use_opensearch %} + + {%- endif %} + {%- if favicon %} + + {%- endif %} + {%- endif %} +{%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} +{%- endblock %} +{%- block extrahead %} {% endblock %} + + +{%- block header %}{% endblock %} + +{%- block relbar1 %}{{ relbar() }}{% endblock %} + +{%- block content %} + {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %} + +
+ {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {% block body %} {% endblock %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} + + {%- block sidebar2 %}{{ sidebar() }}{% endblock %} +
+
+{%- endblock %} + +{%- block relbar2 %}{{ relbar() }}{% endblock %} + +{%- block footer %} + +

asdf asdf asdf asdf 22

+{%- endblock %} + + + diff --git a/docsrc/exts/themes/cyrus/search.html b/docsrc/exts/themes/cyrus/search.html new file mode 100644 index 00000000..e3aa9b5c --- /dev/null +++ b/docsrc/exts/themes/cyrus/search.html @@ -0,0 +1,50 @@ +{# + basic/search.html + ~~~~~~~~~~~~~~~~~ + + Template for the search page. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- extends "layout.html" %} +{% set title = _('Search') %} +{% set script_files = script_files + ['_static/searchtools.js'] %} +{% block footer %} + + {# this is used when loading the search index using $.ajax fails, + such as on Chrome for documents on localhost #} + + {{ super() }} +{% endblock %} +{% block body %} + + + {% if search_performed %} +

{{ _('Search Results') }}

+ {% if not search_results %} +

{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}

+ {% endif %} + {% endif %} +
+ {% if search_results %} +
    + {% for href, caption, context in search_results %} +
  • + {{ caption }} +

    {{ context|e }}

    +
  • + {% endfor %} +
+ {% endif %} +
+{% endblock %} diff --git a/docsrc/exts/themes/cyrus/searchbox.html b/docsrc/exts/themes/cyrus/searchbox.html new file mode 100644 index 00000000..35ad52c5 --- /dev/null +++ b/docsrc/exts/themes/cyrus/searchbox.html @@ -0,0 +1,9 @@ +{%- if builder != 'singlehtml' %} +
+
+ + + +
+
+{%- endif %} diff --git a/docsrc/exts/themes/cyrus/static/css/badge_only.css b/docsrc/exts/themes/cyrus/static/css/badge_only.css new file mode 100644 index 00000000..7e17fb14 --- /dev/null +++ b/docsrc/exts/themes/cyrus/static/css/badge_only.css @@ -0,0 +1,2 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} +/*# sourceMappingURL=badge_only.css.map */ diff --git a/docsrc/exts/themes/cyrus/static/css/theme.css b/docsrc/exts/themes/cyrus/static/css/theme.css new file mode 100644 index 00000000..57b98fe6 --- /dev/null +++ b/docsrc/exts/themes/cyrus/static/css/theme.css @@ -0,0 +1,5 @@ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content p.caption,h3{orphans:3;widows:3}h2,.rst-content p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:0.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:scroll;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt,.rst-content tt .xref,.rst-content code .xref,a .rst-content tt,a .rst-content code{font-weight:bold}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),url(../fonts/Inconsolata.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} +/*# sourceMappingURL=theme.css.map */ diff --git a/docsrc/exts/themes/cyrus/static/fonts/Inconsolata-Bold.ttf b/docsrc/exts/themes/cyrus/static/fonts/Inconsolata-Bold.ttf new file mode 100644 index 00000000..360a232d Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/Inconsolata-Bold.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/Inconsolata.ttf b/docsrc/exts/themes/cyrus/static/fonts/Inconsolata.ttf new file mode 100644 index 00000000..4b8a36d2 Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/Inconsolata.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/Lato-Bold.ttf b/docsrc/exts/themes/cyrus/static/fonts/Lato-Bold.ttf new file mode 100644 index 00000000..e8b9bf6a Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/Lato-Bold.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/Lato-Regular.ttf b/docsrc/exts/themes/cyrus/static/fonts/Lato-Regular.ttf new file mode 100644 index 00000000..7608bc3e Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/Lato-Regular.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Bold.ttf b/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Bold.ttf new file mode 100644 index 00000000..e6ed0de5 Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Bold.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Regular.ttf b/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Regular.ttf new file mode 100644 index 00000000..141d6c08 Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/RobotoSlab-Regular.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.eot b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..7c79c6a6 Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.eot differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.svg b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..45fdf338 --- /dev/null +++ b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.ttf b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..e89738de Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.ttf differ diff --git a/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.woff b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..8c1748aa Binary files /dev/null and b/docsrc/exts/themes/cyrus/static/fonts/fontawesome-webfont.woff differ diff --git a/docsrc/exts/themes/cyrus/static/js/modernizr.min.js b/docsrc/exts/themes/cyrus/static/js/modernizr.min.js new file mode 100644 index 00000000..f65d4797 --- /dev/null +++ b/docsrc/exts/themes/cyrus/static/js/modernizr.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f ul li.current').removeClass('current'); + parent_li.toggleClass('current'); +} + +$(document).ready(function() { + // Shift nav in mobile when clicking the menu. + $(document).on('click', "[data-toggle='wy-nav-top']", function() { + $("[data-toggle='wy-nav-shift']").toggleClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + // Nav menu link click operations + $(document).on('click', ".wy-menu-vertical .current ul li a", function() { + var target = $(this); + // Close menu when you click a link. + $("[data-toggle='wy-nav-shift']").removeClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + // Handle dynamic display of l3 and l4 nav lists + toggleCurrent(target); + if (typeof(window.SphinxRtdTheme) != 'undefined') { + window.SphinxRtdTheme.StickyNav.hashChange(); + } + }); + $(document).on('click', "[data-toggle='rst-current-version']", function() { + $("[data-toggle='rst-versions']").toggleClass("shift-up"); + }); + // Make tables responsive + $("table.docutils:not(.field-list)").wrap("
"); + + // Add expand links to all parents of nested ul + $('.wy-menu-vertical ul').siblings('a').each(function () { + var link = $(this); + expand = $(''); + expand.on('click', function (ev) { + toggleCurrent(link); + ev.stopPropagation(); + return false; + }); + link.prepend(expand); + }); +}); + +// Sphinx theme state +window.SphinxRtdTheme = (function (jquery) { + var stickyNav = (function () { + var navBar, + win, + winScroll = false, + linkScroll = false, + winPosition = 0, + enable = function () { + init(); + reset(); + win.on('hashchange', reset); + + // Set scrolling + win.on('scroll', function () { + if (!linkScroll) { + winScroll = true; + } + }); + setInterval(function () { + if (winScroll) { + winScroll = false; + var newWinPosition = win.scrollTop(), + navPosition = navBar.scrollTop(), + newNavPosition = navPosition + (newWinPosition - winPosition); + navBar.scrollTop(newNavPosition); + winPosition = newWinPosition; + } + }, 25); + }, + init = function () { + navBar = jquery('nav.wy-nav-side:first'); + win = jquery(window); + }, + reset = function () { + // Get anchor from URL and open up nested nav + var anchor = encodeURI(window.location.hash); + if (anchor) { + try { + var link = $('.wy-menu-vertical') + .find('[href="' + anchor + '"]'); + $('.wy-menu-vertical li.toctree-l1 li.current') + .removeClass('current'); + link.closest('li.toctree-l2').addClass('current'); + link.closest('li.toctree-l3').addClass('current'); + link.closest('li.toctree-l4').addClass('current'); + } + catch (err) { + console.log("Error expanding nav for anchor", err); + } + } + }, + hashChange = function () { + linkScroll = true; + win.one('hashchange', function () { + linkScroll = false; + }); + }; + jquery(init); + return { + enable: enable, + hashChange: hashChange + }; + }()); + return { + StickyNav: stickyNav + }; +}($)); diff --git a/docsrc/exts/themes/cyrus/theme.conf b/docsrc/exts/themes/cyrus/theme.conf new file mode 100644 index 00000000..3fcc55ae --- /dev/null +++ b/docsrc/exts/themes/cyrus/theme.conf @@ -0,0 +1,9 @@ +[theme] +inherit = sphinx_rtd_theme +stylesheet = css/theme.css + +[options] +typekit_id = hiw1hhg +analytics_id = +sticky_navigation = false +logo_only = true diff --git a/docsrc/exts/themes/cyrus/versions.html b/docsrc/exts/themes/cyrus/versions.html new file mode 100644 index 00000000..8b3eb79d --- /dev/null +++ b/docsrc/exts/themes/cyrus/versions.html @@ -0,0 +1,37 @@ +{% if READTHEDOCS %} +{# Add rst-badge after rst-versions for small badge style. #} +
+ + Read the Docs + v: {{ current_version }} + + +
+
+
Versions
+ {% for slug, url in versions %} +
{{ slug }}
+ {% endfor %} +
+
+
Downloads
+ {% for type, url in downloads %} +
{{ type }}
+ {% endfor %} +
+
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+
+ Free document hosting provided by Read the Docs. + +
+
+{% endif %} + diff --git a/docsrc/exts/themes/sphinx_rtd_theme/__init__.py b/docsrc/exts/themes/sphinx_rtd_theme/__init__.py new file mode 100644 index 00000000..95ddc52a --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/__init__.py @@ -0,0 +1,17 @@ +"""Sphinx ReadTheDocs theme. + +From https://github.com/ryan-roemer/sphinx-bootstrap-theme. + +""" +import os + +VERSION = (0, 1, 8) + +__version__ = ".".join(str(v) for v in VERSION) +__version_full__ = __version__ + + +def get_html_theme_path(): + """Return list of HTML theme paths.""" + cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + return cur_dir diff --git a/docsrc/exts/themes/sphinx_rtd_theme/breadcrumbs.html b/docsrc/exts/themes/sphinx_rtd_theme/breadcrumbs.html new file mode 100644 index 00000000..0028421e --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/breadcrumbs.html @@ -0,0 +1,23 @@ +
+ +
+
diff --git a/docsrc/exts/themes/sphinx_rtd_theme/footer.html b/docsrc/exts/themes/sphinx_rtd_theme/footer.html new file mode 100644 index 00000000..6347a440 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/footer.html @@ -0,0 +1,36 @@ +
+ {% if next or prev %} + + {% endif %} + +
+ +
+

+ {%- if show_copyright %} + {%- if hasdoc('copyright') %} + {% trans path=pathto('copyright'), copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %} + {%- else %} + {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %} + {%- endif %} + {%- endif %} + + {%- if last_updated %} + {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} + {%- endif %} +

+
+ + {%- if show_sphinx %} + {% trans %}Built with Sphinx using a theme provided by Read the Docs{% endtrans %}. + {%- endif %} + +
+ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/layout.html b/docsrc/exts/themes/sphinx_rtd_theme/layout.html new file mode 100644 index 00000000..9481d8b4 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/layout.html @@ -0,0 +1,181 @@ +{# TEMPLATE VAR SETTINGS #} +{%- set url_root = pathto('', 1) %} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + + + + + + + {{ metatags }} + + {% block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {% endblock %} + + {# FAVICON #} + {% if favicon %} + + {% endif %} + + {# CSS #} + + {# OPENSEARCH #} + {% if not embedded %} + {% if use_opensearch %} + + {% endif %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {% for cssfile in css_files %} + + {% endfor %} + + {% for cssfile in extra_css_files %} + + {% endfor %} + + {%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} + {%- endblock %} + {%- block extrahead %} {% endblock %} + + {# Keep modernizr in head - http://modernizr.com/docs/#installing #} + + + + + + +
+ + {# SIDE NAV, TOGGLES ON MOBILE #} + + +
+ + {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #} + + + + {# PAGE CONTENT #} +
+
+ {% include "breadcrumbs.html" %} +
+ {% block body %}{% endblock %} +
+ {% include "footer.html" %} +
+
+ +
+ +
+ {% include "versions.html" %} + + {% if not embedded %} + + + {%- for scriptfile in script_files %} + + {%- endfor %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {# STICKY NAVIGATION #} + {% if theme_sticky_navigation %} + + {% endif %} + + {%- block footer %} {% endblock %} + + + diff --git a/docsrc/exts/themes/sphinx_rtd_theme/layout_old.html b/docsrc/exts/themes/sphinx_rtd_theme/layout_old.html new file mode 100644 index 00000000..deb8df2a --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/layout_old.html @@ -0,0 +1,205 @@ +{# + basic/layout.html + ~~~~~~~~~~~~~~~~~ + + Master layout template for Sphinx themes. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- block doctype -%} + +{%- endblock %} +{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} +{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} +{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and + (sidebars != []) %} +{%- set url_root = pathto('', 1) %} +{# XXX necessary? #} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + +{%- macro relbar() %} + +{%- endmacro %} + +{%- macro sidebar() %} + {%- if render_sidebar %} +
+
+ {%- block sidebarlogo %} + {%- if logo %} + + {%- endif %} + {%- endblock %} + {%- if sidebars != None %} + {#- new style sidebar: explicitly include/exclude templates #} + {%- for sidebartemplate in sidebars %} + {%- include sidebartemplate %} + {%- endfor %} + {%- else %} + {#- old style sidebars: using blocks -- should be deprecated #} + {%- block sidebartoc %} + {%- include "localtoc.html" %} + {%- endblock %} + {%- block sidebarrel %} + {%- include "relations.html" %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- include "sourcelink.html" %} + {%- endblock %} + {%- if customsidebar %} + {%- include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- include "searchbox.html" %} + {%- endblock %} + {%- endif %} +
+
+ {%- endif %} +{%- endmacro %} + +{%- macro script() %} + + {%- for scriptfile in script_files %} + + {%- endfor %} +{%- endmacro %} + +{%- macro css() %} + + + {%- for cssfile in css_files %} + + {%- endfor %} +{%- endmacro %} + + + + + {{ metatags }} + {%- block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {%- endblock %} + {{ css() }} + {%- if not embedded %} + {{ script() }} + {%- if use_opensearch %} + + {%- endif %} + {%- if favicon %} + + {%- endif %} + {%- endif %} +{%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} +{%- endblock %} +{%- block extrahead %} {% endblock %} + + +{%- block header %}{% endblock %} + +{%- block relbar1 %}{{ relbar() }}{% endblock %} + +{%- block content %} + {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %} + +
+ {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {% block body %} {% endblock %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} + + {%- block sidebar2 %}{{ sidebar() }}{% endblock %} +
+
+{%- endblock %} + +{%- block relbar2 %}{{ relbar() }}{% endblock %} + +{%- block footer %} + +

asdf asdf asdf asdf 22

+{%- endblock %} + + + diff --git a/docsrc/exts/themes/sphinx_rtd_theme/search.html b/docsrc/exts/themes/sphinx_rtd_theme/search.html new file mode 100644 index 00000000..e3aa9b5c --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/search.html @@ -0,0 +1,50 @@ +{# + basic/search.html + ~~~~~~~~~~~~~~~~~ + + Template for the search page. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- extends "layout.html" %} +{% set title = _('Search') %} +{% set script_files = script_files + ['_static/searchtools.js'] %} +{% block footer %} + + {# this is used when loading the search index using $.ajax fails, + such as on Chrome for documents on localhost #} + + {{ super() }} +{% endblock %} +{% block body %} + + + {% if search_performed %} +

{{ _('Search Results') }}

+ {% if not search_results %} +

{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}

+ {% endif %} + {% endif %} +
+ {% if search_results %} +
    + {% for href, caption, context in search_results %} +
  • + {{ caption }} +

    {{ context|e }}

    +
  • + {% endfor %} +
+ {% endif %} +
+{% endblock %} diff --git a/docsrc/exts/themes/sphinx_rtd_theme/searchbox.html b/docsrc/exts/themes/sphinx_rtd_theme/searchbox.html new file mode 100644 index 00000000..35ad52c5 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/searchbox.html @@ -0,0 +1,9 @@ +{%- if builder != 'singlehtml' %} +
+
+ + + +
+
+{%- endif %} diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/css/badge_only.css b/docsrc/exts/themes/sphinx_rtd_theme/static/css/badge_only.css new file mode 100644 index 00000000..7e17fb14 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/static/css/badge_only.css @@ -0,0 +1,2 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} +/*# sourceMappingURL=badge_only.css.map */ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/css/theme.css b/docsrc/exts/themes/sphinx_rtd_theme/static/css/theme.css new file mode 100644 index 00000000..57b98fe6 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/static/css/theme.css @@ -0,0 +1,5 @@ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content p.caption,h3{orphans:3;widows:3}h2,.rst-content p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:0.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:scroll;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt,.rst-content tt .xref,.rst-content code .xref,a .rst-content tt,a .rst-content code{font-weight:bold}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),url(../fonts/Inconsolata.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} +/*# sourceMappingURL=theme.css.map */ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf new file mode 100644 index 00000000..360a232d Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf new file mode 100644 index 00000000..4b8a36d2 Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf new file mode 100644 index 00000000..e8b9bf6a Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf new file mode 100644 index 00000000..7608bc3e Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf new file mode 100644 index 00000000..e6ed0de5 Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf new file mode 100644 index 00000000..141d6c08 Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..7c79c6a6 Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..45fdf338 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..e89738de Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..8c1748aa Binary files /dev/null and b/docsrc/exts/themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff differ diff --git a/docsrc/exts/themes/sphinx_rtd_theme/static/js/modernizr.min.js b/docsrc/exts/themes/sphinx_rtd_theme/static/js/modernizr.min.js new file mode 100644 index 00000000..f65d4797 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/static/js/modernizr.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f ul li.current').removeClass('current'); + parent_li.toggleClass('current'); +} + +$(document).ready(function() { + // Shift nav in mobile when clicking the menu. + $(document).on('click', "[data-toggle='wy-nav-top']", function() { + $("[data-toggle='wy-nav-shift']").toggleClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + // Nav menu link click operations + $(document).on('click', ".wy-menu-vertical .current ul li a", function() { + var target = $(this); + // Close menu when you click a link. + $("[data-toggle='wy-nav-shift']").removeClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + // Handle dynamic display of l3 and l4 nav lists + toggleCurrent(target); + if (typeof(window.SphinxRtdTheme) != 'undefined') { + window.SphinxRtdTheme.StickyNav.hashChange(); + } + }); + $(document).on('click', "[data-toggle='rst-current-version']", function() { + $("[data-toggle='rst-versions']").toggleClass("shift-up"); + }); + // Make tables responsive + $("table.docutils:not(.field-list)").wrap("
"); + + // Add expand links to all parents of nested ul + $('.wy-menu-vertical ul').siblings('a').each(function () { + var link = $(this); + expand = $(''); + expand.on('click', function (ev) { + toggleCurrent(link); + ev.stopPropagation(); + return false; + }); + link.prepend(expand); + }); +}); + +// Sphinx theme state +window.SphinxRtdTheme = (function (jquery) { + var stickyNav = (function () { + var navBar, + win, + winScroll = false, + linkScroll = false, + winPosition = 0, + enable = function () { + init(); + reset(); + win.on('hashchange', reset); + + // Set scrolling + win.on('scroll', function () { + if (!linkScroll) { + winScroll = true; + } + }); + setInterval(function () { + if (winScroll) { + winScroll = false; + var newWinPosition = win.scrollTop(), + navPosition = navBar.scrollTop(), + newNavPosition = navPosition + (newWinPosition - winPosition); + navBar.scrollTop(newNavPosition); + winPosition = newWinPosition; + } + }, 25); + }, + init = function () { + navBar = jquery('nav.wy-nav-side:first'); + win = jquery(window); + }, + reset = function () { + // Get anchor from URL and open up nested nav + var anchor = encodeURI(window.location.hash); + if (anchor) { + try { + var link = $('.wy-menu-vertical') + .find('[href="' + anchor + '"]'); + $('.wy-menu-vertical li.toctree-l1 li.current') + .removeClass('current'); + link.closest('li.toctree-l2').addClass('current'); + link.closest('li.toctree-l3').addClass('current'); + link.closest('li.toctree-l4').addClass('current'); + } + catch (err) { + console.log("Error expanding nav for anchor", err); + } + } + }, + hashChange = function () { + linkScroll = true; + win.one('hashchange', function () { + linkScroll = false; + }); + }; + jquery(init); + return { + enable: enable, + hashChange: hashChange + }; + }()); + return { + StickyNav: stickyNav + }; +}($)); diff --git a/docsrc/exts/themes/sphinx_rtd_theme/theme.conf b/docsrc/exts/themes/sphinx_rtd_theme/theme.conf new file mode 100644 index 00000000..b71548b2 --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/theme.conf @@ -0,0 +1,9 @@ +[theme] +inherit = basic +stylesheet = css/theme.css + +[options] +typekit_id = hiw1hhg +analytics_id = +sticky_navigation = False +logo_only = diff --git a/docsrc/exts/themes/sphinx_rtd_theme/versions.html b/docsrc/exts/themes/sphinx_rtd_theme/versions.html new file mode 100644 index 00000000..8b3eb79d --- /dev/null +++ b/docsrc/exts/themes/sphinx_rtd_theme/versions.html @@ -0,0 +1,37 @@ +{% if READTHEDOCS %} +{# Add rst-badge after rst-versions for small badge style. #} +
+ + Read the Docs + v: {{ current_version }} + + +
+
+
Versions
+ {% for slug, url in versions %} +
{{ slug }}
+ {% endfor %} +
+
+
Downloads
+ {% for type, url in downloads %} +
{{ type }}
+ {% endfor %} +
+
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+
+ Free document hosting provided by Read the Docs. + +
+
+{% endif %} + diff --git a/docsrc/index.rst b/docsrc/index.rst new file mode 100644 index 00000000..7f6e7c07 --- /dev/null +++ b/docsrc/index.rst @@ -0,0 +1,91 @@ +.. _sasl-index: + +========== +Cyrus SASL +========== + +Welcome to Cyrus SASL. + +What is Cyrus SASL? +=================== +Simple Authentication and Security Layer (SASL_) is a specification that describes how authentication mechanisms can be plugged into an application protocol on the wire. Cyrus SASL is an implementation of SASL that makes it easy for application developers to integrate authentication mechanisms into their application in a generic way. + +The latest stable version of Cyrus SASL is |sasl_current_stable_version|. + +:ref:`Cyrus IMAP ` uses Cyrus SASL to provide authentication support to the mail server, however it is just one project using Cyrus SASL. + +Features +-------- +Cyrus SASL provides a number of authentication plugins out of the box. + + Berkeley DB, GDBM, or NDBM (sasldb), PAM, MySQL, PostgreSQL, SQLite, LDAP, Active Directory(LDAP), DCE, Kerberos 4 and 5, proxied IMAP auth, getpwent, shadow, SIA, Courier Authdaemon, httpform, APOP and SASL mechanisms: ANONYMOUS, CRAM-MD5, DIGEST-MD5, EXTERNAL, GSSAPI, LOGIN, NTLM, OTP, PASSDSS, PLAIN, SR + +.. _SASL: https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer + +This document is an introduction to **Cyrus SASL**. It is not intended to be an exhaustive reference for the SASL Application Programming Interface (API), which is detailed in the SASL manual pages, and the libsasl.h header file. + + +Known Bugs +---------- + +.. todo: + Is this still true? + +``libtool`` doesn't always link libraries together. In our environment, +we only have static Krb5 libraries; the GSSAPI plugin should link +these libraries in on platforms that support it (Solaris and Linux +among them) but it does not. It also doesn't always get the runpath +of libraries correct. + +Note for Packagers +------------------ + +People considering doing binary distributions that include saslauthd +should be aware that the code is covered by several slightly different +(but compatible) licenses, due to how it was contributed. Details can +be found within the source code. + + +.. toctree:: + :maxdepth: 1 + :caption: Overview + + download + sasl/quickstart + sasl/installation + Contact Us + +.. toctree:: + :maxdepth: 1 + :caption: Configuration + + sasl/concepts + sasl/components + sasl/options + sasl/sysadmin + sasl/advanced + sasl/upgrading + sasl/appconvert + +.. toctree:: + :maxdepth: 1 + :caption: Developers + + sasl/developer/programming + sasl/developer/plugprog + sasl/developer/testing + +.. toctree:: + :maxdepth: 1 + :caption: Reference + + sasl/auxiliary_properties + sasl/authentication_mechanisms + sasl/pwcheck + sasl/faq + sasl/resources + +.. toctree:: + :caption: IMAP + + Cyrus IMAP diff --git a/docsrc/sasl/advanced.rst b/docsrc/sasl/advanced.rst new file mode 100644 index 00000000..e6e01a60 --- /dev/null +++ b/docsrc/sasl/advanced.rst @@ -0,0 +1,34 @@ +.. _advanced: + +============== +Advanced Usage +============== + +Notes for Advanced Usage of libsasl +=================================== + +Using Cyrus SASL as a static library +------------------------------------ + +As of v2.0.2-ALPHA, Cyrus SASL supports the option to compile all of the +supported mechanisms and glue code into a single static library that may +be linked into any application. In practice, this saves memory by avoiding +the need to have a jump table for each process's reference into the shared +library, and ensures that all the mechanisms are loaded when the application +loads (thus reducing the overhead of loading the DSOs). + +However, this is not a recommended procedure to use in general. It loses +the flexibility of the DSOs that allow one to simply drop in a new mechanism +that even currently-running applications will see for each new connection. +That is, if you choose to use the static version of the library, not only +will you need to recompile the library each time you add a mechanism (provided +the mechanisms even support being compiled staticly), but you will need to +recompile every application that uses Cyrus SASL as well. + +However, if you are sure you wish to use a static version of Cyrus SASL, +compile it by giving ``configure`` the ``--enable-static`` option. +This will compile both a dynamic and a static version. Then, whenever +an application links to libsasl, it will also need to explicitly pull in +any dynamic libraries that may be needed by Cyrus SASL. Most notably, these +might include the GSSAPI, Kerberos, and Database libraries. To avoid compiling +the dynamic version, pass ``--disable-shared``. diff --git a/docsrc/sasl/appconvert.rst b/docsrc/sasl/appconvert.rst new file mode 100644 index 00000000..48820d99 --- /dev/null +++ b/docsrc/sasl/appconvert.rst @@ -0,0 +1,101 @@ +.. _appconvert: + +===================================== +Converting Applications from v1 to v2 +===================================== + +This documents our conversion experience with Cyrus IMAPd, an application +that uses almost every part of SASL, so it should give a good idea what caveats +need to be looked for when one is converting an application which uses SASLv1 +to use SASLv2. + +The major changes in the SASLv2 API have to do with memory management. +That is, the rule "If you allocate it, you free it" is now enforced. That +means that if the application allocates something (for example, an interaction +or callback response), it must free it. Likewise, the application does +NOT free anything handed to it by the SASL library, such as responses +given by sasl_client_step or sasl_decode. + + +Tips for both clients and servers +================================= + +* Change configure scripts to search for libsasl2 and include files + prefixed with sasl/ (sasl/sasl.h, sasl/saslutil.h, etc) +* ``sasl_decode64`` now takes an + additional parameter that is the size of the buffer it is passed. +* External authentication properties are no longer handled by a + ``sasl_external_properties_t``. Instead you make 2 separate calls to + ``sasl_setprop.`` + + * One with SASL_SSF_EXTERNAL to tell the SASL library what SSF is being + provided by the external layer. + * The other sets SASL_AUTH_EXTERNAL to indicate + the authentication name. + +* ``sasl_getprop`` now returns its value in a ``const void \*\*`` + +* ``sasl_encode`` and ``sasl_decode`` now return a constant output buffer, which + you do not need to free (it is only valid until the next call for this sasl\_ + conn_t, however) + +* The SASL_IP_REMOTE and SASL_IP_LOCAL properties are now SASL_IPLOCALPORT + and SASL_IPREMOTEPORT and take strings instead of sockaddrs. These strings + may also be passed to the sasl_[client/server]_new functions. They + are in one of the following formats: + + * a.b.c.d;p (IPv4, with port) + * e:f:g:h:i:j:k:l;p (IPv6, with port) + * e:j:k:l;p (IPv6, abbreviated zero fields, with port) + +* Error handling and reporting is different. All of the functions that used + to return a "reply" string no longer do. Now you should (always) check + ``sasl_errdetail``. Callbacks MUST likewise use ``sasl_seterror`` + instead of setting their (now nonexistent) reply parameter. + +* Be very careful about your handling of maxoutbuf. If you claim that + you can only read 4096 bytes at a time, be sure to only pass at most + that much at a time to the SASL library! + + +Tips for clients +================ + +* In ``sasl_client_new`` you can now pass ip address strings as + parameters 3 and 4 instead of calling setprop later on sockaddr's. + This is preferred but not required (not passing them by either method disables + mechs which require IP address information). You might find the iptostring() + function in utils/smtptest.c to be useful for this. If the protocol supports + the server sending data on success you should pass SASL_SUCCESS_DATA as a + flag. +* ``sasl_client_start`` loses the 3rd "secret" parameter. + Also, NULL clientout and clientoutlen indicates that the protocol does not + support client-send-first. A NULL return value indicates that there is no + first client send. (as opposed to an empty string, which indicates that + the first client send is the empty string). + +* Both ``sasl_client_start`` and ``sasl_client_step`` now take + const clientout parameters that you are no longer responsible for freeing + (it is only valid until the next call for this ``sasl_conn_t``, however) + +* When interactions and callbacks happen you are responsible for freeing + the results. + +Tips for Servers +================ + +* SASL_SECURITY_LAYER flag no longer exists, whether or not to use a + security layer is solely determined by the security properties information, + namely, the ``maxbufsize`` member of the + ``sasl_security_properties_t`` +* ``sasl_server_new`` now can take ip address strings. +* ``sasl_checkpass`` no longer has a "reply" parameter. There + are also considerably fewer possible values for the pwcheck_method + option (now only auxprop, saslauthd, authdaemond, and pwcheck). +* ``sasl_server_start`` / ``sasl_server_step`` have same + output parameter deal as their equivalents on the client side +* ``sasl_listmech`` has a constant output parameter +* If you used to canonicalize the username in a SASL_CB_PROXY_POLICY + callback you should now separate the functionality of authorization and + canonicalization. That is, only do authorization in SASL_CB_PROXY_POLICY, + and do canonicalization in the SASL_CB_CANON_USER callback diff --git a/docsrc/sasl/authentication_mechanisms.rst b/docsrc/sasl/authentication_mechanisms.rst new file mode 100644 index 00000000..c32bab92 --- /dev/null +++ b/docsrc/sasl/authentication_mechanisms.rst @@ -0,0 +1,183 @@ +.. _authentication_mechanisms: + +========================= +Authentication Mechanisms +========================= + +Mechanisms +========== + +ANONYMOUS +--------- + +.. todo:: + Content needed here + +CRAM-MD5 +-------- + +.. todo:: + Content needed here + + +DIGEST-MD5 +---------- + +.. todo:: + Content needed here + +EXTERNAL +-------- + +.. todo:: + Content needed here + + +G2 +----- + +.. todo:: + Content needed here + + +GSSAPI +------ + +Not sure how to get GSSAPI going? Check out our :ref:`GSSAPI configuration guide `. + +.. todo:: + Content needed here + + +GSS-SPEGNO +---------- + +.. todo:: + Content needed here + +KERBEROS_V4 +----------- + +.. todo:: + Content needed here + +LOGIN +----- + +.. todo:: + Content needed here + +NTLM +---- + +.. todo:: + Content needed here + +OTP +--- + +.. todo:: + Content needed here + +PASSDSS +------- + +.. todo:: + Content needed here + +PLAIN +----- + +.. todo:: + Content needed here + +SCRAM +----- + +.. todo:: + Content needed here + +SRP +--- + +.. todo:: + Content needed here + +Non-SASL Authentication +----------------------- + +.. todo:: + Content needed here + +---- + +Summary +======= + +This table shows what security flags and features are supported by each +of the mechanisms provided by the Cyrus SASL Library. + ++-------------+---------+----------------------------------------------------------------+-----------------------------------------------------------+ +| | MAX SSF | SECURITY PROPERTIES | FEATURES | ++-------------+ +----------------------------------------------------------------+-----------------------------------------------------------+ +| | | NOPLAIN | NOACTIVE | NODICT | FORWARD | NOANON | CRED | MUTUAL | CLT FIRST | SRV FIRST | SRV LAST | PROXY | BIND | HTTP | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| ANONYMOUS | 0 | X | | | | | | | X | | | | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| CRAM-MD5 | 0 | X | | | | X | | | | X | | | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| DIGEST-MD5 | 128 | X | | | | X | | X | reauth | initial auth | X | X | | X | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| EXTERNAL | 0 | X | | X | | X | | | X | | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| G2 | 56 | X | X | | | X | | X | X | | X | X | X | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| GSSAPI | 56 | X | X | | | X | X | X | X | | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| GSS-SPNEGO | 56 | X | X | | | X | X | X | X | | | X | | X | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| KERBEROS_V4 | 56 | X | X | | | X | | X | | X | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| LOGIN | 0 | | | | | X | X | | | X | | | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| NTLM | 0 | X | | | | X | | | X | | | | | X | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| OTP | 0 | X | | | X | X | | | X | | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| PASSDSS | 112 | X | X | X | X | X | X | X | X | | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| PLAIN | 0 | | | | | X | X | | X | | | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| SCRAM | 0 | X | X | | | X | | X | X | | X | X | X | ? | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ +| SRP | 128 | X | X | X | X | X | | X | X | | X | X | | | ++-------------+---------+---------+----------+--------+---------+--------+------+--------+-----------+--------------+----------+-------+------+------+ + +.. Helpfully generated from http://www.tablesgenerator.com/text_tables# + +Understanding this table: + +Security Properties: + +* **MAX SSF** - The maximum Security Strength Factor supported by the mechanism (roughly the number of bits of encryption provided, but may have other meanings, for example an SSF of 1 indicates integrity protection only, no encryption). +* **NOPLAIN** - Mechanism is not susceptable to simple passive (eavesdropping) attack. +* **NOACTIVE** - Protection from active (non-dictionary) attacks during authentication exchange. (Implies MUTUAL). +* **NODICT** - Not susceptable to passive dictionary attack. +* **NOFORWARD** - Breaking one session won't help break the next. +* **NOANON** - Don't permit anonymous logins. +* **CRED** - Mechanism can pass client credentials. +* **MUTUAL** - Supports mutual authentication (authenticates the server to the client) + +Features: + +* **CLTFIRST** - The client should send first in this mechanism. +* **SRVFIRST** - The server must send first in this mechanism. +* **SRVLAST** - This mechanism supports server-send-last configurations. +* **PROXY** - This mechanism supports proxy authentication. +* **BIND** - This mechanism supports channel binding. +* **HTTP** - This mechanism has a profile for HTTP. + +.. toctree:: + :hidden: + + gssapi diff --git a/docsrc/sasl/auxiliary_properties.rst b/docsrc/sasl/auxiliary_properties.rst new file mode 100644 index 00000000..e1b3e9a3 --- /dev/null +++ b/docsrc/sasl/auxiliary_properties.rst @@ -0,0 +1,40 @@ +Auxiliary Properties +==================== + +Auxiliary Properties and the Glue Layer +--------------------------------------- + +.. todo:: + Content needed here + +Passwords and other Data +------------------------ + +.. todo:: + Content needed here + +sasldb +------ + +.. todo:: + Content needed here + +ldapdb +------ + +.. todo:: + Content needed here + +sql +--- + +.. todo:: + Content needed here + +User Canonicalization +--------------------- + +.. todo:: + Content needed here + + diff --git a/docsrc/sasl/components.rst b/docsrc/sasl/components.rst new file mode 100644 index 00000000..f6bfa09b --- /dev/null +++ b/docsrc/sasl/components.rst @@ -0,0 +1,184 @@ +.. _components: + +========== +Components +========== + +As the SASL library is a 'glue layer' between many different parts of the +authentication system, there are a lot of different components +that often cause confusion to users of the library who are trying to +configure it for use on their system. This document will try to provide +some structure to all of these components, though you will also need +to read the :ref:`System Administration ` to have a full +understanding of how to install SASL on your system. + +The first thing to realize is that there is a difference between SASL, +the protocol, and Cyrus SASL, the library. The first is a specification +that describes how authentication mechanisms can be plugged into an application +protocol *on the wire*. The later is an implementation that aims +to make this easier for application developers to integrate authentication +mechanisms into their application in a generic way. It is quite possible +to have an application that uses SASL (the specification) without using +Cyrus SASL (the implementation). + +The remainder of this document will refer to components of the Cyrus +SASL implementation, though some of these will necessarily have a broader +scope. + +The Application +=============== + +The application is a client of the SASL library. It can be a client or server +application (or both, in the case of a proxy). It takes care of the +on-the-wire representation of the SASL negotiation, however it performs no +analysis of the exchange itself. It relies on the judgment of the SASL +library whether authentication has occurred or not. The application is also +responsible for determining if the authenticated user may authorize as another +user id (For more details on authentication and authorization identities +and their differences, see Cyrus SASL for System Administrators) + +Examples of applications are Cyrus IMAPd, OpenLDAP, Sendmail, Mutt, +sieveshell, cyradm, and many others. + +The SASL Glue Layer +=================== + +The first component of the SASL library is affectionately called the +``glue`` layer. It takes care of ensuring that the application and +the mechanisms can work together successfully. To this end, it does a +variety of basic tasks: + +* Loading of any plugins (more on these below) +* Ascertaining necessary security properties from the application to aid + in the choice of mechanism (or to limit the available mechanisms) +* Listing of available plugins to the application (mostly used on the server + side) +* Choosing the best mechanism from a list of available mechanisms + for a particular authentication attempt (client-side) +* Routing the authentication (and in the case of a mechanism with a security + layer, encrypted) data packets between the application and the + chosen mechanism. +* Providing information about the SASL negotiation back to the application + (authenticated user, requested authorization identity, security strength of + any negotiated security layer, and so on). + + +The Cyrus SASL implementation also provides several other services to +both its plugins and applications. Some of these are simply general utilities, +such as MIME Base-64 encoding and decoding, and random number generation. +Others are more specific to the task of authentication, such as providing +password verification services. Such services are capable of taking +a username and a plaintext password and saying ``yes`` or +``no``. Details of available password verification services are +discussed below. + +Finally, the glue code allows the mechanisms and applications access to +two special types of plugins, Auxiliary Property or ``auxprop`` +plugins, which provide a simple database interface and can return properties +about the user such as password, home directory, or mail +routing address, and Username Canonicalization, which might provide +site-specific ways to canonicalize a username or perform other tasks. + +In the Cyrus SASL Implementation, the glue code is entirely contained +within ``libsasl2.so`` (or ``libsasl2.a``) + +Plugins +======= + +Plugins: General +---------------- + +The Cyrus SASL architechure is very modular, using loadable modules for +things such as the mechanism profiles and the database access done by the +auxillary property plugins. This means that it is easy to limit what +parts are loaded by a given application, and that third parties can write +their own modules to provide services, just by adhering to the API description +in ``saslplug.h``. + +Plugins: SASL Mechanisms +------------------------ + +The simplest types of plugins to understand are those which provide +SASL mechanisms, such as CRAM-MD5, DIGEST-MD5, GSSAPI, PLAIN, SRP, and so on. +These mechanisms take care of both server-side and client-side parts +of the SASL negotiation. If the given mechanism supports a security layer +(that is, makes guarantees about privacy or integrity of data after the +negotiation is complete), the plugin provides that functionality as well. + +SASL mechanisms are generally defined by the IETF standards process, +however, some mechanisms are not (For example, NTLM). This is in contrast +to the other types of plugins, which provide database and username +canonicalization services to other plugins and thus aren't standardized in +their behavior (they are specific to our implementation). Password verifiers +are also an implementation detail (though saslauthd makes use of +standards such as PAM and LDAP to perform that verification) + +There are several types of mechanisms, in broad strokes we have: + +Password Verification Mechanisms + For example, PLAIN. These receive a raw password from the remote and then pass it into the glue code for + verification by a password verifier. These require the existence of an + outside security layer to hide the otherwise plaintext password from people + who might be snooping on the wire. These mechanisms do not require that + the server have access to a plaintext (or plaintext-equivalent) version + of the password. +Shared Secret Mechanisms + For these mechanisms, such as CRAM-MD5, DIGEST-MD5, and SRP, there is a shared secret between the server and client + (e.g. a password). However, in this case the password itself does not travel + on the wire. Instead, the client passes a server a token that proves that + it knows the secret (without actually sending the secret across the wire). + For these mechanisms, the server generally needs a plaintext equivalent of + the secret to be in local storage (not true for SRP). +Kerberos Mechanisms + Kerberos mechanisms use a trusted + third party to authenticate the client. These mechanisms don't require + the server to share any secret information with the client, it is all performed + through the Kerberos protocol. + + +Mechanism plugins are generally contained in a .so file that has a name +similar to the mechanism's name. Though, in a static compilation they +can also be a part of ``libsasl2.a`` + +Plugins: Auxiliary Property +--------------------------- + +Auxiliary Property (or auxprop) plugins provide a database service for the +glue layer (and through it, to the mechanisms and application). Cyrus SASL +ships with two auxprop plugins: SASLdb and SQL. Though they can be use +in much more generic ways, auxprop plugins are mostly only used by +shared secret mechanisms (or by the auxprop password verify) to access the +``userPassword`` attribute. This provides a plaintext copy of the +password that allows for authentication to take place. + +Like the mechanism plugins, these are named similarly to the databases +that they implement an interface for. + +Plugins: Username Canonicalization +---------------------------------- + +Username Canonicalization plugins are not widely used, however it may be +useful to use as a hook if your site has specific requirements for how userids +are presented to the applications. + +Password Verification Services +============================== + +As described above, the password verifiers take a username and plaintext +password, and say either ``yes`` or ``no``. It is not possible +to use them to verify hashes that might be provided by the shared secret +mechanisms. + +Password verifiers are selected using the ``pwcheck_method`` +SASL option. There are two main password verifiers provided with Cyrus SASL: + +auxprop + This uses an auxprop plugin to fetch the password and then + compares it with the client-provided copy to make the determination. +saslauthd + This calls out to the ``saslauthd`` daemon, which + also ships with the distribution. The ``saslauthd`` daemon has a number + of modules of its own, which allow it to do verification of passwords in + a variety of ways, including PAM, LDAP, against a Kerberos database, and so on. + This is how you would want to, for example, use the data contained in + ``/etc/shadow`` to authenticate users. diff --git a/docsrc/sasl/concepts.rst b/docsrc/sasl/concepts.rst new file mode 100644 index 00000000..74050254 --- /dev/null +++ b/docsrc/sasl/concepts.rst @@ -0,0 +1,63 @@ +Concepts +======== + +SASL +---- + +Simple Authentication and Security Layer (SASL) is a protocol developed by the Internet Engineering Task Force (IETF) for the purpose of providing an extensible and pluggable authentication framework, primarily for non-web related protocols. It is commonly used in email related protocols, such as SMTP, IMAP, and POP, along with XMPP, LDAP, and a few others. In doing so, various implementations of those protocols, such as the Cyrus IMAP or Dovecot servers, can support a wide range of authentication mechanisms with various email clients which implement the IMAP protocol, including Thunderbird, Outlook, and the Android mail client. + +RFC 4422 is the base framework specification for SASL. It provides guidance for protocol designers, server software implementations, and SASL mechanism designers. Protocol definitions, and SASL mechanism specifications in turn make use of this framework to independently support each other. That is, if a protocol were designed 5 years ago to make use of SASL, and a new mechanism were designed today, server implementations and client software could make use of that new mechanism without a change to the original server protocol spec. + +SASL Authentication Mechanisms +------------------------------ + +SASL mechanisms are plugable authentication methods that are developed independently of server protocols. For example, the Generic Security Service Application Program Interface (GSSAPI) mechanism, defined in RFC 4752, defines a network oriented protocol for authenticating a client to a server, using Kerberos version 5, a trusted 3rd party ticket based system. The GSSAPI mechanism should work with all clients and servers which implement support for it, regardless of the actual server protocol used (such as IMAP), given the protocol was designed for use with the SASL framework. + +A list of developed SASL mechanisms can be found at the `IANA registered SASL mechanisms `__ page. A more detailed discussion of these mechanisms can be found in :doc:`Authentication Mechanisms`. + +Security Layers +--------------- + +SASL Security Layers allow a server and client to negotiate integrity and confidentiality protection for a connection once it has been authenticated. It is only available for mechanisms which themselves are capable of providing such protection (such as GSSAPI). It is capable of being used to encrypt a connection over the public internet, and can be used as an alternative to TLS encryption. + +Channel Binding +--------------- + +.. todo:: + What's channel binding? + +Realms +------ + +.. todo:: + What are realms? + +Protocols +--------- + +.. todo:: + What protocols? + +Cyrus SASL +---------- + +.. todo:: + Something required here + +The Glue Library +---------------- + +.. todo:: + A bit stuck with this one too :) + +Auxiliary Properties +-------------------- + +.. todo:: + More properties... + +Plugins +------- + +.. todo:: + Plugins, plugins and plugins diff --git a/docsrc/sasl/developer/installation.rst b/docsrc/sasl/developer/installation.rst new file mode 100644 index 00000000..9baebc7c --- /dev/null +++ b/docsrc/sasl/developer/installation.rst @@ -0,0 +1,81 @@ +.. _sasldevinstallguide: + +=========================== +Cyrus SASL Developer Guide +=========================== + +.. todo: + This is all available at http://www.cyrusimap.org/docs/cyrus-sasl/2.1.25/install.php + +Compile from source +=================== + +Fetch the source +----------------- + +Fetch from git +############## + +If you're not familiar with Git, there are detailed instructions in the :ref:`Cyrus IMAPd GitHub guide `. + +Cyrus SASL is at https://github.com/cyrusimap/cyrus-sasl + +To contribute, we recommend `forking the code `_ then issuing a pull request when you're ready. + +Once forked on GitHub, you can obtain a copy by:: + + git clone https://github.com/YOUR-USERNAME/REPOSITORY-NAME.git + +You will then want to set your local copy to get its changes from the original repository, so it stays in sync. Use ``git remote -v`` to show the current origins of your clone which will currently be your fork:: + + git remote -v + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) + +We want to set that instead to point to the primary original upstream repository:: + + git remote add upstream https://github.com/cyrusimap/cyrus-sasl.git + +Now we can check to see that the upstream is set:: + + git remote -v + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) + upstream https://github.com/cyrusimap/cyrus-sasl.git (fetch) + upstream https://github.com/cyrusimap/cyrus-sasl.git (push) + +We recommend you create a topic branch and make your changes (don't forget to test!). Using a topic branch means you can keep your master +source in sync without affecting your changes. It also means that if your patch undergoes further revisions before inclusion, you +can easily do so. + + +Unpack from tarball +################### + +Cyrus SASL releases are available to download in tarball format from ftp://ftp.cyrusimap.org/cyrus-sasl/ + +Dependencies +------------ + +.. todo: + ?? Libraries + +Compiling +--------- + +:: + cd (source directory) + sh SMakefile + ./configure + make + make install + ln -s /usr/local/lib/sasl2 /usr/lib/sasl2 + + +Configuration +------------- + +`./configure ...` + +.. note: + If you tweak configure.ac or any of the .m4 files, you will have to delete configure and then compile again to create a new configure script. diff --git a/docsrc/sasl/developer/plugprog.rst b/docsrc/sasl/developer/plugprog.rst new file mode 100644 index 00000000..81b9952b --- /dev/null +++ b/docsrc/sasl/developer/plugprog.rst @@ -0,0 +1,347 @@ +.. _plugprog: + +========================= +Plugin Programmer's Guide +========================= + +.. note:: + + NOTE: This is a work in progress. Any contributions would be + *very* appreciated. + +.. contents:: + :local: + +Introduction +============ + +About this Guide +---------------- + +This guide gives a brief overview on the things that one +needs to know to write a :ref:`mechanism ` for the SASLv2 API (and thus +Cyrus SASLv2). Note that this page is a brief overview +and that the authoritative documentation are the header files +included in the SASL distribution. If you have any questions, please +feel free to contact the :ref:`Cyrus development team `. + +Please note that this guide is only intended for developers looking +to write mechanisms for the SASLv2 API, and that application programmers +should be reading the :ref:`Application Programming Guide ` instead. + + +What is SASL? +------------- + +A description of SASL is covered in detail in the +:ref:`programmer's guide `, which mechanism +developers should probably read first anyway to become familiar +with development using the SASL library. + +Common Section +============== + +Overview of Plugin Programming +------------------------------ + +The basic idea behind programming plugins for Cyrus SASL rests in +the ability to dlopen a shared library. Thus, all plugins should +be shared libraries. It is recommended that they are libtool +libraries for portability reasons (Cyrus SASL parses .la files to +get the appropriate name to dlopen), but they can have an extention +of .so as well. + +All plugins should live in the same directory +(generally /usr/lib/sasl2), which the glue code (that is, the interface +layer that sits between the plugins and the application) scans +when one of the init functions (sasl_server_init or sasl_client_init) +is called. Cyrus SASL then attempts to open each library and +run an initialization function. If the initialization function +succeeds, and the versions match, then the glue code determines +that the load was successful and the plugin is available for use. + +There are serveral types of plugins (note that a given plugin library +may contain any or all of the following in combination, though +such a plugin would be a beast!): + + +Mechanism Plugins + These plugins implement mechanisms + for authentication, and are the majority of the plugins included + with Cyrus SASL. Generally implementing both a client and a server + side they take care of the authentication process. +User Canonicalization Plugins + These plugins enable differing + ways of canonicalizing authentication and authorization IDs. +Auxiliary Property Plugins + These plugins allow auxilliary + properties about user accounts to be looked up, such as passwords. + Cyrus SASL includes a plugin to read sasldb files, for example. + + +Use of sasl_utils_t +------------------- + +Because of the way that shared library plugins are loaded for both +speed and namespace reasons, the symbol tables are not shared across +plugins. Thus, the only interface that the plugin should assume it +has to the outside world is through the ``sasl_utils_t`` structure (or +through links that it specifically requires). Likewise, the glue code +has no (and will use no) interface into the plugin other than the +contents of the structures that are passed back to it by the +initialization function. + +.. note:: + + Do not assume you have access to any + functions except through links that your library explicitly makes + or through what is provided via the ``sasl_utils_t`` structure. + +Error Reporting +--------------- + +Error reporting is very important for failed authentication tracking +and helping to debug installations or authentication problems. For +that reason, in addition to the standard SASL return codes, the +glue code provides an interface to its seterror function (via +``sasl_utils_t``). This function sets detailed error information for +a given connection. + +In order to ensure consistency of this information, it is the +responsibility of the deepest function with access to the sasl_conn_t +make the call to set the errdetail string. + +Memory Allocation +----------------- + +Memory allocation in SASLv2 follows the simple paradigm that **if you +allocate it, you free it**. This improves portability, and allows +for a large performance improvement over SASLv1. To prevent memory +leaks (especially in the mechanism plugins), please ensure that you +follow this paradigm. + +Client Send First / Server Send Last +------------------------------------ + +Mechanism plugins used to have to worry about the situation +where they needed clients to send first (or server to send last), yet +the protocol did not support it. Luckily, this is now handled by +the glue code, provided that the plugin declares the appropriate flags +in the structure returned by its init function. Thus, the step functions +will not have to worry about these issues and can be implemented +knowing they will be called only when the application actually has +data for them and/or will allow them to send data. These flags are as +follows: + +SASL_FEAT_WANT_CLIENT_FIRST + The mechanism has the client + side send first always. (e.g. PLAIN) +SASL_FEAT_SERVER_FIRST + The mechanism has the server side + send first always. (e.g. CRAM-MD5) + + +If neither flag is set, the mechanism will handle the client-send +first situation internally, because the client may or may not send +first. (e.g. DIGEST-MD5). In this case, the plugin must +intelligently check for the presence (or absence) of clientin/serverin +data. Note that the optional client send-first is only possible when the +protocol permits an initial response. + +The server send last situation is handled by the plugin intelligently +setting \*serverout when the step function returns SASL_OK. + +* For mechanisms + which never send last (e.g. PLAIN), \*serverout must be set to NULL. +* For + mechanisms which always send last (e.g. DIGEST-MD5), \*serverout must + point to the success data. +* For mechanisms in which the server may or + may not send last (e.g. SRP), \*serverout must be set accordingly. + +.. _plugprog-client: + +Client Plugins +============== + +Client-side mechanism plugins are generally included in the same +plugin with their :ref:`server ` counterpart, though +this is not a requirement. They take care of the client-side of the +SASL negotiation. For a simple example, see the ANONYMOUS plugin. +Client plugins must export ``sasl_client_plug_init`` which returns +a ``sasl_client_plug_t`` in order to load. The structure has +several functional members and a global context (which applies to +all connections using the plugin). The important ones are described +briefly here. + +mech_new + Called at the beginning of each connection, + (on a call to sasl_client_start), + + mech_new does mechanism-specific initialization, and if necessary + allocates a connection context (which the glue code keeps track + of for it). mech_new does not actually send any data to the client, + it simply allocates the context. + +mech_step + Called from ``sasl_client_start`` and + ``sasl_client_step``, this function does the actual work of + the client + side of the authentication. If authentication is successful, it + should return SASL_OK, otherwise it should return a valid SASL + error code (and call seterror). + + This should also set up the + oparams structure before returning SASL_OK, including any + security layer information (in the way of callbacks). + + Note + that as soon as the client has both the authentication and + authorization IDs, it MUST call the canon_user function provided + in its params structure (for both the authentication and + authorization IDs, with SASL_CU_AUTHID and SASL_CU_AUTHZID + respectively). + +mech_dispose + Called to dispose of a connection context. + This is only called when the connection will no longer be used + (e.g. when ``sasl_dispose`` is called) + +mech_free + Called when the sasl library is shutting down + (by ``sasl_client_done/sasl_server_done/sasl_done``). + Intended to free any global state of the plugin. + +.. _plugprog-server: + +Server Plugins +============== + +Server-side mechanism plugins are generally included in the same +plugin with their :ref:`client ` counterpart, though +this is not a requirement. They take care of the server-side of the +SASL negotiation, and are generally more complicated than their +client-side counterparts. For a simple example, see the ANONYMOUS +plugin. + +Server plugins must export ``sasl_server_plug_init`` which returns +a ``sasl_server_plug_t`` in order to load. The structure has +several functional members and a global context (which applies to +all connections using the plugin). The important ones are described +briefly here. + +mech_new + Called at the beginning of each connection, + (on a call to sasl_client_start), + + mech_new does mechanism-specific initialization, and if necessary + allocates a connection context (which the glue code keeps track + of for it). mech_new does not actually send any data to the client, + it simply allocates the context. + +mech_step + Called from ``sasl_server_start`` and + ``sasl_server_step``, this function does the actual work of + the server + side of the authentication. + + If authentication is successful, it + should return SASL_OK, otherwise it should return a valid SASL + error code (and call seterror). This should also set up the + oparams structure before returning SASL_OK, including any + security layer information (in the way of callbacks and SSF + information). + + Also, as soon + as the mechanism has computed both the authentication and the + authorization IDs, it MUST call the canon_user function provided + in the server params structure (for both the authentication and + authorization IDs, with SASL_CU_AUTHID and SASL_CU_AUTHZID + respectively). This action will also fill in its + propctx, so any auxiliary property *requests* + (for example, to lookup + the password) should be done before the request to canonicalize + the authentication id. Authorization ID lookups do not occur until + after the plugin returns success to the SASL library. + + Before returning SASL_OK, ``mech_step`` must fill in the + oparams fields for which it is responsible, that is, ``doneflag`` + (set to 1 to indicate a complete exchange), ``maxoutbuf``, or + the maximum output size it can do at once for a security layer, + ``mech_ssf`` or the supplied SSF of the security layer, + and ``encode``, ``decode``, ``encode_context``, + and ``decode_context``, + which are what the glue code will call on calls to ``sasl_encode``, + ``sasl_encodev``, and ``sasl_decode``. + +mech_dispose + Called to dispose of a connection context. + This is only called when the connection will no longer be used + (e.g. when ``sasl_dispose`` is called) + +mech_free + Called when the sasl library is shutting down + (by ``sasl_client_done/sasl_server_done/sasl_done``). + Intended to free any global state of the plugin. + +setpass + Called to set a user's password. This allows + mechanisms to support their own internal password or secret + database. + +mech_avail + Called by the first call to + ``sasl_listmech``, + it checks to see if the mechanism is available for the given + user, and MAY allocate a connection context (thus avoiding + a call to ``mech_new``). However it should not do this + without significant performance benefit as it forces the glue + code to keep track of extra contexts that may not be used. + +User Canonicalization (canon_user) Plugins +========================================== + +User Canonicalization plugins allow for nonstandard ways of +canonicalizing the username. They are subject to the following +requirements: + +* They must copy their output into the provided output buffers. +* The output buffers may be the same as the input buffers. +* They must function for the case which is only an authentication + ID (flags == SASL_CU_AUTHID) or only an authorization ID + (flags == SASL_CU_AUTHZID) or both + (flags == SASL_CU_AUTHID | SASL_CU_AUTHZID) + +User canonicalization plugins must export a ``sasl_canonuser_init`` +function which returns a ``sasl_canonuser_plug_t`` in order +to load successfully. They must implement at least one of +the ``canon_user_client`` or ``canon_user_server`` members +of the ``sasl_canonuser_plug_t``. The INTERNAL canon_user plugin +that is inside of the glue code implements both in the same way. + +Auxiliary Property (auxprop) Plugins +==================================== + +Perhaps the most exciting addition in SASLv2, Auxprop plugins +allow for an easy way to perform password and secret lookups (as well +as other information needed for authentication and authorization) +from directory services, and in the same request allow the application +to receive properties that it needs to provide the service. + +Auxprop plugins need to export the ``sasl_auxprop_init`` function +and pass back a ``sasl_auxprop_plug_t`` in order to load +successfully. The sasldb plugin included with the Cyrus SASL +distribution would be a good place to start. + +Interfacing with property contexts is extremely well documented in +``prop.h`` and so that is omitted here. The only important +note is to be sure that you are using the interfaces provided +through the ``sasl_utils_t`` structure and not calling +the functions directly. + +To successfully implement an auxprop plugin there is only one +required function to implement, that is the ``auxprop_lookup`` +member of the ``sasl_auxprop_plug_t``. This is called +just after canonicalization of the username, with the canonicalized +username. It can then do whatever lookups are necessary for any +of the requested auxiliary properties. diff --git a/docsrc/sasl/developer/programming.rst b/docsrc/sasl/developer/programming.rst new file mode 100644 index 00000000..9ddc0440 --- /dev/null +++ b/docsrc/sasl/developer/programming.rst @@ -0,0 +1,1101 @@ +.. _programming: + +============================== +Application Programmer's Guide +============================== + +.. note:: + + NOTE: This is a work in progress. Any contributions would be + *very* appreciated. + +.. contents:: + :local: + +Introduction +============ + +About this Guide +---------------- + +This guide gives a tutorial on the use of the Cyrus SASL library +for a client or server application. It complies with versions +including and after 2.0.0. The following pages should only be +considered a guide, not the final word on programming with the +Cyrus SASL library. Consult the header files in the distribution in +the case of ambiguities. + +What is SASL? +------------- + +SASL stands for Simple Authentication Security Layer and is +defined in :rfc:`2222`. That document is very difficult to understand however and +it should be unnecessary to consult it. + +Background +========== + +How did the world work before SASL? +----------------------------------- + +Before SASL, when a new protocol was written which required +authentication (users proving who they are to an entity), the +protocol had to allow explicitly for each individual authentication +mechanism. There had to be a distinct way to say "I want to log in +with Kerberos V4". There had to be another distinct way to say "I +want to log in with CRAM-MD5". There had to be yet a different way +to say "I want to log in anonymously," and so on. This was +not ideal for both the protocol and application writers. + +Additionally, many programmers were not very familiar with +security, so the protocol did support many mechanisms, or worse, +they were supported incorrectly. Moreover, when a new +authentication method was invented the protocol needed to be +modified to support that mechanism. + +This system also was not ideal for application writer. She had +to have a special case for each mechanism she wished her +application to support. Also, the mechanisms were difficult to +implement. Even with a good library, an understanding of how the +mechanism worked was still necessary. Finally if an application +used more than one protocol (for example a mail client might use +IMAP, POP, and SMTP) then "Kerberos V4 for IMAP", "Kerberos V4 for +POP", "Kerberos V4 for SMTP", "CRAM MD5 for IMAP", "CRAM-MD5 for +POP", etc... would need to be written. This could quickly create a +huge number of different mechanism-protocol pairs to implement. + +SASL to the rescue! +------------------- + +SASL hopefully solves all these problems. In practice it makes +many of them easier to deal with. + +Protocol designers simply have to support SASL (in particular +:rfc:`2222`). Consequently, any mechanism that supports SASL (just +about anything you would want to use does now) is supported by the +protocol. If a new authentication mechanism is invented the +protocol automatically supports it without any modifications. + +Application writers, instead of having to support every +mechanism for every protocol, only need to support SASL for every +protocol. Application writers do not need to understand the +authentication mechanisms at all: the SASL library handles all +that. Also with the Cyrus SASL library if a new mechanism is +invented you do not have rewrite your application at all. You may +not even have to restart your application if it is a long running +process. This is because the Cyrus SASL library loads each +mechanism from a shared library. Simply copying a shared library +into a directory will magically make your application support a new +mechanism. + +Cyrus SASL version 2 supports a much improved API over version +1, that allows for much smarter and faster memory allocation for +the mechanisms as well as the applications. It is also provides for +several new types of plugins to allow for greater overall +flexibility. Unfortunately, though similar, this new API is +completely incompatible with the old API, and applications will +need to be rewritten. + +Briefly +======= + +What is the Cyrus SASL library good for? +---------------------------------------- + +The Cyrus SASL library is good for applications that wish to use +protocols that support SASL authentication. An non-exhaustive list +of these are: IMAP, SMTP, ACAP, and LDAP. Also if you are making a +proprietary system and wish to support authentication it is a good +way of supporting many different authentication types. + +What does the Cyrus SASL library do? +------------------------------------ + +From a client point of view, the Cyrus SASL library, given a +list of mechanisms the server supports it will decide the best +mechanism to use and tell you what to send to the server at each +step of the authentication. From a server perspective, it handles +authentication requests from clients. + +What doesn't the Cyrus SASL library do? +--------------------------------------- + +The Cyrus SASL library is neither network nor protocol aware. It +is up to the application to send the data over the wire as well as +to send the data in the protocol specific manner. With IMAP this +means putting it in the form: ``+ [base64'ed data]\\r\\n``. LDAP +just sends data in binary via bind requests. The Cyrus SASL library +has utility base64 encode and decode routines to help with +this. + +Client-only Section +=================== + +A typical interaction from the client's perspective +--------------------------------------------------- + + +* A client makes a few calls (explained later) to initialize + SASL. + +* Every time the client application makes a new connection it + should make a new context that is kept for the life of the + connection. + +* Ask the server for the list of supported mechanisms + +* Feed this list to the library + +* Start the authentication with the mechanism the library + chose + +* The server will return some bytes + +* Give these to the library + +* The library returns some bytes to the application + +* Application sends these bytes over the network + +* repeat the last 4 steps until the server tells you that the + authentication is completed + + +How does this look in code +-------------------------- + +1. Initialize the library +######################### + +This is done once. + +.. code-block:: c + + int result; + + /* attempt to start sasl + * See the section on Callbacks and Interactions for an + * explanation of the variable callbacks + */ + + result=sasl_client_init(callbacks); + + /* check to see if that worked */ + if (result!=SASL_OK) [failure] + +2. Make a new SASL connection +############################# + +For every network connection, make a new SASL connection: + +.. code-block:: c + + /* The SASL context kept for the life of the connection */ + sasl_conn_t *conn; + + + /* client new connection */ + result=sasl_client_new("imap", /* The service we are using */ + serverFQDN, /* The fully qualified domain + name of the server we're + connecting to */ + NULL, NULL, /* Local and remote IP + address strings + (NULL disables mechanisms + which require this info)*/ + NULL, /* connection-specific + callbacks */ + 0, /* security flags */ + &conn); /* allocated on success */ + + /* check to see if that worked */ + if (result!=SASL_OK) [failure] + + +3. Get the mechanism list +######################### + +Next get the list of SASL mechanisms the server supports. This is +usually done through a capability command. Format the list as a +single string separated by spaces. Feed this string into SASL to +begin the authentication process. + +.. code-block:: c + + sasl_interact_t *client_interact=NULL; + const char *out, *mechusing; + unsigned outlen; + + do { + + result=sasl_client_start(conn, /* the same context from + above */ + mechlist, /* the list of mechanisms + from the server */ + &client_interact, /* filled in if an + interaction is needed */ + &out, /* filled in on success */ + &outlen, /* filled in on success */ + &mechusing); + + if (result==SASL_INTERACT) + { + [deal with the interactions. See interactions section below] + } + + + } while (result==SASL_INTERACT); /* the mechanism may ask us to fill + in things many times. result is + SASL_CONTINUE on success */ + if (result!=SASL_CONTINUE) [failure] + + +Note that you do not need to worry about the allocation and freeing +of the output buffer out. This is all handled inside of the +mechanism. It is important to note, however, that the output buffer +is not valid after the next call to ``sasl_client_start`` or +``sasl_client_step``. + +If this is successful send the protocol specific command to +start the authentication process. This may or may not allow for +initial data to be sent (see the documentation of the protocol to +see). + +4. Start authentication +####################### + +* For IMAP this might look like:: + + {tag} "AUTHENTICATE" {mechusing}\r\n + A01 AUTHENTICATE KERBEROS_V4\r\n + +* SMTP looks like:: + + "AUTH" {mechusing}[ {out base64 encoded}] + AUTH DIGEST-MD5 GHGJJGDDFDKHGHJG= + + +.. _client_authentication_step: + +5. Check Results +################ + +Read what the server sent back. It can be one of three +things: + +1. Authentication failure. Authentication process is halted. This + might look like ``A01 NO Authentication failure`` in IMAP or + ``501 Failed`` in SMTP. Either retry the authentication or + abort. + +2. Authentication success. We're now successfully authenticated. + This might look like ``A01 OK Authenticated successful`` in + IMAP or ``235 Authentication successful`` in SMTP. Go :ref:`here `. + +3. Another step in the authentication process is necessary. This + might look like ``+ HGHDS1HAFJ=`` in IMAP or ``334 + PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4=`` + in SMTP. Note it could be an empty string such as ``+ \r\n`` + in IMAP. + + +Convert the continuation data to binary format (for example, this +may include base64 decoding it). Perform another step in the +authentication. + +.. code-block:: c + + do { + result=sasl_client_step(conn, /* our context */ + in, /* the data from the server */ + inlen, /* it's length */ + &client_interact, /* this should be + unallocated and NULL */ + &out, /* filled in on success */ + &outlen); /* filled in on success */ + + if (result==SASL_INTERACT) + { + [deal with the interactions. See below] + } + + + } while (result==SASL_INTERACT || result == SASL_CONTINUE); + + if (result!=SASL_OK) [failure] + + +Format the output (variable out of length outlen) in the protocol +specific manner and send it across the network to the server. + +Go :ref:`back to check results ` (this process +repeats until authentication either succeeds or fails. + +.. _client_authentication_success: + +6. Authentication Successful +############################ + +Before we're done we need to call sasl_client_step() one more +time to make sure the server isn't trying to fool us. Some +protocols include data along with the last step. If so this data +should be used here. If not use a length of zero. + +.. code-block:: c + + result=sasl_client_step(conn, /* our context */ + in, /* the data from the server */ + inlen, /* it's length */ + &client_interact, /* this should be unallocated and NULL */ + &out, /* filled in on success */ + &outlen); /* filled in on success */ + + if (result!=SASL_OK) [failure] + +Congratulations. You have successfully authenticated to the +server. + +Don't throw away the SASL connection object (sasl_conn_t \*) yet +though. If a security layer was negotiated you will need it to +encode and decode the data sent over the network. + +7. Cleaning up +############## + +When you are finally done with connection to server, dispose of +SASL connection. + +.. code-block:: c + + sasl_dispose(&conn); + + +If you are done with SASL forever (application quiting for +example): + +.. code-block:: c + + sasl_client_done(); + +Or if your application is both a SASL client and a SASL server: + +.. code-block:: c + + sasl_done(); + +But note that applications should be using sasl_client_done()/sasl_server_done() whenever possible. + +sasl_client_init +---------------- + +.. code-block:: c + + int sasl_client_init(const sasl_callback_t *callbacks) + +callbacks + List of :ref:`callbacks ` + +This function initializes the SASL library. This must be called +before any other SASL calls. + +sasl_client_new +--------------- + +.. code-block:: c + + int sasl_client_new(const char *service, + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *prompt_supp, + unsigned secflags, + sasl_conn_t **pconn) + +service + the service name being used. This usually is the + protocol name (e.g. "ldap") +serverFQDN + Fully qualified domain name of server +iplocalport and ipremoteport + a string of the format + "a.b.c.d;p" detailing the local or remote IP + and port, or NULL (which will disable + mechanisms that require this information) +prompt_supp + List of :ref:`callbacks ` specific to this + connection +secflags + security flags ORed together requested (e.g. + SASL_SEC_NOPLAINTEXT) +pconn + the SASL connection object allocated upon success + +This function creates a new SASL connection object. It should be +called once for every connection you want to authenticate for. + + +sasl_client_start +----------------- + +.. code-block:: c + + int sasl_client_start(sasl_conn_t *conn, + const char *mechlist, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + const char **mech); + +conn + the SASL connection object gotten from sasl_client_new() +mechlist + the list of mechanisms to try (separated by spaces) +prompt_need + filled in when a SASL_INTERACT is returned +clientout + filled in upon success with data to send to server +clientoutlen + length of that data +mech + filled in with mechanism being used + +This function starts an authentication session. It takes a list of +possible mechanisms (usually gotten from the server through a +capability command) and chooses the "best" mechanism to try. Upon +success clientout points at data to send to the server. + +sasl_client_step +---------------- + +.. code-block:: c + + int sasl_client_step(sasl_conn_t *conn, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen); + +conn + the SASL connection object gotten from sasl_client_new() +serverin + data from the server +serverinlen + length of data from the server +prompt_need + filled in with a SASL_INTERACT is returned +clientout + filled in upon success with data to send to server +clientoutlen + length of that data + +This step preforms a step in the authentication process. It takes +the data from the server (serverin) and outputs data to send to the +server (clientout) upon success. SASL_CONTINUE is returned if +another step in the authentication process is necessary. SASL_OK is +returned if we're all done. + +Server-only Section +=================== + +A typical interaction from the server's perspective +--------------------------------------------------- + +The server makes a few Cyrus SASL calls for initialization. When it +gets a new connection it should make a new context for that +connection immediately. The client may then request a list of +mechanisms the server supports. The client also may request to +authenticate at some point. The client will specify the mechanism +it wishes to use. The server should negotiate this authentication +and keep around the context afterwards for encoding and decoding +the layers. + +How does this look in code? +--------------------------- + +Initialization +############## + +This is done once. The application name is used for +reading configuration information. + +.. code-block:: c + + int result; + + /* Initialize SASL */ + result=sasl_server_init(callbacks, /* Callbacks supported */ + "TestServer"); /* Name of the application */ + + +This should be called for each new connection. It probably should +be called right when the socket is accepted. + +.. code-block:: c + + sasl_conn_t *conn; + int result; + + /* Make a new context for this connection */ + result=sasl_server_new("smtp", /* Registered name of service */ + NULL, /* my fully qualified domain name; + NULL says use gethostname() */ + NULL, /* The user realm used for password + lookups; NULL means default to serverFQDN + Note: This does not affect Kerberos */ + NULL, NULL, /* IP Address information strings */ + NULL, /* Callbacks supported only for this connection */ + 0, /* security flags (security layers are enabled + * using security properties, separately) + &conn); + + +When a client requests the list of mechanisms supported by the +server. This particular call might produce the string: ``{PLAIN, +KERBEROS_V4, CRAM-MD5, DIGEST-MD5}`` + +.. code-block:: c + + result=sasl_listmech(conn, /* The context for this connection */ + NULL, /* not supported */ + "{", /* What to prepend the string with */ + ", ", /* What to separate mechanisms with */ + "}", /* What to append to the string */ + &result_string, /* The produced string. */ + &string_length, /* length of the string */ + &number_of_mechanisms); /* Number of mechanisms in + the string */ + + +When a client requests to authenticate: + +.. code-block:: c + + int result; + const char *out; + unsigned outlen; + + result=sasl_server_start(conn, /* context */ + mechanism_client_chose, + clientin, /* the optional string the client gave us */ + clientinlen, /* and it's length */ + &out, /* The output of the library. + Might not be NULL terminated */ + &outlen); + + if ((result!=SASL_OK) && (result!=SASL_CONTINUE)) + [failure. Send protocol specific message that says authentication failed] + else if (result==SASL_OK) + [authentication succeeded. Send client the protocol specific message + to say that authentication is complete] + else + [send data 'out' with length 'outlen' over the network in protocol + specific format] + +When a response is returned by the client. ``clientin`` is the +data from the client decoded from protocol specific format to a +string of bytes of length ``clientinlen``. This step may occur +zero or more times. An application must be able to deal with it +occurring an arbitrary number of times. + +.. code-block:: c + + int result; + + result=sasl_server_step(conn, + clientin, /* what the client gave */ + clientinlen, /* it's length */ + &out, /* allocated by library on success. + Might not be NULL terminated */ + &outlen); + + if ((result!=SASL_OK) && (result!=SASL_CONTINUE)) + [failure. Send protocol specific message that says authentication failed] + else if (result==SASL_OK) + [authentication succeeded. Send client the protocol specific message + to say that authentication is complete] + else + [send data 'out' with length 'outlen' over the network in protocol + specific format] + + +This continues until authentication succeeds. When the connection +is concluded, make a call to ``sasl_dispose`` as with the +client connection. + +sasl_server_init +---------------- + +.. code-block:: c + + int sasl_server_init(const sasl_callback_t *callbacks, + const char *appname); + +callbacks + A list of :ref:`callbacks ` supported by the application +appname + A string of the name of the application. This string + is what is used when loading configuration options. + +sasl_server_init() initializes the session. This should be the +first function called. In this function the shared library +authentication mechanisms are loaded. + +sasl_server_new +--------------- + +.. code-block:: c + + int sasl_server_new(const char *service, + const char *serverFQDN, + const char *user_realm, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + unsigned secflags, + sasl_conn_t **pconn); + +service + The name of the service you are supporting. This + might be "acap" or "smtp". This is used by Kerberos mechanisms and + possibly other mechanisms. It is also used for PAM + authentication. +serverFQDN + This is the fully qualified domain name of the + server (i.e. your hostname); if NULL, the library calls + ``gethostbyname()``. +user_realm + The realm the connected client is in. The Kerberos + mechanisms ignore this parameter and default to the local Kerberos + realm. A value of NULL makes the library default, usually to the + serverFQDN; a value of "" specifies that the client should specify + the realm; this also changes the semantics of "@" in a username for + mechanisms that don't support realms. +iplocalport and ipremoteport + a string of the format + "a.b.c.d;p" detailing the local or remote IP and port, or NULL + (which will disable mechanisms that require this information) +callbacks + Additional :ref:`callbacks ` that you wish only to apply to + this connection. +secflags + security flags. +pconn + Context. Filled in on success. + +sasl_server_start +----------------- + +.. code-block:: c + + int sasl_server_start(sasl_conn_t *conn, + const char *mech, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +conn + The context for the connection +mech + The authentication mechanism the client wishes to try + (e.g. ``KERBEROS_V4``) +clientin + Initial client challenge bytes. Note: some protocols + do not allow this. If this is the case passing NULL is valid +clientinlen + The length of the challenge. 0 if there is none. +serverout + allocated and filled in by the function. These are + the bytes that should be encoded as per the protocol and sent over + the network back to the client. +serveroutlen + length of bytes to send to client + +This function begins the authentication process with a client. If +the program returns SASL_CONTINUE that means ``serverout`` +should be sent to the client. If SASL_OK is returned that means +authentication is complete and the application should tell the +client the authentication was successful. Any other return code +means the authentication failed and the client should be notified +of this. + +sasl_server_step +---------------- + +.. code-block:: c + + int sasl_server_step(sasl_conn_t *conn, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +conn + The context for the connection +clientin + Data sent by the client. +clientinlen + The length of the client data. Note that this may be 0 +serverout + allocated and filled in by the function. These are + the bytes that should be encoded as per the protocol and sent over + the network back to the client. +serveroutlen + length of bytes to send to client. Note that this may be 0 + +This function preforms a step of the authentication. This may need +to be called an arbitrary number of times. If the program returns +SASL_CONTINUE that means ``serverout`` should be sent to the +client. If SASL_OK is returned that means authentication is +complete and the application should tell the client the +authentication was successful. Any other return code means the +authentication failed and the client should be notified of this. + +sasl_listmech +------------- + +.. code-block:: c + + int sasl_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + unsigned *pcount); + +conn + The context for this connection +user + Currently not implemented +prefix + The string to prepend +sep + The string to separate mechanisms with +suffix + The string to end with +result + Resultant string +plen + Number of characters in the result string +pcount + Number of mechanisms listed in the result string + +This function is used to create a string with a list of SASL +mechanisms supported by the server. This string is often needed for +a capability statement. + +sasl_checkpass +-------------- + +.. code-block:: c + + int sasl_checkpass(sasl_conn_t *conn, + const char *user, + unsigned userlen, + const char *pass, + unsigned passlen); + +conn + The context for this connection +user + The user trying to check the password for +userlen + The user length +pass + The password +passlen + The password length + +This checks a plaintext password for a user. +Some protocols have legacy systems for plaintext authentication +where this might be used. + +Common Section +============== + +.. _callbacks: + +Callbacks and Interactions +-------------------------- + +When the application starts and calls sasl_client_init() you must +specify for what data you support callbacks and/or interactions. + +These are for the library getting information needed for +authentication from the application. This is needed for things like +authentication name and password. If you do not declare supporting +a callback you will not be able to use mechanisms that need that +data. + +A *callback* is for when you have the information before you +start the authentication. The SASL library calls a function you +specify and your function fills in the requested information. For +example if you had the userid of the user already for some reason. + +An *interaction* is usually for things you support but will need to +ask the user for (e.g. password). sasl_client_start() or +sasl_client_step() will return SASL_INTERACT. This will be a list +of sasl_interact_t's which contain a human readable string you can +prompt the user with, a possible computer readable string, and a +default result. The nice thing about interactions is you get them +all at once so if you had a GUI application you could bring up a +dialog box asking for authentication name and password together +instead of one at a time. + +Any memory that is given to the SASL library for the purposes of +callbacks and interactions must persist until the exchange +completes in either success or failure. That is, the data must +persist until ``sasl_client_start`` or +``sasl_client_step`` returns something other than +``SASL_INTERACT`` or ``SASL_CONTINUE``. + +Memory management + As in the rest of the SASLv2 API, + whoever allocates the memory is responsible for freeing it. In + almost all cases this should be fairly easy to manage, however a + slight exception where the interaction sasl_interact_t structure is + allocated and freed by the library, while the results are allocated + and freed by the application. As noted above, however, the + results may not be freed until after the exchange completes, in + either success or failure. + +For a detailed description of what each of the callback types +are see the sasl.h file. Here are some brief explanations: + +SASL_CB_AUTHNAME + the name of the user authenticating +SASL_CB_USER + the name of the user acting for. (for example + postman delivering mail for tmartin might have an AUTHNAME of + postman and a USER of tmartin) +SASL_CB_PASS + password for AUTHNAME +SASL_CB_GETREALM + Realm of the server + +An example of a way to handle callbacks: + +.. code-block:: c + + /* callbacks we support. This is a global variable at the + top of the program */ + static sasl_callback_t callbacks[] = { + { + SASL_CB_GETREALM, NULL, NULL /* we'll just use an interaction if this comes up */ + }, { + SASL_CB_USER, NULL, NULL /* we'll just use an interaction if this comes up */ + }, { + SASL_CB_AUTHNAME, &getauthname_func, NULL /* A mechanism should call getauthname_func + if it needs the authentication name */ + }, { + SASL_CB_PASS, &getsecret_func, NULL /* Call getsecret_func if need secret */ + }, { + SASL_CB_LIST_END, NULL, NULL + } + }; + + + static int getsecret_func(sasl_conn_t *conn, + void *context __attribute__((unused)), + int id, + sasl_secret_t **psecret) + { + [ask the user for their secret] + + [allocate psecret and insert the secret] + + return SASL_OK; + } + + static int getauthname_func(void *context, + int id, + const char **result, + unsigned *len) + { + if (id!=SASL_CB_AUTHNAME) return SASL_FAIL; + + [fill in result and len] + + return SASL_OK; + } + + +in the main program somewhere + +.. code-block:: c + + sasl_client_init(callbacks); + + +Security layers +--------------- + +All is well and good to securely authenticate, but if you don't +have some sort of integrity or privacy layer, anyone can hijack +your TCP session after authentication. If your application has +indicated that it can support a security layer, one might be +negotiated. + +To set that you support a security layer, set a security +property structure with ``max_ssf`` set to a non-zero +number: + +.. code-block:: c + + sasl_security_properties_t secprops; + + secprops.min_ssf = 0; + secprops.max_ssf = 256; + secprops.maxbufsize = /* SEE BELOW */; + + secprops.property_names = NULL; + secprops.property_values = NULL; + secprops.security_flags = SASL_SEC_NOANONYMOUS; /* as appropriate */ + + sasl_setprop(conn, SASL_SEC_PROPS, &secprops); + +The ``secprops`` variable will be copied during the call to +``sasl_setprop``, so you may free its memory immediately. The +SSF stands for "security strength factor" and is a +rough indication of how secure the connection is. A connection +supplying only integrity with no privacy would have an SSF of 1. A +connection secured by 56-bit DES would have an SSF of 56. + +To require a security layer, set ``min_ssf`` to the minimum +acceptable security layer strength. + +After authentication is successful, you can determine whether or +not a security layer has been negotiated by looking at the SASL_SSF +property: + +.. code-block:: c + + const int *ssfp; + + result = sasl_getprop(conn, SASL_SSF, (const **) &ssfp); + if (result != SASL_OK) { + /* ??? */ + } + if (*ssfp > 0) { + /* yay, we have a security layer! */ + } + +If a security layer has been negotiated, your application must +make use of the ``sasl_encode()`` and ``sasl_decode()`` +calls. All output must be passed through ``sasl_encode()`` +before being written to the wire; all input must be passed through +``sasl_decode()`` before being looked at by the application. +Your application must also be prepared to deal with +``sasl_decode()`` not returning any data in the rare case that +the peer application did something strange (by splitting a single +SASL blob into two seperate TCP packets). + +The only subtlety dealing with security layers is the maximum size +of data that can be passed through ``sasl_encode()`` or +``sasl_decode()``. This must be limited to make sure that only +a finite amount of data needs to be buffered. The simple rules to +follow: + +* Before starting authentication, set ``maxbufsize`` in your + security properties to be the buffer size that you pass to the + ``read()`` system call—that is, the amount of data + you're prepared to read at any one time. + +* After authentication finishes, use ``sasl_getprop()`` to + retrieve the ``SASL_MAXOUTBUF`` value, and call + ``sasl_encode()`` with chunks of data of that size or less. + ``sasl_encode()`` will throw an error if you call it with a + larger chunk of data, so be careful! + +Memory management + As usual, whoever allocates the memory + must free it. The SASL library will keep the data returned from + ``sasl_encode()`` until the next call to ``sasl_encode()`` + on that connection. (``sasl_decode()`` results persist until the + next call to ``sasl_decode()`` on that connection.) The + application must not attempt to free the memory returned from either + function. + +Internally + * your application sets SASL_SEC_PROPS with the buffer size X of + the amount of data it will be using to read() from the socket. + * libsasl passes this number to the mechanism. + * the mechanism passes this number to the other side. the other + side gives the corresponding read() size to our side. + * the mechanism subtracts the overhead of the layers from the + size retrieved from the other side and returns it to the + libsasl. + * libsasl then returns (via SASL_MAXOUTBUF) this number as the + maximum amount of plaintext material that can be encoded at any one + time, Y. + * sasl_encode() enforces the restriction of the length Y. + +Example applications that come with the Cyrus SASL library +========================================================== + +`sample-client` and `sample-server` +--------------------------------------- + +The sample client and server included with this distribution were +initially written to help debug mechanisms. They base64 encode all +the data and print it out on standard output. + +Make sure that you set the IP addresses, the username, the +authenticate name, and anything else on the command line (some +mechanisms depend on these being present). + +Also, sometimes you will receive a ``realm: Information +not available`` message, or similar; this is due to the fact +that some mechanisms do not support realms and therefore never set +it. + +Cyrus imapd v2.1.0 or later +--------------------------- + +The Cyrus IMAP server now incorporates SASLv2 for all its +authentication needs. It is a good example of a fairly large server +application. Also of interest is the prot layer, included in +libcyrus. This is a stdio-like interface that automatically takes +care of layers using a simple ``prot_setsasl()`` call. + +Cyrus imapd also sets a ``SASL_CB_PROXY_POLICY`` callback, +which should be of interest to many applications. + +`imtest`, from Cyrus 2.1.0 or later +------------------------------------- + +``imtest`` is an application included with Cyrus imapd. It is +a very simple IMAP client, but should be of interest to those +writing applications. It also uses the prot layer, but it is easy +to incorporate similar support without using the prot layer. +Likewise, there are other sample client applications that you can +look at including ``smtptest`` and ``pop3test`` in the +SASL distribution and the Cyrus IMAPd distribution, respectively. + +Miscellaneous Information +========================= + +Empty exchanges +--------------- + +Some SASL mechanisms intentionally send no data; an application +should be prepared to either send or receive an empty exchange. The +SASL profile for the protocol should define how to send an empty +string; make sure to send an empty string when requested, and when +receiving an empty string make sure that the ``inlength`` +passed in is 0. + +Note especially that the distinction between the empty string "" +and the lack of a string (NULL) is extremely important in many +cases (most notably, the client-send first scenario), and the +application must ensure that it is passing the correct values to +the SASL library at all times. + +Idle +---- + +While the implementation and the plugins correctly implement the +idle calls, none of them currently do anything. diff --git a/docsrc/sasl/developer/testing.rst b/docsrc/sasl/developer/testing.rst new file mode 100644 index 00000000..59016d63 --- /dev/null +++ b/docsrc/sasl/developer/testing.rst @@ -0,0 +1,95 @@ +.. _testing: + +======= +Testing +======= + +.. note:: + + This document is mainly useful for people doing libsasl development + or users having a lot of difficulty getting libsasl to work. + +Testing the CMU SASL Library with the included sample applications +================================================================== + +The CMU SASL library comes with two small sample programs: +sample-client and sample-server. Each of these programs dump base-64 +SASL iterations to STDOUT, and read the next iteration from STDIN. +Lines preceded by "C: " are from the client, and from "S: " are from +the server. + +This makes it fairly straightforward to test mechanisms; simply run +the sample-client on the "client" machine, and sample-server on the +"server" machine. + +Both programs take a -m MECH command line argument; this can be used +to force the mechanism used in the exchange. KERBEROS_V4 requires +that the IP addresses of both client and server be set, along with the +service name, and the server's fully-qualified hostname; these are +done through more command line arguments. + +Example +------- + +Here's the client side of an exchange. The mechanism selection code +chooses KERBEROS_V4; negotiation takes place, and the client is +authenticated. This is being run on the machine SPOOKY.ANDREW.CMU.EDU +(128.2.121.162), pretending to be talking to an "rcmd" service running +on port 23 (note the semicolons in the IP address. There is a strong +chance these will need to be escaped for proper interpretation by the shell): + +:: + + > ./sample-client -i local=128.2.121.162;23,remote=128.2.121.162;23 -s rcmd -n SPOOKY.ANDREW.CMU.EDU + Waiting for mechanism list from server... + S: UExBSU4gQU5PTllNT1VTIEtFUkJFUk9TX1Y0IERJR0VTVC1NRDUgQ1JBTS1NRDUgAAAAAED5EEA= + Choosing best mechanism from: PLAIN ANONYMOUS KERBEROS_V4 DIGEST-MD5 CRAM-MD5 + Using mechanism KERBEROS_V4 + Preparing initial. + Sending initial response... + C: S0VSQkVST1NfVjQA + Waiting for server reply... + S: hVQFjA== + Sending response... + C: BAYCQU5EUkVXLkNNVS5FRFUAOCDnIsZLQRdjLHXvzPNgpURYVj1iMqBIcTRaMpEQ8vWeYnfB+mTCVEa2URpkVgpzS1161MAX7ERzFV/EfGKlrAhGJCdN56mQ3eL2PzJlK7Z9ctKv4gKErcmV + Waiting for server reply... + S: BgcvFb63CLs= + Sending response... + C: ohBT+Jqab9zmDzclN7GSTw== + Negotiation complete + > + + +Here's the server side of the same dialog: + +:: + + > ./sample-server -s rcmd -i local=128.2.121.162;23,remote=128.2.121.162;23 + Generating client mechanism list... + Sending list of 5 mechanism(s) + S: UExBSU4gQU5PTllNT1VTIEtFUkJFUk9TX1Y0IERJR0VTVC1NRDUgQ1JBTS1NRDUgAAAAAED5EEA= + Waiting for client mechanism... + C: S0VSQkVST1NfVjQA + Sending response... + S: hVQFjA== + Waiting for client reply... + C: BAYCQU5EUkVXLkNNVS5FRFUAOCDnIsZLQRdjLHXvzPNgpURYVj1iMqBIcTRaMpEQ8vWeYnfB+mTCVEa2URpkVgpzS1161MAX7ERzFV/EfGKlrAhGJCdN56mQ3eL2PzJlK7Z9ctKv4gKErcmV + Sending response... + S: BgcvFb63CLs= + Waiting for client reply... + C: ohBT+Jqab9zmDzclN7GSTw== + Negotiation complete + Username: rob + Realm: ANDREW.CMU.EDU + SSF: 56 + > + + +Running the Testsuite application +================================= + +The Testsuite application in the utils directory tries out all the +functionality of libsasl against itself. When you run the application +it displays some requirments for running, such as being able to read +and write to the sasldb file. If this program is set up correctly and +still fails we'd like to hear about it at cyrus-bugs@andrew.cmu.edu. diff --git a/docsrc/sasl/faq.rst b/docsrc/sasl/faq.rst new file mode 100644 index 00000000..ac1651e8 --- /dev/null +++ b/docsrc/sasl/faq.rst @@ -0,0 +1,12 @@ +.. _sasl-faq: + +Frequently Asked Questions +========================== + +.. toctree:: + :maxdepth: 2 + :glob: + + faqs/* + +Looking for the :ref:`Cyrus IMAP FAQ `? \ No newline at end of file diff --git a/docsrc/sasl/faqs/authorize-vs-authenticate.rst b/docsrc/sasl/faqs/authorize-vs-authenticate.rst new file mode 100644 index 00000000..9a26d5f1 --- /dev/null +++ b/docsrc/sasl/faqs/authorize-vs-authenticate.rst @@ -0,0 +1,38 @@ +What is the difference between an Authorization ID and a Authentication ID? +--------------------------------------------------------------------------- + +**Authentication** is the act of proving who you are. "Hello, I'm Dave. To +prove it, here's my password: Foo." + +**Authorization** is the act of deciding +whether to grant access to resources. + +:: + + "I'd like to read Kellie's mail for her." + +In the example, I'm trying to read my wife's mail. I supply my own +username as the "authentication identifier", my own password (Or +biometric scan, or whatever else is required to prove I'm really me, +with whichever mechanism is in use), and my wife's username as the +"authorization identifier". + +At no point need I know my wife's password - instead, either Kellie or +an administrator needs to explicitly state that I am allowed in "as +Kellie". Once I've logged in, all the access checks are done against +Kellie, not against Dave, because I'm acting for her. To all intents and +purposes, after the authentication exchange itself, the server can +simply forget about who authenticated - it's not important any more - +and concentrate on who needs to be authorized. + +Another, more common example of the use of differing authentication +identifiers and authorization identifiers is in the design of many proxy +systems. You authenticate perfectly normally to the proxy, authorizing +as yourself. The proxy then authenticates to the master as itself, but +supplies you as the authorization identifier, thus getting all the right +access checks done at source, but not having to have access to your +authentication credentials. Finally, some mechanisms don't support +passing a distinct authorization identifier, and for most its optional, +and defaults to the case that most people are familiar with, where +authorization and authentication identifiers are the same. + diff --git a/docsrc/sasl/faqs/crammd5-digestmd5.rst b/docsrc/sasl/faqs/crammd5-digestmd5.rst new file mode 100644 index 00000000..84bf4d7b --- /dev/null +++ b/docsrc/sasl/faqs/crammd5-digestmd5.rst @@ -0,0 +1,14 @@ +Why do CRAM-MD5 and DIGEST-MD5 not work with CyrusSaslauthd? +------------------------------------------------------------ + +Saslauthd is only capable of verifying plaintext passwords (it takes a +plaintext password and a username and responds with "yes" or "no", +essentially). Therefore, since the plaintext password isn't passed from +client to server in DIGEST-MD5 and CRAM-MD5, Saslauthd can't verify the +password. + +Authentication in a CyrusSaslauthd-only environment will not only fail +with these mechanisms, it doesn't really make a lot of sense. You'll +want to use an AuxpropPlugin instead (for example, sasldb). + + diff --git a/docsrc/sasl/faqs/openldap-sasl-gssapi.rst b/docsrc/sasl/faqs/openldap-sasl-gssapi.rst new file mode 100644 index 00000000..8ece4e51 --- /dev/null +++ b/docsrc/sasl/faqs/openldap-sasl-gssapi.rst @@ -0,0 +1,81 @@ +How do I configure OpenLDAP +SASL+GSSAPI? +----------------------------------------- + +This article assumes that you have read and followed the SASL chapter of the `OpenLDAP Administrator's Guide `_. You should have a Kerberos server installed (such as Heimdal or MIT), and created all the appropriate principals (client and service) necessary. + +To verify that you have the Cyrus :ref:`GSSAPI ` mechanism properly installed, use the pluginviewer command. For instance:: + + server:~# pluginviewer | grep -i gssapi + CRAM-MD5 PLAIN NTLM GSSAPI OTP DIGEST-MD5 ANONYMOUS LOGIN EXTERNAL + Plugin "gssapiv2" [loaded], API version: 4 + SASL mechanism: GSSAPI, best SSF: 56, supports setpass: no + CRAM-MD5 PLAIN NTLM GSSAPI OTP DIGEST-MD5 ANONYMOUS LOGIN EXTERNAL + Plugin "gssapiv2" [loaded], API version: 4 + SASL mechanism: GSSAPI, best SSF: 56 + +Both your server and client systems will need to have this mechanism installed. If not, you may find the mechanism located in a binary package that you do not yet have installed, or you may need to recompile your Cyrus SASL installation. + +On your client system, search the Root DSE of the server to view advertised mechanisms:: + + client:~# ldapsearch -LLL -x -H ldap://ldap.example.org -s "base" -b "" supportedSASLMechanisms + dn: + supportedSASLMechanisms: DIGEST-MD5 + supportedSASLMechanisms: NTLM + supportedSASLMechanisms: GSSAPI + supportedSASLMechanisms: OTP + supportedSASLMechanisms: CRAM-MD5 + +If you received a No Such Object error, you may have an `ACL misconfiguration on your server `_. + +If you do not see GSSAPI listed, verify that the server can read the appropriate keytab. The default is ``/etc/krb5.keytab`` and is typically only readable by the root user. If your Kerberos library supports it, you can create a keytab in an alternate location, such as ``/etc/krb5.keytab-ldap``, with only your LDAP service principal, and read permissions for your OpenLDAP user. + +If your OpenLDAP server is looking for an unexpected principal within your keytab, use sasl-host and sasl-realm to influence which principal it will use (see the slapd.conf man page). + +For more control over how the SASL library operates within the OpenLDAP? server, you can create a slapd.conf SASL configuration. This is not the same configuration file as the OpenLDAP configuration (slapd.conf). The location of this file is dependent how on Cyrus SASL was compiled (via the ``--with-plugindir`` option during configure). It is the directory where your plugins are installed. + +For instance, if you create /usr/lib/sasl2/slapd.conf (assuming that is the correct location on your system) with the following contents:: + + keytab: /etc/krb5.keytab-ldap + mech_list: CRAM-MD5 DIGEST-MD5 GSSAPI + +then the server will search within /etc/krb5.keytab-ldap when initializing the GSSAPI plugin. The server will only offer the mechanisms listed in mech_list. If mech_list is not specified, the server will offer all the mechanisms available, and that it can initialize. + +Once you have verified that the server is advertising GSSAPI support, then try:: + + client:~# ldapsearch -LLL -Y GSSAPI -H ldap://ldap.example.org -s "base" -b "" supportedSASLMechanisms + SASL/GSSAPI authentication started + SASL username: host/client.example.org@EXAMPLE.ORG + SASL SSF: 56 SASL data security layer installed. + dn: + supportedSASLMechanisms: DIGEST-MD5 + supportedSASLMechanisms: NTLM + supportedSASLMechanisms: GSSAPI + supportedSASLMechanisms: OTP + supportedSASLMechanisms: CRAM-MD5 + +If you receive a list of mechanisms, then congratulations, you're done. + +If instead you receive an error, then it's possible that your client is requesting a service principal that mismatches what your server is using. + +Verify that you have received a TGT ticket from your kerberos server, and that you have also received a service principal ticket for the server (e.g. ldap/ldap.example.org@EXAMPLE.ORG). Use klist to verify:: + + client:~# klist + Credentials cache: FILE:/tmp/krb5cc_0 + Principal: host/client.example.org@EXAMPLE.ORG + Issued Expires Principal + Feb 22 11:00:02 Feb 22 21:00:01 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG + Feb 22 11:24:39 Feb 22 21:00:01 ldap/ldap.example.org@EXAMPLE.ORG + +If not, then a network capture utility, such as wireshark, offers a good way to show you which service principal your client is requesting, and what errors are being returned by the server. + +If you wish to also view the interaction with the LDAP server with a capture utility, you will need to negotiate a SASL layer without encryption. You can specify ``-O maxssf=1`` in your client side command (ldapwhoami, ldapsearch etc.), e.g.:: + + client:~# ldapsearch -LLL -Y GSSAPI -H ldap://ldap.example.org -O maxssf=1 -s "base" -b "" supportedSASLMechanisms + +You might find it easier to specify defaults on your client system, to keep your commands shorter. See the man page for ldap.conf for details. You can specify the default server in your ldap.conf file:: + + URI ldap://ldap.example.org + +And you can specify the default mechanism in ~/.ldaprc (in your home directory): + + ASL_MECH GSSAPI diff --git a/docsrc/sasl/faqs/plaintextpasswords.rst b/docsrc/sasl/faqs/plaintextpasswords.rst new file mode 100644 index 00000000..5db69a1f --- /dev/null +++ b/docsrc/sasl/faqs/plaintextpasswords.rst @@ -0,0 +1,20 @@ +Why does CyrusSasl store plaintext passwords in its databases? +-------------------------------------------------------------- + +To operate with the CRAM-MD5 and DIGEST-MD5 mechanisms, Cyrus SASL +stores plaintext versions of the passwords in its secret database (an +AuxpropPlugin). + +This is typically regarded as insecure practice, however the alternative +is not much better. For CRAM-MD5 and DIGEST-MD5 to function, they must +have a plaintext equivalent locally in order to confirm the hash that +actually goes across a wire. This, if these equivalents were +compromised, it is trivially easy for an attacker to have access to any +account on the system. + +Note that for DIGEST-MD5 this isn't strictly true: the hash that DIGEST +can use limits the attack to only the realm for which the password +applies, but this is a questionable security gain for the increased +management hassles (you can't share them between mechanisms) that the +plaintext equivalents cause. + diff --git a/docsrc/sasl/faqs/rfcs.rst b/docsrc/sasl/faqs/rfcs.rst new file mode 100644 index 00000000..0c3ed2b2 --- /dev/null +++ b/docsrc/sasl/faqs/rfcs.rst @@ -0,0 +1,25 @@ +.. _faq-rfcs: + +=============== +RFCs and drafts +=============== + +* :rfc:`4422` - Simple Authentication and Security Layer (SASL) +* `draft-newman-sasl-c-api `_ - The SASL C API +* :rfc:`7613` - Preparation, Enforcement, and Comparison of Internationalized Strings Representing Usernames and Passwords +* :rfc:`4846#section-4` - Base64 Data Encoding + +* :rfc:`4505` - Anonymous Simple Authentication and Security Layer (SASL) Mechanism +* :rfc:`4616` - The PLAIN Simple Authentication and Security Layer (SASL) Mechanism +* :rfc:`4752` - The Kerberos V5 ("GSSAPI") Simple Authentication and Security Layer (SASL) Mechanism +* :rfc:`5801` - Using Generic Security Service Application Program Interface (GSS-API) Mechanisms in SASL: The GS2 Mechanism Family +* :rfc:`5802` - Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms +* :rfc:`2444` - The One-Time-Password SASL Mechanism (OTP) +* :rfc:`2808` - The SecurID(r) SASL Mechanism +* :rfc:`2831` - Using Digest Authentication as a SASL Mechanism (historic: :rfc:`6331`) +* :rfc:`2222#section-7.1` - Simple Authentication and Security Layer (SASL) (KERBEROS_V4) +* `draft-ietf-sasl-crammd5 `_ - The CRAM-MD5 SASL Mechanism (CRAM-MD5) +* `draft-murchison-sasl-login `_ - The LOGIN SASL Mechanism +* `draft-burdis-cat-srp-sasl `_ - Secure Remote Password SASL Mechanism (SRP) +* `draft-newman-sasl-passdss `_ - DSS Secured Password Authentication Mechanism (PASSDSS) +* :rfc:`1939#page-15` - Post Office Protocol - Version 3 (APOP/sasl_checkapop) diff --git a/docsrc/sasl/faqs/upgrade-saslv2.rst b/docsrc/sasl/faqs/upgrade-saslv2.rst new file mode 100644 index 00000000..a13b402d --- /dev/null +++ b/docsrc/sasl/faqs/upgrade-saslv2.rst @@ -0,0 +1,22 @@ +Why am I having a problem running dbconverter-2 to upgrade from SASLv1 to SASLv2? +--------------------------------------------------------------------------------- + +The migration is documented in the official documentation. + +When migrating the ``/etc/sasldb`` database using the ``utils/dbconverter-2`` +utility, you may encounter the error message "Error opening password +file". This is usually due to the fact your SASL V1 library was compiled +using a different version of Berkeley DB than the SASL V2 library. You +can work around this by using Berkeley DB's db_upgrade utility (possibly +chaining the DB3 and DB4 upgrade utilities) to upgrade a copy of sasldb +prior to conversion using dbconverter-2. + +Here is the script we use at our installation, where SASL has to coexist with SASL2:: + + #!/bin/sh + cp /etc/sasldb /tmp/sasldb.$$ + /usr/local/BerkeleyDB.4/bin/db_upgrade /etc/sasldb + echo ""|/usr/local/sasl/sbin/dbconverter-2 + cp /tmp/sasldb.$$ /etc/sasldb + + diff --git a/docsrc/sasl/gssapi.rst b/docsrc/sasl/gssapi.rst new file mode 100644 index 00000000..59b02d34 --- /dev/null +++ b/docsrc/sasl/gssapi.rst @@ -0,0 +1,203 @@ +.. _gssapi: + +================================= +Configuring GSSAPI and Cyrus SASL +================================= + +This document was contributed by `Ken Hornstein `_ and updated +by `Alexey Melnikov `_. + +A couple of people have asked me privately, "Hey, how did you get the +GSSAPI mechanism to work? I tried, but the sample apps kept failing". +(The short answer: I'm a tenacious bastard). + +I figured that it couldn't hurt to give a quick explanation as to +how you get GSSAPI working with the sample apps, since it wasn't +obvious to me, and I consider myself not completely ignorant of GSSAPI +and Kerberos. + +Compile Cyrus SASL with GSSAPI +============================== + +Compile the Cyrus-SASL distribution with the GSSAPI plugin +for your favorite GSS-API mechanism. I personally use the GSSAPI +libraries included with the `MIT Kerberos 5 distribution `_; +`Heimdal `_ +and `CyberSafe `_ work as well. + +Start sample server +=================== + +The command-line used for +sample-server needs to specify the GSSAPI service name and the +location of the plug-ins. + +* On Unix: ``./sample-server -s host -p ../plugins/.libs`` +* On Windows: ``sample-server -s host -p ..\plugins`` + +In this example, I am using "host", which already exists on my +machine, but only root can read it, so I an running this as root. +If you want to use an alternate service name, you will need to +create that service in Kerberos, place it in a keytab readable by +you, and point your Kerberos library at it. + +* On Unix: Unix: both MIT Kerberos and Heimdal, use ``/etc/krb5.keytab`` on Unix by default, but this can be changed + by setting the ``KRB5_KTNAME`` environment variable; the default + for CyberSafe Kerberos is ``/krb5/v5srvtab`` for UNIX systems and can be + changed by setting the ``CSFC5KTNAME`` environment variable. +* On Windows: the default service key table location for CyberSafe is + ``C:\Program Files\CyberSafe\v5srvtab``, unless the + CyberSafe registry setting for the KeyTab key is set to an + alternate path. MIT Kerberos on Windows uses the keytab filename + krb5kt. + +You should get a response similar to: + +:: + + Generating client mechanism list... + Sending list of 3 mechanism(s) + S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw== + +Note that later on (assuming everything works) you might need to paste +in lines that are longer than canonical input processing buffer on your +system. You can get around that by messing around with stty; while +the details vary from system to system, on Solaris you can do something +like: + +:: + + ( stty -icanon min 1 time 0 ; ./sample-server -s host -p ../plugins/.libs ) + +Obtain Kerberos ticket +====================== + +Obtain a Kerberos ticket for the user you want to authenticate as. + +:: + + kinit kenh + +Start up sample client +====================== + +You need to specify the service +name, the hostname, and the userid. An example might be + +:: + + ./sample-client -s host -n your.fqdn.here -u kenh -p ../plugins/.libs + +You should get a response similar to this: + +:: + + Waiting for mechanism list from server... + +Connect Server to Client +======================== + +Cut-and-paste the initial mechanism line from the server process +(this includes the `` S: `` ) into the client process. You +should get something similar to: + + +:: + + S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw== + Choosing best mechanism from: GSSAPI PLAIN ANONYMOUS + Using mechanism GSSAPI + Preparing initial. + Sending initial response... + C: <.... lots of base 64 data ...> + Waiting for server reply... + +If GSSAPI isn't selected as the mechanism, there is a few things that +might have gone wrong: + +* The mechanism might not have been offered by the server. The decoded + mechanism list offered by the server appears in the "``Choosing best + mechanism``" line. If GSSAPI didn't appear in that list, then + something is wrong on the server. Make sure that you specified the + correct plugins directory. If the plugin directory is correct, but + the library fails to load, you might be running across a bug + in libtool on some platforms. If you have your Kerberos/gssapi + libraries not installed in the system library path, those libraries + are likely not able to be found when the SASL GSSAPI plugin loads. + + The solution varies from system to system; what I did was take + the linker line generated by libtool and run it by hand, adding + a ``-R/path/to/kerberos/libraries`` switch (this was on Solaris). + You can check with a system call tracer to see exactly what it is + trying to do. + +* The client doesn't know about the mechanism. The reasons for this + happening are the same as the server: check the -p switch, check + to make sure the correct libraries are being loaded with the GSSAPI + plugin. + + You can turn on a healthy amount of debugging information by changing + the definition in config.h of the VL macro to (and recompiling libsasl): + +:: + + #define VL(foo) printf foo; + +There is a possibility +you might get an error that looks like this: + + :: + + sample-client: Starting SASL negotiation: generic failure + +This can mean that you didn't provide all of the required information +to the sample-client (did you provide a service name with -s, the +hostname of the service with -n, and a username with -u ?), or that +GSSAPI has failed (unfortunately, on the client you cannot find out +the internal GSSAPI error; you will need to break out the debugger +for that). + +Connect Client to Server +======================== + +Cut and paste the client response (The *entire* line that begins +with C:, including the initial ``C:`` ) to the server +process. You should get a response back that starts with ``S:`` . +Cut and paste that to the client, and continue this +exchange until you either get ``Negotiation complete``, or an error. + +If you get an error on the server you should get a complete error +message (including the GSSAPI error string); on the client you +unfortunately will only probably get ``generic failure``, which will +again require the use of a debugger (but the VL macro should help +with this). + +One common thing that happens is that on your server you might see +the error: + +:: + + sample-server: Performing SASL negotiation: authentication failure + (Requested identity not authenticated identity) + +This comes from not having a requested identity (the -u option) that +matches the identity that you were authenticated to via the GSSAPI. +This is of course mechanism specific, but if for example you're using +Kerberos, the Cyrus SASL library strips out the @REALM from your +identity if you are in the same realm as the server. So if your +Kerberos identity is user\@SOME.REALM and the server is in SOME.REALM, +you need to specify "user" to the -u flag of the client. If you're +accessing a server in a foreign realm, you need to pass the full +principal name via the -u option to make this work correctly. + +If you complete the negotiation successfully, you should see something +that looks like (on both the client and server): + +:: + + Negotiation complete + Username: kenh + sample-server: realm: can't request info until later in exchange + SSF: 56 + +If you get to that, then you've done it, and GSSAPI works successfully! diff --git a/docsrc/sasl/installation.rst b/docsrc/sasl/installation.rst new file mode 100644 index 00000000..d9e0cce9 --- /dev/null +++ b/docsrc/sasl/installation.rst @@ -0,0 +1,238 @@ +.. _installation: + +============ +Installation +============ + +Are you looking for the: + +* :ref:`Quick install ` guide, or +* :ref:`Detailed installation instructions for compiling from source ` + +.. _installation_quick: + +Quick install guide +=================== +You can install Cyrus SASL via packages or via tarball. + +Tarball installation +-------------------- + +Fetch the latest Cyrus SASL tarball from ftp://ftp.cyrusimap.org/cyrus-sasl/ + +Untar it then:: + + cd (directory it was untarred into) + ./configure + make + make install + ln -s /usr/local/lib/sasl2 /usr/lib/sasl2 + + +Contributors will want to `compile from source`_. + +.. _compile from source: developer/installation.html + +Unix package Installation +------------------------- + +Are you `upgrading from Cyrus SASLv1`_? + +Please see the file install.php for instructions on how to install this package. + +Note that the library can use the environment variable SASL_PATH to locate the directory where the mechanisms are; this should be a colon-separated list of directories containing plugins. Otherwise it will default to the value of `--with-plugindir` as supplied to `configure` (which itself defaults to `/usr/local/lib`). + +Extra information for :ref:`Mac OSX installation `. + +Extra information for :ref:`Windows installation `. This configuration has not been extensively tested. + +Configuration +------------- + +There are two main ways to configure the SASL library for a given application. The first (and typically easiest) is to make use of the application's configuration files. Provided the application supports it (via the `SASL_CB_GETOPT` callback), please refer to that documetation for how to supply SASL options. + +Alternatively, Cyrus SASL looks for configuration files in `/usr/lib/sasl/Appname.conf` where Appname is settable by the application (for example, Sendmail 8.10 and later set this to "Sendmail"). + +Configuration using the application's configuration files (via the getopt callback) will override those supplied by the SASL configuration files. + +For a detailed guide on configuring libsasl, please look at sysadmin.php and options.php + +.. _upgrading from Cyrus SASLv1: + + +.. _installation_detailed: + +Detailed installation guide +=========================== + +Before reading this section, please be sure you are comfortable with +the concepts presented in the :ref:`components ` guide +and in the :ref:`Quickstart ` guide. + +You will want to have answered the following questions about your intended +installation: + + +1. What mechanisms do you want to support? Are they plaintext (LOGIN, PLAIN), +shared secret (DIGEST-MD5, CRAM-MD5), or Kerberos (KERBEROS_V4, GSSAPI)? +Perhaps you will use some combination (generally plaintext with one of +the other two types). +2. Given the answer to the previous question, how will the mechanisms +perform user verification? + + * Kerberos mechanisms just need your existing Kerberos infrastructure. + * The shared secret mechanisms will need an auxprop plugin backend. + * The plaintext mechanisms can make do with saslauthd, Courier authdaemond (not included), *or* by using an auxprop plugin backend. + * To use Kerberos and Plaintext, you'll want to use saslauthd with a kerberos module for plaintext authentication. To use Shared Secret and plaintext, you'll want to use the auxprop plugin for password verification. + +3. If you are using an auxprop plugin, will you be using SASLdb (and +if so, Berkeley DB [recommended], GDBM, or NDBM?), LDAP or an SQL backend +(Postgres? MySQL?). +4. If you are using saslauthd, what module will you be using? LDAP? +Kerberos? PAM? +5. Also if you are using saslauthd, what communication (IPC) method do +you want to use? On most systems, the correct answer is the default +(unix sockets), but on Solaris you can use IPC doors, which have proven +to be more stable than equivilant Solaris systems using unix sockets. + +Once you have answered these questions, properly configuring a working +configuration of Cyrus SASL becomes easier. + +Requirements +------------ + +1. You'll need the source from https://github.com/cyrusimap/cyrus-sasl + +2. You'll need `GNU make `_. + +3. If you are using SASLdb, you will need to pick your backend. + libsasl2 can use `gdbm `_, `Berkeley db `_, or ndbm to implement its user/password lookup. Most systems come with ndbm. + +4. If you are using SQL, you'll need to properly configure your server/tables, + and build the necessary client libraries on the system where you will be + building and using SASL. Currently we support `PostgreSQL `_ v7.2 (or higher) + and `MySQL `_. + +5. If you are using LDAPDB, you'll need SASL enabled `OpenLDAP `_ libraries. + v2.1.27 (or higher) or v2.2.6 (or higher) is supported. + +6. For Kerberos support, you'll need the `kerberos `_ libraries. + +7. For GSSAPI support you will need either `MIT Kerberos 5 `_, + the `Heimdal `_ or `CyberSafe `_. + +Build Configuration +------------------- + +Once you have answered all the necessary questions and installed +(and tested!) any required packages for your configuration, you are +ready to build SASL. Building SASL is done with the aid of +an autoconf ``configure`` script, which has a *lot* of options. +Be sure to read the output of ``configure --help`` to be sure you +aren't missing any. Note that an ``--enable-foo`` option has a counterpart ``--disable-foo`` +to not enable that feature. + +Some of the most important configuration options are those which allow +you to turn off the compilation of modules you do not need. This is often +the easiest way to solve compilation problems with Cyrus SASL. +If you're not going to need a particular mechanism, don't build it! Not +building them can also add performance improvements as it does take system +resources to load a given plugin, even if that plugin is otherwise unused +(even when it is disabled via the :option:`mech_list` option). + +As of this writing, modules that are enabled by default but may not +be applicable to all systems include CRAM-MD5, DIGEST-MD5, OTP, KERBEROS_V4, +GSSAPI, PLAIN, and ANONYMOUS. These can be disabled with:: + + ``--disable-cram``, + ``--disable-digest``, ``--disable-otp``, + ``--disable-krb4``, ``--disable-gssapi``, + ``--disable-plain``, and ``--disable-anon`` respecively. + +If you are using an SQL auxprop plugin, you may want to specify one or more +of ``--enable-sql``, ``--with-mysql=PATH``, and +``--with-pgsql=PATH``, note that PATH in the later two should be replaced +with the path where you installed the necessary client libraries. + +If you are using LDAPDB auxprop plugin, you will need to specify +``--enable-ldapdb`` and ``--with-ldap=PATH``. Warning: LDAPDB +auxprop plugin (and LDAP enabled saslauthd) introduces a circular dependency +between OpenLDAP and SASL. I.e., you must have OpenLDAP already built when +building LDAPDB in SASL. In order for LDAPDB to work at runtime, you must have +OpenLDAP already built with SASL support. One way to solve this issue is to +build Cyrus SASL first without ldap support, then build OpenLDAP, and then come +back to SASL and build LDAPDB. + +Given the myriad of ways that Berkeley DB can be installed on a system, +people useing it may want to look at the ``--with-bdb-libdir`` and +``--with-bdb-incdir`` as alternatives to ``--with-dbbase`` for +specifying the paths to the Berkeley DB Library and Include directories. + +In fact, if you're not planning on using SASLdb at all, it may be worth +your time to disable its use entirely with the ``--with-dblib=none`` +option. + +If you are planning on using LDAP with saslauthd, be sure to specify +the ``--with-ldap=PATH`` option to ``configure``. + +Building and Installation +------------------------- + +After configure runs, you should be able to build SASL just by +running ``make``. If this runs into problems, be sure that you +have disabled everything that your system doesn't need, and that you have +correctly specified paths to any dependencies you may have. + +To install the library, run ``make install`` as ``root`` followed by +``ln -s /usr/local/lib/sasl2 /usr/lib/sasl2`` (modified for your +installation path as appropriate). Be sure to do this last step or +SASL will not be able to locate your plugins! + +Compilation Hints +----------------- + +You may need to play with your CPPFLAGS and LDFLAGS if you're +using vendor compilers. We use ``gcc`` extensively, but you'll +probably have more luck if you use the same compiler for the library +as you do for your applications. You can see what compilers we use on +our platforms by looking at the "SMakefile". + +Application Configuration +------------------------- + +Plesae read about the :ref:`SASL Options ` to learn what +needs to be configured so that applications can successfully use the SASL +library. + +You will want to ensure that the settings of ``pwcheck_method`` +and ``auxprop_plugin`` match the decisions you made about your +authentication infrastructure. (For example, if you are using +saslauthd as a password verifier, you'll want to be sure to set +``pwcheck_method: saslauthd``). + +If you are using saslauthd, you will want to arrange for +``saslauthd -a pam`` (or ldap, or kerberos4, etc) to be run +at boot. If you are not going to be using saslauthd, then this is +not necessary. + +Many of these pieces are covered in more detail in the +:ref:`SASL System Administrator's Guide `. + +Supported platforms +=================== + +This has been tested under Linux 2.2, Linux 2.4, Solaris 2.7 and +Solaris 2.8. It should work under any platform where dynamic objects +can be linked against other dynamic objects, and where the dynamic +library file extension is ".so", or where libtool creates the .la +files correctly. There is also documentation for +:ref:`Win32 `, :ref:`MacOS X `, and +:ref:`OS/390 `. + +.. toctree:: + :hidden: + + developer/installation + macosx.rst + windows.rst + os390.rst diff --git a/docsrc/sasl/macosx.rst b/docsrc/sasl/macosx.rst new file mode 100644 index 00000000..1f2491cd --- /dev/null +++ b/docsrc/sasl/macosx.rst @@ -0,0 +1,211 @@ +.. _install-macos: + +========================================= +Building and using Cyrus SASL on Mac OS X +========================================= + +The Cyrus SASL v2 distribution now supports Mac OS X, including +applications written to Apple's Carbon and Cocoa interfaces, as well +as the standard Unix-like API. It includes the following +components: + +* A port of the Unix SASL library, which lives in ``/usr/local/lib/libsasl2.dylib`` + (or similar) and with plugins in ``/usr/lib/sasl`` (which should be a symlink to ``/usr/local/lib/sasl``). +* A framework which lives in + ``/Library/Frameworks/SASL2.framework``, and allows the use of the + ``-framework`` option to Apple's ``ld``, or linking with the + framework in Project Builder. This framework is in fact a wrapper for a + symlink to ``/usr/local/lib/libsasl2.dylib`` with the necessary + information to recognize it as a framework. This is what we expect many + Cocoa and Carbon Mach-O applications will want to use, and the framework + is required for CFBundle to work, which is used by the CFM glue library. +* A CFM glue library (``/Library/CFMSupport/SASL2GlueCFM``) which + can be linked in by Carbon CFM applications, that uses CFBundle to bind + the framework and thus load the Unix-level library. It automatically loads + the important functions at ``sasl_client_init`` or + ``sasl_server_init`` time; it also automatically makes sure memory + allocation works if you're using the metrowerks malloc; if you're not, + ``sasl_set_alloc`` works as usual. +* A Carbon port of the existing CFM library for Mac OS 9. Note that + this could probably be modified fairly easily to work on OS X, but + there's not much point. The CFM glue layer to the Unix library + supports many more functions, including the entire server API; also, + the Unix implementation is mostly independent of Kerberos + implementation, while the Mac OS 9 Carbon port specifically requires + MIT Kerberos for Macintosh 3.5 or later in order to get Kerberos + support. The Mac OS 9 code implements only the client API, but this is + mostly what is wanted from SASL on OS 9 anyway. + +If you are building a Carbon CFM application and intend it to run on +both OS 9 and OS X, you should link against the OS 9 Carbon SASL +library, since it exports fewer APIs (client side only, specifically) +than the OS X CFM glue. Your application should work seamlessly with +both libraries if you do this, despite the different implementations +underneath. + +If you need a Carbon CFM application to support server-side SASL +functionality, you need to link against the ``SASL2GlueCFM`` +library, but be aware that your application will not run on OS 9. + +Compiling and Using the Unix library +==================================== + +The Unix library is mostly ready to build on Mac OS X, but it does depend +on the ``dlcompat`` package in order to load its plugins. +``dlcompat-20010505`` is a relatively simple version known to work +with SASL; it is provided with the distribution in a tarball. You should +``make`` and ``make install`` the ``dlcompat`` library +(which probably goes into ``/usr/local/lib/libdl.dylib``) before +attempting to ``./configure`` the SASL distribution itself. SASL will +then pretend it's a real Unix ``libdl``, and link against it. + +Since there are, at this point, newer and far more complex versions of +dlcompat, you may prefer to use those instead if other software requires +their functionality. The dlcompat homepage is located on the `OpenDarwin `_ +site. Many users may want to install the ``/sw`` tree from `the Fink project `_ to get this, as +well as possibly newer autotools and other software. + +As of version 2.1.16, SASL uses and requires a recent version of GNU +autotools (autoconf, automake, and libtool) to build its configuration scripts. +If you are building from GIT, you will need to have the autotools installed +on your system. The version included with all releases of the developer tools +for OS X 10.2.x is too old for this; if you aren't using OS X 10.3 or later, +you should upgrade to more recent patchlevels of these tools. The easiest way +to do this is to install the Fink environment and then ``apt-get +install autoconf2.5 automake1.7 libtool14``. + +Recent versions of SASL ship with Kerberos v4 disabled by default. +If you need Kerberos v4 for some reason, and you are using MIT Kerberos +for Macintosh 4.0 or later, you should ``./configure`` with +the added options ``"--enable-krb4=/usr --without-openssl +--disable-digest"`` so that it finds the +correct location for the header files, and does not use OpenSSL or +build anything that depends on it (such as the digest-md5 plugin), +since OpenSSL provides its own DES routines which do not work with +Kerberos v4. + +.. warning:: + + Please read the "Known Problems" section at the end of + this document for more information on this issue. + +You must be root to make install, since ``/usr/local`` is only +modifiable by root. You need not enable the root account using +NetInfo; the recommended (but underdocumented) method is to use +``sudo -s`` from the Terminal window when you are logged into an +administrator's account, and enter the password for that account. When +building on Mac OS X, ``make install`` will automatically add the +framework to ``/Library/Frameworks``. + +This does not build the CFM glue library. Building the CFM glue +library requires Metrowerks CodeWarrior Pro 6 or later (tested with +6), and the files necessary to build it are in the +``mac/osx_cfm_glue`` folder. + +Changes to the Unix library to make it work on OS X +=================================================== + +This is provided for reference purposes only. The build system will +automatically take care of all of these issues when building on Darwin +or Mac OS X. + +* The random code supports the preferred way to generate random + numbers in Darwin. (In SASL v2, it does this on all unix-like + platforms that lack jrand48). *Note that Mac OS X "Jaguar", version + 10.2, + now has the standard jrand48 function, and that SASL will use this + instead + of the previous workaround.* +* Symbols which are dlopened have an underscore prefixed. (This + behavior is detected by configure in SASL v2.) +* Plugins are linked with the ``-module`` option to ``libtool``, + which causes the ``-bundle`` option to be + supplied to Apple's ``ld``. (This is done on all platforms in + SASL v2.) +* The MD5 symbols are renamed to avoid library conflicts. This + allows proper compilations against Heimdal and MIT's unix kerberos + distribution, and prevents crashes when linked against MIT Kerberos + for Macintosh (which also duplicates the symbols, but in a different + way). Note that the MD5 symbols have local names on all platforms with + SASL v2; this was only different in SASL v1. +* MIT Kerberos for Macintosh 4.0 and later are fully supported. This + was accomplished by using ``krb_get_err_text`` if available and + checking for additional names for the krb4 libraries. + +Changes to the Mac OS 9 projects to support Carbon +================================================== + +.. warning:: + + Please read these notes before you attempt to build SASL for OS 9 Carbon! + +* **Important!** You must make sure that all files have their + correct HFS filetype before starting to build this code! In + particular, all source and text files must be of type ``'TEXT'``, + which is not the default if you use the Mac OS X GIT client to check + out the projects. If you run into this problem, you may want to use a + utility such as FileTyper to recursively change the type on all + files. CodeWarrior is less picky about the projects' filetypes, but + setting them to filetype ``'MMPr'``, creator code ``'CWIE'`` + may be helpful in opening the projects from the Finder. Users on Mac OS + X familiar with the Unix ``find`` + command should be able to rig ``/Developer/Tools/SetFile`` + to do this job as well. +* Many of the important projects (for ``libdes``, ``libsasl``, + ``build_plugins``, and the sample client ``sc_shlb``) + have Carbon versions. +* Plugins are loaded from a ``Carbon`` subfolder of the ``SASL + v2`` folder in the Extensions folder. Plugins directly + in the ``SASL v2`` folder are considered to be for the Classic + libraries. +* Note that when using the ``build_plugins`` project, you must + generate the plugin init files using the ``makeinit.sh`` script in + the ``plugins`` directory. The easiest way to do this is to run the + script from a Unix shell, such as Mac OS X. You must then fix the + filetypes of the generated source files (see above). +* There is a new folder in ``CommonKClient`` called ``mac_kclient3`` + which contains code compatible with MIT's new `KClient + 3.0 `_ + API. This folder must be in your CodeWarrior access paths, the + old ``mac_kclient`` folder must not, and it must precede the + project's main folder. +* The kerberos4 plugin uses this new code. The kerberos4 plugin + also + statically links the Carbon ``libdes``, and no other part of + Carbon SASL uses ``libdes`` directly. *Your application should + **not** link against* ``libdes.shlb`` *under Carbon!* + (It causes problems due to DES symbols also existing in the MIT + Kerberos library, which loads first.) +* To build the projects, you should have the MIT Kerberos for + Macintosh 3.5 installation disk images mounted, since the access paths + include the absolute paths to the library directories from that + image. It's easier than you having to find the paths yourself, and + smaller than having to distribute the libraries with SASL. + +Known Problems +============== + +* The Kerberos v4 headers bundled with Mac OS X (and Kerberos for + Macintosh) are not compatible with OS X's OpenSSL headers. (Kerberos v4 + support is disabled by default.) If you actually need krb4 support, the + easiest solution is to build without using OpenSSL's + ``libcrypto``. To do this, specify the ``--without-openssl`` + option to ``configure``. As of version 2.1.18, this automatically + disables using ``libcrypto`` for DES as well. You will probably + also need to specify ``--disable-digest`` since the digestmd5 plugin + does not build against Kerberos v4's DES headers or library. Note that + this disables several features (digestmd5, NTLM, OTP) which require + OpenSSL. If both Kerberos v4 and functionality that requires OpenSSL are + needed, it is possible to build the Kerberos v4 plugin against + the correct K4 DES libraries, and everything else against OpenSSL; + however, we do not support that configuration. +* Versions of Cyrus SASL prior to 2.1.14 with support for Carbon + CFM applications on Mac OS X have a known bug involving the CFM glue + code (in ``mac/osx_cfm_glue``). If ``sasl_done`` is called + to unload the SASL library, and then one of the initialization + functions (such as ``sasl_client_init``) is called to + reinitialize it from the same process, the application will crash. A + fix for one obvious cause of this problem is included in 2.1.14; + however, as of this writing, it has not been tested. It is possible + that other bugs in Cyrus SASL, or deficiencies in Apple's libraries, + will make this fix insufficient to resolve this issue. diff --git a/docsrc/sasl/options.rst b/docsrc/sasl/options.rst new file mode 100644 index 00000000..f7325baa --- /dev/null +++ b/docsrc/sasl/options.rst @@ -0,0 +1,422 @@ +.. _options: + +======= +Options +======= + +This document contains information on what options are used by the +Cyrus SASL library and bundled mechanisms. The most commonly used +options (and those that are therefore most commonly misunderstood +are :option:`pwcheck_method` and :option:`auxprop_plugin`. Please ensure +that you have configured these correctly if things don't seem to +be working right. Additionally, :option:`mech_list` can be an easy +way to limit what mechanisms a given application will use. + +.. contents:: + :depth: 1 + :local: + +SASL Library +============ + +.. option:: authdaemon_path [] + + Path to Courier-IMAP authdaemond's unix socket. + + Default: /dev/null + +.. option:: auto_transition [yes|noplain|no] + + When set to 'yes' or 'noplain', + and when using an auxprop plugin, automatically transition + users to other mechs when they do a successful plaintext + authentication. When set to 'noplain', only non-plaintext secrets + will be written. *Note that the only mechanisms (as currently + implemented) which don't use plaintext secrets are + OTP and SRP.* + + Default: no + +.. option:: canon_user_plugin [] + + Name of canon_user plugin to use + + Default: INTERNAL + +.. option:: log_level [] + + **Numeric** Logging Level (see ``SASL_LOG_*`` in ``sasl.h`` + for values and descriptions) + + Default: 1 (SASL_LOG_ERR) + +.. option:: mech_list [] + + Whitespace separated list of mechanisms to allow (e.g. 'plain + otp'). Used to restrict the mechanisms to a subset of the installed + plugins. + + Default: empty (use all available plugins) + +.. option:: plugin_list [] + + Location of Plugin list (Unsupported) + + Default: none + +.. option:: pwcheck_method [] + + Whitespace separated list of mechanisms used to verify passwords, + used by sasl_checkpass. Possible values: 'auxprop', 'saslauthd', + 'pwcheck', 'authdaemond' [if compiled with --with-authdaemond]) + and 'alwaystrue' [if compiled with --enable-alwaystrue]) + + Default: auxprop + +.. option:: saslauthd_path [] + + Path to saslauthd run directory (**including** the "/mux" named pipe) + +Auxiliary Property Plugin +========================= + +.. option:: auxprop_plugin [] + + Name of auxiliary plugin to use, you may specify a space-separated + list of plugin names, and the plugins will be queried in order. + + Default: empty - queries all plugins. + +GSSAPI +====== + +.. option:: keytab [] + + Location of keytab file + + Default: /etc/krb5.keytab (system dependant) + +LDAPDB +====== + +.. option:: ldapdb_uri [] + + URI to the LDAP server. You can specify a space-separated list of URIs - + ldapi:// or ldaps://ldap1/ ldaps://ldap2/ + + Default: none + +.. option:: ldapdb_id [] + + ldap SASL authentication id + + Default: none + +.. option:: ldapdb_mech [] + + LDAP SASL mechanism for authentication. + + Default: none + +.. option:: ldapdb_pw [] + + LDAP password for SASL authentication id + + Default: none + +.. option:: ldapdb_rc [] + + The filename specified here will be put into the server's LDAPRC + environment variable, and libldap-specific config options may be set + in that ldaprc file. + + The main purpose behind this option is to allow + a client TLS certificate to be configured, so that SASL/EXTERNAL may + be used between the SASL server and the LDAP server. This is the most + optimal way to use this plugin when the servers are on separate machines. + + Default: none + +.. option:: ldapdb_starttls [try|demand] + + Use StartTLS. This option may be set to 'try' or 'demand'. + When set to "try" any failure in StartTLS is ignored. + When set to "demand" then any failure aborts the connection. + + Default: none + +.. option:: ldapdb_canon_attr [] + + Use the value of the specified attribute as the user's + canonical name. The attribute will be looked up in the user's LDAP + entry. This setting must be configured in order to use LDAPDB as + a canonuser plugin. + + Default: none + +Notes on LDAPDB +--------------- + +Unlike other LDAP-enabled plugins for other services that are common +on the web, this plugin does not require you to configure DN search +patterns to map usernames to LDAP DNs. This plugin requires SASL name +mapping to be configured on the target slapd. This approach keeps the +LDAP-specific configuration details in one place, the slapd.conf, and +makes the configuration of remote services much simpler. + +This plugin is not for use with slapd itself. When OpenLDAP is +built with SASL support, slapd uses its own internal auxprop and +canonuser module. + +By default, without configuring anything else, slapd will fail to load +the ldapdb module when it's present. This is as it should be. If you +don't like the "auxpropfunc: error -7" message that is sent to syslog +by slapd, you can stop it by creating /usr/lib/sasl2/slapd.conf with:: + + auxprop_plugin: slapd + +which will force the SASL library to ignore all other auxprop modules. + +Examples +-------- + +:: + + ldapdb_uri: ldap://ldap.example.com + ldapdb_id: root + ldapdb_pw: secret + ldapdb_mech: DIGEST-MD5 + ldapdb_canon_attr: uid + +The LDAP server must be configured to map the SASL authcId "root" into a DN +that has proxy authorization privileges to every account that is allowed to +login to this server. (See the OpenLDAP Admin Guide section 10 for +details.) + +:: + + ldapdb_uri: ldapi:// + ldapdb_mech: EXTERNAL + +This configuration assumes an LDAP server is on the same server that is +using SASL and the underlying OS is \*NIX based (ldapi:// requires UNIX domain +sockets). This is fast and secure, and needs no username or password to be +stored. The slapd.conf will need to map these usernames to LDAP DNs: + +:: + + sasl-regexp uidNumber=(.*)\\+gidNumber=(.*),cn=peercred,cn=external,cn=auth + ldap:///dc=example,dc=com??sub?(&(uidNumber=$1)(gidNumber=$2)) + + + sasl-regexp uid=(.*),cn=external,cn=auth + ldap:///dc=example,dc=com??sub?(uid=$1) + +NTLM +==== + +.. option:: ntlm_server [] + + Comma separated list of servernames (WinNT, Win2K, Samba, etc) to + which authentication will be proxied. + + Default: empty - perform authentication internally + +.. option:: ntlm_v2 [yes|no] + + (Client) Send NTLMv2 responses to the server. + + Default: no (send NTLMv1) + +OTP +=== + +.. option:: opiekeys [] + + Location of the opiekeys file + + Default: /etc/opiekeys + +.. option:: otp_mda [md4 | md5 | sha1] + + (Without opie) Message digest algorithm for one-time passwords, used by sasl_setpass + + Default: md5 + +Digest-md5 +========== + +.. option:: reauth_timeout [] + + Length in time (in minutes) that authentication info will be + cached for a fast reauth. A value of 0 will disable reauth. + + Default: 0 - reauth disabled. + +SASLDB +====== + +.. option:: sasldb_path [] + + Path to sasldb file + + Default: /etc/sasldb2 (system dependant) + +.. option:: sasldb_mapsize [] + + For sasldb with LMDB. Size of the memory map used by the DB. This is also the maximum possible + size of the database, so it must be set to a value large enough to contain + all the desired user records. + + Default: 1048576 bytes + +.. option:: sasldb_maxreaders [] + + For sasldb with LMDB. Maximum number of threads (or processes) that may concurrently read the + database. + + Default: 126 + +Notes on sasldb with LMDB +------------------------- + +The OpenLDAP LMDB library is an extremely compact, extremely high performance +B+tree database. The code for it is available in the regular OpenLDAP source +distributions and it is distributed under the terms of the OpenLDAP Public License. + +Full documentation, plus papers and presentations are available on +`the LMDB page `_. + +SQL Plugin +========== + +.. option:: sql_engine [] + + Name of SQL engine to use (possible values: 'mysql', 'pgsql', 'sqlite', 'sqlite3'). + + Default: mysql + +.. option:: sql_hostnames [] + + Comma separated list of SQL servers (in host[:port] format). + +.. option:: sql_user + + Username to use for authentication to the SQL server. + +.. option:: sql_passwd + + Password to use for authentication to the SQL server. + +.. option:: sql_database + + Name of the database which contains the auxiliary properties. + +.. option:: sql_select + + SELECT statement to use for fetching properties. This option is + **required** in order to use the SQL plugin. + +.. option:: sql_insert + + INSERT statement to use for creating properties for new users. + +.. option:: sql_update + + UPDATE statement to use for modifying properties. + +.. option: sql_usessl [yes | no] + + When set to 'yes', 'on', '1' or 'true', a secure connection will + be made to the SQL server. + + Default: no + +Notes on SQL +------------ + +The sql_insert and sql_update options are +optional and are only needed if you wish to allow the SASL library +(e.g., saslpasswd2) and plugins (e.g., OTP) to write properties to the +SQL server. If used, both statements MUST be provided so that +properties can be added, changed and deleted. + +NOTE: The columns for writable properites MUST accept NULL values. + +The SQL statements provided in the sql_select, +sql_insert and sql_update options can contain +arguments which will be substituted with the appropriate values. The +valid arguments are: + +%u + Username whose properties are being fetched/stored. +%p + Name of the property being fetched/stored. This could + technically be anything, but SASL authentication will try + userPassword and cmusaslsecretMECHNAME (where MECHNAME is the + name of a SASL mechanism). +%r + Realm to which the user belongs. This could be the + kerberos realm, the FQDN of the computer the SASL application is + running on or whatever is after the @ on a username. (read the + realm documentation). +%v + Value of the property being stored (INSERT or + UPDATE only!). This could technically be anything depending on + the property itself, but is generally a userPassword. + +Note: DO NOT put quotes around the entire SQL +statement, but each individual %u, %r and %v argument MUST be +quoted. + + +Examples +-------- + + + ``sql_select: SELECT %p FROM user_table WHERE username = '%u' and realm = '%r'`` + +would send the following statement to SQL for user "bovik" and +the default realm for the machine "madoka.surf.org.uk":: + + SELECT userPassword FROM user_table WHERE username = 'bovik' and + realm = 'madoka.surf.org.uk' + +:: + + sql_insert: INSERT INTO user_table (username, realm, %p) VALUES ('%u', '%r', '%v') + +would generate the following statement to SQL for user "bovik" in +realm "madoka.surf.org.uk" with userPassword "wert":: + + INSERT INTO user_table (username, realm, userPassword) VALUES + ('bovik', 'madoka.surf.org.uk', 'wert'); + + +Note that all substitutions do not have to be used. For instance, + +:: + + SELECT password FROM auth WHERE username = '%u' + +is a valid value for sql_select. + + + +SRP +=== + +.. option:: srp_mda [md5 | sha1 | rmd160] + + Message digest algorithm for SRP calculations + + Default: sha1 + +Kerberos V4 +=========== + +.. option:: srvtab [] + + Location of the srvtab file + + Default: /etc/srvtab diff --git a/docsrc/sasl/os390.rst b/docsrc/sasl/os390.rst new file mode 100644 index 00000000..4f9ac121 --- /dev/null +++ b/docsrc/sasl/os390.rst @@ -0,0 +1,56 @@ +.. _install-os390: + +======================================= +Building and Using Cyrus SASL on OS/390 +======================================= + +Cyrus SASLv2 can be made to build on OS/390 with some minimal changes. Here +are the suggestions provided by Howard Chu of the OpenLDAP project. + +Cyrus SASL must be compiled in ASCII mode. This can be accomplished with +a special invocation of c89. For ease of use, you can use a shell script +("acc" is a good name) and set the environment variable CC = acc before +configuring anything. The shell script is simple:: + + #! /bin/sh + exec /bin/c89 -Wc,CONVLIT\(ISO8859-1\) -Wc,LANGLVL\(EXTENDED\) -D__LIBASCII $* + +To build the source, you'll need to set these environment variables, at a minimum:: + + _C89_CCMODE=1 + CC=acc + CPP="c89 -E" + LD=c89 + CPPFLAGS=-D_ALL_SOURCE + +That should allow you to run configure and get a coherent build environment. Before you type "make" from the top level though, do this:: + + cd include + make CC=c89 + +In the include directory is a small program that generates an md5global.h +header file. This file must be generated in native EBCDIC. If you just +typed make from the top level, the program and header file would be +generated in ASCII, with an ASCII filename, which would be very confusing +and not very useful. + +In my initial tests I was able to use SASL/EXTERNAL to perform X.509-based +authentication with slapd. I have subsequently tested the DIGEST-MD5 +mechanism, using OpenLDAP's slapd for storage of the secrets. It worked +without any trouble. Note, I configured sasl --with-dblib=none to prevent +it from trying to use its own sasldb. This is simply because I haven't had +the time to fix the EBCDIC/ASCII dependencies in the rest of the SASL +library. Run as-is with a real database backend, the sasldb would try to +create ASCII-named database files, which would be very unpleasant. The +required fixes are trivial, but they are also numerous, and it is a very +time-consuming task to track down all the dependencies. + +Note that this minimal-effort port of SASL will probably only work in the +context of OpenLDAP (though it may work with other special-case auxprop plugins). + +No effort has been made to fix the ASCII filenames in +the library, this SASL library will be unable to create/parse/handle +native config files or database files. This is why I've only tested it +using secrets stored in slapd, and why I only tried SASL/EXTERNAL at +first. (EXTERNAL has no config parameters, and is part of libsasl2 itself, +so it doesn't need to be dynamically loaded from anywhere.) diff --git a/docsrc/sasl/pwcheck.rst b/docsrc/sasl/pwcheck.rst new file mode 100644 index 00000000..de081be7 --- /dev/null +++ b/docsrc/sasl/pwcheck.rst @@ -0,0 +1,174 @@ +Pwcheck +======= + +Auxprop +------- + +Auxprop-hashed +-------------- + +Saslauthd +--------- + +**What is saslauthd?** saslauthd is a daemon which validates + +``ldap_servers`` - ``ldap://localhost`` + + Specify a space separated list of LDAP server URIs of the form **ldap[si]://[name[:port]]**. See the ``ldap.conf`` *URI* option for formatting details. + +``ldap_bind_dn`` - none + + When simple authentication is desired, specify a distinguished name to use for a simple authenticated bind or a simple unauthenticated bind. Do not specify if an anonymous bind is desired. This option is ignored when the evaluated ``ldap_auth_method`` is ``fastbind``. + +``ldap_bind_pw`` - none + + ``ldap_bind_pw`` is an alias for ``ldap_password``. + +``ldap_password`` - none + + When simple authentication is desired, specify a password to perform an authenticated bind, or do not specify for an unauthenticated or anonymous bind. When SASL authentication is desired, specify a password to use where required by the underlying SASL mechanism. This option is ignored when the evaluated ``ldap_auth_method`` is ``fastbind``. + +``ldap_version`` - 3 + + Defaults to version *3*. If ``ldap_use_sasl`` or ``ldap_start_tls`` are enabled, this option will be ignored, and will conform to the default value. Version *3* **is** compatible with anonymous binds, simple authenticated binds and simple unauthenticated binds. Version *2* should only be necessary where required by the server. + +``ldap_search_base`` - none + + When ``ldap_auth_method`` is evaluated as *bind*, ``ldap_search_base`` will be used to search for the user's distinguished name. When ``ldap_auth_method`` is *custom*, ``ldap_search_base`` will be used to find the user's ``ldap_password_attr`` attribute. When ``ldap_auth_method`` is evaluated as *fastbind*, ``ldap_search_base`` is ignored. If ``ldap_search_base`` contains substitution tokens, they will be replaced as specified in the ``ldap_filter`` token expansion rules. + +``ldap_filter`` - uid=%u + + When ``ldap_auth_method`` is evaluated as *bind*, ``ldap_filter`` will be used to search for the user's distinguished name. When ``ldap_auth_method`` is *custom*, ``ldap_filter`` will become, after token expansion, the user's distinguished name. When ``ldap_auth_method`` is evaluated as *fastbind*, ``ldap_filter`` is ignored. + + The following tokens, when contained within the ``ldap_filter`` option, will be substituted with the specified values: + + ``%%`` + + is replaced with a literal %. + + ``%u`` + + is replaced with the userid to be authenticated. + + ``%U`` + + is replaced by the portion of the userid before the first @ character. If an @ character does not exist in the userid, then ``%U`` would function identically to ``%u``. For example, if the userid to be authenticated is *jsmith@example.org*, ``%u`` would be replaced by *jsmith@example.org* and ``%U`` would be replaced by *jsmith*. + + ``%d`` + + is replaced by the portion of the userid after the first @ character. If an @ character does not exist in the userid, ``%d`` will be replaced by the ``realm`` value passed to ``saslauthd``. If no ``realm`` value was passed to saslauthd, ``%d`` will be replaced by the configured ``ldap_default_realm``, or by an empty string if ``ldap_default_realm`` is not configured. + + ``%1-9`` + + Within a userid which contains an @ character, followed by a domain name, ``%1`` will be replaced by the top level domain, ``%2`` will be replaced by the secondary domain, ``%3`` will be replaced by the tertiary domain, up to and including ``%9`` which would be replaced by the ninth level domain. If no @ character exists in the userid, or if there is no domain name after the @ character, or if the specified hierarchical domain level does not exist, the option is replaced by the ``realm`` value passed to ``saslauthd``. Should no ``realm`` value exist in those scenarios, the option is replaced by the configured ``ldap_default_realm``, or by an empty string if ``ldap_default_realm`` has not been configured. + + For example, if the userid to be authenticated is *jsmith@example.org*, ``%1`` would be replaced by *org* and ``%2`` would be replaced by *example*. + + ``%s`` + + is replaced by the ``service`` option passed to ``saslauthd``, or by an empty string if no ``service`` option was passed. + + ``%r`` + + is replaced by the ``realm`` option passed to ``saslauthd``. If no ``realm`` value was passed to saslauthd, ``%r`` will be replaced by the configured ``ldap_default_realm``, or by an empty string if ``ldap_default_realm`` is not configured. + +``ldap_password_attr`` - userPassword + + When ``ldap_auth_method`` is evaluated as *custom*, ``ldap_password_attr`` specifies an attribute that will be requested and retrived. If successfully retrived, the authentication request will succeed if the ``ldap_password_attr`` attribute contains a supported password hash, and if the user submitted password matches the hash. When ``ldap_auth_method`` is *bind* or *fastbind*, ``ldap_password_attr`` is ignored. + + +``ldap_group_dn`` - none + + If ``ldap_group_dn`` is specified, group authorization must also succeed (in addition to the prior authentication step), for the user's authentication attempt to be successful. If ``ldap_group_dn`` contains substitution tokens, they will be replaced as specified in the ``ldap_filter`` token expansion rules. One additional token substitution is applicable to ``ldap_group_dn``: + + ``%D`` + + is replaced by the distinguished name that was specified, or evaluated, in the authentication step. If ``ldap_use_sasl`` is enabled, the distinguished name will be resolved by performing an ldapwhoami extended operation after a successful authentication. If ``ldap_group_dn`` is specified and ``ldap_use_sasl`` is enabled, but the ldap server does not support the ldapwhoami extended operation, or if the ldapwhoami extended operation fails, then the user's authentication attempt is unsuccessful. + + +``ldap_group_attr`` - uniqueMember + + ``ldap_group_attr`` is ignored unless ``ldap_group_dn`` is also specified and ``ldap_group_match_method`` is *attr*. ``ldap_group_attr`` specifies an attribute which contains the authenticating identity's dinstinguished name. See the ``ldap_group_match_method`` entry for additional details. + +``ldap_group_filter`` - none + +``ldap_group_search_base`` - defaults to the evaluated ``ldap_search_base`` + +``ldap_group_scope`` - *sub* + +``ldap_group_match_method`` - attr + +``ldap_default_realm`` - none + +``ldap_default_domain`` - none + + ``ldap_default_domain`` is an alias for ``ldap_default_realm``. + +``ldap_auth_method`` - bind + +``ldap_timeout`` - 5 + +``ldap_size_limit`` - 1 + +``ldap_time_limit`` - 5 + +``ldap_deref`` - never + +``ldap_referrals`` - no + +``ldap_restart`` - yes + +``ldap_scope`` - sub + +``ldap_use_sasl`` - no + +``ldap_id`` - none + +``ldap_sasl_authc_id`` - none + +``ldap_authz_id`` - none + + Does not make any sense to supply an authz identity when performing sasl/fastbind. + +``ldap_sasl_authz_id`` - none + + ``ldap_sasl_authz_id`` is an alias for ``ldap_authz_id``. + +``ldap_realm`` - none + +``ldap_sasl_realm`` - + +``ldap_mech`` - + + It doesn't make any sense to use a mech that does not require an authname and password, when using fastbind. + +``ldap_sasl_mech`` - + +``ldap_sasl_secprops`` - + +``ldap_start_tls`` - + +``ldap_tls_check_peer`` - + +``ldap_tls_cacert_file`` - + +``ldap_tls_cacert_dir`` - + +``ldap_tls_ciphers`` - + +``ldap_tls_cert`` - + +``ldap_tls_key`` - + +``ldap_debug`` - + +Authdaemon +---------- + +Alwaystrue +---------- + +Auto Transition +--------------- + + diff --git a/docsrc/sasl/quickstart.rst b/docsrc/sasl/quickstart.rst new file mode 100644 index 00000000..01b0b3cf --- /dev/null +++ b/docsrc/sasl/quickstart.rst @@ -0,0 +1,94 @@ +.. _quickstart: + +Quickstart guide +================ + +This document offers a general overview of the Cyrus SASL library. +The Cyrus SASL Libray provides applications with an implementation +of the Simple Authentication and Security Layer (RFC2222), and +several authentication mechanisms. Users interested in the "big picture" +of what is provided by the library should read about +:ref:`Cyrus SASL Components `. + +Features +-------- + +The following :ref:`authentication_mechanisms` are included in +this distribution: + +* ANONYMOUS +* CRAM-MD5 +* DIGEST-MD5 +* EXTERNAL +* GSSAPI (MIT Kerberos 5, Heimdal Kerberos 5 or CyberSafe) +* KERBEROS_V4 +* LOGIN +* NTLM (requires OpenSSL libcrypto) +* OTP (requires OpenSSL libcrypto) +* PLAIN +* SRP (work in progress; requires OpenSSL libcrypto) + + +The library also supports storing user secrets in either a hash +database (e.g. Berkeley DB, gdbm, ndbm), LDAP, or in a SQL database +(MySQL, Postgres). + + +Additionally, mechanisms such as PLAIN and LOGIN +(where the plaintext password is directly supplied by the client) +can perform direct password verification via the saslauthd daemon. This +allows the use of LDAP, PAM, and a variety of other password verification +routines. + +The sample directory in the code contains two programs which provide a reference +for using the library, as well as making it easy to test a mechanism +on the command line. See programming.html for more information. + +This library is believed to be thread safe **if**: + +* you supply mutex functions (see sasl_set_mutex()) +* you make no libsasl calls until sasl_client/server_init() completes +* no libsasl calls are made after sasl_done() is begun +* when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library. + + +Typical Installation +-------------------- + +First, if you are upgrading from Cyrus SASLv1, please see upgrading.html. + +Please see the :ref:`installation guide ` for instructions +on how to install this package. + +Note that the library can use the environment variable SASL_PATH to locate the +directory where the mechanisms are; this should be a colon-separated +list of directories containing plugins. Otherwise it will default to the +value of ``--with-plugindir`` as supplied to ``configure`` (which +itself defaults to ``/usr/local/lib``). + +Looking to :ref:`Install on Mac OSX? ` + +Looking to :ref:`Install on Windows? ` + +Configuration +------------- + +There are two main ways to configure the SASL library for a given +application. The first (and typically easiest) is to make use +of the application's configuration files. Provided the application supports it +(via the ``SASL_CB_GETOPT`` callback), please refer to that documetation +for how to supply SASL options. + +Alternatively, Cyrus SASL looks for configuration files in +/usr/lib/sasl/Appname.conf where Appname is settable by the +application (for example, Sendmail 8.10 and later set this to +"Sendmail"). + +Configuration using the application's configuration files (via +the ``getopt`` callback) will override those supplied by +the SASL configuration files. + +For a detailed guide on configuring libsasl, please look at the +:ref:`Sysadmin guide ` and the information on :ref:`options `. diff --git a/docsrc/sasl/resources.rst b/docsrc/sasl/resources.rst new file mode 100644 index 00000000..663dc473 --- /dev/null +++ b/docsrc/sasl/resources.rst @@ -0,0 +1,15 @@ +.. _resources: + +=============================== +Other Documentation & Resources +=============================== + + +* `Using SASL: Pluggable Security `_ +* `Using SASL: CMU's Cyrus SASL Library `_ +* `Information on SASL mechanisms, profiles, servers and clients implementing SASL `_ +* `FAQ from Sendmail `_ +* `The Secure Remote Password Protocol `_ paper by Thomas Wu +* `TCL extensions for SASL `_ +* `The NTLM Authentication Protocol `_ (NTLM) +* `Common Internet File System (CIFS) Technical Reference `_ (SMB/NTLM) diff --git a/docsrc/sasl/sysadmin.rst b/docsrc/sasl/sysadmin.rst new file mode 100644 index 00000000..7a1e4356 --- /dev/null +++ b/docsrc/sasl/sysadmin.rst @@ -0,0 +1,455 @@ +.. _sysadmin: + +===================== +System Administrators +===================== + +This document covers configuring SASL for system administrators, +specifically those administrators who are installing a server that +uses the Cyrus SASL library. You may want to read +:ref:`about components ` which presents an +overview of the Cyrus SASL distribution +and describes how the components interact, as well as the :ref:`installation guide ` + +.. _saslintro: + +What SASL is +============ + +SASL, the Simple Authentication and Security Layer, is a generic +mechanism for protocols to accomplish authentication. Since protocols +(such as SMTP or IMAP) use SASL, it is a natural place for code +sharing between applications. Some notable applications that use the +Cyrus SASL library include `Sendmail `_, +`Cyrus imapd `_, +and `OpenLDAP `_. + +Applications use the SASL library to tell them how to accomplish +the SASL protocol exchange, and what the results were. + +SASL is only a framework: specific SASL mechanisms govern the +exact protocol exchange. If there are n protocols and m different +ways of authenticating, SASL attempts to make it so only n plus m +different specifications need be written instead of n times m +different specifications. With the Cyrus SASL library, the mechanisms +need only be written once, and they'll work with all servers that use +it. + +.. _authid: + +Authentication and authorization identifiers +-------------------------------------------- + +An important concept to become familiar with is the difference between +an "authorization identifier" and an "authentication identifier". + +userid (user id, authorization id) + The userid is the + identifier an application uses to check allowable options. On my Unix + system, the user ``bovik`` (the account of Harry Q. Bovik) is + allowed to write to ``/home/bovik`` and its subdirectories but + not to ``/etc``. +authid (authentication id) + The authentication identifier is + the identifier that is being checked. "bovik"'s password might be + "qqqq", and the system will authenticate anyone who knows "qqqq" as + "bovik". + + However, it's possible to authenticate as one user but + *act as* another user. For instance, Harry might be away on + vacation and assign one of his graduate students, Jane, to read his + mail. He might then allow Jane to act as him merely by supplying her + password and her id as authentication but requesting authorization as + "bovik". So Jane might log in with an authentication identifier of + "jane" and an authorization id of "bovik" and her own (Jane's) + password. + + +Applications can set their own proxy policies; by default, the SASL +library will only allow the same user to act for another (that is, +userid must equal authid). See your application's documentation for +details about changing the default proxy/authorization policies. + +.. _realms: + +Realms +------ + +The Cyrus SASL library supports the concept of "realms". A realm is +an abstract set of users and certain mechanisms authenticate users in +a certain realm. + +In the simplest case, a single server on a single machine, the +realm might be the fully-qualified domain name of the server. If the +applications don't specify a realm to SASL, most mechanisms will +default to this. + +If a site wishes to share passwords between multiple machines, it +might choose it's authentication realm as a domain name, such as +"CMU.EDU". On the other hand, in order to prevent the entire site's +security from being compromised when one machine is compromised, each +server could have it's own realm. Certain mechanisms force the user +(client side) to manually configure what realm they're in, making it +harder for users to authenticate. + +A single site might support multiple different realms. This can +confuse applications that weren't written in anticipation of this; make +sure your application can support it before adding users from different +realms into your databases. + +To add users of different realms to sasldb, you can use the +``-u`` option to saslpasswd2. The SQL plugin has a way of +integrating the realm name into the query string with the '%r' macro. + +The Kerberos mechanisms treat the SASL realm as the Kerberos +realm. Thus, the realm for Kerberos mechanisms defaults to the +default Kerberos realm on the server. They may support cross-realm +authentication; check your application on how it deals with this. + +Realms will be passed to saslauthd as part of the saslauthd protocol, +however the way each saslauthd module deals with the situation is +different (for example, the LDAP plugin allows you to use the realm +to query the server, while the rimap and PAM plugins ignore it entirely). + +Realms are represented in a username string by any text followinhg +the '@' sign. So, usernames like rjs3@ANDREW.CMU.EDU, is user 'rjs3' +in the realm 'ANDREW.CMU.EDU'. If no realm is provided, the server's +FQDN is assumed (likewise when specifying a realm for saslpasswd2). + +.. _saslhow: + +How SASL works +============== + +How SASL works is governed by what mechanism the client and server +choose to use and the exact implementation of that mechanism. This +section describes the way these mechanisms act in the Cyrus SASL +implementation. + +The PLAIN mechanism, ``sasl_checkpass()``, and plaintext passwords +------------------------------------------------------------------ + +The PLAIN mechanism is not a secure method of authentication by +itself. It is intended for connections that are being encrypted by +another level. (For example, the IMAP command "STARTTLS" creates an +encrypted connection over which PLAIN might be used.) The PLAIN +mechanism works by transmitting a userid, an authentication id, and a +password to the server, and the server then determines whether that is +an allowable triple. + +The principal concern for system administrators is how the +authentication identifier and password are verified. The Cyrus SASL +library is flexible in this regard: + +auxprop + checks passwords agains the ``userPassword`` attribute + supplied by an auxiliary property plugin. For example, SASL ships + with a sasldb auxiliary property plugin, that can be used to + authenticate against the passwords stored in ``/etc/sasldb2``. + + Since other mechanisms also use this database for passwords, using + this method will allow SASL to provide a uniform password database to + a large number of mechanisms. +saslauthd + contacts the ``saslauthd`` daemon to to check passwords + using a variety of mechanisms. More information about the various invocations + of saslauthd can be can be found in ``saslauthd(8)``. Generally you + want something like ``saslauthd -a pam``. If plaintext authentications + seem to be taking some time under load, increasing the value of the ``-n`` + parameter can help. + + Saslauthd keeps its named socket in "/var/state/saslauthd" by default. + This can be overridden by specifying an alternate value to + --with-saslauthd=/foo/bar at compile time, or by passing the -m + parameter to saslauthd (along with setting the saslauthd_path SASL + option). Whatever directory this is, it must exist in order for + saslauthd to function. + + Once you configure (and start) ``saslauthd``, there is a + ``testsaslauthd`` program that can be built with ``make + testsaslauthd`` in the ``saslauthd`` subdirectory of the + source. This can be used to check that that the ``saslauthd`` + daemon is installed and running properly. An invocation like + ``testsaslauthd -u rjs3 -p 1234`` with appropriate values for the + username and password should do the trick. + + If you are using the PAM method to verify passwords with saslauthd, keep in + mind that your PAM configuration will need to be configured for each service + name that is using saslauthd for authentication. Common service names + are ``imap``, ``sieve``, and ``smtp``. +Courier-IMAP authdaemond + contacts Courier-IMAP's ``authdaemond`` daemon to check passwords. + This daemon is simliar in functionality to ``saslauthd``, and is shipped + separately with the `Courier `_ mail server. + + Note: this feature is **not** compiled in the library by default, and is + provided for sites with custom/special requirements only (because the + internal authentication protocol its not documented anywhere so it could + change at any time). We have tested against the authdaemond included with + Courier-IMAP 2.2.1. + + To enable ``authdaemond`` support, pass ``--with-authdaemon`` to the + configuration script, set pwcheck_method to ``authdaemond'' and point + authdaemond_path to ``authdaemond``'s unix socket. Optionally, you can + specify --with-authdaemond=PATH to the configure script so that + authdaemond_path points to a default, static, location. +pwcheck + checks passwords with the use of a separate, + helper daemon. This feature is for backwards-compatibility + only. New installations should use saslauthd. +write your own + Last, but not least, the most flexible method of authentication + for PLAIN is to write your own. If you do so, any application that + calls the ``sasl_checkpass()`` routine or uses PLAIN will + invoke your code. The easiest place to modify the plaintext + authentication routines is to modify the routine + ``_sasl_checkpass()`` in the file ``lib/server.c`` to + support a new method, and to add that method to + ``lib/checkpw.c``. Be sure to add a prototype in + ``lib/saslint.h``! + + However, the more flexible and preferred method of + adding a routine is to create a new saslauthd mechanism. + +The LOGIN mechanism (not to be confused with IMAP4's LOGIN command) +is an undocumented, unsupported mechanism. It's included in the Cyrus +SASL distribution for the sake of SMTP servers that might want to +interoperate with old clients. Do not enable this mechanism unless +you know you're going to need it. When enabled, it verifies passwords +the same way the PLAIN mechanism does. + +Shared secrets mechanisms +------------------------- + +The Cyrus SASL library also supports some "shared secret" +authentication methods: CRAM-MD5 and its successor DIGEST-MD5. These +methods rely on the client and the server sharing a "secret", usually +a password. The server generates a challenge and the client a +response proving that it knows the shared secret. This is much more +secure than simply sending the secret over the wire proving that the +client knows it. + +There's a downside: in order to verify such responses, the +server must keep passwords or password equivalents in a database; +if this database is compromised, it is the same as if all the +passwords for the realm are compromised. + +Put another way, *you cannot use saslauthd with these methods*. +If you do not wish to advertise these methods for that reason (i.e. you +are only using saslauthd for password verification), then either remove +the non-plaintext plugins (those other than login and plain) from the +plugin directory, or use the :option:`mech_list` option to disable them. + +For simplicity sake, the Cyrus SASL library stores plaintext +passwords only in the ``/etc/sasldb2`` database. These passwords +are then shared among all mechanisms which choose to use it. +Depending on the exact database method +used (gdbm, ndbm, or db) the file may have different suffixes or may +even have two different files (``sasldb.dir`` and +``sasldb.pag``). It is also possible for a server to define +it's own way of storing authentication secrets. Currently, no +application is known to do this. + +The principle problem for a system administrator is to make sure that +sasldb is properly protected. Only the servers that need to read it to +verify passwords should be able to. If there are any normal shell +users on the system, they must not be able to read it. + +This point is important, so we will repeat it: **sasldb stores the +plaintext versions of all of its passwords. If it is compromised so +are all of the passwords that it stores**. + +Managing password changes is outside the scope of the library. +However, system administrators should probably make a way of letting +user's change their passwords available to users. The +``saslpasswd2`` utility is provided to change the secrets in +sasldb. It does not affect PAM, ``/etc/passwd``, or any other +standard system library; it only affects secrets stored in sasldb. + +Finally, system administrators should think if they want to enable +"auto_transition". If set, the library will automatically create +secrets in sasldb when a user uses PLAIN to successfully authenticate. +However, this means that the individual servers, such as imapd, need +read/write access to sasldb, not just read access. By default, +"auto_transition" is set to false; set it to true to enable. (There's +no point in enabling this option if "pwcheck_method" is "auxprop", +and the sasldb plugin is installed, since you'll be transitioning from +a plaintext store to a plaintext store) + +Kerberos mechanisms +------------------- + +The Cyrus SASL library also comes with two mechanisms that make use of +Kerberos: KERBEROS_V4, which should be able to use any Kerberos v4 +implementation, and GSSAPI (tested against MIT Kerberos 5, Heimdal +Kerberos 5 and CyberSafe Kerberos 5). These mechanisms make use of the kerberos infrastructure +and thus have no password database. + +Applications that wish to use a kerberos mechanism will need access +to a service key, stored either in a :option:`srvtab` file (Kerberos 4) or a +:option:`keytab` file (Kerberos 5). + +The Kerberos 4 :option:`srvtab` file location is configurable; by default it is +``/etc/srvtab``, but this is modifiable by the "srvtab" option. +Different SASL applications can use different srvtab files. + +A SASL application must be able to read its srvtab or keytab file. + +You may want to consult the GSSAPI Tutorial.

+ +The OTP mechanism +----------------- + +The Cyrus SASL library also supports the One-Time-Password (OTP) +mechanism. This mechanism is similar to CRAM-MD5 and DIGEST-MD5 in +that is uses a shared secret and a challenge/response exchange. +However, OTP is more secure than the other shared secret mechanisms in +that the secret is used to generate a sequence of one-time (single +use) passwords which prevents reply attacks, and that secret need +not be stored on the system. These one-time passwords are stored in the +``/etc/sasldb2`` database. + +OTP via OPIE +############ + +For sites with an existing OTP infrastructure using OPIE, Cyrus SASL +can be configured to use OPIE v2.4 instead of using its own database +and server-side routines. + +OPIE should be configured with the ``--disable-user-locking`` +option if the SASL server application will not be running as "root". + +OPIE uses its own "opiekeys" database for storing the data necessary +for generating the server challenges. The location of the :option:`opiekeys` +file is configurable in SASL; by default it is ``/etc/opiekeys``, +but this is modifiable by the :option:`opiekeys` option. + +A SASL server application must be able to read and write the +opiekeys file. + +Auxiliary Properties +==================== + +SASLv2 introduces the concept of Auxilliary Properties. That is, the ability +for information related to authentication and authorization to all be looked +up at once from a directory during the authentication process. SASL Plugins +internally take advantage of this to do password lookups in directories +such as the SASLdb, LDAP or a SQL database. Applications can look up arbitrary properties through them. + +Note that this means that if your password database is in a SASLdb, and +you wish to use it for plaintext password lookups through the sasldb, you +will need to set the sasl :option:`pwcheck_method` to be ``auxprop``. + +How to set configuration options +================================ + +The Cyrus SASL library comes with a built-in configuration file +reader. However, it is also possible for applications to redefine +where the library gets it's configuration options from. + +.. _saslconf: + +The default configuration file +------------------------------ + +By default, the Cyrus SASL library reads its options from +``/usr/lib/sasl2/App.conf`` (where "App" is the application +defined name of the application). For instance, Sendmail reads its +configuration from ``/usr/lib/sasl2/Sendmail.conf`` and the +sample server application included with the library looks in +``/usr/lib/sasl2/sample.conf``. + +A standard Cyrus SASL configuration file looks like:: + + srvtab: /var/app/srvtab + pwcheck_method: saslauthd + +Application configuration +------------------------- + +Applications can redefine how the SASL library looks for configuration +information. Check your application's documentation for specifics. + +For instance, Cyrus imapd reads its sasl options from its own +configuration file, ``/etc/imapd.conf``, by prepending all SASL +options with ``sasl_``: the SASL option "pwcheck_method" is set +by changing "sasl_pwcheck_method" in ``/etc/imapd.conf``. + +Troubleshooting +=============== + +Why doesn't KERBEROS_V4 doesn't appear as an available mechanism? + Check that the ``srvtab`` file is readable by the + user running as the daemon. For Cyrus imapd, it must be readable by + the Cyrus user. By default, the library looks for the srvtab in + ``/etc/srvtab``, but it's configurable using the :option:`srvtab` + option. +Why doesn't OTP doesn't appear as an available mechanism? + If using OPIE, check that the ``opiekeys`` file is + readable by the user running the daemon. For Cyrus imapd, it must + be readable by the Cyrus user. By default, the library looks for the + opiekeys in ``/etc/opiekeys``, but it's configurable using the + :option:`opiekeys` option. +Why don't CRAM-MD5 and DIGEST-MD5 work with my old sasldb? + Because sasldb now stores plaintext passwords only, the old + sasldb is incompatible. +I'm having performance problems on each authentication, there is a noticeable slowdown when sasl initializes, what can I do? + libsasl reads from ``/dev/random`` as part of its + initialization. ``/dev/random`` is a "secure" source of entropy, + and will block your application until a sufficient amount of + randomness has been collected to meet libsasl's needs. + + To improve performance, you can change DEV_RANDOM in + ``config.h`` to be ``/dev/urandom`` and recompile + libsasl. ``/dev/urandom`` offers less secure random numbers but + should return immediately. The included mechanisms, besides OTP and + SRP, use random numbers only to generate nonces, so using + ``/dev/urandom`` is safe if you aren't using OTP or SRP. + + +I've converted the sasldb database to the new format. Why can't anybody authenticate? + sasldb is now a plugin module for the auxprop method. + Make sure you changed the /usr/lib/sasl2/\*.conf files to reflect + ``pwcheck_method: auxprop`` + + ...and if you're using cyrus-imapd, /etc/imapd.conf must reflect: + ``sasl_pwcheck_method: auxprop`` + +Is LOGIN supported? + The LOGIN mechanism is a non-standard, undocumented + plaintext mechanism. It's included in the SASL distribution purely + for sites that need it to interoperate with old clients; we don't + support it. Don't enable it unless you know you need it. + +Is NTLM supported? + The NTLM mechanism is a non-standard, undocumented + mechanism developed by Microsoft. It's included in the SASL + distribution purely for sites that need it to interoperate with + Microsoft clients (ie, Outlook) and/or servers (ie, Exchange); we + don't support it. Don't enable it unless you know you need it. + +How can I get a non-root application to check plaintext passwords? + Use the "saslauthd" daemon and setting "pwcheck_method" + to "saslauthd". + +I want to use Berkeley DB, but it's installed in ``/usr/local/BerkeleyDB.3.1`` and ``configure`` can't find it. + Try setting "CPPFLAGS" and "LDFLAGS" environment + variables before running ``configure``, like so:: + + env CPPFLAGS="-I/usr/local/BerkeleyDB.3.1/include" \ + LDFLAGS="-L/usr/local/BerkeleyDB.3.1/lib -R/usr/local/BerkeleyDB.3.1/lib" \ + ./configure --with-dblib=berkeley + +It's not working and won't tell me why! Help! + Check syslog output (usually stored in + ``/var/log``) for more information. You might want to change your + syslog configuration (usually ``/etc/syslogd.conf``) to log + "\*.debug" to a file while debugging a problem. + + The developers make heavy use of ``strace`` or ``truss`` + when debugging a problem that isn't outputting any useful + information. + +Is there a mailing list to discuss the Cyrus SASL library? + Check out our :ref:`contribution ` page for ways to get in touch + with us, including mailing lists and IRC. diff --git a/docsrc/sasl/upgrading.rst b/docsrc/sasl/upgrading.rst new file mode 100644 index 00000000..77025bd8 --- /dev/null +++ b/docsrc/sasl/upgrading.rst @@ -0,0 +1,113 @@ +.. _upgrading-v1-v2: + +======================= +Upgrading from v1 to v2 +======================= + +This document covers issues with upgrading from SASLv1 to SASLv2. +To upgrade: + +* Install Cyrus SASL v2 as normal according to the :ref:`installation guide `. + This will overwrite + some manpages, but will not affect your current applications. Do NOT + attempt to make it use the same directories, otherwise old Cyrus SASLv1 + applications will no longer function. + +* Install your new Cyrus SASL v2 applications. Applications that + use Cyrus SASLv1 will *not* use the Cyrus SASL v2 + infrastructure (and vice-versa). + +* If you used ``/etc/sasldb`` for authentication, you'll need + to take the following steps to convert to using ``/etc/sasldb2`` + with Cyrus SASL v2: + + 1. run ``utils/dbconverter-2`` after installation. + 2. change the ``pwcheck_method`` in any config files to + ``auxprop`` + 3. (optional) add ``auxprop_plugin`` to the config files, + set to ``sasldb`` + +* If you used ``passwd``, ``shadow``, ``pam``, + ``kerberos_v4`` or ``sia`` as your ``pwcheck_method`` + in libsasl v1, you'll need to convert to using + ``saslauthd``. Arrange to start ``saslauthd -a + `` on boot. Change ``pwcheck_method`` in any + configuration files to ``saslauthd``. + +* If you used ``pwcheck`` with libsasl v1, you can either + continue to use ``pwcheck`` with libsasl v1 or you can switch to + ``saslauthd``, which offers more flexibility and a potentially + much more efficient implementation. + +* If you are continuing to use some libsasl v1 applications, read + onwards to understand the ramifications. + +* If you want to learn how to port applications from libsasl v1 to + libsasl v2, you should read the :ref:`converting applications guide `. + +Backwards Compatibility +======================= + +Cyrus SASLv2 is incompatible with applications that use +Cyrus SASLv1. This means that applications are unable to +simultaneously link both versions of the library, and developers are +encouraged to instead develop or upgrade their applications to link +against the new libsasl. + +Likewise, the format for the sasldb database has been completely +revamped. See :ref:`here ` for a discussion of the relevant +upgrade issues related to sasldb. All new passwords stored in the +sasldb database will be in plaintext, meaning that a compromised +sasldb will compromise all services with the same passwords. (This +situation isn't significantly worse, cryptographically speaking, than +the old method and allows the database to be easy to transition to +another format, when the need arises.) Mechanisms requiring a more +secure password database backend (e.g. SRP) should implement their own +or use alternate property names within sasldb. + +.. _coexist: + +Coexistence with SASLv1 +======================= + +The two library versions and the associated utilities should be able +to coexist on the same system. The man pages will be unable to +coexist (but luckily the new manpages are much better!). The libsasl +v2-specific utilities have had a "2" appended to their name for this +purpose (e.g. ``saslpasswd2``, ``sasldblistusers2``). The +new-style sasldb now defaults to the name ``/etc/sasldb2``, but +this is configurable. + +.. _upgrading-db: + +Database Upgrades +================= + +While there does not seem to be any conflict with the keys stored in +the database, it is not recommended for both versions of the library +to use the same database file. Included in the utils directory is a +program called ``dbconverter-2`` which will allow you to convert +from the old-format database to the new format. Note that if you continue to +run older applications that rely on Cyrus SASLv1, the databases for SASLv1 +and SASLv2 will not automatically be kept in sync. + + +Errors on migration +=================== + +When migrating the ``/etc/sasldb`` database using the ``utils/dbconverter-2`` +utility, you may encounter the error message "Error opening password +file". This is usually due to the fact your SASL V1 library was compiled +using a different version of Berkeley DB than the SASL V2 library. +You can work around this by using Berkeley DB's db_upgrade utility +(possibly chaining the DB3 and DB4 upgrade utilities) to upgrade a copy +of sasldb prior to conversion using dbconverter-2. + +Here is the script we use at our installation, where SASL has to +coexist with SASL2:: + + !/bin/sh + cp /etc/sasldb /tmp/sasldb.$$ + /usr/local/BerkeleyDB.4/bin/db_upgrade /etc/sasldb + echo ""|/usr/local/sasl/sbin/dbconverter-2 + cp /tmp/sasldb.$$ /etc/sasldb diff --git a/docsrc/sasl/windows.rst b/docsrc/sasl/windows.rst new file mode 100644 index 00000000..a6800a13 --- /dev/null +++ b/docsrc/sasl/windows.rst @@ -0,0 +1,170 @@ +.. _install-windows: + +============================== +Building Cyrus SASL on Windows +============================== + +Note, that Cyrus SASL on Windows is still laregely a "work in progress". +So far only the main library, plugins (SASLDB using SleepyCat, no MySQL) +and several applications (see the list below) can be built. In particular, +saslauthd doesn't compile on Windows. + +Prerequisites +============= + +Visual Studio. + We have tested Visual Studio 6 and Visual Studio 7 (.NET). + By default we are using Visual Studio 7 (both 2002 and 2003 versions were tested). If you want to use Visual Studio 6, + you need to remove the leading # character from the line containing ``#VCVER=6`` in win32/common.mak. + +The latest Platform SDK. + We are currently using March 2006. (The earliest tested version was November 2001.) + +SleepyCat + SleepyCat's include files and libraries are required to buil SASLDB plugin, + saslpasswd2.exe and sasldblistusers2.exe. We have tested SleepyCat 4.1.X-4.4.X. + +Cygwin (for building from GIT) + The `Cygwin `_ Unix-compatibility + environment to create the ``_init.c`` files needed for dynamic + loading. Cygwin is *not* required for building from our tar + distribution. + +Step by step +============ + +These directions assume that you've untarred the library or used GIT +and the sources are in ``C:\SASL``. + +Preparing to build (GIT only!) +------------------------------ + +Start a cygwin shell and create the dynamic loading stubs:: + + % cd /cygdrive/c/sasl/plugins + % sh makeinit.sh + +Building using NMake +-------------------- + +Open a "Windows 2000 build environment" from the SDK's Start Menu and +use ``nmake /f NTMakefile`` to build. + +To build a debug verison, use ``nmake /f NTMakefile +CFG=Debug``. For a production version, ``nmake /f NTMakefile +CFG=Release``. If you don't specify CFG parameter, production +version will be built by default. + +As Windows build requires SleepyCat, there are additional options +that have to be provided to NMake on the command line. +If SleepyCat sources are located in ``c:\packages\db\4.1.24`` +and built library in ``c:\packages\db\4.1.24\build_win32\Release_static``, +you should add something like +``DB_INCLUDE=c:\packages\db\4.1.24\build_win32`` +and ``DB_LIBPATH=c:\packages\db\4.1.24\build_win32\Release_static``. + +Also note, that the ``DB_LIB`` defines the name of the SleepyCat library +to link against. It defaults to libdb41s.lib. + +If you don't pass the parameters described above, NMake will pick the +defaults, which is probably not what you want. + +Another option of interest is ``STATIC``. +It specifies which version of the standard C library +to use. The default is "no", meaning that the standard C library +from the MSVCRT.DLL will be used. + +Example:: + + Targeting Windows 2000 and IE 5.0 RETAIL + + C:\Program Files\Microsoft SDK> cd \sasl + + C:\sasl> nmake /f NTMakefile DB_INCLUDE=c:\packages\db\4.1.24\build_win32 + DB_LIBPATH=c:\packages\db\4.1.24\build_win32\Release_static + + No configuration specified. Defaulting to Release. + Using MSVCRT.dll as C library by default. + Defaulting SleepyCat library name to libdb41s.lib. + Codegeneration defaulting to /MD. + + +SASL NTMakefile also understands "clean" target that you can use to clean all files generated by the compiler. + +:: + + C:\sasl> nmake /f NTMakefile clean + + Microsoft (R) Program Maintenance Utility Version 7.00.9466 + Copyright (C) Microsoft Corporation. All rights reserved. + + cd lib && nmake /f NTMakefile clean + + Microsoft (R) Program Maintenance Utility Version 7.00.9466 + Copyright (C) Microsoft Corporation. All rights reserved. + + No configuration specified. Defaulting to Release. + Using MSVCRT.dll as C library by default. + Defaulting SleepyCat library name to libdb41s.lib. + Defaulting SleepyCat include path to c:\work\isode\db\build_win32. + Defaulting SleepyCat library path to c:\work\isode\db\build_win32\Release_static. + + +Building additional plugins +--------------------------- + +Specify "GSSAPI=" parameter if you want to enable GSSAPI plugin. +Currently only =CyberSafe is supported and this will build the plugin +that links against CyberSafe Kerberos. + +GSSAPI depends on ``GSSAPI_INCLUDE`` and ``GSSAPI_LIBPATH`` parameters. +You can either specify them on the command line or edit the defaults in win32\common.mak + +Specify "SQL=" parameter if you want to enable SQL plugin. +Currently only =SQLITE is supported and this will build the plugin +that links against SQLITE (www.sqlite.org). + +SQL= depends on ``SQLITE_INCLUDES`` and ``SQLITE_LIBPATH`` parameters. +You can either specify them on the command line or edit the defaults in win32\common.mak + +Specify "NTLM=1" parameter if you want to enable NTLM plugin. +I.e. ``nmake /f NTMakefile NTLM=1`` + +Specify "SRP=1" parameter if you want to enable SRP plugin. +You can also specify "DO_SRP_SETPASS=1" if you want to enable SRP setpass functionality. + +Specify "OTP=1" parameter if you want to enable OTP plugin. + +NTLM, SRP and OTP plugins depend on OpenSSL. You can either specify +``OPENSSL_INCLUDE`` and ``OPENSSL_LIBPATH`` parameters on the command +line or edit the defaults in win32\common.mak +Note, that unless you are building one of those plugins, OpenSSL is not required! + +If you want to build multiple additional plugins at once, you can specify +multiple parameters described above, for example ``nmake /f NTMakefile NTLM=1 SRP=1 OPT=1`` + +Limitations +----------- + +Currently all plugins except KerberosV4 (kerberos4.c) and PASSDSS (passdss.c) can be built on Windows. +However limited testings was done for some plugins as listed below: + +* GSSAPI - tested using CyberSafe, +* SASLDB - only SleepyCat version can be built, +* SQL - using SQLITE, not tested + + +The following executables were built and tested (to some extent): + +* sample + + * sample-client + * sample-server + +* utils + + * sasldblistusers2 + * saslpasswd2 + * testsuite + * pluginviewer + * Note that saslauthd is *NOT* in this list. diff --git a/include/gai.h b/include/gai.h index d77ad112..59a38988 100644 --- a/include/gai.h +++ b/include/gai.h @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: gai.h,v 1.8 2006/04/10 13:36:20 mel Exp $ * * This module is besed on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/include/makemd5.c b/include/makemd5.c index eaf78aa1..d3629cf9 100644 --- a/include/makemd5.c +++ b/include/makemd5.c @@ -1,10 +1,9 @@ /* creates the md5global.h file. * Derived from KTH kerberos library bits.c program * Tim Martin - * $Id: makemd5.c,v 1.4 2003/02/13 19:55:52 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/include/sasl.h b/include/sasl.h index 54afd9ca..eb001ecc 100755 --- a/include/sasl.h +++ b/include/sasl.h @@ -126,7 +126,7 @@ /* Keep in sync with win32/common.mak */ #define SASL_VERSION_MAJOR 2 #define SASL_VERSION_MINOR 1 -#define SASL_VERSION_STEP 26 +#define SASL_VERSION_STEP 27 /* A convenience macro: same as was defined in the OpenLDAP LDAPDB */ #define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ diff --git a/lib/auxprop.c b/lib/auxprop.c index 0644e5fb..0c449599 100644 --- a/lib/auxprop.c +++ b/lib/auxprop.c @@ -1,9 +1,8 @@ /* auxprop.c - auxilliary property support * Rob Siemborski - * $Id: auxprop.c,v 1.21 2011/09/01 14:12:53 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/canonusr.c b/lib/canonusr.c index faee1038..482bce0c 100644 --- a/lib/canonusr.c +++ b/lib/canonusr.c @@ -1,9 +1,8 @@ /* canonusr.c - user canonicalization support * Rob Siemborski - * $Id: canonusr.c,v 1.22 2011/09/01 16:33:42 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/checkpw.c b/lib/checkpw.c index c38dffc4..583895c4 100644 --- a/lib/checkpw.c +++ b/lib/checkpw.c @@ -1,10 +1,9 @@ /* SASL server API implementation * Rob Siemborski * Tim Martin - * $Id: checkpw.c,v 1.79 2009/05/08 00:43:44 murch Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -72,6 +72,7 @@ #include #else #include +#include #endif #include @@ -588,6 +589,7 @@ static int read_wait(int fd, unsigned delta) errno = ETIMEDOUT; return -1; case +1: + case +2: if (FD_ISSET(fd, &rfds)) { /* Success, file descriptor is readable. */ return 0; @@ -1080,6 +1082,212 @@ static int always_true(sasl_conn_t *conn, } #endif + +#ifdef WIN32 +static char ldapsimple[] = "ldapsimple"; +INIT_ONCE ldapsimple_once=INIT_ONCE_STATIC_INIT; + +#define LDAPSIMPLE_HOST_MAX 9999 +static char* ldapsimplehost=NULL; +static char ldapsimplehost_storage[LDAPSIMPLE_HOST_MAX]; +static int ldapsimpleport = LDAP_PORT; + +//https://stackoverflow.com/questions/12257178/ldap-dn-rdn-length-limitation +#define LDAPSIMPLE_DN_MAX 32768 +static char ldapsimpledn[LDAPSIMPLE_DN_MAX]; + +static BOOL CALLBACK ldapsimple_onceinit( + PINIT_ONCE initonce, + void* conn, + PVOID *lpContext){ + + char *s; + unsigned int len; + sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn; + const sasl_utils_t *utils = sconn->sparams->utils; + + char portstr[6]; + utils->getopt(utils->getopt_context, ldapsimple, "ldapsimple_servers",&s,&len); + + if(s){ + if (len>=LDAPSIMPLE_HOST_MAX) { + sasl_seterror(conn,0,"ldapsimple_server too long)"); + return FALSE; + } + + strncpy(ldapsimplehost_storage,s,len); + ldapsimplehost_storage[len]='\0'; + ldapsimplehost=ldapsimplehost_storage; + } + + utils->getopt(utils->getopt_context, ldapsimple, "ldapsimple_port",&s,&len); + if(s){ + if(len>6){ + sasl_seterror(conn,0,"ldapsimple_port too long)"); + return FALSE; + } + strncpy(portstr,s,len); + portstr[len]='\0'; + ldapsimpleport = atoi(portstr); + if (ldapsimpleport<=0 || ldapsimpleport >65535) { + sasl_seterror(conn,0,"ldapsimple_port out of range)"); + return FALSE; + } + } + utils->getopt(utils->getopt_context, ldapsimple, "ldapsimple_dn",&s,&len); + + if(!s){ + sasl_seterror(conn,0,"ldapsimple_dn not found)"); + return FALSE; + } + + strncpy(ldapsimpledn,s,len); + ldapsimpledn[len]='\0'; + //replace %% to %, %u to %s + BOOL shouldEscape=FALSE; + { + unsigned int i=0; + unsigned int j=0; + for(;ifree(freeme); + } + if (formatdn) { + utils->free(formatdn); + } + if (ldap) { + ldap_unbind(ldap); + } +} + + +static int ldapsimple_verify_password(sasl_conn_t *conn, + const char *userid, + const char *passwd, + const char *service, + const char *user_realm) +{ + + LDAP* ldap; + ULONG res; + ULONG port = LDAP_PORT; + unsigned len; + BOOL configOk=FALSE; + char *freeme = NULL; + char *formatdn = NULL; + ULONG version = LDAP_VERSION3; + sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn; + const sasl_utils_t *utils = sconn->sparams->utils; + + configOk=InitOnceExecuteOnce(&ldapsimple_once, + ldapsimple_onceinit, + conn,NULL); + + if (!configOk){ + sasl_seterror(conn,0,"ldapsimple config failed"); + return SASL_BADPARAM; + } + + //throw @realm + if(strrchr(userid,'@') != NULL) { + char *rtmp; + + if(_sasl_strdup(userid, &freeme, NULL) != SASL_OK){ + sasl_seterror(conn,0,"can not copy userid str"); + return SASL_NOMEM; + } + + userid = freeme; + rtmp = strrchr(userid,'@'); + *rtmp = '\0'; + } + + len=snprintf(NULL,0,ldapsimpledn,userid); + + if (((len+1) >= LDAPSIMPLE_DN_MAX) || (len<0)){ + ldapsimple_clean(utils,freeme,formatdn,ldap); + sasl_seterror(conn,0,"result DN too long or encode error"); + return SASL_NOMEM; + } + + formatdn= utils->malloc(len+1); + if (formatdn == NULL) { + ldapsimple_clean(utils,freeme,formatdn,ldap); + sasl_seterror(conn,0,"not enough memory for format dn"); + return SASL_NOMEM; + } + + snprintf(formatdn,LDAPSIMPLE_DN_MAX,ldapsimpledn,userid); + + ldap=ldap_init(ldapsimplehost,ldapsimpleport); + if (ldap == NULL) { + ldapsimple_clean(utils,freeme,formatdn,ldap); + sasl_seterror(conn,0,"init ldap failed"); + return SASL_FAIL; + } + + res=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,(void*)(&version)); + if (res != LDAP_SUCCESS) { + sasl_seterror(conn,0,"ldapsimple set version to 3 failed"); + ldap_unbind(ldap); + return SASL_FAIL; + } + + res=ldap_connect(ldap,NULL); + + if (res!=LDAP_SUCCESS) { + ldapsimple_clean(utils,freeme,formatdn,ldap); + sasl_seterror(conn,0,"ldapsimple connect failed"); + return SASL_FAIL; + } + + res=ldap_simple_bind_s(ldap,formatdn,passwd); + ldapsimple_clean(utils,freeme,formatdn,ldap); + + if (res==LDAP_SUCCESS) { + return SASL_OK; + } + + return SASL_FAIL; +} +#endif + struct sasl_verify_password_s _sasl_verify_password[] = { { "auxprop", &auxprop_verify_password }, { "auxprop-hashed", &auxprop_verify_password_hashed }, @@ -1094,6 +1302,9 @@ struct sasl_verify_password_s _sasl_verify_password[] = { #endif #ifdef HAVE_ALWAYSTRUE { "alwaystrue", &always_true }, +#endif +#ifdef WIN32 + {"ldapsimple",&ldapsimple_verify_password }, #endif { NULL, NULL } }; diff --git a/lib/client.c b/lib/client.c index 31fe3462..eccdc484 100644 --- a/lib/client.c +++ b/lib/client.c @@ -1,10 +1,9 @@ /* SASL client API implementation * Rob Siemborski * Tim Martin - * $Id: client.c,v 1.86 2011/09/01 14:12:53 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/common.c b/lib/common.c index 91ba4af4..48d358b7 100644 --- a/lib/common.c +++ b/lib/common.c @@ -1,10 +1,9 @@ /* common.c - Functions that are common to server and clinet * Rob Siemborski * Tim Martin - * $Id: common.c,v 1.134 2011/09/22 14:40:30 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -86,8 +86,6 @@ static char * _sasl_get_default_win_path(void *context __attribute__((unused)), #endif -static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $"; - /* It turns out to be convenient to have a shared sasl_utils_t */ const sasl_utils_t *sasl_global_utils = NULL; diff --git a/lib/config.c b/lib/config.c index fde3757c..d1a5b973 100644 --- a/lib/config.c +++ b/lib/config.c @@ -1,10 +1,9 @@ /* SASL Config file API * Rob Siemborski * Tim Martin (originally in Cyrus distribution) - * $Id: config.c,v 1.19 2011/11/08 17:22:40 murch Exp $ */ /* - * Copyright (c) 1998-2009 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/dlopen.c b/lib/dlopen.c index b9c1c800..1cea55ff 100644 --- a/lib/dlopen.c +++ b/lib/dlopen.c @@ -1,10 +1,9 @@ /* dlopen.c--Unix dlopen() dynamic loader interface * Rob Siemborski * Rob Earhart - * $Id: dlopen.c,v 1.52 2009/04/11 10:21:43 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/external.c b/lib/external.c index 4f56db2a..d6c6c40e 100644 --- a/lib/external.c +++ b/lib/external.c @@ -1,10 +1,9 @@ /* SASL server API implementation * Rob Siemborski * Tim Martin - * $Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -57,8 +57,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $"; - /***************************** Server Section *****************************/ static int diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c index 9b5452bf..b4772118 100644 --- a/lib/getaddrinfo.c +++ b/lib/getaddrinfo.c @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: getaddrinfo.c,v 1.8 2003/03/19 18:25:28 rjs3 Exp $ * * This module is based on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/getnameinfo.c b/lib/getnameinfo.c index 177d1cb6..1d92683e 100644 --- a/lib/getnameinfo.c +++ b/lib/getnameinfo.c @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: getnameinfo.c,v 1.5 2003/02/13 19:55:54 rjs3 Exp $ * * This module is besed on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/saslint.h b/lib/saslint.h index e2edb3db..fc37c5b6 100644 --- a/lib/saslint.h +++ b/lib/saslint.h @@ -1,10 +1,9 @@ /* saslint.h - internal SASL library definitions * Rob Siemborski * Tim Martin - * $Id: saslint.h,v 1.73 2011/09/01 14:12:53 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -525,4 +525,11 @@ int get_fqhostname( int abort_if_no_fqdn ); +#ifndef HAVE_GETHOSTNAME +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); +#endif +#endif /* HAVE_GETHOSTNAME */ + #endif /* SASLINT_H */ diff --git a/lib/saslutil.c b/lib/saslutil.c index f13478a4..415bae10 100644 --- a/lib/saslutil.c +++ b/lib/saslutil.c @@ -1,10 +1,9 @@ /* saslutil.c * Rob Siemborski * Tim Martin - * $Id: saslutil.c,v 1.52 2011/09/22 14:43:01 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -80,11 +80,6 @@ * sasl_erasebuffer */ -#ifdef sun -/* gotta define gethostname ourselves on suns */ -extern int gethostname(char *, int); -#endif - char *encode_table; char *decode_table; diff --git a/lib/server.c b/lib/server.c index 51309d6d..bc92fcd1 100644 --- a/lib/server.c +++ b/lib/server.c @@ -1,10 +1,9 @@ /* SASL server API implementation * Rob Siemborski * Tim Martin - * $Id: server.c,v 1.177 2011/11/08 17:22:40 murch Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/seterror.c b/lib/seterror.c index 54300f55..c94919e3 100644 --- a/lib/seterror.c +++ b/lib/seterror.c @@ -3,11 +3,10 @@ * Rob Siemborski * Tim Martin * split from common.c by Rolf Braun - * $Id: seterror.c,v 1.10 2011/09/01 14:12:53 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,12 +24,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/staticopen.h b/lib/staticopen.h index 4e503195..3be30a26 100644 --- a/lib/staticopen.h +++ b/lib/staticopen.h @@ -1,10 +1,9 @@ /* staticopen.h * Rob Siemborski * Howard Chu - * $Id: staticopen.h,v 1.9 2011/04/05 14:50:07 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/lib/windlopen.c b/lib/windlopen.c index f514e0dd..70ac6b53 100644 --- a/lib/windlopen.c +++ b/lib/windlopen.c @@ -1,9 +1,8 @@ /* windlopen.c--Windows dynamic loader interface * Ryan Troll - * $Id: windlopen.c,v 1.17 2009/01/25 20:20:57 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/m4/ax_prog_perl_modules.m4 b/m4/ax_prog_perl_modules.m4 new file mode 100644 index 00000000..11a326c9 --- /dev/null +++ b/m4/ax_prog_perl_modules.m4 @@ -0,0 +1,77 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_prog_perl_modules.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PROG_PERL_MODULES([MODULES], [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# Checks to see if the given perl modules are available. If true the shell +# commands in ACTION-IF-TRUE are executed. If not the shell commands in +# ACTION-IF-FALSE are run. Note if $PERL is not set (for example by +# calling AC_CHECK_PROG, or AC_PATH_PROG), AC_CHECK_PROG(PERL, perl, perl) +# will be run. +# +# MODULES is a space separated list of module names. To check for a +# minimum version of a module, append the version number to the module +# name, separated by an equals sign. +# +# Example: +# +# AX_PROG_PERL_MODULES( Text::Wrap Net::LDAP=1.0.3, , +# AC_MSG_WARN(Need some Perl modules) +# +# LICENSE +# +# Copyright (c) 2009 Dean Povey +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES]) +AC_DEFUN([AX_PROG_PERL_MODULES],[dnl + +m4_define([ax_perl_modules]) +m4_foreach([ax_perl_module], m4_split(m4_normalize([$1])), + [ + m4_append([ax_perl_modules], + [']m4_bpatsubst(ax_perl_module,=,[ ])[' ]) + ]) + +# Make sure we have perl +if test -z "$PERL"; then +AC_CHECK_PROG(PERL,perl,perl) +fi + +if test "x$PERL" != x; then + ax_perl_modules_failed=0 + for ax_perl_module in ax_perl_modules; do + AC_MSG_CHECKING(for perl module $ax_perl_module) + + # Would be nice to log result here, but can't rely on autoconf internals + $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 + if test $? -ne 0; then + AC_MSG_RESULT(no); + ax_perl_modules_failed=1 + else + AC_MSG_RESULT(ok); + fi + done + + # Run optional shell commands + if test "$ax_perl_modules_failed" = 0; then + : + $2 + else + : + $3 + fi +else + AC_MSG_WARN(could not find perl) +fi])dnl diff --git a/m4/sasl2.m4 b/m4/sasl2.m4 index dd0ec69a..17df383b 100644 --- a/m4/sasl2.m4 +++ b/m4/sasl2.m4 @@ -72,8 +72,10 @@ if test "$gssapi" != no; then fi if test "$gssapi" != no; then - if test "$ac_cv_header_gssapi_h" = "yes" -o "$ac_cv_header_gssapi_gssapi_h" = "yes"; then + if test "$ac_cv_header_gssapi_h" = "yes"; then AC_DEFINE(HAVE_GSSAPI_H,,[Define if you have the gssapi.h header file]) + elif test "$ac_cv_header_gssapi_gssapi_h" = "yes"; then + AC_DEFINE(HAVE_GSSAPI_GSSAPI_H,,[Define if you have the gssapi/gssapi.h header file]) fi # We need to find out which gssapi implementation we are @@ -170,7 +172,7 @@ if test "$gssapi" != no; then GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}" GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}" elif test "$gss_impl" = "heimdal"; then - CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL" + CPPFLAGS="$CPPFLAGS" GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err" GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}" elif test "$gss_impl" = "cybersafe03"; then @@ -290,6 +292,26 @@ if test "$gssapi" != no; then cmu_save_LIBS="$LIBS" LIBS="$LIBS $GSSAPIBASE_LIBS" + AC_CHECK_FUNCS(gss_inquire_sec_context_by_oid) + if test "$ac_cv_func_gss_inquire_sec_context_by_oid" = no ; then + if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then + AC_CHECK_DECL(gss_inquire_sec_context_by_oid, + [AC_DEFINE(HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID,1, + [Define if your GSSAPI implementation defines gss_inquire_sec_context_by_oid])],, + [ + AC_INCLUDES_DEFAULT + #include + ]) + fi + fi + if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then + AC_EGREP_HEADER(GSS_C_SEC_CONTEXT_SASL_SSF, gssapi/gssapi_ext.h, + [AC_DEFINE(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF,, + [Define if your GSSAPI implementation defines GSS_C_SEC_CONTEXT_SASL_SSF])]) + fi + cmu_save_LIBS="$LIBS" + LIBS="$LIBS $GSSAPIBASE_LIBS" + AC_MSG_CHECKING([for SPNEGO support in GSSAPI libraries]) AC_TRY_RUN([ #ifdef HAVE_GSSAPI_H diff --git a/m4/sasldb.m4 b/m4/sasldb.m4 index b43eb84e..65dcd180 100644 --- a/m4/sasldb.m4 +++ b/m4/sasldb.m4 @@ -62,7 +62,7 @@ dnl named. arg. dnl How about berkeley db? CYRUS_BERKELEY_DB_CHK() if test "$dblib" = no; then - dnl How about OpenLDAP's mdb? + dnl How about OpenLDAP's lmdb? AC_CHECK_HEADER(lmdb.h, [ AC_CHECK_LIB(lmdb, mdb_env_create, SASL_DB_LIB="-llmdb"; enable_keep_db_open=yes, dblib="no")], dblib="no") diff --git a/plugins/anonymous.c b/plugins/anonymous.c index 67cdf039..f5dc364f 100644 --- a/plugins/anonymous.c +++ b/plugins/anonymous.c @@ -1,10 +1,9 @@ /* Anonymous SASL plugin * Rob Siemborski * Tim Martin - * $Id: anonymous.c,v 1.53 2009/02/13 14:46:47 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -60,8 +60,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: anonymous.c,v 1.53 2009/02/13 14:46:47 mel Exp $"; - static const char anonymous_id[] = "anonymous"; /***************************** Server Section *****************************/ diff --git a/plugins/cram.c b/plugins/cram.c index 8fe33cfb..d02e9baa 100644 --- a/plugins/cram.c +++ b/plugins/cram.c @@ -1,10 +1,9 @@ /* CRAM-MD5 SASL plugin * Rob Siemborski * Tim Martin - * $Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -65,8 +65,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $"; - /* convert a string of 8bit chars to it's representation in hex * using lowercase letters */ diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c index 66903947..ebac6e16 100644 --- a/plugins/digestmd5.c +++ b/plugins/digestmd5.c @@ -3,10 +3,9 @@ * Rob Siemborski * Tim Martin * Alexey Melnikov - * $Id: digestmd5.c,v 1.205 2011/05/13 19:18:37 murch Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -101,11 +101,6 @@ extern int strcasecmp(const char *s1, const char *s2); /* external definitions */ -#ifdef sun -/* gotta define gethostname ourselves on suns */ -extern int gethostname(char *, int); -#endif - #define bool int #ifndef TRUE @@ -122,8 +117,6 @@ extern int gethostname(char *, int); /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: digestmd5.c,v 1.205 2011/05/13 19:18:37 murch Exp $"; - /* Definitions */ #define NONCE_SIZE (32) /* arbitrary */ @@ -2451,7 +2444,7 @@ static int digestmd5_server_mech_step2(server_context_t *stext, #endif } - if (!text->nonce && text->reauth->timeout) { + if (!text->nonce && text->reauth->timeout && text->reauth->size > 0) { unsigned val = hash((char *) nonce) % text->reauth->size; /* reauth attempt or continuation of HTTP Digest on a diff --git a/plugins/gs2.c b/plugins/gs2.c index 996aab82..52cf97d9 100644 --- a/plugins/gs2.c +++ b/plugins/gs2.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. + * Copyright (c) 1998-2016 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,12 +49,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/plugins/gs2_token.c b/plugins/gs2_token.c index 2c492981..bb00143f 100644 --- a/plugins/gs2_token.c +++ b/plugins/gs2_token.c @@ -57,10 +57,6 @@ #include "gs2_token.h" -/* - * $Id: gs2_token.c,v 1.2 2011/05/23 14:45:40 mel Exp $ - */ - #ifndef HAVE_GSS_ENCAPSULATE_TOKEN /* XXXX this code currently makes the assumption that a mech oid will never be longer than 127 bytes. This assumption is not inherent in diff --git a/plugins/gssapi.c b/plugins/gssapi.c index 5204e54b..9e041069 100644 --- a/plugins/gssapi.c +++ b/plugins/gssapi.c @@ -1,10 +1,9 @@ /* GSSAPI SASL plugin * Leif Johansson * Rob Siemborski (SASL v2 Conversion) - * $Id: gssapi.c,v 1.115 2011/11/21 15:12:35 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -47,11 +47,16 @@ #ifdef HAVE_GSSAPI_H #include -#else +#elif defined(HAVE_GSSAPI_GSSAPI_H) #include #endif +#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H #include +#endif +#ifdef HAVE_GSSAPI_GSSAPI_EXT_H +#include +#endif #ifdef WIN32 # include @@ -85,8 +90,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: gssapi.c,v 1.115 2011/11/21 15:12:35 mel Exp $"; - static const char * GSSAPI_BLANK_STRING = ""; static gss_OID_desc gss_spnego_oid = { 6, (void *) "\x2b\x06\x01\x05\x05\x02" }; @@ -100,18 +103,25 @@ extern gss_OID gss_nt_service_name; /* Check if CyberSafe flag is defined */ #ifdef CSF_GSS_C_DES3_FLAG #define K5_MAX_SSF 112 +#define K5_MIN_SSF 112 #endif /* Heimdal and MIT use the following */ #ifdef GSS_KRB5_CONF_C_QOP_DES3_KD #define K5_MAX_SSF 112 +#define K5_MIN_SSF 112 #endif #endif #ifndef K5_MAX_SSF +/* All modern Kerberos implementations support AES */ +#define K5_MAX_SSF 256 +#endif + /* All Kerberos implementations support DES */ -#define K5_MAX_SSF 56 +#ifndef K5_MIN_SSF +#define K5_MIN_SSF 56 #endif /* GSSAPI SASL Mechanism by Leif Johansson @@ -650,10 +660,121 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused)) #endif } +static int gssapi_wrap_sizes(context_t *text, sasl_out_params_t *oparams) +{ + OM_uint32 maj_stat = 0, min_stat = 0; + OM_uint32 max_input = 0; + + maj_stat = gss_wrap_size_limit(&min_stat, + text->gss_ctx, + 1, + GSS_C_QOP_DEFAULT, + (OM_uint32)oparams->maxoutbuf, + &max_input); + if (maj_stat != GSS_S_COMPLETE) { + return SASL_FAIL; + } + + if (max_input > oparams->maxoutbuf) { + /* Heimdal appears to get this wrong */ + oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); + } else { + /* This code is actually correct */ + oparams->maxoutbuf = max_input; + } + + return SASL_OK; +} + +#if !defined(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF) +gss_OID_desc gss_sasl_ssf = { + 11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f" +}; +gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = &gss_sasl_ssf; +#endif + +static int gssapi_get_ssf(context_t *text, sasl_ssf_t *mech_ssf) +{ +#ifdef HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID + OM_uint32 maj_stat = 0, min_stat = 0; + gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; + gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; + uint32_t ssf; + + maj_stat = gss_inquire_sec_context_by_oid(&min_stat, text->gss_ctx, + ssf_oid, &bufset); + switch (maj_stat) { + case GSS_S_UNAVAILABLE: + /* Not supported by the library, fallback to default */ + goto fallback; + case GSS_S_COMPLETE: + if ((bufset->count != 1) || (bufset->elements[0].length != 4)) { + /* Malformed bufset, fail */ + (void)gss_release_buffer_set(&min_stat, &bufset); + return SASL_FAIL; + } + memcpy(&ssf, bufset->elements[0].value, 4); + (void)gss_release_buffer_set(&min_stat, &bufset); + *mech_ssf = ntohl(ssf); + return SASL_OK; + default: + return SASL_FAIL; + } + +fallback: +#endif + *mech_ssf = K5_MIN_SSF; + return SASL_OK; +} + +/* The GSS-SPNEGO mechanism does not do SSF negotiation, instead it uses the + * flags negotiated by GSSAPI to determine If confidentiality or integrity are + * used. These flags are stored in text->qop transalated as layers by the + * caller */ +static int gssapi_spnego_ssf(context_t *text, + sasl_security_properties_t *props, + sasl_out_params_t *oparams) +{ + int ret; + + if (text->qop & LAYER_CONFIDENTIALITY) { + oparams->encode = &gssapi_privacy_encode; + oparams->decode = &gssapi_decode; + ret = gssapi_get_ssf(text, &oparams->mech_ssf); + if (ret != SASL_OK) { + return ret; + } + } else if (text->qop & LAYER_INTEGRITY) { + oparams->encode = &gssapi_integrity_encode; + oparams->decode = &gssapi_decode; + oparams->mech_ssf = 1; + } else { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + } + + if (oparams->mech_ssf) { + ret = gssapi_wrap_sizes(text, oparams); + if (ret != SASL_OK) { + return ret; + } + } + + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + (props->maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + props->maxbufsize); + + return SASL_OK; +} + /***************************** Server Section *****************************/ static int -gssapi_server_mech_new(void *glob_context __attribute__((unused)), +gssapi_server_mech_new(void *glob_context, sasl_server_params_t *params, const char *challenge __attribute__((unused)), unsigned challen __attribute__((unused)), @@ -675,6 +796,7 @@ gssapi_server_mech_new(void *glob_context __attribute__((unused)), text->state = SASL_GSSAPI_STATE_AUTHNEG; text->http_mode = (params->flags & SASL_NEED_HTTP); + text->mech_type = (gss_OID) glob_context; *conn_context = text; @@ -688,7 +810,7 @@ gssapi_server_mech_authneg(context_t *text, unsigned clientinlen, const char **serverout, unsigned *serveroutlen, - sasl_out_params_t *oparams __attribute__((unused))) + sasl_out_params_t *oparams) { gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; @@ -967,8 +1089,9 @@ gssapi_server_mech_authneg(context_t *text, /* HTTP doesn't do any ssf negotiation */ text->state = SASL_GSSAPI_STATE_AUTHENTICATED; ret = SASL_OK; - } - else { + } else if (text->mech_type && text->mech_type == &gss_spnego_oid) { + ret = gssapi_spnego_ssf(text, ¶ms->props, oparams); + } else { /* Switch to ssf negotiation */ text->state = SASL_GSSAPI_STATE_SSFCAP; ret = SASL_CONTINUE; @@ -1022,6 +1145,7 @@ gssapi_server_mech_ssfcap(context_t *text, gss_buffer_desc real_input_token, real_output_token; OM_uint32 maj_stat = 0, min_stat = 0; unsigned char sasldata[4]; + sasl_ssf_t mech_ssf; int ret; input_token = &real_input_token; @@ -1049,21 +1173,14 @@ gssapi_server_mech_ssfcap(context_t *text, } /* build up our security properties token */ - if (text->requiressf != 0 && - (text->qop & (LAYER_INTEGRITY|LAYER_CONFIDENTIALITY))) { - if (params->props.maxbufsize > 0xFFFFFF) { - /* make sure maxbufsize isn't too large */ - /* maxbufsize = 0xFFFFFF */ - sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; - } else { - sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; - sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; - sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; - } + if (params->props.maxbufsize > 0xFFFFFF) { + /* make sure maxbufsize isn't too large */ + /* maxbufsize = 0xFFFFFF */ + sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; } else { - /* From RFC 4752: "The client verifies that the server maximum buffer is 0 - if the server does not advertise support for any security layer." */ - sasldata[1] = sasldata[2] = sasldata[3] = 0; + sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; + sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; + sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; } sasldata[0] = 0; @@ -1082,13 +1199,24 @@ gssapi_server_mech_ssfcap(context_t *text, params->props.maxbufsize) { sasldata[0] |= LAYER_INTEGRITY; } + ret = gssapi_get_ssf(text, &mech_ssf); + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } if ((text->qop & LAYER_CONFIDENTIALITY) && - text->requiressf <= K5_MAX_SSF && - text->limitssf >= K5_MAX_SSF && + text->requiressf <= mech_ssf && + text->limitssf >= mech_ssf && params->props.maxbufsize) { sasldata[0] |= LAYER_CONFIDENTIALITY; } + if ((sasldata[0] & ~LAYER_NONE) == 0) { + /* From RFC 4752: "The client verifies that the server maximum buffer is 0 + if the server does not advertise support for any security layer." */ + sasldata[1] = sasldata[2] = sasldata[3] = 0; + } + /* Remember what we want and can offer */ text->qop = sasldata[0]; @@ -1156,7 +1284,6 @@ gssapi_server_mech_ssfreq(context_t *text, gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; OM_uint32 maj_stat = 0, min_stat = 0; - OM_uint32 max_input; int layerchoice; input_token = &real_input_token; @@ -1205,10 +1332,18 @@ gssapi_server_mech_ssfreq(context_t *text, } else if (/* For compatibility with broken clients setting both bits */ (layerchoice & (LAYER_CONFIDENTIALITY | LAYER_INTEGRITY)) && (text->qop & LAYER_CONFIDENTIALITY)) { /* privacy */ + int ret; oparams->encode = &gssapi_privacy_encode; oparams->decode = &gssapi_decode; - /* FIX ME: Need to extract the proper value here */ - oparams->mech_ssf = K5_MAX_SSF; + + ret = gssapi_get_ssf(text, &oparams->mech_ssf); + if (ret != SASL_OK) { + GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return ret; + } } else { /* not a supported encryption layer */ SETERROR(text->utils, @@ -1245,27 +1380,20 @@ gssapi_server_mech_ssfreq(context_t *text, (((unsigned char *) output_token->value)[2] << 8) | (((unsigned char *) output_token->value)[3] << 0); - if (oparams->mech_ssf) { - maj_stat = gss_wrap_size_limit( &min_stat, - text->gss_ctx, - 1, - GSS_C_QOP_DEFAULT, - (OM_uint32) oparams->maxoutbuf, - &max_input); - - if(max_input > oparams->maxoutbuf) { - /* Heimdal appears to get this wrong */ - oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); - } else { - /* This code is actually correct */ - oparams->maxoutbuf = max_input; - } - } - GSS_LOCK_MUTEX_CTX(params->utils, text); gss_release_buffer(&min_stat, output_token); GSS_UNLOCK_MUTEX_CTX(params->utils, text); + if (oparams->mech_ssf) { + int ret; + + ret = gssapi_wrap_sizes(text, oparams); + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } + } + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; /* used by layers */ @@ -1393,7 +1521,7 @@ static sasl_server_plug_t gssapi_server_plugins[] = | SASL_FEAT_ALLOWS_PROXY | SASL_FEAT_DONTUSE_USERPASSWD | SASL_FEAT_SUPPORTS_HTTP, /* features */ - NULL, /* glob_context */ + &gss_spnego_oid, /* glob_context */ &gssapi_server_mech_new, /* mech_new */ &gssapi_server_mech_step, /* mech_step */ &gssapi_common_mech_dispose, /* mech_dispose */ @@ -1517,7 +1645,6 @@ static int gssapi_client_mech_step(void *conn_context, gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; OM_uint32 maj_stat = 0, min_stat = 0; - OM_uint32 max_input; gss_buffer_desc name_token; int ret; OM_uint32 req_flags = 0, out_req_flags = 0; @@ -1771,7 +1898,10 @@ static int gssapi_client_mech_step(void *conn_context, text->state = SASL_GSSAPI_STATE_AUTHENTICATED; oparams->doneflag = 1; return SASL_OK; - } + } else if (text->mech_type && text->mech_type == &gss_spnego_oid) { + oparams->doneflag = 1; + return gssapi_spnego_ssf(text, ¶ms->props, oparams); + } /* Switch to ssf negotiation */ text->state = SASL_GSSAPI_STATE_SSFCAP; @@ -1784,6 +1914,8 @@ static int gssapi_client_mech_step(void *conn_context, unsigned int alen, external = params->external_ssf; sasl_ssf_t need, allowed; char serverhas, mychoice; + sasl_ssf_t mech_ssf; + int ret; real_input_token.value = (void *) serverin; real_input_token.length = serverinlen; @@ -1818,8 +1950,17 @@ static int gssapi_client_mech_step(void *conn_context, return SASL_FAIL; } + ret = gssapi_get_ssf(text, &mech_ssf); + if (ret != SASL_OK) { + GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + /* taken from kerberos.c */ - if (secprops->min_ssf > (K5_MAX_SSF + external)) { + if (secprops->min_ssf > (mech_ssf + external)) { return SASL_TOOWEAK; } else if (secprops->min_ssf > secprops->max_ssf) { return SASL_BADPARAM; @@ -1843,8 +1984,8 @@ static int gssapi_client_mech_step(void *conn_context, /* use the strongest layer available */ if ((text->qop & LAYER_CONFIDENTIALITY) && - allowed >= K5_MAX_SSF && - need <= K5_MAX_SSF && + allowed >= mech_ssf && + need <= mech_ssf && (serverhas & LAYER_CONFIDENTIALITY)) { const char *ad_compat; @@ -1852,8 +1993,7 @@ static int gssapi_client_mech_step(void *conn_context, /* encryption */ oparams->encode = &gssapi_privacy_encode; oparams->decode = &gssapi_decode; - /* FIX ME: Need to extract the proper value here */ - oparams->mech_ssf = K5_MAX_SSF; + oparams->mech_ssf = mech_ssf; mychoice = LAYER_CONFIDENTIALITY; if (serverhas & LAYER_INTEGRITY) { @@ -1897,27 +2037,19 @@ static int gssapi_client_mech_step(void *conn_context, (((unsigned char *) output_token->value)[2] << 8) | (((unsigned char *) output_token->value)[3] << 0); - if (oparams->mech_ssf) { - maj_stat = gss_wrap_size_limit( &min_stat, - text->gss_ctx, - 1, - GSS_C_QOP_DEFAULT, - (OM_uint32) oparams->maxoutbuf, - &max_input); - - if (max_input > oparams->maxoutbuf) { - /* Heimdal appears to get this wrong */ - oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); - } else { - /* This code is actually correct */ - oparams->maxoutbuf = max_input; - } - } - GSS_LOCK_MUTEX_CTX(params->utils, text); gss_release_buffer(&min_stat, output_token); GSS_UNLOCK_MUTEX_CTX(params->utils, text); - + + if (oparams->mech_ssf) { + int ret; + + ret = gssapi_wrap_sizes(text, oparams); + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } + } /* oparams->user is always set, due to canon_user requirements. * Make sure the client actually requested it though, by checking * if our context was set. diff --git a/plugins/kerberos4.c b/plugins/kerberos4.c index 25d91830..a20904da 100644 --- a/plugins/kerberos4.c +++ b/plugins/kerberos4.c @@ -1,10 +1,9 @@ /* Kerberos4 SASL plugin * Rob Siemborski * Tim Martin - * $Id: kerberos4.c,v 1.100 2009/03/10 16:27:52 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -108,15 +108,8 @@ typedef struct krb_principal { #include #endif /* WIN32 */ -#ifdef sun -/* gotta define gethostname ourselves on suns */ -extern int gethostname(char *, int); -#endif - /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: kerberos4.c,v 1.100 2009/03/10 16:27:52 mel Exp $"; - #ifndef KEYFILE #define KEYFILE "/etc/srvtab"; #endif diff --git a/plugins/login.c b/plugins/login.c index f2a05ac5..e3da5677 100644 --- a/plugins/login.c +++ b/plugins/login.c @@ -2,10 +2,9 @@ * Rob Siemborski (SASLv2 Conversion) * contributed by Rainer Schoepf * based on PLAIN, by Tim Martin - * $Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,12 +22,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -54,8 +54,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $"; - /***************************** Server Section *****************************/ typedef struct context { @@ -315,24 +313,32 @@ static int login_client_mech_step(void *conn_context, sasl_out_params_t *oparams) { client_context_t *text = (client_context_t *) conn_context; + const char *user = NULL; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; - *clientout = NULL; - *clientoutlen = 0; - + if (!clientout) { + PARAMERROR( params->utils ); + return SASL_BADPARAM; + } + switch (text->state) { - case 1: { - const char *user = NULL; - int auth_result = SASL_OK; - int pass_result = SASL_OK; - int result; - + case 1: /* check if sec layer strong enough */ if (params->props.min_ssf > params->external_ssf) { SETERROR( params->utils, "SSF requested of LOGIN plugin"); return SASL_TOOWEAK; } + /* server should have sent request for username - we ignore it */ + if (!serverin) { + SETERROR( params->utils, + "Server didn't issue challenge for USERNAME"); + return SASL_BADPROT; + } + /* try to get the userid */ /* Note: we want to grab the authname and not the userid, which is * who we AUTHORIZE as, and will be the same as the authname @@ -344,16 +350,7 @@ static int login_client_mech_step(void *conn_context, if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) return auth_result; } - - /* try to get the password */ - if (text->password == NULL) { - pass_result = _plug_get_password(params->utils, &text->password, - &text->free_password, prompt_need); - - if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) - return pass_result; - } - + /* free prompts we got */ if (prompt_need && *prompt_need) { params->utils->free(*prompt_need); @@ -361,51 +358,30 @@ static int login_client_mech_step(void *conn_context, } /* if there are prompts not filled in */ - if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) { + if (auth_result == SASL_INTERACT) { /* make the prompt list */ result = _plug_make_prompts(params->utils, prompt_need, NULL, NULL, - auth_result == SASL_INTERACT ? - "Please enter your authentication name" : NULL, - NULL, - pass_result == SASL_INTERACT ? - "Please enter your password" : NULL, NULL, + "Please enter your authentication name", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (result != SASL_OK) return result; return SASL_INTERACT; } - - if (!text->password) { - PARAMERROR(params->utils); - return SASL_BADPARAM; - } - + result = params->canon_user(params->utils->conn, user, 0, SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); if (result != SASL_OK) return result; - /* server should have sent request for username - we ignore it */ - if (!serverin) { - SETERROR( params->utils, - "Server didn't issue challenge for USERNAME"); - return SASL_BADPROT; - } - - if (!clientout) { - PARAMERROR( params->utils ); - return SASL_BADPARAM; - } - if (clientoutlen) *clientoutlen = oparams->alen; *clientout = oparams->authid; text->state = 2; return SASL_CONTINUE; - } case 2: /* server should have sent request for password - we ignore it */ @@ -415,11 +391,41 @@ static int login_client_mech_step(void *conn_context, return SASL_BADPROT; } - if (!clientout) { + /* try to get the password */ + if (text->password == NULL) { + pass_result = _plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (pass_result == SASL_INTERACT) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + NULL, NULL, + NULL, NULL, + "Please enter your password", NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + if (!text->password) { PARAMERROR(params->utils); return SASL_BADPARAM; } - + if (clientoutlen) *clientoutlen = text->password->len; *clientout = (char *) text->password->data; @@ -438,6 +444,10 @@ static int login_client_mech_step(void *conn_context, default: params->utils->log(NULL, SASL_LOG_ERR, "Invalid LOGIN client step %d\n", text->state); + + if (clientoutlen) *clientoutlen = 0; + *clientout = NULL; + return SASL_FAIL; } diff --git a/plugins/makeinit.sh b/plugins/makeinit.sh index cc65f7d0..9f21e8dc 100644 --- a/plugins/makeinit.sh +++ b/plugins/makeinit.sh @@ -47,7 +47,7 @@ SASL_SERVER_PLUG_INIT( $mech ) done # auxprop plugins -for auxprop in sasldb sql ldapdb; do +for auxprop in sasldb sql ldapdb ldapsimple; do echo " #include @@ -91,3 +91,4 @@ done # ldapdb is also a canon_user plugin echo "SASL_CANONUSER_PLUG_INIT( ldapdb )" >> ldapdb_init.c +echo "SASL_CANONUSER_PLUG_INIT( ldapsimple )" >> ldapsimple_init.c diff --git a/plugins/ntlm.c b/plugins/ntlm.c index b5630d8c..9d4c19f2 100644 --- a/plugins/ntlm.c +++ b/plugins/ntlm.c @@ -1,6 +1,5 @@ /* NTLM SASL plugin * Ken Murchison - * $Id: ntlm.c,v 1.37 2011/11/08 17:31:55 murch Exp $ * * References: * http://www.innovation.ch/java/ntlm.html @@ -8,7 +7,7 @@ * http://www.ubiqx.org/cifs/rfc-draft/draft-leach-cifs-v1-spec-02.html */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +25,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -100,8 +100,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: ntlm.c,v 1.37 2011/11/08 17:31:55 murch Exp $"; - #ifdef WIN32 static ssize_t writev (SOCKET fd, const struct iovec *iov, size_t iovcnt); @@ -424,8 +422,8 @@ static HMAC_CTX *_plug_HMAC_CTX_new(const sasl_utils_t *utils) #if OPENSSL_VERSION_NUMBER >= 0x10100000L return HMAC_CTX_new(); #else - return utils->malloc(sizeof(EVP_MD_CTX)); -#endif + return utils->malloc(sizeof(HMAC_CTX)); +#endif } static void _plug_HMAC_CTX_free(HMAC_CTX *ctx, const sasl_utils_t *utils) @@ -437,7 +435,7 @@ static void _plug_HMAC_CTX_free(HMAC_CTX *ctx, const sasl_utils_t *utils) #else HMAC_cleanup(ctx); utils->free(ctx); -#endif +#endif } static unsigned char *V2(unsigned char *V2, sasl_secret_t *passwd, @@ -476,6 +474,7 @@ static unsigned char *V2(unsigned char *V2, sasl_secret_t *passwd, HMAC(EVP_md5(), hash, MD4_DIGEST_LENGTH, (unsigned char *) *buf, 2 * len, hash, &len); /* V2 = HMAC-MD5(NTLMv2hash, challenge + blob) + blob */ + HMAC_CTX_init(ctx); HMAC_Init_ex(ctx, hash, len, EVP_md5(), NULL); HMAC_Update(ctx, challenge, NTLM_NONCE_LENGTH); HMAC_Update(ctx, blob, bloblen); diff --git a/plugins/otp.c b/plugins/otp.c index 07a58f57..3adbff06 100644 --- a/plugins/otp.c +++ b/plugins/otp.c @@ -1,9 +1,8 @@ /* OTP SASL plugin * Ken Murchison - * $Id: otp.c,v 1.43 2011/09/01 14:12:18 mel Exp $ */ /* - * Copyright (c) 1998-2009 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -68,8 +68,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: otp.c,v 1.43 2011/09/01 14:12:18 mel Exp $"; - #define OTP_SEQUENCE_MAX 9999 #define OTP_SEQUENCE_DEFAULT 499 #define OTP_SEQUENCE_REINIT 490 @@ -104,7 +102,7 @@ static EVP_MD_CTX *_plug_EVP_MD_CTX_new(const sasl_utils_t *utils) return EVP_MD_CTX_new(); #else return utils->malloc(sizeof(EVP_MD_CTX)); -#endif +#endif } static void _plug_EVP_MD_CTX_free(EVP_MD_CTX *ctx, const sasl_utils_t *utils) @@ -115,7 +113,7 @@ static void _plug_EVP_MD_CTX_free(EVP_MD_CTX *ctx, const sasl_utils_t *utils) EVP_MD_CTX_free(ctx); #else utils->free(ctx); -#endif +#endif } /* Convert the binary data into ASCII hex */ @@ -180,13 +178,13 @@ static int generate_otp(const sasl_utils_t *utils, "OTP algorithm %s is not available", alg->evp_name); return SASL_FAIL; } - + if ((mdctx = _plug_EVP_MD_CTX_new(utils)) == NULL) { SETERROR(utils, "cannot allocate MD CTX"); r = SASL_NOMEM; goto done; } - + if ((key = utils->malloc(strlen(seed) + secret_len + 1)) == NULL) { SETERROR(utils, "cannot allocate OTP key"); r = SASL_NOMEM; @@ -201,10 +199,10 @@ static int generate_otp(const sasl_utils_t *utils, while (seq-- > 0) otp_hash(md, (char *) otp, OTP_HASH_SIZE, otp, alg->swab, mdctx); - done: +done: if (key) utils->free(key); if (mdctx) _plug_EVP_MD_CTX_free(mdctx, utils); - + return r; } diff --git a/plugins/otp.h b/plugins/otp.h index 722aca23..06ad32c5 100644 --- a/plugins/otp.h +++ b/plugins/otp.h @@ -1,9 +1,8 @@ /* OTP SASL plugin * Ken Murchison - * $Id: otp.h,v 1.2 2003/02/13 19:56:04 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/plugins/passdss.c b/plugins/passdss.c index 4304f481..a55ed60d 100644 --- a/plugins/passdss.c +++ b/plugins/passdss.c @@ -1,9 +1,8 @@ /* PASSDSS-3DES-1 SASL plugin * Ken Murchison - * $Id: passdss.c,v 1.5 2008/10/29 17:59:41 murch Exp $ */ /* - * Copyright (c) 1998-2004 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -83,8 +83,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: passdss.c,v 1.5 2008/10/29 17:59:41 murch Exp $"; - const char g[] = "2"; const char N[] = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"; diff --git a/plugins/plain.c b/plugins/plain.c index e6180a1c..1ae9e5f1 100644 --- a/plugins/plain.c +++ b/plugins/plain.c @@ -1,10 +1,9 @@ /* Plain SASL plugin * Rob Siemborski * Tim Martin - * $Id: plain.c,v 1.67 2009/06/10 16:05:19 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -57,8 +57,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: plain.c,v 1.67 2009/06/10 16:05:19 mel Exp $"; - /***************************** Server Section *****************************/ static int plain_server_mech_new(void *glob_context __attribute__((unused)), diff --git a/plugins/plugin_common.c b/plugins/plugin_common.c index f2b26bdf..70a45593 100644 --- a/plugins/plugin_common.c +++ b/plugins/plugin_common.c @@ -1,9 +1,8 @@ /* Generic SASL plugin utility functions * Rob Siemborski - * $Id: plugin_common.c,v 1.22 2011/09/01 14:12:18 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -94,7 +94,11 @@ static void sockaddr_unmapped( if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr))) return; sin4 = (struct sockaddr_in *)sa; +#ifdef s6_addr32 addr = *(uint32_t *)&sin6->sin6_addr.s6_addr32[3]; +#else + memcpy(&addr, &sin6->sin6_addr.s6_addr[12], 4); +#endif port = sin6->sin6_port; memset(sin4, 0, sizeof(struct sockaddr_in)); sin4->sin_addr.s_addr = addr; diff --git a/plugins/plugin_common.h b/plugins/plugin_common.h index 0f758975..60f1dcd3 100644 --- a/plugins/plugin_common.h +++ b/plugins/plugin_common.h @@ -1,10 +1,9 @@ /* Generic SASL plugin utility functions * Rob Siemborski - * $Id: plugin_common.h,v 1.21 2006/01/17 12:18:21 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -132,7 +132,15 @@ typedef struct buffer_info unsigned curlen; /* Current length of data in buffer */ unsigned reallen; /* total length of buffer (>= curlen) */ } buffer_info_t; + +#ifndef HAVE_GETHOSTNAME +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); #endif +#endif /* HAVE_GETHOSTNAME */ + +#endif /* SASLINT_H */ #ifdef __cplusplus extern "C" { diff --git a/plugins/sasldb.c b/plugins/sasldb.c index 51214d65..f4e5412b 100644 --- a/plugins/sasldb.c +++ b/plugins/sasldb.c @@ -1,10 +1,9 @@ /* SASL server API implementation * Rob Siemborski * Tim Martin - * $Id: sasldb.c,v 1.17 2009/03/10 14:37:03 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/plugins/scram.c b/plugins/scram.c index b0681c4f..a8030887 100644 --- a/plugins/scram.c +++ b/plugins/scram.c @@ -1,9 +1,8 @@ /* SCRAM-SHA-1 SASL plugin * Alexey Melnikov - * $Id: scram.c,v 1.26 2011/09/07 16:09:40 murch Exp $ */ /* - * Copyright (c) 2009-2010 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2009-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -69,8 +69,6 @@ /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: scram.c,v 1.26 2011/09/07 16:09:40 murch Exp $"; - #define NONCE_SIZE (32) /* arbitrary */ #define SALT_SIZE (16) /* arbitrary */ @@ -153,6 +151,8 @@ decode_saslname (char *buf) outp++; } + *outp = '\0'; + return SASL_OK; } @@ -499,6 +499,7 @@ scram_server_mech_step1(server_context_t *text, unsigned *serveroutlen, sasl_out_params_t *oparams __attribute__((unused))) { + char * authorization_id; char * authentication_id; char * p; char * nonce; @@ -604,12 +605,10 @@ scram_server_mech_step1(server_context_t *text, p++; if (p[0] == 'a' && p[1] == '=') { - text->authorization_id = p + 2; + authorization_id = p + 2; - p = strchr (text->authorization_id, ','); + p = strchr (authorization_id, ','); if (p == NULL) { - text->authorization_id = NULL; - SETERROR(sparams->utils, "At least nonce is expected in " SCRAM_SASL_MECH " input"); result = SASL_BADPROT; goto cleanup; @@ -623,7 +622,7 @@ scram_server_mech_step1(server_context_t *text, p++; /* Make a read-write copy we can modify */ - _plug_strdup(sparams->utils, text->authorization_id, &text->authorization_id, NULL); + _plug_strdup(sparams->utils, authorization_id, &text->authorization_id, NULL); if (decode_saslname(text->authorization_id) != SASL_OK) { SETERROR(sparams->utils, "Invalid authorization identity encoding in " SCRAM_SASL_MECH " input"); diff --git a/plugins/securid.c b/plugins/securid.c index f84e73bc..ef853bc6 100644 --- a/plugins/securid.c +++ b/plugins/securid.c @@ -1,9 +1,8 @@ /* SECURID SASL plugin * Ken Murchison - * $Id: securid.c,v 1.1 2006/02/07 19:27:54 murch Exp $ */ /* - * Copyright (c) 2006 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2006-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/plugins/sql.c b/plugins/sql.c index 615d3217..95f5f707 100644 --- a/plugins/sql.c +++ b/plugins/sql.c @@ -7,7 +7,6 @@ ** Simon Loader -- original mysql plugin ** Patrick Welche -- original pgsql plugin ** -** $Id: sql.c,v 1.38 2009/04/11 10:48:07 mel Exp $ ** */ diff --git a/plugins/srp.c b/plugins/srp.c index a07561c6..88f396ec 100644 --- a/plugins/srp.c +++ b/plugins/srp.c @@ -1,10 +1,9 @@ /* SRP SASL plugin * Ken Murchison * Tim Martin 3/17/00 - * $Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -101,8 +101,6 @@ typedef unsigned short uint32; /***************************** Common Section *****************************/ -static const char plugin_id[] = "$Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $"; - /* Size limit of cipher block size */ #define SRP_MAXBLOCKSIZE 16 /* Size limit of SRP buffer */ diff --git a/pwcheck/pwcheck.c b/pwcheck/pwcheck.c index 38d66fb5..ca9a2741 100644 --- a/pwcheck/pwcheck.c +++ b/pwcheck/pwcheck.c @@ -1,26 +1,45 @@ /* pwcheck.c -- Unix pwcheck daemon - $Id: pwcheck.c,v 1.8 2001/12/04 02:06:51 rjs3 Exp $ -Copyright 1998, 1999 Carnegie Mellon University - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Carnegie Mellon -University not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -******************************************************************/ + */ +/* + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #include diff --git a/pwcheck/pwcheck_getpwnam.c b/pwcheck/pwcheck_getpwnam.c index 400289c4..dad00047 100644 --- a/pwcheck/pwcheck_getpwnam.c +++ b/pwcheck/pwcheck_getpwnam.c @@ -1,27 +1,45 @@ /* pwcheck_getpwnam.c -- check passwords using getpwname() - $Id: pwcheck_getpwnam.c,v 1.1 1999/08/26 16:22:43 leg Exp $ - -Copyright 1998, 1999 Carnegie Mellon University - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Carnegie Mellon -University not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -******************************************************************/ + */ +/* + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #include diff --git a/pwcheck/pwcheck_getspnam.c b/pwcheck/pwcheck_getspnam.c index 6d607bbd..e394ff3f 100644 --- a/pwcheck/pwcheck_getspnam.c +++ b/pwcheck/pwcheck_getspnam.c @@ -1,27 +1,45 @@ /* pwcheck_getspnam.c -- check passwords using getspnam() - $Id: pwcheck_getspnam.c,v 1.1 1999/08/26 16:22:44 leg Exp $ - -Copyright 1998, 1999 Carnegie Mellon University - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Carnegie Mellon -University not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -******************************************************************/ + */ +/* + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #include diff --git a/sample/Makefile.am b/sample/Makefile.am index 6bc77aff..6b41b496 100644 --- a/sample/Makefile.am +++ b/sample/Makefile.am @@ -44,7 +44,7 @@ AM_CPPFLAGS=-I$(top_srcdir)/include -noinst_PROGRAMS = client server +noinst_PROGRAMS = client server http_digest_client EXTRA_PROGRAMS = sample-client sample-server EXTRA_DIST = NTMakefile CLEANFILES=sample-client sample-server ./.libs/*sample-client ./.libs/*sample-server @@ -54,9 +54,11 @@ sample_server_SOURCES = sample-server.c server_SOURCES = server.c common.c common.h client_SOURCES = client.c common.c common.h +http_digest_client_SOURCES = http_digest_client.c server_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) client_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) +http_digest_client_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) sample_client_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) sample_server_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) diff --git a/sample/client.c b/sample/client.c index aee8eacc..e723c6b7 100644 --- a/sample/client.c +++ b/sample/client.c @@ -1,6 +1,5 @@ -/* $Id: client.c,v 1.9 2011/09/15 09:31:49 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -18,12 +17,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sample/common.c b/sample/common.c index bcbffe40..712549fd 100644 --- a/sample/common.c +++ b/sample/common.c @@ -1,6 +1,5 @@ -/* $Id: common.c,v 1.4 2003/02/13 19:56:06 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -18,12 +17,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sample/common.h b/sample/common.h index fe56b1d0..819d0101 100644 --- a/sample/common.h +++ b/sample/common.h @@ -1,6 +1,5 @@ -/* $Id: common.h,v 1.3 2003/02/13 19:56:06 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -18,12 +17,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sample/sample-client.c b/sample/sample-client.c index 5de7e079..d0fcd4fa 100644 --- a/sample/sample-client.c +++ b/sample/sample-client.c @@ -1,9 +1,8 @@ /* sample-client.c -- sample SASL client * Rob Earhart - * $Id: sample-client.c,v 1.33 2011/09/01 14:12:18 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -87,9 +87,6 @@ int main(void) int getsubopt(char **optionp, const char * const *tokens, char **valuep); #endif -static const char -build_ident[] = "$Build: sample-client " PACKAGE "-" VERSION " $"; - static const char *progname = NULL; static int verbose; diff --git a/sample/sample-server.c b/sample/sample-server.c index 0da3de02..b24d4466 100644 --- a/sample/sample-server.c +++ b/sample/sample-server.c @@ -1,9 +1,8 @@ /* sample-server.c -- sample SASL server * Rob Earhart - * $Id: sample-server.c,v 1.34 2011/09/01 14:12:18 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -70,9 +70,6 @@ __declspec(dllimport) int getsubopt(char **optionp, const char * const *tokens, int getsubopt(char **optionp, const char * const *tokens, char **valuep); #endif -static const char -build_ident[] = "$Build: sample-server " PACKAGE "-" VERSION " $"; - static const char *progname = NULL; static int verbose; diff --git a/sample/server.c b/sample/server.c index 2a9c0ef7..86377005 100644 --- a/sample/server.c +++ b/sample/server.c @@ -1,6 +1,5 @@ -/* $Id: server.c,v 1.10 2010/12/01 14:51:53 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -18,12 +17,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/Makefile.am b/saslauthd/Makefile.am index f38097cf..75dc1057 100644 --- a/saslauthd/Makefile.am +++ b/saslauthd/Makefile.am @@ -14,7 +14,7 @@ saslauthd_SOURCES = mechanisms.c globals.h \ auth_ldap.c auth_ldap.h cache.c cache.h cfile.c cfile.h \ krbtf.c krbtf.h utils.c utils.h \ ipc_unix.c ipc_doors.c saslauthd-main.c saslauthd-main.h \ - md5.c saslauthd_md5.h md5global.h + md5.c saslauthd_md5.h EXTRA_saslauthd_sources = getaddrinfo.c getnameinfo.c saslauthd_DEPENDENCIES = saslauthd-main.o $(LTLIBOBJS_FULL) saslauthd_LDADD = @SASL_KRB_LIB@ \ @@ -40,3 +40,6 @@ saslauthd.8: saslauthd.mdoc install-data-local: saslauthd.8 $(mkinstalldirs) $(DESTDIR)$(mandir)/man8 $(INSTALL_DATA) $(srcdir)/saslauthd.8 $(DESTDIR)$(mandir)/man8/saslauthd.8 + +uninstall-local: + -rm -rf $(DESTDIR)$(mandir)/man8/saslauthd.8 diff --git a/saslauthd/auth_dce.c b/saslauthd/auth_dce.c index 42a2b600..1fe0cafa 100644 --- a/saslauthd/auth_dce.c +++ b/saslauthd/auth_dce.c @@ -31,10 +31,6 @@ * Authenticate against DCE. * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_dce.c,v 1.3 2001/12/04 02:06:54 rjs3 Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include #include diff --git a/saslauthd/auth_getpwent.c b/saslauthd/auth_getpwent.c index 84e1cc2c..828ff0aa 100644 --- a/saslauthd/auth_getpwent.c +++ b/saslauthd/auth_getpwent.c @@ -31,10 +31,6 @@ * crypt(3) based passwd file validation * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_getpwent.c,v 1.9 2009/02/13 14:23:26 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include "mechanisms.h" #include diff --git a/saslauthd/auth_httpform.c b/saslauthd/auth_httpform.c index c5c1b826..f2c81f5a 100644 --- a/saslauthd/auth_httpform.c +++ b/saslauthd/auth_httpform.c @@ -53,10 +53,6 @@ * Proxy authentication to a remote HTTP server. * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_httpform.c,v 1.2 2006/04/19 19:51:04 murch Exp $" -#endif - #include /* PUBLIC DEPENDENCIES */ diff --git a/saslauthd/auth_krb4.c b/saslauthd/auth_krb4.c index 39e2bd2a..08482a93 100644 --- a/saslauthd/auth_krb4.c +++ b/saslauthd/auth_krb4.c @@ -27,10 +27,6 @@ * DAMAGE. * END COPYRIGHT */ -#ifdef __GNUC__ -#ident "$Id: auth_krb4.c,v 1.12 2005/02/01 12:26:34 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include #include "mechanisms.h" diff --git a/saslauthd/auth_krb5.c b/saslauthd/auth_krb5.c index e3e068d3..0202867f 100644 --- a/saslauthd/auth_krb5.c +++ b/saslauthd/auth_krb5.c @@ -27,10 +27,6 @@ * DAMAGE. * END COPYRIGHT */ -#ifdef __GNUC__ -#ident "$Id: auth_krb5.c,v 1.18 2008/01/23 15:39:34 murch Exp $" -#endif - /* ok, this is wrong but the most convenient way of doing * it for now. We assume (possibly incorrectly) that if GSSAPI exists then * the Kerberos 5 headers and libraries exist. @@ -261,13 +257,14 @@ auth_krb5 ( #else /* !KRB5_HEIMDAL */ -static void k5support_log_err(krb5_context context, +static void k5support_log_err(int priority, + krb5_context context, krb5_error_code code, char const *msg) { const char *k5_msg = krb5_get_error_message(context, code); - syslog(LOG_DEBUG, "auth_krb5: %s: %s (%d)\n", msg, k5_msg, code); + syslog(priority, "auth_krb5: %s: %s (%d)\n", msg, k5_msg, code); krb5_free_error_message(context, k5_msg); } @@ -288,20 +285,20 @@ static int k5support_verify_tgt(krb5_context context, if ((k5_retcode = krb5_sname_to_principal(context, NULL, verify_principal, KRB5_NT_SRV_HST, &server))) { - k5support_log_err(context, k5_retcode, "krb5_sname_to_principal()"); + k5support_log_err(LOG_DEBUG, context, k5_retcode, "krb5_sname_to_principal()"); return 0; } if (keytabname) { if ((k5_retcode = krb5_kt_resolve(context, keytabname, &kt))) { - k5support_log_err(context, k5_retcode, "krb5_kt_resolve()"); + k5support_log_err(LOG_DEBUG, context, k5_retcode, "krb5_kt_resolve()"); goto fini; } } if ((k5_retcode = krb5_kt_read_service_key(context, kt, server, 0, 0, &keyblock))) { - k5support_log_err(context, k5_retcode, "krb5_kt_read_service_key()"); + k5support_log_err(LOG_DEBUG, context, k5_retcode, "krb5_kt_read_service_key()"); goto fini; } @@ -319,7 +316,7 @@ static int k5support_verify_tgt(krb5_context context, if ((k5_retcode = krb5_mk_req(context, &auth_context, 0, verify_principal, thishost, NULL, ccache, &packet))) { - k5support_log_err(context, k5_retcode, "krb5_mk_req()"); + k5support_log_err(LOG_DEBUG, context, k5_retcode, "krb5_mk_req()"); } if (auth_context) { @@ -333,7 +330,7 @@ static int k5support_verify_tgt(krb5_context context, if ((k5_retcode = krb5_rd_req(context, &auth_context, &packet, server, NULL, NULL, NULL))) { - k5support_log_err(context, k5_retcode, "krb5_rd_req()"); + k5support_log_err(LOG_DEBUG, context, k5_retcode, "krb5_rd_req()"); goto fini; } @@ -396,9 +393,9 @@ auth_krb5 ( return strdup("NO saslauthd principal name error"); } - if (krb5_parse_name (context, principalbuf, &auth_user)) { + if ((code = krb5_parse_name (context, principalbuf, &auth_user))) { + k5support_log_err(LOG_ERR, context, code, "krb5_parse_name()"); krb5_free_context(context); - syslog(LOG_ERR, "auth_krb5: krb5_parse_name"); return strdup("NO saslauthd internal error"); } @@ -407,17 +404,17 @@ auth_krb5 ( return strdup("NO saslauthd internal error"); } - if (krb5_cc_resolve(context, tfname, &ccache)) { + if ((code = krb5_cc_resolve(context, tfname, &ccache))) { + k5support_log_err(LOG_ERR, context, code, "krb5_cc_resolve()"); krb5_free_principal(context, auth_user); krb5_free_context(context); - syslog(LOG_ERR, "auth_krb5: krb5_cc_resolve"); return strdup("NO saslauthd internal error"); } - if (krb5_cc_initialize (context, ccache, auth_user)) { + if ((code = krb5_cc_initialize (context, ccache, auth_user))) { + k5support_log_err(LOG_ERR, context, code, "krb5_cc_initialize()"); krb5_free_principal(context, auth_user); krb5_free_context(context); - syslog(LOG_ERR, "auth_krb5: krb5_cc_initialize"); return strdup("NO saslauthd internal error"); } @@ -427,19 +424,19 @@ auth_krb5 ( if ((code = krb5_get_init_creds_password(context, &creds, auth_user, password, NULL, NULL, 0, NULL, &opts))) { + k5support_log_err(LOG_ERR, context, code, "krb5_get_init_creds_password()"); krb5_cc_destroy(context, ccache); krb5_free_principal(context, auth_user); krb5_free_context(context); - syslog(LOG_ERR, "auth_krb5: krb5_get_init_creds_password: %d", code); return strdup("NO saslauthd internal error"); } /* at this point we should have a TGT. Let's make sure it is valid */ - if (krb5_cc_store_cred(context, ccache, &creds)) { + if ((code = krb5_cc_store_cred(context, ccache, &creds))) { + k5support_log_err(LOG_ERR, context, code, "krb5_cc_store_cred()"); krb5_free_principal(context, auth_user); krb5_cc_destroy(context, ccache); krb5_free_context(context); - syslog(LOG_ERR, "auth_krb5: krb5_cc_store_cred"); return strdup("NO saslauthd internal error"); } diff --git a/saslauthd/auth_ldap.c b/saslauthd/auth_ldap.c index 2cd50f37..7ba294f9 100644 --- a/saslauthd/auth_ldap.c +++ b/saslauthd/auth_ldap.c @@ -30,10 +30,6 @@ * Authenticate against LDAP. * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_ldap.c,v 1.17 2004/12/08 12:12:27 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include #include diff --git a/saslauthd/auth_rimap.c b/saslauthd/auth_rimap.c index bdf89b3f..eb779a1d 100644 --- a/saslauthd/auth_rimap.c +++ b/saslauthd/auth_rimap.c @@ -53,10 +53,6 @@ * Proxy authentication to a remote IMAP (or IMSP) server. * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_rimap.c,v 1.14 2011/09/22 14:39:03 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include "mechanisms.h" diff --git a/saslauthd/auth_sasldb.c b/saslauthd/auth_sasldb.c index 720d339a..6ea7b392 100644 --- a/saslauthd/auth_sasldb.c +++ b/saslauthd/auth_sasldb.c @@ -31,10 +31,6 @@ * crypt(3) based passwd file validation * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: auth_sasldb.c,v 1.6 2009/02/20 22:08:56 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include "mechanisms.h" diff --git a/saslauthd/auth_shadow.c b/saslauthd/auth_shadow.c index d69e380f..743b6c05 100644 --- a/saslauthd/auth_shadow.c +++ b/saslauthd/auth_shadow.c @@ -27,10 +27,6 @@ * DAMAGE. * END COPYRIGHT */ -#ifdef __GNUC__ -#ident "$Id: auth_shadow.c,v 1.12 2009/08/14 14:58:38 mel Exp $" -#endif - #include /* PUBLIC DEPENDENCIES */ diff --git a/saslauthd/auth_sia.c b/saslauthd/auth_sia.c index 72268b2e..ca30cab6 100644 --- a/saslauthd/auth_sia.c +++ b/saslauthd/auth_sia.c @@ -27,10 +27,6 @@ * DAMAGE. * END COPYRIGHT */ -#ifdef __GNUC__ -#ident "$Id: auth_sia.c,v 1.3 2001/12/04 02:06:55 rjs3 Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include "mechanisms.h" diff --git a/saslauthd/cache.c b/saslauthd/cache.c index 543e1766..0d78a735 100644 --- a/saslauthd/cache.c +++ b/saslauthd/cache.c @@ -97,7 +97,7 @@ int cache_init(void) { if (table_size == 0) table_size = CACHE_DEFAULT_TABLE_SIZE; - bytes = (table_size * CACHE_MAX_BUCKETS_PER * sizeof(struct bucket)) \ + bytes = (table_size * CACHE_MAX_BUCKETS_PER * sizeof(struct bucket)) + sizeof(struct stats) + 256; @@ -242,9 +242,10 @@ int cache_lookup(const char *user, const char *realm, const char *service, const high_bucket = low_bucket + CACHE_MAX_BUCKETS_PER; for (ref_bucket = low_bucket; ref_bucket < high_bucket; ref_bucket++) { - if (strcmp(user, ref_bucket->creds + ref_bucket->user_offt) == 0 && \ - strcmp (realm, ref_bucket->creds + ref_bucket->realm_offt) == 0 && \ - strcmp(service, ref_bucket->creds + ref_bucket->service_offt) == 0) { + if (strcmp(user, ref_bucket->creds + ref_bucket->user_offt) == 0 && + strcmp (realm, ref_bucket->creds + ref_bucket->realm_offt) == 0 && + strcmp(service, ref_bucket->creds + ref_bucket->service_offt) == 0 && + ref_bucket->created > epoch_timeout) { read_bucket = ref_bucket; break; } @@ -259,12 +260,12 @@ int cache_lookup(const char *user, const char *realm, const char *service, const * best bucket to place the new entry (CACHE_FLUSH_WITH_RESCAN). **************************************************************/ - if (read_bucket != NULL && read_bucket->created > epoch_timeout) { + if (read_bucket != NULL) { if (memcmp(pwd_digest, read_bucket->pwd_digest, 16) == 0) { if (flags & VERBOSE) - logger(L_DEBUG, L_FUNC, debug, user, realm, service, "found with valid passwd"); + logger(L_DEBUG, L_FUNC, debug, user, service, realm, "found with valid passwd"); cache_un_lock(hash_offset); table_stats->hits++; @@ -272,14 +273,14 @@ int cache_lookup(const char *user, const char *realm, const char *service, const } if (flags & VERBOSE) - logger(L_DEBUG, L_FUNC, debug, user, realm, service, "found with invalid passwd, update pending"); + logger(L_DEBUG, L_FUNC, debug, user, service, realm, "found with invalid passwd, update pending"); result->status = CACHE_FLUSH; } else { if (flags & VERBOSE) - logger(L_DEBUG, L_FUNC, debug, user, realm, service, "not found, update pending"); + logger(L_DEBUG, L_FUNC, debug, user, service, realm, "not found, update pending"); result->status = CACHE_FLUSH_WITH_RESCAN; } diff --git a/saslauthd/cfile.c b/saslauthd/cfile.c index 386b07a6..8e983d3a 100644 --- a/saslauthd/cfile.c +++ b/saslauthd/cfile.c @@ -2,10 +2,9 @@ * Dave Eckhardt * Rob Siemborski * Tim Martin (originally in Cyrus distribution) - * $Id: cfile.c,v 1.1 2005/01/19 00:11:41 shadow Exp $ */ /* - * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2001-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,12 +22,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/cfile.h b/saslauthd/cfile.h index 29cab98d..c383a304 100644 --- a/saslauthd/cfile.h +++ b/saslauthd/cfile.h @@ -2,10 +2,9 @@ * Dave Eckhardt * Rob Siemborski * Tim Martin (originally in Cyrus distribution) - * $Id: cfile.h,v 1.1 2005/01/19 00:11:42 shadow Exp $ */ /* - * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2001-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,12 +22,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/getaddrinfo.c b/saslauthd/getaddrinfo.c index 2ab42cb8..357736f4 100644 --- a/saslauthd/getaddrinfo.c +++ b/saslauthd/getaddrinfo.c @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: getaddrinfo.c,v 1.2 2003/02/13 19:56:07 rjs3 Exp $ * * This module is besed on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/getnameinfo.c b/saslauthd/getnameinfo.c index 970425b3..88c2fd73 100644 --- a/saslauthd/getnameinfo.c +++ b/saslauthd/getnameinfo.c @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: getnameinfo.c,v 1.2 2003/02/13 19:56:07 rjs3 Exp $ * * This module is besed on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/include/gai.h b/saslauthd/include/gai.h index 54b93ffd..6a60eea0 100644 --- a/saslauthd/include/gai.h +++ b/saslauthd/include/gai.h @@ -1,12 +1,11 @@ /* * Mar 8, 2000 by Hajimu UMEMOTO - * $Id: gai.h,v 1.2 2003/02/13 19:56:13 rjs3 Exp $ * * This module is besed on ssh-1.2.27-IPv6-1.5 written by * KIKUCHI Takahiro */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,12 +23,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/saslauthd/ipc_doors.c b/saslauthd/ipc_doors.c index 92f403c0..4e459d7c 100644 --- a/saslauthd/ipc_doors.c +++ b/saslauthd/ipc_doors.c @@ -203,13 +203,42 @@ void ipc_cleanup() { logger(L_DEBUG, L_FUNC, "door file removed: %s", door_file); } +/************************************************************* + * It is very rare but not impossible to have door_return actually return. + * When it does, it leaks a reference count. Prevent that. + **************************************************************/ + +void +safe_door_return(char *data, size_t len) +{ + (void) door_return(data, len, NULL, 0); + /* + * If door_return() failed, and our response wasn't empty, try sending + * an empty response. If that still doesn't work, then we must exit + * this thread. + */ + if (len > 0) { + logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno)); + (void) door_return(NULL, 0, NULL, 0); + } + logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno)); + + pthread_mutex_lock(&num_lock); + if (num_procs > 0 && num_thr > 0) { + num_thr--; + } + pthread_mutex_unlock(&num_lock); + pthread_exit(NULL); +} + /************************************************************* * Handle the door data, pass the request off to * do_auth() back in saslauthd-main.c, then send the * result back through the door. **************************************************************/ -void do_request(void *cookie, char *data, size_t datasize, door_desc_t *dp, size_t ndesc) { +static void +do_request(void *cookie, char *data, size_t datasize, door_desc_t *dp, uint_t ndesc) { unsigned short count = 0; /* input/output data byte count */ char *response = NULL; /* response to send to the client */ char response_buff[1024]; /* temporary response buffer */ @@ -227,6 +256,12 @@ void do_request(void *cookie, char *data, size_t datasize, door_desc_t *dp, size **************************************************************/ dataend = data + datasize; + if (data == NULL || datasize < sizeof(unsigned short)) { + logger(L_ERR, L_FUNC, "Bad data"); + send_no(""); + return; + } + /* login id */ memcpy(&count, data, sizeof(unsigned short)); @@ -328,8 +363,7 @@ void do_request(void *cookie, char *data, size_t datasize, door_desc_t *dp, size if (flags & VERBOSE) logger(L_DEBUG, L_FUNC, "response: %s", response_buff); - if(door_return(response_buff, strlen(response_buff), NULL, 0) < 0) - logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno)); + safe_door_return(response_buff, strlen(response_buff)); return; } @@ -353,14 +387,17 @@ void need_thread(door_info_t *di) { pthread_create(&newt, &thread_attr, &server_thread, NULL); } - + /************************************************************* * Start a new server thread. * Make it available for door invocations. **************************************************************/ void *server_thread(void *arg) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - door_return(NULL, 0, NULL, 0); + + safe_door_return(NULL, 0); + + return (void *) NULL; } /************************************************************* @@ -382,8 +419,7 @@ void send_no(char *mesg) { if (flags & VERBOSE) logger(L_DEBUG, L_FUNC, "response: %s", buff); - if(door_return(buff, strlen(buff), NULL, 0) < 0) - logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno)); + safe_door_return(buff, strlen(buff)); return; } diff --git a/saslauthd/krbtf.c b/saslauthd/krbtf.c index 370850dc..16783135 100644 --- a/saslauthd/krbtf.c +++ b/saslauthd/krbtf.c @@ -1,6 +1,6 @@ /* MODULE: krbtf */ /* - * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2001-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -18,12 +18,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -41,7 +42,6 @@ /* * Dec 4, 2002 by Dave Eckhardt - * $Id: krbtf.c,v 1.2 2005/02/14 05:18:36 shadow Exp $ * This is inspired by code which was identical in both * auth_krb4.c and auth_krb5.c. This code is shared * between the two implementations, contains protection @@ -50,10 +50,6 @@ * needless disk i/o. */ -#ifdef __GNUC__ -#ident "$Id: krbtf.c,v 1.2 2005/02/14 05:18:36 shadow Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include #include diff --git a/saslauthd/lak.c b/saslauthd/lak.c index 17f58baf..8cb6aa30 100644 --- a/saslauthd/lak.c +++ b/saslauthd/lak.c @@ -1378,8 +1378,8 @@ static int lak_group_member( } done:; - if (res) - ldap_msgfree(res); + if (res) + ldap_msgfree(res); if (group_dn) free(group_dn); if (group_filter) @@ -1391,7 +1391,7 @@ done:; if (dn_bv) ber_bvfree(dn_bv); - return rc; + return rc; } static int lak_auth_custom( @@ -1453,8 +1453,25 @@ static int lak_auth_bind( if ( rc == LAK_OK && (ISSET(lak->conf->group_dn) || ISSET(lak->conf->group_filter)) ) - rc = lak_group_member(lak, user, service, realm, dn->value); + { + /* restore config bind */ + lak_unbind(lak); + rc = lak_user(<> + lak->conf->bind_dn, + lak->conf->id, + lak->conf->authz_id, + lak->conf->mech, + lak->conf->realm, + lak->conf->password, + &lu); + if (rc != LAK_OK) + goto done; + rc = lak_bind(lak, lu); + if (rc != LAK_OK) + goto done; + rc = lak_group_member(lak, user, service, realm, dn->value); + } done:; if (lu) lak_user_free(lu); @@ -1712,6 +1729,44 @@ static int lak_check_password( #ifdef HAVE_OPENSSL +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static void *OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) + memset(ret, 0, num); + return ret; +} + +#if OPENSSL_VERSION_NUMBER < 0x00907000L +static EVP_MD_CTX *EVP_MD_CTX_create(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +static void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +{ + if (ctx != NULL) + memset(ctx, '\0', sizeof *ctx); + OPENSSL_free(ctx); +} +#endif /* OPENSSL_VERSION_NUMBER < 0x00907000L */ + +#define EVP_MD_CTX_new() EVP_MD_CTX_create() +#define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx)) + +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + static int lak_base64_decode( const char *src, char **ret, @@ -1720,20 +1775,28 @@ static int lak_base64_decode( int rc, i, tlen = 0; char *text; - EVP_ENCODE_CTX EVP_ctx; + EVP_ENCODE_CTX *enc_ctx = EVP_ENCODE_CTX_new(); + + if (enc_ctx == NULL) + return LAK_NOMEM; text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1); - if (text == NULL) + if (text == NULL) { + EVP_ENCODE_CTX_free(enc_ctx); return LAK_NOMEM; + } - EVP_DecodeInit(&EVP_ctx); - rc = EVP_DecodeUpdate(&EVP_ctx, (unsigned char *) text, &i, (const unsigned char *)src, strlen(src)); + EVP_DecodeInit(enc_ctx); + rc = EVP_DecodeUpdate(enc_ctx, (unsigned char *) text, &i, (const unsigned char *)src, strlen(src)); if (rc < 0) { + EVP_ENCODE_CTX_free(enc_ctx); free(text); return LAK_FAIL; } tlen += i; - EVP_DecodeFinal(&EVP_ctx, (unsigned char *) text, &i); + EVP_DecodeFinal(enc_ctx, (unsigned char *) text, &i); + + EVP_ENCODE_CTX_free(enc_ctx); *ret = text; if (rlen != NULL) @@ -1749,7 +1812,7 @@ static int lak_check_hashed( { int rc, clen; LAK_HASH_ROCK *hrock = (LAK_HASH_ROCK *) rock; - EVP_MD_CTX mdctx; + EVP_MD_CTX *mdctx; const EVP_MD *md; unsigned char digest[EVP_MAX_MD_SIZE]; char *cred; @@ -1758,17 +1821,24 @@ static int lak_check_hashed( if (!md) return LAK_FAIL; + mdctx = EVP_MD_CTX_new(); + if (!mdctx) + return LAK_NOMEM; + rc = lak_base64_decode(hash, &cred, &clen); - if (rc != LAK_OK) + if (rc != LAK_OK) { + EVP_MD_CTX_free(mdctx); return rc; + } - EVP_DigestInit(&mdctx, md); - EVP_DigestUpdate(&mdctx, passwd, strlen(passwd)); + EVP_DigestInit(mdctx, md); + EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); if (hrock->salted) { - EVP_DigestUpdate(&mdctx, &cred[EVP_MD_size(md)], + EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)], clen - EVP_MD_size(md)); } - EVP_DigestFinal(&mdctx, digest, NULL); + EVP_DigestFinal(mdctx, digest, NULL); + EVP_MD_CTX_free(mdctx); rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md)); free(cred); diff --git a/saslauthd/mechanisms.c b/saslauthd/mechanisms.c index ab977cf4..48cc5513 100644 --- a/saslauthd/mechanisms.c +++ b/saslauthd/mechanisms.c @@ -30,10 +30,6 @@ * authentication drivers. * END SYNOPSIS */ -#ifdef __GNUC__ -#ident "$Id: mechanisms.c,v 1.8 2006/03/13 20:17:09 mel Exp $" -#endif - /* PUBLIC DEPENDENCIES */ #include "mechanisms.h" diff --git a/saslauthd/mechanisms.h b/saslauthd/mechanisms.h index 3ed8d1c0..59fb1391 100644 --- a/saslauthd/mechanisms.h +++ b/saslauthd/mechanisms.h @@ -25,10 +25,6 @@ * DAMAGE. * END COPYRIGHT */ -#ifdef __GNUC__ -#ident "$Id: mechanisms.h,v 1.10 2006/03/13 20:17:09 mel Exp $" -#endif - #ifndef _MECHANISMS_H #define _MECHANISMS_H diff --git a/saslauthd/testsaslauthd.c b/saslauthd/testsaslauthd.c index 5de666e7..7c1adfd4 100644 --- a/saslauthd/testsaslauthd.c +++ b/saslauthd/testsaslauthd.c @@ -2,7 +2,7 @@ * Rob Siemborski */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sasldb/allockey.c b/sasldb/allockey.c index 3d09034d..f5f673d3 100644 --- a/sasldb/allockey.c +++ b/sasldb/allockey.c @@ -1,10 +1,9 @@ /* db_berkeley.c--SASL berkeley db interface * Rob Siemborski * Tim Martin - * $Id: allockey.c,v 1.9 2008/10/30 14:17:08 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sasldb/db_berkeley.c b/sasldb/db_berkeley.c index 4104acdb..475b532b 100644 --- a/sasldb/db_berkeley.c +++ b/sasldb/db_berkeley.c @@ -1,10 +1,9 @@ /* db_berkeley.c--SASL berkeley db interface * Rob Siemborski * Tim Martin - * $Id: db_berkeley.c,v 1.11 2011/09/12 08:50:47 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sasldb/db_gdbm.c b/sasldb/db_gdbm.c index 8f4a7905..ee56a6bf 100644 --- a/sasldb/db_gdbm.c +++ b/sasldb/db_gdbm.c @@ -1,10 +1,9 @@ /* db_gdbm.c--SASL gdbm interface * Rob Siemborski * Rob Earhart - * $Id: db_gdbm.c,v 1.4 2003/02/13 19:56:14 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -90,7 +90,7 @@ int _sasldb_getdata(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -175,7 +175,7 @@ int _sasldb_putdata(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -233,7 +233,7 @@ int _sasl_check_db(const sasl_utils_t *utils, if(!utils) return SASL_BADPARAM; if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -242,7 +242,7 @@ int _sasl_check_db(const sasl_utils_t *utils, } ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE, - &vf, &cntxt); + (sasl_callback_ft *)&vf, &cntxt); if(ret != SASL_OK) { utils->seterror(conn, 0, "No verifyfile callback"); @@ -287,7 +287,7 @@ sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { diff --git a/sasldb/db_lmdb.c b/sasldb/db_lmdb.c index ca54b46f..71a70d5f 100644 --- a/sasldb/db_lmdb.c +++ b/sasldb/db_lmdb.c @@ -1,6 +1,5 @@ /* db_lmdb.c--SASL OpenLDAP LMDB interface * Howard Chu - * $Id$ */ /* * Copyright (C) 2011-2012 Howard Chu, All rights reserved. @@ -21,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -419,8 +419,8 @@ int _sasl_check_db(const sasl_utils_t *utils, } #if defined(KEEP_DB_OPEN) -void sasldb_auxprop_free (void *glob_context, - const sasl_utils_t *utils) +void sasldb_auxprop_free (void *glob_context __attribute__((unused)), + const sasl_utils_t *utils __attribute__((unused))) { do_close(); } diff --git a/sasldb/db_ndbm.c b/sasldb/db_ndbm.c index 035ea1e0..e6ec5642 100644 --- a/sasldb/db_ndbm.c +++ b/sasldb/db_ndbm.c @@ -1,10 +1,9 @@ /* db_ndbm.c--SASL ndbm interface * Rob Siemborski * Rob Earhart - * $Id: db_ndbm.c,v 1.5 2003/02/13 19:56:14 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -50,6 +50,7 @@ #include #include #include +#include #include "sasldb.h" static int db_ok = 0; @@ -92,7 +93,7 @@ int _sasldb_getdata(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -101,7 +102,8 @@ int _sasldb_getdata(const sasl_utils_t *utils, } db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR); if (! db) { - utils->seterror(cntxt, 0, "Could not open db"); + utils->seterror(cntxt, 0, "Could not open db `%s': %s", + path, strerror(errno)); result = SASL_FAIL; goto cleanup; } @@ -109,7 +111,9 @@ int _sasldb_getdata(const sasl_utils_t *utils, dkey.dsize = key_len; dvalue = dbm_fetch(db, dkey); if (! dvalue.dptr) { - utils->seterror(cntxt, 0, "no user in db"); + utils->seterror(cntxt, SASL_NOLOG, + "user: %s@%s property: %s not found in sasldb", + authid, realm, propName); result = SASL_NOUSER; goto cleanup; } @@ -170,7 +174,7 @@ int _sasldb_putdata(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -182,10 +186,12 @@ int _sasldb_putdata(const sasl_utils_t *utils, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (! db) { + utils->seterror(conn, 0, "Could not open db `%s' for writing: %s", + path, strerror(errno)); utils->log(conn, SASL_LOG_ERR, "SASL error opening password file. " "Do you have write permissions?\n"); - utils->seterror(conn, 0, "Could not open db for write"); + result = SASL_FAIL; goto cleanup; } dkey.dptr = key; @@ -234,7 +240,7 @@ int _sasl_check_db(const sasl_utils_t *utils, if(!utils) return SASL_BADPARAM; if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -249,7 +255,7 @@ int _sasl_check_db(const sasl_utils_t *utils, } ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE, - &vf, &cntxt); + (sasl_callback_ft *)&vf, &cntxt); if(ret != SASL_OK) { utils->seterror(conn, 0, "No verifyfile callback"); @@ -311,7 +317,7 @@ sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils, } if (utils->getcallback(conn, SASL_CB_GETOPT, - &getopt, &cntxt) == SASL_OK) { + (sasl_callback_ft *)&getopt, &cntxt) == SASL_OK) { const char *p; if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK && p != NULL && *p != 0) { @@ -322,7 +328,8 @@ sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils, db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR); if(!db) { - utils->seterror(conn, 0, "Could not open db"); + utils->seterror(conn, 0, "Could not open db `%s': %s", + path, strerror(errno)); return NULL; } diff --git a/sasldb/db_none.c b/sasldb/db_none.c index 45c4bbe5..12eaedb2 100644 --- a/sasldb/db_none.c +++ b/sasldb/db_none.c @@ -1,10 +1,9 @@ /* db_none.c--provides linkage for systems which lack a backend db lib * Rob Siemborski * Rob Earhart - * $Id: db_none.c,v 1.3 2003/02/13 19:56:14 rjs3 Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/sasldb/sasldb.h b/sasldb/sasldb.h index 06183ebd..8068a8b0 100644 --- a/sasldb/sasldb.h +++ b/sasldb/sasldb.h @@ -1,10 +1,9 @@ /* sasldb.h - SASLdb library header * Rob Siemborski * Tim Martin - * $Id: sasldb.h,v 1.6 2006/04/03 10:58:20 mel Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -73,7 +73,7 @@ int _sasldb_putdata(const sasl_utils_t *utils, const char *data, size_t data_len); /* Should be run before any db access is attempted */ -int _sasl_check_db(const sasl_utils_t *utils, +LIBSASL_API int _sasl_check_db(const sasl_utils_t *utils, sasl_conn_t *conn); /* These allow iterating through the keys of the database */ @@ -84,15 +84,15 @@ typedef int (* sasldb_list_callback_t) (const char *authid, const char *property, void *rock); -sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils, +LIBSASL_API sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils, sasl_conn_t *conn); -int _sasldb_getnextkey(const sasl_utils_t *utils, +LIBSASL_API int _sasldb_getnextkey(const sasl_utils_t *utils, sasldb_handle handle, char *out, const size_t max_out, size_t *out_len); -int _sasldb_releasekeyhandle(const sasl_utils_t *utils, +LIBSASL_API int _sasldb_releasekeyhandle(const sasl_utils_t *utils, sasldb_handle handle); -int _sasldb_listusers(const sasl_utils_t *utils, +LIBSASL_API int _sasldb_listusers(const sasl_utils_t *utils, sasl_conn_t *context, sasldb_list_callback_t callback, void *callback_rock); diff --git a/utils/dbconverter-2.c b/utils/dbconverter-2.c index 33e18fb2..c53d4039 100644 --- a/utils/dbconverter-2.c +++ b/utils/dbconverter-2.c @@ -1,10 +1,9 @@ /* dbconverter-2.c -- convert libsasl v1 sasldb's to SASLv2 format - * $Id: dbconverter-2.c,v 1.8 2003/02/13 19:56:17 rjs3 Exp $ * Rob Siemborski * based on SASLv1 sasldblistusers */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/utils/pluginviewer.c b/utils/pluginviewer.c index 41b859de..f031351c 100644 --- a/utils/pluginviewer.c +++ b/utils/pluginviewer.c @@ -1,10 +1,8 @@ /* pluginviewer.c -- Plugin Viewer for CMU SASL * Alexey Melnikov, Isode Ltd. - * - * $Id: pluginviewer.c,v 1.11 2011/09/01 14:12:18 mel Exp $ */ /* - * Copyright (c) 2004 Carnegie Mellon University. All rights reserved. + * Copyright (c) 2004-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -88,9 +87,6 @@ int main(void) int getsubopt(char **optionp, const char * const *tokens, char **valuep); #endif -static const char -build_ident[] = "$Build: pluginviewer " PACKAGE "-" VERSION " $"; - static const char *progname = NULL; /* SASL authentication methods (client or server side). NULL means all. */ static char *sasl_mech = NULL; diff --git a/utils/sasldblistusers.c b/utils/sasldblistusers.c index f755866a..f1b58210 100644 --- a/utils/sasldblistusers.c +++ b/utils/sasldblistusers.c @@ -1,10 +1,9 @@ /* sasldblistusers.c -- list users in sasldb - * $Id: sasldblistusers.c,v 1.24 2011/09/01 14:12:18 mel Exp $ * Rob Siemborski * Tim Martin */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/utils/saslpasswd.c b/utils/saslpasswd.c index b633f8f8..0815ed7a 100644 --- a/utils/saslpasswd.c +++ b/utils/saslpasswd.c @@ -2,7 +2,7 @@ * Rob Earhart */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -75,8 +76,6 @@ char myhostname[1025]; #define PW_BUF_SIZE 2048 -static const char build_ident[] = "$Build: saslpasswd " PACKAGE "-" VERSION " $"; - const char *progname = NULL; char *sasldb_path = NULL; diff --git a/utils/sfsasl.c b/utils/sfsasl.c index 431b06c9..efcd2f69 100644 --- a/utils/sfsasl.c +++ b/utils/sfsasl.c @@ -4,7 +4,7 @@ #include /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +22,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/utils/sfsasl.h b/utils/sfsasl.h index 284ac581..ce41d539 100644 --- a/utils/sfsasl.h +++ b/utils/sfsasl.h @@ -2,7 +2,7 @@ #define SFSASL_H /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,12 +20,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: diff --git a/utils/testsuite.c b/utils/testsuite.c index 7e4e852a..12da7f74 100644 --- a/utils/testsuite.c +++ b/utils/testsuite.c @@ -1,10 +1,9 @@ /* testsuite.c -- Stress the library a little * Rob Siemborski * Tim Martin - * $Id: testsuite.c,v 1.49 2011/11/09 15:49:47 murch Exp $ */ /* - * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,12 +21,13 @@ * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact - * Office of Technology Transfer * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: @@ -263,15 +263,15 @@ void *test_malloc(size_t size) void *test_realloc(void *ptr, size_t size) { void *out; - mem_info_t **prev, *cur; + mem_info_t *cur; out = realloc(ptr, size); if(DETAILED_MEMORY_DEBUGGING) - fprintf(stderr, " %p = realloc(%p,%d)\n", + fprintf(stderr, " %p = realloc(%p,%zd)\n", out, ptr, size); - prev = &head; cur = head; + cur = head; while(cur) { if(cur->addr == ptr) { @@ -280,7 +280,6 @@ void *test_realloc(void *ptr, size_t size) return out; } - prev = &cur->next; cur = cur->next; } @@ -308,7 +307,7 @@ void *test_calloc(size_t nmemb, size_t size) out = calloc(nmemb, size); if(DETAILED_MEMORY_DEBUGGING) - fprintf(stderr, " %p = calloc(%d, %d)\n", + fprintf(stderr, " %p = calloc(%zd, %zd)\n", out, nmemb, size); if(out) { @@ -370,7 +369,7 @@ int mem_stat() fprintf(stderr, " Currently Still Allocated:\n"); for(cur = head; cur; cur = cur->next) { - fprintf(stderr, " %p (%5d)\t", cur->addr, cur->size); + fprintf(stderr, " %p (%5zd)\t", cur->addr, cur->size); for(data = (unsigned char *) cur->addr, n = 0; n < (cur->size > 12 ? 12 : cur->size); n++) { if (isprint((int) data[n])) @@ -481,6 +480,7 @@ static struct sasl_callback goodsasl_cb[] = { { SASL_CB_LIST_END, NULL, NULL } }; +#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) int givebadpath(void * context __attribute__((unused)), char ** path) { @@ -498,6 +498,7 @@ static struct sasl_callback withbadpathsasl_cb[] = { { SASL_CB_GETPATH, (sasl_callback_ft)&givebadpath, NULL }, { SASL_CB_LIST_END, NULL, NULL } }; +#endif int giveokpath(void * context __attribute__((unused)), const char ** path) @@ -2709,7 +2710,7 @@ void create_ids(void) const char challenge[] = "<1896.697170952@cyrus.andrew.cmu.edu>"; MD5_CTX ctx; unsigned char digest[16]; - char digeststr[32]; + char digeststr[33]; #endif if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK) @@ -2760,8 +2761,8 @@ void create_ids(void) /* Test sasl_checkapop */ #ifdef DO_SASL_CHECKAPOP _sasl_MD5Init(&ctx); - _sasl_MD5Update(&ctx,challenge,strlen(challenge)); - _sasl_MD5Update(&ctx,password,strlen(password)); + _sasl_MD5Update(&ctx,(const unsigned char *)challenge,strlen(challenge)); + _sasl_MD5Update(&ctx,(const unsigned char *)password,strlen(password)); _sasl_MD5Final(digest, &ctx); /* convert digest from binary to ASCII hex */ @@ -2986,7 +2987,7 @@ int main(int argc, char **argv) g_secret = malloc(sizeof(sasl_secret_t) + strlen(password)); g_secret->len = (unsigned) strlen(password); - strcpy(g_secret->data, password); + strcpy((char *) g_secret->data, password); if(random_tests < 0) random_tests = 25; diff --git a/win32/common.mak b/win32/common.mak index 5c9c4b28..aa5e8061 100644 --- a/win32/common.mak +++ b/win32/common.mak @@ -2,7 +2,7 @@ #Keep in sync with include/sasl.h and win32/include/config.h SASL_VERSION_MAJOR=2 SASL_VERSION_MINOR=1 -SASL_VERSION_STEP=26 +SASL_VERSION_STEP=27 !IF "$(STATIC)" == "" STATIC=yes @@ -26,7 +26,7 @@ LINK32EXE=$(LINK32) # It seems that -lib must be the first parameter LINK32LIB=link.exe /lib /nologo -SYS_LIBS=ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib +SYS_LIBS=ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wldap32.lib !IF "$(BITS)" == "64" SYS_LIBS=$(SYS_LIBS) bufferoverflowU.lib diff --git a/win32/include/config.h b/win32/include/config.h index 34408378..83ff00ba 100644 --- a/win32/include/config.h +++ b/win32/include/config.h @@ -55,7 +55,7 @@ #define PACKAGE "cyrus-sasl" /* Our version */ -#define VERSION "2.1.26" +#define VERSION "2.1.27" /* Visual Studio supports prototypes */ #define PROTOTYPES 1 @@ -117,7 +117,9 @@ typedef int intptr_t; /* Windows calls these functions something else */ #define strcasecmp stricmp +#if _MSC_VER < 1900 #define snprintf _snprintf +#endif #define strncasecmp strnicmp #define MAXHOSTNAMELEN 1024