/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/mandosclient.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-03 01:09:36 UTC
  • mfrom: (24.1.9 mandos)
  • Revision ID: teddy@fukt.bsnet.se-20080803010936-ujme8tgxceszfbi1
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
                            Take an additional non-option argument and
                            parse it as a plus-separated and -prefixed
                            list of additional options.

* plugins.d/mandosclient.c (DH_BITS): Replaced with
                                      "mandos_context.dh_bits".  All
                                      users changed.
  (certdir): Renamed to "keydir".  All users changed.
  (certfile): Renamed to "pubkeyfile".  All users changed.
  (certkey): Renamed to "seckeyfile".  All users changed.
  (encrypted_session): Replaced with "mandos_context".  All users
                       changed.
  (initgnutls): Take additional "session" and "dh_params" arguments.
                All callers changed.
  (start_mandos_communication): Take additional "mc" argument.  All
                                callers changed.  Print target IPv6
                                address if different than supplied
                                string.
  (simple_poll) Replaced with "mandos_context.simple_poll".  All users
                changed.
  (server): Replaced with "mandos_context.server".  All users changed.
  (main): Default interface to "eth0".  Rename "--certdir" to
          "--keydir", "--certkey" to "--seckey", and "--certfile" to
          "--pubkey".  New options "--dh-bits" and "--priority".  If
          the interface is not up, bring it up.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <stdlib.h>
38
38
#include <time.h>
39
39
#include <net/if.h>             /* if_nametoindex */
40
 
#include <sys/ioctl.h>          /* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
41
 
                                   SIOCSIFFLAGS */
42
 
#include <net/if.h>             /* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
43
 
                                   SIOCSIFFLAGS */
 
40
#include <sys/ioctl.h>          // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
 
41
#include <net/if.h>             // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
44
42
 
45
43
#include <avahi-core/core.h>
46
44
#include <avahi-core/lookup.h>
87
85
  const char *priority;
88
86
} mandos_context;
89
87
 
90
 
/* 
91
 
 * Decrypt OpenPGP data using keyrings in HOMEDIR.
92
 
 * Returns -1 on error
93
 
 */
94
 
static ssize_t pgp_packet_decrypt (const char *cryptotext,
95
 
                                   size_t crypto_size,
96
 
                                   char **plaintext,
 
88
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
 
89
                                   char **new_packet,
97
90
                                   const char *homedir){
98
91
  gpgme_data_t dh_crypto, dh_plain;
99
92
  gpgme_ctx_t ctx;
100
93
  gpgme_error_t rc;
101
94
  ssize_t ret;
102
 
  ssize_t plaintext_capacity = 0;
103
 
  ssize_t plaintext_length = 0;
 
95
  ssize_t new_packet_capacity = 0;
 
96
  ssize_t new_packet_length = 0;
104
97
  gpgme_engine_info_t engine_info;
105
 
  
 
98
 
106
99
  if (debug){
107
 
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
 
100
    fprintf(stderr, "Trying to decrypt OpenPGP packet\n");
108
101
  }
109
102
  
110
103
  /* Init GPGME */
116
109
    return -1;
117
110
  }
118
111
  
119
 
  /* Set GPGME home directory for the OpenPGP engine only */
 
112
  /* Set GPGME home directory */
120
113
  rc = gpgme_get_engine_info (&engine_info);
121
114
  if (rc != GPG_ERR_NO_ERROR){
122
115
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
132
125
    engine_info = engine_info->next;
133
126
  }
134
127
  if(engine_info == NULL){
135
 
    fprintf(stderr, "Could not set GPGME home dir to %s\n", homedir);
 
128
    fprintf(stderr, "Could not set home dir to %s\n", homedir);
136
129
    return -1;
137
130
  }
138
131
  
139
 
  /* Create new GPGME data buffer from memory cryptotext */
140
 
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
141
 
                               0);
 
132
  /* Create new GPGME data buffer from packet buffer */
 
133
  rc = gpgme_data_new_from_mem(&dh_crypto, packet, packet_size, 0);
142
134
  if (rc != GPG_ERR_NO_ERROR){
143
135
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
144
136
            gpgme_strsource(rc), gpgme_strerror(rc));
150
142
  if (rc != GPG_ERR_NO_ERROR){
151
143
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
152
144
            gpgme_strsource(rc), gpgme_strerror(rc));
153
 
    gpgme_data_release(dh_crypto);
154
145
    return -1;
155
146
  }
156
147
  
159
150
  if (rc != GPG_ERR_NO_ERROR){
160
151
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
161
152
            gpgme_strsource(rc), gpgme_strerror(rc));
162
 
    plaintext_length = -1;
163
 
    goto decrypt_end;
 
153
    return -1;
164
154
  }
165
155
  
166
 
  /* Decrypt data from the cryptotext data buffer to the plaintext
167
 
     data buffer */
 
156
  /* Decrypt data from the FILE pointer to the plaintext data
 
157
     buffer */
168
158
  rc = gpgme_op_decrypt(ctx, dh_crypto, dh_plain);
169
159
  if (rc != GPG_ERR_NO_ERROR){
170
160
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
171
161
            gpgme_strsource(rc), gpgme_strerror(rc));
172
 
    plaintext_length = -1;
173
 
    goto decrypt_end;
 
162
    return -1;
174
163
  }
175
 
  
 
164
 
176
165
  if(debug){
177
 
    fprintf(stderr, "Decryption of OpenPGP data succeeded\n");
 
166
    fprintf(stderr, "Decryption of OpenPGP packet succeeded\n");
178
167
  }
