| 28 memcpy(newpacket->data+curbyte, chipsahoy, AIM_COOKIELEN); |
28 memcpy(newpacket->data+curbyte, chipsahoy, AIM_COOKIELEN); |
| 29 |
29 |
| 30 return aim_tx_enqueue(sess, newpacket); |
30 return aim_tx_enqueue(sess, newpacket); |
| 31 } |
31 } |
| 32 |
32 |
| 33 faim_export unsigned long aim_auth_clientready(struct aim_session_t *sess, |
33 /* |
| 34 struct aim_conn_t *conn) |
34 * This is sent back as a general response to the login command. |
| 35 { |
35 * It can be either an error or a success, depending on the |
| 36 struct aim_tool_version tools[] = { |
36 * precense of certain TLVs. |
| 37 {0x0001, 0x0003, AIM_TOOL_NEWWIN, 0x0361}, |
37 * |
| 38 {0x0007, 0x0001, AIM_TOOL_NEWWIN, 0x0361}, |
38 * The client should check the value passed as errorcode. If |
| 39 }; |
39 * its nonzero, there was an error. |
| 40 int i,j; |
40 * |
| 41 struct command_tx_struct *newpacket; |
41 */ |
| 42 int toolcount = sizeof(tools)/sizeof(struct aim_tool_version); |
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) |
| 43 |
43 { |
| 44 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 1152))) |
44 struct aim_tlvlist_t *tlvlist; |
| 45 return -1; |
45 int ret = 0; |
| 46 |
46 rxcallback_t userfunc; |
| 47 newpacket->lock = 1; |
47 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL; |
| 48 |
48 unsigned char *cookie = NULL; |
| 49 i = aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); |
49 int errorcode = 0, regstatus = 0; |
| 50 aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); |
50 int latestbuild = 0, latestbetabuild = 0; |
| 51 |
51 char *latestrelease = NULL, *latestbeta = NULL; |
| 52 for (j = 0; j < toolcount; j++) { |
52 char *latestreleaseurl = NULL, *latestbetaurl = NULL; |
| 53 i += aimutil_put16(newpacket->data+i, tools[j].group); |
53 char *latestreleaseinfo = NULL, *latestbetainfo = NULL; |
| 54 i += aimutil_put16(newpacket->data+i, tools[j].version); |
54 |
| 55 i += aimutil_put16(newpacket->data+i, tools[j].tool); |
55 /* |
| 56 i += aimutil_put16(newpacket->data+i, tools[j].toolversion); |
56 * Read block of TLVs. All further data is derived |
| |
57 * from what is parsed here. |
| |
58 * |
| |
59 */ |
| |
60 tlvlist = aim_readtlvchain(data, datalen); |
| |
61 |
| |
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)); |
| 57 } |
69 } |
| 58 |
70 |
| 59 newpacket->commandlen = i; |
71 /* |
| 60 newpacket->lock = 0; |
72 * Check for an error code. If so, we should also |
| 61 |
73 * have an error url. |
| 62 aim_tx_enqueue(sess, newpacket); |
74 */ |
| 63 |
75 if (aim_gettlv(tlvlist, 0x0008, 1)) |
| 64 return sess->snac_nextid; |
76 errorcode = aim_gettlv16(tlvlist, 0x0008, 1); |
| 65 } |
77 if (aim_gettlv(tlvlist, 0x0004, 1)) |
| 66 |
78 errurl = aim_gettlv_str(tlvlist, 0x0004, 1); |
| 67 faim_export unsigned long aim_auth_changepasswd(struct aim_session_t *sess, |
79 |
| 68 struct aim_conn_t *conn, |
80 /* |
| 69 char *new, char *current) |
81 * BOS server address. |
| 70 { |
82 */ |
| 71 struct command_tx_struct *newpacket; |
83 if (aim_gettlv(tlvlist, 0x0005, 1)) |
| 72 int i; |
84 bosip = aim_gettlv_str(tlvlist, 0x0005, 1); |
| 73 |
85 |
| 74 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+4+strlen(current)+4+strlen(new)))) |
86 /* |
| 75 return -1; |
87 * Authorization cookie. |
| 76 |
88 */ |
| 77 newpacket->lock = 1; |
89 if (aim_gettlv(tlvlist, 0x0006, 1)) { |
| 78 |
90 struct aim_tlv_t *tmptlv; |
| 79 i = aim_putsnac(newpacket->data, 0x0007, 0x0004, 0x0000, sess->snac_nextid); |
91 |
| 80 aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0); |
92 tmptlv = aim_gettlv(tlvlist, 0x0006, 1); |
| 81 |
93 |
| 82 /* new password TLV t(0002) */ |
94 if ((cookie = malloc(tmptlv->length))) |
| 83 i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(new), new); |
95 memcpy(cookie, tmptlv->value, tmptlv->length); |
| 84 |
96 } |
| 85 /* current password TLV t(0012) */ |
97 |
| 86 i += aim_puttlv_str(newpacket->data+i, 0x0012, strlen(current), current); |
98 /* |
| 87 |
99 * The email address attached to this account |
| 88 aim_tx_enqueue(sess, newpacket); |
100 * Not available for ICQ logins. |
| 89 |
101 */ |
| 90 return sess->snac_nextid; |
102 if (aim_gettlv(tlvlist, 0x0011, 1)) |
| 91 } |
103 email = aim_gettlv_str(tlvlist, 0x0011, 1); |
| 92 |
104 |
| 93 faim_export unsigned long aim_auth_setversions(struct aim_session_t *sess, |
105 /* |
| 94 struct aim_conn_t *conn) |
106 * The registration status. (Not real sure what it means.) |
| 95 { |
107 * Not available for ICQ logins. |
| 96 struct command_tx_struct *newpacket; |
108 * |
| 97 int i; |
109 * 1 = No disclosure |
| 98 |
110 * 2 = Limited disclosure |
| 99 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + (4*2)))) |
111 * 3 = Full disclosure |
| 100 return -1; |
112 * |
| 101 |
113 * This has to do with whether your email address is available |
| 102 newpacket->lock = 1; |
114 * to other users or not. AFAIK, this feature is no longer used. |
| 103 |
115 * |
| 104 i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid); |
116 */ |
| 105 aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); |
117 if (aim_gettlv(tlvlist, 0x0013, 1)) |
| 106 |
118 regstatus = aim_gettlv16(tlvlist, 0x0013, 1); |
| 107 i += aimutil_put16(newpacket->data+i, 0x0001); |
119 |
| 108 i += aimutil_put16(newpacket->data+i, 0x0003); |
120 if (aim_gettlv(tlvlist, 0x0040, 1)) |
| 109 |
121 latestbetabuild = aim_gettlv32(tlvlist, 0x0040, 1); |
| 110 i += aimutil_put16(newpacket->data+i, 0x0007); |
122 if (aim_gettlv(tlvlist, 0x0041, 1)) |
| 111 i += aimutil_put16(newpacket->data+i, 0x0001); |
123 latestbetaurl = aim_gettlv_str(tlvlist, 0x0041, 1); |
| 112 |
124 if (aim_gettlv(tlvlist, 0x0042, 1)) |
| 113 newpacket->commandlen = i; |
125 latestbetainfo = aim_gettlv_str(tlvlist, 0x0042, 1); |
| 114 newpacket->lock = 0; |
126 if (aim_gettlv(tlvlist, 0x0043, 1)) |
| 115 aim_tx_enqueue(sess, newpacket); |
127 latestbeta = aim_gettlv_str(tlvlist, 0x0043, 1); |
| 116 |
128 if (aim_gettlv(tlvlist, 0x0048, 1)) |
| 117 return sess->snac_nextid; |
129 ; /* no idea what this is */ |
| |
130 |
| |
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 */ |
| |
141 |
| |
142 |
| |
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 |
| |
146 |
| |
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); |
| |
169 |
| |
170 aim_freetlvchain(&tlvlist); |
| |
171 |
| |
172 return ret; |
| 118 } |
173 } |
| 119 |
174 |
| 120 /* |
175 /* |
| 121 * Request account confirmation. |
176 * Middle handler for 0017/0007 SNACs. Contains the auth key prefixed |
| 122 * |
177 * by only its length in a two byte word. |
| 123 * This will cause an email to be sent to the address associated with |
178 * |
| 124 * the account. By following the instructions in the mail, you can |
179 * Calls the client, which should then use the value to call aim_send_login. |
| 125 * get the TRIAL flag removed from your account. |
|
| 126 * |
180 * |
| 127 */ |
181 */ |
| 128 faim_export unsigned long aim_auth_reqconfirm(struct aim_session_t *sess, |
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) |
| 129 struct aim_conn_t *conn) |
183 { |
| 130 { |
184 unsigned char *key; |
| 131 return aim_genericreq_n(sess, conn, 0x0007, 0x0006); |
185 int keylen; |
| 132 } |
186 int ret = 1; |
| 133 |
187 rxcallback_t userfunc; |
| 134 /* |
188 |
| 135 * Request a bit of account info. |
189 keylen = aimutil_get16(data); |
| 136 * |
190 if (!(key = malloc(keylen+1))) |
| 137 * The only known valid tag is 0x0011 (email address). |
191 return ret; |
| 138 * |
192 memcpy(key, data+2, keylen); |
| 139 */ |
193 key[keylen] = '\0'; |
| 140 faim_export unsigned long aim_auth_getinfo(struct aim_session_t *sess, |
194 |
| 141 struct aim_conn_t *conn, |
195 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
| 142 unsigned short info) |
196 ret = userfunc(sess, rx, (char *)key); |
| 143 { |
197 |
| 144 struct command_tx_struct *newpacket; |
198 free(key); |
| 145 int i; |
199 |
| 146 |
200 return ret; |
| 147 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + 4))) |
201 } |
| 148 return -1; |
202 |
| 149 |
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) |
| 150 newpacket->lock = 1; |
204 { |
| 151 |
205 |
| 152 i = aim_putsnac(newpacket->data, 0x0007, 0x0002, 0x0000, sess->snac_nextid); |
206 if (snac->subtype == 0x0003) |
| 153 aim_cachesnac(sess, 0x0002, 0x0002, 0x0000, NULL, 0); |
207 return parse(sess, mod, rx, snac, data, datalen); |
| 154 |
208 else if (snac->subtype == 0x0007) |
| 155 i += aimutil_put16(newpacket->data+i, info); |
209 return keyparse(sess, mod, rx, snac, data, datalen); |
| 156 i += aimutil_put16(newpacket->data+i, 0x0000); |
210 |
| 157 |
211 return 0; |
| 158 newpacket->commandlen = i; |
212 } |
| 159 newpacket->lock = 0; |
213 |
| 160 aim_tx_enqueue(sess, newpacket); |
214 faim_internal int auth_modfirst(struct aim_session_t *sess, aim_module_t *mod) |
| 161 |
215 { |
| 162 return sess->snac_nextid; |
216 |
| 163 } |
217 mod->family = 0x0017; |
| 164 |
218 mod->version = 0x0000; |
| 165 faim_export unsigned long aim_auth_setemail(struct aim_session_t *sess, |
219 mod->flags = 0; |
| 166 struct aim_conn_t *conn, |
220 strncpy(mod->name, "auth", sizeof(mod->name)); |
| 167 char *newemail) |
221 mod->snachandler = snachandler; |
| 168 { |
222 |
| 169 struct command_tx_struct *newpacket; |
223 return 0; |
| 170 int i; |
224 } |
| 171 |
|
| 172 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+2+2+strlen(newemail)))) |
|
| 173 return -1; |
|
| 174 |
|
| 175 newpacket->lock = 1; |
|
| 176 |
|
| 177 i = aim_putsnac(newpacket->data, 0x0007, 0x0004, 0x0000, sess->snac_nextid); |
|
| 178 aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0); |
|
| 179 |
|
| 180 i += aim_puttlv_str(newpacket->data+i, 0x0011, strlen(newemail), newemail); |
|
| 181 |
|
| 182 aim_tx_enqueue(sess, newpacket); |
|
| 183 |
|
| 184 return sess->snac_nextid; |
|
| 185 } |
|