ntlmssp

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2025 License: MIT Imports: 15 Imported by: 271

README

go-ntlmssp

Go Reference Test

Go package that provides NTLM/Negotiate authentication over HTTP

This package only implements authentication, no key exchange or encryption. It only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding. This package implements NTLMv2.

Installation

To install the package, use go get:

go get github.com/Azure/go-ntlmssp

Usage

url, user, password := "http://www.example.com/secrets", "robpike", "pw123"
client := &http.Client{
  Transport: ntlmssp.Negotiator{
    RoundTripper: &http.Transport{},
  },
}

req, _ := http.NewRequest("GET", url, nil)
req.SetBasicAuth(user, password)
res, _ := client.Do(req)

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Documentation

Overview

Protocol details from https://msdn.microsoft.com/en-us/library/cc236621.aspx, implementation hints from http://davenport.sourceforge.net/ntlm.html . This package only implements authentication, no key exchange or encryption. It only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding. This package implements NTLMv2.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetDomain deprecated

func GetDomain(username string) (user string, domain string, domainNeeded bool)

GetDomain extracts the user domain from the username if present.

Deprecated: Pass the username directly to ProcessChallenge, it will handle domain extraction. Don't pass the resulting domain to NewNegotiateMessage, that function expects the client machine domain, not the user domain.

func NewAuthenticateMessage added in v0.1.0

func NewAuthenticateMessage(challenge []byte, username, password string, options *AuthenticateMessageOptions) ([]byte, error)

NewAuthenticateMessage creates a new AUTHENTICATE message in response to the CHALLENGE message that was received from the server. The options parameter allows specifying additional settings for the message, it can be nil to use defaults.

func NewNegotiateMessage

func NewNegotiateMessage(domain, workstation string) ([]byte, error)

NewNegotiateMessage creates a new NEGOTIATE message with the flags that this package supports. Note that domain and workstation refer to the client machine, not the user that is authenticating. It is recommended to leave them empty unless you know which are their correct values.

The server may ignore these values, or may use them to infer that the client if running on the same machine.

func ProcessChallenge deprecated

func ProcessChallenge(challengeMessageData []byte, username, password string, domainNeeded bool) ([]byte, error)

ProcessChallenge crafts an AUTHENTICATE message in response to the CHALLENGE message that was received from the server. DomainNeeded is ignored, as the function extracts the domain from the username if needed.

Deprecated: Use NewAuthenticateMessage instead.

func ProcessChallengeWithHash deprecated

func ProcessChallengeWithHash(challengeMessageData []byte, username, hash string) ([]byte, error)

ProcessChallengeWithHash is like ProcessChallenge but expects the password to be already hashed. The hash should be provided in hexadecimal format.

Deprecated: Use NewAuthenticateMessage with [AuthenticateMessageOptions.PasswordHashed] instead.

Types

type AuthenticateMessageOptions added in v0.1.0

type AuthenticateMessageOptions struct {
	WorkstationName string

	// PasswordHashed indicates whether the provided password is already hashed.
	// If true, the password is expected to be in hexadecimal format.
	PasswordHashed bool
}

AuthenticateMessageOptions contains optional parameters for the Authenticate message.

type Negotiator

type Negotiator struct {
	// RoundTripper is the underlying round tripper to use.
	// If nil, http.DefaultTransport is used.
	http.RoundTripper

	// AllowBasicAuth controls whether to send Basic authentication credentials
	// if the server requests it.
	//
	// If false (default), Basic authentication requests are ignored
	// and only NTLM/Negotiate authentication is performed.
	// If true, Basic authentication requests are honored.
	//
	// Only set this to true if you trust the server you are connecting to.
	// Basic authentication sends the credentials in clear text and may be
	// vulnerable to man-in-the-middle attacks and compromised servers.
	AllowBasicAuth bool

	// WorkstationDomain is the domain of the client machine.
	// It is normally not needed to set this field.
	// It is passed to the negotiate message.
	WorkstationDomain string

	// WorkstationName is the workstation name of the client machine.
	// It is passed to the negotiate and authenticate messages.
	// Useful for auditing purposes on the server side.
	WorkstationName string
}

Negotiator is a net/http.RoundTripper decorator that automatically converts basic authentication to NTLM/Negotiate authentication when appropriate.

The credentials must be set using net/http.Request.SetBasicAuth on a per-request basis.

By default, no credentials will be sent to the server unless it requests Basic authentication and [Negotiator.AllowBasicAuth] is set to true.

Example

ExampleNegotiator demonstrates basic HTTPS authentication using NTLM. The library works the same way with HTTP - just use http:// URLs instead.

url := "https://ntlm-protected-server.example.com/resource"
username := "DOMAIN\\username" // or "username@domain.com" for UPN format
password := "your-password"

client := &http.Client{
	Transport: ntlmssp.Negotiator{},
}

req, err := http.NewRequest("GET", url, nil)
if err != nil {
	log.Fatal(err)
}

// Set basic auth credentials - these will be automatically converted to NTLM
req.SetBasicAuth(username, password)

resp, err := client.Do(req)
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()

fmt.Printf("Status: %s\n", resp.Status)
Example (CustomTLS)

ExampleNegotiator_customTLS demonstrates HTTPS authentication with custom TLS configuration.

url := "https://ntlm-protected-server.example.com/resource"
username := "DOMAIN\\username" // or "username@domain.com" for UPN format
password := "your-password"

client := &http.Client{
	Transport: ntlmssp.Negotiator{
		RoundTripper: &http.Transport{
			TLSClientConfig: &tls.Config{
				MinVersion: tls.VersionTLS12,
			},
		},
	},
}

req, err := http.NewRequest("GET", url, nil)
if err != nil {
	log.Fatal(err)
}

// Set basic auth credentials - these will be automatically converted to NTLM
req.SetBasicAuth(username, password)

resp, err := client.Do(req)
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()

fmt.Printf("Status: %s\n", resp.Status)

func (Negotiator) RoundTrip

func (l Negotiator) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip sends the request to the server, handling any authentication re-sends as needed.

type Version

type Version struct {
	ProductMajorVersion uint8
	ProductMinorVersion uint8
	ProductBuild        uint16

	NTLMRevisionCurrent uint8
	// contains filtered or unexported fields
}

Version is a struct representing https://msdn.microsoft.com/en-us/library/cc236654.aspx

func DefaultVersion

func DefaultVersion() Version

DefaultVersion returns a Version with "sensible" defaults (Windows 7)

Directories

Path Synopsis
internal
md4
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL