OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /* This bit implements a simple API for using the SRP library over sockets. */ |
2 | |||
3 | #include <stdio.h> |
||
4 | #include <string.h> |
||
5 | #include <stdlib.h> |
||
6 | #include <unistd.h> |
||
7 | #include <sys/types.h> |
||
8 | #include <sys/socket.h> |
||
9 | #include "t_defines.h" |
||
10 | #include "t_pwd.h" |
||
11 | #include "t_server.h" |
||
12 | #include "t_client.h" |
||
13 | #include "tinysrp.h" |
||
14 | |||
15 | #ifndef MSG_WAITALL |
||
16 | #ifdef linux |
||
17 | #define MSG_WAITALL 0x100 /* somehow not defined on my box */ |
||
18 | #endif |
||
19 | #endif |
||
20 | |||
21 | /* This is called by the client with a connected socket, username, and |
||
22 | passphrase. pass can be NULL in which case the user is queried. */ |
||
23 | |||
24 | int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp) |
||
25 | { |
||
26 | int i, index; |
||
27 | unsigned char username[MAXUSERLEN + 1], sbuf[MAXSALTLEN]; |
||
28 | unsigned char msgbuf[MAXPARAMLEN + 1], bbuf[MAXPARAMLEN]; |
||
29 | unsigned char passbuf[128], *skey; |
||
30 | struct t_client *tc; |
||
31 | struct t_preconf *tcp; /* @@@ should go away */ |
||
32 | struct t_num salt, *A, B; |
||
33 | |||
34 | /* Send the username. */ |
||
35 | |||
36 | i = strlen(user); |
||
37 | if (i > MAXUSERLEN) { |
||
38 | i = MAXUSERLEN; |
||
39 | } |
||
40 | msgbuf[0] = i; |
||
41 | memcpy(msgbuf + 1, user, i); |
||
42 | if (send(s, msgbuf, i + 1, 0) < 0) { |
||
43 | return 0; |
||
44 | } |
||
45 | memcpy(username, user, i); |
||
46 | username[i] = '\0'; |
||
47 | |||
48 | /* Get the prime index and salt. */ |
||
49 | |||
50 | i = recv(s, msgbuf, 2, MSG_WAITALL); |
||
51 | if (i <= 0) { |
||
52 | return 0; |
||
53 | } |
||
54 | index = msgbuf[0]; |
||
55 | if (index <= 0 || index > t_getprecount()) { |
||
56 | return 0; |
||
57 | } |
||
58 | tcp = t_getpreparam(index - 1); |
||
59 | salt.len = msgbuf[1]; |
||
60 | if (salt.len > MAXSALTLEN) { |
||
61 | return 0; |
||
62 | } |
||
63 | salt.data = sbuf; |
||
64 | i = recv(s, sbuf, salt.len, MSG_WAITALL); |
||
65 | if (i <= 0) { |
||
66 | return 0; |
||
67 | } |
||
68 | |||
69 | /* @@@ t_clientopen() needs a variant that takes the index */ |
||
70 | |||
71 | tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt); |
||
72 | if (tc == NULL) { |
||
73 | return 0; |
||
74 | } |
||
75 | |||
76 | /* Calculate A and send it to the server. */ |
||
77 | |||
78 | A = t_clientgenexp(tc); |
||
79 | msgbuf[0] = A->len - 1; /* len is max 256 */ |
||
80 | memcpy(msgbuf + 1, A->data, A->len); |
||
81 | if (send(s, msgbuf, A->len + 1, 0) < 0) { |
||
82 | return 0; |
||
83 | } |
||
84 | |||
85 | /* Ask the user for the passphrase. */ |
||
86 | |||
87 | if (pass == NULL) { |
||
88 | t_getpass(passbuf, sizeof(passbuf), "Enter password:"); |
||
89 | pass = passbuf; |
||
90 | } |
||
91 | t_clientpasswd(tc, pass); |
||
92 | |||
93 | /* Get B from the server. */ |
||
94 | |||
95 | i = recv(s, msgbuf, 1, 0); |
||
96 | if (i <= 0) { |
||
97 | return 0; |
||
98 | } |
||
99 | B.len = msgbuf[0] + 1; |
||
100 | B.data = bbuf; |
||
101 | i = recv(s, bbuf, B.len, MSG_WAITALL); |
||
102 | if (i <= 0) { |
||
103 | return 0; |
||
104 | } |
||
105 | |||
106 | /* Compute the session key. */ |
||
107 | |||
108 | skey = t_clientgetkey(tc, &B); |
||
109 | if (skey == NULL) { |
||
110 | return 0; |
||
111 | } |
||
112 | |||
113 | /* Send the response. */ |
||
114 | |||
115 | if (send(s, t_clientresponse(tc), RESPONSE_LEN, 0) < 0) { |
||
116 | return 0; |
||
117 | } |
||
118 | |||
119 | /* Get the server's response. */ |
||
120 | |||
121 | i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL); |
||
122 | if (i <= 0) { |
||
123 | return 0; |
||
124 | } |
||
125 | if (t_clientverify(tc, msgbuf) != 0) { |
||
126 | return 0; |
||
127 | } |
||
128 | |||
129 | /* All done. Now copy the key and clean up. */ |
||
130 | |||
131 | if (tsrp) { |
||
132 | memcpy(tsrp->username, username, strlen(username) + 1); |
||
133 | memcpy(tsrp->key, skey, SESSION_KEY_LEN); |
||
134 | } |
||
135 | t_clientclose(tc); |
||
136 | |||
137 | return 1; |
||
138 | } |
||
139 | |||
140 | /* This is called by the server with a connected socket. */ |
||
141 | |||
142 | int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp) |
||
143 | { |
||
144 | int i, j; |
||
145 | unsigned char username[MAXUSERLEN], *skey; |
||
146 | unsigned char msgbuf[MAXPARAMLEN + 1], abuf[MAXPARAMLEN]; |
||
147 | struct t_server *ts; |
||
148 | struct t_num A, *B; |
||
149 | |||
150 | /* Get the username. */ |
||
151 | |||
152 | i = recv(s, msgbuf, 1, 0); |
||
153 | if (i <= 0) { |
||
154 | return 0; |
||
155 | } |
||
156 | j = msgbuf[0]; |
||
157 | i = recv(s, username, j, MSG_WAITALL); |
||
158 | if (i <= 0) { |
||
159 | return 0; |
||
160 | } |
||
161 | username[j] = '\0'; |
||
162 | |||
163 | ts = t_serveropen(username); |
||
164 | if (ts == NULL) { |
||
165 | return 0; |
||
166 | } |
||
167 | |||
168 | /* Send the prime index and the salt. */ |
||
169 | |||
170 | msgbuf[0] = ts->index; /* max 256 primes... */ |
||
171 | i = ts->s.len; |
||
172 | msgbuf[1] = i; |
||
173 | memcpy(msgbuf + 2, ts->s.data, i); |
||
174 | if (send(s, msgbuf, i + 2, 0) < 0) { |
||
175 | return 0; |
||
176 | } |
||
177 | |||
178 | /* Calculate B while we're waiting. */ |
||
179 | |||
180 | B = t_servergenexp(ts); |
||
181 | |||
182 | /* Get A from the client. */ |
||
183 | |||
184 | i = recv(s, msgbuf, 1, 0); |
||
185 | if (i <= 0) { |
||
186 | return 0; |
||
187 | } |
||
188 | A.len = msgbuf[0] + 1; |
||
189 | A.data = abuf; |
||
190 | i = recv(s, abuf, A.len, MSG_WAITALL); |
||
191 | if (i <= 0) { |
||
192 | return 0; |
||
193 | } |
||
194 | |||
195 | /* Now send B. */ |
||
196 | |||
197 | msgbuf[0] = B->len - 1; |
||
198 | memcpy(msgbuf + 1, B->data, B->len); |
||
199 | if (send(s, msgbuf, B->len + 1, 0) < 0) { |
||
200 | return 0; |
||
201 | } |
||
202 | |||
203 | /* Calculate the session key while we're waiting. */ |
||
204 | |||
205 | skey = t_servergetkey(ts, &A); |
||
206 | if (skey == NULL) { |
||
207 | return 0; |
||
208 | } |
||
209 | |||
210 | /* Get the response from the client. */ |
||
211 | |||
212 | i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL); |
||
213 | if (i <= 0) { |
||
214 | return 0; |
||
215 | } |
||
216 | if (t_serververify(ts, msgbuf) != 0) { |
||
217 | return 0; |
||
218 | } |
||
219 | |||
220 | /* Client authenticated. Now authenticate ourselves to the client. */ |
||
221 | |||
222 | if (send(s, t_serverresponse(ts), RESPONSE_LEN, 0) < 0) { |
||
223 | return 0; |
||
224 | } |
||
225 | |||
226 | /* Copy the key and clean up. */ |
||
227 | |||
228 | if (tsrp) { |
||
229 | memcpy(tsrp->username, username, strlen(username) + 1); |
||
230 | memcpy(tsrp->key, skey, SESSION_KEY_LEN); |
||
231 | } |
||
232 | t_serverclose(ts); |
||
233 | |||
234 | return 1; |
||
235 | } |