Sun, 08 Feb 2009 06:40:15 +0000
Avoid assertion failures on NULL 'from' attributes
| 7170 | 1 | /* |
| 15884 | 2 | * purple - Jabber Protocol Plugin |
| 7170 | 3 | * |
| 4 | * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
| 5 | * | |
| 6 | * This program is free software; you can redistribute it and/or modify | |
| 7 | * it under the terms of the GNU General Public License as published by | |
| 8 | * the Free Software Foundation; either version 2 of the License, or | |
| 9 | * (at your option) any later version. | |
| 10 | * | |
| 11 | * This program is distributed in the hope that it will be useful, | |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | * GNU General Public License for more details. | |
| 15 | * | |
| 16 | * You should have received a copy of the GNU General Public License | |
| 17 | * along with this program; if not, write to the Free Software | |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
15884
diff
changeset
|
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 7170 | 19 | * |
| 20 | */ | |
| 21 | #include "internal.h" | |
| 7234 | 22 | #include "debug.h" |
| 7170 | 23 | #include "ft.h" |
| 24 | #include "util.h" | |
| 25 | ||
| 26 | #include "jabber.h" | |
| 27 | #include "iq.h" | |
|
12324
caf9784f2405
[gaim-migrate @ 14628]
Richard Laager <rlaager@pidgin.im>
parents:
12323
diff
changeset
|
28 | #include "oob.h" |
| 7170 | 29 | |
| 30 | typedef struct _JabberOOBXfer { | |
| 31 | char *address; | |
| 32 | int port; | |
| 33 | char *page; | |
| 34 | ||
| 35 | GString *headers; | |
| 36 | ||
| 37 | char *iq_id; | |
| 38 | ||
| 39 | JabberStream *js; | |
| 40 | ||
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
41 | gchar *write_buffer; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
42 | gsize written_len; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
43 | guint writeh; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
44 | |
| 7170 | 45 | } JabberOOBXfer; |
| 46 | ||
| 15884 | 47 | static void jabber_oob_xfer_init(PurpleXfer *xfer) |
| 7170 | 48 | { |
| 49 | JabberOOBXfer *jox = xfer->data; | |
| 15884 | 50 | purple_xfer_start(xfer, -1, jox->address, jox->port); |
| 7170 | 51 | } |
| 52 | ||
| 15884 | 53 | static void jabber_oob_xfer_free(PurpleXfer *xfer) |
| 7170 | 54 | { |
| 55 | JabberOOBXfer *jox = xfer->data; | |
| 7395 | 56 | jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers, |
| 57 | xfer); | |
| 7170 | 58 | |
| 59 | g_string_free(jox->headers, TRUE); | |
| 60 | g_free(jox->address); | |
| 61 | g_free(jox->page); | |
| 62 | g_free(jox->iq_id); | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
63 | g_free(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
64 | if(jox->writeh) |
| 15884 | 65 | purple_input_remove(jox->writeh); |
| 7170 | 66 | g_free(jox); |
| 67 | ||
| 68 | xfer->data = NULL; | |
| 69 | } | |
| 70 | ||
| 15884 | 71 | static void jabber_oob_xfer_end(PurpleXfer *xfer) |
| 7170 | 72 | { |
| 73 | JabberOOBXfer *jox = xfer->data; | |
| 74 | JabberIq *iq; | |
| 75 | ||
| 76 | iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT); | |
| 77 | xmlnode_set_attrib(iq->node, "to", xfer->who); | |
| 78 | jabber_iq_set_id(iq, jox->iq_id); | |
| 79 | ||
| 80 | jabber_iq_send(iq); | |
| 81 | ||
| 82 | jabber_oob_xfer_free(xfer); | |
| 83 | } | |
| 84 | ||
| 15884 | 85 | static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInputCondition cond) { |
| 86 | PurpleXfer *xfer = data; | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
87 | JabberOOBXfer *jox = xfer->data; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
88 | int len, total_len = strlen(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
89 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
90 | len = write(xfer->fd, jox->write_buffer + jox->written_len, |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
91 | total_len - jox->written_len); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
92 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
93 | if(len < 0 && errno == EAGAIN) |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
94 | return; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
95 | else if(len < 0) { |
| 15884 | 96 | purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Write error on oob xfer!\n"); |
| 97 | purple_input_remove(jox->writeh); | |
| 98 | purple_xfer_cancel_local(xfer); | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
99 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
100 | jox->written_len += len; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
101 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
102 | if(jox->written_len == total_len) { |
| 15884 | 103 | purple_input_remove(jox->writeh); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
104 | g_free(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
105 | jox->write_buffer = NULL; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
106 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
107 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
108 | |
| 15884 | 109 | static void jabber_oob_xfer_start(PurpleXfer *xfer) |
| 7170 | 110 | { |
| 111 | JabberOOBXfer *jox = xfer->data; | |
| 112 | ||
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
113 | if(jox->write_buffer == NULL) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
114 | jox->write_buffer = g_strdup_printf( |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
115 | "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", |
| 7170 | 116 | jox->page, jox->address); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
117 | jox->written_len = 0; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
118 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
119 | |
| 15884 | 120 | jox->writeh = purple_input_add(xfer->fd, PURPLE_INPUT_WRITE, |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
121 | jabber_oob_xfer_request_send, xfer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
122 | |
| 15884 | 123 | jabber_oob_xfer_request_send(xfer, xfer->fd, PURPLE_INPUT_WRITE); |
| 7170 | 124 | } |
| 125 | ||
| 15884 | 126 | static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) { |
| 7170 | 127 | JabberOOBXfer *jox = xfer->data; |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
128 | char test[2048]; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
129 | char *tmp, *lenstr; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
130 | int len; |
| 7170 | 131 | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
132 | if((len = read(xfer->fd, test, sizeof(test))) > 0) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
133 | jox->headers = g_string_append_len(jox->headers, test, len); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
134 | if((tmp = strstr(jox->headers->str, "\r\n\r\n"))) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
135 | *tmp = '\0'; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
136 | lenstr = strstr(jox->headers->str, "Content-Length: "); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
137 | if(lenstr) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
138 | int size; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
139 | sscanf(lenstr, "Content-Length: %d", &size); |
| 15884 | 140 | purple_xfer_set_size(xfer, size); |
| 7170 | 141 | } |
| 15884 | 142 | purple_xfer_set_read_fnc(xfer, NULL); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
143 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
144 | tmp += 4; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
145 | |
|
14697
518c0fae208e
[gaim-migrate @ 17381]
Daniel Atallah <datallah@pidgin.im>
parents:
14356
diff
changeset
|
146 | *buffer = (unsigned char*) g_strdup(tmp); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
147 | return strlen(tmp); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
148 | } |
| 7170 | 149 | return 0; |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
150 | } else if (errno != EAGAIN) { |
| 15884 | 151 | purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Read error on oob xfer!\n"); |
| 152 | purple_xfer_cancel_local(xfer); | |
| 7170 | 153 | } |
| 7234 | 154 | |
| 7170 | 155 | return 0; |
| 156 | } | |
| 157 | ||
| 15884 | 158 | static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) { |
| 7170 | 159 | JabberOOBXfer *jox = xfer->data; |
| 160 | JabberIq *iq; | |
| 8399 | 161 | xmlnode *y, *z; |
| 7170 | 162 | |
| 163 | iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR); | |
| 164 | xmlnode_set_attrib(iq->node, "to", xfer->who); | |
| 165 | jabber_iq_set_id(iq, jox->iq_id); | |
| 166 | y = xmlnode_new_child(iq->node, "error"); | |
| 8399 | 167 | xmlnode_set_attrib(y, "code", code); |
| 168 | if(!strcmp(code, "406")) { | |
| 169 | z = xmlnode_new_child(y, "not-acceptable"); | |
| 170 | xmlnode_set_attrib(y, "type", "modify"); | |
| 13808 | 171 | xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
| 8399 | 172 | } else if(!strcmp(code, "404")) { |
| 173 | z = xmlnode_new_child(y, "not-found"); | |
| 174 | xmlnode_set_attrib(y, "type", "cancel"); | |
| 13808 | 175 | xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
| 8399 | 176 | } |
| 7170 | 177 | jabber_iq_send(iq); |
| 178 | ||
| 179 | jabber_oob_xfer_free(xfer); | |
| 180 | } | |
| 181 | ||
| 15884 | 182 | static void jabber_oob_xfer_recv_denied(PurpleXfer *xfer) { |
| 8399 | 183 | jabber_oob_xfer_recv_error(xfer, "406"); |
| 184 | } | |
| 185 | ||
| 15884 | 186 | static void jabber_oob_xfer_recv_canceled(PurpleXfer *xfer) { |
| 8399 | 187 | jabber_oob_xfer_recv_error(xfer, "404"); |
| 188 | } | |
| 189 | ||
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
190 | void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type, |
|
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
191 | const char *id, xmlnode *querynode) { |
| 7170 | 192 | JabberOOBXfer *jox; |
| 15884 | 193 | PurpleXfer *xfer; |
| 7170 | 194 | char *filename; |
| 195 | char *url; | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
196 | xmlnode *urlnode; |
| 7170 | 197 | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
198 | if(type != JABBER_IQ_SET) |
| 14356 | 199 | return; |
| 200 | ||
|
25818
d087a2754595
Avoid assertion failures on NULL 'from' attributes
Paul Aurich <darkrain42@pidgin.im>
parents:
25817
diff
changeset
|
201 | if(!from) |
| 7170 | 202 | return; |
| 203 | ||
| 204 | if(!(urlnode = xmlnode_get_child(querynode, "url"))) | |
| 205 | return; | |
| 206 | ||
| 207 | url = xmlnode_get_data(urlnode); | |
| 208 | ||
| 209 | jox = g_new0(JabberOOBXfer, 1); | |
| 15884 | 210 | purple_url_parse(url, &jox->address, &jox->port, &jox->page, NULL, NULL); |
| 7170 | 211 | g_free(url); |
| 212 | jox->js = js; | |
| 213 | jox->headers = g_string_new(""); | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
214 | jox->iq_id = g_strdup(id); |
| 7170 | 215 | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
216 | xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from); |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
217 | if (xfer) |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
218 | { |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
219 | xfer->data = jox; |
| 7170 | 220 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
221 | if(!(filename = g_strdup(g_strrstr(jox->page, "/")))) |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
222 | filename = g_strdup(jox->page); |
| 7170 | 223 | |
| 15884 | 224 | purple_xfer_set_filename(xfer, filename); |
| 7170 | 225 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
226 | g_free(filename); |
| 7170 | 227 | |
| 15884 | 228 | purple_xfer_set_init_fnc(xfer, jabber_oob_xfer_init); |
| 229 | purple_xfer_set_end_fnc(xfer, jabber_oob_xfer_end); | |
| 230 | purple_xfer_set_request_denied_fnc(xfer, jabber_oob_xfer_recv_denied); | |
| 231 | purple_xfer_set_cancel_recv_fnc(xfer, jabber_oob_xfer_recv_canceled); | |
| 232 | purple_xfer_set_read_fnc(xfer, jabber_oob_xfer_read); | |
| 233 | purple_xfer_set_start_fnc(xfer, jabber_oob_xfer_start); | |
| 7170 | 234 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
235 | js->oob_file_transfers = g_list_append(js->oob_file_transfers, xfer); |
| 7170 | 236 | |
| 15884 | 237 | purple_xfer_request(xfer); |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
238 | } |
| 7170 | 239 | } |
| 240 | ||
| 241 |