| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 | using System;using System.Net;using System.Security.Principal;using MediaBrowser.Model.Cryptography;using MediaBrowser.Model.IO;using MediaBrowser.Model.Logging;using MediaBrowser.Model.Text;using SocketHttpListener.Net.WebSockets;using SocketHttpListener.Primitives;namespace SocketHttpListener.Net{    public sealed class HttpListenerContext    {        HttpListenerRequest request;        HttpListenerResponse response;        IPrincipal user;        HttpConnection cnc;        string error;        int err_status = 400;        private readonly ICryptoProvider _cryptoProvider;        private readonly IMemoryStreamFactory _memoryStreamFactory;        private readonly ITextEncoding _textEncoding;        internal HttpListenerContext(HttpConnection cnc, ILogger logger, ICryptoProvider cryptoProvider, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding, IFileSystem fileSystem)        {            this.cnc = cnc;            _cryptoProvider = cryptoProvider;            _memoryStreamFactory = memoryStreamFactory;            _textEncoding = textEncoding;            request = new HttpListenerRequest(this, _textEncoding);            response = new HttpListenerResponse(this, _textEncoding);        }        internal int ErrorStatus        {            get { return err_status; }            set { err_status = value; }        }        internal string ErrorMessage        {            get { return error; }            set { error = value; }        }        internal bool HaveError        {            get { return (error != null); }        }        internal HttpConnection Connection        {            get { return cnc; }        }        public HttpListenerRequest Request        {            get { return request; }        }        public HttpListenerResponse Response        {            get { return response; }        }        public IPrincipal User        {            get { return user; }        }        internal void ParseAuthentication(AuthenticationSchemes expectedSchemes)        {            if (expectedSchemes == AuthenticationSchemes.Anonymous)                return;            // TODO: Handle NTLM/Digest modes            string header = request.Headers["Authorization"];            if (header == null || header.Length < 2)                return;            string[] authenticationData = header.Split(new char[] { ' ' }, 2);            if (string.Equals(authenticationData[0], "basic", StringComparison.OrdinalIgnoreCase))            {                user = ParseBasicAuthentication(authenticationData[1]);            }            // TODO: throw if malformed -> 400 bad request        }        internal IPrincipal ParseBasicAuthentication(string authData)        {            try            {                // Basic AUTH Data is a formatted Base64 String                //string domain = null;                string user = null;                string password = null;                int pos = -1;                var authDataBytes = Convert.FromBase64String(authData);                string authString = _textEncoding.GetDefaultEncoding().GetString(authDataBytes, 0, authDataBytes.Length);                // The format is DOMAIN\username:password                // Domain is optional                pos = authString.IndexOf(':');                // parse the password off the end                password = authString.Substring(pos + 1);                // discard the password                authString = authString.Substring(0, pos);                // check if there is a domain                pos = authString.IndexOf('\\');                if (pos > 0)                {                    //domain = authString.Substring (0, pos);                    user = authString.Substring(pos);                }                else                {                    user = authString;                }                HttpListenerBasicIdentity identity = new HttpListenerBasicIdentity(user, password);                // TODO: What are the roles MS sets                return new GenericPrincipal(identity, new string[0]);            }            catch (Exception)            {                // Invalid auth data is swallowed silently                return null;            }        }        public HttpListenerWebSocketContext AcceptWebSocket(string protocol)        {            if (protocol != null)            {                if (protocol.Length == 0)                    throw new ArgumentException("An empty string.", "protocol");                if (!protocol.IsToken())                    throw new ArgumentException("Contains an invalid character.", "protocol");            }            return new HttpListenerWebSocketContext(this, protocol, _cryptoProvider, _memoryStreamFactory);        }    }    public class GenericPrincipal : IPrincipal    {        private IIdentity m_identity;        private string[] m_roles;        public GenericPrincipal(IIdentity identity, string[] roles)        {            if (identity == null)                throw new ArgumentNullException("identity");            m_identity = identity;            if (roles != null)            {                m_roles = new string[roles.Length];                for (int i = 0; i < roles.Length; ++i)                {                    m_roles[i] = roles[i];                }            }            else            {                m_roles = null;            }        }        public virtual IIdentity Identity        {            get            {                return m_identity;            }        }        public virtual bool IsInRole(string role)        {            if (role == null || m_roles == null)                return false;            for (int i = 0; i < m_roles.Length; ++i)            {                if (m_roles[i] != null && String.Compare(m_roles[i], role, StringComparison.OrdinalIgnoreCase) == 0)                    return true;            }            return false;        }    }}
 |