Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/aquarela/smbconnect.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "headers.h"
2
 
3
SmbClient *
4
smbconnect(char *to, char *share, char **errmsgp)
5
{
6
	NbSession *nbs;
7
	SmbBuffer *b;
8
	SmbHeader h, rh;
9
	long n;
10
	ushort bytecountfixupoffset;
11
	ushort andxfixupoffset;
12
	uchar *pdata;
13
	SmbPeerInfo peerinfo;
14
	ushort index;
15
	vlong utcintenthsofaus;
16
	ulong secssince1970;
17
	ushort bytecount;
18
	int x;
19
	MSchapreply mschapreply;
20
	NbName nbto;
21
	SmbClient *c;
22
	char namebuf[100];
23
	ushort ipctid, sharetid;
24
 
25
	nbmknamefromstringandtype(nbto, to, 0x20);
26
 
27
	peerinfo.encryptionkey = nil;
28
	peerinfo.oemdomainname = nil;
29
	assert(smbglobals.nbname[0] != 0);
30
	nbs = nbssconnect(nbto, smbglobals.nbname);
31
	if (nbs == nil)
32
		return nil;
33
print("netbios session established\n");
34
	b = smbbuffernew(65535);
35
	memset(&h, 0, sizeof(h));
36
	h.command = SMB_COM_NEGOTIATE;
37
	h.flags2 = SMB_FLAGS2_KNOWS_LONG_NAMES | SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_UNICODE;
38
	h.wordcount = 0;
39
	h.pid = 42;
40
	smbbufferputheader(b, &h, &peerinfo);
41
	bytecountfixupoffset = smbbufferwriteoffset(b);
42
	smbbufferputbytes(b, nil, 2);
43
	smbbufferputb(b, 2);
44
	smbbufferputstring(b, nil, SMB_STRING_ASCII, "NT LM 0.12");
45
	smbbufferoffsetputs(b, bytecountfixupoffset, smbbufferwriteoffset(b) - bytecountfixupoffset - 2);
46
	nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
47
	nbsswrite(nbs, smbbufferreadpointer(b), smbbufferwriteoffset(b));
48
	/*
49
	 * now receive a reply
50
	 */
51
	smbbufferreset(b);
52
	n = nbssread(nbs, smbbufferwritepointer(b), smbbufferwritespace(b));
53
	if (n < 0) {
54
		smbstringprint(errmsgp, "smbconnect: read error: %r");
55
		goto fail;
56
	}
57
	smbbuffersetreadlen(b, n);
58
	nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
59
	if (!smbbuffergetandcheckheader(b, &rh, h.command, 1, &pdata, &bytecount, errmsgp))
60
		goto fail;
61
	if (!smbsuccess(&rh, errmsgp))
62
		goto fail;
63
	if (rh.wordcount == 0) {
64
		smbstringprint(errmsgp, "no parameters in negotiate response");
65
		goto fail;
66
	}
67
	index = smbnhgets(pdata); pdata += 2;
68
	if (index != 0) {
69
		smbstringprint(errmsgp, "no agreement on protocol");
70
		goto fail;
71
	}
72
	if (rh.wordcount != 17) {
73
		smbstringprint(errmsgp, "wrong number of parameters for negotiate response");
74
		goto fail;
75
	}
76
	peerinfo.securitymode = *pdata++;
77
	peerinfo.maxmpxcount = smbnhgets(pdata); pdata += 2;
78
	peerinfo.maxnumbervcs = smbnhgets(pdata); pdata += 2;
79
	peerinfo.maxbuffersize = smbnhgetl(pdata); pdata += 4;
80
	peerinfo.maxrawsize = smbnhgetl(pdata); pdata += 4;
81
	peerinfo.sessionkey = smbnhgets(pdata); pdata += 4;
82
	peerinfo.capabilities = smbnhgets(pdata); pdata += 4;
83
	utcintenthsofaus = smbnhgetv(pdata); pdata += 8;
84
	secssince1970 = utcintenthsofaus / 10000000 - 11644473600LL;
85
	peerinfo.utc =  (vlong)secssince1970 * (vlong)1000000000 + (utcintenthsofaus % 10000000) * 100;
86
	peerinfo.tzoff = -smbnhgets(pdata) * 60; pdata += 2;
87
	peerinfo.encryptionkeylength = *pdata++;
88
	print("securitymode: 0x%.2ux\n", peerinfo.securitymode);
89
	print("maxmpxcount: 0x%.4ux\n", peerinfo.maxmpxcount);
90
	print("maxnumbervcs: 0x%.4ux\n", peerinfo.maxnumbervcs);
91
	print("maxbuffersize: 0x%.8lux\n", peerinfo.maxbuffersize);
92
	print("maxrawsize: 0x%.8lux\n", peerinfo.maxrawsize);
93
	print("sessionkey: 0x%.8lux\n", peerinfo.sessionkey);
94
	print("capabilities: 0x%.8lux\n", peerinfo.capabilities);
95
	print("utc: %s(and %lld μs)\n", asctime(gmtime(peerinfo.utc / 1000000000)), peerinfo.utc % 1000000000);
96
	print("tzoff: %d\n", peerinfo.tzoff);
97
	print("encryptionkeylength: %d\n", peerinfo.encryptionkeylength);
98
	smberealloc(&peerinfo.encryptionkey, peerinfo.encryptionkeylength);
99
	if (!smbbuffergetbytes(b, peerinfo.encryptionkey, peerinfo.encryptionkeylength)) {
100
		smbstringprint(errmsgp, "not enough data for encryption key");
101
		goto fail;
102
	}
103
	print("encryptionkey: ");
104
	for (x = 0; x < peerinfo.encryptionkeylength; x++)
105
		print("%.2ux", peerinfo.encryptionkey[x]);
106
	print("\n");
107
	if (!smbbuffergetucs2(b, 0, &peerinfo.oemdomainname)) {
108
		smbstringprint(errmsgp, "not enough data for oemdomainname");
109
		goto fail;
110
	}
111
	print("oemdomainname: %s\n", peerinfo.oemdomainname);
112
	if (peerinfo.capabilities & CAP_EXTENDED_SECURITY) {
113
		smbstringprint(errmsgp, "server wants extended security");
114
		goto fail;
115
	}
116
	/*
117
	 * ok - now send SMB_COM_SESSION_SETUP_ANDX
118
	 * fix the flags to reflect what the peer can do
119
	 */
120
	smbbufferreset(b);
121
	h.command = SMB_COM_SESSION_SETUP_ANDX;
122
	h.wordcount = 13;
123
	h.flags2 &= ~SMB_FLAGS2_UNICODE;
124
	if (smbsendunicode(&peerinfo))
125
		h.flags2 |= SMB_FLAGS2_UNICODE;
126
	smbbufferputheader(b, &h, &peerinfo);
127
	smbbufferputb(b, SMB_COM_TREE_CONNECT_ANDX);
128
	smbbufferputb(b, 0);
129
	andxfixupoffset = smbbufferwriteoffset(b);
130
	smbbufferputs(b, 0);
131
	smbbufferputs(b, 0xffff);
132
	smbbufferputs(b, 1);
133
	smbbufferputs(b, 0);
134
	smbbufferputl(b, peerinfo.sessionkey);
135
	smbbufferputs(b, sizeof(mschapreply.LMresp));
136
	smbbufferputs(b, sizeof(mschapreply.NTresp));
137
	smbbufferputl(b, 0);
138
	smbbufferputl(b, CAP_UNICODE | CAP_LARGE_FILES);
139
	bytecountfixupoffset = smbbufferwriteoffset(b);
140
	smbbufferputs(b, 0);
141
	if (auth_respond(peerinfo.encryptionkey, peerinfo.encryptionkeylength,
142
		nil, 0,
143
		&mschapreply, sizeof(mschapreply), auth_getkey,
144
		"proto=mschap role=client server=%s", "cher") != sizeof(mschapreply)) {
145
		print("auth_respond failed: %r\n");
146
		goto fail;
147
	}
148
	smbbufferputbytes(b, &mschapreply, sizeof(mschapreply));
149
	smbbufferputstring(b, &peerinfo, 0, smbglobals.accountname);
150
	smbbufferputstring(b, &peerinfo, 0, smbglobals.primarydomain);
151
	smbbufferputstring(b, &peerinfo, 0, smbglobals.nativeos);
152
	smbbufferputstring(b, &peerinfo, 0, "");
153
	smbbufferoffsetputs(b, bytecountfixupoffset, smbbufferwriteoffset(b) - bytecountfixupoffset - 2);
154
	smbbufferalignl2(b, 2);
155
	smbbufferoffsetputs(b, andxfixupoffset, smbbufferwriteoffset(b));
156
	smbbufferputb(b, 4);
157
	smbbufferputb(b, SMB_COM_NO_ANDX_COMMAND);
158
	smbbufferputb(b, 0);
159
	smbbufferputs(b, 0);
160
	smbbufferputs(b, 0);
161
	smbbufferputs(b, 0);
162
	bytecountfixupoffset = smbbufferwriteoffset(b);
163
	smbbufferputs(b, 0);
164
	strcpy(namebuf, "\\\\");
165
	strcat(namebuf, to);
166
	strcat(namebuf, "\\IPC$");
167
	smbbufferputstring(b, &peerinfo, SMB_STRING_UPCASE, namebuf);
168
	smbbufferputstring(b, nil, SMB_STRING_ASCII, "?????");
169
	smbbufferoffsetputs(b, bytecountfixupoffset, smbbufferwriteoffset(b) - bytecountfixupoffset - 2);
170
	nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
171
	nbsswrite(nbs, smbbufferreadpointer(b), smbbufferwriteoffset(b));
172
	smbbufferreset(b);
173
	n = nbssread(nbs, smbbufferwritepointer(b), smbbufferwritespace(b));
174
	if (n < 0) {
175
		smbstringprint(errmsgp, "read error: %r");
176
		goto fail;
177
	}
178
	smbbuffersetreadlen(b, n);
179
	nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
180
	if (!smbbuffergetandcheckheader(b, &rh, h.command, 1, &pdata, &bytecount, errmsgp))
181
		goto fail;
182
	if (!smbsuccess(&rh, errmsgp))
183
		goto fail;
184
	h.uid = rh.uid;
185
	ipctid = rh.tid;
186
	/*
187
	 * now do another TREE_CONNECT if needed
188
	 */
189
	if (share) {
190
		smbbufferreset(b);
191
		h.command = SMB_COM_TREE_CONNECT_ANDX;
192
		h.wordcount = 4;
193
		h.tid = 0;
194
		smbbufferputheader(b, &h, &peerinfo);
195
		smbbufferputb(b, SMB_COM_NO_ANDX_COMMAND);
196
		smbbufferputb(b, 0);
197
		smbbufferputs(b, 0);
198
		smbbufferputs(b, 0);
199
		smbbufferputs(b, 0);
200
		bytecountfixupoffset = smbbufferwriteoffset(b);
201
		smbbufferputs(b, 0);
202
		strcpy(namebuf, "\\\\");
203
		strcat(namebuf, to);
204
		strcat(namebuf, "\\");
205
		strcat(namebuf, share);
206
		smbbufferputstring(b, &peerinfo, SMB_STRING_UPCASE, namebuf);
207
		smbbufferputstring(b, nil, SMB_STRING_ASCII, "A:");
208
		smbbufferoffsetputs(b, bytecountfixupoffset, smbbufferwriteoffset(b) - bytecountfixupoffset - 2);
209
		nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
210
		nbsswrite(nbs, smbbufferreadpointer(b), smbbufferwriteoffset(b));
211
		smbbufferreset(b);
212
		n = nbssread(nbs, smbbufferwritepointer(b), smbbufferwritespace(b));
213
		if (n < 0) {
214
			smbstringprint(errmsgp, "read error: %r");
215
			goto fail;
216
		}
217
		smbbuffersetreadlen(b, n);
218
		nbdumpdata(smbbufferreadpointer(b), smbbufferwriteoffset(b));
219
		if (!smbbuffergetandcheckheader(b, &rh, h.command, 3, &pdata, &bytecount, errmsgp))
220
			goto fail;
221
		if (!smbsuccess(&rh, errmsgp))
222
			goto fail;
223
		sharetid = rh.tid;
224
	}
225
	else
226
		sharetid = -2;
227
	c = smbemalloc(sizeof(*c));
228
	c->peerinfo = peerinfo;
229
	c->ipctid = ipctid;
230
	c->sharetid = sharetid;
231
	c->b = b;
232
	c->protoh = h;
233
	c->nbss = nbs;
234
	return c;
235
fail:
236
	smbbufferfree(&b);
237
	free(peerinfo.encryptionkey);
238
	free(peerinfo.oemdomainname);
239
	return nil;
240
}
241
 
242
void
243
smbclientfree(SmbClient *c)
244
{
245
	if (c) {
246
		free(c->peerinfo.encryptionkey);
247
		free(c->peerinfo.oemdomainname);
248
		free(c);
249
		smbbufferfree(&c->b);
250
	}
251
}
252
 
253
int
254
smbtransactionclientsend(void *magic, SmbBuffer *ob, char **)
255
{
256
	SmbClient *c = magic;
257
smblogprint(-1, "sending:\n");
258
smblogdata(-1, smblogprint, smbbufferreadpointer(ob), smbbufferwriteoffset(ob), 256);
259
	return nbsswrite(c->nbss, smbbufferreadpointer(ob), smbbufferwriteoffset(ob)) == 0;
260
}
261
 
262
int
263
smbtransactionclientreceive(void *magic, SmbBuffer *ib, char **)
264
{
265
	long n; 
266
	SmbClient *c = magic;
267
	smbbufferreset(ib);
268
	n = nbssread(c->nbss, smbbufferwritepointer(ib), smbbufferwritespace(ib));
269
	if (n >= 0) {
270
		assert(smbbufferputbytes(ib, nil, n));
271
		return 1;
272
	}
273
	return 0;
274
}
275