View Javadoc

1   /**
2    *
3    * Copyright 2003-2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  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  package org.apache.geronimo.security.jaas.server;
18  
19  import javax.security.auth.callback.Callback;
20  import javax.security.auth.callback.CallbackHandler;
21  import javax.security.auth.callback.UnsupportedCallbackException;
22  
23  /**
24   * This callback handler separates the process of obtaining callbacks from
25   * the user from the process of providing the user's values to the login
26   * module.  This means the JaasLoginService can figure out what callbacks
27   * the module wants and prompt the user in advance, and then turn around
28   * and pass those values to the login module, instead of actually prompting
29   * the user at the mercy of the login module.
30   *
31   * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
32   */
33  public class DecouplingCallbackHandler implements CallbackHandler {
34      private Callback[] source;
35      private boolean exploring = true;
36  
37      public DecouplingCallbackHandler() {
38      }
39  
40      public void handle(Callback[] callbacks) throws IllegalArgumentException, UnsupportedCallbackException {
41          if (exploring) {
42              source = callbacks;
43              throw new UnsupportedCallbackException(callbacks != null && callbacks.length > 0 ? callbacks[0] : null, "DO NOT PROCEED WITH THIS LOGIN");
44          } else {
45              if(callbacks.length != source.length) {
46                  throw new IllegalArgumentException("Mismatched callbacks");
47              }
48              for (int i = 0; i < callbacks.length; i++) {
49                  callbacks[i] = source[i];
50              }
51          }
52      }
53  
54      /**
55       * Within the same VM, the client just populates the callbacks directly
56       * into the array held by this object.  However, remote clients will
57       * serialize their responses, so they need to be manually set back on this
58       * object to take effect.
59       *
60       * @param callbacks The callbacks populated by the client
61       */
62      public void setClientResponse(Callback[] callbacks) throws IllegalArgumentException {
63          if(source == null && callbacks == null) {
64              return; // i.e. The Kerberos LM doesn't need callbacks
65          }
66          if(callbacks.length != source.length) {
67              throw new IllegalArgumentException("Mismatched callbacks");
68          }
69          for (int i = 0; i < callbacks.length; i++) {
70              source[i] = callbacks[i];
71          }
72      }
73  
74  
75      /**
76       * While we're exploring, we'll discover new callbacks that the server
77       * login module wants.  While not exploring, we'll actually set
78       * values for the server callbacks.
79       */
80      public void setExploring() {
81          exploring = true;
82          source = null;
83      }
84  
85      /**
86       * Indicates that the exploring phase is over.
87       */
88      public Callback[] finalizeCallbackList() {
89          exploring = false;
90          return source;
91      }
92  }