~sbeattie/ubuntu/lucid/asterisk/reenable-hardening

« back to all changes in this revision

Viewing changes to apps/app_externalivr.c

  • Committer: Bazaar Package Importer
  • Author(s): Jean-Michel Dault
  • Date: 2010-02-16 14:08:54 UTC
  • mfrom: (1.2.5 upstream) (8.3.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100216140854-rb2godspb9lduazl
Tags: 1:1.6.2.2-1ubuntu1
* Merge from Debian: security update
  * Changes:
  - debian/control: Change Maintainer
  - debian/control: Removed Uploaders field.
  - debian/control: Removed Debian Vcs-Svn entry and replaced with
      ubuntu-voip Vcs-Bzr, to reflect divergence in packages.
  - debian/asterisk.init : chown /dev/dahdi
  - debian/backports/hardy : add file
  - debian/backports/asterisk.init.hardy : add file

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
#include "asterisk.h"
35
35
 
36
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 195319 $")
 
36
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 232813 $")
37
37
 
38
38
#include <signal.h>
39
39
 
107
107
};
108
108
 
109
109
static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
110
 
        int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
 
110
        int *eivr_events_fd, int *eivr_commands_fd, int *eivr_errors_fd, 
111
111
        const struct ast_str *args, const struct ast_flags flags);
112
112
 
113
113
int eivr_connect_socket(struct ast_channel *chan, const char *host, int port);
316
316
        struct ast_flags flags = { 0, };
317
317
        char *opts[0];
318
318
        struct playlist_entry *entry;
319
 
        int child_stdin[2] = { 0, 0 };
320
 
        int child_stdout[2] = { 0, 0 };
321
 
        int child_stderr[2] = { 0, 0 };
 
319
        int child_stdin[2] = { -1, -1 };
 
320
        int child_stdout[2] = { -1, -1 };
 
321
        int child_stderr[2] = { -1, -1 };
322
322
        int res = -1;
323
323
        int pid;
324
324
 
349
349
        u->abort_current_sound = 0;
350
350
        u->chan = chan;
351
351
 
 
352
        if (ast_strlen_zero(data)) {
 
353
                ast_log(LOG_WARNING, "ExternalIVR requires a command to execute\n");
 
354
                return -1;
 
355
        }
 
356
 
352
357
        buf = ast_strdupa(data);
353
358
        AST_STANDARD_APP_ARGS(eivr_args, buf);
354
359
 
433
438
                ivr_desc.local_address.sin_family = AF_INET;
434
439
                ivr_desc.local_address.sin_port = htons(port);
435
440
                memcpy(&ivr_desc.local_address.sin_addr.s_addr, hp.hp.h_addr, hp.hp.h_length);
436
 
                ser = ast_tcptls_client_start(&ivr_desc);
437
 
 
438
 
                if (!ser) {
 
441
                if (!(ser = ast_tcptls_client_create(&ivr_desc)) || !(ser = ast_tcptls_client_start(ser))) {
439
442
                        goto exit;
440
443
                }
441
 
                res = eivr_comm(chan, u, ser->fd, ser->fd, -1, pipe_delim_args, flags);
 
444
                res = eivr_comm(chan, u, &ser->fd, &ser->fd, NULL, pipe_delim_args, flags);
442
445
 
443
446
        } else {
444
 
        
445
447
                if (pipe(child_stdin)) {
446
448
                        ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno));
447
449
                        goto exit;
476
478
                } else {
477
479
                        /* parent process */
478
480
                        close(child_stdin[0]);
479
 
                        child_stdin[0] = 0;
 
481
                        child_stdin[0] = -1;
480
482
                        close(child_stdout[1]);
481
 
                        child_stdout[1] = 0;
 
483
                        child_stdout[1] = -1;
482
484
                        close(child_stderr[1]);
483
 
                        child_stderr[1] = 0;
484
 
                        res = eivr_comm(chan, u, child_stdin[1], child_stdout[0], child_stderr[0], pipe_delim_args, flags);
 
485
                        child_stderr[1] = -1;
 
486
                        res = eivr_comm(chan, u, &child_stdin[1], &child_stdout[0], &child_stderr[0], pipe_delim_args, flags);
485
487
                }
486
488
        }
487
489
 
488
490
        exit:
489
 
        if (u->gen_active)
 
491
        if (u->gen_active) {
490
492
                ast_deactivate_generator(chan);
491
 
 
492
 
        if (child_stdin[0])
 
493
        }
 
494
        if (child_stdin[0] > -1) {
493
495
                close(child_stdin[0]);
494
 
 
495
 
        if (child_stdin[1])
 
496
        }
 
497
        if (child_stdin[1] > -1) {
496
498
                close(child_stdin[1]);
497
 
 
498
 
        if (child_stdout[0])
 
499
        }
 
500
        if (child_stdout[0] > -1) {
499
501
                close(child_stdout[0]);
500
 
 
501
 
        if (child_stdout[1])
 
502
        }
 
503
        if (child_stdout[1] > -1) {
502
504
                close(child_stdout[1]);
503
 
 
504
 
        if (child_stderr[0])
 
505
        }
 
