/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 03:33:56 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080803033356-6aemgj0g0hoz91ow
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
                                                 On debug, show
                                                 decrypted plaintext
                                                 in hexadecimal.  Free
                                                 the GPGME data
                                                 buffers even on
                                                 errors.

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