1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #include "headers.h"
- SmbProcessResult
- smbnegotiate(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *b)
- {
- ushort index;
- int i;
- uchar bufferformat;
- if (!smbcheckwordcount("negotiate", h, 0))
- return SmbProcessResultFormat;
- if (s->state != SmbSessionNeedNegotiate) {
- /* this acts as a complete session reset */
- smblogprint(-1, "smbnegotiate: called when already negotiated\n");
- return SmbProcessResultUnimp;
- }
- i = 0;
- index = 0xffff;
- while (smbbuffergetb(b, &bufferformat)) {
- char *s;
- if (bufferformat != 0x02) {
- smblogprint(-1, "smbnegotiate: unrecognised buffer format 0x%.2ux\n", bufferformat);
- return SmbProcessResultFormat;
- }
- if (!smbbuffergetstr(b, 0, &s)) {
- smblogprint(-1, "smbnegotiate: no null found\n");
- return SmbProcessResultFormat;
- }
- smblogprint(h->command, "smbnegotiate: '%s'\n", s);
- if (index == 0xffff && strcmp(s, "NT LM 0.12") == 0)
- index = i;
- i++;
- free(s);
- }
- if (index != 0xffff) {
- Tm *tm;
- ulong capabilities;
- ulong bytecountfixupoffset;
- h->wordcount = 17;
- if (!smbbufferputheader(s->response, h, nil)
- || !smbbufferputs(s->response, index)
- || !smbbufferputb(s->response, 3) /* user security, encrypted */
- || !smbbufferputs(s->response, 1) /* max mux */
- || !smbbufferputs(s->response, 1) /* max vc */
- || !smbbufferputl(s->response, smbglobals.maxreceive) /* max buffer size */
- || !smbbufferputl(s->response, 0x10000) /* max raw */
- || !smbbufferputl(s->response, threadid())) /* session key */
- goto die;
- /* <= Win2k insist upon this being set to ensure that they observe the prototol (!) */
- capabilities = CAP_NT_SMBS;
- if (smbglobals.unicode)
- capabilities |= CAP_UNICODE;
- tm = localtime(time(nil));
- s->tzoff = tm->tzoff;
- if (!smbbufferputl(s->response, capabilities)
- || !smbbufferputv(s->response, nsec() / 100 + (vlong)10000000 * 11644473600LL)
- || !smbbufferputs(s->response, -s->tzoff / 60)
- || !smbbufferputb(s->response, 8)) /* crypt len */
- goto die;
- bytecountfixupoffset = smbbufferwriteoffset(s->response);
- if (!smbbufferputs(s->response, 0))
- goto die;
- s->cs = auth_challenge("proto=mschap role=server");
- if (s->cs == nil) {
- smblogprint(h->command, "smbnegotiate: couldn't get mschap challenge\n");
- return SmbProcessResultMisc;
- }
- if (s->cs->nchal != 8) {
- smblogprint(h->command, "smbnegotiate: nchal %d\n", s->cs->nchal);
- return SmbProcessResultMisc;
- }
- if (!smbbufferputbytes(s->response, s->cs->chal, s->cs->nchal)
- || !smbbufferputstring(s->response, nil, SMB_STRING_UNICODE, smbglobals.primarydomain)
- || !smbbufferfixuprelatives(s->response, bytecountfixupoffset))
- goto die;
- }
- else {
- h->wordcount = 1;
- if (!smbbufferputheader(s->response, h, nil)
- || !smbbufferputs(s->response, index)
- || !smbbufferputs(s->response, 0))
- goto die;
- }
- s->state = SmbSessionNeedSetup;
- return SmbProcessResultReply;
- die:
- return SmbProcessResultDie;
- }
|