Browse Source

[http] Allow for domain names within NTLM user names

Allow a NetBIOS domain name to be specified within a URL using a
syntax such as:

  http://domain%5Cusername:password@server/path

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
6737a8795f
3 changed files with 112 additions and 3 deletions
  1. 60
    0
      src/core/netbios.c
  2. 30
    0
      src/include/ipxe/netbios.h
  3. 22
    3
      src/net/tcp/httpntlm.c

+ 60
- 0
src/core/netbios.c View File

@@ -0,0 +1,60 @@
1
+/*
2
+ * Copyright (C) 2018 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ *
19
+ * You can also choose to distribute this program under the terms of
20
+ * the Unmodified Binary Distribution Licence (as given in the file
21
+ * COPYING.UBDL), provided that you have satisfied its requirements.
22
+ */
23
+
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
+
26
+/** @file
27
+ *
28
+ * NetBIOS user names
29
+ *
30
+ */
31
+
32
+#include <stddef.h>
33
+#include <string.h>
34
+#include <ipxe/netbios.h>
35
+
36
+/**
37
+ * Split NetBIOS [domain\]username into separate domain and username fields
38
+ *
39
+ * @v username		NetBIOS [domain\]username string
40
+ * @ret domain		Domain portion of string, or NULL if no domain present
41
+ *
42
+ * This function modifies the original string by removing the
43
+ * separator.  The caller may restore the string using
44
+ * netbios_domain_undo().
45
+ */
46
+const char * netbios_domain ( char **username ) {
47
+	char *domain_username = *username;
48
+	char *sep;
49
+
50
+	/* Find separator, if present */
51
+	sep = strchr ( domain_username, '\\' );
52
+	if ( ! sep )
53
+		return NULL;
54
+
55
+	/* Overwrite separator with NUL terminator and update username string */
56
+	*sep = '\0';
57
+	*username = ( sep + 1 );
58
+
59
+	return domain_username;
60
+}

+ 30
- 0
src/include/ipxe/netbios.h View File

@@ -0,0 +1,30 @@
1
+#ifndef _IPXE_NETBIOS_H
2
+#define _IPXE_NETBIOS_H
3
+
4
+/** @file
5
+ *
6
+ * NetBIOS user names
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
+
12
+extern const char * netbios_domain ( char **username );
13
+
14
+/**
15
+ * Restore NetBIOS [domain\]username
16
+ *
17
+ * @v domain		NetBIOS domain name
18
+ * @v username		NetBIOS user name
19
+ *
20
+ * Restore the separator in a NetBIOS [domain\]username as split by
21
+ * netbios_domain().
22
+ */
23
+static inline void netbios_domain_undo ( const char *domain, char *username ) {
24
+
25
+	/* Restore separator, if applicable */
26
+	if ( domain )
27
+		username[-1] = '\\';
28
+}
29
+
30
+#endif /* _IPXE_NETBIOS_H */

+ 22
- 3
src/net/tcp/httpntlm.c View File

@@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
35 35
 #include <ipxe/uri.h>
36 36
 #include <ipxe/base64.h>
37 37
 #include <ipxe/ntlm.h>
38
+#include <ipxe/netbios.h>
38 39
 #include <ipxe/http.h>
39 40
 
40 41
 struct http_authentication http_ntlm_auth __http_authentication;
@@ -113,6 +114,8 @@ static int http_ntlm_authenticate ( struct http_transaction *http ) {
113 114
 	struct http_request_auth_ntlm *req = &http->request.auth.ntlm;
114 115
 	struct http_response_auth_ntlm *rsp = &http->response.auth.ntlm;
115 116
 	struct ntlm_key key;
117
+	const char *domain;
118
+	char *username;
116 119
 	const char *password;
117 120
 
118 121
 	/* If we have no challenge yet, then just send a Negotiate message */
@@ -130,16 +133,23 @@ static int http_ntlm_authenticate ( struct http_transaction *http ) {
130 133
 	req->username = http->uri->user;
131 134
 	password = ( http->uri->password ? http->uri->password : "" );
132 135
 
136
+	/* Split NetBIOS [domain\]username */
137
+	username = ( ( char * ) req->username );
138
+	domain = netbios_domain ( &username );
139
+
133 140
 	/* Generate key */
134
-	ntlm_key ( NULL, req->username, password, &key );
141
+	ntlm_key ( domain, username, password, &key );
135 142
 
136 143
 	/* Generate responses */
137 144
 	ntlm_response ( &rsp->info, &key, NULL, &req->lm, &req->nt );
138 145
 
139 146
 	/* Calculate Authenticate message length */
140
-	req->len = ntlm_authenticate_len ( &rsp->info, NULL, req->username,
147
+	req->len = ntlm_authenticate_len ( &rsp->info, domain, username,
141 148
 					   http_ntlm_workstation );
142 149
 
150
+	/* Restore NetBIOS [domain\]username */
151
+	netbios_domain_undo ( domain, username );
152
+
143 153
 	return 0;
144 154
 }
145 155
 
@@ -156,6 +166,8 @@ static int http_format_ntlm_auth ( struct http_transaction *http,
156 166
 	struct http_request_auth_ntlm *req = &http->request.auth.ntlm;
157 167
 	struct http_response_auth_ntlm *rsp = &http->response.auth.ntlm;
158 168
 	struct ntlm_authenticate *auth;
169
+	const char *domain;
170
+	char *username;
159 171
 	size_t check;
160 172
 
161 173
 	/* If we have no challenge yet, then just send a Negotiate message */
@@ -173,12 +185,19 @@ static int http_format_ntlm_auth ( struct http_transaction *http,
173 185
 	if ( ! auth )
174 186
 		return -ENOMEM;
175 187
 
188
+	/* Split NetBIOS [domain\]username */
189
+	username = ( ( char * ) req->username );
190
+	domain = netbios_domain ( &username );
191
+
176 192
 	/* Construct raw Authenticate message */
177
-	check = ntlm_authenticate ( &rsp->info, NULL, req->username,
193
+	check = ntlm_authenticate ( &rsp->info, domain, username,
178 194
 				    http_ntlm_workstation, &req->lm,
179 195
 				    &req->nt, auth );
180 196
 	assert ( check == req->len );
181 197
 
198
+	/* Restore NetBIOS [domain\]username */
199
+	netbios_domain_undo ( domain, username );
200
+
182 201
 	/* Base64-encode Authenticate message */
183 202
 	len = base64_encode ( auth, req->len, buf, len );
184 203
 

Loading…
Cancel
Save