comparison libpurple/protocols/jabber/si.c @ 25247:151b4054ce40

Trigger error callbacks when receiving a malformed-ish packet. Clean up a few pieces of code. Use G_GSIZE_FORMAT like KingAnt showed me. Don't crash if an iq packet doesn't contain the seq attribute. Error check g_fopen() Don't unref the PurpleXfer until after we've called some functions with it. Not sure that could ever actually crash it (I didn't bother to run through the ref-counts in my head to see if it would fail). committer: Marcus Lundblad <ml@update.uu.se>
author Paul Aurich <paul@darkrain42.org>
date Tue, 16 Dec 2008 19:16:10 +0000
parents 2faa374df334
children 4b51394fd834
comparison
equal deleted inserted replaced
25246:3918ed48d7a8 25247:151b4054ce40
30 #include "notify.h" 30 #include "notify.h"
31 31
32 #include "buddy.h" 32 #include "buddy.h"
33 #include "disco.h" 33 #include "disco.h"
34 #include "jabber.h" 34 #include "jabber.h"
35 #include "ibb.h"
35 #include "iq.h" 36 #include "iq.h"
36 #include "si.h" 37 #include "si.h"
37 #include "ibb.h"
38 38
39 #define STREAMHOST_CONNECT_TIMEOUT 15 39 #define STREAMHOST_CONNECT_TIMEOUT 15
40 40
41 typedef struct _JabberSIXfer { 41 typedef struct _JabberSIXfer {
42 JabberStream *js; 42 JabberStream *js;
997 { 997 {
998 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); 998 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
999 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; 999 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
1000 1000
1001 if (size <= purple_xfer_get_bytes_remaining(xfer)) { 1001 if (size <= purple_xfer_get_bytes_remaining(xfer)) {
1002 purple_debug_info("jabber", "about to write %lu bytes from IBB stream\n", 1002 purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
1003 size); 1003 size);
1004 if(!fwrite(data, size, 1, jsx->fp)) { 1004 if(!fwrite(data, size, 1, jsx->fp)) {
1005 purple_debug_error("jabber", "error writing to file\n"); 1005 purple_debug_error("jabber", "error writing to file\n");
1006 jabber_si_xfer_cancel_recv(xfer); 1006 jabber_si_xfer_cancel_recv(xfer);
1007 return; 1007 return;
1016 } 1016 }
1017 } else { 1017 } else {
1018 /* trying to write past size of file transfers negotiated size, 1018 /* trying to write past size of file transfers negotiated size,
1019 reject transfer to protect against malicious behaviour */ 1019 reject transfer to protect against malicious behaviour */
1020 purple_debug_error("jabber", 1020 purple_debug_error("jabber",
1021 "IBB file transfer, trying to write past end of file\n"); 1021 "IBB file transfer send more data than expected\n");
1022 jabber_si_xfer_cancel_recv(xfer); 1022 jabber_si_xfer_cancel_recv(xfer);
1023 purple_xfer_end(xfer); 1023 purple_xfer_end(xfer);
1024 } 1024 }
1025 1025
1026 } 1026 }
1034 PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who); 1034 PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who);
1035 if (xfer) { 1035 if (xfer) {
1036 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; 1036 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
1037 JabberIBBSession *sess = 1037 JabberIBBSession *sess =
1038 jabber_ibb_session_create_from_xmlnode(js, packet, xfer); 1038 jabber_ibb_session_create_from_xmlnode(js, packet, xfer);
1039 1039 const char *filename;
1040
1040 if (sess) { 1041 if (sess) {
1042 /* open the file to write to */
1043 filename = purple_xfer_get_local_filename(xfer);
1044 jsx->fp = g_fopen(filename, "wb");
1045 if (jsx->fp == NULL) {
1046 purple_debug_error("jabber", "failed to open file %s for writing: %s\n",
1047 filename, g_strerror(errno));
1048 purple_xfer_cancel_remote(xfer);
1049 return FALSE;
1050 }
1051
1041 /* setup callbacks here...*/ 1052 /* setup callbacks here...*/
1042 jabber_ibb_session_set_data_received_callback(sess, 1053 jabber_ibb_session_set_data_received_callback(sess,
1043 jabber_si_xfer_ibb_recv_data_cb); 1054 jabber_si_xfer_ibb_recv_data_cb);
1044 jabber_ibb_session_set_closed_callback(sess, 1055 jabber_ibb_session_set_closed_callback(sess,
1045 jabber_si_xfer_ibb_closed_cb); 1056 jabber_si_xfer_ibb_closed_cb);
1046 jabber_ibb_session_set_error_callback(sess, 1057 jabber_ibb_session_set_error_callback(sess,
1047 jabber_si_xfer_ibb_error_cb); 1058 jabber_si_xfer_ibb_error_cb);
1048
1049 /* open the file to write to */
1050 jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
1051 1059
1052 jsx->ibb_session = sess; 1060 jsx->ibb_session = sess;
1053 1061
1054 /* start the transfer */ 1062 /* start the transfer */
1055 purple_xfer_start(xfer, 0, NULL, 0); 1063 purple_xfer_start(xfer, 0, NULL, 0);
1080 gsize packet_size = remaining < jabber_ibb_session_get_block_size(sess) ? 1088 gsize packet_size = remaining < jabber_ibb_session_get_block_size(sess) ?
1081 remaining : jabber_ibb_session_get_block_size(sess); 1089 remaining : jabber_ibb_session_get_block_size(sess);
1082 gpointer data = g_malloc(packet_size); 1090 gpointer data = g_malloc(packet_size);
1083 int res; 1091 int res;
1084 1092
1085 purple_debug_info("jabber", "IBB: about to read %lu bytes from file %p\n", 1093 purple_debug_info("jabber", "IBB: about to read %" G_GSIZE_FORMAT " bytes from file %p\n",
1086 packet_size, jsx->fp); 1094 packet_size, jsx->fp);
1087 res = fread(data, packet_size, 1, jsx->fp); 1095 res = fread(data, packet_size, 1, jsx->fp);
1088 1096
1089 if (res == 1) { 1097 if (res == 1) {
1090 jabber_ibb_session_send_data(sess, data, packet_size); 1098 jabber_ibb_session_send_data(sess, data, packet_size);
1119 static void 1127 static void
1120 jabber_si_xfer_ibb_opened_cb(JabberIBBSession *sess) 1128 jabber_si_xfer_ibb_opened_cb(JabberIBBSession *sess)
1121 { 1129 {
1122 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); 1130 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
1123 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; 1131 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
1124 1132 JabberStream *js = jabber_ibb_session_get_js(sess);
1133 PurpleConnection *gc = js->gc;
1134 PurpleAccount *account = purple_connection_get_account(gc);
1135
1125 if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) { 1136 if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) {
1126 purple_xfer_start(xfer, 0, NULL, 0); 1137 const char *filename = purple_xfer_get_local_filename(xfer);
1127 purple_xfer_set_bytes_sent(xfer, 0); 1138 jsx->fp = g_fopen(filename, "rb");
1128 purple_xfer_update_progress(xfer); 1139 if (jsx->fp == NULL) {
1129 jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb"); 1140 purple_debug_error("jabber", "Failed to open file %s for reading: %s\n",
1130 jabber_si_xfer_ibb_send_data(sess); 1141 filename, g_strerror(errno));
1142 jabber_si_xfer_free(xfer);
1143 purple_xfer_error(purple_xfer_get_type(xfer), account,
1144 jabber_ibb_session_get_who(sess),
1145 _("Failed to open the file"));
1146 purple_xfer_end(xfer);
1147 } else {
1148 /* XXX: Shouldn't this specify a valid file descriptor? */
1149 purple_xfer_start(xfer, 0, NULL, 0);
1150 purple_xfer_set_bytes_sent(xfer, 0);
1151 purple_xfer_update_progress(xfer);
1152 jabber_si_xfer_ibb_send_data(sess);
1153 }
1131 } else { 1154 } else {
1132 /* error */ 1155 /* error */
1133 JabberStream *js = jabber_ibb_session_get_js(sess);
1134 PurpleConnection *gc = js->gc;
1135 PurpleAccount *account = purple_connection_get_account(gc);
1136 jabber_si_xfer_free(xfer); 1156 jabber_si_xfer_free(xfer);
1137 purple_xfer_error(purple_xfer_get_type(xfer), account, 1157 purple_xfer_error(purple_xfer_get_type(xfer), account,
1138 jabber_ibb_session_get_who(sess), 1158 jabber_ibb_session_get_who(sess),
1139 _("Failed to open in-band bytestream")); 1159 _("Failed to open in-band bytestream"));
1140 purple_xfer_end(xfer); 1160 purple_xfer_end(xfer);
1165 /* open the IBB session */ 1185 /* open the IBB session */
1166 jabber_ibb_session_open(jsx->ibb_session); 1186 jabber_ibb_session_open(jsx->ibb_session);
1167 1187
1168 } else { 1188 } else {
1169 /* failed to create IBB session */ 1189 /* failed to create IBB session */
1170 purple_xfer_unref(xfer);
1171 purple_debug_error("jabber", 1190 purple_debug_error("jabber",
1172 "failed to initiate IBB session for file transfer\n"); 1191 "failed to initiate IBB session for file transfer\n");
1173 jabber_si_xfer_cancel_send(xfer); 1192 jabber_si_xfer_cancel_send(xfer);
1193 purple_xfer_unref(xfer);
1174 } 1194 }
1175 } 1195 }
1176 1196
1177 static void jabber_si_xfer_send_method_cb(JabberStream *js, xmlnode *packet, 1197 static void jabber_si_xfer_send_method_cb(JabberStream *js, xmlnode *packet,
1178 gpointer data) 1198 gpointer data)