506
        if (child_stderr[0] > -1) {
505
507
                close(child_stderr[0]);
506
 
 
507
 
        if (child_stderr[1])
 
508
        }
 
509
        if (child_stderr[1] > -1) {
508
510
                close(child_stderr[1]);
 
511
        }
509
512
        if (ser) {
510
513
                ao2_ref(ser, -1);
511
514
        }
512
 
        while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
 
515
        while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
513
516
                ast_free(entry);
514
 
 
 
517
        }
515
518
        return res;
516
519
}
517
520
 
518
521
static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
519
 
                                int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
 
522
                                int *eivr_events_fd, int *eivr_commands_fd, int *eivr_errors_fd, 
520
523
                                const struct ast_str *args, const struct ast_flags flags)
521
524
{
522
525
        struct playlist_entry *entry;
524
527
        int ms;
525
528
        int exception;
526
529
        int ready_fd;
527
 
        int waitfds[2] = { eivr_commands_fd, eivr_errors_fd };
 
530
        int waitfds[2] = { *eivr_commands_fd, (eivr_errors_fd) ? *eivr_errors_fd : -1 };
528
531
        struct ast_channel *rchan;
529
532
        char *command;
530
533
        int res = -1;
535
538
        FILE *eivr_errors = NULL;
536
539
        FILE *eivr_events = NULL;
537
540
 
538
 
        if (!(eivr_events = fdopen(eivr_events_fd, "w"))) {
 
541
        if (!(eivr_events = fdopen(*eivr_events_fd, "w"))) {
539
542
                ast_chan_log(LOG_WARNING, chan, "Could not open stream to send events\n");
540
543
                goto exit;
541
544
        }
542
 
        if (!(eivr_commands = fdopen(eivr_commands_fd, "r"))) {
 
545
        if (!(eivr_commands = fdopen(*eivr_commands_fd, "r"))) {
543
546
                ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive commands\n");
544
547
                goto exit;
545
548
        }
546
 
        if (eivr_errors_fd > -1) {  /* if opening a socket connection, error stream will not be used */
547
 
                if (!(eivr_errors = fdopen(eivr_errors_fd, "r"))) {
 
549
        if (eivr_errors_fd) {  /* if opening a socket connection, error stream will not be used */
 
550
                if (!(eivr_errors = fdopen(*eivr_errors_fd, "r"))) {
548
551
                        ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive errors\n");
549
552
                        goto exit;
550
553
                }
584
587
                errno = 0;
585
588
                exception = 0;
586
589
 
587
 
                rchan = ast_waitfor_nandfds(&chan, 1, waitfds, (eivr_errors_fd < 0) ? 1 : 2, &exception, &ready_fd, &ms);
 
590
                rchan = ast_waitfor_nandfds(&chan, 1, waitfds, (eivr_errors_fd) ? 2 : 1, &exception, &ready_fd, &ms);
588
591
 
589
592
                if (chan->_state == AST_STATE_UP && !AST_LIST_EMPTY(&u->finishlist)) {
590
593
                        AST_LIST_LOCK(&u->finishlist);
629
632
                                break;
630
633
                        }
631
634
                        ast_frfree(f);
632
 
                } else if (ready_fd == eivr_commands_fd) {
 
635
                } else if (ready_fd == *eivr_commands_fd) {
633
636
                        char input[1024];
634
637
 
635
 
                        if (exception || (dup2(eivr_commands_fd, test_available_fd) == -1) || feof(eivr_commands)) {
 
638
                        if (exception || (dup2(*eivr_commands_fd, test_available_fd) == -1) || feof(eivr_commands)) {
636
639
                                ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
637
640
                                res = -1;
638
641
                                break;
752
755
                                else
753
756
                                        ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
754
757
                        }
755
 
                } else if (eivr_errors_fd && ready_fd == eivr_errors_fd) {
 
758
                } else if (eivr_errors_fd && (ready_fd == *eivr_errors_fd)) {
756
759
                        char input[1024];
757
760
  
758
761
                        if (exception || feof(eivr_errors)) {
772
775
                        break;
773
776
                }
774
777
        }
775
 
  
776
 
 
777
 
exit:
778
 
 
 
778
 
 
779
        exit:
779
780
        if (test_available_fd > -1) {
780
781
                close(test_available_fd);
781
782
        }
782
 
 
783
 
        if (eivr_events)
 
783
        if (eivr_events) {
784
784
                fclose(eivr_events);
785
 
 
786
 
        if (eivr_commands)
 
785
                *eivr_events_fd = -1;
 
786
        }
 
787
        if (eivr_commands) {
787
788
                fclose(eivr_commands);
788
 
 
789
 
        if (eivr_errors)
 
789
                *eivr_commands_fd = -1;
 
790
        }
 
791
        if (eivr_errors) {
790
792
                fclose(eivr_errors);
791
 
  
 
793
                *eivr_errors_fd = -1;
 
794
        }
792
795
        return res;
793
 
 
794
796
}
795
797
 
796
798
static int unload_module(void)