~ubuntu-branches/ubuntu/utopic/jetty/utopic-proposed

« back to all changes in this revision

Viewing changes to contrib/jetty-ldap-jaas/src/main/java/org/mortbay/jetty/plus/jaas/ldap/LdapLoginModule.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2009-08-09 08:48:10 UTC
  • Revision ID: james.westby@ubuntu.com-20090809084810-k522b97ind2robyd
ImportĀ upstreamĀ versionĀ 6.1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.mortbay.jetty.plus.jaas.ldap;
 
2
 
 
3
// ========================================================================
 
4
// Copyright 2007 Mort Bay Consulting Pty. Ltd.
 
5
// ------------------------------------------------------------------------
 
6
// Licensed under the Apache License, Version 2.0 (the "License");
 
7
// you may not use this file except in compliance with the License.
 
8
// You may obtain a copy of the License at
 
9
// http://www.apache.org/licenses/LICENSE-2.0
 
10
// Unless required by applicable law or agreed to in writing, software
 
11
// distributed under the License is distributed on an "AS IS" BASIS,
 
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
// See the License for the specific language governing permissions and
 
14
// limitations under the License.
 
15
// ========================================================================
 
16
 
 
17
import java.io.IOException;
 
18
import java.util.ArrayList;
 
19
import java.util.Hashtable;
 
20
import java.util.List;
 
21
import java.util.Map;
 
22
import java.util.Properties;
 
23
 
 
24
import javax.naming.Context;
 
25
import javax.naming.NamingEnumeration;
 
26
import javax.naming.NamingException;
 
27
import javax.naming.directory.Attribute;
 
28
import javax.naming.directory.Attributes;
 
29
import javax.naming.directory.DirContext;
 
30
import javax.naming.directory.InitialDirContext;
 
31
import javax.naming.directory.SearchControls;
 
32
import javax.naming.directory.SearchResult;
 
33
import javax.security.auth.Subject;
 
34
import javax.security.auth.callback.Callback;
 
35
import javax.security.auth.callback.CallbackHandler;
 
36
import javax.security.auth.callback.NameCallback;
 
37
import javax.security.auth.callback.UnsupportedCallbackException;
 
38
import javax.security.auth.login.LoginException;
 
39
 
 
40
import org.mortbay.jetty.plus.jaas.callback.ObjectCallback;
 
41
import org.mortbay.jetty.plus.jaas.spi.AbstractLoginModule;
 
42
import org.mortbay.jetty.plus.jaas.spi.UserInfo;
 
43
import org.mortbay.jetty.security.Credential;
 
44
import org.mortbay.log.Log;
 
45
 
 
46
/**
 
47
 *
 
48
 * A LdapLoginModule for use with JAAS setups
 
49
 *
 
50
 * The jvm should be started with the following parameter:
 
51
 * <br><br>
 
52
 * <code>
 
53
 * -Djava.security.auth.login.config=etc/ldap-loginModule.conf
 
54
 * </code>
 
55
 * <br><br>
 
56
 * and an example of the ldap-loginModule.conf would be:
 
57
 * <br><br>
 
58
 * <pre>
 
59
 * ldaploginmodule {
 
60
 *    org.mortbay.jetty.plus.jaas.spi.LdapLoginModule required
 
61
 *    debug="true"
 
62
 *    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
 
63
 *    hostname="ldap.example.com"
 
64
 *    port="389"
 
65
 *    bindDn="cn=Directory Manager"
 
66
 *    bindPassword="directory"
 
67
 *    authenticationMethod="simple"
 
68
 *    forceBindingLogin="false"
 
69
 *    userBaseDn="ou=people,dc=alcatel"
 
70
 *    userRdnAttribute="uid"
 
71
 *    userIdAttribute="uid"
 
72
 *    userPasswordAttribute="userPassword"
 
73
 *    userObjectClass="inetOrgPerson"
 
74
 *    roleBaseDn="ou=groups,dc=example,dc=com"
 
75
 *    roleNameAttribute="cn"
 
76
 *    roleMemberAttribute="uniqueMember"
 
77
 *    roleObjectClass="groupOfUniqueNames";
 
78
 *    };
 
79
 *  </pre>
 
80
 *
 
81
 * @author Jesse McConnell <jesse@codehaus.org>
 
82
 * @author Frederic Nizery <frederic.nizery@alcatel-lucent.fr>
 
83
 * @author Trygve Laugstol <trygvis@codehaus.org>
 
84
 */
 