179
 
  
 
168
 
180
169
  if (debug){
181
170
    gpgme_decrypt_result_t result;
182
171
    result = gpgme_op_decrypt_result(ctx);
206
195
    }
207
196
  }
208
197
  
 
198
  /* Delete the GPGME FILE pointer cryptotext data buffer */
 
199
  gpgme_data_release(dh_crypto);
 
200
  
209
201
  /* Seek back to the beginning of the GPGME plaintext data buffer */
210
202
  if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
211
203
    perror("pgpme_data_seek");
212
 
    plaintext_length = -1;
213
 
    goto decrypt_end;
214
204
  }
215
205
  
216
 
  *plaintext = NULL;
 
206
  *new_packet = 0;
217
207
  while(true){
218
 
    if (plaintext_length + BUFFER_SIZE > plaintext_capacity){
219
 
      *plaintext = realloc(*plaintext,
220
 
                            (unsigned int)plaintext_capacity
 
208
    if (new_packet_length + BUFFER_SIZE > new_packet_capacity){
 
209
      *new_packet = realloc(*new_packet,
 
210
                            (unsigned int)new_packet_capacity
221
211
                            + BUFFER_SIZE);
222
 
      if (*plaintext == NULL){
 
212
      if (*new_packet == NULL){
223
213
        perror("realloc");
224
 
        plaintext_length = -1;
225
 
        goto decrypt_end;
 
214
        return -1;
226
215
      }
227
 
      plaintext_capacity += BUFFER_SIZE;
 
216
      new_packet_capacity += BUFFER_SIZE;
228
217
    }
229
218
    
230
 
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
 
219
    ret = gpgme_data_read(dh_plain, *new_packet + new_packet_length,
231
220
                          BUFFER_SIZE);
232
221
    /* Print the data, if any */
233
222
    if (ret == 0){
234
 
      /* EOF */
235
223
      break;
236
224
    }
237
225
    if(ret < 0){
238
226
      perror("gpgme_data_read");
239
 
      plaintext_length = -1;
240
 
      goto decrypt_end;
 
227
      return -1;
241
228
    }
242
 
    plaintext_length += ret;
 
229
    new_packet_length += ret;
243
230
  }
244
231
 
245
 
  if(debug){
246
 
    fprintf(stderr, "Decrypted password is: ");
247
 
    for(size_t i = 0; i < plaintext_length; i++){
248
 
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
249
 
    }
250
 
    fprintf(stderr, "\n");
251
 
  }
252
 
  
253
 
 decrypt_end:
254
 
  
255
 
  /* Delete the GPGME cryptotext data buffer */
256
 
  gpgme_data_release(dh_crypto);
 
232
  /* FIXME: check characters before printing to screen so to not print
 
233
     terminal control characters */
 
234
  /*   if(debug){ */
 
235
  /*     fprintf(stderr, "decrypted password is: "); */
 
236
  /*     fwrite(*new_packet, 1, new_packet_length, stderr); */
 
237
  /*     fprintf(stderr, "\n"); */
 
238
  /*   } */
257
239
  
258
240
  /* Delete the GPGME plaintext data buffer */
259
241
  gpgme_data_release(dh_plain);
260
 
  return plaintext_length;
 
242
  return new_packet_length;
261
243
}
262
244
 
263
245
static const char * safer_gnutls_strerror (int value) {
552
534
  return retval;
553
535
}
554
536
 
555
 
static void resolve_callback(AvahiSServiceResolver *r,
556
 
                             AvahiIfIndex interface,
557
 
                             AVAHI_GCC_UNUSED AvahiProtocol protocol,
558
 
                             AvahiResolverEvent event,
559
 
                             const char *name,
560
 
                             const char *type,
561
 
                             const char *domain,
562
 
                             const char *host_name,
563
 
                             const AvahiAddress *address,
564
 
                             uint16_t port,
565
 
                             AVAHI_GCC_UNUSED AvahiStringList *txt,
566
 
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags
567
 
                             flags,
568
 
                             void* userdata) {
 
537
static void resolve_callback( AvahiSServiceResolver *r,
 
538
                              AvahiIfIndex interface,
 
539
                              AVAHI_GCC_UNUSED AvahiProtocol protocol,
 
540
                              AvahiResolverEvent event,
 
541
                              const char *name,
 
542
                              const char *type,
 
543
                              const char *domain,
 
544
                              const char *host_name,
 
545
                              const AvahiAddress *address,
 
546
                              uint16_t port,
 
547
                              AVAHI_GCC_UNUSED AvahiStringList *txt,
 
548
                              AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
 
549
                              void* userdata) {
569
550
  mandos_context *mc = userdata;
570
551
  assert(r);                    /* Spurious warning */
571
552
  
604
585
                             const char *name,
605
586
                             const char *type,
606
587
                             const char *domain,
607
 
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags
608
 
                             flags,
 
588
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
609
589
                             void* userdata) {
610
590
  mandos_context *mc = userdata;
611
591
  assert(b);                    /* Spurious warning */
628
608
       the callback function is called the server will free
629
609
       the resolver for us. */
630
610
    
631
 
    if (!(avahi_s_service_resolver_new(mc->server, interface,
632
 
                                       protocol, name, type, domain,
 
611
    if (!(avahi_s_service_resolver_new(mc->server, interface, protocol, name,
 
612
                                       type, domain,
633
613
                                       AVAHI_PROTO_INET6, 0,
634
614
                                       resolve_callback, mc)))
635
615
      fprintf(stderr, "Failed to resolve service '%s': %s\n", name,