View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.http;
21  
22  import jcifs.ntlmssp.NtlmFlags;
23  import jcifs.ntlmssp.Type1Message;
24  import jcifs.ntlmssp.Type2Message;
25  import jcifs.ntlmssp.Type3Message;
26  import jcifs.util.Base64;
27  import org.apache.http.impl.auth.NTLMEngine;
28  import org.apache.http.impl.auth.NTLMEngineException;
29  import org.apache.log4j.Logger;
30  
31  import java.io.IOException;
32  
33  /**
34   * JCIFS based NTLM authentication.
35   */
36  public final class JCIFSEngine implements NTLMEngine {
37      static final Logger LOGGER = Logger.getLogger("davmail.http.JCIFSEngine");
38  
39      private static final int TYPE_1_FLAGS =
40              NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
41                      NtlmFlags.NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED | NtlmFlags.NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED |
42                      NtlmFlags.NTLMSSP_NEGOTIATE_NTLM | NtlmFlags.NTLMSSP_REQUEST_TARGET |
43                      NtlmFlags.NTLMSSP_NEGOTIATE_OEM | NtlmFlags.NTLMSSP_NEGOTIATE_UNICODE |
44                      NtlmFlags.NTLMSSP_NEGOTIATE_56 | NtlmFlags.NTLMSSP_NEGOTIATE_128;
45  
46      public String generateType1Msg(final String domain, final String workstation) {
47          final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation);
48          LOGGER.debug("Generate Type1Msg "+type1Message);
49          return Base64.encode(type1Message.toByteArray());
50      }
51  
52      public String generateType3Msg(final String username, final String password,
53                                     final String domain, final String workstation, final String challenge)
54              throws NTLMEngineException {
55          Type2Message type2Message;
56          try {
57              type2Message = new Type2Message(Base64.decode(challenge));
58          } catch (final IOException exception) {
59              throw new NTLMEngineException("Invalid NTLM type 2 message", exception);
60          }
61          LOGGER.debug("Received Type2Msg " + type2Message);
62  
63          // from HttpClient 4 doc
64          // final int type3Flags = type2Message.getFlags()
65          //        & (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));
66          int type3Flags = NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
67                  NtlmFlags.NTLMSSP_NEGOTIATE_NTLM | NtlmFlags.NTLMSSP_NEGOTIATE_UNICODE;
68          Type3Message type3Message = new Type3Message(type2Message, password,
69                  domain, username, workstation, type3Flags);
70          LOGGER.debug("Generate Type3Msg "+type3Message);
71          return Base64.encode(type3Message.toByteArray());
72      }
73  
74  }