85
public class LdapLoginModule extends AbstractLoginModule
 
86
{
 
87
    /**
 
88
     * hostname of the ldap server
 
89
     */
 
90
    private String _hostname;
 
91
 
 
92
    /**
 
93
     * port of the ldap server
 
94
     */
 
95
    private int _port;
 
96
 
 
97
    /**
 
98
     * Context.SECURITY_AUTHENTICATION
 
99
     */
 
100
    private String _authenticationMethod;
 
101
 
 
102
    /**
 
103
     * Context.INITIAL_CONTEXT_FACTORY
 
104
     */
 
105
    private String _contextFactory;
 
106
 
 
107
    /**
 
108
     * root DN used to connect to
 
109
     */
 
110
    private String _bindDn;
 
111
 
 
112
    /**
 
113
     * password used to connect to the root ldap context
 
114
     */
 
115
    private String _bindPassword;
 
116
 
 
117
    /**
 
118
     * object class of a user
 
119
     */
 
120
    private String _userObjectClass = "inetOrgPerson";
 
121
 
 
122
    /**
 
123
     * attribute that the principal is located
 
124
     */
 
125
    private String _userRdnAttribute = "uid";
 
126
 
 
127
    /**
 
128
     * attribute that the principal is located
 
129
     */
 
130
    private String _userIdAttribute = "cn";
 
131
 
 
132
    /**
 
133
     * name of the attribute that a users password is stored under
 
134
     * <p/>
 
135
     * NOTE: not always accessible, see force binding login
 
136
     */
 
137
    private String _userPasswordAttribute = "userPassword";
 
138
 
 
139
    /**
 
140
     * base DN where users are to be searched from
 
141
     */
 
142
    private String _userBaseDn;
 
143
 
 
144
    /**
 
145
     * base DN where role membership is to be searched from
 
146
     */
 
147
    private String _roleBaseDn;
 
148
 
 
149
    /**
 
150
     * object class of roles
 
151
     */
 
152
    private String _roleObjectClass = "groupOfUniqueNames";
 
153
 
 
154
    /**
 
155
     * name of the attribute that a username would be under a role class
 
156
     */
 
157
    private String _roleMemberAttribute = "uniqueMember";
 
158
 
 
159
    /**
 
160
     * the name of the attribute that a role would be stored under
 
161
     */
 
162
    private String _roleNameAttribute = "roleName";
 
163
 
 
164
    private boolean _debug;
 
165
 
 
166
    /**
 
167
     * if the getUserInfo can pull a password off of the user then
 
168
     * password comparison is an option for authn, to force binding
 
169
     * login checks, set this to true
 
170
     */
 
171
    private boolean _forceBindingLogin = false;
 
172
 
 
173
    private DirContext _rootContext;
 
174
 
 
175
    /**
 
176
     * get the available information about the user
 
177
     * <p/>
 
178
     * for this LoginModule, the credential can be null which will result in a
 
179
     * binding ldap authentication scenario
 
180
     * <p/>
 
181
     * roles are also an optional concept if required
 
182
     *
 
183
     * @param username
 
184
     * @return
 
185
     * @throws Exception
 
186
     */
 
187
    public UserInfo getUserInfo(String username) throws Exception
 
188
    {
 
189
        String pwdCredential = getUserCredentials(username);
 
190
 
 
191
        if (pwdCredential == null)
 
192
        {
 
193
            return null;
 
194
        }
 
195
 
 
196
        pwdCredential = convertCredentialLdapToJetty(pwdCredential);
 
197
 
 
198
        //String md5Credential = Credential.MD5.digest("foo");
 
199
        //byte[] ba = digestMD5("foo");
 
200
        //System.out.println(md5Credential + "  " + ba );
 
201
        Credential credential = Credential.getCredential(pwdCredential);
 
202
        List roles = getUserRoles(_rootContext, username);
 
203
 
 
204
        return new UserInfo(username, credential, roles);
 
205
    }
 
206
 
 
207
    protected String doRFC2254Encoding(String inputString)
 
208
    {
 
209
        StringBuffer buf = new StringBuffer(inputString.length());
 
210
        for (int i = 0; i < inputString.length(); i++)
 
211
        {
 
212
            char c = inputString.charAt(i);
 
213
            switch (c)
 
214
            {
 
215
                case '\\':
 
216
                    buf.append("\\5c");
 
217
                    break;
 
218
                case '*':
 
219
                    buf.append("\\2a");
 
220
                    break;
 
221
                case '(':
 
222
                    buf.append("\\28");
 
223
                    break;
 
224
                case ')':
 
225
                    buf.append("\\29");
 
226
                    break;
 
227
                case '\0':
 
228
                    buf.append("\\00");
 
229
                    break;
 
230
                default:
 
231
                    buf.append(c);
 
232
                    break;
 
233
            }
 
234
        }
 
235
        return buf.toString();
 
236
    }
 
237
 
 
238
    /**
 
239
     * attempts to get the users credentials from the users context
 
240
     * <p/>
 
241
     * NOTE: this is not an user authenticated operation
 
242
     *
 
243
     * @param username
 
244
     * @return
 
245
     * @throws LoginException
 
246
     */
 
247
    private String getUserCredentials(String username) throws LoginException
 
248
    {
 
249
        String ldapCredential = null;
 
250
 
 
251
        SearchControls ctls = new SearchControls();
 
252
        ctls.setCountLimit(1);
 
253
        ctls.setDerefLinkFlag(true);
 
254
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
255
 
 
256
        String filter = "(&(objectClass={0})({1}={2}))";
 
257
 
 
258
        Log.debug("Searching for users with filter: \'" + filter + "\'" + " from base dn: " + _userBaseDn);
 
259
 
 
260
        try
 
261
        {
 
262
            Object[] filterArguments = {_userObjectClass, _userIdAttribute, username};
 
263
            NamingEnumeration results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls);
 
264
 
 
265
            Log.debug("Found user?: " + results.hasMoreElements());
 
266
 
 
267
            if (!results.hasMoreElements())
 
268
            {
 
269
                throw new LoginException("User not found.");
 
270
            }
 
271
 
 
272
            SearchResult result = findUser(username);
 
273
 
 
274
            Attributes attributes = result.getAttributes();
 
275
 
 
276
            Attribute attribute = attributes.get(_userPasswordAttribute);
 
277
            if (attribute != null)
 
278
            {
 
279
                try
 
280
                {
 
281
                    byte[] value = (byte[]) attribute.get();
 
282
 
 
283
                    ldapCredential = new String(value);
 
284
                }
 
285
                catch (NamingException e)
 
286
                {
 
287
                    Log.debug("no password available under attribute: " + _userPasswordAttribute);
 
288
                }
 
289
            }
 
290
        }
 
291
        catch (NamingException e)
 
292
        {
 
293
            throw new LoginException("Root context binding failure.");
 
294
        }
 
295
 
 
296
        Log.debug("user cred is: " + ldapCredential);
 
297
 
 
298
        return ldapCredential;
 
299
    }
 
