static int netkeysrvauth(int fd, char *user) { char response[32]; Chalstate *ch; int tries; AuthInfo *ai; if(readstr(fd, user, 32) < 0) return -1; ai = nil; ch = nil; for(tries = 0; tries < 10; tries++){ if((ch = auth_challenge("proto=p9cr role=server user=%q", user)) == nil) return -1; writestr(fd, ch->chal, "challenge", 1); if(readstr(fd, response, sizeof response) < 0) return -1; ch->resp = response; ch->nresp = strlen(response); if((ai = auth_response(ch)) != nil) break; } auth_freechal(ch); if(ai == nil) return -1; writestr(fd, "", "challenge", 1); if(auth_chuid(ai, 0) < 0) fatal(1, "newns"); auth_freeAI(ai); return fd; }
/* * called by listen as rexexec rexexec net dir ... */ void main(int argc, char **argv) { char buf[8192]; int n, nn; AuthInfo *ai; ARGBEGIN{ }ARGEND; ai = auth_proxy(0, auth_getkey, "proto=p9any role=server"); if(ai == nil) sysfatal("auth_proxy: %r"); if(strcmp(ai->cuid, "none") == 0) sysfatal("rexexec by none disallowed"); if(auth_chuid(ai, nil) < 0) sysfatal("auth_chuid: %r"); n = 0; do { nn = read(0, buf+n, 1); if(nn <= 0) sysfatal("can't read command"); n += nn; if(n == sizeof buf) buf[n-1] = '\0'; } while (buf[n-1] != '\0'); putenv("service", "rx"); execl("/bin/rc", "rc", "-lc", buf, nil); sysfatal("can't exec rc"); }
int passive(void) { int fd; /* * Ignore doauth==0 on purpose. Is it useful here? */ procsetname("auth_proxy auth_getkey proto=p9any role=server"); ai = auth_proxy(0, auth_getkey, "proto=p9any role=server"); if(ai == nil) sysfatal("auth_proxy: %r"); if(auth_chuid(ai, nil) < 0) sysfatal("auth_chuid: %r"); putenv("service", "import"); fd = dup(0, -1); close(0); open("/dev/null", ORDWR); close(1); open("/dev/null", ORDWR); return fd; }
static void authsrvuser(Conn *c) { int i; char *ns, *user; AuthInfo *ai; Msg *m; m = recvmsg(c, SSH_CMSG_USER); user = getstring(m); c->user = emalloc(strlen(user)+1); strcpy(c->user, user); free(m); ai = authusername(c); while(ai == nil){ /* * clumsy: if the client aborted the auth_tis early * we don't send a new failure. we check this by * looking at c->unget, which is only used in that * case. */ if(c->unget != nil) goto skipfailure; sendmsg(allocmsg(c, SSH_SMSG_FAILURE, 0)); skipfailure: m = recvmsg(c, -1); for(i=0; i<c->nokauthsrv; i++) if(c->okauthsrv[i]->firstmsg == m->type){ ai = (*c->okauthsrv[i]->fn)(c, m); break; } if(i==c->nokauthsrv) badmsg(m, 0); } sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0)); if(noworld(ai->cuid)) ns = "/lib/namespace.noworld"; else ns = nil; if(auth_chuid(ai, ns) < 0){ sshlog("auth_chuid to %s: %r", ai->cuid); sysfatal("auth_chuid: %r"); } sshlog("logged in as %s", ai->cuid); auth_freeAI(ai); }
static int dologin(char *response) { AuthInfo *ai; static int tries; static uint32_t delaysecs = 5; chs->user = user; chs->resp = response; chs->nresp = strlen(response); if((ai = auth_response(chs)) == nil){ if(tries >= 20){ senderr("authentication failed: %r; server exiting"); exits(nil); } if(++tries == 3) syslog(0, "pop3", "likely password guesser from %s", peeraddr); delaysecs *= 2; if (delaysecs > 30*60) delaysecs = 30*60; /* half-hour max. */ sleep(delaysecs * 1000); /* prevent beating on our auth server */ return senderr("authentication failed"); } if(auth_chuid(ai, nil) < 0){ senderr("chuid failed: %r; server exiting"); exits(nil); } auth_freeAI(ai); auth_freechal(chs); chs = nil; loggedin = 1; if(newns(user, 0) < 0){ senderr("newns failed: %r; server exiting"); exits(nil); } syslog(0, "pop3", "user %s logged in", user); enableaddr(); if(readmbox(box) < 0) exits(nil); return sendok("mailbox is %s", box); }
void setupuser(AuthInfo *ai) { Waitmsg *w; int pid; if(ai){ strecpy(username, username+sizeof username, ai->cuid); if(auth_chuid(ai, nil) < 0) bye("user auth failed: %r"); auth_freeAI(ai); }else strecpy(username, username+sizeof username, getuser()); if(newns(username, 0) < 0) bye("user login failed: %r"); /* * hack to allow access to outgoing smtp forwarding */ enableForwarding(); snprint(mboxDir, MboxNameLen, "/mail/box/%s", username); if(myChdir(mboxDir) < 0) bye("can't open user's mailbox"); switch(pid = fork()){ case -1: bye("can't initialize mail system"); break; case 0: execl("/bin/upas/fs", "upas/fs", "-np", nil); _exits("rob1"); _exits(0); break; default: break; } if((w=wait()) == nil || w->pid != pid || w->msg[0] != '\0') bye("can't initialize mail system"); free(w); }
static int srvp9auth(int fd, char *user) { uchar key[16]; uchar digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; int i; AuthInfo *ai; ai = auth_proxy(0, nil, "proto=%q role=server %s", p9authproto, keyspec); if(ai == nil) return -1; if(auth_chuid(ai, nil) < 0) return -1; strecpy(user, user+MaxStr, ai->cuid); memmove(key+4, ai->secret, ai->nsecret); if(ealgs == nil) return fd; /* exchange random numbers */ srand(truerand()); for(i = 0; i < 4; i++) key[i+12] = rand(); if(readn(fd, key, 4) != 4) return -1; if(write(fd, key+12, 4) != 4) return -1; /* scramble into two secrets */ sha1(key, sizeof(key), digest, nil); mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); /* set up encryption */ i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil); if(i < 0) werrstr("can't establish ssl connection: %r"); return i; }
SmbProcessResult smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) { uchar andxcommand; ushort andxoffset; ulong andxfixupoffset; ushort vcnumber; ulong sessionkey; ushort caseinsensitivepasswordlength; ushort casesensitivepasswordlength; ushort bytecountfixup, offset; uchar *mschapreply; AuthInfo *ai; char *sp; SmbProcessResult pr; char *accountname = nil; char *primarydomain = nil; char *nativeos = nil; char *nativelanman = nil; if (!smbcheckwordcount("comsessionsetupandx", h, 13)) { fmtfail: pr = SmbProcessResultFormat; goto done; } andxcommand = *pdata++; switch (andxcommand) { case SMB_COM_TREE_CONNECT_ANDX: case SMB_COM_OPEN_ANDX: case SMB_COM_CREATE_NEW: case SMB_COM_DELETE: case SMB_COM_FIND: case SMB_COM_COPY: case SMB_COM_NT_RENAME: case SMB_COM_QUERY_INFORMATION: case SMB_COM_NO_ANDX_COMMAND: case SMB_COM_OPEN: case SMB_COM_CREATE: case SMB_COM_CREATE_DIRECTORY: case SMB_COM_DELETE_DIRECTORY: case SMB_COM_FIND_UNIQUE: case SMB_COM_RENAME: case SMB_COM_CHECK_DIRECTORY: case SMB_COM_SET_INFORMATION: case SMB_COM_OPEN_PRINT_FILE: break; default: smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n", smboptable[andxcommand].name, andxcommand); goto fmtfail; } pdata++; andxoffset = smbnhgets(pdata); pdata += 2; s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2; smbresponseinit(s, s->peerinfo.maxlen); s->client.maxmpxcount = smbnhgets(pdata); pdata += 2; vcnumber = smbnhgets(pdata); pdata += 2; sessionkey = smbnhgetl(pdata); pdata += 4; caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2; casesensitivepasswordlength = smbnhgets(pdata); pdata += 2; pdata += 4; s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/ smbloglock(); smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset); smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen); smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount); smblogprint(h->command, "vcnumber: %ud\n", vcnumber); smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey); smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength); smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength); smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities); smblogunlock(); mschapreply = smbbufferreadpointer(b); if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) { smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n"); goto fmtfail; } if (!smbbuffergetstring(b, h, 0, &accountname) || !smbbuffergetstring(b, h, 0, &primarydomain) || !smbbuffergetstring(b, h, 0, &nativeos) || !smbbuffergetstring(b, h, 0, &nativelanman)) { smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n"); goto fmtfail; } for (sp = accountname; *sp; sp++) *sp = tolower(*sp); smblogprint(h->command, "account: %s\n", accountname); smblogprint(h->command, "primarydomain: %s\n", primarydomain); smblogprint(h->command, "nativeos: %s\n", nativeos); smblogprint(h->command, "nativelanman: %s\n", nativelanman); if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) { smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n", s->client.accountname, accountname); smbseterror(s, ERRSRV, ERRtoomanyuids); errordone: pr = SmbProcessResultError; goto done; } if (s->client.accountname == nil) { /* first time */ if (accountname[0] == 0) { smbseterror(s, ERRSRV, ERRbaduid); goto errordone; } if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) { smblogprint(h->command, "smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply)); if(s->cs == nil){ smbseterror(s, ERRSRV, ERRerror); goto errordone; } s->cs->user = accountname; s->cs->resp = &s->client.mschapreply; s->cs->nresp = sizeof(MSchapreply); ai = auth_response(s->cs); if (ai == nil) { smblogprint(h->command, "authentication failed\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } smblogprint(h->command, "authentication succeeded\n"); if (auth_chuid(ai, nil) < 0) { smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n"); auth_freeAI(ai); miscerror: pr = SmbProcessResultMisc; goto done; } auth_freeAI(ai); h->uid = 1; s->client.accountname = accountname; s->client.primarydomain = primarydomain; s->client.nativeos = nativeos; s->client.nativelanman = nativelanman; accountname = nil; primarydomain = nil; nativeos = nil; nativelanman = nil; } else { if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24 && memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) { smblogprint(h->command, "second time authentication failed\n"); smbseterror(s, ERRSRV, ERRbadpw); goto errordone; } } /* CIFS says 4 with or without extended security, samba/ms says 3 without */ h->wordcount = 3; if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset)) goto miscerror; if (!smbresponseputs(s, 0)) goto miscerror; bytecountfixup = smbresponseoffset(s); if (!smbresponseputs(s, 0)) goto miscerror; if (!smbresponseputstring(s, 1, smbglobals.nativeos) || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman) || !smbresponseputstring(s, 1, smbglobals.primarydomain)) goto miscerror; offset = smbresponseoffset(s); smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2); s->state = SmbSessionEstablished; if (andxcommand != SMB_COM_NO_ANDX_COMMAND) pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b); else pr = SmbProcessResultReply; done: free(accountname); free(primarydomain); free(nativeos); free(nativelanman); return pr; }