]>
Commit | Line | Data |
---|---|---|
9de3ca7e | 1 | /* |
2 | * aim_login.c | |
3 | * | |
4 | * This contains all the functions needed to actually login. | |
5 | * | |
6 | */ | |
7 | ||
8 | #include "aim.h" | |
9 | ||
10 | ||
11 | /* | |
12 | * FIXME: Reimplement the TIS stuff. | |
13 | */ | |
14 | #ifdef TIS_TELNET_PROXY | |
15 | #include "tis_telnet_proxy.h" | |
16 | #endif | |
17 | ||
18 | /* | |
19 | * send_login(int socket, char *sn, char *password) | |
20 | * | |
21 | * This is the initial login request packet. | |
22 | * | |
23 | * The password is encoded before transmition, as per | |
24 | * encode_password(). See that function for their | |
25 | * stupid method of doing it. | |
26 | * | |
27 | * | |
28 | * | |
29 | */ | |
30 | int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct client_info_s *clientinfo) | |
31 | #if 0 | |
32 | { | |
33 | char *password_encoded = NULL; /* to store encoded password */ | |
34 | int curbyte=0; | |
35 | ||
36 | struct command_tx_struct newpacket; | |
37 | ||
38 | if (conn) | |
39 | newpacket.conn = conn; | |
40 | else | |
41 | newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); | |
42 | ||
43 | newpacket.commandlen = 6+2+strlen(sn)+1+1+2+strlen(password)+6; | |
44 | ||
45 | if (clientinfo) | |
46 | { | |
47 | if (strlen(clientinfo->clientstring)) | |
48 | newpacket.commandlen += strlen(clientinfo->clientstring)+4; | |
49 | newpacket.commandlen += 6+6+6; | |
50 | if (strlen(clientinfo->country)) | |
51 | newpacket.commandlen += strlen(clientinfo->country)+4; | |
52 | if (strlen(clientinfo->lang)) | |
53 | newpacket.commandlen += strlen(clientinfo->lang)+4; | |
54 | } | |
55 | ||
56 | newpacket.data = (char *) calloc (1, newpacket.commandlen ); | |
57 | newpacket.lock = 1; | |
58 | newpacket.type = 0x01; | |
59 | ||
60 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000); | |
61 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); | |
62 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); | |
63 | curbyte += aimutil_put16(newpacket.data+curbyte, strlen(sn)); | |
64 | curbyte += aimutil_putstr(newpacket.data+curbyte, sn, strlen(sn)); | |
65 | ||
66 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x0002); | |
67 | curbyte += aimutil_put16(newpacket.data+curbyte, strlen(password)); | |
68 | password_encoded = (char *) malloc(strlen(password)); | |
69 | aim_encode_password(password, password_encoded); | |
70 | curbyte += aimutil_putstr(newpacket.data+curbyte, password_encoded, strlen(password)); | |
71 | free(password_encoded); | |
72 | ||
73 | curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0016, 0x0001); | |
74 | ||
75 | if (clientinfo) | |
76 | { | |
77 | if (strlen(clientinfo->clientstring)) | |
78 | { | |
79 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x0003); | |
80 | curbyte += aimutil_put16(newpacket.data+curbyte, strlen(clientinfo->clientstring)); | |
81 | curbyte += aimutil_putstr(newpacket.data+curbyte, clientinfo->clientstring, strlen(clientinfo->clientstring)); | |
82 | } | |
83 | curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0017, 0x0001); | |
84 | curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0018, 0x0001); | |
85 | curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x001a, 0x0013); | |
86 | if (strlen(clientinfo->country)) | |
87 | { | |
88 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x000e); | |
89 | curbyte += aimutil_put16(newpacket.data+curbyte, strlen(clientinfo->country)); | |
90 | curbyte += aimutil_putstr(newpacket.data+curbyte, clientinfo->country, strlen(clientinfo->country)); | |
91 | } | |
92 | if (strlen(clientinfo->lang)) | |
93 | { | |
94 | curbyte += aimutil_put16(newpacket.data+curbyte, 0x000f); | |
95 | curbyte += aimutil_put16(newpacket.data+curbyte, strlen(clientinfo->lang)); | |
96 | curbyte += aimutil_putstr(newpacket.data+curbyte, clientinfo->lang, strlen(clientinfo->lang)); | |
97 | } | |
98 | } | |
99 | ||
100 | curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0009, 0x0015); | |
101 | ||
102 | newpacket.lock = 0; | |
103 | aim_tx_enqueue(&newpacket); | |
104 | ||
105 | return 0; | |
106 | } | |
107 | #else | |
108 | { | |
109 | ||
110 | /* this is for the client info field of this packet. for now, just | |
111 | put a few zeros in there and hope they don't notice. */ | |
112 | char info_field[] = { | |
113 | 0x00, 0x00, 0x00, 0x00 | |
114 | }; | |
115 | int info_field_len = 4; | |
116 | ||
117 | char *password_encoded = NULL; /* to store encoded password */ | |
118 | int n = 0; /* counter during packet construction */ | |
119 | ||
120 | struct command_tx_struct newpacket; | |
121 | ||
122 | if (conn) | |
123 | newpacket.conn = conn; | |
124 | else | |
125 | newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); | |
126 | ||
127 | /* breakdown of new_packet_login_len */ | |
128 | newpacket.commandlen = 6; /* SNAC: fixed bytes */ | |
129 | newpacket.commandlen += 2; /* SN len */ | |
130 | newpacket.commandlen += strlen(sn); /* SN text */ | |
131 | newpacket.commandlen += 1; /* SN null terminator */ | |
132 | newpacket.commandlen += 1; /* fixed byte */ | |
133 | newpacket.commandlen += 2; /* password len */ | |
134 | newpacket.commandlen += strlen(password); /* password text */ | |
135 | newpacket.commandlen += 1; /* password null term*/ | |
136 | newpacket.commandlen += 1; /* fixed byte */ | |
137 | newpacket.commandlen += 2; /* info field len */ | |
138 | newpacket.commandlen += info_field_len; /* info field text */ | |
139 | newpacket.commandlen += 1; /* info field null term */ | |
140 | newpacket.commandlen += 41; /* fixed bytes */ | |
141 | ||
142 | /* allocate buffer to use for constructing packet_login */ | |
143 | newpacket.data = (char *) malloc ( newpacket.commandlen ); | |
144 | memset(newpacket.data, 0x00, newpacket.commandlen); | |
145 | ||
146 | newpacket.lock = 1; | |
147 | newpacket.type = 0x01; | |
148 | ||
149 | newpacket.data[0] = 0x00; | |
150 | newpacket.data[1] = 0x00; | |
151 | newpacket.data[2] = 0x00; | |
152 | newpacket.data[3] = 0x01; | |
153 | newpacket.data[4] = 0x00; | |
154 | newpacket.data[5] = 0x01; | |
155 | ||
156 | newpacket.data[6] = (char) ( (strlen(sn)) >> 8); | |
157 | newpacket.data[7] = (char) ( (strlen(sn)) & 0xFF); | |
158 | ||
159 | n = 8; | |
160 | memcpy(&(newpacket.data[n]), sn, strlen(sn)); | |
161 | n += strlen(sn); | |
162 | newpacket.data[n] = 0x00; | |
163 | n++; | |
164 | ||
165 | newpacket.data[n] = 0x02; | |
166 | n++; | |
167 | ||
168 | /* store password length as word */ | |
169 | newpacket.data[n] = (char) ( (strlen(password)) >> 8); | |
170 | newpacket.data[n+1] = (char) ( (strlen(password)) & 0xFF); | |
171 | n += 2; | |
172 | ||
173 | /* allocate buffer for encoded password */ | |
174 | password_encoded = (char *) malloc(strlen(password)); | |
175 | /* encode password */ | |
176 | aim_encode_password(password, password_encoded); | |
177 | /* store encoded password */ | |
178 | memcpy(&(newpacket.data[n]), password_encoded, strlen(password)); | |
179 | ||
180 | n += strlen(password); | |
181 | /* free buffer */ | |
182 | free(password_encoded); | |
183 | /* place null terminator after encoded password */ | |
184 | newpacket.data[n] = 0x00; | |
185 | n++; | |
186 | ||
187 | newpacket.data[n] = 0x03; | |
188 | n++; | |
189 | ||
190 | newpacket.data[n] = (char) ( (info_field_len) >> 8); | |
191 | newpacket.data[n+1] = (char) ( (info_field_len) & 0xFF); | |
192 | n += 2; | |
193 | memcpy(&(newpacket.data[n]), info_field, info_field_len); | |
194 | n += info_field_len; | |
195 | newpacket.data[n] = 0x00; | |
196 | n++; | |
197 | ||
198 | newpacket.data[n] = 0x16; | |
199 | newpacket.data[n+1] = 0x00; | |
200 | newpacket.data[n+2] = 0x02; | |
201 | newpacket.data[n+3] = 0x00; | |
202 | n += 4; | |
203 | newpacket.data[n] = 0x01; | |
204 | newpacket.data[n+1] = 0x00; | |
205 | newpacket.data[n+2] = 0x17; | |
206 | newpacket.data[n+3] = 0x00; | |
207 | n += 4; | |
208 | ||
209 | newpacket.data[n] = 0x02; | |
210 | newpacket.data[n+1] = 0x00; | |
211 | newpacket.data[n+2] = 0x01; | |
212 | newpacket.data[n+3] = 0x00; | |
213 | n += 4; | |
214 | ||
215 | newpacket.data[n] = 0x18; | |
216 | newpacket.data[n+1] = 0x00; | |
217 | newpacket.data[n+2] = 0x02; | |
218 | newpacket.data[n+3] = 0x00; | |
219 | n += 4; | |
220 | ||
221 | newpacket.data[n] = 0x01; | |
222 | newpacket.data[n+1] = 0x00; | |
223 | newpacket.data[n+2] = 0x1a; | |
224 | newpacket.data[n+3] = 0x00; | |
225 | n += 4; | |
226 | ||
227 | newpacket.data[n] = 0x02; | |
228 | newpacket.data[n+1] = 0x00; | |
229 | newpacket.data[n+2] = 0x13; | |
230 | newpacket.data[n+3] = 0x00; | |
231 | n += 4; | |
232 | ||
233 | newpacket.data[n] = 0x0e; | |
234 | newpacket.data[n+1] = 0x00; | |
235 | newpacket.data[n+2] = 0x02; | |
236 | newpacket.data[n+3] = 0x75; | |
237 | n += 4; | |
238 | ||
239 | newpacket.data[n] = 0x73; | |
240 | newpacket.data[n+1] = 0x00; | |
241 | newpacket.data[n+2] = 0x0f; | |
242 | newpacket.data[n+3] = 0x00; | |
243 | n += 4; | |
244 | ||
245 | newpacket.data[n] = 0x02; | |
246 | newpacket.data[n+1] = 0x65; | |
247 | newpacket.data[n+2] = 0x6e; | |
248 | newpacket.data[n+3] = 0x00; | |
249 | n += 4; | |
250 | newpacket.data[n] = 0x09; | |
251 | newpacket.data[n+1] = 0x00; | |
252 | newpacket.data[n+2] = 0x02; | |
253 | newpacket.data[n+3] = 0x00; | |
254 | n += 4; | |
255 | ||
256 | newpacket.data[n] = 0x15; | |
257 | n += 1; | |
258 | ||
259 | aim_tx_enqueue(&newpacket); | |
260 | ||
261 | return 0; | |
262 | } | |
263 | #endif | |
264 | ||
265 | /* | |
266 | * int encode_password( | |
267 | * const char *password, | |
268 | * char *encoded | |
269 | * ); | |
270 | * | |
271 | * This takes a const pointer to a (null terminated) string | |
272 | * containing the unencoded password. It also gets passed | |
273 | * an already allocated buffer to store the encoded password. | |
274 | * This buffer should be the exact length of the password without | |
275 | * the null. The encoded password buffer IS NOT NULL TERMINATED. | |
276 | * | |
277 | * The encoding_table seems to be a fixed set of values. We'll | |
278 | * hope it doesn't change over time! | |
279 | * | |
280 | */ | |
281 | int aim_encode_password(const char *password, char *encoded) | |
282 | { | |
283 | u_char encoding_table[] = { | |
284 | 0xf3, 0xb3, 0x6c, 0x99, | |
285 | 0x95, 0x3f, 0xac, 0xb6, | |
286 | 0xc5, 0xfa, 0x6b, 0x63, | |
287 | 0x69, 0x6c, 0xc3, 0x9f | |
288 | }; | |
289 | ||
290 | int i; | |
291 | ||
292 | for (i = 0; i < strlen(password); i++) | |
293 | encoded[i] = (password[i] ^ encoding_table[i]); | |
294 | ||
295 | return 0; | |
296 | } | |
297 | ||
298 | ||
299 | ||
300 |