/mandos/trunk

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

« back to all changes in this revision

Viewing changes to plugins.d/password-request.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-29 05:53:59 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080829055359-wkdasnyxtylmnxus
* mandos.xml (EXAMPLE): Replaced all occurences of command name with
                        "&COMMANDNAME;".

* plugins.d/password-prompt.c (main): Improved some documentation
                                      strings.  Do perror() of
                                      tcgetattr() fails.  Add debug
                                      output if interrupted by signal.
                                      Loop over write() instead of
                                      using fwrite() when outputting
                                      password.  Add debug output if
                                      getline() returns 0, unless it
                                      was caused by a signal.  Add
                                      exit status code to debug
                                      output.

* plugins.d/password-prompt.xml: Changed all single quotes to double
                                 quotes for consistency.  Removed
                                 <?xml-stylesheet>.
  (ENTITY TIMESTAMP): New.  Automatically updated by Emacs time-stamp
                      by using Emacs local variables.
  (/refentry/refentryinfo/title): Changed to "Mandos Manual".
  (/refentry/refentryinfo/productname): Changed to "Mandos".
  (/refentry/refentryinfo/date): New; set to "&TIMESTAMP;".
  (/refentry/refentryinfo/copyright): Split copyright holders.
  (/refentry/refnamediv/refpurpose): Improved wording.
  (SYNOPSIS): Fix to use correct markup.  Add short options.
  (DESCRIPTION, OPTIONS): Improved wording.
  (OPTIONS): Improved wording.  Use more correct markup.  Document
             short options.
  (EXIT STATUS): Add text.
  (ENVIRONMENT): Document use of "cryptsource" and "crypttarget".
  (FILES): REMOVED.
  (BUGS): Add text.
  (EXAMPLE): Added some examples.
  (SECURITY): Added text.
  (SEE ALSO): Remove reference to mandos(8).  Add reference to
              crypttab(5).

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#define _LARGEFILE_SOURCE
33
33
#define _FILE_OFFSET_BITS 64
34
34
 
35
 
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY() */
 
35
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY(), asprintf() */
36
36
 
37
 
#include <stdio.h>              /* fprintf(), stderr, fwrite(), stdout,
38
 
                                   ferror() */
 
37
#include <stdio.h>              /* fprintf(), stderr, fwrite(),
 
38
                                   stdout, ferror() */
39
39
#include <stdint.h>             /* uint16_t, uint32_t */
40
40
#include <stddef.h>             /* NULL, size_t, ssize_t */
41
41
#include <stdlib.h>             /* free(), EXIT_SUCCESS, EXIT_FAILURE,
42
42
                                   srand() */
43
43
#include <stdbool.h>            /* bool, true */
44
44
#include <string.h>             /* memset(), strcmp(), strlen(),
45
 
                                   strerror(), memcpy(), strcpy() */
 
45
                                   strerror(), asprintf(), strcpy() */
46
46
#include <sys/ioctl.h>          /* ioctl */
47
47
#include <sys/types.h>          /* socket(), inet_pton(), sockaddr,
48
48
                                   sockaddr_in6, PF_INET6,
81
81
#include <avahi-common/error.h>
82
82
 
83
83
/* GnuTLS */
84
 
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and functions
 
84
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and
 
85
                                   functions:
85
86
                                   gnutls_*
86
87
                                   init_gnutls_session(),
87
88
                                   GNUTLS_* */
89
90
                                   GNUTLS_OPENPGP_FMT_BASE64 */
90
91
 
91
92
/* GPGME */
92
 
#include <gpgme.h>              /* All GPGME types, constants and functions
 
93
#include <gpgme.h>              /* All GPGME types, constants and
 
94
                                   functions:
93
95
                                   gpgme_*
94
96
                                   GPGME_PROTOCOL_OpenPGP,
95
97
                                   GPG_ERR_NO_* */
212
214
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
213
215
            gpgme_strsource(rc), gpgme_strerror(rc));
214
216
    plaintext_length = -1;
 
217
    if (debug){
 
218
      gpgme_decrypt_result_t result;
 
219
      result = gpgme_op_decrypt_result(ctx);
 
220
      if (result == NULL){
 
221
        fprintf(stderr, "gpgme_op_decrypt_result failed\n");
 
222
      } else {
 
223
        fprintf(stderr, "Unsupported algorithm: %s\n",
 
224
                result->unsupported_algorithm);
 
225
        fprintf(stderr, "Wrong key usage: %u\n",
 
226
                result->wrong_key_usage);
 
227
        if(result->file_name != NULL){
 
228
          fprintf(stderr, "File name: %s\n", result->file_name);
 
229
        }
 
230
        gpgme_recipient_t recipient;
 
231
        recipient = result->recipients;
 
232
        if(recipient){
 
233
          while(recipient != NULL){
 
234
            fprintf(stderr, "Public key algorithm: %s\n",
 
235
                    gpgme_pubkey_algo_name(recipient->pubkey_algo));
 
236
            fprintf(stderr, "Key ID: %s\n", recipient->keyid);
 
237
            fprintf(stderr, "Secret key available: %s\n",
 
238
                    recipient->status == GPG_ERR_NO_SECKEY
 
239
                    ? "No" : "Yes");
 
240
            recipient = recipient->next;
 
241
          }
 
242
        }
 
243
      }
 
244
    }
