1535
|
1 /*
|
|
2 aim_auth.c
|
|
3
|
|
4 Deals with the authorizer.
|
|
5
|
|
6 */
|
|
7
|
|
8 #define FAIM_INTERNAL
|
|
9 #include <aim.h>
|
|
10
|
|
11 /* this just pushes the passed cookie onto the passed connection -- NO SNAC! */
|
|
12 faim_export int aim_auth_sendcookie(struct aim_session_t *sess,
|
|
13 struct aim_conn_t *conn,
|
|
14 unsigned char *chipsahoy)
|
|
15 {
|
|
16 struct command_tx_struct *newpacket;
|
|
17 int curbyte=0;
|
|
18
|
|
19 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0001, 4+2+2+AIM_COOKIELEN)))
|
|
20 return -1;
|
|
21
|
|
22 newpacket->lock = 1;
|
|
23
|
|
24 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
|
|
25 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
|
|
26 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0006);
|
|
27 curbyte += aimutil_put16(newpacket->data+curbyte, AIM_COOKIELEN);
|
|
28 memcpy(newpacket->data+curbyte, chipsahoy, AIM_COOKIELEN);
|
|
29
|
|
30 return aim_tx_enqueue(sess, newpacket);
|
|
31 }
|
|
32
|
1649
|
33 /*
|
|
34 * This is sent back as a general response to the login command.
|
|
35 * It can be either an error or a success, depending on the
|
|
36 * precense of certain TLVs.
|
|
37 *
|
|
38 * The client should check the value passed as errorcode. If
|
|
39 * its nonzero, there was an error.
|
|
40 *
|
|
41 */
|
|
42 static int parse(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
1535
|
43 {
|
1649
|
44 struct aim_tlvlist_t *tlvlist;
|
|
45 int ret = 0;
|
|
46 rxcallback_t userfunc;
|
|
47 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL;
|
|
48 unsigned char *cookie = NULL;
|
|
49 int errorcode = 0, regstatus = 0;
|
|
50 int latestbuild = 0, latestbetabuild = 0;
|
|
51 char *latestrelease = NULL, *latestbeta = NULL;
|
|
52 char *latestreleaseurl = NULL, *latestbetaurl = NULL;
|
|
53 char *latestreleaseinfo = NULL, *latestbetainfo = NULL;
|
|
54
|
|
55 /*
|
|
56 * Read block of TLVs. All further data is derived
|
|
57 * from what is parsed here.
|
|
58 *
|
|
59 */
|
|
60 tlvlist = aim_readtlvchain(data, datalen);
|
1535
|
61
|
1649
|
62 /*
|
|
63 * No matter what, we should have a screen name.
|
|
64 */
|
|
65 memset(sess->sn, 0, sizeof(sess->sn));
|
|
66 if (aim_gettlv(tlvlist, 0x0001, 1)) {
|
|
67 sn = aim_gettlv_str(tlvlist, 0x0001, 1);
|
|
68 strncpy(sess->sn, sn, sizeof(sess->sn));
|
|
69 }
|
1535
|
70
|
1649
|
71 /*
|
|
72 * Check for an error code. If so, we should also
|
|
73 * have an error url.
|
|
74 */
|
|
75 if (aim_gettlv(tlvlist, 0x0008, 1))
|
|
76 errorcode = aim_gettlv16(tlvlist, 0x0008, 1);
|
|
77 if (aim_gettlv(tlvlist, 0x0004, 1))
|
|
78 errurl = aim_gettlv_str(tlvlist, 0x0004, 1);
|
1535
|
79
|
1649
|
80 /*
|
|
81 * BOS server address.
|
|
82 */
|
|
83 if (aim_gettlv(tlvlist, 0x0005, 1))
|
|
84 bosip = aim_gettlv_str(tlvlist, 0x0005, 1);
|
|
85
|
|
86 /*
|
|
87 * Authorization cookie.
|
|
88 */
|
|
89 if (aim_gettlv(tlvlist, 0x0006, 1)) {
|
|
90 struct aim_tlv_t *tmptlv;
|
|
91
|
|
92 tmptlv = aim_gettlv(tlvlist, 0x0006, 1);
|
|
93
|
|
94 if ((cookie = malloc(tmptlv->length)))
|
|
95 memcpy(cookie, tmptlv->value, tmptlv->length);
|
1535
|
96 }
|
|
97
|
1649
|
98 /*
|
|
99 * The email address attached to this account
|
|
100 * Not available for ICQ logins.
|
|
101 */
|
|
102 if (aim_gettlv(tlvlist, 0x0011, 1))
|
|
103 email = aim_gettlv_str(tlvlist, 0x0011, 1);
|
1535
|
104
|
1649
|
105 /*
|
|
106 * The registration status. (Not real sure what it means.)
|
|
107 * Not available for ICQ logins.
|
|
108 *
|
|
109 * 1 = No disclosure
|
|
110 * 2 = Limited disclosure
|
|
111 * 3 = Full disclosure
|
|
112 *
|
|
113 * This has to do with whether your email address is available
|
|
114 * to other users or not. AFAIK, this feature is no longer used.
|
|
115 *
|
|
116 */
|
|
117 if (aim_gettlv(tlvlist, 0x0013, 1))
|
|
118 regstatus = aim_gettlv16(tlvlist, 0x0013, 1);
|
1535
|
119
|
1649
|
120 if (aim_gettlv(tlvlist, 0x0040, 1))
|
|
121 latestbetabuild = aim_gettlv32(tlvlist, 0x0040, 1);
|
|
122 if (aim_gettlv(tlvlist, 0x0041, 1))
|
|
123 latestbetaurl = aim_gettlv_str(tlvlist, 0x0041, 1);
|
|
124 if (aim_gettlv(tlvlist, 0x0042, 1))
|
|
125 latestbetainfo = aim_gettlv_str(tlvlist, 0x0042, 1);
|
|
126 if (aim_gettlv(tlvlist, 0x0043, 1))
|
|
127 latestbeta = aim_gettlv_str(tlvlist, 0x0043, 1);
|
|
128 if (aim_gettlv(tlvlist, 0x0048, 1))
|
|
129 ; /* no idea what this is */
|
1535
|
130
|
1649
|
131 if (aim_gettlv(tlvlist, 0x0044, 1))
|
|
132 latestbuild = aim_gettlv32(tlvlist, 0x0044, 1);
|
|
133 if (aim_gettlv(tlvlist, 0x0045, 1))
|
|
134 latestreleaseurl = aim_gettlv_str(tlvlist, 0x0045, 1);
|
|
135 if (aim_gettlv(tlvlist, 0x0046, 1))
|
|
136 latestreleaseinfo = aim_gettlv_str(tlvlist, 0x0046, 1);
|
|
137 if (aim_gettlv(tlvlist, 0x0047, 1))
|
|
138 latestrelease = aim_gettlv_str(tlvlist, 0x0047, 1);
|
|
139 if (aim_gettlv(tlvlist, 0x0049, 1))
|
|
140 ; /* no idea what this is */
|
1535
|
141
|
|
142
|
1649
|
143 if ((userfunc = aim_callhandler(sess, rx->conn, snac?snac->family:0x0017, snac?snac->subtype:0x0003)))
|
|
144 ret = userfunc(sess, rx, sn, errorcode, errurl, regstatus, email, bosip, cookie, latestrelease, latestbuild, latestreleaseurl, latestreleaseinfo, latestbeta, latestbetabuild, latestbetaurl, latestbetainfo);
|
|
145
|
1535
|
146
|
1649
|
147 if (sn)
|
|
148 free(sn);
|
|
149 if (bosip)
|
|
150 free(bosip);
|
|
151 if (errurl)
|
|
152 free(errurl);
|
|
153 if (email)
|
|
154 free(email);
|
|
155 if (cookie)
|
|
156 free(cookie);
|
|
157 if (latestrelease)
|
|
158 free(latestrelease);
|
|
159 if (latestreleaseurl)
|
|
160 free(latestreleaseurl);
|
|
161 if (latestbeta)
|
|
162 free(latestbeta);
|
|
163 if (latestbetaurl)
|
|
164 free(latestbetaurl);
|
|
165 if (latestreleaseinfo)
|
|
166 free(latestreleaseinfo);
|
|
167 if (latestbetainfo)
|
|
168 free(latestbetainfo);
|
1535
|
169
|
1649
|
170 aim_freetlvchain(&tlvlist);
|
1535
|
171
|
1649
|
172 return ret;
|
1535
|
173 }
|
|
174
|
|
175 /*
|
1649
|
176 * Middle handler for 0017/0007 SNACs. Contains the auth key prefixed
|
|
177 * by only its length in a two byte word.
|
1535
|
178 *
|
1649
|
179 * Calls the client, which should then use the value to call aim_send_login.
|
1535
|
180 *
|
|
181 */
|
1649
|
182 static int keyparse(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
1535
|
183 {
|
1649
|
184 unsigned char *key;
|
|
185 int keylen;
|
|
186 int ret = 1;
|
|
187 rxcallback_t userfunc;
|
|
188
|
|
189 keylen = aimutil_get16(data);
|
|
190 if (!(key = malloc(keylen+1)))
|
|
191 return ret;
|
|
192 memcpy(key, data+2, keylen);
|
|
193 key[keylen] = '\0';
|
|
194
|
|
195 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
|
|
196 ret = userfunc(sess, rx, (char *)key);
|
|
197
|
|
198 free(key);
|
|
199
|
|
200 return ret;
|
1535
|
201 }
|
|
202
|
1649
|
203 static int snachandler(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
1535
|
204 {
|
|
205
|
1649
|
206 if (snac->subtype == 0x0003)
|
|
207 return parse(sess, mod, rx, snac, data, datalen);
|
|
208 else if (snac->subtype == 0x0007)
|
|
209 return keyparse(sess, mod, rx, snac, data, datalen);
|
1535
|
210
|
1649
|
211 return 0;
|
1535
|
212 }
|
|
213
|
1649
|
214 faim_internal int auth_modfirst(struct aim_session_t *sess, aim_module_t *mod)
|
1535
|
215 {
|
|
216
|
1649
|
217 mod->family = 0x0017;
|
|
218 mod->version = 0x0000;
|
|
219 mod->flags = 0;
|
|
220 strncpy(mod->name, "auth", sizeof(mod->name));
|
|
221 mod->snachandler = snachandler;
|
1535
|
222
|
1649
|
223 return 0;
|
1535
|
224 }
|