| /* |
| * Copyright (c) Edward Thomson. All rights reserved. |
| * |
| * This file is part of ntlmclient, distributed under the MIT license. |
| * For full terms and copyright information, and for third-party |
| * copyright information, see the included LICENSE.txt file. |
| */ |
| #ifndef INCLUDE_NTLMCLIENT_H__ |
| #define INCLUDE_NTLMCLIENT_H__ |
| |
| #include <stdlib.h> |
| #include <stdint.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define NTLM_CLIENT_VERSION "0.0.1" |
| #define NTLM_CLIENT_VERSION_MAJOR 0 |
| #define NTLM_CLIENT_VERSION_MINOR 0 |
| #define NTLM_CLIENT_VERSION_TEENY 1 |
| |
| typedef struct ntlm_client ntlm_client; |
| |
| /* |
| * Flags for initializing the `ntlm_client` context. A combination of |
| * these flags can be provided to `ntlm_client_init`. |
| */ |
| typedef enum { |
| /** Default settings for the `ntlm_client`. */ |
| NTLM_CLIENT_DEFAULTS = 0, |
| |
| /** |
| * Disable Unicode negotiation. By default, strings are converted |
| * into UTF-16 when supplied to the remote host, but if this flag |
| * is specified, localizable strings (like username and password) |
| * will only be sent to the server as they were provided to the |
| * library. Since the NTLM protocol does not deliver the locale |
| * information, these will be interpreted by the remote host in |
| * whatever locale is configured, and likely be corrupted unless |
| * you limit yourself to ASCII. |
| * |
| * You are discouraged from setting this flag. |
| */ |
| NTLM_CLIENT_DISABLE_UNICODE = (1 << 0), |
| |
| /* |
| * Enable LM ("Lan Manager") authentication support. By default, |
| * LM authentication is disabled, since most remote servers have |
| * disabled support for it, and because it is both trivially |
| * brute-forced _and_ subject to rainbow table lookups. If this |
| * flag is enabled, LM is still not used unless NTLM2 support is |
| * also disabled. |
| * |
| * You are discouraged from setting this flag. |
| */ |
| NTLM_CLIENT_ENABLE_LM = (1 << 1), |
| |
| /* |
| * Enable NTLM ("Lan Manager") authentication support. By default, |
| * NTLM authentication is disabled, since most remote servers have |
| * disabled support for it, due to its weakness. If this flag is |
| * enabled, NTLM is still not used unless NTLM2 support is also |
| * disabled. |
| * |
| * You are discouraged from setting this flag. |
| */ |
| NTLM_CLIENT_ENABLE_NTLM = (1 << 2), |
| |
| /* |
| * Disable NTLM2 authentication support. By default, _only_ NTLM2 |
| * support is enabled, since most remote servers will only support |
| * it due to its (relative) lack of weakness. If this flag is |
| * set, either NTLM or LM (or both) must be explicitly enabled or |
| * there will be no mechanisms available to use. |
| * |
| * You are discouraged from setting this flag. |
| */ |
| NTLM_CLIENT_DISABLE_NTLM2 = (1 << 3), |
| |
| /* |
| * Request the target's name. By default, you are expected to |
| * provide the name of the target you are authenticating to (eg, |
| * the remote hostname). If set, the remote host will provide |
| * its idea of its hostname in the challenge message. You may |
| * then set the authentication target based on it. |
| */ |
| NTLM_CLIENT_DISABLE_REQUEST_TARGET = (1 << 4), |
| } ntlm_client_flags; |
| |
| |
| /** Declare a public function exported for application use. */ |
| #if __GNUC__ >= 4 && !defined(NTLM_STATIC) |
| # define NTLM_EXTERN(type) extern \ |
| __attribute__((visibility("default"))) \ |
| type |
| #elif defined(_MSC_VER) && !defined(NTLM_STATIC) |
| # define NTLM_EXTERN(type) __declspec(dllexport) type |
| #else |
| # define NTLM_EXTERN(type) extern type |
| #endif |
| |
| /** |
| * Initializes an `ntlm_client` context, which can begin sending |
| * and receiving NTLM authentication messages. |
| * |
| * @param flags the `ntlm_client_flag_t`s to use for negotiation. |
| * @return the `ntlm_client` context, or `NULL` if out-of-memory. |
| */ |
| NTLM_EXTERN(ntlm_client *) ntlm_client_init(ntlm_client_flags flags); |
| |
| /** |
| * Gets the error message for the most recent error that occurred. If |
| * a function returns an error, more details can be retrieved with this |
| * function. The string returned is a constant string; it should not |
| * be freed. |
| * |
| * @return a constant string containing the error message. |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_errmsg(ntlm_client *ntlm); |
| |
| /** |
| * Sets the local hostname and domain. These strings should be in |
| * ASCII. They will be provided to the remote host during the |
| * negotiation phase. |
| * |
| * @param ntlm the `ntlm_client` context to configure |
| * @param hostname the hostname of the local machine |
| * @param domain the domain of the local machine |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_set_hostname( |
| ntlm_client *ntlm, |
| const char *hostname, |
| const char *domain); |
| |
| /** |
| * Sets the local operating system version. These numbers are expected |
| * to correspond to Windows operating system versions; for example |
| * major version 6, minor version 2, build 9200 would correspond to |
| * Windows 8 (aka "NT 6.2"). |
| * |
| * It is not likely that you need to set the local version. |
| * |
| * @param ntlm the `ntlm_client` context to configure |
| * @param major the major version number of the local operating system |
| * @param minor the minor version number of the local operating system |
| * @param build the build number of the local operating system |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_set_version( |
| ntlm_client *ntlm, |
| uint8_t major, |
| uint8_t minor, |
| uint16_t build); |
| |
| /** |
| * Sets the username and password to authenticate with to the remote |
| * host. Username and password may be specified in UTF-8 but the |
| * domain should be in ASCII. These will not be sent to the remote host |
| * but will instead be used to compute the LM, NTLM or NTLM2 responses, |
| * which will be provided to the remote host during the response phase. |
| * |
| * @param ntlm the `ntlm_client` context to configure |
| * @param username the username to authenticate with |
| * @param domain the domain of the user authenticating |
| * @param password the password to authenticate with |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_set_credentials( |
| ntlm_client *ntlm, |
| const char *username, |
| const char *domain, |
| const char *password); |
| |
| /** |
| * Sets the authentication target, your idea of the remote host's |
| * name. The target should be provided as ASCII. It will be |
| * provided to the remote host during the response phase. |
| * |
| * @param ntlm the `ntlm_client` context to configure |
| * @param target the name of the authentication target |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_set_target( |
| ntlm_client *ntlm, |
| const char *target); |
| |
| /** |
| * Gets the remote host's nonce, as it was provided in the challenge |
| * message. This is an opaque 8 byte value that is used to compute |
| * the LM, NTLM and NTLM2 responses. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the challenge from the remote host |
| */ |
| NTLM_EXTERN(uint64_t) ntlm_client_challenge_nonce( |
| ntlm_client *ntlm); |
| |
| /** |
| * Gets the remote hosts's target name, which can be used as the |
| * authentication target. This will be given as it was provided |
| * in the challenge message. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the remote host's target name |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_target(ntlm_client *ntlm); |
| |
| /** |
| * Gets the remote hosts's name, which is generally its short name. |
| * This will be given as it was provided in the challenge message. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the remote host's server name |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_target_server(ntlm_client *ntlm); |
| |
| /** |
| * Gets the remote hosts's domain, which is generally the short or |
| * NT-style domain name. This will be given as it was provided in |
| * the challenge message. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the remote host's domain |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_target_domain(ntlm_client *ntlm); |
| |
| /** |
| * Gets the remote hosts's DNS name, which is generally the long-style |
| * Active Directory or fully-qualified hostname. This will be given |
| * as it was provided in the challenge message. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the remote host's DNS name |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_target_server_dns(ntlm_client *ntlm); |
| |
| /** |
| * Gets the remote hosts's DNS domain, which is generally the long-style |
| * Active Directory or fully-qualified domain name. This will be given |
| * as it was provided in the challenge message. |
| * |
| * @param ntlm the `ntlm_client` context to query |
| * @return the remote host's DNS domain |
| */ |
| NTLM_EXTERN(const char *) ntlm_client_target_domain_dns(ntlm_client *ntlm); |
| |
| /** |
| * Computes a negotiation message (aka a "Type 1" message) to begin |
| * NTLM authentication with the server. The local hostname should be |
| * set before calling this function (if necessary). This message |
| * should be delivered to the server to indicate a willingness to begin |
| * NTLM authentication. This buffer should not be freed by the caller. |
| * |
| * @param out a pointer to the negotiation message |
| * @param out_len a pointer to the length of the negotiation message |
| * @param ntlm the `ntlm_client` context |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_negotiate( |
| const unsigned char **out, |
| size_t *out_len, |
| ntlm_client *ntlm); |
| |
| /** |
| * Parses a challenge message (aka a "Type 2" message) from the server. |
| * This must be called in order to calculate the response to the |
| * authentication. |
| * |
| * @param ntlm the `ntlm_client` context |
| * @param message the challenge message from the server |
| * @param message_len the length of the challenge message |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_set_challenge( |
| ntlm_client *ntlm, |
| const unsigned char *message, |
| size_t message_len); |
| |
| /** |
| * Computes a response message (aka a "Type 3" message) to complete |
| * NTLM authentication with the server. The credentials should be |
| * set before calling this function. This message should be delivered |
| * to the server to complete authentication. This buffer should not |
| * be freed by the caller. |
| * |
| * @param out a pointer to the response message |
| * @param out_len a pointer to the length of the response message |
| * @param ntlm the `ntlm_client` context |
| * @return 0 on success, non-zero on failure |
| */ |
| NTLM_EXTERN(int) ntlm_client_response( |
| const unsigned char **out, |
| size_t *out_len, |
| ntlm_client *ntlm); |
| |
| /** |
| * Resets an `ntlm_client` context completely, so that authentication |
| * may be retried. You must set _all_ parameters again, including the |
| * target, username, password, etc. Once these values are configured |
| * again, the negotiation can begin. |
| * |
| * @param ntlm the `ntlm_client` context to reset |
| */ |
| NTLM_EXTERN(void) ntlm_client_reset(ntlm_client *ntlm); |
| |
| /** |
| * Frees an `ntlm_client` context. This should be done to free memory |
| * belonging to the context. The context cannot be reused. |
| * |
| * @param ntlm the `ntlm_client` context to free |
| */ |
| NTLM_EXTERN(void) ntlm_client_free(ntlm_client *ntlm); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* INCLUDE_NTLMCLIENT_H__ */ |