1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.catalina.realm;
20
21
22 import java.io.IOException;
23 import javax.security.auth.callback.Callback;
24 import javax.security.auth.callback.CallbackHandler;
25 import javax.security.auth.callback.NameCallback;
26 import javax.security.auth.callback.PasswordCallback;
27 import javax.security.auth.callback.UnsupportedCallbackException;
28
29 import org.apache.catalina.util.StringManager;
30
31 /**
32 * <p>Implementation of the JAAS <code>CallbackHandler</code> interface,
33 * used to negotiate delivery of the username and credentials that were
34 * specified to our constructor. No interaction with the user is required
35 * (or possible).</p>
36 *
37 * <p>This <code>CallbackHandler</code> will pre-digest the supplied
38 * password, if required by the <code><Realm></code> element in
39 * <code>server.xml</code>.</p>
40 * <p>At present, <code>JAASCallbackHandler</code> knows how to handle callbacks of
41 * type <code>javax.security.auth.callback.NameCallback</code> and
42 * <code>javax.security.auth.callback.PasswordCallback</code>.</p>
43 *
44 * @author Craig R. McClanahan
45 * @author Andrew R. Jaquith
46 * @version $Revision: 543691 $ $Date: 2007-06-02 03:37:08 +0200 (sam., 02 juin 2007) $
47 */
48
49 public class JAASCallbackHandler implements CallbackHandler {
50
51 // ------------------------------------------------------------ Constructor
52
53
54 /**
55 * Construct a callback handler configured with the specified values.
56 * Note that if the <code>JAASRealm</code> instance specifies digested passwords,
57 * the <code>password</code> parameter will be pre-digested here.
58 *
59 * @param realm Our associated JAASRealm instance
60 * @param username Username to be authenticated with
61 * @param password Password to be authenticated with
62 */
63 public JAASCallbackHandler(JAASRealm realm, String username,
64 String password) {
65
66 super();
67 this.realm = realm;
68 this.username = username;
69
70 if (realm.hasMessageDigest()) {
71 this.password = realm.digest(password);
72 }
73 else {
74 this.password = password;
75 }
76 }
77
78
79 // ----------------------------------------------------- Instance Variables
80
81 /**
82 * The string manager for this package.
83 */
84 protected static final StringManager sm =
85 StringManager.getManager(Constants.Package);
86
87 /**
88 * The password to be authenticated with.
89 */
90 protected String password = null;
91
92
93 /**
94 * The associated <code>JAASRealm</code> instance.
95 */
96 protected JAASRealm realm = null;
97
98
99 /**
100 * The username to be authenticated with.
101 */
102 protected String username = null;
103
104
105 // --------------------------------------------------------- Public Methods
106
107
108 /**
109 * Retrieve the information requested in the provided <code>Callbacks</code>.
110 * This implementation only recognizes <code>NameCallback</code> and
111 * <code>PasswordCallback</code> instances.
112 *
113 * @param callbacks The set of <code>Callback</code>s to be processed
114 *
115 * @exception IOException if an input/output error occurs
116 * @exception UnsupportedCallbackException if the login method requests
117 * an unsupported callback type
118 */
119 public void handle(Callback callbacks[])
120 throws IOException, UnsupportedCallbackException {
121
122 for (int i = 0; i < callbacks.length; i++) {
123
124 if (callbacks[i] instanceof NameCallback) {
125 if (realm.getContainer().getLogger().isTraceEnabled())
126 realm.getContainer().getLogger().trace(sm.getString("jaasCallback.username", username));
127 ((NameCallback) callbacks[i]).setName(username);
128 } else if (callbacks[i] instanceof PasswordCallback) {
129 final char[] passwordcontents;
130 if (password != null) {
131 passwordcontents = password.toCharArray();
132 } else {
133 passwordcontents = new char[0];
134 }
135 ((PasswordCallback) callbacks[i]).setPassword
136 (passwordcontents);
137 } else {
138 throw new UnsupportedCallbackException(callbacks[i]);
139 }
140 }
141 }
142 }