2N/A * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A/* DIGEST-MD5 SASL plugin 2N/A * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. 2N/A * Redistribution and use in source and binary forms, with or without 2N/A * modification, are permitted provided that the following conditions 2N/A * 1. Redistributions of source code must retain the above copyright 2N/A * notice, this list of conditions and the following disclaimer. 2N/A * 2. Redistributions in binary form must reproduce the above copyright 2N/A * notice, this list of conditions and the following disclaimer in 2N/A * the documentation and/or other materials provided with the 2N/A * 3. The name "Carnegie Mellon University" must not be used to 2N/A * endorse or promote products derived from this software without 2N/A * prior written permission. For permission or any other legal 2N/A * details, please contact 2N/A * Office of Technology Transfer 2N/A * Carnegie Mellon University 2N/A * 5000 Forbes Avenue 2N/A * Pittsburgh, PA 15213-3890 2N/A * (412) 268-4387, fax: (412) 268-7395 2N/A * tech-transfer@andrew.cmu.edu 2N/A * 4. Redistributions of any form whatsoever must retain the following 2N/A * "This product includes software developed by Computing Services 2N/A * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 2N/A * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 2N/A * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 2N/A * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 2N/A * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 2N/A * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 2N/A * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2N/A/* EXPORT DELETE START */ 2N/A#
else /* system DES library */ 2N/A#
endif /* WITH_DES */ 2N/A/* EXPORT DELETE END */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ && USE_UEF */ 2N/A#
endif /* end WIN32 */ 2N/A/* external definitions */ 2N/A/* gotta define gethostname ourselves on suns */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A/***************************** Common Section *****************************/ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A unsigned char [
16]);
2N/A#
endif /* _SUN_SDK_ */ 2N/A/* cached auth info used for fast reauth */ 2N/A } s;
/* server stuff */ 2N/A } c;
/* client stuff */ 2N/A/* context that stores info */ 2N/A int state;
/* state in the authentication we are in */ 2N/A /* copy of utils from the params structures */ 2N/A /* For general use */ 2N/A unsigned int size;
/* Absolute size of buffer */ 2N/A unsigned int needsize;
/* How much of the size of the buffer is left */ 2N/A /* Server MaxBuf for Client or Client MaxBuf For Server */ 2N/A /* if privacy mode is used use these functions for encode and decode */ 2N/A int n;
/* bits to make privacy key */ 2N/A int flag;
/* a bitmask to make things easier for us */ 2N/Astatic const unsigned char *
COLON = (
unsigned char *)
":";
2N/A#
endif /* _SUN_SDK_ */ 2N/A/* Hashes a string to produce an unsigned short */ 2N/A Hex[i *
2 +
1] = (j +
'a' -
10);
2N/A unsigned char *
pszQop,
/* qop-value: "", "auth", 2N/A /* calculate H(A2) */ 2N/A /* utils->MD5Update(&Md5Ctx, (unsigned char *) "AUTHENTICATE:", 13); */ 2N/A /* append ":00000000000000000000000000000000" */ 2N/A /* calculate response */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A break;
/* abort if outside 8859-1 */ 2N/A /* if scan >= end, then this is a 8859-1 string. */ 2N/A * if the string is entirely in the 8859-1 subset of UTF-8, then translate to 2N/A * 8859-1 prior to MD5 2N/A /* if we found a character outside 8859-1, don't alter string */ 2N/A /* convert to 8859-1 prior to applying hash */ 2N/A /* Chris Newman clarified that the following text in DIGEST-MD5 spec 2N/A is bogus: "if name and password are both in ISO 8859-1 charset" 2N/A We should use code example instead */ 2N/A /* We have to convert UTF-8 to ISO-8859-1 if possible */ 2N/A /* a NULL realm is equivalent to the empty string */ 2N/A /* We have to convert UTF-8 to ISO-8859-1 if possible */ 2N/A#
endif /* _DEV_URANDOM && _SUN_SDK_ */ 2N/A /* base 64 encode it so it has valid chars */ 2N/A "Unable to allocate final buffer");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * Returns SASL_OK on success, SASL_BUFOVER if result won't fit 2N/A /* skipping spaces: */ 2N/A while (s[0] ==
' ' || s[0] ==
HT || s[0] ==
CR || s[0] ==
LF) {
2N/A if (s[0]==
'\0')
break;
2N/A#
endif /* _SUN_SDK_ */ 2N/A while (((
unsigned char *)s)[0]>
SP) {
2N/A#
endif /* _SUN_SDK_ */ 2N/A if (s[0]==
DEL || s[0]==
'(' || s[0]==
')' || s[0]==
'<' || s[0]==
'>' ||
2N/A s[0]==
'@' || s[0]==
',' || s[0]==
';' || s[0]==
':' || s[0]==
'\\' ||
2N/A s[0]==
'\'' || s[0]==
'/' || s[0]==
'[' || s[0]==
']' || s[0]==
'?' ||
2N/A s[0]==
'=' || s[0]==
'{' || s[0]==
'}') {
2N/A /* the above chars are never uppercase */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A/* NULL - error (unbalanced quotes), 2N/A otherwise pointer to the first character after value */ 2N/A outptr--;
/* Will be incremented at the end of the loop */ 2N/A else {
/* not qouted value (token) */ 2N/A /* skipping spaces: */ 2N/A /* strip wierd chars */ 2N/A if (
curp[0] !=
'=') {
/* No '=' sign */ 2N/A /* syntax check: MUST be '\0' or ',' */ 2N/A/* EXPORT DELETE START */ 2N/A/* slide the first 7 bytes of 'inbuf' into the high seven bits of the 2N/A first 8 bytes of 'keybuf'. 'keybuf' better be 8 bytes long or longer. */ 2N/A/****************************** 2N/A *****************************/ 2N/A /* now chop off the padding */ 2N/A /* invalid padding length */ 2N/A /* verify all padding is correct */ 2N/A /* chop off the padding */ 2N/A /* copy in the HMAC to digest */ 2N/A /* determine padding length */ 2N/A /* now construct the full stuff to be ciphered */ 2N/A /* allocate enc & dec context */ 2N/A /* setup enc context */ 2N/A /* setup dec context */ 2N/A/****************************** 2N/A *****************************/ 2N/A /* Update the ivec (des_cbc_encrypt implementations tend to be broken in 2N/A /* now chop off the padding */ 2N/A /* invalid padding length */ 2N/A /* verify all padding is correct */ 2N/A /* chop off the padding */ 2N/A /* copy in the HMAC to digest */ 2N/A /* determine padding length */ 2N/A /* now construct the full stuff to be ciphered */ 2N/A /* Update the ivec (des_cbc_encrypt implementations tend to be broken in 2N/A /* allocate enc context */ 2N/A /* setup enc context */ 2N/A /* setup dec context */ 2N/A /* free des contextss. only cipher_enc_context needs to be free'd, 2N/A since cipher_dec_context was allocated at the same time. */ 2N/A#
endif /* WITH_DES */ 2N/A/* quick generic implementation of RC4 */ 2N/A /* fill in linearly s0=0 s1=1... */ 2N/A for (i = 0; i <
256; i++) {
2N/A /* j = (j + Si + Ki) mod 256 */ 2N/A /* swap Si and Sj */ 2N/A /* counters initialized to 0 */ 2N/A /* swap Si and Sj */ 2N/A /* byte K is Xor'ed with plaintext */ 2N/A /* swap Si and Sj */ 2N/A /* byte K is Xor'ed with plaintext */ 2N/A /* free rc4 context structures */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* allocate rc4 context structures */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* initialize them */ 2N/A /* decrypt the text part */ 2N/A /* decrypt the HMAC part */ 2N/A /* no padding so we just subtract the HMAC to get the text length */ 2N/A /* encrypt the text part */ 2N/A /* encrypt the HMAC part */ 2N/A#
endif /* WITH_RC4 */ 2N/A/* EXPORT DELETE END */ 2N/A /* EXPORT DELETE START */ 2N/A /* EXPORT DELETE END */ 2N/A * slide the first 7 bytes of 'inbuf' into the high seven bits of the 2N/A * first 8 bytes of 'keybuf'. 'inbuf' better be 8 bytes long or longer. 2N/A * This is used to compute the IV for "des" and "3des" as described in 2N/A * and "3des" is the last 8 bytes of Kcc or Kcs - the encryption keys. 2N/A * Create encryption and decryption session handle handles for later use. 2N/A * Returns SASL_OK on success - any other return indicates failure. 2N/A * free_uef is called to release associated resources by 2N/A * digestmd5_common_mech_dispose 2N/A /* allocate rc4 context structures */ 2N/A "enc C_OpenSession Failed:0x%.8X\n",
rv);
2N/A "enc C_CreateObject: rv = 0x%.8X\n",
rv);
2N/A /* Initialize the encryption operation in the session */ 2N/A "C_EncryptInit: rv = 0x%.8X\n",
rv);
2N/A "dec C_OpenSession Failed:0x%.8X\n",
rv);
2N/A "dec C_CreateObject: rv = 0x%.8X\n",
rv);
2N/A /* Initialize the decryption operation in the session */ 2N/A "C_DecryptInit: rv = 0x%.8X\n",
rv);
2N/A "C_EncryptFinal failed:0x%.8X\n",
rv);
2N/A "C_DestroyObject failed:0x%.8X\n",
rv);
2N/A "C_CloseSession failed:0x%.8X\n",
rv);
2N/A "C_DecryptFinal failed:0x%.8X\n",
rv);
2N/A "C_DestroyObject failed:0x%.8X\n",
rv);
2N/A "C_CloseSession failed:0x%.8X\n",
rv);
2N/A "C_DecryptUpdate failed:0x%.8X\n",
rv);
2N/A "C_DecryptUpdate:0x%.8X, digestLen:%d\n",
2N/A "C_EncryptUpdate failed: 0x%.8X " 2N/A "inputlen:%d outputlen:%d\n",
2N/A "C_EncryptUpdate failed: 0x%.8X ulDigestLen:%d\n",
2N/A "C_DecryptUpdate failed:0x%.8X\n",
rv);
2N/A "C_DecryptUpdate unexpected data len:%d !=%d\n",
2N/A /* now chop off the padding */ 2N/A /* invalid padding length */ 2N/A /* verify all padding is correct */ 2N/A /* chop off the padding */ 2N/A /* copy in the HMAC to digest */ 2N/A /* determine padding length */ 2N/A /* now construct the full stuff to be ciphered */ 2N/A "C_EncryptUpdate failed: 0x%.8X " 2N/A "inputlen:%d outputlen:%d\n",
2N/A /* create integrity keys */ 2N/A/* len, CIPHER(Kc, {msg, pag, HMAC(ki, {SeqNum, msg})[0..9]}), x0001, SeqNum */ 2N/A /* avoid the data copy */ 2N/A /* make sure the output buffer is big enough for this blob */ 2N/A (
4 +
/* for length */ 2N/A 8 +
/* maximum pad */ 2N/A 6 +
/* for padding */ 2N/A 1));
/* trailing null */ 2N/A /* skip by the length for now */ 2N/A /* construct (seqnum, msg) */ 2N/A /* We can just use the output buffer because it's big enough */ 2N/A /* HMAC(ki, (seqnum, msg) ) */ 2N/A /* calculate the encrypted part */ 2N/A /* copy in version */ 2N/A /* put the 1st 4 bytes in */ 2N/A /* if less than 4 bytes just copy those we have into text->size */ 2N/A if (*
inputlen==0)
/* have to wait until next time for data */ 2N/A /* check the version number */ 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* check the CMAC */ 2N/A /* construct (seqnum, msg) */ 2N/A /* HMAC(ki, (seqnum, msg) ) */ 2N/A "CMAC doesn't match at byte %d!",
lup);
2N/A "CMAC doesn't match at byte %d!",
lup);
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* check the sequence number */ 2N/A "Incorrect Sequence Number");
2N/A "Incorrect Sequence Number");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* avoid the data copy */ 2N/A /* construct output */ 2N/A /* construct (seqnum, msg) */ 2N/A /* we can just use the output buffer */ 2N/A /* HMAC(ki, (seqnum, msg) ) */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* copy into output */ 2N/A /* length of message in network byte order */ 2N/A /* the message text */ 2N/A /* construct (seqnum, msg) */ 2N/A /* HMAC(ki, (seqnum, msg) ) */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* make sure the MAC is right */ 2N/A "MAC doesn't match");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* ok make output message */ 2N/A * if less than 4 bytes just copy those we have into text->size 2N/A if (*
inputlen == 0)
/* have to wait until next time for data */ 2N/A /* free the stuff in the context */ 2N/A/***************************** Server Section *****************************/ 2N/A /* calculate session key */ 2N/A /* save HA1 because we need it to make the privacy and integrity keys */ 2N/A (
unsigned char *)
qop,
/* qop-value: "", "auth", 2N/A (
unsigned char *)
"AUTHENTICATE",
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* response_value (used for reauth i think */ 2N/A (
unsigned char *)
qop,
/* qop-value: "", "auth", 2N/A /* look at user realm first */ 2N/A /* Catch improperly converted apps */ 2N/A "user_realm is an empty string!");
2N/A "user_realm is an empty string!");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "no way to obtain domain");
2N/A "no way to obtain domain");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * Convert hex string to int 2N/A /* holds state are in -- allocate server size */ 2N/A "DIGEST-MD5 server step 1");
2N/A /* what options should we offer the client? */ 2N/A /* do we allow this particular cipher? */ 2N/A "internal error: cipheropts too big");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* we didn't allow anything?!? we'll return SASL_TOOWEAK, since 2N/A that's close enough */ 2N/A * digest-challenge = 1#( realm | nonce | qop-options | stale | maxbuf | 2N/A * charset | cipher-opts | auth-param ) 2N/A /* FIXME: get nonce XXX have to clean up after self if fail */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A /* Note typo below */ 2N/A "internal error: failed creating a nonce");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* add to challenge; if we chose not to specify a realm, we won't 2N/A * send one to the client */ 2N/A "internal error: add_to_challenge failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * qop-options A quoted string of one or more tokens indicating the 2N/A * "quality of protection" values supported by the server. The value 2N/A * "auth" indicates authentication; the value "auth-int" indicates 2N/A * authentication with integrity protection; the value "auth-conf" 2N/A * indicates authentication with integrity protection and encryption. 2N/A /* add qop to challenge */ 2N/A "internal error: add_to_challenge 3 failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * Cipheropts - list of ciphers server supports 2N/A /* add cipher-opts to challenge; only add if there are some */ 2N/A "internal error: add_to_challenge 4 failed");
2N/A "internal error: add_to_challenge 4 failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* "stale" is true if a reauth failed because of a nonce timeout */ 2N/A "internal error: add_to_challenge failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * maxbuf A number indicating the size of the largest buffer the server 2N/A * is able to receive when using "auth-int". If this directive is 2N/A * missing, the default value is 65536. This directive may appear at most 2N/A * once; if multiple instances are present, the client should abort the 2N/A * authentication exchange. 2N/A "internal error: add_to_challenge 5 failed");
2N/A "internal error: add_to_challenge 5 failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "internal error: add_to_challenge 6 failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * This directive is required for backwards compatibility with HTTP 2N/A * Digest., which supports other algorithms. . This directive is 2N/A * required and MUST appear exactly once; if not present, or if multiple 2N/A * instances are present, the client should abort the authentication 2N/A * algorithm = "algorithm" "=" "md5-sess" 2N/A "internal error: add_to_challenge 7 failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * The size of a digest-challenge MUST be less than 2048 bytes!!! 2N/A "internal error: challenge larger than 2048 bytes");
2N/A "internal error: challenge larger than 2048 bytes");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* setting the default value (65536) */ 2N/A /* password prop_request */ 2N/A "*cmusaslsecretDIGEST-MD5",
2N/A /* can we mess with clientin? copy it to be safe */ 2N/A "DIGEST-MD5 server step 2");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* parse what we got */ 2N/A /* Extracting parameters */ 2N/A * digest-response = 1#( username | realm | nonce | cnonce | 2N/A * nonce-count | qop | digest-uri | response | maxbuf | charset | 2N/A * cipher | auth-param ) 2N/A "error converting hex to int");
2N/A "error converting hex to int");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "duplicate realm: authentication aborted");
2N/A "duplicate realm: authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * digest-uri-value = serv-type "/" host [ "/" serv-name ] 2N/A /* verify digest-uri format */ 2N/A /* make sure it's the service that we're expecting */ 2N/A "bad digest-uri: doesn't match service");
2N/A "bad digest-uri: doesn't match service");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* xxx we don't verify the hostname component */ 2N/A "duplicate maxbuf: authentication aborted");
2N/A "duplicate maxbuf: authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "invalid maxbuf parameter");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "maxbuf parameter too small");
2N/A "maxbuf parameter too small");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "client doesn't support UTF-8");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
2N/A * username = "username" "=" <"> username-value <"> 2N/A * username-value = qdstr-val cnonce = "cnonce" "=" <"> 2N/A * cnonce-value <"> cnonce-value = qdstr-val nonce-count = "nc" 2N/A * "=" nc-value nc-value = 8LHEX qop = "qop" "=" 2N/A * qop-value digest-uri = "digest-uri" "=" digest-uri-value 2N/A * digest-uri-value = serv-type "/" host [ "/" serv-name ] serv-type 2N/A * = 1*ALPHA host = 1*( ALPHA | DIGIT | "-" | "." ) service 2N/A * = host response = "response" "=" <"> response-value <"> 2N/A * response-value = 32LHEX LHEX = "0" | "1" | "2" | "3" | "4" | "5" | 2N/A * "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f" cipher = 2N/A * "cipher" "=" cipher-value 2N/A /* Verifing that all parameters was defined */ 2N/A "required parameters missing");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* reauth attempt, see if we have any info for this user */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* we don't have any reauth info, so bail */ 2N/A /* Sanity check the parameters */ 2N/A "realm changed: authentication aborted");
2N/A "realm changed: authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "nonce changed: authentication aborted");
2N/A "nonce changed: authentication aborted");
2N/A#
endif /* _SUN_SKD_ */ 2N/A "incorrect nonce-count: authentication aborted");
2N/A "incorrect nonce-count: authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "cnonce changed: authentication aborted");
2N/A "cnonce changed: authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "unable to request user password");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* this will trigger the getting of the aux properties */ 2N/A /* Note that if we don't have an authorization id, we don't use it... */ 2N/A "unable canonify user and get auxprops");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "unable to canonicalize authorization ID");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* We didn't find this username */ 2N/A "no secret in database");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A "unable to allocate secret");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A * Verifying response obtained from client 2N/A * H_URP = H({ username-value,":",realm-value,":",passwd}) sec->data 2N/A /* Calculate the secret from the plaintext password */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A * A1 = { H( { username-value, ":", realm-value, ":", passwd } ), 2N/A * ":", nonce-value, ":", cnonce-value } 2N/A /* We're done with sec now. Let's get rid of it */ 2N/A "Have neither type of secret");
2N/A "Have neither type of secret");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* defaulting qop to "auth" if not specified */ 2N/A /* see what cipher was requested */ 2N/A /* find the cipher requested & make sure it's one we're happy 2N/A /* erg? client requested something we didn't advertise! */ 2N/A "protocol violation: client requested invalid cipher");
2N/A#
endif /* !_SUN_SDK_ */ 2N/A /* Mark that we attempted security layer negotiation */ 2N/A "protocol violation: client requested invalid qop");
2N/A "protocol violation: client requested invalid qop");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A /* if ok verified */ 2N/A gettext(
"client response doesn't match what we generated"));
2N/A "client response doesn't match what we generated");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* see if our nonce expired */ 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A * nothing more to do; authenticated set oparams information 2N/A /* MAC block (privacy) */ 2N/A /* MAC block (integrity) */ 2N/A /* used by layers */ 2N/A /* initialize cipher if need be */ 2N/A "couldn't init cipher");
2N/A "couldn't init cipher");
2N/A#
endif /* _SUN_SDK_ */ 2N/A * The server receives and validates the "digest-response". The server 2N/A * checks that the nonce-count is "00000001". If it supports subsequent 2N/A * authentication, it saves the value of the nonce and the nonce-count. 2N/A * The "username-value", "realm-value" and "passwd" are encoded according 2N/A * to the value of the "charset" directive. If "charset=UTF-8" is 2N/A * present, and all the characters of either "username-value" or "passwd" 2N/A * are in the ISO 8859-1 character set, then it must be converted to 2N/A * UTF-8 before being hashed. A sample implementation of this conversion 2N/A /* add to challenge */ 2N/A /* successful auth, setup for future reauth */ 2N/A /* successful initial auth, create new entry */ 2N/A /* paranoia. prevent replay attacks */ 2N/A /* failed reauth, clear entry */ 2N/A /* failed initial auth, leave existing cache */ 2N/A /* free everything */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* setup SSF limits */ 2N/A /* here's where we attempt fast reauth if possible */ 2N/A "DIGEST-MD5 reauth failed");
2N/A "DIGEST-MD5 reauth failed\n");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* re-initialize everything for a fresh start */ 2N/A /* fall through and issue challenge */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A "DIGEST-MD5",
/* mech_name */ 2N/A /* EXPORT DELETE START */ 2N/A /* EXPORT DELETE END */ 2N/A /* EXPORT DELETE START */ 2N/A /* EXPORT DELETE END */ 2N/A#
endif /* _SUN_SDK_ && USE_UEF */ 2N/A#
endif /* _SUN_SDK_ && USE_UEF */ 2N/A /* fetch and canonify the reauth_timeout */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* USE_UEF_CLIENT */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* EXPORT DELETE START */ 2N/A /* CRYPT DELETE START */ 2N/A * Let libsasl know that we are a "Sun" plugin so that privacy 2N/A * and integrity will be allowed. 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* CRYPT DELETE END */ 2N/A /* EXPORT DELETE END */ 2N/A/***************************** Client Section *****************************/ 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A/* calculate H(A1) as per spec */ 2N/A /* calculate the session key */ 2N/A /* xxx rc-* use different n */ 2N/A /* save HA1 because we'll need it for the privacy and integrity keys */ 2N/A /* Verifing that all parameters was defined */ 2N/A /* a NULL realm is equivalent to the empty string */ 2N/A /* default to a qop of just authentication */ 2N/A (
unsigned char *)
qop,
/* qop-value: "", "auth", 2N/A (
unsigned char *)
"AUTHENTICATE",
2N/A#
endif /* _SUN_SDK_ */ 2N/A (
unsigned char *)
qop,
/* qop-value: "", "auth", 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* allocated exactly this. safe */ 2N/A * strcat (digesturi, "/"); strcat (digesturi, params->serverFQDN); 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A "internal error: add_to_challenge maxbuf failed");
2N/A "internal error: add_to_challenge maxbuf failed");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "charset", (
unsigned char *)
"utf-8",
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* MAC block (privacy) */ 2N/A /* MAC block (integrity) */ 2N/A /* used by layers */ 2N/A /* initialize cipher if need be */ 2N/A "couldn't init cipher");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A "no server challenge");
2N/A "no server challenge");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* create a new cnonce */ 2N/A "failed to create cnonce");
2N/A "failed to create cnonce");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* parse the challenge */ 2N/A /* if parse error */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A "Server supports unknown layer: %s\n",
2N/A gettext(
"Server doesn't support known qop level"));
2N/A "Server doesn't support known qop level");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* do we support this cipher? */ 2N/A "Server supports unknown cipher: %s\n",
2N/A /* clear any cached password */ 2N/A /* maxbuf A number indicating the size of the largest 2N/A * buffer the server is able to receive when using 2N/A * "auth-int". If this directive is missing, the default 2N/A * value is 65536. This directive may appear at most once; 2N/A * if multiple instances are present, the client should 2N/A * abort the authentication exchange. 2N/A "At least two maxbuf directives found." 2N/A " Authentication aborted");
2N/A "At least two maxbuf directives found. Authentication aborted");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "Invalid maxbuf parameter received from server");
2N/A "Invalid maxbuf parameter received from server");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "Invalid maxbuf parameter received from server" 2N/A "Invalid maxbuf parameter received from server (too small: %s)",
value);
2N/A#
endif /* _SUN_SDK_ */ 2N/A "Charset must be UTF-8");
2N/A "Charset must be UTF-8");
2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A "'algorithm' isn't 'md5-sess'");
2N/A "'algorithm' isn't 'md5-sess'");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "Must see 'algorithm' only once");
2N/A "Must see 'algorithm' only once");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
2N/A "Must see 'algorithm' once. Didn't see at all");
2N/A "Must see 'algorithm' once. Didn't see at all");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* make sure we have everything we require */ 2N/A "Don't have nonce.");
2N/A "Don't have nonce.");
2N/A#
endif /* _SUN_SDK_ */ 2N/A /* get requested ssf */ 2N/A /* what do we _need_? how much is too much? */ 2N/A /* we now go searching for an option that gives us at least "musthave" 2N/A and at most "limit" bits of ssf. */ 2N/A /* let's find an encryption scheme that we like */ 2N/A /* examine each cipher we support, see if it meets our security 2N/A requirements, and see if the server supports it. 2N/A choose the best one of these */ 2N/A /* we found a cipher we like */ 2N/A /* we didn't find any ciphers we like */ 2N/A "No good privacy layers");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* we failed to find an encryption layer we liked; 2N/A can we use integrity or nothing? */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* See if server supports not having a layer */ 2N/A "Server doesn't support \"no layer\"");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A "Can't find an acceptable layer");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* need to free all the realms */ 2N/A /* try to get the authid */ 2N/A /* try to get the userid */ 2N/A /* try to get the password */ 2N/A /* try to get the realm */ 2N/A /* only one choice */ 2N/A /* fake the realm if we must */ 2N/A /* free prompts we got */ 2N/A /* if there are prompts not filled in */ 2N/A /* make our default realm */ 2N/A /* make the prompt list */ 2N/A "Please enter your authorization name" :
NULL,
2N/A "Please enter your authentication name" :
NULL,
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* Get an allocated version of the realm into the structure */ 2N/A /* holds state are in -- allocate client size */ 2N/A "DIGEST-MD5 client step 1");
2N/A /* check if we have cached info for this user on this server */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* we have info, so use it */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* we don't have any reauth info, so just return 2N/A * that there is no initial client send */ 2N/A * (username | realm | nonce | cnonce | nonce-count | qop digest-uri | 2N/A * response | maxbuf | charset | auth-param ) 2N/A "DIGEST-MD5 client step 2");
2N/A /* don't bother parsing the challenge more than once */ 2N/A /* only one choice! */ 2N/A * (username | realm | nonce | cnonce | nonce-count | qop digest-uri | 2N/A * response | maxbuf | charset | auth-param ) 2N/A /* need to free all the realms */ 2N/A "DIGEST-MD5 client step 3");
2N/A /* Verify that server is really what he claims to be */ 2N/A /* parse the response */ 2N/A "DIGEST-MD5 Received Garbage");
2N/A "DIGEST-MD5 Received Garbage");
2N/A#
endif /* _SUN_SDK_ */ 2N/A "DIGEST-MD5: This server wants us to believe that he knows shared secret");
2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
2N/A /* successful initial auth, setup for future reauth */ 2N/A /* reauth, we already incremented nonce_count */ 2N/A#
endif /* !_SUN_SDK_ */ 2N/A /* failed reauth, clear cache */ 2N/A /* failed initial auth, leave existing cache */ 2N/A /* here's where we attempt fast reauth if possible */ 2N/A /* check if we have saved info for this server */ 2N/A /* we don't have any reauth info, so just return 2N/A * that there is no initial client send */ 2N/A /* fall through and respond to challenge */ 2N/A /* fall through and respond to challenge */ 2N/A /* cleanup after a failed reauth attempt */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* EXPORT DELETE START */ 2N/A /* EXPORT DELETE END */ 2N/A /* EXPORT DELETE START */ 2N/A /* EXPORT DELETE END */ 2N/A#
endif /* _SUN_SDK_ && USE_UEF */ 2N/A#
endif /* _SUN_SDK_ && USE_UEF */ 2N/A#
endif /* USE_UEF_CLIENT */ 2N/A#
endif /* _SUN_SDK_ */ 2N/A /* EXPORT DELETE START */ 2N/A /* CRYPT DELETE START */ 2N/A * Let libsasl know that we are a "Sun" plugin so that privacy 2N/A * and integrity will be allowed. 2N/A#
endif /* _INTEGRATED_SOLARIS_ */ 2N/A /* CRYPT DELETE END */ 2N/A /* EXPORT DELETE END */ 2N/A/* If we fail here - we should just not offer privacy or integrity */ 2N/A "C_GetMechanismList returned 0x%.8X count:%d\n",
rv,
2N/A "C_GetMechanismList returned 0x%.8X count:%d\n",
rv,
2N/A "C_Initialize returned 0x%.8X\n",
rv);
2N/A /* adjust the available ciphers */ 2N/A#
endif /* _SUN_SDK_ */