コード例 #1
0
ファイル: HttpHelper.cs プロジェクト: kudrinyaroslav/ON-0110
        /// <summary>
        /// Create HTTP headers for a SOAP message.
        /// </summary>
        /// <param name="size">SOAP message size.</param>
        /// <param name="path">Address for the first line.</param>
        /// <param name="address">Hostname.</param>
        /// <param name="packet"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="testingSettings"></param>
        /// <returns>UTF-8 encoded string.</returns>
        public static byte[] CreateHttpHeaders(long size,
                                               string path,
                                               string address,
                                               HttpPacket packet,
                                               string username,
                                               string password,
                                               DigestTestingSettings testingSettings,
                                               ref string nonceBack,
                                               ref int nonceCounter)
        {
            // Create HTTP headers and add content
            StringBuilder httpRequest = new StringBuilder();

            httpRequest.AppendFormat(STATUSLINEPATTERN, path);
            httpRequest.AppendFormat(HOSTLINEPATTERN, address);
            httpRequest.AppendFormat("{0}: {1}; {2}={3}\r\n", CONTENTTYPE, APPLICATIONSOAPXML, CHARSET, "utf-8");
            if (packet != null)
            {
                HttpDigest.DigestAuthenticationParameters parameters = new HttpDigest.DigestAuthenticationParameters();
                parameters.Address   = path;
                parameters.Challenge = packet;
                parameters.UserName  = username;
                parameters.Password  = password;
                httpRequest.AppendFormat("{0}\r\n", HttpDigest.CreateDigestAuthenticationHeader(parameters, testingSettings, ref nonceBack, ref nonceCounter));
            }
            httpRequest.Append(CONTENTLENGTH + ": " + (size).ToString() + "\r\n");
            httpRequest.Append("\r\n");

            // Convert HTTP request to byte array to send
            return(Encoding.UTF8.GetBytes(httpRequest.ToString()));
        }
