001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.satsa.acl;
028:
029: import java.util.Vector;
030: import java.io.IOException;
031: import java.io.InputStream;
032: import java.io.InputStreamReader;
033: import com.sun.midp.io.j2me.storage.RandomAccessStream;
034: import com.sun.midp.io.j2me.storage.File;
035: import com.sun.midp.security.ImplicitlyTrustedClass;
036: import com.sun.midp.security.SecurityToken;
037: import com.sun.satsa.security.SecurityInitializer;
038: import com.sun.midp.configurator.Constants;
039:
040: import javax.microedition.io.Connector;
041:
042: /**
043: * This class represents access control file that describes permissions for one
044: * card slot.
045: */
046: public class ACSlot {
047:
048: /**
049: * Inner class to request security token from SecurityInitializer.
050: * SecurityInitializer should be able to check this inner class name.
051: */
052: static private class SecurityTrusted implements
053: ImplicitlyTrustedClass {
054: };
055:
056: /** This class has a different security domain than the MIDlet suite */
057: private static SecurityToken classSecurityToken = SecurityInitializer
058: .requestToken(new SecurityTrusted());
059:
060: /**
061: * Constructs an instance of an access control file object.
062: */
063: public ACSlot() {
064: }
065:
066: /**
067: * Load access control information.
068: * @param slotNum card slot number.
069: * @return object that contains access control information or null if
070: * this information doesn't exist or contains errors.
071: */
072: public static ACSlot load(int slotNum) {
073:
074: RandomAccessStream storage;
075: InputStream permIS;
076:
077: try {
078: storage = new RandomAccessStream(classSecurityToken);
079: storage.connect(File
080: .getStorageRoot(Constants.INTERNAL_STORAGE_ID)
081: + "acl_" + slotNum, Connector.READ);
082: permIS = storage.openInputStream();
083: } catch (IOException e) {
084: return null;
085: }
086:
087: try {
088: ACSlot f = new ACSlot();
089: f.init(new ACLFileReader(new InputStreamReader(permIS)));
090: return f;
091: } catch (Exception e) {
092: System.out.println("Error reading ACList " + e);
093: } finally {
094: try {
095: storage.disconnect();
096: } catch (Exception e) {
097: // nothing we can do.
098: }
099: }
100: return null;
101: }
102:
103: /**
104: * The list of ACL objects.
105: */
106: private Vector ACLists = new Vector();
107: /**
108: * The list of PIN data objects.
109: */
110: private Vector PINAttrs = new Vector();
111:
112: /**
113: * Initializes ACF object.
114: * @param r reader for permissions file.
115: * @throws IOException if I/O error occurs.
116: */
117: private void init(ACLFileReader r) throws IOException {
118:
119: while (true) {
120:
121: ACList acl;
122: try {
123:
124: String s = r.readWord();
125:
126: if (s == null) {
127: break;
128: }
129:
130: if (s.equals("acf")) {
131: ACLists.addElement(new ACList(r));
132: } else if (s.equals("pin_data")) {
133: PINAttrs.addElement(new PINAttributes(r));
134: } else {
135: throw new Exception();
136: }
137:
138: } catch (Exception e) {
139: throw new IOException("Line " + r.lineNumber);
140: }
141: }
142: }
143:
144: /**
145: * Return PIN attributes.
146: * @param id PIN identifier.
147: * @return PIN attributes.
148: */
149: PINAttributes getPINAttributes(int id) {
150:
151: for (int j = 0; j < PINAttrs.size(); j++) {
152:
153: PINAttributes p = (PINAttributes) PINAttrs.elementAt(j);
154: if (p.id == id) {
155: return p;
156: }
157: }
158: return null;
159: }
160:
161: /**
162: * Returns object that should be used for access control verification.
163: * @param isAPDU true for APDU connection, false for JCRMI.
164: * @param selectAPDU SELECT APDU command data.
165: * @param root name of CA that authorized the suite.
166: * @return object that can be used to check permissions.
167: */
168: ACLPermissions getACLPermissions(boolean isAPDU, byte[] selectAPDU,
169: String root) {
170:
171: Vector permissions = new Vector();
172: Vector pins = new Vector();
173: boolean found = false;
174: boolean allow = false;
175:
176: for (int i = 0; i < ACLists.size(); i++) {
177:
178: ACList acd = (ACList) ACLists.elementAt(i);
179:
180: if (!acd.match(selectAPDU)) {
181: continue;
182: }
183:
184: found = true;
185:
186: acd.getPINs(isAPDU, pins);
187:
188: Vector acl = acd.getACEntries();
189:
190: for (int j = 0; j < acl.size(); j++) {
191:
192: ACEntry ace = (ACEntry) acl.elementAt(j);
193:
194: if (!ace.verifyPrincipal(root)) {
195: continue;
196: }
197:
198: if (!ace.hasPermissions()) {
199: allow = true;
200: continue;
201: }
202:
203: ace.getPermissions(isAPDU, permissions);
204: }
205: }
206:
207: ACLPermissions perm;
208:
209: if (isAPDU) {
210: perm = new APDUPermissions(this );
211: } else {
212: perm = new JCRMIPermissions(this );
213: }
214:
215: if (pins.size() != 0) {
216: PINData[] data = new PINData[pins.size()];
217: pins.copyInto(data);
218: perm.setPINData(data);
219: }
220:
221: if (!found || allow) {
222: perm.setType(ACLPermissions.ALLOW);
223: } else if (permissions.size() == 0) {
224: throw new SecurityException("Access denied.");
225: } else {
226: perm.setPermissions(permissions);
227: perm.setType(ACLPermissions.CHECK);
228: }
229: return perm;
230: }
231: }
|