File: ntlm.go

package info (click to toggle)
golang-github-thomsonreuterseikon-go-ntlm 0.0~git20151030.0.b00ec39-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, buster-backports
  • size: 248 kB
  • ctags: 296
  • sloc: makefile: 3
file content (127 lines) | stat: -rw-r--r-- 3,503 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//Copyright 2013 Thomson Reuters Global Resources. BSD License please see License file for more information

// Package NTLM implements the interfaces used for interacting with NTLMv1 and NTLMv2.
// To create NTLM v1 or v2 sessions you would use CreateClientSession and create ClientServerSession.
package ntlm

import (
	rc4P "crypto/rc4"
	"errors"
)

type Version int

const (
	Version1 Version = 1
	Version2 Version = 2
)

type Mode int

const (
	ConnectionlessMode Mode = iota
	ConnectionOrientedMode
)

// Creates an NTLM v1 or v2 client
// mode - This must be ConnectionlessMode or ConnectionOrientedMode depending on what type of NTLM is used
// version - This must be Version1 or Version2 depending on the version of NTLM used
func CreateClientSession(version Version, mode Mode) (n ClientSession, err error) {
	switch version {
	case Version1:
		n = new(V1ClientSession)
	case Version2:
		n = new(V2ClientSession)
	default:
		return nil, errors.New("Unknown NTLM Version, must be 1 or 2")
	}

	return n, nil
}

type ClientSession interface {
	SetUserInfo(username string, password string, domain string)
	SetMode(mode Mode)

	GenerateNegotiateMessage() (*NegotiateMessage, error)
	ProcessChallengeMessage(*ChallengeMessage) error
	GenerateAuthenticateMessage() (*AuthenticateMessage, error)

	Seal(message []byte) ([]byte, error)
	Sign(message []byte) ([]byte, error)
	Mac(message []byte, sequenceNumber int) ([]byte, error)
	VerifyMac(message, expectedMac []byte, sequenceNumber int) (bool, error)
}

// Creates an NTLM v1 or v2 server
// mode - This must be ConnectionlessMode or ConnectionOrientedMode depending on what type of NTLM is used
// version - This must be Version1 or Version2 depending on the version of NTLM used
func CreateServerSession(version Version, mode Mode) (n ServerSession, err error) {
	switch version {
	case Version1:
		n = new(V1ServerSession)
	case Version2:
		n = new(V2ServerSession)
	default:
		return nil, errors.New("Unknown NTLM Version, must be 1 or 2")
	}

	n.SetMode(mode)
	return n, nil
}

type ServerSession interface {
	SetUserInfo(username string, password string, domain string)
	GetUserInfo() (string, string, string)

	SetMode(mode Mode)
	SetServerChallenge(challege []byte)

	ProcessNegotiateMessage(*NegotiateMessage) error
	GenerateChallengeMessage() (*ChallengeMessage, error)
	ProcessAuthenticateMessage(*AuthenticateMessage) error

	GetSessionData() *SessionData

	Version() int
	Seal(message []byte) ([]byte, error)
	Sign(message []byte) ([]byte, error)
	Mac(message []byte, sequenceNumber int) ([]byte, error)
	VerifyMac(message, expectedMac []byte, sequenceNumber int) (bool, error)
}

// This struct collects NTLM data structures and keys that are used across all types of NTLM requests
type SessionData struct {
	mode Mode

	user       string
	password   string
	userDomain string

	NegotiateFlags uint32

	negotiateMessage    *NegotiateMessage
	challengeMessage    *ChallengeMessage
	authenticateMessage *AuthenticateMessage

	serverChallenge     []byte
	clientChallenge     []byte
	ntChallengeResponse []byte
	lmChallengeResponse []byte

	responseKeyLM             []byte
	responseKeyNT             []byte
	exportedSessionKey        []byte
	encryptedRandomSessionKey []byte
	keyExchangeKey            []byte
	sessionBaseKey            []byte
	mic                       []byte

	ClientSigningKey []byte
	ServerSigningKey []byte
	ClientSealingKey []byte
	ServerSealingKey []byte

	clientHandle *rc4P.Cipher
	serverHandle *rc4P.Cipher
}