/// <summary> /// Default constructor. /// </summary> /// <param name="challenge">Client challenge.</param> /// <param name="realm">Realm value. This must be one value of the challenge Realm.</param> /// <param name="userName">User name.</param> /// <param name="password">User password.</param> /// <param name="cnonce">Client nonce value.</param> /// <param name="nonceCount">Nonce count. One-based client authentication attempt number. Normally this value is 1.</param> /// <param name="qop">Indicates what "quality of protection" the client accepted. This must be one value of the challenge QopOptions.</param> /// <param name="digestUri">Digest URI.</param> /// <exception cref="ArgumentNullException">Is raised when <b>challenge</b>,<b>realm</b>,<b>password</b>,<b>nonce</b>,<b>qop</b> or <b>digestUri</b> is null reference.</exception> public AUTH_SASL_DigestMD5_Response(AUTH_SASL_DigestMD5_Challenge challenge,string realm,string userName,string password,string cnonce,int nonceCount,string qop,string digestUri) { if(challenge == null){ throw new ArgumentNullException("challenge"); } if(realm == null){ throw new ArgumentNullException("realm"); } if(userName == null){ throw new ArgumentNullException("userName"); } if(password == null){ throw new ArgumentNullException("password"); } if(cnonce == null){ throw new ArgumentNullException("cnonce"); } if(qop == null){ throw new ArgumentNullException("qop"); } if(digestUri == null){ throw new ArgumentNullException("digestUri"); } m_pChallenge = challenge; m_Realm = realm; m_UserName = userName; m_Password = password; m_Nonce = m_pChallenge.Nonce; m_Cnonce = cnonce; m_NonceCount = nonceCount; m_Qop = qop; m_DigestUri = digestUri; m_Response = CalculateResponse(userName,password); m_Charset = challenge.Charset; }
/// <summary> /// Parses DIGEST-MD5 challenge from challenge-string. /// </summary> /// <param name="challenge">Challenge string.</param> /// <returns>Returns DIGEST-MD5 challenge.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>challenge</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when challenge parsing + validation fails.</exception> public static AUTH_SASL_DigestMD5_Challenge Parse(string challenge) { if(challenge == null){ throw new ArgumentNullException("challenge"); } AUTH_SASL_DigestMD5_Challenge retVal = new AUTH_SASL_DigestMD5_Challenge(); string[] parameters = TextUtils.SplitQuotedString(challenge,','); foreach(string parameter in parameters){ string[] name_value = parameter.Split(new char[]{'='},2); string name = name_value[0].Trim(); if(name_value.Length == 2){ if(name.ToLower() == "realm"){ retVal.m_Realm = TextUtils.UnQuoteString(name_value[1]).Split(','); } else if(name.ToLower() == "nonce"){ retVal.m_Nonce = TextUtils.UnQuoteString(name_value[1]); } else if(name.ToLower() == "qop"){ retVal.m_QopOptions = TextUtils.UnQuoteString(name_value[1]).Split(','); } else if(name.ToLower() == "stale"){ retVal.m_Stale = Convert.ToBoolean(TextUtils.UnQuoteString(name_value[1])); } else if(name.ToLower() == "maxbuf"){ retVal.m_Maxbuf = Convert.ToInt32(TextUtils.UnQuoteString(name_value[1])); } else if(name.ToLower() == "charset"){ retVal.m_Charset = TextUtils.UnQuoteString(name_value[1]); } else if(name.ToLower() == "algorithm"){ retVal.m_Algorithm = TextUtils.UnQuoteString(name_value[1]); } else if(name.ToLower() == "cipher-opts"){ retVal.m_CipherOpts = TextUtils.UnQuoteString(name_value[1]); } //else if(name.ToLower() == "auth-param"){ // retVal.m_AuthParam = TextUtils.UnQuoteString(name_value[1]); //} } } /* Validate required fields. Per RFC 2831 2.1.1. Only [nonce algorithm] parameters are required. */ if(string.IsNullOrEmpty(retVal.Nonce)){ throw new ParseException("The challenge-string doesn't contain required parameter 'nonce' value."); } if(string.IsNullOrEmpty(retVal.Algorithm)){ throw new ParseException("The challenge-string doesn't contain required parameter 'algorithm' value."); } return retVal; }