Skip to content

Commit 664a52b

Browse files
committed
Merge pull request #6 from Rican7/bugfix/user-principal-name-username-empty-targetname
Bugfix - User Principal Name (UPN) usernames should send up an empty "TargetName" in the authentication message
2 parents 1a1da88 + 9960069 commit 664a52b

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

src/Robin/Ntlm/Message/AbstractAuthenticateMessageEncoder.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ abstract class AbstractAuthenticateMessageEncoder implements AuthenticateMessage
6969
*/
7070
const LM_RESPONSE_LENGTH = 24;
7171

72+
/**
73+
* The separator used in usernames in the UPN (User Principal Name) format.
74+
*
75+
* @type string
76+
*/
77+
const USER_PRINCIPAL_NAME_SEPARATOR = '@';
78+
7279

7380
/**
7481
* Properties
@@ -97,6 +104,35 @@ protected function __construct(EncodingConverterInterface $encoding_converter)
97104
$this->encoding_converter = $encoding_converter;
98105
}
99106

107+
/**
108+
* Identifies the "TargetName" of the intended authentication by inspecting
109+
* some of the authentication details.
110+
*
111+
* @param string $username The user's "username".
112+
* @param string $nt_domain The domain name of the NT user authenticating.
113+
* @param ServerChallenge $server_challenge The value of a decoded NTLM
114+
* server's "CHALLENGE_MESSAGE".
115+
* @return string The identified "TargetName" (domain/server name) of the
116+
* NT user authenticating.
117+
*/
118+
public function identifyTargetName($username, $nt_domain, ServerChallenge $server_challenge)
119+
{
120+
// If a domain name wasn't supplied, fall back to the server challenge's supplied value
121+
$target_name = $nt_domain ?: $server_challenge->getTargetName();
122+
123+
/**
124+
* If the username is in the "UPN" (Kerberos) format, the target name should be empty
125+
*
126+
* @link https://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx
127+
* @link http://davenport.sourceforge.net/ntlm.html#nameVariations
128+
*/
129+
if (false !== strpos($username, static::USER_PRINCIPAL_NAME_SEPARATOR)) {
130+
$target_name = '';
131+
}
132+
133+
return $target_name;
134+
}
135+
100136
/**
101137
* Encodes the binary "AUTHENTICATE_MESSAGE" string from its provided parts.
102138
*

src/Robin/Ntlm/Message/NtlmV1AuthenticateMessageEncoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function encode(
159159
) {
160160
$negotiate_flags = $server_challenge->getNegotiateFlags();
161161
$server_challenge_nonce = $server_challenge->getNonce();
162-
$target_name = $nt_domain ?: $server_challenge->getTargetName();
162+
$target_name = $this->identifyTargetName($username, $nt_domain, $server_challenge);
163163

164164
$client_challenge = null;
165165

src/Robin/Ntlm/Message/NtlmV2AuthenticateMessageEncoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public function encode(
138138
$negotiate_flags = $server_challenge->getNegotiateFlags();
139139
$server_challenge_nonce = $server_challenge->getNonce();
140140
$target_info = $server_challenge->getTargetInfo();
141-
$target_name = $nt_domain ?: $server_challenge->getTargetName();
141+
$target_name = $this->identifyTargetName($username, $nt_domain, $server_challenge);
142142

143143
// Generate a client challenge
144144
$client_challenge = $this->random_byte_generator->generate(static::CLIENT_CHALLENGE_LENGTH);

0 commit comments

Comments
 (0)