From fc2f0dd93013d0037e2dd442eb0b71174ad8412d Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 8 Nov 2017 19:08:54 +0000 Subject: [ntlm] Add support for NTLM authentication mechanism Signed-off-by: Michael Brown --- src/include/ipxe/errfile.h | 1 + src/include/ipxe/ntlm.h | 199 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 src/include/ipxe/ntlm.h (limited to 'src/include') diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 2dc182dd..e0d0dbc8 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -370,6 +370,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_efi_entropy ( ERRFILE_OTHER | 0x004e0000 ) #define ERRFILE_cert_cmd ( ERRFILE_OTHER | 0x004f0000 ) #define ERRFILE_acpi_settings ( ERRFILE_OTHER | 0x00500000 ) +#define ERRFILE_ntlm ( ERRFILE_OTHER | 0x00510000 ) /** @} */ diff --git a/src/include/ipxe/ntlm.h b/src/include/ipxe/ntlm.h new file mode 100644 index 00000000..b0436c9a --- /dev/null +++ b/src/include/ipxe/ntlm.h @@ -0,0 +1,199 @@ +#ifndef _IPXE_NTLM_H +#define _IPXE_NTLM_H + +/** @file + * + * NT LAN Manager (NTLM) authentication + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include + +/** A message header */ +struct ntlm_header { + /** Magic signature */ + uint8_t magic[8]; + /** Message type */ + uint32_t type; +} __attribute__ (( packed )); + +/** Magic signature */ +#define NTLM_MAGIC { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0' } + +/** Message types */ +enum ntlm_type { + /** Negotiate message type */ + NTLM_NEGOTIATE = 0x00000001UL, + /** Challenge message type */ + NTLM_CHALLENGE = 0x00000002UL, + /** Authenticate message */ + NTLM_AUTHENTICATE = 0x00000003UL, +}; + +/** Negotiation flags */ +enum ntlm_flags { + /** Negotiate key exchange */ + NTLM_NEGOTIATE_KEY_EXCH = 0x20000000UL, + /** Negotiate extended security */ + NTLM_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000UL, + /** Negotiate always sign */ + NTLM_NEGOTIATE_ALWAYS_SIGN = 0x00008000UL, + /** Negotiate NTLM key */ + NTLM_NEGOTIATE_NTLM = 0x00000200UL, + /** Request target name and information */ + NTLM_REQUEST_TARGET = 0x00000004UL, + /** Negotiate Unicode character encoding */ + NTLM_NEGOTIATE_UNICODE = 0x00000001UL, +}; + +/** A version descriptor */ +struct ntlm_version { + /** Product major version */ + uint8_t major; + /** Product minor version */ + uint8_t minor; + /** Product build number */ + uint16_t build; + /** Reserved */ + uint8_t reserved[3]; + /** NTLMSSP revision */ + uint8_t revision; +} __attribute__ (( packed )); + +/** A nonce */ +struct ntlm_nonce { + /** Raw bytes */ + uint8_t raw[8]; +} __attribute__ (( packed )); + +/** A variable-length data descriptor */ +struct ntlm_data { + /** Length (in bytes) */ + uint16_t len; + /** Maximum length (in bytes) + * + * Should always be set equal to the length; this field is + * entirely superfluous. + */ + uint16_t max_len; + /** Offset from start of message header */ + uint32_t offset; +} __attribute__ (( packed )); + +/** A Negotiate message */ +struct ntlm_negotiate { + /** Message header */ + struct ntlm_header header; + /** Negotiation flags */ + uint32_t flags; + /** Domain name */ + struct ntlm_data domain; + /** Workstation name */ + struct ntlm_data workstation; +} __attribute__ (( packed )); + +/** A Challenge message */ +struct ntlm_challenge { + /** Message header */ + struct ntlm_header header; + /** Target name */ + struct ntlm_data name; + /** Negotiation flags */ + uint32_t flags; + /** Server nonce */ + struct ntlm_nonce nonce; + /** Reserved */ + uint8_t reserved[8]; + /** Target information */ + struct ntlm_data info; +} __attribute__ (( packed )); + +/** An Authenticate message */ +struct ntlm_authenticate { + /** Message header */ + struct ntlm_header header; + /** LAN Manager response */ + struct ntlm_data lm; + /** NT response */ + struct ntlm_data nt; + /** Domain name */ + struct ntlm_data domain; + /** User name */ + struct ntlm_data user; + /** Workstation name */ + struct ntlm_data workstation; + /** Session key */ + struct ntlm_data session; + /** Negotiation flags */ + uint32_t flags; +} __attribute__ (( packed )); + +/** A LAN Manager response */ +struct ntlm_lm_response { + /** HMAC-MD5 digest */ + uint8_t digest[MD5_DIGEST_SIZE]; + /** Client nonce */ + struct ntlm_nonce nonce; +} __attribute__ (( packed )); + +/** An NT response */ +struct ntlm_nt_response { + /** HMAC-MD5 digest */ + uint8_t digest[MD5_DIGEST_SIZE]; + /** Response version */ + uint8_t version; + /** Highest response version */ + uint8_t high; + /** Reserved */ + uint8_t reserved_a[6]; + /** Current time */ + uint64_t time; + /** Client nonce */ + struct ntlm_nonce nonce; + /** Must be zero */ + uint32_t zero; +} __attribute__ (( packed )); + +/** NTLM version */ +#define NTLM_VERSION_NTLMV2 0x01 + +/** NTLM challenge information */ +struct ntlm_challenge_info { + /** Server nonce */ + struct ntlm_nonce *nonce; + /** Target information */ + void *target; + /** Length of target information */ + size_t len; +}; + +/** An NTLM verification key */ +struct ntlm_key { + /** Raw bytes */ + uint8_t raw[MD5_DIGEST_SIZE]; +}; + +extern const struct ntlm_negotiate ntlm_negotiate; +extern int ntlm_challenge ( struct ntlm_challenge *challenge, size_t len, + struct ntlm_challenge_info *info ); +extern void ntlm_key ( const char *domain, const char *username, + const char *password, struct ntlm_key *key ); +extern void ntlm_response ( struct ntlm_challenge_info *info, + struct ntlm_key *key, struct ntlm_nonce *nonce, + struct ntlm_lm_response *lm, + struct ntlm_nt_response *nt ); +extern size_t ntlm_authenticate ( struct ntlm_challenge_info *info, + const char *domain, const char *username, + const char *workstation, + struct ntlm_lm_response *lm, + struct ntlm_nt_response *nt, + struct ntlm_authenticate *auth ); +extern size_t ntlm_authenticate_len ( struct ntlm_challenge_info *info, + const char *domain, const char *username, + const char *workstation ); + +#endif /* _IPXE_NTLM_H */ -- cgit v1.2.3-55-g7522