300
 
 
301
    /**
 
302
     * attempts to get the users roles from the root context
 
303
     * <p/>
 
304
     * NOTE: this is not an user authenticated operation
 
305
     *
 
306
     * @param dirContext
 
307
     * @param username
 
308
     * @return
 
309
     * @throws LoginException
 
310
     */
 
311
    private List getUserRoles(DirContext dirContext, String username) throws LoginException, NamingException
 
312
    {
 
313
        String userDn = _userRdnAttribute + "=" + username + "," + _userBaseDn;
 
314
 
 
315
        return getUserRolesByDn(dirContext, userDn);
 
316
    }
 
317
 
 
318
    private List getUserRolesByDn(DirContext dirContext, String userDn) throws LoginException, NamingException
 
319
    {
 
320
        ArrayList roleList = new ArrayList();
 
321
 
 
322
        if (dirContext == null || _roleBaseDn == null || _roleMemberAttribute == null || _roleObjectClass == null)
 
323
        {
 
324
            return roleList;
 
325
        }
 
326
 
 
327
        SearchControls ctls = new SearchControls();
 
328
        ctls.setDerefLinkFlag(true);
 
329
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
330
 
 
331
        String filter = "(&(objectClass={0})({1}={2}))";
 
332
        Object[] filterArguments = {_roleObjectClass, _roleMemberAttribute, userDn};
 
333
        NamingEnumeration results = dirContext.search(_roleBaseDn, filter, filterArguments, ctls);
 
334
 
 
335
        Log.debug("Found user roles?: " + results.hasMoreElements());
 
336
 
 
337
        while (results.hasMoreElements())
 
338
        {
 
339
            SearchResult result = (SearchResult)results.nextElement();
 
340
 
 
341
            Attributes attributes = result.getAttributes();
 
342
 
 
343
            if (attributes == null)
 
344
            {
 
345
                continue;
 
346
            }
 
347
 
 
348
            Attribute roleAttribute = attributes.get(_roleNameAttribute);
 
349
 
 
350
            if (roleAttribute == null)
 
351
            {
 
352
                continue;
 
353
            }
 
354
 
 
355
            NamingEnumeration roles = roleAttribute.getAll();
 
356
            while (roles.hasMore())
 
357
            {
 
358
                roleList.add(roles.next());
 
359
            }
 
360
        }
 
361
 
 
362
        return roleList;
 
363
    }
 
