001: /*
002: * Copyright 1999-2003 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: package com.sun.jndi.ldap.sasl;
027:
028: import javax.security.auth.callback.*;
029: import javax.security.sasl.RealmCallback;
030: import javax.security.sasl.RealmChoiceCallback;
031: import java.io.IOException;
032:
033: /**
034: * DefaultCallbackHandler for satisfying NameCallback and
035: * PasswordCallback for an LDAP client.
036: * NameCallback is used for getting the authentication ID and is
037: * gotten from the java.naming.security.principal property.
038: * PasswordCallback is gotten from the java.naming.security.credentials
039: * property and must be of type String, char[] or byte[].
040: * If byte[], it is assumed to have UTF-8 encoding.
041: *
042: * If the caller of getPassword() will be using the password as
043: * a byte array, then it should encode the char[] array returned by
044: * getPassword() into a byte[] using UTF-8.
045: *
046: * @author Rosanna Lee
047: */
048: final class DefaultCallbackHandler implements CallbackHandler {
049: private char[] passwd;
050: private String authenticationID;
051: private String authRealm;
052:
053: DefaultCallbackHandler(String principal, Object cred, String realm)
054: throws IOException {
055: authenticationID = principal;
056: authRealm = realm;
057: if (cred instanceof String) {
058: passwd = ((String) cred).toCharArray();
059: } else if (cred instanceof char[]) {
060: passwd = (char[]) ((char[]) cred).clone();
061: } else if (cred != null) {
062: // assume UTF-8 encoding
063: String orig = new String((byte[]) cred, "UTF8");
064: passwd = orig.toCharArray();
065: }
066: }
067:
068: public void handle(Callback[] callbacks) throws IOException,
069: UnsupportedCallbackException {
070: for (int i = 0; i < callbacks.length; i++) {
071: if (callbacks[i] instanceof NameCallback) {
072: ((NameCallback) callbacks[i]).setName(authenticationID);
073:
074: } else if (callbacks[i] instanceof PasswordCallback) {
075: ((PasswordCallback) callbacks[i]).setPassword(passwd);
076:
077: } else if (callbacks[i] instanceof RealmChoiceCallback) {
078: /* Deals with a choice of realms */
079: String[] choices = ((RealmChoiceCallback) callbacks[i])
080: .getChoices();
081: int selected = 0;
082:
083: if (authRealm != null && authRealm.length() > 0) {
084: selected = -1; // no realm chosen
085: for (int j = 0; j < choices.length; j++) {
086: if (choices[j].equals(authRealm)) {
087: selected = j;
088: }
089: }
090: if (selected == -1) {
091: StringBuffer allChoices = new StringBuffer();
092: for (int j = 0; j < choices.length; j++) {
093: allChoices.append(choices[j] + ",");
094: }
095: throw new IOException(
096: "Cannot match "
097: + "'java.naming.security.sasl.realm' property value, '"
098: + authRealm + "' with choices "
099: + allChoices
100: + "in RealmChoiceCallback");
101: }
102: }
103:
104: ((RealmChoiceCallback) callbacks[i])
105: .setSelectedIndex(selected);
106:
107: } else if (callbacks[i] instanceof RealmCallback) {
108: /* 1 or 0 realms specified in challenge */
109: RealmCallback rcb = (RealmCallback) callbacks[i];
110: if (authRealm != null) {
111: rcb.setText(authRealm); // Use what user supplied
112: } else {
113: String defaultRealm = rcb.getDefaultText();
114: if (defaultRealm != null) {
115: rcb.setText(defaultRealm); // Use what server supplied
116: } else {
117: rcb.setText(""); // Specify no realm
118: }
119: }
120: } else {
121: throw new UnsupportedCallbackException(callbacks[i]);
122: }
123: }
124: }
125:
126: void clearPassword() {
127: if (passwd != null) {
128: for (int i = 0; i < passwd.length; i++) {
129: passwd[i] = '\0';
130: }
131: passwd = null;
132: }
133: }
134:
135: protected void finalize() throws Throwable {
136: clearPassword();
137: }
138: }
|