/* * Copyright 1999-2010 University of Chicago * * 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 org.globus.gsi; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.StringReader; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.regex.Pattern; import javax.security.auth.x500.X500Principal; import org.globus.gsi.SigningPolicy; import org.globus.gsi.testutils.FileSetupUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; public class SigningPolicyParserTest { FileSetupUtil successFile; FileSetupUtil singleAllowedDn; FileSetupUtil[] tabTestFiles; @Before public void setup() throws Exception { this.successFile = new FileSetupUtil( "certificateUtilTest/samplePolicy.signing_policy"); this.singleAllowedDn = new FileSetupUtil("certificateUtilTest/5aba75cb.signing_policy"); this.tabTestFiles = new FileSetupUtil[3]; this.tabTestFiles[0] = new FileSetupUtil("certificateUtilTest/afe55e66.signing_policy"); this.tabTestFiles[1] = new FileSetupUtil("certificateUtilTest/cf4ba8c8.signing_policy"); this.tabTestFiles[2] = new FileSetupUtil("certificateUtilTest/49f18420.signing_policy"); } @Test public void testPatternMatching() throws Exception { // test getPattern method // no wildcards or question marks String patternStr = "CN=abcdefgh"; String patternR = (SigningPolicyParser.getPattern(patternStr)) .pattern(); assertTrue("CN=abcdefgh".equals(patternR)); // first character wildcard and question marks String pattern1Str = "CN=*def?gh?"; Pattern pattern1 = SigningPolicyParser.getPattern(pattern1Str); String pattern1R = pattern1.pattern(); assertTrue(("CN=" + SigningPolicyParser.WILDCARD_PATTERN + "def" + SigningPolicyParser.SINGLE_PATTERN + "gh" + SigningPolicyParser.SINGLE_PATTERN).equals(pattern1R)); // only wild cards String pattern2Str = "/CN=abc*def*gh"; Pattern pattern2 = SigningPolicyParser.getPattern(pattern2Str); String pattern2R = pattern2.pattern(); assertTrue( ("/CN=abc" + SigningPolicyParser.WILDCARD_PATTERN + "def" + SigningPolicyParser.WILDCARD_PATTERN + "gh").equals( pattern2R)); // test isValidDN methods // Add patern2, wildcards in middle Vector<Pattern> allowed = new Vector(); allowed.add(pattern2); X500Principal fooPrincipal = new X500Principal("CN=foo"); SigningPolicy policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject21 = new X500Principal("CN=abc12DEF34defdef56gh"); assertTrue(policy.isValidSubject(subject21)); X500Principal subject22 = new X500Principal("CN=123abc12def34defdef56gh"); assertFalse(policy.isValidSubject(subject22)); X500Principal subject23 = new X500Principal("CN=abc12def34defdef56gh123"); assertFalse(policy.isValidSubject(subject23)); // wildcard as first and last character String pattern3Str = "*abc*def*gh*"; Pattern pattern3 = SigningPolicyParser.getPattern(pattern3Str); allowed.clear(); allowed.add(pattern3); policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject31 = new X500Principal("CN=ABC12def34defdef56gh"); assertTrue(policy.isValidSubject(subject31)); X500Principal subject32 = new X500Principal("CN=123abc12def34defdef56gh555"); assertTrue(policy.isValidSubject(subject32)); // use of space and slashes, from old signing policy file String pattern4Str = "/C=US/O=Globus/*"; Pattern pattern4 = SigningPolicyParser.getPattern(pattern4Str); allowed.clear(); allowed.add(pattern4); policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject41 = new X500Principal( "CN=Globus Certification Authority, O=Globus, C=US"); assertTrue(policy.isValidSubject(subject41)); // wildcard as first character, question mark String pattern5Str = "/*C=US/O=Globus/CN=foo-?/CN=*"; Pattern pattern5 = SigningPolicyParser.getPattern(pattern5Str); allowed.clear(); allowed.add(pattern5); policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject51 = new X500Principal( "CN=Globus Certification Authority, O=Globus, O=US"); assertFalse(policy.isValidSubject(subject51)); X500Principal subject52 = new X500Principal( "CN=test space,CN=a12b,CN=foo-1,O=Globus,C=US,C=SOME"); assertTrue(policy.isValidSubject(subject52)); X500Principal subject53 = new X500Principal("CN=,CN=foo-k,O=Globus,C=US"); assertTrue(policy.isValidSubject(subject53)); X500Principal subject54 = new X500Principal("CN= , CN=foo-1, O=Globus, C=US"); assertTrue(policy.isValidSubject(subject54)); X500Principal subject55 = new X500Principal("C=US,O=Globus,CN=foo-123,CN="); assertFalse(policy.isValidSubject(subject55)); // multiple question mark with punctuation String pattern6Str = "/C=US/O=global/CN=*/CN=user-??"; Pattern pattern6 = SigningPolicyParser.getPattern(pattern6Str); allowed.clear(); allowed.add(pattern6); policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject61 = new X500Principal("CN=user-12,CN=foo,O=Globus,C=US"); assertFalse(policy.isValidSubject(subject61)); X500Principal subject62 = new X500Principal("CN=user-12,CN=foo,O=Global,C=US"); assertTrue(policy.isValidSubject(subject62)); X500Principal subject63 = new X500Principal("CN=user-12,CN=bar 1,CN=foo ,O=global,C=US"); assertTrue(policy.isValidSubject(subject63)); // add multiple patterns and test validity if atleast one matches String pattern7Str = "/C=US/O=Globus/CN=*/CN=user-??"; Pattern pattern7 = SigningPolicyParser.getPattern(pattern7Str); allowed.add(pattern7); policy = new SigningPolicy(fooPrincipal, allowed); X500Principal subject71 = new X500Principal("CN=user-12, CN=bar 1, CN=foo , O=Globus,C=US"); assertTrue(policy.isValidSubject(subject71)); assertTrue(policy.isValidSubject(subject63)); } // JGLOBUS-103 @Test public void testFileSuccess() throws Exception { this.successFile.copyFileToTemp(); SigningPolicyParser parser = new SigningPolicyParser(); Map<X500Principal, SigningPolicy> map = parser.parse(this.successFile.getAbsoluteFilename()); assertTrue(map != null); SigningPolicy policy = map.get(new X500Principal( "CN=Globus Certification Authority,O=Globus,C=US")); assertTrue(policy != null); List<Pattern> allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 2); List<String> patterns = new Vector(2); patterns.add((allowedDN.get(0)).pattern()); patterns.add((allowedDN.get(1)).pattern()); // given the getPattern method is already tested, assuming it // works here. Pattern p1 = SigningPolicyParser.getPattern("/C=us/O=Globus/*"); assertTrue(patterns.contains(p1.pattern())); p1 = SigningPolicyParser.getPattern("/C=US/O=Globus/*"); assertTrue(patterns.contains(p1.pattern())); p1 = SigningPolicyParser .getPattern("/C=us/O=National Computational Science Alliance/*"); assertFalse(patterns.contains(p1.pattern())); policy = map.get(new X500Principal( "CN=Globus Certification Authority,O=National Computational Science Alliance,C=US")); assertTrue(policy != null); allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 1); patterns.clear(); patterns.add(((Pattern) allowedDN.get(0)).pattern()); p1 = SigningPolicyParser .getPattern("/C=us/O=National Computational Science Alliance/*"); assertTrue(patterns.contains(p1.pattern())); // test file with single allows DN without double quotes this.singleAllowedDn.copyFileToTemp(); map.clear(); map = parser.parse(this.singleAllowedDn.getAbsoluteFilename()); policy = map.get(new X500Principal( "OU=Certification Authority,O=National Computational Science Alliance,C=US")); assertTrue(policy != null); allowedDN.clear(); allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 1); patterns = new Vector(1); patterns.add(((Pattern) allowedDN.get(0)).pattern()); p1 = SigningPolicyParser .getPattern("/C=US/O=National Computational Science Alliance/*"); assertTrue(patterns.contains(p1.pattern())); } @Test public void testFilesWithTab() throws Exception { this.tabTestFiles[0].copyFileToTemp(); SigningPolicyParser parser = new SigningPolicyParser(); Map<X500Principal, SigningPolicy> map = parser.parse(this.tabTestFiles[0].getAbsoluteFilename()); SigningPolicy policy = map.get(new X500Principal("CN=CyGridCA,O=HPCL,O=CyGrid,C=CY")); assertTrue(policy != null); List<Pattern> allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 1); allowedDN.clear(); map.clear(); this.tabTestFiles[1].copyFileToTemp(); map = parser.parse(this.tabTestFiles[1].getAbsoluteFilename()); policy = map.get(new X500Principal("CN=CNRS,O=CNRS,C=FR")); assertTrue(policy != null); allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 2); Vector patterns = new Vector(2); patterns.add(((Pattern) allowedDN.get(0)).pattern()); patterns.add(((Pattern) allowedDN.get(1)).pattern()); // given the getPattern method is already tested, assuming it // works here. Pattern p1 = SigningPolicyParser .getPattern("/C=FR/O=CNRS/CN=CNRS-Projets"); assertTrue(patterns.contains(p1.pattern())); p1 = SigningPolicyParser.getPattern("/C=FR/O=CNRS/CN=CNRS"); assertTrue(patterns.contains(p1.pattern())); allowedDN.clear(); map.clear(); this.tabTestFiles[2].copyFileToTemp(); map = parser.parse(this.tabTestFiles[2].getAbsoluteFilename()); policy = map.get( new X500Principal("CN=INFN Certification Authority,O=INFN,C=IT")); assertTrue(policy != null); allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 2); patterns.clear(); patterns.add(((Pattern) allowedDN.get(0)).pattern()); patterns.add(((Pattern) allowedDN.get(1)).pattern()); // given the getPattern method is already tested, assuming it // works here. p1 = SigningPolicyParser.getPattern("/C=it/O=INFN/*"); assertTrue(patterns.contains(p1.pattern())); p1 = SigningPolicyParser.getPattern("/C=IT/O=INFN/*"); assertTrue(patterns.contains(p1.pattern())); } @Test(expected = SigningPolicyException.class) public void testFileFailure() throws Exception { SigningPolicyParser parser = new SigningPolicyParser(); parser.parse("Foo"); } @Test public void testParsingFailure() throws Exception { SigningPolicyParser parser = new SigningPolicyParser(); // not x509 String error1 = "access_id_CA notX509 '/C=US/O=Globus/CN=Globus " + "Certification Authority'\n pos_rights globus CA:sign\n" + " cond_subjects globus '\"/C=us/O=Globus/*\" \"/C=US/O=Globus/*\"'"; Map<X500Principal, SigningPolicy> map = null; boolean worked = false; try { map = parser.parse(new StringReader(error1)); } catch (IllegalArgumentException e) { worked = true; } assertTrue(worked); // not globus error1 = "access_id_CA X509 '/C=US/O=Globus/CN=Globus " + "Certification Authority'\n pos_rights notglobus " + "CA:sign\n cond_subjects globus '\"/C=us/O=Globus/*\" " + "\"/C=US/O=Globus/*\"'"; map = parser.parse(new StringReader(error1)); // order of rights matter, atleast one positive right implies // allowed DN error1 = "access_id_CA X509 '/C=US/O=Globus/CN=Globus Certification " + "Authority'\n pos_rights globus CA:sign\n cond_subjects" + " globus '\"/C=us/O=Globus/*\" \"/C=US/O=Globus/*\"' \n " + "neg_rights notglobus some:right"; map = parser.parse(new StringReader(error1)); SigningPolicy policy = map.get(new X500Principal( "CN=Globus Certification Authority,O=Globus,C=US")); assertTrue(policy != null); List<Pattern> allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 2); // incorrect start error1 = "X509 '/C=US/O=Globus/CN=Globus Certification Authority'\n" + " pos_rights notglobus CA:sign\n cond_subjects " + "globus \'\"/C=us/O=Globus/*\" \"/C=US/O=Globus/*\"\'"; boolean exception = false; try { map = parser.parse(new StringReader(error1)); } catch (SigningPolicyException exp) { exception = true; } assertTrue(exception); // erroneous quote error1 = "access_id_CA X509 '/C=US/O=Globus/CN=Globus Certification " + "Authority\n pos_rights notglobus CA:sign\n " + "cond_subjects globus \'\"/C=us/O=Globus/*\" " + "\"/C=US/O=Globus/*\"\'"; exception = false; try { map = parser.parse(new StringReader(error1)); } catch (SigningPolicyException exp) { if ((exp.getMessage().indexOf("invalid")) != -1) { exception = true; } } assertTrue(exception); // neg rights rather than restrictions error1 = "access_id_CA X509 '/C=US/O=Globus/CN=Globus " + "Certification Authority'\n pos_rights globus " + "CA:sign\n neg_rights notglobus some:right"; exception = false; try { map = parser.parse(new StringReader(error1)); } catch (SigningPolicyException exp) { // if ((exp.getMessage().indexOf("File format is incorrect") != -1) && // (exp.getMessage(). // indexOf("neg_rights cannot be used here") != -1)) { exception = true; // } } assertTrue(exception); // first pos_rights is all that matters error1 = "access_id_CA X509 '/C=US/O=Globus/CN=Globus Certification " + "Authority'\n pos_rights globus CA:sign\n " + "cond_subjects globus '\"/C=us/O=Globus/*\" " + "\"/C=US/O=Globus/*\"' \n cond_subjects globus " + "'\"/C=us/O=Globus/*\"'"; map = parser.parse(new StringReader(error1)); policy = map.get(new X500Principal( "CN=Globus Certification Authority,O=Globus,C=US")); assertTrue(policy != null); allowedDN = policy.getAllowedDNs(); assertTrue(allowedDN != null); assertTrue(allowedDN.size() == 2); } @After public void cleanUp() throws Exception { this.singleAllowedDn.deleteFile(); this.successFile.deleteFile(); this.tabTestFiles[0].deleteFile(); this.tabTestFiles[1].deleteFile(); this.tabTestFiles[2].deleteFile(); } }