215
245
    goto decrypt_end;
216
246
  }
217
247
  
219
249
    fprintf(stderr, "Decryption of OpenPGP data succeeded\n");
220
250
  }
221
251
  
222
 
  if (debug){
223
 
    gpgme_decrypt_result_t result;
224
 
    result = gpgme_op_decrypt_result(ctx);
225
 
    if (result == NULL){
226
 
      fprintf(stderr, "gpgme_op_decrypt_result failed\n");
227
 
    } else {
228
 
      fprintf(stderr, "Unsupported algorithm: %s\n",
229
 
              result->unsupported_algorithm);
230
 
      fprintf(stderr, "Wrong key usage: %u\n",
231
 
              result->wrong_key_usage);
232
 
      if(result->file_name != NULL){
233
 
        fprintf(stderr, "File name: %s\n", result->file_name);
234
 
      }
235
 
      gpgme_recipient_t recipient;
236
 
      recipient = result->recipients;
237
 
      if(recipient){
238
 
        while(recipient != NULL){
239
 
          fprintf(stderr, "Public key algorithm: %s\n",
240
 
                  gpgme_pubkey_algo_name(recipient->pubkey_algo));
241
 
          fprintf(stderr, "Key ID: %s\n", recipient->keyid);
242
 
          fprintf(stderr, "Secret key available: %s\n",
243
 
                  recipient->status == GPG_ERR_NO_SECKEY
244
 
                  ? "No" : "Yes");
245
 
          recipient = recipient->next;
246
 
        }
247
 
      }
248
 
    }
249
 
  }
250
 
  
251
252
  /* Seek back to the beginning of the GPGME plaintext data buffer */
252
253
  if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
253
254
    perror("pgpme_data_seek");
300
301
}
301
302
 
302
303
static const char * safer_gnutls_strerror (int value) {
303
 
  const char *ret = gnutls_strerror (value);
 
304
  const char *ret = gnutls_strerror (value); /* Spurious warning */
304
305
  if (ret == NULL)
305
306
    ret = "(unknown)";
306
307
  return ret;
313
314
}
314
315
 
