aboutsummaryrefslogtreecommitdiffstats
path: root/ntlm.h
blob: ad835201ce1515deef88bef04d88c4309fd4d843 (plain)
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
/* ntlm.h  -- interface declarations for SMB authentication code */

#include "smbtypes.h"

/* 
 * These structures are byte-order dependant, and should not
 * be manipulated except by the use of the routines provided
 */

typedef struct
{
uint16  len;
uint16  maxlen;
uint32  offset;
}tSmbStrHeader;

typedef struct
{
char          ident[8];
uint32        msgType;
uint32        flags;
tSmbStrHeader    user;
tSmbStrHeader    domain;
uint8         buffer[1024];
uint32        bufIndex;
}tSmbNtlmAuthRequest;

typedef struct
{
char          ident[8];
uint32        msgType;
tSmbStrHeader    uDomain;
uint32        flags;
uint8         challengeData[8];
uint32        context[2];
tSmbStrHeader    targetInfo;
uint8         buffer[1024];
uint32        bufIndex;
}tSmbNtlmAuthChallenge;


typedef struct
{
char          ident[8];
uint32        msgType;
tSmbStrHeader    lmResponse;
tSmbStrHeader    ntResponse;
tSmbStrHeader    uDomain;
tSmbStrHeader    uUser;
tSmbStrHeader    uWks;
tSmbStrHeader    sessionKey;
uint32        flags;
uint8         buffer[1024];
uint32        bufIndex;
}tSmbNtlmAuthResponse;

/* public: */

#define SmbLength(ptr) (((ptr)->buffer - (uint8*)(ptr)) + (ptr)->bufIndex)

extern void dumpSmbNtlmAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request);
extern void dumpSmbNtlmAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge);
extern void dumpSmbNtlmAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response);

extern void buildSmbNtlmAuthRequest(tSmbNtlmAuthRequest *request, char *user, char *domain);
extern void buildSmbNtlmAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, char *user, char *password);

/* ntlm.h ends here */
">)); memset (opad, 0, sizeof (opad)); memcpy (ipad, password, pass_len); memcpy (opad, password, pass_len); for (i=0; i<64; i++) { ipad[i] ^= 0x36; opad[i] ^= 0x5c; } MD5Init (&ctx); MD5Update (&ctx, ipad, sizeof (ipad)); MD5Update (&ctx, challenge, chal_len); MD5Final (response, &ctx); MD5Init (&ctx); MD5Update (&ctx, opad, sizeof (opad)); MD5Update (&ctx, response, resp_len); MD5Final (response, &ctx); } int do_cram_md5 (int sock, char *command, struct query *ctl, char *strip) /* authenticate as per RFC2195 */ { int result; int len; unsigned char buf1[1024]; unsigned char msg_id[768]; unsigned char response[16]; unsigned char reply[1024]; unsigned char *respdata; gen_send (sock, "%s CRAM-MD5", command); /* From RFC2195: * The data encoded in the first ready response contains an * presumptively arbitrary string of random digits, a timestamp, and the * fully-qualified primary host name of the server. The syntax of the * unencoded form must correspond to that of an RFC 822 'msg-id' * [RFC822] as described in [POP3]. */ if ((result = gen_recv (sock, buf1, sizeof (buf1)))) { return result; } /* caller may specify a response prefix we should strip if present */ respdata = buf1; if (strip && strncmp(buf1, strip, strlen(strip)) == 0) respdata += strlen(strip); len = from64tobits (msg_id, respdata, sizeof(msg_id)); if (len < 0) { report (stderr, GT_("could not decode BASE64 challenge\n")); return PS_AUTHFAIL; } else if (len < sizeof (msg_id)) { msg_id[len] = 0; } else { msg_id[sizeof (msg_id)-1] = 0; } if (outlevel >= O_DEBUG) { report (stdout, GT_("decoded as %s\n"), msg_id); } /* The client makes note of the data and then responds with a string * consisting of the user name, a space, and a 'digest'. The latter is * computed by applying the keyed MD5 algorithm from [KEYED-MD5] where * the key is a shared secret and the digested text is the timestamp * (including angle-brackets). */ hmac_md5(ctl->password, strlen(ctl->password), msg_id, strlen (msg_id), response, sizeof (response)); snprintf (reply, sizeof(reply), "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", ctl->remotename, response[0], response[1], response[2], response[3], response[4], response[5], response[6], response[7], response[8], response[9], response[10], response[11], response[12], response[13], response[14], response[15]); to64frombits (buf1, reply, strlen(reply)); /* ship the authentication back, accept the server's responses */ /* PMDF5.2 IMAP has a bug that requires this to be a single write */ suppress_tags = TRUE; result = gen_transact(sock, buf1, sizeof(buf1)); suppress_tags = FALSE; if (result) return(result); else return(PS_SUCCESS); } /* cram.c ends here */