001: /*
002: * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * (C) Copyright IBM Corp. 1999 All Rights Reserved.
028: * Copyright 1997 The Open Group Research Institute. All rights reserved.
029: */
030:
031: package sun.security.krb5.internal.tools;
032:
033: import sun.security.krb5.*;
034: import sun.security.krb5.internal.*;
035: import sun.security.krb5.internal.ccache.*;
036: import java.io.File;
037: import java.io.IOException;
038: import java.util.StringTokenizer;
039: import java.util.Vector;
040: import java.io.BufferedReader;
041: import java.io.InputStreamReader;
042: import java.io.FileInputStream;
043:
044: /**
045: * Maintains user-specific options or default settings when the user requests
046: * a KDC ticket using Kinit.
047: *
048: * @author Yanni Zhang
049: * @author Ram Marti
050: * @version 1.00 12 Apr 2000
051: */
052: class KinitOptions {
053: public boolean validate = false;
054:
055: // forwardable and proxiable flags have two states:
056: // -1 - flag set to be not forwardable or proxiable;
057: // 1 - flag set to be forwardable or proxiable.
058: public short forwardable = -1;
059: public short proxiable = -1;
060: public boolean renew = false;
061: public KerberosTime lifetime;
062: public KerberosTime renewable_lifetime;
063: public String target_service;
064: public String keytab_file;
065: public String cachename;
066: private PrincipalName principal;
067: public String realm;
068: char[] password = null;
069: public boolean keytab;
070: private boolean DEBUG = Krb5.DEBUG;
071: private boolean includeAddresses = true; // default.
072: private boolean useKeytab = false; // default = false.
073: private String ktabName; // keytab file name
074:
075: public KinitOptions() throws RuntimeException, RealmException {
076: // no args were specified in the command line;
077: // use default values
078: cachename = FileCredentialsCache.getDefaultCacheName();
079: if (cachename == null) {
080: throw new RuntimeException("default cache name error");
081: }
082: principal = getDefaultPrincipal();
083: }
084:
085: public void setKDCRealm(String r) throws RealmException {
086: realm = r;
087: }
088:
089: public String getKDCRealm() {
090: if (realm == null) {
091: if (principal != null) {
092: return principal.getRealmString();
093: }
094: }
095: return null;
096: }
097:
098: public KinitOptions(String[] args) throws KrbException,
099: RuntimeException, IOException {
100: // currently we provide support for -f -p -c principal options
101: String p = null; // store principal
102:
103: for (int i = 0; i < args.length; i++) {
104: if (args[i].equals("-f")) {
105: forwardable = 1;
106: } else if (args[i].equals("-p")) {
107: proxiable = 1;
108: } else if (args[i].equals("-c")) {
109:
110: if (args[i + 1].startsWith("-")) {
111: throw new IllegalArgumentException("input format "
112: + " not correct: " + " -c option "
113: + "must be followed " + "by the cache name");
114: }
115: cachename = args[++i];
116: if ((cachename.length() >= 5)
117: && cachename.substring(0, 5).equalsIgnoreCase(
118: "FILE:")) {
119: cachename = cachename.substring(5);
120: }
121: ;
122: } else if (args[i].equals("-A")) {
123: includeAddresses = false;
124: } else if (args[i].equals("-k")) {
125: useKeytab = true;
126: } else if (args[i].equals("-t")) {
127: if (ktabName != null) {
128: throw new IllegalArgumentException(
129: "-t option/keytab file name repeated");
130: } else if (i + 1 < args.length) {
131: ktabName = args[++i];
132: } else {
133: throw new IllegalArgumentException(
134: "-t option requires keytab file name");
135: }
136:
137: useKeytab = true;
138: } else if (args[i].equalsIgnoreCase("-help")) {
139: printHelp();
140: System.exit(0);
141: } else if (p == null) { // Haven't yet processed a "principal"
142: p = args[i];
143: try {
144: principal = new PrincipalName(p);
145: } catch (Exception e) {
146: throw new IllegalArgumentException("invalid "
147: + "Principal name: " + p + e.getMessage());
148: }
149: if (principal.getRealm() == null) {
150: String realm = Config.getInstance().getDefault(
151: "default_realm", "libdefaults");
152: if (realm != null) {
153: principal.setRealm(realm);
154: } else
155: throw new IllegalArgumentException("invalid "
156: + "Realm name");
157: }
158: } else if (this .password == null) {
159: // Have already processed a Principal, this must be a password
160: password = args[i].toCharArray();
161: } else {
162: throw new IllegalArgumentException(
163: "too many parameters");
164: }
165: }
166: // we should get cache name before getting the default principal name
167: if (cachename == null) {
168: cachename = FileCredentialsCache.getDefaultCacheName();
169: if (cachename == null) {
170: throw new RuntimeException("default cache name error");
171: }
172: }
173: if (principal == null) {
174: principal = getDefaultPrincipal();
175: }
176: }
177:
178: PrincipalName getDefaultPrincipal() {
179: String cname;
180: String realm = null;
181: try {
182: realm = Config.getInstance().getDefaultRealm();
183: } catch (KrbException e) {
184: System.out.println("Can not get default realm "
185: + e.getMessage());
186: e.printStackTrace();
187: return null;
188: }
189:
190: // get default principal name from the cachename if it is
191: // available.
192:
193: try {
194: CCacheInputStream cis = new CCacheInputStream(
195: new FileInputStream(cachename));
196: int version;
197: if ((version = cis.readVersion()) == FileCCacheConstants.KRB5_FCC_FVNO_4) {
198: cis.readTag();
199: } else {
200: if (version == FileCCacheConstants.KRB5_FCC_FVNO_1
201: || version == FileCCacheConstants.KRB5_FCC_FVNO_2) {
202: cis.setNativeByteOrder();
203: }
204: }
205: PrincipalName p = cis.readPrincipal(version);
206: cis.close();
207: String temp = p.getRealmString();
208: if (temp == null) {
209: p.setRealm(realm);
210: }
211: if (DEBUG) {
212: System.out
213: .println(">>>KinitOptions principal name from "
214: + "the cache is :" + p);
215: }
216: return p;
217: } catch (IOException e) {
218: // ignore any exceptions; we will use the user name as the
219: // principal name
220: if (DEBUG) {
221: e.printStackTrace();
222: }
223: } catch (RealmException e) {
224: if (DEBUG) {
225: e.printStackTrace();
226: }
227: }
228:
229: String username = System.getProperty("user.name");
230: if (DEBUG) {
231: System.out.println(">>>KinitOptions default username is :"
232: + username);
233: }
234: if (realm != null) {
235: try {
236: PrincipalName p = new PrincipalName(username);
237: if (p.getRealm() == null)
238: p.setRealm(realm);
239: return p;
240: } catch (RealmException e) {
241: // ignore exception , return null
242: if (DEBUG) {
243: System.out
244: .println("Exception in getting principal "
245: + "name " + e.getMessage());
246: e.printStackTrace();
247: }
248: }
249: }
250: return null;
251: }
252:
253: void printHelp() {
254: System.out.println("Usage: kinit "
255: + "[-A] [-f] [-p] [-c cachename] "
256: + "[[-k [-t keytab_file_name]] [principal] "
257: + "[password]");
258: System.out.println("\tavailable options to "
259: + "Kerberos 5 ticket request:");
260: System.out.println("\t -A do not include addresses");
261: System.out.println("\t -f forwardable");
262: System.out.println("\t -p proxiable");
263: System.out.println("\t -c cache name "
264: + "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
265: System.out.println("\t -k use keytab");
266: System.out.println("\t -t keytab file name");
267: System.out.println("\t principal the principal name "
268: + "(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
269: System.out.println("\t password "
270: + "the principal's Kerberos password");
271: }
272:
273: public boolean getAddressOption() {
274: return includeAddresses;
275: }
276:
277: public boolean useKeytabFile() {
278: return useKeytab;
279: }
280:
281: public String keytabFileName() {
282: return ktabName;
283: }
284:
285: public PrincipalName getPrincipal() {
286: return principal;
287: }
288: }
|