364
 
 
365
    /**
 
366
     * since ldap uses a context bind for valid authentication checking, we override login()
 
367
     * <p/>
 
368
     * if credentials are not available from the users context or if we are forcing the binding check
 
369
     * then we try a binding authentication check, otherwise if we have the users encoded password then
 
370
     * we can try authentication via that mechanic
 
371
     *
 
372
     * @return
 
373
     * @throws LoginException
 
374
     */
 
375
    public boolean login() throws LoginException
 
376
    {
 
377
        try
 
378
        {
 
379
            if (getCallbackHandler() == null)
 
380
            {
 
381
                throw new LoginException("No callback handler");
 
382
            }
 
383
 
 
384
            Callback[] callbacks = configureCallbacks();
 
385
            getCallbackHandler().handle(callbacks);
 
386
 
 
387
            String webUserName = ((NameCallback) callbacks[0]).getName();
 
388
            Object webCredential = ((ObjectCallback) callbacks[1]).getObject();
 
389
 
 
390
            if (webUserName == null || webCredential == null)
 
391
            {
 
392
                setAuthenticated(false);
 
393
                return isAuthenticated();
 
394
            }
 
395
 
 
396
            if (_forceBindingLogin)
 
397
            {
 
398
                return bindingLogin(webUserName, webCredential);
 
399
            }
 
400
 
 
401
            // This sets read and the credential
 
402
            UserInfo userInfo = getUserInfo(webUserName);
 
403
 
 
404
            if( userInfo == null) {
 
405
                setAuthenticated(false);
 
406
                return false;
 
407
            }
 
408
 
 
409
            setCurrentUser(new JAASUserInfo(userInfo));
 
410
 
 
411
            if (webCredential instanceof String)
 
412
            {
 
413
                return credentialLogin(Credential.getCredential((String) webCredential));
 
414
            }
 
415
 
 
416
            return credentialLogin(webCredential);
 
417
        }
 
418
        catch (UnsupportedCallbackException e)
 
419
        {
 
420
            throw new LoginException("Error obtaining callback information.");
 
421
        }
 
422
        catch (IOException e)
 
423
        {
 
424
            if (_debug)
 
425
            {
 
426
                e.printStackTrace();
 
427
            }
 
428
            throw new LoginException("IO Error performing login.");
 
429
        }
 
430
        catch (Exception e)
 
431
        {
 
432
            if (_debug)
 
433
            {
 
434
                e.printStackTrace();
 
435
            }
 
436
            throw new LoginException("Error obtaining user info.");
 
437
        }
 
438
    }
 
439
 
 
440
    /**
 
441
     * password supplied authentication check
 
442
     *
 
443
     * @param webCredential
 
444
     * @return
 
445
     * @throws LoginException
 
446
     */
 
447
    protected boolean credentialLogin(Object webCredential) throws LoginException
 
448
    {
 
449
        setAuthenticated(getCurrentUser().checkCredential(webCredential));
 
450
        return isAuthenticated();
 
451
    }
 
452
 
 
453
    /**
 
454
     * binding authentication check
 
455
     * This methode of authentication works only if the user branch of the DIT (ldap tree)
 
456
     * has an ACI (acces control instruction) that allow the access to any user or at least
 
457
     * for the user that logs in.
 
458
     *
 
459
     * @param username
 
460
     * @param password
 
461
     * @return
 
462
     * @throws LoginException
 
463
     */
 
