]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/imap4d/auth.c
ip/torrent: remove unneeded assignment
[plan9front.git] / sys / src / cmd / ip / imap4d / auth.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <libsec.h>
5 #include <bio.h>
6 #include "imap4d.h"
7
8 /*
9  * hack to allow smtp forwarding.
10  * hide the peer IP address under a rock in the ratifier FS.
11  */
12 void
13 enableForwarding(void)
14 {
15         char buf[64], peer[64], *p;
16         static ulong last;
17         ulong now;
18         int fd;
19
20         if(remote == nil)
21                 return;
22
23         now = time(0);
24         if(now < last + 5*60)
25                 return;
26         last = now;
27
28         fd = open("/srv/ratify", ORDWR);
29         if(fd < 0)
30                 return;
31         if(!mount(fd, -1, "/mail/ratify", MBEFORE, "")){
32                 close(fd);
33                 return;
34         }
35         close(fd);
36
37         strncpy(peer, remote, sizeof(peer));
38         peer[sizeof(peer) - 1] = '\0';
39         p = strchr(peer, '!');
40         if(p != nil)
41                 *p = '\0';
42
43         snprint(buf, sizeof(buf), "/mail/ratify/trusted/%s#32", peer);
44
45         /*
46          * if the address is already there and the user owns it,
47          * remove it and recreate it to give him a new time quanta.
48          */
49         if(access(buf, 0) >= 0 && remove(buf) < 0)
50                 return;
51
52         fd = create(buf, OREAD, 0666);
53         if(fd >= 0)
54                 close(fd);
55 }
56
57 void
58 setupuser(AuthInfo *ai)
59 {
60         Waitmsg *w;
61         int pid;
62
63         if(ai){
64                 strecpy(username, username+sizeof username, ai->cuid);
65
66                 if(auth_chuid(ai, nil) < 0)
67                         bye("user auth failed: %r");
68                 auth_freeAI(ai);
69         }else
70                 strecpy(username, username+sizeof username, getuser());
71
72         if(newns(username, 0) < 0)
73                 bye("user login failed: %r");
74
75         /*
76          * hack to allow access to outgoing smtp forwarding
77          */
78         enableForwarding();
79
80         snprint(mboxDir, MboxNameLen, "/mail/box/%s", username);
81         if(myChdir(mboxDir) < 0)
82                 bye("can't open user's mailbox");
83
84         switch(pid = fork()){
85         case -1:
86                 bye("can't initialize mail system");
87                 break;
88         case 0:
89                 execl("/bin/upas/fs", "upas/fs", "-np", nil);
90 _exits("rob1");
91                 _exits(0);
92                 break;
93         default:
94                 break;
95         }
96         if((w=wait()) == nil || w->pid != pid || w->msg[0] != '\0')
97                 bye("can't initialize mail system");
98         free(w);
99 }
100
101 static char*
102 authresp(void)
103 {
104         char *s, *t;
105         int n;
106
107         t = Brdline(&bin, '\n');
108         n = Blinelen(&bin);
109         if(n < 2)
110                 return nil;
111         n--;
112         if(t[n-1] == '\r')
113                 n--;
114         t[n] = '\0';
115         if(n == 0 || strcmp(t, "*") == 0)
116                 return nil;
117
118         s = binalloc(&parseBin, n + 1, 0);
119         n = dec64((uchar*)s, n, t, n);
120         s[n] = '\0';
121         return s;
122 }
123
124 /*
125  * rfc 2195 cram-md5 authentication
126  */
127 char*
128 cramauth(void)
129 {
130         AuthInfo *ai;
131         Chalstate *cs;
132         char *s, *t;
133         int n;
134
135         if((cs = auth_challenge("proto=cram role=server")) == nil)
136                 return "couldn't get cram challenge";
137
138         n = cs->nchal;
139         s = binalloc(&parseBin, n * 2, 0);
140         n = enc64(s, n * 2, (uchar*)cs->chal, n);
141         Bprint(&bout, "+ ");
142         Bwrite(&bout, s, n);
143         Bprint(&bout, "\r\n");
144         if(Bflush(&bout) < 0)
145                 writeErr();
146
147         s = authresp();
148         if(s == nil)
149                 return "client cancelled authentication";
150
151         t = strchr(s, ' ');
152         if(t == nil)
153                 bye("bad auth response");
154         *t++ = '\0';
155         strncpy(username, s, UserNameLen);
156         username[UserNameLen-1] = '\0';
157
158         cs->user = username;
159         cs->resp = t;
160         cs->nresp = strlen(t);
161         if((ai = auth_response(cs)) == nil)
162                 return "login failed";
163         auth_freechal(cs);
164         setupuser(ai);
165         return nil;
166 }
167
168 AuthInfo*
169 passLogin(char *user, char *secret)
170 {
171         AuthInfo *ai;
172         Chalstate *cs;
173         uchar digest[MD5dlen];
174         char response[2*MD5dlen+1];
175         int i;
176
177         if((cs = auth_challenge("proto=cram role=server")) == nil)
178                 return nil;
179
180         hmac_md5((uchar*)cs->chal, strlen(cs->chal),
181                 (uchar*)secret, strlen(secret), digest,
182                 nil);
183         for(i = 0; i < MD5dlen; i++)
184                 snprint(response + 2*i, sizeof(response) - 2*i, "%2.2ux", digest[i]);
185
186         cs->user = user;
187         cs->resp = response;
188         cs->nresp = strlen(response);
189         ai = auth_response(cs);
190         auth_freechal(cs);
191         return ai;
192 }