4 * This contains all the functions needed to actually login.
12 * FIXME: Reimplement the TIS stuff.
14 #ifdef TIS_TELNET_PROXY
15 #include "tis_telnet_proxy.h"
19 * send_login(int socket, char *sn, char *password)
21 * This is the initial login request packet.
23 * The password is encoded before transmition, as per
24 * encode_password(). See that function for their
25 * stupid method of doing it.
30 int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct client_info_s *clientinfo)
33 char *password_encoded = NULL; /* to store encoded password */
36 struct command_tx_struct newpacket;
39 newpacket.conn = conn;
41 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH);
43 newpacket.commandlen = 6+2+strlen(sn)+1+1+2+strlen(password)+6;
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;
56 newpacket.data = (char *) calloc (1, newpacket.commandlen );
58 newpacket.type = 0x01;
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));
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);
73 curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0016, 0x0001);
77 if (strlen(clientinfo->clientstring))
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));
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))
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));
92 if (strlen(clientinfo->lang))
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));
100 curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0009, 0x0015);
103 aim_tx_enqueue(&newpacket);
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
115 int info_field_len = 4;
117 char *password_encoded = NULL; /* to store encoded password */
118 int n = 0; /* counter during packet construction */
120 struct command_tx_struct newpacket;
123 newpacket.conn = conn;
125 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH);
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 */
142 /* allocate buffer to use for constructing packet_login */
143 newpacket.data = (char *) malloc ( newpacket.commandlen );
144 memset(newpacket.data, 0x00, newpacket.commandlen);
147 newpacket.type = 0x01;
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;
156 newpacket.data[6] = (char) ( (strlen(sn)) >> 8);
157 newpacket.data[7] = (char) ( (strlen(sn)) & 0xFF);
160 memcpy(&(newpacket.data[n]), sn, strlen(sn));
162 newpacket.data[n] = 0x00;
165 newpacket.data[n] = 0x02;
168 /* store password length as word */
169 newpacket.data[n] = (char) ( (strlen(password)) >> 8);
170 newpacket.data[n+1] = (char) ( (strlen(password)) & 0xFF);
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));
180 n += strlen(password);
182 free(password_encoded);
183 /* place null terminator after encoded password */
184 newpacket.data[n] = 0x00;
187 newpacket.data[n] = 0x03;
190 newpacket.data[n] = (char) ( (info_field_len) >> 8);
191 newpacket.data[n+1] = (char) ( (info_field_len) & 0xFF);
193 memcpy(&(newpacket.data[n]), info_field, info_field_len);
195 newpacket.data[n] = 0x00;
198 newpacket.data[n] = 0x16;
199 newpacket.data[n+1] = 0x00;
200 newpacket.data[n+2] = 0x02;
201 newpacket.data[n+3] = 0x00;
203 newpacket.data[n] = 0x01;
204 newpacket.data[n+1] = 0x00;
205 newpacket.data[n+2] = 0x17;
206 newpacket.data[n+3] = 0x00;
209 newpacket.data[n] = 0x02;
210 newpacket.data[n+1] = 0x00;
211 newpacket.data[n+2] = 0x01;
212 newpacket.data[n+3] = 0x00;
215 newpacket.data[n] = 0x18;
216 newpacket.data[n+1] = 0x00;
217 newpacket.data[n+2] = 0x02;
218 newpacket.data[n+3] = 0x00;
221 newpacket.data[n] = 0x01;
222 newpacket.data[n+1] = 0x00;
223 newpacket.data[n+2] = 0x1a;
224 newpacket.data[n+3] = 0x00;
227 newpacket.data[n] = 0x02;
228 newpacket.data[n+1] = 0x00;
229 newpacket.data[n+2] = 0x13;
230 newpacket.data[n+3] = 0x00;
233 newpacket.data[n] = 0x0e;
234 newpacket.data[n+1] = 0x00;
235 newpacket.data[n+2] = 0x02;
236 newpacket.data[n+3] = 0x75;
239 newpacket.data[n] = 0x73;
240 newpacket.data[n+1] = 0x00;
241 newpacket.data[n+2] = 0x0f;
242 newpacket.data[n+3] = 0x00;
245 newpacket.data[n] = 0x02;
246 newpacket.data[n+1] = 0x65;
247 newpacket.data[n+2] = 0x6e;
248 newpacket.data[n+3] = 0x00;
250 newpacket.data[n] = 0x09;
251 newpacket.data[n+1] = 0x00;
252 newpacket.data[n+2] = 0x02;
253 newpacket.data[n+3] = 0x00;
256 newpacket.data[n] = 0x15;
259 aim_tx_enqueue(&newpacket);
266 * int encode_password(
267 * const char *password,
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.
277 * The encoding_table seems to be a fixed set of values. We'll
278 * hope it doesn't change over time!
281 int aim_encode_password(const char *password, char *encoded)
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
292 for (i = 0; i < strlen(password); i++)
293 encoded[i] = (password[i] ^ encoding_table[i]);