diff --git a/websocket-sharp/AuthenticationChallenge.cs b/websocket-sharp/AuthenticationChallenge.cs index 639060d6..d5dc022b 100644 --- a/websocket-sharp/AuthenticationChallenge.cs +++ b/websocket-sharp/AuthenticationChallenge.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Specialized; using System.Text; +using WebSocketSharp.Net; namespace WebSocketSharp { @@ -36,17 +37,32 @@ namespace WebSocketSharp { #region Private Fields - private NameValueCollection _parameters; - private string _scheme; + private NameValueCollection _parameters; + private AuthenticationSchemes _scheme; + + #endregion + + #region Private Constructors + + private AuthenticationChallenge (AuthenticationSchemes scheme, NameValueCollection parameters) + { + _scheme = scheme; + _parameters = parameters; + } #endregion #region Internal Constructors - internal AuthenticationChallenge (string scheme, string parameters) + internal AuthenticationChallenge (AuthenticationSchemes scheme, string realm) + : this (scheme, new NameValueCollection ()) { - _scheme = scheme; - _parameters = parameters.ParseAuthParameters (); + _parameters["realm"] = realm; + if (scheme == AuthenticationSchemes.Digest) { + _parameters["nonce"] = AuthenticationResponse.CreateNonceValue (); + _parameters["algorithm"] = "MD5"; + _parameters["qop"] = "auth"; + } } #endregion @@ -65,41 +81,41 @@ namespace WebSocketSharp public string Algorithm { get { - return _parameters ["algorithm"]; + return _parameters["algorithm"]; } } public string Domain { get { - return _parameters ["domain"]; + return _parameters["domain"]; } } public string Nonce { get { - return _parameters ["nonce"]; + return _parameters["nonce"]; } } public string Opaque { get { - return _parameters ["opaque"]; + return _parameters["opaque"]; } } public string Qop { get { - return _parameters ["qop"]; + return _parameters["qop"]; } } public string Realm { get { - return _parameters ["realm"]; + return _parameters["realm"]; } } - public string Scheme { + public AuthenticationSchemes Scheme { get { return _scheme; } @@ -107,24 +123,66 @@ namespace WebSocketSharp public string Stale { get { - return _parameters ["stale"]; + return _parameters["stale"]; } } #endregion + #region Internal Methods + + internal static AuthenticationChallenge CreateBasicChallenge (string realm) + { + return new AuthenticationChallenge (AuthenticationSchemes.Basic, realm); + } + + internal static AuthenticationChallenge CreateDigestChallenge (string realm) + { + return new AuthenticationChallenge (AuthenticationSchemes.Digest, realm); + } + + internal static AuthenticationChallenge Parse (string value) + { + var chal = value.Split (new[] { ' ' }, 2); + if (chal.Length != 2) + return null; + + var scheme = chal[0].ToLower (); + return scheme == "basic" + ? new AuthenticationChallenge ( + AuthenticationSchemes.Basic, AuthenticationResponse.ParseParameters (chal[1])) + : scheme == "digest" + ? new AuthenticationChallenge ( + AuthenticationSchemes.Digest, AuthenticationResponse.ParseParameters (chal[1])) + : null; + } + + internal string ToBasicString () + { + return String.Format ("Basic realm=\"{0}\"", _parameters["realm"]); + } + + internal string ToDigestString () + { + return String.Format ( + "Digest realm=\"{0}\", nonce=\"{1}\", algorithm={2}, qop=\"{3}\"", + _parameters["realm"], + _parameters["nonce"], + _parameters["algorithm"], + _parameters["qop"]); + } + + #endregion + #region Public Methods - public static AuthenticationChallenge Parse (string value) + public override string ToString () { - var challenge = value.Split (new [] { ' ' }, 2); - if (challenge.Length != 2) - return null; - - var scheme = challenge [0].ToLower (); - return scheme == "basic" || scheme == "digest" - ? new AuthenticationChallenge (scheme, challenge [1]) - : null; + return _scheme == AuthenticationSchemes.Basic + ? ToBasicString () + : _scheme == AuthenticationSchemes.Digest + ? ToDigestString () + : String.Empty; } #endregion diff --git a/websocket-sharp/AuthenticationResponse.cs b/websocket-sharp/AuthenticationResponse.cs index c45c1115..6e0f94e7 100644 --- a/websocket-sharp/AuthenticationResponse.cs +++ b/websocket-sharp/AuthenticationResponse.cs @@ -2,8 +2,12 @@ /* * AuthenticationResponse.cs * + * ParseBasicCredentials is derived from System.Net.HttpListenerContext.cs of Mono + * (http://www.mono-project.com). + * * The MIT License * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) * Copyright (c) 2013-2014 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -28,6 +32,7 @@ using System; using System.Collections.Specialized; +using System.Security.Cryptography; using System.Security.Principal; using System.Text; using WebSocketSharp.Net; @@ -38,15 +43,15 @@ namespace WebSocketSharp { #region Private Fields - private uint _nonceCount; - private NameValueCollection _parameters; - private string _scheme; + private uint _nonceCount; + private NameValueCollection _parameters; + private AuthenticationSchemes _scheme; #endregion #region Private Constructors - private AuthenticationResponse (string scheme, NameValueCollection parameters) + private AuthenticationResponse (AuthenticationSchemes scheme, NameValueCollection parameters) { _scheme = scheme; _parameters = parameters; @@ -57,7 +62,7 @@ namespace WebSocketSharp #region Internal Constructors internal AuthenticationResponse (NetworkCredential credentials) - : this ("Basic", new NameValueCollection (), credentials, 0) + : this (AuthenticationSchemes.Basic, new NameValueCollection (), credentials, 0) { } @@ -68,15 +73,17 @@ namespace WebSocketSharp } internal AuthenticationResponse ( - string scheme, NameValueCollection parameters, NetworkCredential credentials, uint nonceCount) + AuthenticationSchemes scheme, + NameValueCollection parameters, + NetworkCredential credentials, + uint nonceCount) + : this (scheme, parameters) { - _scheme = scheme.ToLower (); - _parameters = parameters; - _parameters ["username"] = credentials.UserName; - _parameters ["password"] = credentials.Password; - _parameters ["uri"] = credentials.Domain; + _parameters["username"] = credentials.UserName; + _parameters["password"] = credentials.Password; + _parameters["uri"] = credentials.Domain; _nonceCount = nonceCount; - if (_scheme == "digest") + if (scheme == AuthenticationSchemes.Digest) initAsDigest (); } @@ -104,59 +111,59 @@ namespace WebSocketSharp public string Algorithm { get { - return _parameters ["algorithm"]; + return _parameters["algorithm"]; } } public string Cnonce { get { - return _parameters ["cnonce"]; + return _parameters["cnonce"]; } } public string Nc { get { - return _parameters ["nc"]; + return _parameters["nc"]; } } public string Nonce { get { - return _parameters ["nonce"]; + return _parameters["nonce"]; } } public string Opaque { get { - return _parameters ["opaque"]; + return _parameters["opaque"]; } } public string Password { get { - return _parameters ["password"]; + return _parameters["password"]; } } public string Qop { get { - return _parameters ["qop"]; + return _parameters["qop"]; } } public string Realm { get { - return _parameters ["realm"]; + return _parameters["realm"]; } } public string Response { get { - return _parameters ["response"]; + return _parameters["response"]; } } - public string Scheme { + public AuthenticationSchemes Scheme { get { return _scheme; } @@ -164,13 +171,13 @@ namespace WebSocketSharp public string Uri { get { - return _parameters ["uri"]; + return _parameters["uri"]; } } public string UserName { get { - return _parameters ["username"]; + return _parameters["username"]; } } @@ -178,40 +185,119 @@ namespace WebSocketSharp #region Private Methods + private static string createA1 (string username, string password, string realm) + { + return String.Format ("{0}:{1}:{2}", username, realm, password); + } + + private static string createA1 ( + string username, string password, string realm, string nonce, string cnonce) + { + return String.Format ( + "{0}:{1}:{2}", hash (createA1 (username, password, realm)), nonce, cnonce); + } + + private static string createA2 (string method, string uri) + { + return String.Format ("{0}:{1}", method, uri); + } + + private static string createA2 (string method, string uri, string entity) + { + return String.Format ("{0}:{1}:{2}", method, uri, entity); + } + + private static string hash (string value) + { + var src = Encoding.UTF8.GetBytes (value); + var md5 = MD5.Create (); + var hashed = md5.ComputeHash (src); + + var res = new StringBuilder (64); + foreach (var b in hashed) + res.Append (b.ToString ("x2")); + + return res.ToString (); + } + private void initAsDigest () { - var qops = _parameters ["qop"]; + var qops = _parameters["qop"]; if (qops != null) { if (qops.Split (',').Contains (qop => qop.Trim ().ToLower () == "auth")) { - _parameters ["qop"] = "auth"; - _parameters ["nc"] = String.Format ("{0:x8}", ++_nonceCount); - _parameters ["cnonce"] = HttpUtility.CreateNonceValue (); + _parameters["qop"] = "auth"; + _parameters["nc"] = String.Format ("{0:x8}", ++_nonceCount); + _parameters["cnonce"] = CreateNonceValue (); } else { - _parameters ["qop"] = null; + _parameters["qop"] = null; } } - _parameters ["method"] = "GET"; - _parameters ["response"] = HttpUtility.CreateRequestDigest (_parameters); + _parameters["method"] = "GET"; + _parameters["response"] = CreateRequestDigest (_parameters); } #endregion - #region Public Methods + #region Internal Methods - public static AuthenticationResponse Parse (string value) + internal static string CreateNonceValue () + { + var src = new byte[16]; + var rand = new Random (); + rand.NextBytes (src); + + var res = new StringBuilder (32); + foreach (var b in src) + res.Append (b.ToString ("x2")); + + return res.ToString (); + } + + internal static string CreateRequestDigest (NameValueCollection parameters) + { + var username = parameters["username"]; + var password = parameters["password"]; + var realm = parameters["realm"]; + var nonce = parameters["nonce"]; + var uri = parameters["uri"]; + var algorithm = parameters["algorithm"]; + var qop = parameters["qop"]; + var nc = parameters["nc"]; + var cnonce = parameters["cnonce"]; + var method = parameters["method"]; + + var a1 = algorithm != null && algorithm.ToLower () == "md5-sess" + ? createA1 (username, password, realm, nonce, cnonce) + : createA1 (username, password, realm); + + var a2 = qop != null && qop.ToLower () == "auth-int" + ? createA2 (method, uri, parameters["entity"]) + : createA2 (method, uri); + + var secret = hash (a1); + var data = qop != null + ? String.Format ("{0}:{1}:{2}:{3}:{4}", nonce, nc, cnonce, qop, hash (a2)) + : String.Format ("{0}:{1}", nonce, hash (a2)); + + return hash (String.Format ("{0}:{1}", secret, data)); + } + + internal static AuthenticationResponse Parse (string value) { try { - var credentials = value.Split (new [] { ' ' }, 2); - if (credentials.Length != 2) + var cred = value.Split (new[] { ' ' }, 2); + if (cred.Length != 2) return null; - var scheme = credentials [0].ToLower (); + var scheme = cred[0].ToLower (); return scheme == "basic" - ? new AuthenticationResponse (scheme, credentials [1].ParseBasicCredentials ()) + ? new AuthenticationResponse ( + AuthenticationSchemes.Basic, ParseBasicCredentials (cred[1])) : scheme == "digest" - ? new AuthenticationResponse (scheme, credentials [1].ParseAuthParameters ()) + ? new AuthenticationResponse ( + AuthenticationSchemes.Digest, ParseParameters (cred[1])) : null; } catch { @@ -220,23 +306,101 @@ namespace WebSocketSharp return null; } + internal static NameValueCollection ParseBasicCredentials (string value) + { + // Decode the basic-credentials (a Base64 encoded string). + var userPass = Encoding.Default.GetString (Convert.FromBase64String (value)); + + // The format is [\]:. + var i = userPass.IndexOf (':'); + var user = userPass.Substring (0, i); + var pass = i < userPass.Length - 1 ? userPass.Substring (i + 1) : String.Empty; + + // Check if 'domain' exists. + i = user.IndexOf ('\\'); + if (i > -1) + user = user.Substring (i + 1); + + var res = new NameValueCollection (); + res["username"] = user; + res["password"] = pass; + + return res; + } + + internal static NameValueCollection ParseParameters (string value) + { + var res = new NameValueCollection (); + foreach (var param in value.SplitHeaderValue (',')) { + var i = param.IndexOf ('='); + var name = i > 0 ? param.Substring (0, i).Trim () : null; + var val = i < 0 + ? param.Trim ().Trim ('"') + : i < param.Length - 1 + ? param.Substring (i + 1).Trim ().Trim ('"') + : String.Empty; + + res.Add (name, val); + } + + return res; + } + + internal string ToBasicString () + { + var userPass = String.Format ("{0}:{1}", _parameters["username"], _parameters["password"]); + var cred = Convert.ToBase64String (Encoding.UTF8.GetBytes (userPass)); + + return "Basic " + cred; + } + + internal string ToDigestString () + { + var res = new StringBuilder (64); + res.AppendFormat ("username=\"{0}\"", _parameters["username"]); + res.AppendFormat (", realm=\"{0}\"", _parameters["realm"]); + res.AppendFormat (", nonce=\"{0}\"", _parameters["nonce"]); + res.AppendFormat (", uri=\"{0}\"", _parameters["uri"]); + + var algorithm = _parameters["algorithm"]; + if (algorithm != null) + res.AppendFormat (", algorithm={0}", algorithm); + + res.AppendFormat (", response=\"{0}\"", _parameters["response"]); + + var qop = _parameters["qop"]; + if (qop != null) { + res.AppendFormat (", qop={0}", qop); + res.AppendFormat (", nc={0}", _parameters["nc"]); + res.AppendFormat (", cnonce=\"{0}\"", _parameters["cnonce"]); + } + + var opaque = _parameters["opaque"]; + if (opaque != null) + res.AppendFormat (", opaque=\"{0}\"", opaque); + + return "Digest " + res.ToString (); + } + + #endregion + + #region Public Methods + public IIdentity ToIdentity () { - return _scheme == "basic" - ? new HttpBasicIdentity ( - _parameters ["username"], _parameters ["password"]) as IIdentity - : _scheme == "digest" + return _scheme == AuthenticationSchemes.Basic + ? new HttpBasicIdentity (_parameters["username"], _parameters["password"]) as IIdentity + : _scheme == AuthenticationSchemes.Digest ? new HttpDigestIdentity (_parameters) : null; } public override string ToString () { - return _scheme == "basic" - ? HttpUtility.CreateBasicAuthCredentials ( - _parameters ["username"], _parameters ["password"]) - : _scheme == "digest" - ? HttpUtility.CreateDigestAuthCredentials (_parameters) + return _scheme == AuthenticationSchemes.Basic + ? ToBasicString () + : _scheme == AuthenticationSchemes.Digest + ? ToDigestString () : String.Empty; } diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 4400963c..ec4501c7 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -6,7 +6,6 @@ * - GetStatusDescription is derived from System.Net.HttpListenerResponse.cs * - IsPredefinedScheme is derived from System.Uri.cs * - MaybeUri is derived from System.Uri.cs - * - ParseBasicCredentials is derived from System.Net.HttpListenerContext.cs * * The MIT License * @@ -571,46 +570,6 @@ namespace WebSocketSharp return true; } - internal static NameValueCollection ParseAuthParameters (this string value) - { - var res = new NameValueCollection (); - foreach (var param in value.SplitHeaderValue (',')) { - var i = param.IndexOf ('='); - var name = i > 0 ? param.Substring (0, i).Trim () : null; - var val = i < 0 - ? param.Trim ().Trim ('"') - : i < param.Length - 1 - ? param.Substring (i + 1).Trim ().Trim ('"') - : String.Empty; - - res.Add (name, val); - } - - return res; - } - - internal static NameValueCollection ParseBasicCredentials (this string value) - { - // Decode the basic-credentials (a Base64 encoded string). - var cred = Encoding.Default.GetString (Convert.FromBase64String (value)); - - // The format is [\]:. - var i = cred.IndexOf (':'); - var user = cred.Substring (0, i); - var pass = i < cred.Length - 1 ? cred.Substring (i + 1) : String.Empty; - - // Check if 'domain' exists. - i = user.IndexOf ('\\'); - if (i > -1) - user = user.Substring (i + 1); - - var res = new NameValueCollection (); - res ["username"] = user; - res ["password"] = pass; - - return res; - } - internal static string Quote (this string value) { return value.IsToken () diff --git a/websocket-sharp/Net/HttpDigestIdentity.cs b/websocket-sharp/Net/HttpDigestIdentity.cs index 5ad16cbd..caa471aa 100644 --- a/websocket-sharp/Net/HttpDigestIdentity.cs +++ b/websocket-sharp/Net/HttpDigestIdentity.cs @@ -175,7 +175,7 @@ namespace WebSocketSharp.Net parameters ["method"] = method; parameters ["entity"] = entity; - return _parameters ["response"] == HttpUtility.CreateRequestDigest (parameters); + return _parameters ["response"] == AuthenticationResponse.CreateRequestDigest (parameters); } #endregion diff --git a/websocket-sharp/Net/HttpUtility.cs b/websocket-sharp/Net/HttpUtility.cs index f6c76d03..ab0d0311 100644 --- a/websocket-sharp/Net/HttpUtility.cs +++ b/websocket-sharp/Net/HttpUtility.cs @@ -47,7 +47,6 @@ using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Text; -using System.Security.Cryptography; namespace WebSocketSharp.Net { @@ -78,27 +77,6 @@ namespace WebSocketSharp.Net #region Private Methods - private static string getA1 (string username, string password, string realm) - { - return String.Format ("{0}:{1}:{2}", username, realm, password); - } - - private static string getA1 ( - string username, string password, string realm, string nonce, string cnonce) - { - return String.Format ("{0}:{1}:{2}", hash (getA1 (username, password, realm)), nonce, cnonce); - } - - private static string getA2 (string method, string uri) - { - return String.Format ("{0}:{1}", method, uri); - } - - private static string getA2 (string method, string uri, string entity) - { - return String.Format ("{0}:{1}:{2}", method, uri, entity); - } - private static int getChar (byte [] bytes, int offset, int length) { var value = 0; @@ -150,19 +128,6 @@ namespace WebSocketSharp.Net : -1; } - private static string hash (string value) - { - var src = Encoding.UTF8.GetBytes (value); - var md5 = MD5.Create (); - var hashed = md5.ComputeHash (src); - - var res = new StringBuilder (64); - foreach (var b in hashed) - res.Append (b.ToString ("x2")); - - return res.ToString (); - } - private static void initEntities () { // Build the dictionary of HTML entity references. @@ -532,103 +497,6 @@ namespace WebSocketSharp.Net #region Internal Methods - internal static string CreateBasicAuthChallenge (string realm) - { - return String.Format ("Basic realm=\"{0}\"", realm); - } - - internal static string CreateBasicAuthCredentials (string username, string password) - { - var userPass = String.Format ("{0}:{1}", username, password); - var base64UserPass = Convert.ToBase64String (Encoding.UTF8.GetBytes (userPass)); - - return "Basic " + base64UserPass; - } - - internal static string CreateDigestAuthChallenge (string realm) - { - var nonce = CreateNonceValue (); - var algorithm = "MD5"; - var qop = "auth"; - - return String.Format ( - "Digest realm=\"{0}\", nonce=\"{1}\", algorithm={2}, qop=\"{3}\"", - realm, - nonce, - algorithm, - qop); - } - - internal static string CreateDigestAuthCredentials (NameValueCollection authParams) - { - var digestRes = new StringBuilder (64); - digestRes.AppendFormat ("username=\"{0}\"", authParams ["username"]); - digestRes.AppendFormat (", realm=\"{0}\"", authParams ["realm"]); - digestRes.AppendFormat (", nonce=\"{0}\"", authParams ["nonce"]); - digestRes.AppendFormat (", uri=\"{0}\"", authParams ["uri"]); - - var algorithm = authParams ["algorithm"]; - if (algorithm != null) - digestRes.AppendFormat (", algorithm={0}", algorithm); - - digestRes.AppendFormat (", response=\"{0}\"", authParams ["response"]); - - var qop = authParams ["qop"]; - if (qop != null) { - digestRes.AppendFormat (", qop={0}", qop); - digestRes.AppendFormat (", nc={0}", authParams ["nc"]); - digestRes.AppendFormat (", cnonce=\"{0}\"", authParams ["cnonce"]); - } - - var opaque = authParams ["opaque"]; - if (opaque != null) - digestRes.AppendFormat (", opaque=\"{0}\"", opaque); - - return "Digest " + digestRes.ToString (); - } - - internal static string CreateNonceValue () - { - var src = new byte [16]; - var rand = new Random (); - rand.NextBytes (src); - - var nonce = new StringBuilder (32); - foreach (var b in src) - nonce.Append (b.ToString ("x2")); - - return nonce.ToString (); - } - - internal static string CreateRequestDigest (NameValueCollection parameters) - { - var username = parameters ["username"]; - var password = parameters ["password"]; - var realm = parameters ["realm"]; - var nonce = parameters ["nonce"]; - var uri = parameters ["uri"]; - var algorithm = parameters ["algorithm"]; - var qop = parameters ["qop"]; - var nc = parameters ["nc"]; - var cnonce = parameters ["cnonce"]; - var method = parameters ["method"]; - - var a1 = algorithm != null && algorithm.ToLower () == "md5-sess" - ? getA1 (username, password, realm, nonce, cnonce) - : getA1 (username, password, realm); - - var a2 = qop != null && qop.ToLower () == "auth-int" - ? getA2 (method, uri, parameters ["entity"]) - : getA2 (method, uri); - - var secret = hash (a1); - var data = qop != null - ? String.Format ("{0}:{1}:{2}:{3}:{4}", nonce, nc, cnonce, qop, hash (a2)) - : String.Format ("{0}:{1}", nonce, hash (a2)); - - return hash (String.Format ("{0}:{1}", secret, data)); - } - internal static Uri CreateRequestUrl ( string requestUri, string host, bool websocketRequest, bool secure) { diff --git a/websocket-sharp/Net/ListenerAsyncResult.cs b/websocket-sharp/Net/ListenerAsyncResult.cs index 8a03852e..b1e1025c 100644 --- a/websocket-sharp/Net/ListenerAsyncResult.cs +++ b/websocket-sharp/Net/ListenerAsyncResult.cs @@ -157,7 +157,7 @@ namespace WebSocketSharp.Net if (scheme == AuthenticationSchemes.Basic && (header == null || !header.StartsWith ("basic", StringComparison.OrdinalIgnoreCase))) { context.Response.CloseWithAuthChallenge ( - HttpUtility.CreateBasicAuthChallenge (listener.Realm)); + AuthenticationChallenge.CreateBasicChallenge (listener.Realm).ToBasicString ()); listener.BeginGetContext (this); return; @@ -166,7 +166,7 @@ namespace WebSocketSharp.Net if (scheme == AuthenticationSchemes.Digest && (header == null || !header.StartsWith ("digest", StringComparison.OrdinalIgnoreCase))) { context.Response.CloseWithAuthChallenge ( - HttpUtility.CreateDigestAuthChallenge (listener.Realm)); + AuthenticationChallenge.CreateDigestChallenge (listener.Realm).ToDigestString ()); listener.BeginGetContext (this); return; diff --git a/websocket-sharp/Server/HttpServer.cs b/websocket-sharp/Server/HttpServer.cs index 7b2d5491..8edfb596 100644 --- a/websocket-sharp/Server/HttpServer.cs +++ b/websocket-sharp/Server/HttpServer.cs @@ -521,10 +521,10 @@ namespace WebSocketSharp.Server if (scheme == AuthenticationSchemes.Basic) context.Response.CloseWithAuthChallenge ( - HttpUtility.CreateBasicAuthChallenge (_listener.Realm)); + AuthenticationChallenge.CreateBasicChallenge (_listener.Realm).ToBasicString ()); else if (scheme == AuthenticationSchemes.Digest) context.Response.CloseWithAuthChallenge ( - HttpUtility.CreateDigestAuthChallenge (_listener.Realm)); + AuthenticationChallenge.CreateDigestChallenge (_listener.Realm).ToDigestString ()); else context.Response.Close (HttpStatusCode.Forbidden); diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs index 712bf5fd..007af3ed 100644 --- a/websocket-sharp/Server/WebSocketServer.cs +++ b/websocket-sharp/Server/WebSocketServer.cs @@ -522,10 +522,10 @@ namespace WebSocketSharp.Server AuthenticationSchemes scheme, TcpListenerWebSocketContext context) { var challenge = scheme == AuthenticationSchemes.Basic - ? HttpUtility.CreateBasicAuthChallenge (Realm) - : scheme == AuthenticationSchemes.Digest - ? HttpUtility.CreateDigestAuthChallenge (Realm) - : null; + ? AuthenticationChallenge.CreateBasicChallenge (Realm).ToBasicString () + : scheme == AuthenticationSchemes.Digest + ? AuthenticationChallenge.CreateDigestChallenge (Realm).ToDigestString () + : null; if (challenge == null) { context.Close (HttpStatusCode.Forbidden); diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 53bd2016..d59d6bda 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1236,7 +1236,8 @@ namespace WebSocketSharp var res = sendHandshakeRequest (req); if (res.IsUnauthorized) { _authChallenge = res.AuthChallenge; - if (_credentials != null && (!_preAuth || _authChallenge.Scheme == "digest")) { + if (_credentials != null && + (!_preAuth || _authChallenge.Scheme == AuthenticationSchemes.Digest)) { if (res.Headers.Contains ("Connection", "close")) { closeClientResources (); setClientStream ();