summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/ntlm
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/ntlm')
-rw-r--r--source4/heimdal/lib/ntlm/heimntlm-protos.h11
-rw-r--r--source4/heimdal/lib/ntlm/heimntlm.h81
-rw-r--r--source4/heimdal/lib/ntlm/ntlm.c278
3 files changed, 297 insertions, 73 deletions
diff --git a/source4/heimdal/lib/ntlm/heimntlm-protos.h b/source4/heimdal/lib/ntlm/heimntlm-protos.h
index 438ba2b94d..bc64791b43 100644
--- a/source4/heimdal/lib/ntlm/heimntlm-protos.h
+++ b/source4/heimdal/lib/ntlm/heimntlm-protos.h
@@ -43,7 +43,7 @@ heim_ntlm_calculate_ntlm2_sess (
int
heim_ntlm_decode_targetinfo (
- struct ntlm_buf */*data*/,
+ const struct ntlm_buf */*data*/,
int /*ucs2*/,
struct ntlm_targetinfo */*ti*/);
@@ -65,7 +65,7 @@ heim_ntlm_decode_type3 (
int
heim_ntlm_encode_targetinfo (
- struct ntlm_targetinfo */*ti*/,
+ const struct ntlm_targetinfo */*ti*/,
int /*ucs2*/,
struct ntlm_buf */*data*/);
@@ -76,15 +76,18 @@ heim_ntlm_encode_type1 (
int
heim_ntlm_encode_type2 (
- struct ntlm_type2 */*type2*/,
+ const struct ntlm_type2 */*type2*/,
struct ntlm_buf */*data*/);
int
heim_ntlm_encode_type3 (
- struct ntlm_type3 */*type3*/,
+ const struct ntlm_type3 */*type3*/,
struct ntlm_buf */*data*/);
void
+heim_ntlm_free_buf (struct ntlm_buf */*p*/);
+
+void
heim_ntlm_free_targetinfo (struct ntlm_targetinfo */*ti*/);
void
diff --git a/source4/heimdal/lib/ntlm/heimntlm.h b/source4/heimdal/lib/ntlm/heimntlm.h
index 1c1afe1eb1..09d2205fd2 100644
--- a/source4/heimdal/lib/ntlm/heimntlm.h
+++ b/source4/heimdal/lib/ntlm/heimntlm.h
@@ -31,17 +31,22 @@
* SUCH DAMAGE.
*/
-/* $Id: heimntlm.h 19469 2006-12-20 07:28:37Z lha $ */
+/* $Id: heimntlm.h 22376 2007-12-28 18:38:23Z lha $ */
#ifndef HEIM_NTLM_H
#define HEIM_NTLM_H
+/**
+ * Buffer for storing data in the NTLM library. When filled in by the
+ * library it should be freed with heim_ntlm_free_buf().
+ */
struct ntlm_buf {
- size_t length;
- void *data;
+ size_t length; /**< length buffer data */
+ void *data; /**< pointer to the data itself */
};
#define NTLM_NEG_UNICODE 0x00000001
+#define NTLM_NEG_TARGET 0x00000004
#define NTLM_NEG_SIGN 0x00000010
#define NTLM_NEG_SEAL 0x00000020
#define NTLM_NEG_NTLM 0x00000200
@@ -52,42 +57,66 @@ struct ntlm_buf {
#define NTLM_NEG_ALWAYS_SIGN 0x00008000
#define NTLM_NEG_NTLM2_SESSION 0x00080000
-#define NTLM_NEG_TARGET_DOMAIN 0x00010000
+#define NTLM_TARGET_DOMAIN 0x00010000
+#define NTLM_TARGET_SERVER 0x00020000
#define NTLM_ENC_128 0x20000000
#define NTLM_NEG_KEYEX 0x40000000
+/**
+ * Struct for the NTLM target info, the strings is assumed to be in
+ * UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_targetinfo().
+ */
struct ntlm_targetinfo {
- char *servername;
- char *domainname;
- char *dnsdomainname;
- char *dnsservername;
+ char *servername; /**< */
+ char *domainname; /**< */
+ char *dnsdomainname; /**< */
+ char *dnsservername; /**< */
};
+/**
+ * Struct for the NTLM type1 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type1().
+ */
+
struct ntlm_type1 {
- uint32_t flags;
- char *domain;
- char *hostname;
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *domain; /**< */
+ char *hostname; /**< */
+ uint32_t os[2]; /**< */
};
+/**
+ * Struct for the NTLM type2 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type2().
+ */
+
struct ntlm_type2 {
- uint32_t flags;
- char *targetname;
- struct ntlm_buf targetinfo;
- unsigned char challange[8];
- uint32_t context[2];
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *targetname; /**< */
+ struct ntlm_buf targetinfo; /**< */
+ unsigned char challange[8]; /**< */
+ uint32_t context[2]; /**< */
+ uint32_t os[2]; /**< */
};
+/**
+ * Struct for the NTLM type3 message info, the strings is assumed to
+ * be in UTF8. When filled in by the library it should be freed with
+ * heim_ntlm_free_type3().
+ */
+
struct ntlm_type3 {
- uint32_t flags;
- char *username;
- char *targetname;
- struct ntlm_buf lm;
- struct ntlm_buf ntlm;
- struct ntlm_buf sessionkey;
- char *ws;
- uint32_t os[2];
+ uint32_t flags; /**< */
+ char *username; /**< */
+ char *targetname; /**< */
+ struct ntlm_buf lm; /**< */
+ struct ntlm_buf ntlm; /**< */
+ struct ntlm_buf sessionkey; /**< */
+ char *ws; /**< */
+ uint32_t os[2]; /**< */
};
#include <heimntlm-protos.h>
diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c
index 671bf329e8..f3dccfaca1 100644
--- a/source4/heimdal/lib/ntlm/ntlm.c
+++ b/source4/heimdal/lib/ntlm/ntlm.c
@@ -33,7 +33,7 @@
#include <config.h>
-RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
+RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $");
#include <stdio.h>
#include <stdlib.h>
@@ -51,12 +51,37 @@ RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
#include <heimntlm.h>
-
-/*
- * Source of NTLM information:
- * http://davenport.sourceforge.net/ntlm.html
+/*! \mainpage Heimdal NTLM library
+ *
+ * \section intro Introduction
+ *
+ * Heimdal libheimntlm library is a implementation of the NTLM
+ * protocol, both version 1 and 2. The GSS-API mech that uses this
+ * library adds support for transport encryption and integrity
+ * checking.
+ *
+ * NTLM is a protocol for mutual authentication, its still used in
+ * many protocol where Kerberos is not support, one example is
+ * EAP/X802.1x mechanism LEAP from Microsoft and Cisco.
+ *
+ * This is a support library for the core protocol, its used in
+ * Heimdal to implement and GSS-API mechanism. There is also support
+ * in the KDC to do remote digest authenticiation, this to allow
+ * services to authenticate users w/o direct access to the users ntlm
+ * hashes (same as Kerberos arcfour enctype hashes).
+ *
+ * More information about the NTLM protocol can found here
+ * http://davenport.sourceforge.net/ntlm.html .
+ *
+ * The Heimdal projects web page: http://www.h5l.org/
*/
+/** @defgroup ntlm_core Heimdal NTLM library
+ *
+ * The NTLM core functions implement the string2key generation
+ * function, message encode and decode function, and the hash function
+ * functions.
+ */
struct sec_buffer {
uint16_t length;
@@ -73,8 +98,16 @@ static const unsigned char ntlmsigature[8] = "NTLMSSP\x00";
#define CHECK(f, e) \
do { ret = f ; if (ret != (e)) { ret = EINVAL; goto out; } } while(0)
-static void
-_ntlm_free_buf(struct ntlm_buf *p)
+/**
+ * heim_ntlm_free_buf frees the ntlm buffer
+ *
+ * @param p buffer to be freed
+ *
+ * @ingroup ntlm_core
+ */
+
+void
+heim_ntlm_free_buf(struct ntlm_buf *p)
{
if (p->data)
free(p->data);
@@ -96,7 +129,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
buf->length = len * 2;
buf->data = malloc(buf->length);
if (buf->data == NULL && len != 0) {
- _ntlm_free_buf(buf);
+ heim_ntlm_free_buf(buf);
return ENOMEM;
}
@@ -104,7 +137,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
for (i = 0; i < len; i++) {
unsigned char t = (unsigned char)string[i];
if (t & 0x80) {
- _ntlm_free_buf(buf);
+ heim_ntlm_free_buf(buf);
return EINVAL;
}
if (up)
@@ -201,7 +234,7 @@ put_string(krb5_storage *sp, int ucs2, const char *s)
CHECK(krb5_storage_write(sp, buf.data, buf.length), buf.length);
if (ucs2)
- _ntlm_free_buf(&buf);
+ heim_ntlm_free_buf(&buf);
ret = 0;
out:
return ret;
@@ -226,7 +259,7 @@ out:
}
static krb5_error_code
-put_buf(krb5_storage *sp, struct ntlm_buf *buf)
+put_buf(krb5_storage *sp, const struct ntlm_buf *buf)
{
krb5_error_code ret;
CHECK(krb5_storage_write(sp, buf->data, buf->length), buf->length);
@@ -235,8 +268,12 @@ out:
return ret;
}
-/*
+/**
+ * Frees the ntlm_targetinfo message
+ *
+ * @param ti targetinfo to be freed
*
+ * @ingroup ntlm_core
*/
void
@@ -260,8 +297,22 @@ out:
return ret;
}
+/**
+ * Encodes a ntlm_targetinfo message.
+ *
+ * @param ti the ntlm_targetinfo message to encode.
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_targetinfo(struct ntlm_targetinfo *ti,
+heim_ntlm_encode_targetinfo(const struct ntlm_targetinfo *ti,
int ucs2,
struct ntlm_buf *data)
{
@@ -299,16 +350,34 @@ out:
return ret;
}
+/**
+ * Decodes an NTLM targetinfo message
+ *
+ * @param data input data buffer with the encode NTLM targetinfo message
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param ti the decoded target info, should be freed with heim_ntlm_free_targetinfo().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_decode_targetinfo(struct ntlm_buf *data, int ucs2,
+heim_ntlm_decode_targetinfo(const struct ntlm_buf *data,
+ int ucs2,
struct ntlm_targetinfo *ti)
{
memset(ti, 0, sizeof(*ti));
return 0;
}
-/*
- * encoder/decoder type1 messages
+/**
+ * Frees the ntlm_type1 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
@@ -367,6 +436,19 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type1 message.
+ *
+ * @param type1 the ntlm_type1 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
heim_ntlm_encode_type1(const struct ntlm_type1 *type1, struct ntlm_buf *data)
{
@@ -435,8 +517,12 @@ out:
return ret;
}
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type2 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
@@ -444,7 +530,7 @@ heim_ntlm_free_type2(struct ntlm_type2 *data)
{
if (data->targetname)
free(data->targetname);
- _ntlm_free_buf(&data->targetinfo);
+ heim_ntlm_free_buf(&data->targetinfo);
memset(data, 0, sizeof(*data));
}
@@ -499,8 +585,21 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type2 message.
+ *
+ * @param type2 the ntlm_type2 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_type2(struct ntlm_type2 *type2, struct ntlm_buf *data)
+heim_ntlm_encode_type2(const struct ntlm_type2 *type2, struct ntlm_buf *data)
{
struct sec_buffer targetname, targetinfo;
krb5_error_code ret;
@@ -562,22 +661,26 @@ out:
return ret;
}
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type3 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
*/
void
heim_ntlm_free_type3(struct ntlm_type3 *data)
{
- _ntlm_free_buf(&data->lm);
- _ntlm_free_buf(&data->ntlm);
+ heim_ntlm_free_buf(&data->lm);
+ heim_ntlm_free_buf(&data->ntlm);
if (data->targetname)
free(data->targetname);
if (data->username)
free(data->username);
if (data->ws)
free(data->ws);
- _ntlm_free_buf(&data->sessionkey);
+ heim_ntlm_free_buf(&data->sessionkey);
memset(data, 0, sizeof(*data));
}
@@ -629,7 +732,7 @@ heim_ntlm_decode_type3(const struct ntlm_buf *buf,
CHECK(ret_buf(in, &ntlm, &type3->ntlm), 0);
CHECK(ret_string(in, ucs2, &target, &type3->targetname), 0);
CHECK(ret_string(in, ucs2, &username, &type3->username), 0);
- CHECK(ret_string(in, ucs2, &username, &type3->ws), 0);
+ CHECK(ret_string(in, ucs2, &ws, &type3->ws), 0);
if (sessionkey.offset)
CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
@@ -641,8 +744,21 @@ out:
return ret;
}
+/**
+ * Encodes an ntlm_type3 message.
+ *
+ * @param type3 the ntlm_type3 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
int
-heim_ntlm_encode_type3(struct ntlm_type3 *type3, struct ntlm_buf *data)
+heim_ntlm_encode_type3(const struct ntlm_type3 *type3, struct ntlm_buf *data)
{
struct sec_buffer lm, ntlm, target, username, sessionkey, ws;
krb5_error_code ret;
@@ -766,8 +882,16 @@ splitandenc(unsigned char *hash,
memset(key, 0, sizeof(key));
}
-/*
- * String-to-key function for NTLM
+/**
+ * Calculate the NTLM key, the password is assumed to be in UTF8.
+ *
+ * @param password password to calcute the key for.
+ * @param key calcuted key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -784,18 +908,28 @@ heim_ntlm_nt_key(const char *password, struct ntlm_buf *key)
ret = ascii2ucs2le(password, 0, &buf);
if (ret) {
- _ntlm_free_buf(key);
+ heim_ntlm_free_buf(key);
return ret;
}
MD4_Init(&ctx);
MD4_Update(&ctx, buf.data, buf.length);
MD4_Final(key->data, &ctx);
- _ntlm_free_buf(&buf);
+ heim_ntlm_free_buf(&buf);
return 0;
}
-/*
+/**
* Calculate NTLMv1 response hash
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param challange sent by the server
+ * @param answer calculated answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -823,8 +957,18 @@ heim_ntlm_calculate_ntlm1(void *key, size_t len,
return 0;
}
-/*
- * Calculate NTLMv1 master key
+/**
+ * Generates an NTLMv1 session random with assosited session master key.
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param session generated session nonce, should be freed with heim_ntlm_free_buf().
+ * @param master calculated session master key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -849,8 +993,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
master->length = MD4_DIGEST_LENGTH;
master->data = malloc(master->length);
if (master->data == NULL) {
- _ntlm_free_buf(master);
- _ntlm_free_buf(session);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
return EINVAL;
}
@@ -866,8 +1010,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
}
if (RAND_bytes(session->data, session->length) != 1) {
- _ntlm_free_buf(master);
- _ntlm_free_buf(session);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
return EINVAL;
}
@@ -877,8 +1021,16 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
return 0;
}
-/*
+/**
+ * Generates an NTLMv2 session key.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param ntlmv2 the ntlmv2 session key
*
+ * @ingroup ntlm_core
*/
void
@@ -932,8 +1084,22 @@ nt2unixtime(uint64_t t)
}
-/*
+/**
* Calculate NTLMv2 response
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -1020,8 +1186,23 @@ out:
static const int authtimediff = 3600 * 2; /* 2 hours */
-/*
+/**
* Verify NTLMv2 response.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param now the time now (0 if the library should pick it up itself)
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int
@@ -1110,13 +1291,13 @@ heim_ntlm_verify_ntlm2(const void *key, size_t len,
HMAC_CTX_cleanup(&c);
if (memcmp(serveranswer, clientanswer, 16) != 0) {
- _ntlm_free_buf(infotarget);
+ heim_ntlm_free_buf(infotarget);
return EINVAL;
}
return 0;
out:
- _ntlm_free_buf(infotarget);
+ heim_ntlm_free_buf(infotarget);
if (sp)
krb5_storage_free(sp);
return ret;
@@ -1125,6 +1306,17 @@ out:
/*
* Calculate the NTLM2 Session Response
+ *
+ * @param clnt_nonce client nonce
+ * @param svr_chal server challage
+ * @param ntlm2_hash ntlm hash
+ * @param lm The LM response, should be freed with heim_ntlm_free_buf().
+ * @param ntlm The NTLM response, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
*/
int