/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
                                                   return immediately
                                                   if interrupted by
                                                   signal.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include <stdint.h>             /* uint16_t, uint32_t */
45
45
#include <stddef.h>             /* NULL, size_t, ssize_t */
46
46
#include <stdlib.h>             /* free(), EXIT_SUCCESS, EXIT_FAILURE,
47
 
                                   srand(), strtof(), abort() */
 
47
                                   srand(), strtof() */
48
48
#include <stdbool.h>            /* bool, false, true */
49
49
#include <string.h>             /* memset(), strcmp(), strlen(),
50
50
                                   strerror(), asprintf(), strcpy() */
72
72
                                */
73
73
#include <unistd.h>             /* close(), SEEK_SET, off_t, write(),
74
74
                                   getuid(), getgid(), seteuid(),
75
 
                                   setgid(), pause() */
 
75
                                   setgid() */
76
76
#include <arpa/inet.h>          /* inet_pton(), htons */
77
77
#include <iso646.h>             /* not, or, and */
78
78
#include <argp.h>               /* struct argp_option, error_t, struct
544
544
    struct sockaddr_in6 in6;
545
545
  } to;
546
546
  char *buffer = NULL;
547
 
  char *decrypted_buffer = NULL;
 
547
  char *decrypted_buffer;
548
548
  size_t buffer_length = 0;
549
549
  size_t buffer_capacity = 0;
550
550
  size_t written;
551
 
  int retval = -1;
 
551
  int retval = 0;
552
552
  gnutls_session_t session;
553
553
  int pf;                       /* Protocol family */
554
554
  
581
581
  tcp_sd = socket(pf, SOCK_STREAM, 0);
582
582
  if(tcp_sd < 0){
583
583
    perror("socket");
 
584
    retval = -1;
584
585
    goto mandos_end;
585
586
  }
586
587
  
587
588
  if(quit_now){
 
589
    retval = -1;
588
590
    goto mandos_end;
589
591
  }
590
592
  
598
600
  }
599
601
  if(ret < 0 ){
600
602
    perror("inet_pton");
 
603
    retval = -1;
601
604
    goto mandos_end;
602
605
  }
603
606
  if(ret == 0){
604
607
    fprintf(stderr, "Bad address: %s\n", ip);
 
608
    retval = -1;
605
609
    goto mandos_end;
606
610
  }
607
611
  if(af == AF_INET6){
615
619
      if(if_index == AVAHI_IF_UNSPEC){
616
620
        fprintf(stderr, "An IPv6 link-local address is incomplete"
617
621
                " without a network interface\n");
 
622
        retval = -1;
618
623
        goto mandos_end;
619
624
      }
620
625
      /* Set the network interface number as scope */
627
632
  }
628
633
  
629
634
  if(quit_now){
 
635
    retval = -1;
630
636
    goto mandos_end;
631
637
  }
632
638
  
663
669
  }
664
670
  
665
671
  if(quit_now){
 
672
    retval = -1;
666
673
    goto mandos_end;
667
674
  }
668
675
  
673
680
  }
674
681
  if(ret < 0){
675
682
    perror("connect");
 
683
    retval = -1;
676
684
    goto mandos_end;
677
685
  }
678
686
  
679
687
  if(quit_now){
 
688
    retval = -1;
680
689
    goto mandos_end;
681
690
  }
682
691
  
688
697
                                   out_size - written));
689
698
    if(ret == -1){
690
699
      perror("write");
 
700
      retval = -1;
691
701
      goto mandos_end;
692
702
    }
693
703
    written += (size_t)ret;
703
713
    }
704
714
  
705
715
    if(quit_now){
 
716
      retval = -1;
706
717
      goto mandos_end;
707
718
    }
708
719
  }
712
723
  }
713
724
  
714
725
  if(quit_now){
 
726
    retval = -1;
715
727
    goto mandos_end;
716
728
  }
717
729
  
718
730
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd);
719
731
  
