/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.undertow.server.security; import io.undertow.testutils.category.UnitTest; import io.undertow.security.idm.DigestAlgorithm; import io.undertow.security.impl.DigestAuthorizationToken; import io.undertow.security.impl.DigestQop; import org.junit.Test; import org.junit.experimental.categories.Category; import java.util.EnumMap; import java.util.Map; import static org.junit.Assert.assertEquals; /** * Test case to test the parsing of the Authorization header for Digest requests. * * The RFC defines which values are quoted and which ones are not, however different implementations interpret this differently. * This test case tests different headers generated by supported browsers. * * Ordering of the values is not important, however the construction of the Map of expected values does match the header being * tested for readability. * * @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a> */ @Category(UnitTest.class) public class ParseDigestAuthorizationTokenTestCase { private void doTest(final String header, final Map<DigestAuthorizationToken, String> expected) { Map<DigestAuthorizationToken, String> parsedHeader = DigestAuthorizationToken.parseHeader(header); assertEquals(expected, parsedHeader); } @Test public void testChrome_22() { final String header = "username=\"userTwo\", realm=\"Digest_Realm\", nonce=\"Yxmkh5liIOYNMTM1MTUyNjQzMTE4NJziT7YLEOEJ4QEN1py4Yog=\", uri=\"/\", algorithm=MD5, response=\"5b26e00233607e8a714cd1d910692e08\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, cnonce=\"8c008c8ce43dc0a7\""; Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class); expected.put(DigestAuthorizationToken.USERNAME, "userTwo"); expected.put(DigestAuthorizationToken.REALM, "Digest_Realm"); expected.put(DigestAuthorizationToken.NONCE, "Yxmkh5liIOYNMTM1MTUyNjQzMTE4NJziT7YLEOEJ4QEN1py4Yog="); expected.put(DigestAuthorizationToken.DIGEST_URI, "/"); expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken()); expected.put(DigestAuthorizationToken.RESPONSE, "5b26e00233607e8a714cd1d910692e08"); expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000"); expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken()); expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001"); expected.put(DigestAuthorizationToken.CNONCE, "8c008c8ce43dc0a7"); doTest(header, expected); } @Test public void testCurl_7() { final String header = "username=\"userTwo\", realm=\"Digest_Realm\", nonce=\"5CgZ39vhie0NMTM1MTUyNDc4ODkwNMwr6sWKVSGfhXB4jBtkupY=\", uri=\"/\", cnonce=\"MTYwOTQ4\", nc=00000001, qop=\"auth\", response=\"c3c1ce9945a0c36d54860eda7846018b\", opaque=\"00000000000000000000000000000000\", algorithm=\"MD5\""; Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class); expected.put(DigestAuthorizationToken.USERNAME, "userTwo"); expected.put(DigestAuthorizationToken.REALM, "Digest_Realm"); expected.put(DigestAuthorizationToken.NONCE, "5CgZ39vhie0NMTM1MTUyNDc4ODkwNMwr6sWKVSGfhXB4jBtkupY="); expected.put(DigestAuthorizationToken.DIGEST_URI, "/"); expected.put(DigestAuthorizationToken.CNONCE, "MTYwOTQ4"); expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001"); expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken()); expected.put(DigestAuthorizationToken.RESPONSE, "c3c1ce9945a0c36d54860eda7846018b"); expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000"); expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken()); doTest(header, expected); } @Test public void testFirefox_16() { final String header = "username=\"userOne\", realm=\"Digest_Realm\", nonce=\"nBhFxtSS6rkNMTM1MTUyNjE2MjgyNWA/xW/LOH53vhXGq/2B/yQ=\", uri=\"/\", algorithm=MD5, response=\"b0adb1025da2de0d16f44131858bad6f\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, cnonce=\"8127726535363b07\""; Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class); expected.put(DigestAuthorizationToken.USERNAME, "userOne"); expected.put(DigestAuthorizationToken.REALM, "Digest_Realm"); expected.put(DigestAuthorizationToken.NONCE, "nBhFxtSS6rkNMTM1MTUyNjE2MjgyNWA/xW/LOH53vhXGq/2B/yQ="); expected.put(DigestAuthorizationToken.DIGEST_URI, "/"); expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken()); expected.put(DigestAuthorizationToken.RESPONSE, "b0adb1025da2de0d16f44131858bad6f"); expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000"); expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken()); expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001"); expected.put(DigestAuthorizationToken.CNONCE, "8127726535363b07"); doTest(header, expected); } @Test public void testOpera_12() { final String header = "username=\"userOne\", realm=\"Digest_Realm\", uri=\"/\", algorithm=MD5, nonce=\"D2floAc+FhkNMTM1MTUyMzY2ODc4Mhbi2Zrcuv1lvdgEaPXa+bg=\", cnonce=\"v722VYJEeG28C3SoXS8BEWThGHPDOlXgUCCts70i7Fc=\", opaque=\"00000000000000000000000000000000\", qop=auth, nc=00000001, response=\"8106a5d19bc67982527cbb576658f9d6\""; Map<DigestAuthorizationToken, String> expected = new EnumMap<>(DigestAuthorizationToken.class); expected.put(DigestAuthorizationToken.USERNAME, "userOne"); expected.put(DigestAuthorizationToken.REALM, "Digest_Realm"); expected.put(DigestAuthorizationToken.DIGEST_URI, "/"); expected.put(DigestAuthorizationToken.ALGORITHM, DigestAlgorithm.MD5.getToken()); expected.put(DigestAuthorizationToken.NONCE, "D2floAc+FhkNMTM1MTUyMzY2ODc4Mhbi2Zrcuv1lvdgEaPXa+bg="); expected.put(DigestAuthorizationToken.CNONCE, "v722VYJEeG28C3SoXS8BEWThGHPDOlXgUCCts70i7Fc="); expected.put(DigestAuthorizationToken.OPAQUE, "00000000000000000000000000000000"); expected.put(DigestAuthorizationToken.MESSAGE_QOP, DigestQop.AUTH.getToken()); expected.put(DigestAuthorizationToken.NONCE_COUNT, "00000001"); expected.put(DigestAuthorizationToken.RESPONSE, "8106a5d19bc67982527cbb576658f9d6"); doTest(header, expected); } }