コード例 #2
0
ファイル: HttpDigest.cs プロジェクト: kudrinyaroslav/ON-0110
        /// <summary>
        /// Creates header using challenge packet.
        /// </summary>
        /// <returns></returns>
        public static string CreateDigestAuthenticationHeader(
            DigestAuthenticationParameters authenticationParameters,
            DigestTestingSettings testingSettings,
            ref string nonceBack,
            ref int nonceCounter)
        {
            string header = string.Empty;

            string     username = authenticationParameters.UserName;
            string     password = authenticationParameters.Password;
            string     address  = authenticationParameters.Address;
            HttpPacket packet   = authenticationParameters.Challenge;

            if (packet.Headers.ContainsKey(WWWAUTHENTICATEHEADER))
            {
                string challenge = packet.Headers[WWWAUTHENTICATEHEADER];

                int schemeEnd = challenge.IndexOf(' ');

                // scheme - should be "Digest"
                string scheme = challenge.Substring(0, schemeEnd).Trim();

                string authParams = challenge.Substring(schemeEnd).Trim();

                List <int> commas  = new List <int>();
                bool       inQuote = false;
                for (int i = 0; i < authParams.Length; i++)
                {
                    char nextChar = authParams[i];
                    if (nextChar == '"')
                    {
                        inQuote = !inQuote;
                    }
                    else
                    {
                        if (nextChar == ',' && !inQuote)
                        {
                            commas.Add(i);
                        }
                    }
                }
                commas.Add(authParams.Length);

                Dictionary <string, string> parameters = new Dictionary <string, string>(StringComparer.CurrentCultureIgnoreCase);

                int lastStart = 0;
                foreach (int comma in commas)
                {
                    string   field      = authParams.Substring(lastStart, (comma - lastStart));
                    string[] pair       = field.Split('=');
                    var      equalPos   = field.IndexOf('=');
                    var      paramName  = field.Substring(0, equalPos);
                    var      paramValue = field.Substring(equalPos + 1);
                    if (!string.IsNullOrEmpty(paramName) && !string.IsNullOrEmpty(paramValue))
                    {
                        parameters.Add(Unquote(paramName), paramValue.Trim());
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Invalid authentication header: {0}", challenge));
                    }

                    lastStart = comma + 1;
                }


                // parameters are parsed
                // quotes are not trimmed!

                if (parameters[NONCE] != nonceBack)
                {
                    nonceBack    = parameters[NONCE];
                    nonceCounter = 1;
                }
                else
                {
                    nonceCounter++;
                }
                string nonceCounterString = string.Format("{0:x08}", nonceCounter);

                StringBuilder sb = new StringBuilder("Authorization: Digest ");
                if (testingSettings == null || !testingSettings.UserNameMissing)
                {
                    sb.AppendFormat("username=\"{0}\", ", username);
                }

                if (testingSettings == null || !testingSettings.RealmMissing)
                {
                    // realm should contain quotes;
                    sb.AppendFormat("{0}={1}, ", REALM, parameters[REALM]);
                }

                string alg = MD5;
                if (parameters.ContainsKey(ALGORITHM))
                {
                    alg = parameters[ALGORITHM];
                }

                sb.AppendFormat("qop=\"auth\", algorithm=\"{0}\", ", alg);
                if (testingSettings == null || !testingSettings.UriMissing)
                {
                    sb.AppendFormat("uri=\"{0}\", ", address);
                }
                if (testingSettings == null || !testingSettings.NonceMissing)
                {
                    sb.AppendFormat("{0}={1}, nc={2}, ", NONCE, parameters[NONCE], nonceCounterString);
                }

                // cnonce
                string cnonce = GetNonce();
                sb.AppendFormat("cnonce=\"{0}\", ", cnonce);

                // opaque
                if (parameters.ContainsKey(OPAQUE))
                {
                    sb.AppendFormat("{0}={1}, ", OPAQUE, parameters[OPAQUE]);
                }

                // response
                if (testingSettings == null || !testingSettings.ResponseMissing)
                {
                    string realm = Unquote(parameters[REALM]);
                    string nonce = Unquote(parameters[NONCE]);

                    /*
                     * request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
                     *                        ":" nc-value
                     *                        ":" unq(cnonce-value)
                     *                        ":" unq(qop-value)
                     *                        ":" H(A2)
                     *                ) <">
                     *
                     * A1       = unq(username-value) ":" unq(realm-value) ":" passwd
                     *
                     * A2       = Method ":" digest-uri-value
                     *
                     */

                    string a1;
                    a1 = string.Format("{0}:{1}:{2}", username, realm, password);

                    System.Diagnostics.Debug.WriteLine(string.Format("A1: {0}", a1));

                    if (alg == MD5SESS)
                    {
                        if (string.IsNullOrEmpty(_a1))
                        {
                            _a1 = GetMD5HashBinHex(a1);
                        }
                        a1 = string.Format("{0}:{1}:{2}", _a1, nonce, cnonce);
                    }
                    string a2 = string.Format("POST:{0}", address);

                    string ha1 = GetMD5HashBinHex(a1);
                    string ha2 = GetMD5HashBinHex(a2);

                    System.Diagnostics.Debug.WriteLine(string.Format("HA1: {0}", ha1));
                    System.Diagnostics.Debug.WriteLine(string.Format("A2: {0}", a2));
                    System.Diagnostics.Debug.WriteLine(string.Format("HA2: {0}", ha2));

                    string a = string.Format("{0}:{1}:{4}:{2}:auth:{3}", ha1, nonce, cnonce, ha2, nonceCounterString);

                    System.Diagnostics.Debug.WriteLine(string.Format("unhashedDigest: {0}", a));

                    string response = GetMD5HashBinHex(a);
                    System.Diagnostics.Debug.WriteLine(string.Format("hashedDigest: {0}", response));

                    sb.AppendFormat("response=\"{0}\"", response);
                }
                header = sb.ToString();
            }

            return(header);
        }
