* NTLM authentication support with the ntlm library, in Unix systems.
[alpine.git] / imap / src / c-client / auth_ntl.c
blob0afe99fc4d9966239da1277545277a27263cb0e1
1 /* ========================================================================
2 * Copyright 1988-2008 University of Washington
3 * Copyright 2015 Imagination Technologies
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
16 * Program: NT LAN Manager authenticator
18 * Author: Maciej W. Rozycki
20 * Date: 25 January 2015
21 * Last Edited: 25 January 2015
24 #include <ntlm.h>
26 long auth_ntlm_client (authchallenge_t challenger,authrespond_t responder,
27 char *service,NETMBX *mb,void *stream,
28 unsigned long *trial,char *user);
30 AUTHENTICATOR auth_ntl = { /* secure, has full auth, hidden */
31 AU_SECURE | AU_AUTHUSER | AU_HIDE,
32 "NTLM", /* authenticator name */
33 NIL, /* always valid */
34 auth_ntlm_client, /* client method */
35 NIL, /* no server method */
36 NIL /* next authenticator */
39 /* Client authenticator
40 * Accepts: challenger function
41 * responder function
42 * SASL service name
43 * parsed network mailbox structure
44 * stream argument for functions
45 * pointer to current trial count
46 * returned user name
47 * Returns: T if success, NIL otherwise, number of trials incremented if retry
50 long auth_ntlm_client (authchallenge_t challenger, authrespond_t responder,
51 char *service, NETMBX *mb, void *stream,
52 unsigned long *trial, char *user)
54 tSmbNtlmAuthChallenge *challenge;
55 tSmbNtlmAuthResponse response;
56 tSmbNtlmAuthRequest request;
57 char tbuf[MAILTMPLEN];
58 char ubuf[MAILTMPLEN];
59 char pass[MAILTMPLEN];
60 unsigned long clen;
61 unsigned long ulen;
62 unsigned long dlen;
63 long ret = NIL;
64 char *sep;
66 /* get initial (empty) challenge */
67 if (challenge = (*challenger) (stream, &clen)) {
68 fs_give ((void **) &challenge);
69 pass[0] = NIL; /* prompt user */
70 mm_login (mb, user, pass, *trial);
71 if (!pass[0]) { /* user requested abort */
72 (*responder) (stream, NIL, 0);
73 *trial = 0; /* cancel subsequent attempts */
74 ret = LONGT; /* will get a BAD response back */
75 } else {
76 /* translate domain\user to user@domain */
77 /* otherwise buildSmbNtlmAuthResponse */
78 /* will override the domain requested with */
79 /* one returned by the challenge message */
80 sep = strchr (user, '\\');
81 if (*sep) {
82 dlen = sep - user;
83 ulen = strlen (sep + 1);
84 memcpy (ubuf, sep + 1, ulen);
85 ubuf[ulen] = '@';
86 memcpy (ubuf + ulen + 1, user, dlen);
87 ubuf[ulen + dlen + 1] = '\0';
88 user = ubuf;
90 buildSmbNtlmAuthRequest (&request, user, NULL);
91 /* send a negotiate message */
92 if ((*responder) (stream, (void *) &request, SmbLength (&request)) &&
93 (challenge = (*challenger) (stream, &clen))) {
94 /* interpret the challenge message */
95 buildSmbNtlmAuthResponse (challenge, &response, user, pass);
96 fs_give ((void **) &challenge);
97 /* send a response message */
98 if ((*responder) (stream, (void *) &response, SmbLength (&response))) {
99 if (challenge = (*challenger) (stream, &clen))
100 fs_give ((void **) &challenge);
101 else {
102 ++*trial; /* can try again if necessary */
103 ret = LONGT; /* check the authentication */
109 memset (pass,0,MAILTMPLEN); /* erase password */
110 if (!ret) *trial = 65535; /* don't retry if bad protocol */
111 return ret;