source: java/net/deterlab/abac/CredentialFactory.java @ 2405adf

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

Add GENIProv parsing works

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