1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
/*
This file is part of the KDE libraries.
Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KNTLM_H
#define KNTLM_H
#include <qglobal.h>
#include <qcstring.h>
#include <qstring.h>
#include <kdelibs_export.h>
/**
* @short KNTLM class implements the NTLM authentication protocol.
*
* The KNTLM class is useful for creating the authentication structures which
* can be used for various servers which implements NTLM type authentication.
* A comprehensive description of the NTLM authentication protocol can be found
* at http://davenport.sourceforge.net/ntlm.html
* The class also contains methods to create the LanManager and NT (MD4) hashes
* of a password.
* This class doesn't maintain any state information, so all methods are static.
*/
class KIO_EXPORT KNTLM {
public:
enum Flags {
Negotiate_Unicode = 0x00000001,
Negotiate_OEM = 0x00000002,
Request_Target = 0x00000004,
Negotiate_Sign = 0x00000010,
Negotiate_Seal = 0x00000020,
Negotiate_Datagram_Style = 0x00000040,
Negotiate_LM_Key = 0x00000080,
Negotiate_Netware = 0x00000100,
Negotiate_NTLM = 0x00000200,
Negotiate_Domain_Supplied = 0x00001000,
Negotiate_WS_Supplied = 0x00002000,
Negotiate_Local_Call = 0x00004000,
Negotiate_Always_Sign = 0x00008000,
Target_Type_Domain = 0x00010000,
Target_Type_Server = 0x00020000,
Target_Type_Share = 0x00040000,
Negotiate_NTLM2_Key = 0x00080000,
Request_Init_Response = 0x00100000,
Request_Accept_Response = 0x00200000,
Request_NonNT_Key = 0x00400000,
Negotiate_Target_Info = 0x00800000,
Negotiate_128 = 0x20000000,
Negotiate_Key_Exchange = 0x40000000,
Negotiate_56 = 0x80000000
};
typedef struct
{
Q_UINT16 len;
Q_UINT16 maxlen;
Q_UINT32 offset;
} SecBuf;
/**
* The NTLM Type 1 structure
*/
typedef struct
{
char signature[8]; /* "NTLMSSP\0" */
Q_UINT32 msgType; /* 1 */
Q_UINT32 flags;
SecBuf domain;
SecBuf workstation;
} Negotiate;
/**
* The NTLM Type 2 structure
*/
typedef struct
{
char signature[8];
Q_UINT32 msgType; /* 2 */
SecBuf targetName;
Q_UINT32 flags;
Q_UINT8 challengeData[8];
Q_UINT32 context[2];
SecBuf targetInfo;
} Challenge;
/**
* The NTLM Type 3 structure
*/
typedef struct
{
char signature[8];
Q_UINT32 msgType; /* 3 */
SecBuf lmResponse;
SecBuf ntResponse;
SecBuf domain;
SecBuf user;
SecBuf workstation;
SecBuf sessionKey;
Q_UINT32 flags;
} Auth;
typedef struct
{
Q_UINT32 signature;
Q_UINT32 reserved;
Q_UINT64 timestamp;
Q_UINT8 challenge[8];
Q_UINT8 unknown[4];
//Target info block - variable length
} Blob;
/**
* Creates the initial message (type 1) which should be sent to the server.
*
* @param negotiate - a buffer where the Type 1 message will returned.
* @param domain - the domain name which should be send with the message.
* @param workstation - the workstation name which should be send with the message.
* @param flags - various flags, in most cases the defaults will good.
*
* @return true if creating the structure succeeds, false otherwise.
*/
static bool getNegotiate( QByteArray &negotiate, const QString &domain = QString::null,
const QString &workstation = QString::null,
Q_UINT32 flags = Negotiate_Unicode | Request_Target | Negotiate_NTLM );
/**
* Creates the type 3 message which should be sent to the server after
* the challenge (type 2) received.
*
* @param auth - a buffer where the Type 3 message will returned.
* @param challenge - the Type 2 message returned by the server.
* @param user - user's name.
* @param password - user's password.
* @param domain - the target domain. If left empty, it will be extracted
* from the challenge.
* @param workstation - the user's workstation.
* @param forceNTLM - force the use of NTLM authentication (either v1 or v2).
* @param forceNTLMv2 - force the use of NTLMv2 or LMv2 authentication. If false, NTLMv2
* support is autodetected from the challenge.
*
* @return true if auth filled with the Type 3 message, false if an error occured
* (challenge data invalid, or NTLM authentication forced, but the challenge data says
* no NTLM supported).
*/
static bool getAuth( QByteArray &auth, const QByteArray &challenge, const QString &user,
const QString &password, const QString &domain = QString::null,
const QString &workstation = QString::null, bool forceNTLM = false, bool forceNTLMv2 = false );
/**
* Returns the LanManager response from the password and the server challenge.
*/
static QByteArray getLMResponse( const QString &password, const unsigned char *challenge );
/**
* Calculates the LanManager hash of the specified password.
*/
static QByteArray lmHash( const QString &password );
/**
* Calculates the LanManager response from the LanManager hash and the server challenge.
*/
static QByteArray lmResponse( const QByteArray &hash, const unsigned char *challenge );
/**
* Returns the NTLM response from the password and the server challenge.
*/
static QByteArray getNTLMResponse( const QString &password, const unsigned char *challenge );
/**
* Returns the NTLM hash (MD4) from the password.
*/
static QByteArray ntlmHash( const QString &password );
/**
* Calculates the NTLMv2 response.
*/
static QByteArray getNTLMv2Response( const QString &target, const QString &user,
const QString &password, const QByteArray &targetInformation,
const unsigned char *challenge );
/**
* Calculates the LMv2 response.
*/
static QByteArray getLMv2Response( const QString &target, const QString &user,
const QString &password, const unsigned char *challenge );
/**
* Returns the NTLMv2 hash.
*/
static QByteArray ntlmv2Hash( const QString &target, const QString &user, const QString &password );
/**
* Calculates the LMv2 response.
*/
static QByteArray lmv2Response( const QByteArray &hash,
const QByteArray &clientData, const unsigned char *challenge );
/**
* Extracts a string field from an NTLM structure.
*/
static QString getString( const QByteArray &buf, const SecBuf &secbuf, bool unicode );
/**
* Extracts a byte array from an NTLM structure.
*/
static QByteArray getBuf( const QByteArray &buf, const SecBuf &secbuf );
static QByteArray createBlob( const QByteArray &targetinfo );
static QByteArray hmacMD5( const QByteArray &data, const QByteArray &key );
private:
static QByteArray QString2UnicodeLE( const QString &target );
static QString UnicodeLE2QString( const QChar* data, uint len );
static void addBuf( QByteArray &buf, SecBuf &secbuf, QByteArray &data );
static void addString( QByteArray &buf, SecBuf &secbuf, const QString &str, bool unicode = false );
static void convertKey( unsigned char *key_56, void* ks );
};
#endif /* KNTLM_H */
|