Esempio n. 1
0
        public void Encode(HTTP2Stream context, HTTPRequest request, Queue <HTTP2FrameHeaderAndPayload> to, UInt32 streamId)
        {
            // Add usage of SETTINGS_MAX_HEADER_LIST_SIZE to be able to create a header and one or more continuation fragments
            // (https://httpwg.org/specs/rfc7540.html#SettingValues)

            using (BufferPoolMemoryStream bufferStream = new BufferPoolMemoryStream())
            {
                WriteHeader(bufferStream, ":method", HTTPRequest.MethodNames[(int)request.MethodType]);
                // add path
                WriteHeader(bufferStream, ":path", request.CurrentUri.PathAndQuery);
                // add authority
                WriteHeader(bufferStream, ":authority", request.CurrentUri.Authority);
                // add scheme
                WriteHeader(bufferStream, ":scheme", "https");

                //bool hasBody = false;

                // add other, regular headers
                request.EnumerateHeaders((header, values) =>
                {
                    if (header.Equals("connection", StringComparison.OrdinalIgnoreCase) ||
                        header.Equals("te", StringComparison.OrdinalIgnoreCase) ||
                        header.Equals("host", StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }

                    //if (!hasBody)
                    //    hasBody = header.Equals("content-length", StringComparison.OrdinalIgnoreCase) && int.Parse(values[0]) > 0;

                    // https://httpwg.org/specs/rfc7540.html#HttpSequence
                    // The chunked transfer encoding defined in Section 4.1 of [RFC7230] MUST NOT be used in HTTP/2.
                    if (header.Equals("Transfer-Encoding", StringComparison.OrdinalIgnoreCase))
                    {
                        // error!
                    }

                    for (int i = 0; i < values.Count; ++i)
                    {
                        WriteHeader(bufferStream, header, values[i]);

                        if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                        {
                            HTTPManager.Logger.Information("HPACKEncoder", string.Format("[{0}] - Encode - Header({1}/{2}): '{3}': '{4}'", context.Id, i + 1, values.Count, header, values[i]));
                        }
                    }
                }, true);

                byte[] requestBody = request.GetEntityBody();
                CreateHeaderFrames(to,
                                   streamId,
                                   bufferStream.ToArray(true),
                                   (UInt32)bufferStream.Length,
                                   requestBody != null && requestBody.Length > 0 /*hasBody*/);
            }
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        /// <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;
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }