1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/*
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Licensed to the Apache Software Foundation (ASF) under one
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * or more contributor license agreements.  See the NOTICE file
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed with this work for additional information
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * regarding copyright ownership.  The ASF licenses this file
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to you under the Apache License, Version 2.0 (the
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * "License"); you may not use this file except in compliance
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * with the License.  You may obtain a copy of the License at
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *   http://www.apache.org/licenses/LICENSE-2.0
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing,
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * software distributed under the License is distributed on an
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * KIND, either express or implied.  See the License for the
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * specific language governing permissions and limitations
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * under the License.
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.apache.qpid.management.common.sasl;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.Callback;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.CallbackHandler;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.NameCallback;
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.PasswordCallback;
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.auth.callback.UnsupportedCallbackException;
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.IOException;
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.UnsupportedEncodingException;
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.security.MessageDigest;
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.security.NoSuchAlgorithmException;
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class UsernameHashedPasswordCallbackHandler implements CallbackHandler
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private String user;
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private char[] pwchars;
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    {
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.user = user;
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.pwchars = getHash(password);
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    {
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (int i = 0; i < callbacks.length; i++)
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        {
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (callbacks[i] instanceof NameCallback)
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            {
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                NameCallback ncb = (NameCallback) callbacks[i];
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                ncb.setName(user);
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            else if (callbacks[i] instanceof PasswordCallback)
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            {
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                PasswordCallback pcb = (PasswordCallback) callbacks[i];
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                pcb.setPassword(pwchars);
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            else
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            {
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw new UnsupportedCallbackException(callbacks[i]);
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void clearPassword()
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    {
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (pwchars != null)
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        {
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (int i = 0 ; i < pwchars.length ; i++)
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            {
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                pwchars[i] = 0;
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            pwchars = null;
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    protected void finalize()
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    {
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        clearPassword();
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    {
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        byte[] data = text.getBytes("utf-8");
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        MessageDigest md = MessageDigest.getInstance("MD5");
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (byte b : data)
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        {
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            md.update(b);
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        byte[] digest = md.digest();
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        char[] hash = new char[digest.length ];
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        int index = 0;
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        for (byte b : digest)
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        {
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            hash[index++] = (char) b;
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return hash;
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
108