720
732
  if(quit_now){
 
733
    retval = -1;
721
734
    goto mandos_end;
722
735
  }
723
736
  
724
737
  do {
725
738
    ret = gnutls_handshake(session);
726
739
    if(quit_now){
 
740
      retval = -1;
727
741
      goto mandos_end;
728
742
    }
729
743
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
733
747
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
734
748
      gnutls_perror(ret);
735
749
    }
 
750
    retval = -1;
736
751
    goto mandos_end;
737
752
  }
738
753
  
746
761
  while(true){
747
762
    
748
763
    if(quit_now){
 
764
      retval = -1;
749
765
      goto mandos_end;
750
766
    }
751
767
    
753
769
                                   buffer_capacity);
754
770
    if(buffer_capacity == 0){
755
771
      perror("incbuffer");
 
772
      retval = -1;
756
773
      goto mandos_end;
757
774
    }
758
775
    
759
776
    if(quit_now){
 
777
      retval = -1;
760
778
      goto mandos_end;
761
779
    }
762
780
    
775
793
          ret = gnutls_handshake(session);
776
794
          
777
795
          if(quit_now){
 
796
            retval = -1;
778
797
            goto mandos_end;
779
798
          }
780
799
        } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
781
800
        if(ret < 0){
782
801
          fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
783
802
          gnutls_perror(ret);
 
803
          retval = -1;
784
804
          goto mandos_end;
785
805
        }
786
806
        break;
787
807
      default:
788
808
        fprintf(stderr, "Unknown error while reading data from"
789
809
                " encrypted session with Mandos server\n");
 
810
        retval = -1;
790
811
        gnutls_bye(session, GNUTLS_SHUT_RDWR);
791
812
        goto mandos_end;
792
813
      }
800
821
  }
801
822
  
802
823
  if(quit_now){
 
824
    retval = -1;
803
825
    goto mandos_end;
804
826
  }
805
827
  
806
828
  do {
807
829
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
808
830
    if(quit_now){
 
831
      retval = -1;
809
832
      goto mandos_end;
810
833
    }
811
834
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
820
843
      written = 0;
821
844
      while(written < (size_t) decrypted_buffer_size){
822
845
        if(quit_now){
 
846
          retval = -1;
823
847
          goto mandos_end;
824
848
        }
825
849
        
831
855
            fprintf(stderr, "Error writing encrypted data: %s\n",
832
856
                    strerror(errno));
833
857
          }
834
 
          goto mandos_end;
 
858
          retval = -1;
 
859
          break;
835
860
        }
836
861
        written += (size_t)ret;
837
862
      }
838
 
      retval = 0;
 
863
      free(decrypted_buffer);
 
864
    } else {
 
865
      retval = -1;
839
866
    }
 
867
  } else {
 
868
    retval = -1;
840
869
  }
841
870
  
842
871
  /* Shutdown procedure */
843
872
  
844
873
 mandos_end:
845
 
  free(decrypted_buffer);
846
874
  free(buffer);
847
875
  if(tcp_sd >= 0){
848
876
    ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
1596
1624
  if(quit_now){
1597
1625
    sigemptyset(&old_sigterm_action.sa_mask);
1598
1626
    old_sigterm_action.sa_handler = SIG_DFL;
1599
 
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
1600
 
                                            &old_sigterm_action,
1601
 
                                            NULL));
 
1627
    ret = sigaction(signal_received, &old_sigterm_action, NULL);
1602
1628
    if(ret == -1){
1603
1629
      perror("sigaction");
1604
1630
    }
1605
 
    do {
1606
 
      ret = raise(signal_received);
1607
 
    } while(ret != 0 and errno == EINTR);
1608
 
    if(ret != 0){
1609
 
      perror("raise");
1610
 
      abort();
1611
 
    }
1612
 
    TEMP_FAILURE_RETRY(pause());
 
1631
    raise(signal_received);
1613
1632
  }
1614
1633
  
1615
1634
  return exitcode;