/// <summary> /// Generates a string that can be set to an Authorization header. /// </summary> public string GenerateResponseHeader(HTTPRequest request, Credentials credentials) { try { switch (Type) { case AuthenticationTypes.Basic: return(string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credentials.UserName, credentials.Password))))); case AuthenticationTypes.Digest: { NonceCount++; string HA1 = string.Empty; // 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, to provide mutual // authentication, and to provide some message integrity protection. string cnonce = new System.Random(request.GetHashCode()).Next(int.MinValue, int.MaxValue).ToString("X8"); string ncvalue = NonceCount.ToString("X8"); switch (Algorithm.TrimAndLower()) { case "md5": HA1 = string.Format("{0}:{1}:{2}", credentials.UserName, Realm, credentials.Password).CalculateMD5Hash(); break; case "md5-sess": if (string.IsNullOrEmpty(this.HA1Sess)) { this.HA1Sess = string.Format("{0}:{1}:{2}:{3}:{4}", credentials.UserName, Realm, credentials.Password, Nonce, ncvalue).CalculateMD5Hash(); } HA1 = this.HA1Sess; break; default: //throw new NotSupportedException("Not supported hash algorithm found in Web Authentication: " + Algorithm); return(string.Empty); } // A string of 32 hex digits, which proves that the user knows a password. Set according to the qop value. string response = string.Empty; // The server sent QoP-value can be a list of supported methodes(if sent at all - in this case it's null). // The rfc is not specify that this is a space or comma separeted list. So it can be "auth, auth-int" or "auth auth-int". // We will first check the longer value("auth-int") then the short one ("auth"). If one matches we will reset the qop to the exact value. string qop = this.QualityOfProtections != null?this.QualityOfProtections.TrimAndLower() : null; if (qop == null) { string HA2 = string.Concat(request.MethodType.ToString().ToUpper(), ":", request.CurrentUri.GetRequestPathAndQueryURL()).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}", HA1, Nonce, HA2).CalculateMD5Hash(); } else if (qop.Contains("auth-int")) { qop = "auth-int"; byte[] entityBody = request.GetEntityBody(); if (entityBody == null) { entityBody = string.Empty.GetASCIIBytes(); } string HA2 = string.Format("{0}:{1}:{2}", request.MethodType.ToString().ToUpper(), request.CurrentUri.GetRequestPathAndQueryURL(), entityBody.CalculateMD5Hash()).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); } else if (qop.Contains("auth")) { qop = "auth"; string HA2 = string.Concat(request.MethodType.ToString().ToUpper(), ":", request.CurrentUri.GetRequestPathAndQueryURL()).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); } else //throw new NotSupportedException("Unrecognized Quality of Protection value found: " + this.QualityOfProtections); { return(string.Empty); } string result = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", cnonce=\"{4}\", response=\"{5}\"", credentials.UserName, Realm, Nonce, request.Uri.GetRequestPathAndQueryURL(), cnonce, response); if (qop != null) { result += String.Concat(", qop=\"", qop, "\", nc=", ncvalue); } if (!string.IsNullOrEmpty(Opaque)) { result = String.Concat(result, ", opaque=\"", Opaque, "\""); } return(result); } // end of case "digest": default: break; } } catch { } return(string.Empty); }
public string GenerateResponseHeader(HTTPRequest request, Credentials credentials) { try { AuthenticationTypes type = this.Type; if (type == AuthenticationTypes.Basic) { string result = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credentials.UserName, credentials.Password))); return(result); } if (type == AuthenticationTypes.Digest) { this.NonceCount++; string text = string.Empty; string text2 = new Random(request.GetHashCode()).Next(-2147483648, 2147483647).ToString("X8"); string text3 = this.NonceCount.ToString("X8"); string text4 = this.Algorithm.TrimAndLower(); string result; if (text4 != null) { if (Digest.< > f__switch$map1 == null) { Digest.< > f__switch$map1 = new Dictionary <string, int>(2) { { "md5", 0 }, { "md5-sess", 1 } }; } int num; if (Digest.< > f__switch$map1.TryGetValue(text4, out num)) { if (num != 0) { if (num != 1) { goto IL_199; } if (string.IsNullOrEmpty(this.HA1Sess)) { this.HA1Sess = string.Format("{0}:{1}:{2}:{3}:{4}", new object[] { credentials.UserName, this.Realm, credentials.Password, this.Nonce, text3 }).CalculateMD5Hash(); } text = this.HA1Sess; } else { text = string.Format("{0}:{1}:{2}", credentials.UserName, this.Realm, credentials.Password).CalculateMD5Hash(); } string text5 = string.Empty; string text6 = (this.QualityOfProtections == null) ? null : this.QualityOfProtections.TrimAndLower(); if (text6 == null) { string arg = (request.MethodType.ToString().ToUpper() + ":" + request.CurrentUri.PathAndQuery).CalculateMD5Hash(); text5 = string.Format("{0}:{1}:{2}", text, this.Nonce, arg).CalculateMD5Hash(); } else if (text6.Contains("auth-int")) { text6 = "auth-int"; byte[] array = request.GetEntityBody(); if (array == null) { array = string.Empty.GetASCIIBytes(); } string text7 = string.Format("{0}:{1}:{2}", request.MethodType.ToString().ToUpper(), request.CurrentUri.PathAndQuery, array.CalculateMD5Hash()).CalculateMD5Hash(); text5 = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", new object[] { text, this.Nonce, text3, text2, text6, text7 }).CalculateMD5Hash(); } else { if (!text6.Contains("auth")) { result = string.Empty; return(result); } text6 = "auth"; string text8 = (request.MethodType.ToString().ToUpper() + ":" + request.CurrentUri.PathAndQuery).CalculateMD5Hash(); text5 = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", new object[] { text, this.Nonce, text3, text2, text6, text8 }).CalculateMD5Hash(); } string text9 = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", cnonce=\"{4}\", response=\"{5}\"", new object[] { credentials.UserName, this.Realm, this.Nonce, request.Uri.PathAndQuery, text2, text5 }); if (text6 != null) { text9 += ", qop=\"" + text6 + "\", nc=" + text3; } if (!string.IsNullOrEmpty(this.Opaque)) { text9 = text9 + ", opaque=\"" + this.Opaque + "\""; } result = text9; return(result); } } IL_199: result = string.Empty; return(result); } } catch { } return(string.Empty); }
/// <summary> /// Generates a string that can be set to an Authorization header. /// </summary> public string GenerateResponseHeader(HTTPRequest request, Credentials credentials) { try { switch (Type) { case AuthenticationTypes.Basic: return string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credentials.UserName, credentials.Password)))); case AuthenticationTypes.Digest: { NonceCount++; string HA1 = string.Empty; // 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, to provide mutual // authentication, and to provide some message integrity protection. string cnonce = new System.Random(request.GetHashCode()).Next(int.MinValue, int.MaxValue).ToString("X8"); string ncvalue = NonceCount.ToString("X8"); switch (Algorithm.TrimAndLower()) { case "md5": HA1 = string.Format("{0}:{1}:{2}", credentials.UserName, Realm, credentials.Password).CalculateMD5Hash(); break; case "md5-sess": if (string.IsNullOrEmpty(this.HA1Sess)) this.HA1Sess = string.Format("{0}:{1}:{2}:{3}:{4}", credentials.UserName, Realm, credentials.Password, Nonce, ncvalue).CalculateMD5Hash(); HA1 = this.HA1Sess; break; default: //throw new NotSupportedException("Not supported hash algorithm found in Web Authentication: " + Algorithm); return string.Empty; } // A string of 32 hex digits, which proves that the user knows a password. Set according to the qop value. string response = string.Empty; // The server sent QoP-value can be a list of supported methodes(if sent at all - in this case it's null). // The rfc is not specify that this is a space or comma separeted list. So it can be "auth, auth-int" or "auth auth-int". // We will first check the longer value("auth-int") then the short one ("auth"). If one matches we will reset the qop to the exact value. string qop = this.QualityOfProtections != null ? this.QualityOfProtections.TrimAndLower() : null; if (qop == null) { string HA2 = string.Concat(request.MethodType.ToString().ToUpper(), ":", request.CurrentUri.PathAndQuery).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}", HA1, Nonce, HA2).CalculateMD5Hash(); } else if (qop.Contains("auth-int")) { qop = "auth-int"; byte[] entityBody = request.GetEntityBody(); if (entityBody == null) entityBody = string.Empty.GetASCIIBytes(); string HA2 = string.Format("{0}:{1}:{2}", request.MethodType.ToString().ToUpper(), request.CurrentUri.PathAndQuery, entityBody.CalculateMD5Hash()).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); } else if (qop.Contains("auth")) { qop = "auth"; string HA2 = string.Concat(request.MethodType.ToString().ToUpper(), ":", request.CurrentUri.PathAndQuery).CalculateMD5Hash(); response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); } else //throw new NotSupportedException("Unrecognized Quality of Protection value found: " + this.QualityOfProtections); return string.Empty; string result = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", cnonce=\"{4}\", response=\"{5}\"", credentials.UserName, Realm, Nonce, request.Uri.PathAndQuery, cnonce, response); if (qop != null) result += String.Concat(", qop=\"", qop, "\", nc=", ncvalue); if (!string.IsNullOrEmpty(Opaque)) result = String.Concat(result, ", opaque=\"", Opaque, "\""); return result; }// end of case "digest": default: break; } } catch { } return string.Empty; }
public string GenerateResponseHeader(HTTPRequest request, Credentials credentials) { try { switch (Type) { case AuthenticationTypes.Basic: return("Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{credentials.UserName}:{credentials.Password}"))); case AuthenticationTypes.Digest: { NonceCount++; string empty = string.Empty; string text = new Random(request.GetHashCode()).Next(-2147483648, 2147483647).ToString("X8"); string text2 = NonceCount.ToString("X8"); switch (Algorithm.TrimAndLower()) { case "md5": empty = $"{credentials.UserName}:{Realm}:{credentials.Password}".CalculateMD5Hash(); break; case "md5-sess": if (string.IsNullOrEmpty(HA1Sess)) { HA1Sess = $"{credentials.UserName}:{Realm}:{credentials.Password}:{Nonce}:{text2}".CalculateMD5Hash(); } empty = HA1Sess; break; default: return(string.Empty); } string empty2 = string.Empty; string text3 = (QualityOfProtections == null) ? null : QualityOfProtections.TrimAndLower(); if (text3 == null) { string arg = (request.MethodType.ToString().ToUpper() + ":" + request.CurrentUri.PathAndQuery).CalculateMD5Hash(); empty2 = $"{empty}:{Nonce}:{arg}".CalculateMD5Hash(); } else if (text3.Contains("auth-int")) { text3 = "auth-int"; byte[] array = request.GetEntityBody(); if (array == null) { array = string.Empty.GetASCIIBytes(); } string text4 = $"{request.MethodType.ToString().ToUpper()}:{request.CurrentUri.PathAndQuery}:{array.CalculateMD5Hash()}".CalculateMD5Hash(); empty2 = $"{empty}:{Nonce}:{text2}:{text}:{text3}:{text4}".CalculateMD5Hash(); } else { if (!text3.Contains("auth")) { return(string.Empty); } text3 = "auth"; string text5 = (request.MethodType.ToString().ToUpper() + ":" + request.CurrentUri.PathAndQuery).CalculateMD5Hash(); empty2 = $"{empty}:{Nonce}:{text2}:{text}:{text3}:{text5}".CalculateMD5Hash(); } string text6 = $"Digest username=\"{credentials.UserName}\", realm=\"{Realm}\", nonce=\"{Nonce}\", uri=\"{request.Uri.PathAndQuery}\", cnonce=\"{text}\", response=\"{empty2}\""; if (text3 != null) { text6 += ", qop=\"" + text3 + "\", nc=" + text2; } if (!string.IsNullOrEmpty(Opaque)) { text6 = text6 + ", opaque=\"" + Opaque + "\""; } return(text6); } } } catch { } return(string.Empty); }