464
    protected boolean bindingLogin(String username, Object password) throws LoginException, NamingException
 
465
    {
 
466
        SearchResult searchResult = findUser(username);
 
467
 
 
468
        DirContext usrsContext = (DirContext)_rootContext.lookup(_userBaseDn);
 
469
        DirContext usrContext = (DirContext)usrsContext.lookup(searchResult.getName());
 
470
        String userDn = usrContext.getNameInNamespace();
 
471
 
 
472
        Log.info("Attempting authentication: " + userDn);
 
473
 
 
474
        Hashtable environment = getEnvironment();
 
475
        environment.put(Context.SECURITY_PRINCIPAL, userDn);
 
476
        environment.put(Context.SECURITY_CREDENTIALS, password);
 
477
 
 
478
        DirContext dirContext = new InitialDirContext(environment);
 
479
 
 
480
        List roles = getUserRolesByDn(dirContext, userDn);
 
481
 
 
482
        UserInfo userInfo = new UserInfo(username, null, roles);
 
483
 
 
484
        setCurrentUser(new JAASUserInfo(userInfo));
 
485
 
 
486
        setAuthenticated(true);
 
487
 
 
488
        return true;
 
489
    }
 
490
 
 
491
    private SearchResult findUser(String username) throws NamingException, LoginException
 
492
    {
 
493
        SearchControls ctls = new SearchControls();
 
494
        ctls.setCountLimit(1);
 
495
        ctls.setDerefLinkFlag(true);
 
496
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
497
 
 
498
        String filter = "(&(objectClass={0})({1}={2}))";
 
499
 
 
500
        Log.info("Searching for users with filter: \'" + filter + "\'" + " from base dn: " + _userBaseDn);
 
501
 
 
502
        Object[] filterArguments = new Object[]{
 
503
            _userObjectClass,
 
504
            _userIdAttribute,
 
505
            username
 
506
        };
 
507
        NamingEnumeration results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls);
 
508
 
 
509
        Log.info("Found user?: " + results.hasMoreElements());
 
510
 
 
511
        if (!results.hasMoreElements())
 
512
        {
 
513
            throw new LoginException("User not found.");
 
514
        }
 
515
 
 
516
        return (SearchResult)results.nextElement();
 
517
    }
 
518
 
 
519
    public void initialize(Subject subject,
 
520
                           CallbackHandler callbackHandler,
 
521
                           Map sharedState,
 
522
                           Map options)
 
523
    {
 
524
        super.initialize(subject, callbackHandler, sharedState, options);
 
525
 
 
526
        _hostname = (String) options.get("hostname");
 
527
        _port = Integer.parseInt((String) options.get("port"));
 
528
        _contextFactory = (String) options.get("contextFactory");
 
529
        _bindDn = (String) options.get("bindDn");
 
530
        _bindPassword = (String) options.get("bindPassword");
 
531
        _authenticationMethod = (String) options.get("authenticationMethod");
 
532
 
 
533
        _userBaseDn = (String) options.get("userBaseDn");
 
534
 
 
535
        _roleBaseDn = (String) options.get("roleBaseDn");
 
536
 
 
537
        if (options.containsKey("forceBindingLogin"))
 
538
        {
 
539
            _forceBindingLogin = Boolean.valueOf((String) options.get("forceBindingLogin")).booleanValue();
 
540
        }
 
541
 
 
542
        _userObjectClass = getOption(options, "userObjectClass", _userObjectClass);
 
543
        _userRdnAttribute = getOption(options, "userRdnAttribute", _userRdnAttribute);
 
544
        _userIdAttribute = getOption(options, "userIdAttribute", _userIdAttribute);
 
545
        _userPasswordAttribute = getOption(options, "userPasswordAttribute", _userPasswordAttribute);
 
546
        _roleObjectClass = getOption(options, "roleObjectClass", _roleObjectClass);
 
547
        _roleMemberAttribute = getOption(options, "roleMemberAttribute", _roleMemberAttribute);
 
548
        _roleNameAttribute = getOption(options, "roleNameAttribute", _roleNameAttribute);
 
549
        _debug = Boolean.valueOf(String.valueOf(getOption(options, "debug", Boolean.toString(_debug)))).booleanValue();
 
550
 
 
551
        try
 
552
        {
 
553
            _rootContext = new InitialDirContext(getEnvironment());
 
554
        }
 
555
        catch (NamingException ex)
 
556
        {
 
557
            throw new RuntimeException("Unable to establish root context", ex);
 
558
        }
 
559
    }
 