コード例 #3
0
        byte[] CreateRequest(Message message, out int bodyOffset)
        {
            byte[] messageBytes;

            if (_currentMessageBytes == null)
            {
                // Encode message using _encoder
                // After it message is closed (due to our code)
                ArraySegment <byte> messageBuffer = EncodeMessage(message);

                // Copy byte in order not to use Buffer
                messageBytes = new byte[messageBuffer.Count];
                Array.Copy(messageBuffer.Array, messageBytes, messageBuffer.Count);

                _currentMessageBytes = messageBytes;
            }
            else
            {
                messageBytes = _currentMessageBytes;
            }

            // xml directive to add
            string xmlDirective = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

            string                username = string.Empty;
            string                password = string.Empty;
            HttpPacket            header   = null;
            DigestTestingSettings settings = null;

            if (_credentialsProvider != null)
            {
                username = _credentialsProvider.Username;
                password = _credentialsProvider.Password;
                if (_credentialsProvider.Security == Security.Digest ||
                    _credentialsProvider.Security == Security.DigestTesting)
                {
                    header = _digestAuthChallenge;
                }
                if (_credentialsProvider.Security == Security.DigestTesting)
                {
                    settings = _credentialsProvider.DigestTestingSettings;
                }
            }

            // create headers
            byte[] httpHeaders = HttpHelper.CreateHttpHeaders(messageBytes.Length + xmlDirective.Length,
                                                              _to.Uri.PathAndQuery,
                                                              _to.Uri.Host,
                                                              header, username, password, settings, ref _nonceBack, ref _nonceCounter);

            //whole message with headers
            byte[] bytes = new byte[httpHeaders.Length + messageBytes.Length + xmlDirective.Length];

            Array.Copy(httpHeaders, bytes, httpHeaders.Length);

            Array.Copy(Encoding.UTF8.GetBytes(xmlDirective), 0, bytes, httpHeaders.Length, xmlDirective.Length);

            Array.Copy(messageBytes, 0, bytes, httpHeaders.Length + xmlDirective.Length, messageBytes.Length);

            // body offset - for logger
            bodyOffset = httpHeaders.Length;

            return(bytes);
        }
コード例 #4
0
        // POSTPONED to projects following Erdinger

        /*[Test(Name = "DIGEST AUTHENTICATION – INVALID AUTHENTICATION",
         *  Path = "Security Test Cases",
         *  Order = "01.01.03",
         *  Id = "1-1-3",
         *  Category = Category.SECURITY,
         *  Version = 2.1,
         *  RequirementLevel = RequirementLevel.Must,
         *  RequiredFeatures = new Feature[] { Feature.Digest },
         *  FunctionalityUnderTest = new Functionality[] { Functionality.DigestAuthentication })]*/
        public void DigestAuthenticationParametersTest()
        {
            RunTest(() =>
            {
                Assert(!(string.IsNullOrEmpty(_password) || string.IsNullOrEmpty(_username)),
                       "This test cannot be performed without credentials supplied",
                       "Check if credentials were defined");


                string operationName = _secureOperation;

                string requestDescription = string.Empty;

                Action checkDigest =
                    new Action(
                        () =>
                {
                    bool exception = false;
                    try
                    {
                        RunStep(
                            () => { InvokeOperation(operationName); },
                            string.Format("Invoke {0} {1}", _secureOperation, requestDescription));
                    }
                    catch (Exception exc)
                    {
                        StepPassed();
                        if (exc is HttpTransport.Interfaces.Exceptions.AccessDeniedException)
                        {
                            // digest
                            exception = true;
                        }
                    }
                    finally
                    {
                        DoRequestDelay();
                    }

                    Assert(exception,
                           string.Format("No HTTP 401 response received when operation is invoked {0}", requestDescription),
                           "Check response");
                });

                requestDescription            = "without credentials supplied";
                _credentialsProvider.Security = Security.None;

                // without credentials at all
                checkDigest();

                // with some fields missing
                DigestTestingSettings settings             = new DigestTestingSettings();
                _credentialsProvider.DigestTestingSettings = settings;
                _credentialsProvider.Security = Security.DigestTesting;

                settings.UserNameMissing = true;
                requestDescription       = "without username included in request";

                checkDigest();

                // realm
                settings.RealmMissing    = true;
                settings.UserNameMissing = false;
                requestDescription       = "without realm included in request";

                checkDigest();

                // nonce

                settings.NonceMissing = true;
                settings.RealmMissing = false;
                requestDescription    = "without nonce included in request";

                checkDigest();

                // uri

                settings.UriMissing   = true;
                settings.NonceMissing = false;
                requestDescription    = "without URI included in request";

                checkDigest();

                // response

                settings.ResponseMissing = true;
                settings.UriMissing      = false;
                requestDescription       = "without response included in request";

                checkDigest();
            },
                    () =>
            {
            });
        }