315
316
static int init_gnutls_global(mandos_context *mc,
316
 
                              const char *pubkeyfile,
317
 
                              const char *seckeyfile){
 
317
                              const char *pubkeyfilename,
 
318
                              const char *seckeyfilename){
318
319
  int ret;
319
320
  
320
321
  if(debug){
339
340
  /* OpenPGP credentials */
340
341
  gnutls_certificate_allocate_credentials(&mc->cred);
341
342
  if (ret != GNUTLS_E_SUCCESS){
342
 
    fprintf (stderr, "GnuTLS memory error: %s\n",
 
343
    fprintf (stderr, "GnuTLS memory error: %s\n", /* Spurious
 
344
                                                     warning */
343
345
             safer_gnutls_strerror(ret));
344
346
    gnutls_global_deinit ();
345
347
    return -1;
347
349
  
348
350
  if(debug){
349
351
    fprintf(stderr, "Attempting to use OpenPGP certificate %s"
350
 
            " and keyfile %s as GnuTLS credentials\n", pubkeyfile,
351
 
            seckeyfile);
 
352
            " and keyfile %s as GnuTLS credentials\n", pubkeyfilename,
 
353
            seckeyfilename);
352
354
  }
353
355
  
354
356
  ret = gnutls_certificate_set_openpgp_key_file
355
 
    (mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
 
357
    (mc->cred, pubkeyfilename, seckeyfilename,
 
358
     GNUTLS_OPENPGP_FMT_BASE64);
356
359
  if (ret != GNUTLS_E_SUCCESS) {
357
360
    fprintf(stderr,
358
361
            "Error[%d] while reading the OpenPGP key pair ('%s',"
359
 
            " '%s')\n", ret, pubkeyfile, seckeyfile);
 
362
            " '%s')\n", ret, pubkeyfilename, seckeyfilename);
360
363
    fprintf(stdout, "The GnuTLS error is: %s\n",
361
364
            safer_gnutls_strerror(ret));
362
365
    goto globalfail;
472
475
    fprintf(stderr, "Binding to interface %s\n", interface);
473
476
  }
474
477
  
475
 
  memset(&to,0,sizeof(to));     /* Spurious warning */
 
478
  memset(&to, 0, sizeof(to));
476
479
  to.in6.sin6_family = AF_INET6;
477
480
  /* It would be nice to have a way to detect if we were passed an
478
481
     IPv4 address here.   Now we assume an IPv6 address. */
632
635
    } else {
633
636
      retval = -1;
634
637
    }
 
638
  } else {
 
639
    retval = -1;
635
640
  }
636
641
  
637
642
  /* Shutdown procedure */
658
663
                             flags,
659
664
                             void* userdata) {
660
665
  mandos_context *mc = userdata;
661
 
  assert(r);                    /* Spurious warning */
 
666
  assert(r);
662
667
  
663
668
  /* Called whenever a service has been resolved successfully or
664
669
     timed out */
700
705
                             flags,
701
706
                             void* userdata) {
702
707
  mandos_context *mc = userdata;
703
 
  assert(b);                    /* Spurious warning */
 
708
  assert(b);
704
709
  
705
710
  /* Called whenever a new services becomes available on the LAN or
706
711
     is removed from the LAN */
742
747
 
743
748
/* Combines file name and path and returns the malloced new
744
749
   string. some sane checks could/should be added */
745
 
static const char *combinepath(const char *first, const char *second){
746
 
  size_t f_len = strlen(first);
747
 
  size_t s_len = strlen(second);
748
 
  char *tmp = malloc(f_len + s_len + 2);
749
 
  if (tmp == NULL){
 
750
static char *combinepath(const char *first, const char *second){
 
751
  char *tmp;
 
752
  int ret = asprintf(&tmp, "%s/%s", first, second);
 
753
  if(ret < 0){
750
754
    return NULL;
751
755
  }
752
 
  if(f_len > 0){
753
 
    memcpy(tmp, first, f_len);  /* Spurious warning */
754
 
  }
755
 
  tmp[f_len] = '/';
756
 
  if(s_len > 0){
757
 
    memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
758
 
  }
759
 
  tmp[f_len + 1 + s_len] = '\0';
760
756
  return tmp;
761
757
}
762
758
 
773
769
    gid_t gid;
774
770
    char *connect_to = NULL;
775
771
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
776
 
    const char *pubkeyfile = "pubkey.txt";
777
 
    const char *seckeyfile = "seckey.txt";
 
772
    char *pubkeyfilename = NULL;
 
773
    char *seckeyfilename = NULL;
 
774
    const char *pubkeyname = "pubkey.txt";
 
775
    const char *seckeyname = "seckey.txt";
778
776
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
779
777
                          .dh_bits = 1024, .priority = "SECURE256"};
780
778
    bool gnutls_initalized = false;
832
830
          keydir = arg;
833
831
          break;
834
832
        case 's':
835
 
          seckeyfile = arg;
 
833
          seckeyname = arg;
836
834
          break;
837
835
        case 'p':
838
 
          pubkeyfile = arg;
 
836
          pubkeyname = arg;
839
837
          break;
840
838
        case 129:
841
839
          errno = 0;
870
868
      }
871
869
    }
872
870
      
873
 
    pubkeyfile = combinepath(keydir, pubkeyfile);
874
 
    if (pubkeyfile == NULL){
 
871
    pubkeyfilename = combinepath(keydir, pubkeyname);
 
872
    if (pubkeyfilename == NULL){
875
873
      perror("combinepath");
876
874
      exitcode = EXIT_FAILURE;
877
875
      goto end;
878
876
    }
879
877
    
880
 
    seckeyfile = combinepath(keydir, seckeyfile);
881
 
    if (seckeyfile == NULL){
 
878
    seckeyfilename = combinepath(keydir, seckeyname);
 
879
    if (seckeyfilename == NULL){
882
880
      perror("combinepath");
883
881
      exitcode = EXIT_FAILURE;
884
882
      goto end;
885
883
    }
886
884
 
887
 
    ret = init_gnutls_global(&mc, pubkeyfile, seckeyfile);
 
885
    ret = init_gnutls_global(&mc, pubkeyfilename, seckeyfilename);
888
886
    if (ret == -1){
889
887
      fprintf(stderr, "init_gnutls_global failed\n");
890
888
      exitcode = EXIT_FAILURE;
901
899
        exitcode = EXIT_FAILURE;
902
900
        goto end;
903
901
      }
904
 
      strcpy(network.ifr_name, interface); /* Spurious warning */
 
902
      strcpy(network.ifr_name, interface);
905
903
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
906
904
      if(ret == -1){
907
905
        perror("ioctl SIOCGIFFLAGS");
1043
1041
 
1044
1042
    if (mc.simple_poll != NULL)
1045
1043
        avahi_simple_poll_free(mc.simple_poll);
1046
 
    free(pubkeyfile);
1047
 
    free(seckeyfile);
 
1044
    free(pubkeyfilename);
 
1045
    free(seckeyfilename);
1048
1046
 
1049
1047
    if (gnutls_initalized){
1050
1048
      gnutls_certificate_free_credentials(mc.cred);