source: java/net/deterlab/abac/CredentialFactory.java @ 1a1acd9

abac0-leakabac0-meimei-idmei-rt0-nmei_rt0tvf-new-xml
Last change on this file since 1a1acd9 was 1a1acd9, checked in by Ted Faber <faber@…>, 11 years ago

Set default CerdentialFactory? to read both GENI and X509

  • Property mode set to 100644
File size: 7.4 KB
Line 
1package net.deterlab.abac;
2
3import java.io.*;
4import java.util.*;
5import java.lang.reflect.*;
6
7
8/**
9 * The system demultiplex point for parsing Credentials.  Static class that
10 * keeps an ordered list of CredentialParsers to try and a couple helper
11 * functions to open files, etc in calling the CredentialParsers.  All
12 * credential parsing should use a credential factory.
13 * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
14 * @version 1.4
15 */
16public class CredentialFactory implements Cloneable {
17    protected List<CredentialFactorySpecialization> spec;
18    static public String[] defNames = new String[] {
19        "net.deterlab.abac.GENICredential",
20        "net.deterlab.abac.X509Credential"
21    };
22    public static final int maxSize = 50 * 1024;
23
24    /**
25     * Create a Credential Factory that parses the default type(s)
26     * @throws ABACException if the object cannot be created
27     */
28    public CredentialFactory() throws ABACException {
29        spec = new ArrayList<CredentialFactorySpecialization>();
30        for ( String name: defNames) 
31            registerClass(name);
32    }
33
34    /**
35     * Create a Credential Factory that parses the given type(s).  Each String
36     * should be the binary name for a class that exports a static
37     * getCredentialParser method that returns a CredentialParser for the
38     * class.
39     * @param names a Collection of Strings naming the classes to parse
40     * @throws ABACException if the object cannot be created
41     */
42    public CredentialFactory(Collection<String> names) throws ABACException {
43        spec = new ArrayList<CredentialFactorySpecialization>();
44        for (String n : names ) 
45            registerClass(n);
46    }
47
48    /**
49     * Create a Credential Factory that parses the given type(s).  Each String
50     * should be the binary name for a class that exports a static
51     * getCredentialParser method that returns a CredentialParser for the
52     * class.
53     * @param names an Array of Strings naming the classes to parse
54     * @throws ABACException if the object cannot be created
55     */
56    public CredentialFactory(String[] names) throws ABACException {
57        spec = new ArrayList<CredentialFactorySpecialization>();
58        for (String n : names ) 
59            registerClass(n);
60    }
61
62    /**
63     * Create a Credential Factory that is a clone of the given
64     * CredentialFactory.
65     * @param cf the CredentialFactory to copy
66     * @throws ABACException if the object cannot be created
67     */
68    public CredentialFactory(CredentialFactory cf) throws ABACException {
69        this();
70
71        spec = new ArrayList<CredentialFactorySpecialization>();
72
73        for ( int i = 0; i < spec.size(); i++) 
74            spec.add(cf.spec.get(i));
75    }
76
77    /**
78     * Make a copy of this CredentialFactory
79     * @returns a CredentialFactory, a copy of this one
80     */
81    public Object clone() throws CloneNotSupportedException {
82        CredentialFactory cf = null;
83        try {
84            cf = new CredentialFactory(this);
85        }
86        catch (ABACException ae) {
87            return null;
88        }
89        return cf;
90    }
91
92
93    /**
94     * Parse an input stream using each possible credential format and the
95     * available identities for validation.  Return the credentials found or
96     * throw an ABACException with the problem.  It wraps the input stream in a
97     * BufferedInputStream in order to retry is a parser fails.  Credentials
98     * larger than maxSize will nor be able to be reparsed.
99     * @param is an InputStream to parse
100     * @param ids a Collection of Identities for validation
101     * @return an Array of Credentials parsed
102     * @throws CertInvalidException if the stream is unparsable
103     * @throws MissingIssuerException if none of the Identities can validate the
104     * @throws BadSignatureException if the signature check fails
105     */
106    public Credential[] parseCredential(InputStream is, 
107            Collection<Identity> ids) throws ABACException {
108        Credential[] rv = null;
109        ABACException err = null;
110
111        if (!is.markSupported() && spec.size() > 1) 
112            is = new BufferedInputStream(is, maxSize);
113        if (spec.size() > 1)
114            is.mark(maxSize);
115
116        for (CredentialFactorySpecialization c : spec ) {
117            try {
118                rv = c.parseCredential(is, ids);
119                break;
120            }
121            catch (ABACException e ) {
122                err = e;
123                rv = null;
124            }
125            try {
126                if (spec.size() > 1) is.reset(); 
127            }
128            catch (IOException ie) { 
129                break;
130            }
131        }
132
133        if ( rv != null ) 
134            return rv;
135        else 
136            throw (err != null) ? err :
137                new ABACException("null exception and failed construction??");
138    }
139
140
141    /**
142     * Parse a File using each possible credential format and the
143     * available identities for validation.  Return the credentials found or
144     * throw an ABACException with the problem.  Calls the InputStream version
145     * internally.
146     * @param f a File to parse
147     * @param ids a Collection of Identities for validation
148     * @return an Array of Credentials parsed
149     * @throws CertInvalidException if the stream is unparsable
150     * @throws MissingIssuerException if none of the Identities can validate the
151     * @throws BadSignatureException if the signature check fails
152     */
153    public Credential[] parseCredential(File f, 
154            Collection<Identity> ids) throws ABACException {
155        try {
156            return parseCredential(new FileInputStream(f), ids);
157        }
158        catch (FileNotFoundException e) {
159            throw new CertInvalidException(e.getMessage(), e);
160        }
161    }
162    /**
163     * Parse a file named fn using each possible credential format and the
164     * available identities for validation.  Return the credentials found or
165     * throw an ABACException with the problem.  Calls the InputStream version
166     * internally.
167     * @param fn a String holding the filename to parse
168     * @param ids a Collection of Identities for validation
169     * @return an Array of Credentials parsed
170     * @throws CertInvalidException if the stream is unparsable
171     * @throws MissingIssuerException if none of the Identities can validate the
172     * @throws BadSignatureException if the signature check fails
173     */
174    public Credential[] parseCredential(String fn, 
175            Collection<Identity> ids) throws ABACException {
176        return parseCredential(new File(fn), ids);
177    }
178
179    /**
180     * Return a credential of the from the first
181     * CredentialFactorySpecialization in the factory.
182     * @param head a Role, the head of the encoded ABAC statement
183     * @param tail a Role, the tail of the decoded ABAC statement
184     * @return a Credential encoding that ABAC statement
185     */
186    public Credential generateCredential(Role head, Role tail) {
187        if (spec.isEmpty()) return null;
188        return spec.get(0).generateCredential(head, tail);
189    }
190
191    /**
192     * Add the named class to the list of usable specializations.  The class
193     * passed in must have a static getCredentialFactorySpecialization() method
194     * that returns a CredentialFactorySpecialization to use.
195     * @param name a String containing the binary name of the class to register
196     * @throws ABACException if there is a problem.  The cause field of this
197     * exception is set to the classloading exception, if any.
198     */
199    public void registerClass(String name)
200        throws ABACException {
201        CredentialFactorySpecialization cs = null;
202
203        try {
204            /* <?> doesn't guarantee much, but shuts the compiler up */
205            Class<?> c =  Class.forName(name);
206            Method m = c.getMethod("getCredentialFactorySpecialization");
207
208            cs = (CredentialFactorySpecialization) m.invoke(null);
209        }
210        catch (Exception e) {
211            throw new ABACException("Could not register credential type" + 
212                    e.getMessage(), e);
213        }
214
215        spec.add(cs);
216    }
217}
Note: See TracBrowser for help on using the repository browser.