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.midp.appmanager;
028:
029: import java.util.Vector;
030:
031: import javax.microedition.lcdui.*;
032:
033: import javax.microedition.midlet.*;
034:
035: import com.sun.midp.i18n.Resource;
036: import com.sun.midp.i18n.ResourceConstants;
037:
038: import com.sun.midp.midlet.MIDletSuite;
039:
040: import com.sun.midp.midletsuite.InstallInfo;
041: import com.sun.midp.midletsuite.MIDletSuiteImpl;
042: import com.sun.midp.midletsuite.MIDletSuiteStorage;
043:
044: import com.sun.midp.publickeystore.PublicKeyInfo;
045: import com.sun.midp.publickeystore.WebPublicKeyStore;
046:
047: import com.sun.midp.security.Permissions;
048:
049: /**
050: * This class enabled the user to manage the state of Third Party certificate
051: * authorities.
052: */
053: public class CaManager extends MIDlet {
054: /** Construct a CA manager MIDlet. */
055: public CaManager() {
056: Display display = Display.getDisplay(this );
057:
058: display.setCurrent(new CaForm(this , display));
059: }
060:
061: /** Start; there are not resource to re-allocate. */
062: public void startApp() {
063: }
064:
065: /** Pause; there are no resources that need to be released. */
066: public void pauseApp() {
067: }
068:
069: /**
070: * Destroy cleans up.
071: *
072: * @param unconditional is ignored; this object always
073: * destroys itself when requested.
074: */
075: public void destroyApp(boolean unconditional) {
076: }
077:
078: /** Exits this application. */
079: void exit() {
080: notifyDestroyed();
081: }
082: }
083:
084: /**
085: * A list of certificate authorities, each with a check box next to it.
086: * Check means enable, no check mean disabled.
087: */
088: class CaForm extends Form implements CommandListener {
089:
090: /** MIDlet suite storage object. */
091: private MIDletSuiteStorage suiteStorage;
092:
093: /** List of suites to disable. */
094: private Vector disableSuites;
095:
096: /** List of suites to enable. */
097: private Vector enableSuites;
098:
099: /** Command object for "Save" command for the form. */
100: private Command confirmCmd = new Command(Resource
101: .getString(ResourceConstants.SAVE), Command.OK, 1);
102:
103: /** Command object for "Exit" command for splash screen. */
104: private Command exitCmd = new Command(Resource
105: .getString(ResourceConstants.EXIT), Command.BACK, 1);
106:
107: /** Command object for "Save" command for the confirmation form. */
108: private Command saveCmd = new Command(Resource
109: .getString(ResourceConstants.SAVE), Command.OK, 1);
110:
111: /** Command object for "Exit" command for splash screen. */
112: private Command cancelCmd = new Command(Resource
113: .getString(ResourceConstants.CANCEL), Command.BACK, 1);
114:
115: /** List of CAs. */
116: private Vector caList;
117:
118: /** Parent CA manager. */
119: private CaManager parent;
120:
121: /** Parent display. */
122: private Display display;
123:
124: /** CA choices. */
125: private ChoiceGroup choices;
126:
127: /** The index of the first item in the choice group. */
128: private int firstIndex;
129:
130: /**
131: * Construct a certificate form from a list of CA's.
132: *
133: * @param theParent Parent CaManager object
134: * @param theDisplay parent Display object
135: */
136: CaForm(CaManager theParent, Display theDisplay) {
137: super ("Certificate Authorities");
138:
139: String manufacturerCa = null;
140: String operatorCa = null;
141: StringBuffer label = new StringBuffer(80);
142: Item item = null;
143:
144: parent = theParent;
145: display = theDisplay;
146:
147: suiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
148:
149: WebPublicKeyStore keystore = WebPublicKeyStore
150: .getTrustedKeyStore();
151: caList = new Vector();
152:
153: for (int i = 0; i < keystore.numberOfKeys(); i++) {
154: PublicKeyInfo key = keystore.getKey(i);
155: if (Permissions.MANUFACTURER_DOMAIN_BINDING.equals(key
156: .getDomain())) {
157: manufacturerCa = key.getOwner();
158: continue;
159: }
160:
161: if (Permissions.OPERATOR_DOMAIN_BINDING.equals(key
162: .getDomain())) {
163: operatorCa = key.getOwner();
164: continue;
165: }
166:
167: caList.addElement(new Ca(key.getOwner(), key.isEnabled()));
168: }
169:
170: if (manufacturerCa != null) {
171: label.setLength(0);
172: label.append(Resource
173: .getString(ResourceConstants.MANUFACTURER));
174: label.append(": ");
175:
176: item = new StringItem(label.toString(), manufacturerCa);
177: item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
178: append(item);
179: }
180:
181: if (operatorCa != null) {
182: label.setLength(0);
183: label.append(Resource
184: .getString(ResourceConstants.SERVICE_PROVIDER));
185: label.append(": ");
186:
187: item = new StringItem(label.toString(), operatorCa);
188: item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
189: append(item);
190: }
191:
192: if (caList.size() > 0) {
193: label.setLength(0);
194: label.append(Resource
195: .getString(ResourceConstants.THIRD_PARTIES));
196: label.append(": ");
197:
198: choices = new ChoiceGroup(label.toString(),
199: ChoiceGroup.MULTIPLE);
200: item = choices;
201:
202: firstIndex = addCa((Ca) caList.elementAt(0));
203: for (int i = 1; i < caList.size(); i++) {
204: addCa((Ca) caList.elementAt(i));
205: }
206:
207: append(item);
208: }
209:
210: if (item == null) {
211: append(new StringItem(null, Resource
212: .getString(ResourceConstants.AMS_NO_CA_FOUND)));
213: } else {
214: addCommand(confirmCmd);
215: }
216:
217: addCommand(exitCmd);
218: setCommandListener(this );
219: }
220:
221: /**
222: * Respond to a command issued on any Screen.
223: *
224: * @param c command activated by the user
225: * @param s the Displayable the command was on.
226: */
227: public void commandAction(Command c, Displayable s) {
228: if (c == confirmCmd) {
229: confirmChanges();
230: return;
231: }
232:
233: if (c == exitCmd) {
234: parent.exit();
235: return;
236: }
237:
238: if (c == saveCmd) {
239: save();
240: return;
241: }
242:
243: if (c == cancelCmd) {
244: display.setCurrent(this );
245: return;
246: }
247: }
248:
249: /** Add a CA to the form. */
250: private int addCa(Ca ca) {
251: int index = choices.append(ca.name, null);
252:
253: choices.setSelectedIndex(index, ca.enabled);
254:
255: return index;
256: }
257:
258: /** Confirm the changes with the user. */
259: private void confirmChanges() {
260: boolean saveNeeded = false;
261: enableSuites = new Vector();
262: disableSuites = new Vector();
263:
264: // Determine which CA's will be enabled.
265: for (int i = 0; i < caList.size(); i++) {
266: Ca ca = (Ca) caList.elementAt(i);
267: ca.willBeEnabled = choices.isSelected(firstIndex + i);
268: }
269:
270: for (int i = 0; i < caList.size(); i++) {
271: Ca ca = (Ca) caList.elementAt(i);
272: if (ca.willBeEnabled && !ca.enabled) {
273: saveNeeded = true;
274: addSuitesAuthorizedBy(ca, enableSuites);
275: } else if (!ca.willBeEnabled && ca.enabled) {
276: saveNeeded = true;
277: addSuitesAuthorizedBy(ca, disableSuites);
278: }
279: }
280:
281: if (!saveNeeded) {
282: parent.exit();
283: return;
284: }
285:
286: if (disableSuites.size() == 0) {
287: // we only confirm the disabling of suites
288: save();
289: return;
290: }
291:
292: StringBuffer toBeDisabled = new StringBuffer();
293: toBeDisabled
294: .append(Resource
295: .getString(ResourceConstants.AMS_SUITES_TO_BE_DISABLED));
296: for (int i = 0; i < disableSuites.size(); i++) {
297: if (i > 0) {
298: toBeDisabled.append(",\n");
299: }
300:
301: toBeDisabled.append(((MIDletSuite) disableSuites
302: .elementAt(i))
303: .getProperty(MIDletSuiteImpl.SUITE_NAME_PROP));
304: }
305:
306: Alert a = new Alert(Resource
307: .getString(ResourceConstants.AMS_CONFIRMATION),
308: toBeDisabled.toString(), null, AlertType.WARNING);
309: a.setTimeout(Alert.FOREVER);
310: a.addCommand(cancelCmd);
311: a.addCommand(saveCmd);
312: a.setCommandListener(this );
313: display.setCurrent(a);
314: }
315:
316: /** Save the enable status of Third Party certificate authorities. */
317: private void save() {
318: for (int i = 0; i < caList.size(); i++) {
319: Ca ca = (Ca) caList.elementAt(i);
320: if (ca.willBeEnabled && !ca.enabled) {
321: WebPublicKeyStore.enableCertAuthority(ca.name);
322: } else if (!ca.willBeEnabled && ca.enabled) {
323: WebPublicKeyStore.disableCertAuthority(ca.name);
324: }
325: }
326:
327: disableSuites(disableSuites);
328: enableSuites(enableSuites);
329:
330: display.setCurrent(null);
331: parent.exit();
332: }
333:
334: /**
335: * Get a list of suites authorized by a CA.
336: *
337: * @param ca desired CA
338: *
339: * @return list of suites
340: */
341: private void addSuitesAuthorizedBy(Ca ca, Vector suites) {
342: int[] suiteIds = null;
343: MIDletSuite midletSuite = null;
344: InstallInfo installInfo = null;
345:
346: suiteIds = suiteStorage.getListOfSuites();
347:
348: for (int i = 0; i < suiteIds.length; i++) {
349: try {
350: midletSuite = suiteStorage.getMIDletSuite(suiteIds[i],
351: false);
352: } catch (Throwable t) {
353: continue;
354: }
355:
356: installInfo = ((MIDletSuiteImpl) midletSuite)
357: .getInstallInfo();
358:
359: String[] authPath = installInfo.getAuthPath();
360:
361: if (authPath != null && ca.name.equals(authPath[0])) {
362: suites.addElement(midletSuite);
363: continue;
364: }
365:
366: midletSuite.close();
367: }
368: }
369:
370: /**
371: * Disable a list suites. Closes each suite.
372: *
373: * @param suites list of MIDlet suites
374: */
375: private void disableSuites(Vector suites) {
376: MIDletSuite midletSuite = null;
377:
378: for (int i = 0; i < suites.size(); i++) {
379: midletSuite = (MIDletSuite) suites.elementAt(i);
380: try {
381: suiteStorage.disable(midletSuite.getID());
382: } catch (Throwable t) {
383: // nothing can be done
384: }
385:
386: midletSuite.close();
387: }
388: }
389:
390: /**
391: * Enable a list suites. Closes each suite.
392: *
393: * @param suites list of MIDlet suites
394: */
395: private void enableSuites(Vector suites) {
396: MIDletSuite midletSuite = null;
397:
398: for (int i = 0; i < suites.size(); i++) {
399: midletSuite = (MIDletSuite) suites.elementAt(i);
400: try {
401: suiteStorage.enable(midletSuite.getID());
402: } catch (Throwable t) {
403: // nothing can be done
404: }
405:
406: midletSuite.close();
407: }
408: }
409: }
410:
411: /**
412: * Represents a CA.
413: */
414: class Ca {
415: /** Name of the CA. */
416: String name;
417:
418: /** If true the CA is enabled. */
419: boolean enabled;
420:
421: /** If true the CA will be enabled after the user presses "save". */
422: boolean willBeEnabled;
423:
424: /**
425: * Construct a CA.
426: *
427: * @param theName name of the CA
428: * @param isEnabled true if the CA is enabled
429: */
430: Ca(String theName, boolean isEnabled) {
431: name = theName;
432: enabled = isEnabled;
433: }
434: }
|