560
   
 
561
    public boolean commit() throws LoginException 
 
562
    {
 
563
                try 
 
564
                {
 
565
                        _rootContext.close();
 
566
                } 
 
567
                catch (NamingException e) 
 
568
                {
 
569
                        throw new LoginException("error closing root context: " + e.getMessage());
 
570
                }
 
571
 
 
572
                return super.commit();
 
573
        }
 
574
 
 
575
        public boolean abort() throws LoginException 
 
576
        {
 
577
                try 
 
578
                {
 
579
                        _rootContext.close();
 
580
                } 
 
581
                catch (NamingException e) 
 
582
                {
 
583
                        throw new LoginException("error closing root context: " + e.getMessage());
 
584
                }
 
585
 
 
586
                return super.abort();
 
587
        }
 
588
    
 
589
    private String getOption(Map options, String key, String defaultValue)
 
590
    {
 
591
        Object value = options.get(key);
 
592
 
 
593
        if (value == null) {
 
594
            return defaultValue;
 
595
        }
 
596
 
 
597
        return (String) value;
 
598
    }
 
599
 
 
600
    /**
 
601
     * get the context for connection
 
602
     *
 
603
     * @return
 
604
     */
 
605
    public Hashtable getEnvironment()
 
606
    {
 
607
        Properties env = new Properties();
 
608
 
 
609
        env.put(Context.INITIAL_CONTEXT_FACTORY, _contextFactory);
 
610
 
 
611
        if (_hostname != null)
 
612
        {
 
613
            if (_port != 0)
 
614
            {
 
615
                env.put(Context.PROVIDER_URL, "ldap://" + _hostname + ":" + _port + "/");
 
616
            }
 
617
            else
 
618
            {
 
619
                env.put(Context.PROVIDER_URL, "ldap://" + _hostname + "/");
 
620
            }
 
621
        }
 
622
 
 
623
        if (_authenticationMethod != null)
 
624
        {
 
625
            env.put(Context.SECURITY_AUTHENTICATION, _authenticationMethod);
 
626
        }
 
627
 
 
628
        if (_bindDn != null)
 
629
        {
 
630
            env.put(Context.SECURITY_PRINCIPAL, _bindDn);
 
631
        }
 
632
 
 
633
        if (_bindPassword != null)
 
634
        {
 
635
            env.put(Context.SECURITY_CREDENTIALS, _bindPassword);
 
636
        }
 
637
 
 
638
        return env;
 
639
    }
 
640
 
 
641
    public static String convertCredentialJettyToLdap( String encryptedPassword )
 
642
    {
 
643
        if ("MD5:".startsWith(encryptedPassword.toUpperCase()))
 
644
        {
 
645
            return "{MD5}" + encryptedPassword.substring("MD5:".length(), encryptedPassword.length());
 
646
        }
 
647
 
 
648
        if ("CRYPT:".startsWith(encryptedPassword.toUpperCase()))
 
649
        {
 
650
            return "{CRYPT}" + encryptedPassword.substring("CRYPT:".length(), encryptedPassword.length());
 
651
        }
 
652
 
 
653
        return encryptedPassword;
 
654
    }
 
655
 
 
656
    public static String convertCredentialLdapToJetty( String encryptedPassword )
 
657
    {
 
658
        if (encryptedPassword == null)
 
659
        {
 
660
            return encryptedPassword;
 
661
        }
 
662
 
 
663
        if ("{MD5}".startsWith(encryptedPassword.toUpperCase()))
 
664
        {
 
665
            return "MD5:" + encryptedPassword.substring("{MD5}".length(), encryptedPassword.length());
 
666
        }
 
667
 
 
668
        if ("{CRYPT}".startsWith(encryptedPassword.toUpperCase()))
 
669
        {
 
670
            return "CRYPT:" + encryptedPassword.substring("{CRYPT}".length(), encryptedPassword.length());
 
671
        }
 
672
 
 
673
        return encryptedPassword;
 
674
    }
 
675
}