/*
* 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();
}
}