Changeset 5ebff60 for protocols/jabber/iq.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/iq.c
raf359b4 r5ebff60 25 25 #include "sha1.h" 26 26 27 static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig);28 static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_node *node, struct xt_node *orig);29 static int jabber_iq_disco_server( struct im_connection *ic);30 31 xt_status jabber_pkt_iq( struct xt_node *node, gpointer data)27 static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 28 static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 29 static int jabber_iq_disco_server(struct im_connection *ic); 30 31 xt_status jabber_pkt_iq(struct xt_node *node, gpointer data) 32 32 { 33 33 struct im_connection *ic = data; … … 36 36 char *type, *s; 37 37 int st, pack = 1; 38 39 type = xt_find_attr( node, "type" ); 40 41 if( !type ) 42 { 43 imcb_error( ic, "Received IQ packet without type." ); 44 imc_logout( ic, TRUE ); 38 39 type = xt_find_attr(node, "type"); 40 41 if (!type) { 42 imcb_error(ic, "Received IQ packet without type."); 43 imc_logout(ic, TRUE); 45 44 return XT_ABORT; 46 45 } 47 48 if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 ) 49 { 50 return jabber_cache_handle_packet( ic, node ); 51 } 52 else if( strcmp( type, "get" ) == 0 ) 53 { 54 if( !( ( c = xt_find_node( node->children, "query" ) ) || 55 ( c = xt_find_node( node->children, "ping" ) ) || 56 ( c = xt_find_node( node->children, "time" ) ) ) || 57 !( s = xt_find_attr( c, "xmlns" ) ) ) 58 { 46 47 if (strcmp(type, "result") == 0 || strcmp(type, "error") == 0) { 48 return jabber_cache_handle_packet(ic, node); 49 } else if (strcmp(type, "get") == 0) { 50 if (!((c = xt_find_node(node->children, "query")) || 51 (c = xt_find_node(node->children, "ping")) || 52 (c = xt_find_node(node->children, "time"))) || 53 !(s = xt_find_attr(c, "xmlns"))) { 59 54 /* Sigh. Who decided to suddenly invent new elements 60 55 instead of just sticking with <query/>? */ 61 56 return XT_HANDLED; 62 57 } 63 64 reply = xt_new_node( "query", NULL, NULL);65 xt_add_attr( reply, "xmlns", s);66 58 59 reply = xt_new_node("query", NULL, NULL); 60 xt_add_attr(reply, "xmlns", s); 61 67 62 /* Of course this is a very essential query to support. ;-) */ 68 if( strcmp( s, XMLNS_VERSION ) == 0 ) 69 { 70 xt_add_child( reply, xt_new_node( "name", set_getstr( &ic->acc->set, "user_agent" ), NULL ) ); 71 xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) ); 72 xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) ); 73 } 74 else if( strcmp( s, XMLNS_TIME_OLD ) == 0 ) 75 { 63 if (strcmp(s, XMLNS_VERSION) == 0) { 64 xt_add_child(reply, xt_new_node("name", set_getstr(&ic->acc->set, "user_agent"), NULL)); 65 xt_add_child(reply, xt_new_node("version", BITLBEE_VERSION, NULL)); 66 xt_add_child(reply, xt_new_node("os", ARCH, NULL)); 67 } else if (strcmp(s, XMLNS_TIME_OLD) == 0) { 76 68 time_t time_ep; 77 69 char buf[1024]; 78 79 buf[sizeof(buf)-1] = 0; 80 time_ep = time( NULL ); 81 82 strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%S", gmtime( &time_ep ) ); 83 xt_add_child( reply, xt_new_node( "utc", buf, NULL ) ); 84 85 strftime( buf, sizeof( buf ) - 1, "%Z", localtime( &time_ep ) ); 86 xt_add_child( reply, xt_new_node( "tz", buf, NULL ) ); 87 } 88 else if( strcmp( s, XMLNS_TIME ) == 0 ) 89 { 70 71 buf[sizeof(buf) - 1] = 0; 72 time_ep = time(NULL); 73 74 strftime(buf, sizeof(buf) - 1, "%Y%m%dT%H:%M:%S", gmtime(&time_ep)); 75 xt_add_child(reply, xt_new_node("utc", buf, NULL)); 76 77 strftime(buf, sizeof(buf) - 1, "%Z", localtime(&time_ep)); 78 xt_add_child(reply, xt_new_node("tz", buf, NULL)); 79 } else if (strcmp(s, XMLNS_TIME) == 0) { 90 80 time_t time_ep; 91 81 char buf[1024]; 92 93 buf[sizeof(buf)-1] = 0; 94 time_ep = time( NULL ); 95 96 xt_free_node( reply ); 97 reply = xt_new_node( "time", NULL, NULL ); 98 xt_add_attr( reply, "xmlns", XMLNS_TIME ); 99 100 strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%SZ", gmtime( &time_ep ) ); 101 xt_add_child( reply, xt_new_node( "utc", buf, NULL ) ); 102 103 strftime( buf, sizeof( buf ) - 1, "%z", localtime( &time_ep ) ); 104 if( strlen( buf ) >= 5 ) 105 { 82 83 buf[sizeof(buf) - 1] = 0; 84 time_ep = time(NULL); 85 86 xt_free_node(reply); 87 reply = xt_new_node("time", NULL, NULL); 88 xt_add_attr(reply, "xmlns", XMLNS_TIME); 89 90 strftime(buf, sizeof(buf) - 1, "%Y%m%dT%H:%M:%SZ", gmtime(&time_ep)); 91 xt_add_child(reply, xt_new_node("utc", buf, NULL)); 92 93 strftime(buf, sizeof(buf) - 1, "%z", localtime(&time_ep)); 94 if (strlen(buf) >= 5) { 106 95 buf[6] = '\0'; 107 96 buf[5] = buf[4]; … … 109 98 buf[3] = ':'; 110 99 } 111 xt_add_child( reply, xt_new_node( "tzo", buf, NULL ) ); 112 } 113 else if( strcmp( s, XMLNS_PING ) == 0 ) 114 { 115 xt_free_node( reply ); 116 reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), NULL ); 117 if( ( s = xt_find_attr( node, "id" ) ) ) 118 xt_add_attr( reply, "id", s ); 100 xt_add_child(reply, xt_new_node("tzo", buf, NULL)); 101 } else if (strcmp(s, XMLNS_PING) == 0) { 102 xt_free_node(reply); 103 reply = jabber_make_packet("iq", "result", xt_find_attr(node, "from"), NULL); 104 if ((s = xt_find_attr(node, "id"))) { 105 xt_add_attr(reply, "id", s); 106 } 119 107 pack = 0; 120 } 121 else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 ) 122 { 108 } else if (strcmp(s, XMLNS_DISCO_INFO) == 0) { 123 109 const char *features[] = { XMLNS_DISCO_INFO, 124 125 126 127 128 129 130 131 132 133 134 110 XMLNS_VERSION, 111 XMLNS_TIME_OLD, 112 XMLNS_TIME, 113 XMLNS_CHATSTATES, 114 XMLNS_MUC, 115 XMLNS_PING, 116 XMLNS_RECEIPTS, 117 XMLNS_SI, 118 XMLNS_BYTESTREAMS, 119 XMLNS_FILETRANSFER, 120 NULL }; 135 121 const char **f; 136 137 c = xt_new_node( "identity", NULL, NULL ); 138 xt_add_attr( c, "category", "client" ); 139 xt_add_attr( c, "type", "pc" ); 140 xt_add_attr( c, "name", set_getstr( &ic->acc->set, "user_agent" ) ); 141 xt_add_child( reply, c ); 142 143 for( f = features; *f; f ++ ) 144 { 145 c = xt_new_node( "feature", NULL, NULL ); 146 xt_add_attr( c, "var", *f ); 147 xt_add_child( reply, c ); 148 } 149 } 150 else 151 { 152 xt_free_node( reply ); 153 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 122 123 c = xt_new_node("identity", NULL, NULL); 124 xt_add_attr(c, "category", "client"); 125 xt_add_attr(c, "type", "pc"); 126 xt_add_attr(c, "name", set_getstr(&ic->acc->set, "user_agent")); 127 xt_add_child(reply, c); 128 129 for (f = features; *f; f++) { 130 c = xt_new_node("feature", NULL, NULL); 131 xt_add_attr(c, "var", *f); 132 xt_add_child(reply, c); 133 } 134 } else { 135 xt_free_node(reply); 136 reply = jabber_make_error_packet(node, "feature-not-implemented", "cancel", NULL); 154 137 pack = 0; 155 138 } 156 } 157 else if( strcmp( type, "set" ) == 0 ) 158 { 159 if( ( c = xt_find_node( node->children, "si" ) ) && 160 ( s = xt_find_attr( c, "xmlns" ) ) && 161 ( strcmp( s, XMLNS_SI ) == 0 ) ) 162 { 163 return jabber_si_handle_request( ic, node, c ); 164 } 165 else if( !( c = xt_find_node( node->children, "query" ) ) || 166 !( s = xt_find_attr( c, "xmlns" ) ) ) 167 { 139 } else if (strcmp(type, "set") == 0) { 140 if ((c = xt_find_node(node->children, "si")) && 141 (s = xt_find_attr(c, "xmlns")) && 142 (strcmp(s, XMLNS_SI) == 0)) { 143 return jabber_si_handle_request(ic, node, c); 144 } else if (!(c = xt_find_node(node->children, "query")) || 145 !(s = xt_find_attr(c, "xmlns"))) { 168 146 return XT_HANDLED; 169 } 170 else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 171 { 172 /* This is a roster push. XMPP servers send this when someone 173 was added to (or removed from) the buddy list. AFAIK they're 174 sent even if we added this buddy in our own session. */ 175 int bare_len = strlen( jd->me ); 176 177 if( ( s = xt_find_attr( node, "from" ) ) == NULL || 178 ( strncmp( s, jd->me, bare_len ) == 0 && 179 ( s[bare_len] == 0 || s[bare_len] == '/' ) ) ) 180 { 181 jabber_parse_roster( ic, node, NULL ); 182 147 } else if (strcmp(s, XMLNS_ROSTER) == 0) { 148 /* This is a roster push. XMPP servers send this when someone 149 was added to (or removed from) the buddy list. AFAIK they're 150 sent even if we added this buddy in our own session. */ 151 int bare_len = strlen(jd->me); 152 153 if ((s = xt_find_attr(node, "from")) == NULL || 154 (strncmp(s, jd->me, bare_len) == 0 && 155 (s[bare_len] == 0 || s[bare_len] == '/'))) { 156 jabber_parse_roster(ic, node, NULL); 157 183 158 /* Should we generate a reply here? Don't think it's 184 159 very important... */ 185 } 186 else 187 { 188 imcb_log( ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)" ); 189 190 xt_free_node( reply ); 191 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL ); 160 } else { 161 imcb_log(ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)"); 162 163 xt_free_node(reply); 164 reply = jabber_make_error_packet(node, "not-allowed", "cancel", NULL); 192 165 pack = 0; 193 166 } 194 } 195 else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 ) 196 { 167 } else if (strcmp(s, XMLNS_BYTESTREAMS) == 0) { 197 168 /* Bytestream Request (stage 2 of file transfer) */ 198 return jabber_bs_recv_request( ic, node, c ); 199 } 200 else 201 { 202 xt_free_node( reply ); 203 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 169 return jabber_bs_recv_request(ic, node, c); 170 } else { 171 xt_free_node(reply); 172 reply = jabber_make_error_packet(node, "feature-not-implemented", "cancel", NULL); 204 173 pack = 0; 205 174 } 206 175 } 207 176 208 177 /* If we recognized the xmlns and managed to generate a reply, 209 178 finish and send it. */ 210 if( reply ) 211 { 179 if (reply) { 212 180 /* Normally we still have to pack it into an iq-result 213 181 packet, but for errors, for example, we don't. */ 214 if ( pack )215 {216 reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), reply );217 if( ( s = xt_find_attr( node, "id" ) ) )218 xt_add_attr( reply, "id", s );219 } 220 221 st = jabber_write_packet( ic, reply);222 xt_free_node( reply);223 if ( !st )182 if (pack) { 183 reply = jabber_make_packet("iq", "result", xt_find_attr(node, "from"), reply); 184 if ((s = xt_find_attr(node, "id"))) { 185 xt_add_attr(reply, "id", s); 186 } 187 } 188 189 st = jabber_write_packet(ic, reply); 190 xt_free_node(reply); 191 if (!st) { 224 192 return XT_ABORT; 225 } 226 227 return XT_HANDLED; 228 } 229 230 static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 231 static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 232 233 int jabber_init_iq_auth( struct im_connection *ic ) 193 } 194 } 195 196 return XT_HANDLED; 197 } 198 199 static xt_status jabber_do_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 200 static xt_status jabber_finish_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 201 202 int jabber_init_iq_auth(struct im_connection *ic) 234 203 { 235 204 struct jabber_data *jd = ic->proto_data; 236 205 struct xt_node *node; 237 206 int st; 238 239 node = xt_new_node( "query", NULL, xt_new_node( "username", jd->username, NULL ));240 xt_add_attr( node, "xmlns", XMLNS_AUTH);241 node = jabber_make_packet( "iq", "get", NULL, node);242 243 jabber_cache_add( ic, node, jabber_do_iq_auth);244 st = jabber_write_packet( ic, node);245 207 208 node = xt_new_node("query", NULL, xt_new_node("username", jd->username, NULL)); 209 xt_add_attr(node, "xmlns", XMLNS_AUTH); 210 node = jabber_make_packet("iq", "get", NULL, node); 211 212 jabber_cache_add(ic, node, jabber_do_iq_auth); 213 st = jabber_write_packet(ic, node); 214 246 215 return st; 247 216 } 248 217 249 static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)218 static xt_status jabber_do_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 250 219 { 251 220 struct jabber_data *jd = ic->proto_data; … … 253 222 xt_status st; 254 223 char *s; 255 256 if( !( query = xt_find_node( node->children, "query" ) ) ) 257 { 258 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" ); 259 imc_logout( ic, FALSE ); 260 return XT_HANDLED; 261 } 262 224 225 if (!(query = xt_find_node(node->children, "query"))) { 226 imcb_log(ic, "Warning: Received incomplete IQ packet while authenticating"); 227 imc_logout(ic, FALSE); 228 return XT_HANDLED; 229 } 230 263 231 /* Time to authenticate ourselves! */ 264 reply = xt_new_node( "query", NULL, NULL ); 265 xt_add_attr( reply, "xmlns", XMLNS_AUTH ); 266 xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) ); 267 xt_add_child( reply, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) ); 268 269 if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) ) 270 { 232 reply = xt_new_node("query", NULL, NULL); 233 xt_add_attr(reply, "xmlns", XMLNS_AUTH); 234 xt_add_child(reply, xt_new_node("username", jd->username, NULL)); 235 xt_add_child(reply, xt_new_node("resource", set_getstr(&ic->acc->set, "resource"), NULL)); 236 237 if (xt_find_node(query->children, "digest") && (s = xt_find_attr(jd->xt->root, "id"))) { 271 238 /* We can do digest authentication, it seems, and of 272 239 course we prefer that. */ … … 275 242 unsigned char hash[20]; 276 243 int i; 277 278 sha1_init( &sha ); 279 sha1_append( &sha, (unsigned char*) s, strlen( s ) ); 280 sha1_append( &sha, (unsigned char*) ic->acc->pass, strlen( ic->acc->pass ) ); 281 sha1_finish( &sha, hash ); 282 283 for( i = 0; i < 20; i ++ ) 284 sprintf( hash_hex + i * 2, "%02x", hash[i] ); 285 286 xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) ); 287 } 288 else if( xt_find_node( query->children, "password" ) ) 289 { 244 245 sha1_init(&sha); 246 sha1_append(&sha, (unsigned char *) s, strlen(s)); 247 sha1_append(&sha, (unsigned char *) ic->acc->pass, strlen(ic->acc->pass)); 248 sha1_finish(&sha, hash); 249 250 for (i = 0; i < 20; i++) { 251 sprintf(hash_hex + i * 2, "%02x", hash[i]); 252 } 253 254 xt_add_child(reply, xt_new_node("digest", hash_hex, NULL)); 255 } else if (xt_find_node(query->children, "password")) { 290 256 /* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */ 291 xt_add_child( reply, xt_new_node( "password", ic->acc->pass, NULL ) ); 292 } 293 else 294 { 295 xt_free_node( reply ); 296 297 imcb_error( ic, "Can't find suitable authentication method" ); 298 imc_logout( ic, FALSE ); 257 xt_add_child(reply, xt_new_node("password", ic->acc->pass, NULL)); 258 } else { 259 xt_free_node(reply); 260 261 imcb_error(ic, "Can't find suitable authentication method"); 262 imc_logout(ic, FALSE); 299 263 return XT_ABORT; 300 264 } 301 302 reply = jabber_make_packet( "iq", "set", NULL, reply);303 jabber_cache_add( ic, reply, jabber_finish_iq_auth);304 st = jabber_write_packet( ic, reply);305 265 266 reply = jabber_make_packet("iq", "set", NULL, reply); 267 jabber_cache_add(ic, reply, jabber_finish_iq_auth); 268 st = jabber_write_packet(ic, reply); 269 306 270 return st ? XT_HANDLED : XT_ABORT; 307 271 } 308 272 309 static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)273 static xt_status jabber_finish_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 310 274 { 311 275 struct jabber_data *jd = ic->proto_data; 312 276 char *type; 313 314 if( !( type = xt_find_attr( node, "type" ) ) ) 315 { 316 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" ); 317 imc_logout( ic, FALSE ); 318 return XT_HANDLED; 319 } 320 321 if( strcmp( type, "error" ) == 0 ) 322 { 323 imcb_error( ic, "Authentication failure" ); 324 imc_logout( ic, FALSE ); 277 278 if (!(type = xt_find_attr(node, "type"))) { 279 imcb_log(ic, "Warning: Received incomplete IQ packet while authenticating"); 280 imc_logout(ic, FALSE); 281 return XT_HANDLED; 282 } 283 284 if (strcmp(type, "error") == 0) { 285 imcb_error(ic, "Authentication failure"); 286 imc_logout(ic, FALSE); 325 287 return XT_ABORT; 326 } 327 else if( strcmp( type, "result" ) == 0 ) 328 { 288 } else if (strcmp(type, "result") == 0) { 329 289 /* This happens when we just successfully authenticated the 330 290 old (non-SASL) way. */ 331 291 jd->flags |= JFLAG_AUTHENTICATED; 332 if ( !jabber_get_roster( ic ) )292 if (!jabber_get_roster(ic)) { 333 293 return XT_ABORT; 334 if( !jabber_iq_disco_server( ic ) ) 294 } 295 if (!jabber_iq_disco_server(ic)) { 335 296 return XT_ABORT; 336 } 337 338 return XT_HANDLED; 339 } 340 341 xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 297 } 298 } 299 300 return XT_HANDLED; 301 } 302 303 xt_status jabber_pkt_bind_sess(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 342 304 { 343 305 struct jabber_data *jd = ic->proto_data; 344 306 struct xt_node *c, *reply = NULL; 345 307 char *s; 346 347 if( node && ( c = xt_find_node( node->children, "bind" ) ) ) 348 { 349 c = xt_find_node( c->children, "jid" ); 350 if( !c || !c->text ) 351 { 308 309 if (node && (c = xt_find_node(node->children, "bind"))) { 310 c = xt_find_node(c->children, "jid"); 311 if (!c || !c->text) { 352 312 /* Server is crap, but this is no disaster. */ 353 } 354 else if( jabber_compare_jid( jd->me, c->text ) == 0 ) 355 { 356 s = strchr( c->text, '/' ); 357 if( s ) 313 } else if (jabber_compare_jid(jd->me, c->text) == 0) { 314 s = strchr(c->text, '/'); 315 if (s) { 358 316 *s = '\0'; 359 jabber_set_me( ic, c->text ); 360 if( s ) 317 } 318 jabber_set_me(ic, c->text); 319 if (s) { 361 320 *s = '/'; 362 }363 else if( c && c->text_len && ( s = strchr( c->text, '/' )) &&364 strcmp( s + 1, set_getstr( &ic->acc->set, "resource" ) ) != 0 )365 imcb_log( ic, "Server changed session resource string to `%s'", s + 1);366 }367 368 if( jd->flags & JFLAG_WANT_BIND ) 369 {370 reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ));371 xt_add_attr( reply, "xmlns", XMLNS_BIND);321 } 322 } else if (c && c->text_len && (s = strchr(c->text, '/')) && 323 strcmp(s + 1, set_getstr(&ic->acc->set, "resource")) != 0) { 324 imcb_log(ic, "Server changed session resource string to `%s'", s + 1); 325 } 326 } 327 328 if (jd->flags & JFLAG_WANT_BIND) { 329 reply = xt_new_node("bind", NULL, xt_new_node("resource", set_getstr(&ic->acc->set, "resource"), NULL)); 330 xt_add_attr(reply, "xmlns", XMLNS_BIND); 372 331 jd->flags &= ~JFLAG_WANT_BIND; 373 } 374 else if( jd->flags & JFLAG_WANT_SESSION ) 375 { 376 reply = xt_new_node( "session", NULL, NULL ); 377 xt_add_attr( reply, "xmlns", XMLNS_SESSION ); 332 } else if (jd->flags & JFLAG_WANT_SESSION) { 333 reply = xt_new_node("session", NULL, NULL); 334 xt_add_attr(reply, "xmlns", XMLNS_SESSION); 378 335 jd->flags &= ~JFLAG_WANT_SESSION; 379 336 } 380 381 if( reply != NULL ) 382 { 383 reply = jabber_make_packet( "iq", "set", NULL, reply ); 384 jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); 385 386 if( !jabber_write_packet( ic, reply ) ) 337 338 if (reply != NULL) { 339 reply = jabber_make_packet("iq", "set", NULL, reply); 340 jabber_cache_add(ic, reply, jabber_pkt_bind_sess); 341 342 if (!jabber_write_packet(ic, reply)) { 387 343 return XT_ABORT; 388 } 389 else if( ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 ) 390 { 391 if( !jabber_get_roster( ic ) ) 344 } 345 } else if ((jd->flags & (JFLAG_WANT_BIND | JFLAG_WANT_SESSION)) == 0) { 346 if (!jabber_get_roster(ic)) { 392 347 return XT_ABORT; 393 if( !jabber_iq_disco_server( ic ) ) 348 } 349 if (!jabber_iq_disco_server(ic)) { 394 350 return XT_ABORT; 395 } 396 397 return XT_HANDLED; 398 } 399 400 int jabber_get_roster( struct im_connection *ic ) 351 } 352 } 353 354 return XT_HANDLED; 355 } 356 357 int jabber_get_roster(struct im_connection *ic) 401 358 { 402 359 struct xt_node *node; 403 360 int st; 404 405 imcb_log( ic, "Authenticated, requesting buddy list");406 407 node = xt_new_node( "query", NULL, NULL);408 xt_add_attr( node, "xmlns", XMLNS_ROSTER);409 node = jabber_make_packet( "iq", "get", NULL, node);410 411 jabber_cache_add( ic, node, jabber_parse_roster);412 st = jabber_write_packet( ic, node);413 361 362 imcb_log(ic, "Authenticated, requesting buddy list"); 363 364 node = xt_new_node("query", NULL, NULL); 365 xt_add_attr(node, "xmlns", XMLNS_ROSTER); 366 node = jabber_make_packet("iq", "get", NULL, node); 367 368 jabber_cache_add(ic, node, jabber_parse_roster); 369 st = jabber_write_packet(ic, node); 370 414 371 return st; 415 372 } 416 373 417 static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)374 static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 418 375 { 419 376 struct xt_node *query, *c; 420 int initial = ( orig != NULL ); 421 422 if( !( query = xt_find_node( node->children, "query" ) ) ) 423 { 424 imcb_log( ic, "Warning: Received NULL roster packet" ); 425 return XT_HANDLED; 426 } 427 377 int initial = (orig != NULL); 378 379 if (!(query = xt_find_node(node->children, "query"))) { 380 imcb_log(ic, "Warning: Received NULL roster packet"); 381 return XT_HANDLED; 382 } 383 428 384 c = query->children; 429 while( ( c = xt_find_node( c, "item" ) ) ) 430 { 431 struct xt_node *group = xt_find_node( c->children, "group" ); 432 char *jid = xt_find_attr( c, "jid" ); 433 char *name = xt_find_attr( c, "name" ); 434 char *sub = xt_find_attr( c, "subscription" ); 435 436 if( jid && sub ) 437 { 438 if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) ) 439 { 440 imcb_add_buddy( ic, jid, ( group && group->text_len ) ? 441 group->text : NULL ); 442 443 if( name ) 444 imcb_rename_buddy( ic, jid, name ); 445 } 446 else if( strcmp( sub, "remove" ) == 0 ) 447 { 448 jabber_buddy_remove_bare( ic, jid ); 449 imcb_remove_buddy( ic, jid, NULL ); 450 } 451 } 452 385 while ((c = xt_find_node(c, "item"))) { 386 struct xt_node *group = xt_find_node(c->children, "group"); 387 char *jid = xt_find_attr(c, "jid"); 388 char *name = xt_find_attr(c, "name"); 389 char *sub = xt_find_attr(c, "subscription"); 390 391 if (jid && sub) { 392 if ((strcmp(sub, "both") == 0 || strcmp(sub, "to") == 0)) { 393 imcb_add_buddy(ic, jid, (group && group->text_len) ? 394 group->text : NULL); 395 396 if (name) { 397 imcb_rename_buddy(ic, jid, name); 398 } 399 } else if (strcmp(sub, "remove") == 0) { 400 jabber_buddy_remove_bare(ic, jid); 401 imcb_remove_buddy(ic, jid, NULL); 402 } 403 } 404 453 405 c = c->next; 454 406 } 455 456 if( initial ) 457 imcb_connected( ic ); 458 459 return XT_HANDLED; 460 } 461 462 int jabber_get_vcard( struct im_connection *ic, char *bare_jid ) 407 408 if (initial) { 409 imcb_connected(ic); 410 } 411 412 return XT_HANDLED; 413 } 414 415 int jabber_get_vcard(struct im_connection *ic, char *bare_jid) 463 416 { 464 417 struct xt_node *node; 465 466 if( strchr( bare_jid, '/' ) ) 467 return 1; /* This was an error, but return 0 should only be done if the connection died... */ 468 469 node = xt_new_node( "vCard", NULL, NULL ); 470 xt_add_attr( node, "xmlns", XMLNS_VCARD ); 471 node = jabber_make_packet( "iq", "get", bare_jid, node ); 472 473 jabber_cache_add( ic, node, jabber_iq_display_vcard ); 474 return jabber_write_packet( ic, node ); 475 } 476 477 static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 418 419 if (strchr(bare_jid, '/')) { 420 return 1; /* This was an error, but return 0 should only be done if the connection died... */ 421 422 } 423 node = xt_new_node("vCard", NULL, NULL); 424 xt_add_attr(node, "xmlns", XMLNS_VCARD); 425 node = jabber_make_packet("iq", "get", bare_jid, node); 426 427 jabber_cache_add(ic, node, jabber_iq_display_vcard); 428 return jabber_write_packet(ic, node); 429 } 430 431 static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 478 432 { 479 433 struct xt_node *vc, *c, *sc; /* subchild, ic is already in use ;-) */ 480 434 GString *reply; 481 435 char *s; 482 483 if( ( s = xt_find_attr( node, "type" ) ) == NULL || 484 strcmp( s, "result" ) != 0 || 485 ( vc = xt_find_node( node->children, "vCard" ) ) == NULL ) 486 { 487 s = xt_find_attr( orig, "to" ); /* If this returns NULL something's wrong.. */ 488 imcb_log( ic, "Could not retrieve vCard of %s", s ? s : "(NULL)" ); 489 return XT_HANDLED; 490 } 491 492 s = xt_find_attr( orig, "to" ); 493 reply = g_string_new( "vCard information for " ); 494 reply = g_string_append( reply, s ? s : "(NULL)" ); 495 reply = g_string_append( reply, ":\n" ); 496 436 437 if ((s = xt_find_attr(node, "type")) == NULL || 438 strcmp(s, "result") != 0 || 439 (vc = xt_find_node(node->children, "vCard")) == NULL) { 440 s = xt_find_attr(orig, "to"); /* If this returns NULL something's wrong.. */ 441 imcb_log(ic, "Could not retrieve vCard of %s", s ? s : "(NULL)"); 442 return XT_HANDLED; 443 } 444 445 s = xt_find_attr(orig, "to"); 446 reply = g_string_new("vCard information for "); 447 reply = g_string_append(reply, s ? s : "(NULL)"); 448 reply = g_string_append(reply, ":\n"); 449 497 450 /* I hate this format, I really do... */ 498 499 if( ( c = xt_find_node( vc->children, "FN" ) ) && c->text_len ) 500 g_string_append_printf( reply, "Name: %s\n", c->text ); 501 502 if( ( c = xt_find_node( vc->children, "N" ) ) && c->children ) 503 { 504 reply = g_string_append( reply, "Full name:" ); 505 506 if( ( sc = xt_find_node( c->children, "PREFIX" ) ) && sc->text_len ) 507 g_string_append_printf( reply, " %s", sc->text ); 508 if( ( sc = xt_find_node( c->children, "GIVEN" ) ) && sc->text_len ) 509 g_string_append_printf( reply, " %s", sc->text ); 510 if( ( sc = xt_find_node( c->children, "MIDDLE" ) ) && sc->text_len ) 511 g_string_append_printf( reply, " %s", sc->text ); 512 if( ( sc = xt_find_node( c->children, "FAMILY" ) ) && sc->text_len ) 513 g_string_append_printf( reply, " %s", sc->text ); 514 if( ( sc = xt_find_node( c->children, "SUFFIX" ) ) && sc->text_len ) 515 g_string_append_printf( reply, " %s", sc->text ); 516 517 reply = g_string_append_c( reply, '\n' ); 518 } 519 520 if( ( c = xt_find_node( vc->children, "NICKNAME" ) ) && c->text_len ) 521 g_string_append_printf( reply, "Nickname: %s\n", c->text ); 522 523 if( ( c = xt_find_node( vc->children, "BDAY" ) ) && c->text_len ) 524 g_string_append_printf( reply, "Date of birth: %s\n", c->text ); 525 451 452 if ((c = xt_find_node(vc->children, "FN")) && c->text_len) { 453 g_string_append_printf(reply, "Name: %s\n", c->text); 454 } 455 456 if ((c = xt_find_node(vc->children, "N")) && c->children) { 457 reply = g_string_append(reply, "Full name:"); 458 459 if ((sc = xt_find_node(c->children, "PREFIX")) && sc->text_len) { 460 g_string_append_printf(reply, " %s", sc->text); 461 } 462 if ((sc = xt_find_node(c->children, "GIVEN")) && sc->text_len) { 463 g_string_append_printf(reply, " %s", sc->text); 464 } 465 if ((sc = xt_find_node(c->children, "MIDDLE")) && sc->text_len) { 466 g_string_append_printf(reply, " %s", sc->text); 467 } 468 if ((sc = xt_find_node(c->children, "FAMILY")) && sc->text_len) { 469 g_string_append_printf(reply, " %s", sc->text); 470 } 471 if ((sc = xt_find_node(c->children, "SUFFIX")) && sc->text_len) { 472 g_string_append_printf(reply, " %s", sc->text); 473 } 474 475 reply = g_string_append_c(reply, '\n'); 476 } 477 478 if ((c = xt_find_node(vc->children, "NICKNAME")) && c->text_len) { 479 g_string_append_printf(reply, "Nickname: %s\n", c->text); 480 } 481 482 if ((c = xt_find_node(vc->children, "BDAY")) && c->text_len) { 483 g_string_append_printf(reply, "Date of birth: %s\n", c->text); 484 } 485 526 486 /* Slightly alternative use of for... ;-) */ 527 for( c = vc->children; ( c = xt_find_node( c, "EMAIL" ) ); c = c->next ) 528 { 529 if( ( sc = xt_find_node( c->children, "USERID" ) ) == NULL || sc->text_len == 0 ) 487 for (c = vc->children; (c = xt_find_node(c, "EMAIL")); c = c->next) { 488 if ((sc = xt_find_node(c->children, "USERID")) == NULL || sc->text_len == 0) { 530 489 continue; 531 532 if( xt_find_node( c->children, "HOME" ) ) 490 } 491 492 if (xt_find_node(c->children, "HOME")) { 533 493 s = "Home"; 534 else if( xt_find_node( c->children, "WORK" ) )494 } else if (xt_find_node(c->children, "WORK")) { 535 495 s = "Work"; 536 else496 } else { 537 497 s = "Misc."; 538 539 g_string_append_printf( reply, "%s e-mail address: %s\n", s, sc->text ); 540 } 541 542 if( ( c = xt_find_node( vc->children, "URL" ) ) && c->text_len ) 543 g_string_append_printf( reply, "Homepage: %s\n", c->text ); 544 498 } 499 500 g_string_append_printf(reply, "%s e-mail address: %s\n", s, sc->text); 501 } 502 503 if ((c = xt_find_node(vc->children, "URL")) && c->text_len) { 504 g_string_append_printf(reply, "Homepage: %s\n", c->text); 505 } 506 545 507 /* Slightly alternative use of for... ;-) */ 546 for( c = vc->children; ( c = xt_find_node( c, "ADR" ) ); c = c->next ) 547 { 548 if( xt_find_node( c->children, "HOME" ) ) 508 for (c = vc->children; (c = xt_find_node(c, "ADR")); c = c->next) { 509 if (xt_find_node(c->children, "HOME")) { 549 510 s = "Home"; 550 else if( xt_find_node( c->children, "WORK" ) )511 } else if (xt_find_node(c->children, "WORK")) { 551 512 s = "Work"; 552 else513 } else { 553 514 s = "Misc."; 554 555 g_string_append_printf( reply, "%s address: ", s ); 556 557 if( ( sc = xt_find_node( c->children, "STREET" ) ) && sc->text_len ) 558 g_string_append_printf( reply, "%s ", sc->text ); 559 if( ( sc = xt_find_node( c->children, "EXTADR" ) ) && sc->text_len ) 560 g_string_append_printf( reply, "%s, ", sc->text ); 561 if( ( sc = xt_find_node( c->children, "PCODE" ) ) && sc->text_len ) 562 g_string_append_printf( reply, "%s, ", sc->text ); 563 if( ( sc = xt_find_node( c->children, "LOCALITY" ) ) && sc->text_len ) 564 g_string_append_printf( reply, "%s, ", sc->text ); 565 if( ( sc = xt_find_node( c->children, "REGION" ) ) && sc->text_len ) 566 g_string_append_printf( reply, "%s, ", sc->text ); 567 if( ( sc = xt_find_node( c->children, "CTRY" ) ) && sc->text_len ) 568 g_string_append_printf( reply, "%s", sc->text ); 569 570 if( reply->str[reply->len-2] == ',' ) 571 reply = g_string_truncate( reply, reply->len-2 ); 572 573 reply = g_string_append_c( reply, '\n' ); 574 } 575 576 for( c = vc->children; ( c = xt_find_node( c, "TEL" ) ); c = c->next ) 577 { 578 if( ( sc = xt_find_node( c->children, "NUMBER" ) ) == NULL || sc->text_len == 0 ) 515 } 516 517 g_string_append_printf(reply, "%s address: ", s); 518 519 if ((sc = xt_find_node(c->children, "STREET")) && sc->text_len) { 520 g_string_append_printf(reply, "%s ", sc->text); 521 } 522 if ((sc = xt_find_node(c->children, "EXTADR")) && sc->text_len) { 523 g_string_append_printf(reply, "%s, ", sc->text); 524 } 525 if ((sc = xt_find_node(c->children, "PCODE")) && sc->text_len) { 526 g_string_append_printf(reply, "%s, ", sc->text); 527 } 528 if ((sc = xt_find_node(c->children, "LOCALITY")) && sc->text_len) { 529 g_string_append_printf(reply, "%s, ", sc->text); 530 } 531 if ((sc = xt_find_node(c->children, "REGION")) && sc->text_len) { 532 g_string_append_printf(reply, "%s, ", sc->text); 533 } 534 if ((sc = xt_find_node(c->children, "CTRY")) && sc->text_len) { 535 g_string_append_printf(reply, "%s", sc->text); 536 } 537 538 if (reply->str[reply->len - 2] == ',') { 539 reply = g_string_truncate(reply, reply->len - 2); 540 } 541 542 reply = g_string_append_c(reply, '\n'); 543 } 544 545 for (c = vc->children; (c = xt_find_node(c, "TEL")); c = c->next) { 546 if ((sc = xt_find_node(c->children, "NUMBER")) == NULL || sc->text_len == 0) { 579 547 continue; 580 581 if( xt_find_node( c->children, "HOME" ) ) 548 } 549 550 if (xt_find_node(c->children, "HOME")) { 582 551 s = "Home"; 583 else if( xt_find_node( c->children, "WORK" ) )552 } else if (xt_find_node(c->children, "WORK")) { 584 553 s = "Work"; 585 else554 } else { 586 555 s = "Misc."; 587 588 g_string_append_printf( reply, "%s phone number: %s\n", s, sc->text ); 589 } 590 591 if( ( c = xt_find_node( vc->children, "DESC" ) ) && c->text_len ) 592 g_string_append_printf( reply, "Other information:\n%s", c->text ); 593 556 } 557 558 g_string_append_printf(reply, "%s phone number: %s\n", s, sc->text); 559 } 560 561 if ((c = xt_find_node(vc->children, "DESC")) && c->text_len) { 562 g_string_append_printf(reply, "Other information:\n%s", c->text); 563 } 564 594 565 /* *sigh* */ 595 596 imcb_log( ic, "%s", reply->str);597 g_string_free( reply, TRUE);598 599 return XT_HANDLED; 600 } 601 602 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig);603 604 int jabber_add_to_roster( struct im_connection *ic, const char *handle, const char *name, const char *group)566 567 imcb_log(ic, "%s", reply->str); 568 g_string_free(reply, TRUE); 569 570 return XT_HANDLED; 571 } 572 573 static xt_status jabber_add_to_roster_callback(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 574 575 int jabber_add_to_roster(struct im_connection *ic, const char *handle, const char *name, const char *group) 605 576 { 606 577 struct xt_node *node; 607 578 int st; 608 579 609 580 /* Build the item entry */ 610 node = xt_new_node( "item", NULL, NULL ); 611 xt_add_attr( node, "jid", handle ); 612 if( name ) 613 xt_add_attr( node, "name", name ); 614 if( group ) 615 xt_add_child( node, xt_new_node( "group", group, NULL ) ); 616 581 node = xt_new_node("item", NULL, NULL); 582 xt_add_attr(node, "jid", handle); 583 if (name) { 584 xt_add_attr(node, "name", name); 585 } 586 if (group) { 587 xt_add_child(node, xt_new_node("group", group, NULL)); 588 } 589 617 590 /* And pack it into a roster-add packet */ 618 node = xt_new_node( "query", NULL, node);619 xt_add_attr( node, "xmlns", XMLNS_ROSTER);620 node = jabber_make_packet( "iq", "set", NULL, node);621 jabber_cache_add( ic, node, jabber_add_to_roster_callback);622 623 st = jabber_write_packet( ic, node);624 591 node = xt_new_node("query", NULL, node); 592 xt_add_attr(node, "xmlns", XMLNS_ROSTER); 593 node = jabber_make_packet("iq", "set", NULL, node); 594 jabber_cache_add(ic, node, jabber_add_to_roster_callback); 595 596 st = jabber_write_packet(ic, node); 597 625 598 return st; 626 599 } 627 600 628 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)601 static xt_status jabber_add_to_roster_callback(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 629 602 { 630 603 char *s, *jid = NULL; 631 604 struct xt_node *c; 632 633 if( ( c = xt_find_node( orig->children, "query" ) ) && 634 ( c = xt_find_node( c->children, "item" ) ) && 635 ( jid = xt_find_attr( c, "jid" ) ) && 636 ( s = xt_find_attr( node, "type" ) ) && 637 strcmp( s, "result" ) == 0 ) 638 { 639 if( bee_user_by_handle( ic->bee, ic, jid ) == NULL ) 640 imcb_add_buddy( ic, jid, NULL ); 641 } 642 else 643 { 644 imcb_log( ic, "Error while adding `%s' to your contact list.", 645 jid ? jid : "(unknown handle)" ); 646 } 647 648 return XT_HANDLED; 649 } 650 651 int jabber_remove_from_roster( struct im_connection *ic, char *handle ) 605 606 if ((c = xt_find_node(orig->children, "query")) && 607 (c = xt_find_node(c->children, "item")) && 608 (jid = xt_find_attr(c, "jid")) && 609 (s = xt_find_attr(node, "type")) && 610 strcmp(s, "result") == 0) { 611 if (bee_user_by_handle(ic->bee, ic, jid) == NULL) { 612 imcb_add_buddy(ic, jid, NULL); 613 } 614 } else { 615 imcb_log(ic, "Error while adding `%s' to your contact list.", 616 jid ? jid : "(unknown handle)"); 617 } 618 619 return XT_HANDLED; 620 } 621 622 int jabber_remove_from_roster(struct im_connection *ic, char *handle) 652 623 { 653 624 struct xt_node *node; 654 625 int st; 655 626 656 627 /* Build the item entry */ 657 node = xt_new_node( "item", NULL, NULL);658 xt_add_attr( node, "jid", handle);659 xt_add_attr( node, "subscription", "remove");660 628 node = xt_new_node("item", NULL, NULL); 629 xt_add_attr(node, "jid", handle); 630 xt_add_attr(node, "subscription", "remove"); 631 661 632 /* And pack it into a roster-add packet */ 662 node = xt_new_node( "query", NULL, node);663 xt_add_attr( node, "xmlns", XMLNS_ROSTER);664 node = jabber_make_packet( "iq", "set", NULL, node);665 666 st = jabber_write_packet( ic, node);667 668 xt_free_node( node);633 node = xt_new_node("query", NULL, node); 634 xt_add_attr(node, "xmlns", XMLNS_ROSTER); 635 node = jabber_make_packet("iq", "set", NULL, node); 636 637 st = jabber_write_packet(ic, node); 638 639 xt_free_node(node); 669 640 return st; 670 641 } 671 642 672 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig);673 674 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid)643 xt_status jabber_iq_parse_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 644 645 xt_status jabber_iq_query_features(struct im_connection *ic, char *bare_jid) 675 646 { 676 647 struct xt_node *node, *query; 677 648 struct jabber_buddy *bud; 678 679 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL ) 680 { 649 650 if ((bud = jabber_buddy_by_jid(ic, bare_jid, 0)) == NULL) { 681 651 /* Who cares about the unknown... */ 682 imcb_log( 683 return XT_HANDLED; 684 } 685 686 if ( bud->features )/* been here already */687 return XT_HANDLED; 688 689 node = xt_new_node( "query", NULL, NULL ); 690 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO);691 692 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) ) 693 {694 imcb_log( ic, "WARNING: Couldn't generate feature query");695 xt_free_node( node);696 return XT_HANDLED; 697 } 698 699 jabber_cache_add( ic, query, jabber_iq_parse_features);700 701 return jabber_write_packet( ic, query) ? XT_HANDLED : XT_ABORT;702 } 703 704 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)652 imcb_log(ic, "Couldn't find buddy: %s", bare_jid); 653 return XT_HANDLED; 654 } 655 656 if (bud->features) { /* been here already */ 657 return XT_HANDLED; 658 } 659 660 node = xt_new_node("query", NULL, NULL); 661 xt_add_attr(node, "xmlns", XMLNS_DISCO_INFO); 662 663 if (!(query = jabber_make_packet("iq", "get", bare_jid, node))) { 664 imcb_log(ic, "WARNING: Couldn't generate feature query"); 665 xt_free_node(node); 666 return XT_HANDLED; 667 } 668 669 jabber_cache_add(ic, query, jabber_iq_parse_features); 670 671 return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT; 672 } 673 674 xt_status jabber_iq_parse_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 705 675 { 706 676 struct xt_node *c; … … 708 678 char *feature, *xmlns, *from; 709 679 710 if( !( from = xt_find_attr( node, "from" ) ) || 711 !( c = xt_find_node( node->children, "query" ) ) || 712 !( xmlns = xt_find_attr( c, "xmlns" ) ) || 713 !( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) ) 714 { 715 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 716 return XT_HANDLED; 717 } 718 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 719 { 680 if (!(from = xt_find_attr(node, "from")) || 681 !(c = xt_find_node(node->children, "query")) || 682 !(xmlns = xt_find_attr(c, "xmlns")) || 683 !(strcmp(xmlns, XMLNS_DISCO_INFO) == 0)) { 684 imcb_log(ic, "WARNING: Received incomplete IQ-result packet for discover"); 685 return XT_HANDLED; 686 } 687 if ((bud = jabber_buddy_by_jid(ic, from, 0)) == NULL) { 720 688 /* Who cares about the unknown... */ 721 imcb_log( ic, "Couldn't find buddy: %s", from);722 return XT_HANDLED; 723 } 724 689 imcb_log(ic, "Couldn't find buddy: %s", from); 690 return XT_HANDLED; 691 } 692 725 693 c = c->children; 726 while ( ( c = xt_find_node( c, "feature" ) ) )727 {728 feature = xt_find_attr( c, "var" );729 if( feature )730 bud->features = g_slist_append( bud->features, g_strdup( feature ) );694 while ((c = xt_find_node(c, "feature"))) { 695 feature = xt_find_attr(c, "var"); 696 if (feature) { 697 bud->features = g_slist_append(bud->features, g_strdup(feature)); 698 } 731 699 c = c->next; 732 700 } … … 735 703 } 736 704 737 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig);738 739 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns)705 xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig); 706 707 xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns) 740 708 { 741 709 struct xt_node *node, *query; 742 710 struct jabber_data *jd = ic->proto_data; 743 744 node = xt_new_node( "query", NULL, NULL ); 745 xt_add_attr( node, "xmlns", xmlns ); 746 747 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) ) 748 { 749 imcb_log( ic, "WARNING: Couldn't generate server query" ); 750 xt_free_node( node ); 711 712 node = xt_new_node("query", NULL, NULL); 713 xt_add_attr(node, "xmlns", xmlns); 714 715 if (!(query = jabber_make_packet("iq", "get", jid, node))) { 716 imcb_log(ic, "WARNING: Couldn't generate server query"); 717 xt_free_node(node); 751 718 } 752 719 753 720 jd->have_streamhosts--; 754 jabber_cache_add( ic, query, jabber_iq_parse_server_features);755 756 return jabber_write_packet( ic, query) ? XT_HANDLED : XT_ABORT;721 jabber_cache_add(ic, query, jabber_iq_parse_server_features); 722 723 return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT; 757 724 } 758 725 … … 760 727 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info 761 728 */ 762 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig)729 xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) 763 730 { 764 731 struct xt_node *c; … … 766 733 char *xmlns, *from; 767 734 768 if( !( c = xt_find_node( node->children, "query" ) ) || 769 !( from = xt_find_attr( node, "from" ) ) || 770 !( xmlns = xt_find_attr( c, "xmlns" ) ) ) 771 { 772 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 735 if (!(c = xt_find_node(node->children, "query")) || 736 !(from = xt_find_attr(node, "from")) || 737 !(xmlns = xt_find_attr(c, "xmlns"))) { 738 imcb_log(ic, "WARNING: Received incomplete IQ-result packet for discover"); 773 739 return XT_HANDLED; 774 740 } … … 776 742 jd->have_streamhosts++; 777 743 778 if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 ) 779 { 744 if (strcmp(xmlns, XMLNS_DISCO_ITEMS) == 0) { 780 745 char *itemjid; 781 746 782 747 /* answer from server */ 783 748 784 749 c = c->children; 785 while ( ( c = xt_find_node( c, "item" ) ) )786 {787 itemjid = xt_find_attr( c, "jid" ); 788 789 if( itemjid )790 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO );750 while ((c = xt_find_node(c, "item"))) { 751 itemjid = xt_find_attr(c, "jid"); 752 753 if (itemjid) { 754 jabber_iq_query_server(ic, itemjid, XMLNS_DISCO_INFO); 755 } 791 756 792 757 c = c->next; 793 758 } 794 } 795 else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) 796 { 759 } else if (strcmp(xmlns, XMLNS_DISCO_INFO) == 0) { 797 760 char *category, *type; 798 761 … … 800 763 801 764 c = c->children; 802 while ( ( c = xt_find_node( c, "identity" ) ) )803 {804 category = xt_find_attr( c, "category");805 type = xt_find_attr( c, "type" ); 806 807 if( type && ( strcmp( type, "bytestreams" ) == 0 ) &&808 category && ( strcmp( category, "proxy" ) == 0 ) )809 jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS );765 while ((c = xt_find_node(c, "identity"))) { 766 category = xt_find_attr(c, "category"); 767 type = xt_find_attr(c, "type"); 768 769 if (type && (strcmp(type, "bytestreams") == 0) && 770 category && (strcmp(category, "proxy") == 0)) { 771 jabber_iq_query_server(ic, from, XMLNS_BYTESTREAMS); 772 } 810 773 811 774 c = c->next; 812 775 } 813 } 814 else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 ) 815 { 776 } else if (strcmp(xmlns, XMLNS_BYTESTREAMS) == 0) { 816 777 char *host, *jid, *port_s; 817 778 int port; … … 819 780 /* answer from proxy */ 820 781 821 if( ( c = xt_find_node( c->children, "streamhost" ) ) && 822 ( host = xt_find_attr( c, "host" ) ) && 823 ( port_s = xt_find_attr( c, "port" ) ) && 824 ( sscanf( port_s, "%d", &port ) == 1 ) && 825 ( jid = xt_find_attr( c, "jid" ) ) ) 826 { 827 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); 828 829 sh->jid = g_strdup( jid ); 830 sh->host = g_strdup( host ); 831 g_snprintf( sh->port, sizeof( sh->port ), "%u", port ); 832 833 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); 834 jd->streamhosts = g_slist_append( jd->streamhosts, sh ); 835 } 836 } 837 838 if( jd->have_streamhosts == 0 ) 782 if ((c = xt_find_node(c->children, "streamhost")) && 783 (host = xt_find_attr(c, "host")) && 784 (port_s = xt_find_attr(c, "port")) && 785 (sscanf(port_s, "%d", &port) == 1) && 786 (jid = xt_find_attr(c, "jid"))) { 787 jabber_streamhost_t *sh = g_new0(jabber_streamhost_t, 1); 788 789 sh->jid = g_strdup(jid); 790 sh->host = g_strdup(host); 791 g_snprintf(sh->port, sizeof(sh->port), "%u", port); 792 793 imcb_log(ic, "Proxy found: jid %s host %s port %u", jid, host, port); 794 jd->streamhosts = g_slist_append(jd->streamhosts, sh); 795 } 796 } 797 798 if (jd->have_streamhosts == 0) { 839 799 jd->have_streamhosts++; 840 841 return XT_HANDLED; 842 } 843 844 static xt_status jabber_iq_version_response( struct im_connection *ic, 845 struct xt_node *node, struct xt_node *orig ); 846 847 void jabber_iq_version_send( struct im_connection *ic, struct jabber_buddy *bud, void *data ) 800 } 801 802 return XT_HANDLED; 803 } 804 805 static xt_status jabber_iq_version_response(struct im_connection *ic, 806 struct xt_node *node, struct xt_node *orig); 807 808 void jabber_iq_version_send(struct im_connection *ic, struct jabber_buddy *bud, void *data) 848 809 { 849 810 struct xt_node *node, *query; 850 851 node = xt_new_node( "query", NULL, NULL);852 xt_add_attr( node, "xmlns", XMLNS_VERSION);853 query = jabber_make_packet( "iq", "get", bud->full_jid, node);854 jabber_cache_add( ic, query, jabber_iq_version_response);855 856 jabber_write_packet( ic, query);857 } 858 859 static xt_status jabber_iq_version_response( 860 struct xt_node *node, struct xt_node *orig)811 812 node = xt_new_node("query", NULL, NULL); 813 xt_add_attr(node, "xmlns", XMLNS_VERSION); 814 query = jabber_make_packet("iq", "get", bud->full_jid, node); 815 jabber_cache_add(ic, query, jabber_iq_version_response); 816 817 jabber_write_packet(ic, query); 818 } 819 820 static xt_status jabber_iq_version_response(struct im_connection *ic, 821 struct xt_node *node, struct xt_node *orig) 861 822 { 862 823 struct xt_node *query; … … 866 827 bee_user_t *bu; 867 828 struct jabber_buddy *bud = NULL; 868 869 if( ( s = xt_find_attr( node, "from" ) ) && 870 ( bud = jabber_buddy_by_jid( ic, s, 0 ) ) && 871 ( query = xt_find_node( node->children, "query" ) ) && 872 ( bu = bee_user_by_handle( ic->bee, ic, bud->bare_jid ) ) ) 873 { 874 rets = g_string_new( "Resource " ); 875 g_string_append( rets, bud->resource ); 876 } 877 else 878 return XT_HANDLED; 879 880 for( query = query->children; query; query = query->next ) 881 if( query->text_len > 0 ) 882 g_string_append_printf( rets, " %s: %s,", query->name, query->text ); 883 884 g_string_truncate( rets, rets->len - 1 ); 829 830 if ((s = xt_find_attr(node, "from")) && 831 (bud = jabber_buddy_by_jid(ic, s, 0)) && 832 (query = xt_find_node(node->children, "query")) && 833 (bu = bee_user_by_handle(ic->bee, ic, bud->bare_jid))) { 834 rets = g_string_new("Resource "); 835 g_string_append(rets, bud->resource); 836 } else { 837 return XT_HANDLED; 838 } 839 840 for (query = query->children; query; query = query->next) { 841 if (query->text_len > 0) { 842 g_string_append_printf(rets, " %s: %s,", query->name, query->text); 843 } 844 } 845 846 g_string_truncate(rets, rets->len - 1); 885 847 ret[0] = rets->str; 886 imcb_buddy_action_response( bu, "VERSION", ret, NULL);887 g_string_free( rets, TRUE);888 889 return XT_HANDLED; 890 } 891 892 static xt_status jabber_iq_disco_server_response( 893 struct xt_node *node, struct xt_node *orig);894 895 static int jabber_iq_disco_server( struct im_connection *ic)848 imcb_buddy_action_response(bu, "VERSION", ret, NULL); 849 g_string_free(rets, TRUE); 850 851 return XT_HANDLED; 852 } 853 854 static xt_status jabber_iq_disco_server_response(struct im_connection *ic, 855 struct xt_node *node, struct xt_node *orig); 856 857 static int jabber_iq_disco_server(struct im_connection *ic) 896 858 { 897 859 struct xt_node *node, *iq; 898 860 struct jabber_data *jd = ic->proto_data; 899 900 node = xt_new_node( "query", NULL, NULL);901 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO);902 iq = jabber_make_packet( "iq", "get", jd->server, node);903 904 jabber_cache_add( ic, iq, jabber_iq_disco_server_response);905 return jabber_write_packet( ic, iq);906 } 907 908 static xt_status jabber_iq_disco_server_response( 909 struct xt_node *node, struct xt_node *orig)861 862 node = xt_new_node("query", NULL, NULL); 863 xt_add_attr(node, "xmlns", XMLNS_DISCO_INFO); 864 iq = jabber_make_packet("iq", "get", jd->server, node); 865 866 jabber_cache_add(ic, iq, jabber_iq_disco_server_response); 867 return jabber_write_packet(ic, iq); 868 } 869 870 static xt_status jabber_iq_disco_server_response(struct im_connection *ic, 871 struct xt_node *node, struct xt_node *orig) 910 872 { 911 873 struct jabber_data *jd = ic->proto_data; 912 874 struct xt_node *id; 913 914 if( ( id = xt_find_path( node, "query/identity" ) ) ) 915 { 875 876 if ((id = xt_find_path(node, "query/identity"))) { 916 877 char *cat, *type, *name; 917 918 if ( !( cat = xt_find_attr( id, "category" )) ||919 !( type = xt_find_attr( id, "type" )) ||920 !( name = xt_find_attr( id, "name" ) ) )878 879 if (!(cat = xt_find_attr(id, "category")) || 880 !(type = xt_find_attr(id, "type")) || 881 !(name = xt_find_attr(id, "name"))) { 921 882 return XT_HANDLED; 922 923 if( strcmp( cat, "server" ) == 0 && strcmp( type, "im" ) == 0 && 924 strstr( name, "Google" ) != NULL ) 883 } 884 885 if (strcmp(cat, "server") == 0 && strcmp(type, "im") == 0 && 886 strstr(name, "Google") != NULL) { 925 887 jd->flags |= JFLAG_GTALK; 926 } 927 928 return XT_HANDLED; 929 } 888 } 889 } 890 891 return XT_HANDLED; 892 }
Note: See TracChangeset
for help on using the changeset viewer.