~ubuntu-dev/ubuntu/lucid/zabbix/lucid-201002110857

« back to all changes in this revision

Viewing changes to src/libs/zbxjabber/jabber.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Haas
  • Date: 2009-10-10 12:21:16 UTC
  • mfrom: (1.1.10 upstream) (8.2.6 sid)
  • Revision ID: james.westby@ubuntu.com-20091010122116-44k2zdq57rb40i6z
Tags: 1:1.6.6-2
* debian/po/ja.po updated (Closes: #548651)
* debian/po/cs.po updated (Closes: #548675)
* debian/po/sv.po updated (Closes: #548796)
* debian/po/de.po updated (Closes: #549248)
* debian/po/it.po updated (Closes: #549579)
* debian/po/pt.po updated (Closes: #550087)
* debian/po/ru.po updated (Closes: #550102)
* debian/po/es.po updated (Closes: #550173)
* debian/po/fr.po updated (Closes: #550315)
* Manpages for zabbix_server and zabbix_agent added (Closes: #496696)
* Added hint about the difference of the zabbix_agent.conf and
  zabbix_agentd.conf in each config file as a comment. (Closes: #548701)

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
        close (*sock);
36
36
}
37
37
 
38
 
static int      zbx_j_sock = -1;
 
38
static int              zbx_j_sock = -1;
 
39
static const char       *__module_name = "JABBER";
39
40
 
40
41
static int
41
42
zbx_io_connect (iksparser *prs, void **socketptr, const char *server, int port)
165
166
} jabber_session_t, *jabber_session_p;
166
167
 
167
168
static jabber_session_p jsess = NULL;
 
169
static char             *jabber_error = NULL;
 
170
static int              jabber_error_len = 0;
168
171
 
169
 
static int on_result (jabber_session_p sess, ikspak *pak)
 
172
static int on_result(jabber_session_p sess, ikspak *pak)
170
173
{
171
 
        zabbix_log (LOG_LEVEL_DEBUG, "JABBER: ready");
 
174
        const char      *__function_name = "on_result";
 
175
 
 
176
        zabbix_log(LOG_LEVEL_DEBUG, "%s: In %s()", __module_name, __function_name);
 
177
 
172
178
        sess->status = JABBER_READY;
 
179
 
 
180
        zabbix_log(LOG_LEVEL_DEBUG, "%s: End of %s()", __module_name, __function_name);
 
181
 
173
182
        return IKS_FILTER_EAT;
174
183
}
175
184
 
190
199
 ******************************************************************************/
191
200
static int disconnect_jabber()
192
201
{
193
 
        if ( JABBER_DISCONNECTED != jsess->status)
 
202
        const char      *__function_name = "disconnect_jabber";
 
203
 
 
204
        zabbix_log(LOG_LEVEL_DEBUG, "%s: In %s()", __module_name, __function_name);
 
205
        
 
206
        if (JABBER_DISCONNECTED != jsess->status)
194
207
                iks_disconnect(jsess->prs);
195
208
        
196
 
        zabbix_log(LOG_LEVEL_INFORMATION, "JABBER: disconnecting");
197
 
        
198
209
        if (jsess->my_filter)
199
210
        {
200
211
                iks_filter_delete (jsess->my_filter);
213
224
 
214
225
        jsess->status = JABBER_DISCONNECTED;
215
226
 
 
227
        zabbix_log(LOG_LEVEL_DEBUG, "%s: End of %s()", __module_name, __function_name);
 
228
 
216
229
        return SUCCEED;
217
230
}
218
231
 
219
 
static int on_stream (jabber_session_p sess, int type, iks *node)
 
232
static int on_stream(jabber_session_p sess, int type, iks *node)
220
233
{
221
 
        iks *x = NULL;
222
 
        ikspak *pak = NULL;
 
234
        const char      *__function_name = "on_stream";
 
235
        iks             *x = NULL;
 
236
        ikspak          *pak = NULL;
 
237
        int             ret = IKS_OK;
 
238
 
 
239
        zabbix_log(LOG_LEVEL_DEBUG, "%s: In %s()", __module_name, __function_name);
223
240
 
224
241
        switch (type) {
225
242
                case IKS_NODE_START:
226
 
                        if (sess->opt_use_tls && !iks_is_secure (sess->prs)) {
227
 
                                iks_start_tls (sess->prs);
228
 
                                break;
229
 
                        }
230
 
                        if (!sess->opt_use_sasl) {
231
 
                                x = iks_make_auth (sess->acc, sess->pass, iks_find_attrib (node, "id"));
232
 
                                iks_insert_attrib (x, "id", "auth");
233
 
                                iks_send (sess->prs, x);
234
 
                                iks_delete (x);
235
 
                        }
236
243
                        break;
237
 
 
238
244
                case IKS_NODE_NORMAL:
239
 
                        if (strcmp ("stream:features", iks_name (node)) == 0) {
240
 
                                sess->features = iks_stream_features (node);
241
 
                                if (sess->opt_use_sasl) {
242
 
                                        if (sess->opt_use_tls && !iks_is_secure (sess->prs)) break;
243
 
                                        if (sess->status == JABBER_AUTHORIZED) {
244
 
                                                if (sess->features & IKS_STREAM_BIND) {
245
 
                                                        x = iks_make_resource_bind (sess->acc);
246
 
                                                        iks_send (sess->prs, x);
247
 
                                                        iks_delete (x);
 
245
                        if (0 == strcmp("stream:features", iks_name(node)))
 
246
                        {
 
247
                                sess->features = iks_stream_features(node);
 
248
 
 
249
                                if (IKS_STREAM_STARTTLS == (sess->features & IKS_STREAM_STARTTLS))
 
250
                                        iks_start_tls (sess->prs);
 
251
                                else
 
252
                                {
 
253
                                        if (sess->status == JABBER_AUTHORIZED)
 
254
                                        {
 
255
                                                if (IKS_STREAM_BIND == (sess->features & IKS_STREAM_BIND))
 
256
                                                {
 
257
                                                        x = iks_make_resource_bind(sess->acc);
 
258
                                                        iks_send(sess->prs, x);
 
259
                                                        iks_delete(x);
248
260
                                                }
249
 
                                                if (sess->features & IKS_STREAM_SESSION) {
 
261
                                                if (IKS_STREAM_SESSION == (sess->features & IKS_STREAM_SESSION))
 
262
                                                {
250
263
                                                        x = iks_make_session ();
251
 
                                                        iks_insert_attrib (x, "id", "auth");
252
 
                                                        iks_send (sess->prs, x);
253
 
                                                        iks_delete (x);
 
264
                                                        iks_insert_attrib(x, "id", "auth");
 
265
                                                        iks_send(sess->prs, x);
 
266
                                                        iks_delete(x);
254
267
                                                }
255
 
                                        } else {
256
 
                                                if (sess->features & IKS_STREAM_SASL_MD5)
257
 
                                                        iks_start_sasl (sess->prs, IKS_SASL_DIGEST_MD5, sess->acc->user, sess->pass);
258
 
                                                else if (sess->features & IKS_STREAM_SASL_PLAIN)
259
 
                                                        iks_start_sasl (sess->prs, IKS_SASL_PLAIN, sess->acc->user, sess->pass);
 
268
                                        }
 
269
                                        else
 
270
                                        {
 
271
                                                if (IKS_STREAM_SASL_MD5 == (sess->features & IKS_STREAM_SASL_MD5))
 
272
                                                        iks_start_sasl(sess->prs, IKS_SASL_DIGEST_MD5, sess->acc->user, sess->pass);
 
273
                                                else if (IKS_STREAM_SASL_PLAIN == (sess->features & IKS_STREAM_SASL_PLAIN))
 
274
                                                        iks_start_sasl(sess->prs, IKS_SASL_PLAIN, sess->acc->user, sess->pass);
260
275
                                        }
261
276
                                }
262
 
                        } else if (strcmp ("failure", iks_name (node)) == 0) {
263
 
                                zabbix_log (LOG_LEVEL_WARNING, "JABBER: sasl authentication failed");
264
 
                        } else if (strcmp ("success", iks_name (node)) == 0) {
265
 
                                zabbix_log (LOG_LEVEL_DEBUG, "JABBER: authorized");
 
277
                        }
 
278
                        else if (strcmp("failure", iks_name(node)) == 0)
 
279
                        {
 
280
                                zbx_snprintf(jabber_error, jabber_error_len, "sasl authentication failed");
 
281
                                jsess->status = JABBER_ERROR;
 
282
                                ret = IKS_HOOK;
 
283
                        }
 
284
                        else if (strcmp("success", iks_name(node)) == 0)
 
285
                        {
 
286
                                zabbix_log(LOG_LEVEL_DEBUG, "%s: authorized",
 
287
                                                __module_name);
266
288
                                sess->status = JABBER_AUTHORIZED;
267
 
                                iks_send_header (sess->prs, sess->acc->server);
268
 
                        } else {
269
 
                                pak = iks_packet (node);
270
 
                                iks_filter_packet (sess->my_filter, pak);
 
289
                                iks_send_header(sess->prs, sess->acc->server);
 
290
                        }
 
291
                        else
 
292
                        {
 
293
                                pak = iks_packet(node);
 
294
                                iks_filter_packet(sess->my_filter, pak);
 
295
                                if (JABBER_READY == jsess->status)
 
296
                                        ret = IKS_HOOK;
271
297
                        }
272
298
                        break;
273
 
 
274
299
                case IKS_NODE_STOP:
275
 
                        zabbix_log (LOG_LEVEL_WARNING, "JABBER: server disconnected");
276
 
                        disconnect_jabber();
 
300
                        zbx_snprintf(jabber_error, jabber_error_len, "server disconnected");
 
301
                        jsess->status = JABBER_ERROR;
 
302
                        ret = IKS_HOOK;
277
303
                        break;
278
304
                case IKS_NODE_ERROR:
279
 
                        zabbix_log (LOG_LEVEL_WARNING, "JABBER: stream error");
 
305
                        zbx_snprintf(jabber_error, jabber_error_len, "stream error");
280
306
                        jsess->status = JABBER_ERROR;
 
307
                        ret = IKS_HOOK;
281
308
        }
282
309
 
283
 
        if (node) iks_delete (node);
284
 
        return IKS_OK;
 
310
        if (node)
 
311
               iks_delete(node);
 
312
 
 
313
        zabbix_log(LOG_LEVEL_DEBUG, "%s: End of %s()", __module_name, __function_name);
 
314
 
 
315
        return ret;
285
316
}
286
317
 
287
318
static int on_error (void *user_data, ikspak *pak)
288
319
{
289
 
        zabbix_log (LOG_LEVEL_WARNING, "JABBER: authorization failed");
 
320
        zbx_snprintf(jabber_error, jabber_error_len, "authorization failed");
290
321
 
291
322
        jsess->status = JABBER_ERROR;
 
323
 
292
324
        return IKS_FILTER_EAT;
293
325
}
294
326
 
295
327
#ifdef DEBUG
296
328
static void on_log (jabber_session_p sess, const char *data, size_t size, int is_incoming)
297
329
{
298
 
        zabbix_log(LOG_LEVEL_DEBUG, "%s%s [%s]\n", iks_is_secure (sess->prs) ? "Sec" : "", is_incoming ? "RECV" : "SEND", data);
 
330
        zabbix_log(LOG_LEVEL_DEBUG, "%s: %s%s: %s",
 
331
                        __module_name, iks_is_secure (sess->prs) ? "Sec" : "", is_incoming ? "RECV" : "SEND", data);
299
332
}
300
333
#endif
301
334
 
315
348
 * Comments:                                                                  *
316
349
 *                                                                            *
317
350
 ******************************************************************************/
318
 
static int connect_jabber(const char *jabber_id, const char *password, int use_sasl, int port, char *error, int len)
 
351
static int connect_jabber(const char *jabber_id, const char *password, int use_sasl, int port)
319
352
{
320
 
        char *buf = NULL;
321
 
 
322
 
        int iks_error = IKS_OK;
 
353
        const char      *__function_name = "connect_jabber";
 
354
        char            *buf = NULL;
 
355
        int             iks_error, timeout, ret = FAIL;
323
356
                
324
 
        zabbix_log(LOG_LEVEL_DEBUG, "JABBER: connecting as %s", jabber_id);
 
357
        zabbix_log(LOG_LEVEL_DEBUG, "%s: In %s('%s')",
 
358
                        __module_name, __function_name, jabber_id);
325
359
 
326
 
        if(NULL == jsess)
 
360
        if (NULL == jsess)
327
361
        {
328
362
                jsess = zbx_malloc(jsess, sizeof (jabber_session_t));
329
363
                memset (jsess, 0, sizeof (jabber_session_t));
330
364
        }
331
 
        else
332
 
        {
 
365
        else if (JABBER_DISCONNECTED != jsess->status)
333
366
                disconnect_jabber();
334
 
        }
335
 
 
336
 
        jsess->pass = strdup(password);
337
 
        jsess->opt_use_sasl = use_sasl;
338
 
 
339
 
        if ( !(jsess->prs = iks_stream_new (IKS_NS_CLIENT, jsess, (iksStreamHook *) on_stream)) )
 
367
 
 
368
        if (NULL == (jsess->prs = iks_stream_new(IKS_NS_CLIENT, jsess, (iksStreamHook *)on_stream)))
340
369
        {
341
 
                zbx_snprintf(error, len, "Cannot create iksemel parser [%s]", strerror(errno));
 
370
                zbx_snprintf(jabber_error, jabber_error_len, "Cannot create iksemel parser: %s",
 
371
                                strerror(errno));
342
372
                goto lbl_fail;
343
373
        }
344
374
 
345
375
#ifdef DEBUG
346
 
        iks_set_log_hook (jsess->prs, (iksLogHook *) on_log);
 
376
        iks_set_log_hook (jsess->prs, (iksLogHook *)on_log);
347
377
#endif /* DEBUG */
348
378
 
349
 
        jsess->acc = iks_id_new (iks_parser_stack (jsess->prs), jabber_id);
 
379
        jsess->acc = iks_id_new(iks_parser_stack(jsess->prs), jabber_id);
350
380
 
351
381
        if (NULL == jsess->acc->resource) {
352
382
                /* user gave no resource name, use the default */
353
 
                buf = zbx_dsprintf (buf, "%s@%s/%s", jsess->acc->user, jsess->acc->server, "ZABBIX");
354
 
                jsess->acc = iks_id_new (iks_parser_stack (jsess->prs), buf);
355
 
                zbx_free (buf);
 
383
                buf = zbx_dsprintf(buf, "%s@%s/%s", jsess->acc->user, jsess->acc->server, "ZABBIX");
 
384
                jsess->acc = iks_id_new(iks_parser_stack (jsess->prs), buf);
 
385
                zbx_free(buf);
356
386
        }
357
387
 
358
 
        if( !(jsess->my_filter = iks_filter_new ()) )
 
388
        jsess->pass = strdup(password);
 
389
        jsess->opt_use_sasl = use_sasl;
 
390
 
 
391
        if (NULL == (jsess->my_filter = iks_filter_new()))
359
392
        {
360
 
                zbx_snprintf(error, len, "Cannot create filter [%s]", strerror(errno));
 
393
                zbx_snprintf(jabber_error, jabber_error_len, "Cannot create filter: %s",
 
394
                                strerror(errno));
361
395
                goto lbl_fail;
362
396
        }
363
397
 
364
 
        iks_filter_add_rule (jsess->my_filter, (iksFilterHook *) on_result, jsess,
 
398
        iks_filter_add_rule(jsess->my_filter, (iksFilterHook *)on_result, jsess,
365
399
                IKS_RULE_TYPE, IKS_PAK_IQ,
366
400
                IKS_RULE_SUBTYPE, IKS_TYPE_RESULT,
367
401
                IKS_RULE_ID, "auth",
368
402
                IKS_RULE_DONE);
369
403
 
370
 
        iks_filter_add_rule (jsess->my_filter, on_error, jsess,
 
404
        iks_filter_add_rule(jsess->my_filter, on_error, jsess,
371
405
                IKS_RULE_TYPE, IKS_PAK_IQ,
372
406
                IKS_RULE_SUBTYPE, IKS_TYPE_ERROR,
373
407
                IKS_RULE_ID, "auth",
374
408
                IKS_RULE_DONE);
375
409
 
376
 
        switch (iks_error = iks_connect_with(jsess->prs, jsess->acc->server, port, jsess->acc->server, &zbx_iks_transport) ) {
 
410
        switch (iks_connect_with(jsess->prs, jsess->acc->server, port, jsess->acc->server, &zbx_iks_transport))
 
411
/*      switch (iks_connect_via(jsess->prs, jsess->acc->server, port, jsess->acc->server))*/
 
412
        {
377
413
                case IKS_OK:
378
414
                        break;
379
415
                case IKS_NET_NODNS:
380
 
                        zbx_snprintf(error, len, "Hostname lookup failed");
 
416
                        zbx_snprintf(jabber_error, jabber_error_len, "Hostname lookup failed");
381
417
                        goto lbl_fail;
382
418
                case IKS_NET_NOCONN:
383
 
                        zbx_snprintf(error, len, "Connection failed: %s", strerror_from_system(errno));
 
419
                        zbx_snprintf(jabber_error, jabber_error_len, "Connection failed: %s",
 
420
                                        strerror_from_system(errno));
384
421
                        goto lbl_fail;
385
422
                default:
386
 
                        zbx_snprintf(error, len, "Connection error: %s", strerror_from_system(errno));
 
423
                        zbx_snprintf(jabber_error, jabber_error_len, "Connection error: %s",
 
424
                                        strerror_from_system(errno));
387
425
                        goto lbl_fail;
388
426
        }
389
427
 
390
 
        while (jsess->status != JABBER_READY) {
391
 
                switch (iks_error = iks_recv (jsess->prs, 5)) {
392
 
                        case IKS_OK:
393
 
                        case IKS_HOOK:
394
 
                                break;
395
 
                        case IKS_NET_TLSFAIL:
396
 
                                zbx_snprintf(error, len, "tls handshake failed");
397
 
                                goto lbl_fail;
398
 
                        default:
399
 
                                zbx_snprintf(error, len, "receiving error [%i][%i]", iks_error, errno);
400
 
                                goto lbl_fail;
401
 
                }
 
428
        timeout = 30;
 
429
        while (JABBER_READY != jsess->status && JABBER_ERROR != jsess->status) {
 
430
                iks_error = iks_recv(jsess->prs, 1);
 
431
 
 
432
                if (IKS_HOOK == iks_error)
 
433
                        break;
 
434
 
 
435
                if (IKS_NET_TLSFAIL == iks_error)
 
436
                {
 
437
                        zbx_snprintf(jabber_error, jabber_error_len, "tls handshake failed");
 
438
                        break;
 
439
                }
 
440
 
 
441
                if (IKS_OK != iks_error)
 
442
                {
 
443
                        zbx_snprintf(jabber_error, jabber_error_len, "receiving error [%i][%i]",
 
444
                                        iks_error, errno);
 
445
                        break;
 
446
                }
 
447
 
 
448
                if (--timeout == 0)
 
449
                        break;
402
450
        }
403
451
 
404
 
        return SUCCEED;
 
452
        if (JABBER_READY == jsess->status)
 
453
                ret = SUCCEED;
405
454
 
406
455
lbl_fail:
407
 
        disconnect_jabber();
408
 
        return FAIL;
 
456
        zabbix_log(LOG_LEVEL_DEBUG, "%s: End of %s():%s",
 
457
                        __module_name, __function_name,
 
458
                        zbx_result_string(ret));
 
459
 
 
460
        return ret;
409
461
}
410
462
 
411
463
/******************************************************************************
424
476
 * Comments:                                                                  *
425
477
 *                                                                            *
426
478
 ******************************************************************************/
427
 
int     send_jabber(char *username, char *passwd, char *sendto, char *message, char *error, int max_error_len)
 
479
int     send_jabber(char *username, char *passwd, char *sendto, char *subject, char *message, char *error, int max_error_len)
428
480
{
429
 
        iks *x = NULL;
430
 
        int ret = FAIL;
431
 
        int iks_error = IKS_OK;
 
481
        const char      *__function_name = "send_jabber";
 
482
        iks             *x;
 
483
        int             ret = FAIL, iks_error = IKS_OK;
432
484
 
433
485
        assert(error);
434
486
 
435
 
        zabbix_log( LOG_LEVEL_DEBUG, "JABBER: sending message");
 
487
        zabbix_log(LOG_LEVEL_DEBUG, "%s: In %s()",
 
488
                        __module_name, __function_name);
436
489
 
437
490
        *error = '\0';
438
491
 
439
 
        if (NULL == jsess || jsess->status == JABBER_DISCONNECTED || jsess->status == JABBER_ERROR) {
440
 
                if (SUCCEED != connect_jabber(username, passwd, 1, IKS_JABBER_PORT,  error, max_error_len))
441
 
                {
442
 
                        zabbix_log(LOG_LEVEL_WARNING, "JABBER: %s", error);
443
 
                        return FAIL;
444
 
                }
445
 
        }
446
 
 
447
 
        zabbix_log( LOG_LEVEL_DEBUG, "JABBER: sending");
448
 
        if( (x = iks_make_msg(IKS_TYPE_NONE, sendto, message)) )
 
492
        jabber_error = error;
 
493
        jabber_error_len = max_error_len;
 
494
 
 
495
        if (SUCCEED != connect_jabber(username, passwd, 1, IKS_JABBER_PORT))
 
496
                goto lbl_fail;
 
497
 
 
498
        zabbix_log(LOG_LEVEL_DEBUG, "%s: sending",
 
499
                        __module_name);
 
500
 
 
501
        if (NULL != (x = iks_make_msg(IKS_TYPE_NONE, sendto, message)))
449
502
        {
 
503
                iks_insert_cdata(iks_insert(x, "subject"), subject, 0);
450
504
                iks_insert_attrib(x, "from", username);
451
 
                if ( IKS_OK == (iks_error = iks_send (jsess->prs, x)) )
 
505
                if (IKS_OK == (iks_error = iks_send(jsess->prs, x)))
452
506
                {
453
 
                        zabbix_log( LOG_LEVEL_DEBUG, "JABBER: message sent");
 
507
                        zabbix_log(LOG_LEVEL_DEBUG, "%s: message sent",
 
508
                                        __module_name);
454
509
                        ret = SUCCEED;
455
510
                }
456
511
                else
457
512
                {
458
513
                        jsess->status = JABBER_ERROR;
459
514
 
460
 
                        zbx_snprintf(error, max_error_len, "JABBER: Cannot send message: %s", strerror_from_system(errno));
461
 
                        zabbix_log(LOG_LEVEL_WARNING, "%s", error);
 
515
                        zbx_snprintf(error, max_error_len, "Cannot send message: %s",
 
516
                                        strerror_from_system(errno));
462
517
                }
463
 
                iks_delete (x);
 
518
                iks_delete(x);
464
519
        }
465
520
        else
466
 
        {
467
 
                zbx_snprintf(error, max_error_len, "JABBER: Cannot create message");
468
 
                zabbix_log(LOG_LEVEL_WARNING, "%s", error);
469
 
        }
 
521
                zbx_snprintf(error, max_error_len, "Cannot create message");
 
522
 
 
523
lbl_fail:
 
524
        if (NULL != jsess && JABBER_DISCONNECTED != jsess->status)
 
525
                disconnect_jabber();
 
526
 
 
527
        jabber_error = NULL;
 
528
        jabber_error_len = 0;
 
529
 
 
530
        if ('\0' != *error)
 
531
                zabbix_log(LOG_LEVEL_WARNING, "%s: [%s] %s",
 
532
                                __module_name,
 
533
                                username,
 
534
                                error);
 
535
 
 
536
        zabbix_log(LOG_LEVEL_DEBUG, "%s: End of %s():%s",
 
537
                        __module_name, __function_name,
 
538
                        zbx_result_string(ret));
470
539
 
471
540
        return ret;
472
541
}