1 /*
2 * Ostatnia aktualizacja:
3 *
4 * - $Id: auth.c,v 1.19 2002/11/25 18:20:49 mati Exp $
5 *
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include "libtlen.h"
12
13 static void shaHashBlock (j_SHA_CTX * ctx);
14
15 void
shaInit(j_SHA_CTX * ctx)16 shaInit (j_SHA_CTX * ctx)
17 {
18 int i;
19
20 ctx->lenW = 0;
21 ctx->sizeHi = ctx->sizeLo = 0;
22
23 /* Initialize H with the magic constants (see FIPS180 for constants)
24 */
25 ctx->H[0] = 0x67452301L;
26 ctx->H[1] = 0xefcdab89L;
27 ctx->H[2] = 0x98badcfeL;
28 ctx->H[3] = 0x10325476L;
29 ctx->H[4] = 0xc3d2e1f0L;
30
31 for (i = 0; i < 80; i++)
32 ctx->W[i] = 0;
33 }
34
35
36 void
shaUpdate(j_SHA_CTX * ctx,unsigned char * dataIn,int len)37 shaUpdate (j_SHA_CTX * ctx, unsigned char *dataIn, int len)
38 {
39 int i;
40
41 /* Read the data into W and process blocks as they get full
42 */
43 for (i = 0; i < len; i++)
44 {
45 ctx->W[ctx->lenW / 4] <<= 8;
46 ctx->W[ctx->lenW / 4] |= (unsigned long) dataIn[i];
47 if ((++ctx->lenW) % 64 == 0)
48 {
49 shaHashBlock (ctx);
50 ctx->lenW = 0;
51 }
52 ctx->sizeLo += 8;
53 ctx->sizeHi += (ctx->sizeLo < 8);
54 }
55 }
56
57
58 void
shaFinal(j_SHA_CTX * ctx,unsigned char hashout[20])59 shaFinal (j_SHA_CTX * ctx, unsigned char hashout[20])
60 {
61 unsigned char pad0x80 = 0x80;
62 unsigned char pad0x00 = 0x00;
63 unsigned char padlen[8];
64 int i;
65
66 /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
67 */
68 padlen[0] = (unsigned char) ((ctx->sizeHi >> 24) & 255);
69 padlen[1] = (unsigned char) ((ctx->sizeHi >> 16) & 255);
70 padlen[2] = (unsigned char) ((ctx->sizeHi >> 8) & 255);
71 padlen[3] = (unsigned char) ((ctx->sizeHi >> 0) & 255);
72 padlen[4] = (unsigned char) ((ctx->sizeLo >> 24) & 255);
73 padlen[5] = (unsigned char) ((ctx->sizeLo >> 16) & 255);
74 padlen[6] = (unsigned char) ((ctx->sizeLo >> 8) & 255);
75 padlen[7] = (unsigned char) ((ctx->sizeLo >> 0) & 255);
76 shaUpdate (ctx, &pad0x80, 1);
77 while (ctx->lenW != 56)
78 shaUpdate (ctx, &pad0x00, 1);
79 shaUpdate (ctx, padlen, 8);
80
81 /* Output hash
82 */
83 for (i = 0; i < 20; i++)
84 {
85 hashout[i] = (unsigned char) (ctx->H[i / 4] >> 24);
86 ctx->H[i / 4] <<= 8;
87 }
88
89 /*
90 * Re-initialize the context (also zeroizes contents)
91 */
92 shaInit (ctx);
93 }
94
95
96 void
shaBlock(unsigned char * dataIn,int len,unsigned char hashout[20])97 shaBlock (unsigned char *dataIn, int len, unsigned char hashout[20])
98 {
99 j_SHA_CTX ctx;
100
101 shaInit (&ctx);
102 shaUpdate (&ctx, dataIn, len);
103 shaFinal (&ctx, hashout);
104 }
105
106
107 #define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
108
109 static void
shaHashBlock(j_SHA_CTX * ctx)110 shaHashBlock (j_SHA_CTX * ctx)
111 {
112 int t;
113 unsigned long A, B, C, D, E, TEMP;
114
115 for (t = 16; t <= 79; t++)
116 ctx->W[t] =
117 SHA_ROTL (ctx->W[t - 3] ^ ctx->W[t - 8] ^ ctx->
118 W[t - 14] ^ ctx->W[t - 16], 1);
119
120 A = ctx->H[0];
121 B = ctx->H[1];
122 C = ctx->H[2];
123 D = ctx->H[3];
124 E = ctx->H[4];
125
126 for (t = 0; t <= 19; t++)
127 {
128 TEMP = (SHA_ROTL (A, 5) + (((C ^ D) & B) ^ D) + E +
129 ctx->W[t] + 0x5a827999L) & 0xffffffffL;
130 E = D;
131 D = C;
132 C = SHA_ROTL (B, 30);
133 B = A;
134 A = TEMP;
135 }
136 for (t = 20; t <= 39; t++)
137 {
138 TEMP = (SHA_ROTL (A, 5) + (B ^ C ^ D) + E + ctx->W[t] +
139 0x6ed9eba1L) & 0xffffffffL;
140 E = D;
141 D = C;
142 C = SHA_ROTL (B, 30);
143 B = A;
144 A = TEMP;
145 }
146 for (t = 40; t <= 59; t++)
147 {
148 TEMP = (SHA_ROTL (A, 5) + ((B & C) | (D & (B | C))) + E +
149 ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
150 E = D;
151 D = C;
152 C = SHA_ROTL (B, 30);
153 B = A;
154 A = TEMP;
155 }
156 for (t = 60; t <= 79; t++)
157 {
158 TEMP = (SHA_ROTL (A, 5) + (B ^ C ^ D) + E + ctx->W[t] +
159 0xca62c1d6L) & 0xffffffffL;
160 E = D;
161 D = C;
162 C = SHA_ROTL (B, 30);
163 B = A;
164 A = TEMP;
165 }
166
167 ctx->H[0] += A;
168 ctx->H[1] += B;
169 ctx->H[2] += C;
170 ctx->H[3] += D;
171 ctx->H[4] += E;
172 }
173
174 /*----------------------------------------------------------------------------
175 *
176 * This code added by Thomas "temas" Muldowney for Jabber compatability
177 *
178 *---------------------------------------------------------------------------*/
179 char *
shahash(char * str)180 shahash (char *str)
181 {
182 static char final[41];
183 char *pos;
184 unsigned char hashval[20];
185 int x;
186
187 if (!str || strlen (str) == 0)
188 return NULL;
189
190 shaBlock ((unsigned char *) str, strlen (str), hashval);
191
192 pos = final;
193 for (x = 0; x < 20; x++)
194 {
195 snprintf (pos, 3, "%02x", hashval[x]);
196 pos += 2;
197 }
198 return (char *) final;
199 }
200
201 void
shahash_r(const char * str,char hashbuf[41])202 shahash_r (const char *str, char hashbuf[41])
203 {
204 int x;
205 char *pos;
206 unsigned char hashval[20];
207
208 if (!str || strlen (str) == 0)
209 return;
210
211 shaBlock ((unsigned char *) str, strlen (str), hashval);
212
213 pos = hashbuf;
214 for (x = 0; x < 20; x++)
215 {
216 snprintf (pos, 3, "%02x", hashval[x]);
217 pos += 2;
218 }
219
220 return;
221 }
222
223 /*********************************************/
224 // Ten kod dodany przeze mnie i Piotra Paw�owa
225
226 void
calc_passcode(const char * pass,char * code)227 calc_passcode (const char *pass, char *code)
228 {
229 int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7;
230 char z;
231 while ((z = *pass++) != 0)
232 {
233 if (z == ' ')
234 continue;
235 if (z == '\t')
236 continue;
237 magic1 ^= (((magic1 & 0x3f) + sum) * z) + (magic1 << 8);
238 magic2 += (magic2 << 8) ^ magic1;
239 sum += z;
240 }
241 magic1 &= 0x7fffffff;
242 magic2 &= 0x7fffffff;
243 sprintf (code, "%08x%08x", magic1, magic2);
244 }
245
246 /*
247 * tlen_hash()
248 *
249 * Generuje hash potrzebny do zalogowania si�
250 *
251 * - pass - has�o
252 * - id - identyfikator sesji
253 *
254 * Funkcja wewn�trzna na potrzeby tlen_authorize
255 *
256 */
257
tlen_hash(const char * pass,const char * id)258 char *tlen_hash (const char *pass, const char *id)
259 {
260 char passcode[17];
261 char dohasha[25];
262 char *hash;
263 hash = (char *) malloc (41);
264 calc_passcode (pass, passcode);
265 strcpy (dohasha, id);
266 strcat (dohasha, passcode);
267 dohasha[24]=0;
268 shahash_r (dohasha, hash);
269 return (char *) hash;
270 }
271
272 /*
273 * tlen_getid()
274 *
275 * Wysy�a pro�b� o ID do serwera
276 *
277 * - sesja - nasza sesja
278 *
279 * Wywo�ywane zaraz po po��czeniu
280 *
281 */
282
tlen_getid(struct tlen_session * sesja)283 int tlen_getid (struct tlen_session *sesja)
284 {
285 tlen_socket_write_string (sesja, "<s v='2'>");
286 return 1;
287 }
288
289 /*
290 * tlen_authorize()
291 *
292 * Wysy�a zapytanie loguj�ce do serwera
293 *
294 * - sesja - nasza sesja
295 *
296 * Wywo�ywane po otrzymaniu ID
297 *
298 */
299
tlen_authorize(struct tlen_session * sesja)300 int tlen_authorize (struct tlen_session *sesja)
301 {
302 char *query;
303 char *hash;
304
305 tlen_debug ("Username: %s\nHaslo: <hidden>\nID: %s\n", sesja->username, sesja->sid);
306
307 if (!(query = (char *)malloc (strlen("<iq type='set' id=''><query xmlns='jabber:iq:auth'><username></username><digest></digest><resource>t</resource></query></iq>") + strlen (sesja->username) + 40 + 8 + 1)))
308 {
309 perror ("malloc");
310 sesja->error = TLEN_ERROR_MALLOC;
311 }
312
313 hash = tlen_hash (sesja->password, sesja->sid);
314 sprintf (query,"<iq type='set' id='%s'><query xmlns='jabber:iq:auth'><username>%s</username><digest>%s</digest><resource>t</resource></query></iq>",sesja->sid, sesja->username, hash);
315 tlen_socket_write_string (sesja, query);
316 free (query);
317 free (hash);
318 return 1;
319 }
320