source: java/net/deterlab/abac/CredentialFactory.java @ a7f73b5

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

Document cleanup. Change a few visibilities.

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