/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <auth.h>#include <libsec.h>#include <bio.h>#include "imap4d.h" /* * hack to allow smtp forwarding. * hide the peer IP address under a rock in the ratifier FS. */voidenableForwarding(void){ char buf[64], peer[64], *p; static ulong last; ulong now; int fd; if(remote == nil) return; now = time(0); if(now < last + 5*60) return; last = now; fd = open("/srv/ratify", ORDWR); if(fd < 0) return; if(!mount(fd, -1, "/mail/ratify", MBEFORE, "")){ close(fd); return; } close(fd); strncpy(peer, remote, sizeof(peer)); peer[sizeof(peer) - 1] = '\0'; p = strchr(peer, '!'); if(p != nil) *p = '\0'; snprint(buf, sizeof(buf), "/mail/ratify/trusted/%s#32", peer); /* * if the address is already there and the user owns it, * remove it and recreate it to give him a new time quanta. */ if(access(buf, 0) >= 0 && remove(buf) < 0) return; fd = create(buf, OREAD, 0666); if(fd >= 0) close(fd);} voidsetupuser(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 char*authresp(void){ char *s, *t; int n; t = Brdline(&bin, '\n'); n = Blinelen(&bin); if(n < 2) return nil; n--; if(t[n-1] == '\r') n--; t[n] = '\0'; if(n == 0 || strcmp(t, "*") == 0) return nil; s = binalloc(&parseBin, n + 1, 0); n = dec64((uchar*)s, n, t, n); s[n] = '\0'; return s;} /* * rfc 2195 cram-md5 authentication */char*cramauth(void){ AuthInfo *ai; Chalstate *cs; char *s, *t; int n; if((cs = auth_challenge("proto=cram role=server")) == nil) return "couldn't get cram challenge"; n = cs->nchal; s = binalloc(&parseBin, n * 2, 0); n = enc64(s, n * 2, (uchar*)cs->chal, n); Bprint(&bout, "+ "); Bwrite(&bout, s, n); Bprint(&bout, "\r\n"); if(Bflush(&bout) < 0) writeErr(); s = authresp(); if(s == nil) return "client cancelled authentication"; t = strchr(s, ' '); if(t == nil) bye("bad auth response"); *t++ = '\0'; strncpy(username, s, UserNameLen); username[UserNameLen-1] = '\0'; cs->user = username; cs->resp = t; cs->nresp = strlen(t); if((ai = auth_response(cs)) == nil) return "login failed"; auth_freechal(cs); setupuser(ai); return nil;} AuthInfo*passLogin(char *user, char *secret){ AuthInfo *ai; Chalstate *cs; uchar digest[MD5dlen]; char response[2*MD5dlen+1]; int i; if((cs = auth_challenge("proto=cram role=server")) == nil) return nil; hmac_md5((uchar*)cs->chal, strlen(cs->chal), (uchar*)secret, strlen(secret), digest, nil); for(i = 0; i < MD5dlen; i++) snprint(response + 2*i, sizeof(response) - 2*i, "%2.2ux", digest[i]); cs->user = user; cs->resp = response; cs->nresp = strlen(response); ai = auth_response(cs); auth_freechal(cs); return ai;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <libsec.h>
#include <bio.h>
#include "imap4d.h"
/*
* hack to allow smtp forwarding.
* hide the peer IP address under a rock in the ratifier FS.
*/
void
enableForwarding(void)
{
char buf[64], peer[64], *p;
static ulong last;
ulong now;
int fd;
if(remote == nil)
return;
now = time(0);
if(now < last + 5*60)
return;
last = now;
fd = open("/srv/ratify", ORDWR);
if(fd < 0)
return;
if(!mount(fd, -1, "/mail/ratify", MBEFORE, "")){
close(fd);
return;
}
close(fd);
strncpy(peer, remote, sizeof(peer));
peer[sizeof(peer) - 1] = '\0';
p = strchr(peer, '!');
if(p != nil)
*p = '\0';
snprint(buf, sizeof(buf), "/mail/ratify/trusted/%s#32", peer);
/*
* if the address is already there and the user owns it,
* remove it and recreate it to give him a new time quanta.
*/
if(access(buf, 0) >= 0 && remove(buf) < 0)
return;
fd = create(buf, OREAD, 0666);
if(fd >= 0)
close(fd);
}
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 char*
authresp(void)
{
char *s, *t;
int n;
t = Brdline(&bin, '\n');
n = Blinelen(&bin);
if(n < 2)
return nil;
n--;
if(t[n-1] == '\r')
n--;
t[n] = '\0';
if(n == 0 || strcmp(t, "*") == 0)
return nil;
s = binalloc(&parseBin, n + 1, 0);
n = dec64((uchar*)s, n, t, n);
s[n] = '\0';
return s;
}
/*
* rfc 2195 cram-md5 authentication
*/
char*
cramauth(void)
{
AuthInfo *ai;
Chalstate *cs;
char *s, *t;
int n;
if((cs = auth_challenge("proto=cram role=server")) == nil)
return "couldn't get cram challenge";
n = cs->nchal;
s = binalloc(&parseBin, n * 2, 0);
n = enc64(s, n * 2, (uchar*)cs->chal, n);
Bprint(&bout, "+ ");
Bwrite(&bout, s, n);
Bprint(&bout, "\r\n");
if(Bflush(&bout) < 0)
writeErr();
s = authresp();
if(s == nil)
return "client cancelled authentication";
t = strchr(s, ' ');
if(t == nil)
bye("bad auth response");
*t++ = '\0';
strncpy(username, s, UserNameLen);
username[UserNameLen-1] = '\0';
cs->user = username;
cs->resp = t;
cs->nresp = strlen(t);
if((ai = auth_response(cs)) == nil)
return "login failed";
auth_freechal(cs);
setupuser(ai);
return nil;
}
AuthInfo*
passLogin(char *user, char *secret)
{
AuthInfo *ai;
Chalstate *cs;
uchar digest[MD5dlen];
char response[2*MD5dlen+1];
int i;
if((cs = auth_challenge("proto=cram role=server")) == nil)
return nil;
hmac_md5((uchar*)cs->chal, strlen(cs->chal),
(uchar*)secret, strlen(secret), digest,
nil);
for(i = 0; i < MD5dlen; i++)
snprint(response + 2*i, sizeof(response) - 2*i, "%2.2ux", digest[i]);
cs->user = user;
cs->resp = response;
cs->nresp = strlen(response);
ai = auth_response(cs);
auth_freechal(cs);
return ai;
}