001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.auth.internal.kerberos.v5;
019:
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.IOException;
023: import java.io.InputStreamReader;
024: import java.io.StreamTokenizer;
025: import java.util.Hashtable;
026:
027: /**
028: * Kerberos configuration.
029: *
030: * Parses Kerberos configuration file according to the following syntax:<br>
031: * CONFIG = (SECTION)*<br>
032: * SECTION = '[' name ']' (EXPR)*<br>
033: * EXPR = S | C<br>
034: * S = tag '=' value<br>
035: * C = tag '=' '{' (EXPR)* '}'<br>
036: *
037: * @see http://web.mit.edu/kerberos/www/krb5-1.5/krb5-1.5.1/doc/krb5-admin/krb5.conf.html#krb5.conf
038: */
039: public class KrbConfig {
040:
041: private static final int TT_START_SECTION = '[';
042:
043: private static final int TT_END_SECTION = ']';
044:
045: private static final int TT_EQAUL = '=';
046:
047: private Hashtable<String, Hashtable<String, String>> values = new Hashtable<String, Hashtable<String, String>>();
048:
049: /**
050: * Creates configuration.
051: *
052: * @param f -
053: * configuration file
054: * @throws IOException -
055: * in case of I/O errors
056: */
057: public KrbConfig(File f) throws IOException {
058: StreamTokenizer t = new StreamTokenizer(new InputStreamReader(
059: new FileInputStream(f)));
060:
061: t.commentChar('#');
062:
063: t.ordinaryChar(TT_START_SECTION);
064: t.ordinaryChar(TT_END_SECTION);
065: t.ordinaryChar(TT_EQAUL);
066:
067: t.wordChars('_', '_');
068: t.wordChars(':', ':');
069: t.wordChars('/', '/');
070:
071: t.nextToken(); // init stream tokenizer
072:
073: String currentSection = nextSection(t);
074: while (currentSection != null) {
075:
076: // allow duplicate section
077: Hashtable<String, String> sectionValues = values
078: .get(currentSection);
079: if (sectionValues == null) {
080: sectionValues = new Hashtable<String, String>();
081: values.put(currentSection, sectionValues);
082: }
083:
084: // parse section content
085: parseSection(t, sectionValues);
086:
087: currentSection = nextSection(t);
088: }
089: }
090:
091: private String nextSection(StreamTokenizer t) throws IOException {
092: while (true) {
093: if (t.ttype == StreamTokenizer.TT_EOF) {
094: return null;
095: }
096: if (t.ttype != TT_START_SECTION) {
097: t.nextToken();
098: continue;
099: }
100:
101: t.nextToken();
102: if (t.ttype != StreamTokenizer.TT_WORD) {
103: t.nextToken();
104: continue;
105: }
106: String section = t.sval;
107:
108: t.nextToken();
109: if (t.ttype != TT_END_SECTION) {
110: t.nextToken();
111: continue;
112: }
113: t.nextToken();
114: return section;
115: }
116: }
117:
118: // TODO: implement parsing values in curly braces and decide
119: // how to represent them
120: private void parseSection(StreamTokenizer t,
121: Hashtable<String, String> sectionValues) throws IOException {
122:
123: while (true) {
124: // end of file or new section
125: if (t.ttype == StreamTokenizer.TT_EOF
126: || t.ttype == TT_START_SECTION) {
127: return;
128: }
129:
130: // tag
131: if (t.ttype != StreamTokenizer.TT_WORD) {
132: t.nextToken();
133: continue;
134: }
135: String tag = t.sval;
136: t.nextToken();
137:
138: // equals char
139: if (t.ttype != TT_EQAUL) {
140: t.nextToken();
141: continue;
142: }
143: t.nextToken();
144:
145: // value
146: if (t.ttype != StreamTokenizer.TT_WORD) {
147: t.nextToken();
148: continue;
149: }
150: String value = t.sval;
151: t.nextToken();
152:
153: sectionValues.put(tag, value);
154: }
155: }
156:
157: public String getValue(String section, String tag) {
158: Hashtable<String, String> h = values.get(section);
159: if (h != null) {
160: return h.get(tag);
161: }
162: return null;
163: }
164:
165: /**
166: * Search Kerberos configuration
167: *
168: * @return - configuration file or null if there is no one
169: * @throws IOException -
170: * in case of I/O errors
171: */
172: public static KrbConfig getSystemConfig() throws IOException {
173:
174: String fName = System.getProperty("java.security.krb5.conf"); //$NON-NLS-1$
175: if (fName == null) {
176:
177: fName = System.getProperty("java.home") + "/lib/security/krb5.conf"; //$NON-NLS-1$ //$NON-NLS-2$
178: File f = new File(fName);
179: if (f.exists()) {
180: return new KrbConfig(f);
181: }
182:
183: String OSName = System.getProperty("os.name"); //$NON-NLS-1$
184: if (OSName.indexOf("Windows") != -1) { //$NON-NLS-1$
185: fName = "c:\\winnt\\krb5.ini"; //$NON-NLS-1$
186: } else if (OSName.indexOf("Linux") != -1) { //$NON-NLS-1$
187: fName = "/etc/krb5.conf"; //$NON-NLS-1$
188: } else {
189: throw new UnsupportedOperationException(OSName);
190: }
191: }
192:
193: File f = new File(fName);
194: if (f.exists() && f.isFile()) {
195: return new KrbConfig(f);
196: }
197: return null;
198: }
199: }
|