~ubuntu-branches/ubuntu/raring/reprepro/raring

« back to all changes in this revision

Viewing changes to signature.c

  • Committer: Bazaar Package Importer
  • Author(s): Bernhard R. Link
  • Date: 2011-05-05 16:34:23 UTC
  • mfrom: (21.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110505163423-x49kbdijyoubai4x
Tags: 4.6.0-1
* new release
- general cleanup
- new FilterSrcList
* increase Standards-Version, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
gpgme_ctx_t context = NULL;
40
40
 
41
41
retvalue gpgerror(gpg_error_t err) {
42
 
        if( err != 0 ) {
 
42
        if (err != 0) {
43
43
                fprintf(stderr, "gpgme gave error %s:%d:  %s\n",
44
44
                                gpg_strsource(err), gpg_err_code(err),
45
45
                                gpg_strerror(err));
46
 
                if( gpg_err_code(err) == GPG_ERR_ENOMEM )
 
46
                if (gpg_err_code(err) == GPG_ERR_ENOMEM)
47
47
                        return RET_ERROR_OOM;
48
48
                else
49
49
                        return RET_ERROR_GPGME;
59
59
        msg = mprintf("%s needs a passphrase\nPlease enter passphrase%s:",
60
60
                        (uid_hint!=NULL)?uid_hint:"key",
61
61
                        (prev_was_bad!=0)?" again":"");
62
 
        if( msg == NULL )
 
62
        if (msg == NULL)
63
63
                return gpg_err_make(GPG_ERR_SOURCE_USER_1, GPG_ERR_ENOMEM);
64
64
        p = getpass(msg);
65
65
        write(fd, p, strlen(p));
73
73
#ifdef HAVE_LIBGPGME
74
74
        gpg_error_t err;
75
75
 
76
 
        if( context != NULL )
 
76
        if (context != NULL)
77
77
                return RET_NOTHING;
78
78
        gpgme_check_version(NULL);
79
79
        err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
80
 
        if( err != 0 )
 
80
        if (err != 0)
81
81
                return gpgerror(err);
82
82
        err = gpgme_new(&context);
83
 
        if( err != 0 )
84
 
                return gpgerror(err);
85
 
        err = gpgme_set_protocol(context,GPGME_PROTOCOL_OpenPGP);
86
 
        if( err != 0 )
87
 
                return gpgerror(err);
88
 
        if( allowpassphrase )
89
 
                gpgme_set_passphrase_cb(context,signature_getpassphrase,NULL);
90
 
        gpgme_set_armor(context,1);
 
83
        if (err != 0)
 
84
                return gpgerror(err);
 
85
        err = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP);
 
86
        if (err != 0)
 
87
                return gpgerror(err);
 
88
        if (allowpassphrase)
 
89
                gpgme_set_passphrase_cb(context, signature_getpassphrase,
 
90
                                NULL);
 
91
        gpgme_set_armor(context, 1);
91
92
#endif /* HAVE_LIBGPGME */
92
93
        return RET_OK;
93
94
}
94
95
 
95
96
void signatures_done(void) {
96
97
#ifdef HAVE_LIBGPGME
97
 
        if( context != NULL ) {
 
98
        if (context != NULL) {
98
99
                gpgme_release(context);
99
100
                context = NULL;
100
101
        }
108
109
        int i;
109
110
 
110
111
        signresult = gpgme_op_sign_result(context);
111
 
        if( signresult != NULL && signresult->signatures != NULL )
 
112
        if (signresult != NULL && signresult->signatures != NULL)
112
113
                return RET_OK;
113
114
        /* in an ideal world, this point is never reached.
114
115
         * Sadly it is and people are obviously confused by it,
115
116
         * so do some work to give helpful messages. */
116
 
        if( options != NULL ) {
 
117
        if (options != NULL) {
117
118
                assert (options->count > 0);
118
119
                uidoptions = mprintf(" -u '%s'", options->values[0]);
119
 
                for( i = 1 ;
 
120
                for (i = 1 ;
120
121
                     uidoptions != NULL && i < options->count ;
121
 
                     i++ ) {
 
122
                     i++) {
122
123
                        char *u = mprintf("%s -u '%s'", uidoptions,
123
124
                                        options->values[0]);
124
125
                        free(uidoptions);
125
126
                        uidoptions = u;
126
127
                }
127
 
                if( FAILEDTOALLOC(uidoptions) )
 
128
                if (FAILEDTOALLOC(uidoptions))
128
129
                        return RET_ERROR_OOM;
129
130
        } else
130
131
                uidoptions = NULL;
131
132
 
132
 
        if( signresult == NULL )
 
133
        if (signresult == NULL)
133
134
                fputs(
134
135
"Error: gpgme returned NULL unexpectedly for gpgme_op_sign_result\n", stderr);
135
136
        else
136
 
                fputs( "Error: gpgme created no signature!\n", stderr);
 
137
                fputs("Error: gpgme created no signature!\n", stderr);
137
138
        fputs(
138
139
"This most likely means gpg is confused or produces some error libgpgme is\n"
139
140
"not able to understand. Try running\n", stderr);
140
 
        if( willcleanup )
 
141
        if (willcleanup)
141
142
                fprintf(stderr,
142
143
"gpg %s --output 'some-other-file' %s 'some-file'\n",
143
144
                        (uidoptions==NULL)?"":uidoptions,
163
164
        int fd, e, ret;
164
165
 
165
166
        signature_data = gpgme_data_release_and_get_mem(dh_gpg, &signature_len);
166
 
        if( signature_data == NULL )
 
167
        if (FAILEDTOALLOC(signature_data))
167
168
                return RET_ERROR_OOM;
168
169
        fd = open(signaturename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NOFOLLOW, 0666);
169
 
        if( fd < 0 ) {
 
170
        if (fd < 0) {
170
171
                free(signature_data);
171
172
                return RET_ERRNO(errno);
172
173
        }
173
174
        p = signature_data;
174
 
        while( signature_len > 0 ) {
 
175
        while (signature_len > 0) {
175
176
                written = write(fd, p, signature_len);
176
 
                if( written < 0 ) {
 
177
                if (written < 0) {
177
178
                        e = errno;
178
179
                        fprintf(stderr, "Error %d writing to %s: %s\n",
179
180
                                        e, signaturename,
191
192
        free(signature_data);
192
193
#endif
193
194
        ret = close(fd);
194
 
        if( ret < 0 ) {
 
195
        if (ret < 0) {
195
196
                e = errno;
196
197
                fprintf(stderr, "Error %d writing to %s: %s\n",
197
198
                                e, signaturename,
198
199
                                strerror(e));
199
200
                return RET_ERRNO(e);
200
201
        }
201
 
        if( verbose > 1 ) {
 
202
        if (verbose > 1) {
202
203
                printf("Successfully created '%s'\n", signaturename);
203
204
        }
204
205
        return RET_OK;
210
211
        retvalue r;
211
212
 
212
213
        err = gpgme_data_new(&dh_gpg);
213
 
        if( err != 0 )
 
214
        if (err != 0)
214
215
                return gpgerror(err);
215
216
        err = gpgme_op_sign(context, dh, dh_gpg,
216
217
                        clearsign?GPGME_SIG_MODE_CLEAR:GPGME_SIG_MODE_DETACH);
217
 
        if( err != 0 )
 
218
        if (err != 0)
218
219
                return gpgerror(err);
219
220
        r = check_signature_created(clearsign, willcleanup,
220
221
                        options, filename, signaturename);
221
 
        if( RET_WAS_ERROR(r) ) {
 
222
        if (RET_WAS_ERROR(r)) {
222
223
                gpgme_data_release(dh_gpg);
223
224
                return r;
224
225
        }
236
237
        gpgme_data_t dh;
237
238
#endif /* HAVE_LIBGPGME */
238
239
 
239
 
        assert( options != NULL && options->count > 0 );
 
240
        assert (options != NULL && options->count > 0);
240
241
 
241
242
        r = signature_init(false);
242
 
        if( RET_WAS_ERROR(r) )
 
243
        if (RET_WAS_ERROR(r))
243
244
                return r;
244
245
 
245
246
        /* make sure it does not already exists */
246
247
 
247
248
        ret = unlink(signaturename);
248
 
        if( ret != 0 && (e = errno) != ENOENT ) {
249
 
                fprintf(stderr, "Could not remove '%s' to prepare replacement: %s\n",
 
249
        if (ret != 0 && (e = errno) != ENOENT) {
 
250
                fprintf(stderr,
 
251
"Could not remove '%s' to prepare replacement: %s\n",
250
252
                                signaturename, strerror(e));
251
253
                return RET_ERROR;
252
254
        }
253
255
        ret = unlink(clearsignfilename);
254
 
        if( ret != 0 && (e = errno) != ENOENT ) {
255
 
                fprintf(stderr, "Could not remove '%s' to prepare replacement: %s\n",
 
256
        if (ret != 0 && (e = errno) != ENOENT) {
 
257
                fprintf(stderr,
 
258
"Could not remove '%s' to prepare replacement: %s\n",
256
259
                                clearsignfilename, strerror(e));
257
260
                return RET_ERROR;
258
261
        }
259
262
 
260
 
        if( options->values[0][0] == '!' ) {
 
263
        if (options->values[0][0] == '!') {
261
264
                // TODO: allow external programs, too
262
 
                fprintf(stderr, "sign-scripts (starting with '!') not allowed yet.\n");
 
265
                fprintf(stderr,
 
266
"sign-scripts (starting with '!') not allowed yet.\n");
263
267
                return RET_ERROR;
264
268
        }
265
269
#ifdef HAVE_LIBGPGME
266
270
        gpgme_signers_clear(context);
267
 
        if( options->count == 1 &&
 
271
        if (options->count == 1 &&
268
272
                        (strcasecmp(options->values[0], "yes") == 0 ||
269
 
                          strcasecmp(options->values[0], "default") == 0) ) {
 
273
                          strcasecmp(options->values[0], "default") == 0)) {
270
274
                /* use default options */
271
275
                options = NULL;
272
 
        } else for( i = 0 ; i < options->count ; i++ ) {
 
276
        } else for (i = 0 ; i < options->count ; i++) {
273
277
                const char *option = options->values[i];
274
278
                gpgme_key_t key;
275
279
 
276
280
                err = gpgme_op_keylist_start(context, option, 1);
277
 
                if( err != 0 )
 
281
                if (err != 0)
278
282
                        return gpgerror(err);
279
283
                err = gpgme_op_keylist_next(context, &key);
280
 
                if( gpg_err_code(err) == GPG_ERR_EOF ) {
281
 
                        fprintf(stderr, "Could not find any key matching '%s'!\n", option);
 
284
                if (gpg_err_code(err) == GPG_ERR_EOF) {
 
285
                        fprintf(stderr,
 
286
"Could not find any key matching '%s'!\n", option);
282
287
                        return RET_ERROR;
283
288
                }
284
289
                err = gpgme_signers_add(context, key);
285
290
                gpgme_key_unref(key);
286
 
                if( err != 0 ) {
 
291
                if (err != 0) {
287
292
                        gpgme_op_keylist_end(context);
288
293
                        return gpgerror(err);
289
294
                }
291
296
        }
292
297
 
293
298
        err = gpgme_data_new_from_mem(&dh, data, datalen, 0);
294
 
        if( err != 0 ) {
 
299
        if (err != 0) {
295
300
                return gpgerror(err);
296
301
        }
297
302
 
298
303
        r = create_signature(false, dh, options,
299
304
                        filename, signaturename, willcleanup);
300
 
        if( RET_WAS_ERROR(r) ) {
 
305
        if (RET_WAS_ERROR(r)) {
301
306
                gpgme_data_release(dh);
302
307
                return r;
303
308
        }
304
309
        i = gpgme_data_seek(dh, 0, SEEK_SET);
305
 
        if( i < 0 ) {
 
310
        if (i < 0) {
306
311
                e = errno;
307
312
                fprintf(stderr,
308
313
"Error %d rewinding gpgme's data buffer to start: %s\n",
313
318
        r = create_signature(true, dh, options,
314
319
                        filename, clearsignfilename, willcleanup);
315
320
        gpgme_data_release(dh);
316
 
        if( RET_WAS_ERROR(r) )
 
321
        if (RET_WAS_ERROR(r))
317
322
                return r;
318
323
        return RET_OK;
319
324
#else /* HAVE_LIBGPGME */
338
343
        struct signature *sig;
339
344
 
340
345
        result = gpgme_op_verify_result(context);
341
 
        if( result == NULL ) {
342
 
                fprintf(stderr,"Internal error communicating with libgpgme: no result record!\n\n");
 
346
        if (result == NULL) {
 
347
                fprintf(stderr,
 
348
"Internal error communicating with libgpgme: no result record!\n\n");
343
349
                return RET_ERROR_GPGME;
344
350
        }
345
 
        if( signatures_p != NULL ) {
 
351
        if (signatures_p != NULL) {
346
352
                count = 0;
347
 
                for( s = result->signatures ; s != NULL ; s = s->next ) {
 
353
                for (s = result->signatures ; s != NULL ; s = s->next) {
348
354
                        count++;
349
355
                }
350
356
                signatures = calloc(1, sizeof(struct signatures) +
351
357
                                count * sizeof(struct signature));
352
 
                if( FAILEDTOALLOC(signatures) )
 
358
                if (FAILEDTOALLOC(signatures))
353
359
                        return RET_ERROR_OOM;
354
360
                signatures->count = count;
355
361
                signatures->validcount = 0;
358
364
                signatures = NULL;
359
365
                sig = NULL;
360
366
        }
361
 
        for( s = result->signatures ; s != NULL ; s = s->next ) {
 
367
        for (s = result->signatures ; s != NULL ; s = s->next) {
362
368
                enum signature_state state = sist_error;
363
369
 
364
 
                if( signatures_p != NULL ) {
 
370
                if (signatures_p != NULL) {
365
371
                        sig->keyid = strdup(s->fpr);
366
 
                        if( FAILEDTOALLOC(sig->keyid) ) {
 
372
                        if (FAILEDTOALLOC(sig->keyid)) {
367
373
                                signatures_free(signatures);
368
374
                                return RET_ERROR_OOM;
369
375
                        }
370
376
                }
371
 
                switch( gpg_err_code(s->status) ) {
 
377
                switch (gpg_err_code(s->status)) {
372
378
                        case GPG_ERR_NO_ERROR:
373
379
                                had_valid = true;
374
380
                                state = sist_valid;
375
 
                                if( signatures )
 
381
                                if (signatures)
376
382
                                        signatures->validcount++;
377
383
                                break;
378
384
                        case GPG_ERR_KEY_EXPIRED:
379
385
                                had_valid = true;
380
 
                                if( verbose > 0 )
 
386
                                if (verbose > 0)
381
387
                                        fprintf(stderr,
382
388
"Ignoring signature with '%s' on '%s', as the key has expired.\n",
383
389
                                                s->fpr, filename);
384
390
                                state = sist_mostly;
385
 
                                if( sig != NULL )
 
391
                                if (sig != NULL)
386
392
                                        sig->expired_key = true;
387
393
                                break;
388
394
                        case GPG_ERR_CERT_REVOKED:
389
395
                                had_valid = true;
390
 
                                if( verbose > 0 )
 
396
                                if (verbose > 0)
391
397
                                        fprintf(stderr,
392
398
"Ignoring signature with '%s' on '%s', as the key is revoked.\n",
393
399
                                                s->fpr, filename);
394
400
                                state = sist_mostly;
395
 
                                if( sig != NULL )
 
401
                                if (sig != NULL)
396
402
                                        sig->revoced_key = true;
397
403
                                break;
398
404
                        case GPG_ERR_SIG_EXPIRED:
399
405
                                had_valid = true;
400
 
                                if( verbose > 0 ) {
 
406
                                if (verbose > 0) {
401
407
                                        time_t timestamp = s->timestamp,
402
408
                                              exp_timestamp = s->exp_timestamp;
403
409
                                        fprintf(stderr,
408
414
                                                ctime(&exp_timestamp));
409
415
                                }
410
416
                                state = sist_mostly;
411
 
                                if( sig != NULL )
 
417
                                if (sig != NULL)
412
418
                                        sig->expired_signature = true;
413
419
                                break;
414
420
                        case GPG_ERR_BAD_SIGNATURE:
415
421
                                had_broken = true;
416
 
                                if( verbose > 0 ) {
 
422
                                if (verbose > 0) {
417
423
                                        fprintf(stderr,
418
424
"WARNING: '%s' has a invalid signature with '%s'\n", filename, s->fpr);
419
425
                                }
420
426
                                state = sist_bad;
421
427
                                break;
422
428
                        case GPG_ERR_NO_PUBKEY:
423
 
                                if( verbose > 0 ) {
 
429
                                if (verbose > 0) {
424
430
                                        fprintf(stderr,
425
431
"Could not check validity of signature with '%s' in '%s' as public key missing!\n",
426
432
                                                s->fpr, filename);
441
447
                        default:
442
448
                                break;
443
449
                }
444
 
                if( state == sist_error ) {
 
450
                if (state == sist_error) {
445
451
                        fprintf(stderr,
446
452
"Error checking signature (gpgme returned unexpected value %d)!\n"
447
453
"Please file a bug report, so reprepro can handle this in the future.\n",
449
455
                        signatures_free(signatures);
450
456
                        return RET_ERROR_GPGME;
451
457
                }
452
 
                if( sig != NULL ) {
 
458
                if (sig != NULL) {
453
459
                        sig->state = state;
454
460
                        sig++;
455
461
                }
456
462
        }
457
 
        if( broken != NULL && had_broken && ! had_valid )
 
463
        if (broken != NULL && had_broken && ! had_valid)
458
464
                *broken = true;
459
 
        if( signatures_p != NULL )
 
465
        if (signatures_p != NULL)
460
466
                *signatures_p = signatures;
461
467
        return RET_OK;
462
468
}
467
473
           valid if the primary key is expired */
468
474
        int i;
469
475
 
470
 
        for( i = 0 ; i < signatures->count ; i++ ) {
 
476
        for (i = 0 ; i < signatures->count ; i++) {
471
477
                gpg_error_t err;
472
478
                gpgme_key_t gpgme_key = NULL;
473
479
                gpgme_subkey_t subkey;
474
480
                struct signature *sig = &signatures->signatures[i];
475
481
 
476
 
                if( sig->state == sist_error || sig->state == sist_missing ) {
 
482
                if (sig->state == sist_error || sig->state == sist_missing) {
477
483
                        sig->primary_keyid = strdup(sig->keyid);
478
 
                        if( FAILEDTOALLOC(sig->primary_keyid) )
 
484
                        if (FAILEDTOALLOC(sig->primary_keyid))
479
485
                                return RET_ERROR_OOM;
480
486
                        continue;
481
487
                }
482
488
 
483
489
                err = gpgme_get_key(context, sig->keyid, &gpgme_key, 0);
484
 
                if( err != 0 ) {
485
 
                        fprintf(stderr, "gpgme error %s:%d retrieving key '%s': %s\n",
486
 
                                        gpg_strsource(err), (int)gpg_err_code(err),
 
490
                if (err != 0) {
 
491
                        fprintf(stderr,
 
492
"gpgme error %s:%d retrieving key '%s': %s\n",
 
493
                                        gpg_strsource(err),
 
494
                                        (int)gpg_err_code(err),
487
495
                                        sig->keyid, gpg_strerror(err));
488
 
                        if( gpg_err_code(err) == GPG_ERR_ENOMEM )
 
496
                        if (gpg_err_code(err) == GPG_ERR_ENOMEM)
489
497
                                return RET_ERROR_OOM;
490
498
                        else
491
499
                                return RET_ERROR_GPGME;
492
500
                }
493
 
                assert( gpgme_key != NULL );
 
501
                assert (gpgme_key != NULL);
494
502
                /* the first "sub"key is the primary key */
495
503
                subkey = gpgme_key->subkeys;
496
 
                if( subkey->revoked ) {
 
504
                if (subkey->revoked) {
497
505
                        sig->revoced_key = true;
498
 
                        if( sig->state == sist_valid ) {
 
506
                        if (sig->state == sist_valid) {
499
507
                                sig->state = sist_mostly;
500
508
                                signatures->validcount--;
501
509
                        }
502
510
                }
503
 
                if( subkey->expired ) {
 
511
                if (subkey->expired) {
504
512
                        sig->expired_key = true;
505
 
                        if( sig->state == sist_valid ) {
 
513
                        if (sig->state == sist_valid) {
506
514
                                sig->state = sist_mostly;
507
515
                                signatures->validcount--;
508
516
                        }
509
517
                }
510
518
                sig->primary_keyid = strdup(subkey->keyid);
511
519
                gpgme_key_unref(gpgme_key);
512
 
                if( FAILEDTOALLOC(sig->primary_keyid) )
 
520
                if (FAILEDTOALLOC(sig->primary_keyid))
513
521
                        return RET_ERROR_OOM;
514
522
        }
515
523
        return RET_OK;
517
525
#endif /* HAVE_LIBGPGME */
518
526
 
519
527
static inline void extractchunk(const char *buffer, const char **begin, const char **end, const char **next) {
520
 
        const char *startofchanges,*endofchanges,*afterchanges;
 
528
        const char *startofchanges, *endofchanges, *afterchanges;
521
529
 
522
530
        startofchanges = buffer;
523
 
        while( *startofchanges == ' ' || *startofchanges == '\t' ||
524
 
                        *startofchanges == '\r' || *startofchanges =='\n' )
 
531
        while (*startofchanges == ' ' || *startofchanges == '\t' ||
 
532
                        *startofchanges == '\r' || *startofchanges =='\n')
525
533
                startofchanges++;
526
534
 
527
535
        endofchanges = startofchanges;
528
536
        afterchanges = NULL;
529
 
        while( *endofchanges != '\0' ) {
530
 
                if( *endofchanges == '\n' ) {
 
537
        while (*endofchanges != '\0') {
 
538
                if (*endofchanges == '\n') {
531
539
                        endofchanges++;
532
540
                        afterchanges = endofchanges;
533
 
                        while( *afterchanges =='\r' )
 
541
                        while (*afterchanges =='\r')
534
542
                                afterchanges++;
535
 
                        if( *afterchanges == '\n' )
 
543
                        if (*afterchanges == '\n')
536
544
                                break;
537
545
                        endofchanges = afterchanges;
538
546
                        afterchanges = NULL;
540
548
                        endofchanges++;
541
549
        }
542
550
 
543
 
        if( afterchanges == NULL )
 
551
        if (afterchanges == NULL)
544
552
                afterchanges = endofchanges;
545
553
        else
546
 
                while( *afterchanges == '\n' || *afterchanges =='\r' )
 
554
                while (*afterchanges == '\n' || *afterchanges =='\r')
547
555
                        afterchanges++;
548
556
        *begin = startofchanges;
549
557
        *end = endofchanges;
553
561
void signatures_free(struct signatures *signatures) {
554
562
        int i;
555
563
 
556
 
        if( signatures == NULL )
 
564
        if (signatures == NULL)
557
565
                return;
558
566
 
559
 
        for( i = 0 ; i < signatures->count ; i++ ) {
 
567
        for (i = 0 ; i < signatures->count ; i++) {
560
568
                free(signatures->signatures[i].keyid);
561
569
                free(signatures->signatures[i].primary_keyid);
562
570
        }
565
573
 
566
574
#ifdef HAVE_LIBGPGME
567
575
static retvalue extract_signed_data(const char *buffer, size_t bufferlen, const char *filenametoshow, char **chunkread, /*@null@*/ /*@out@*/struct signatures **signatures_p, bool *brokensignature, bool *failed) {
568
 
        const char *startofchanges,*endofchanges,*afterchanges;
 
576
        const char *startofchanges, *endofchanges, *afterchanges;
569
577
        char *chunk;
570
578
        gpg_error_t err;
571
 
        gpgme_data_t dh,dh_gpg;
 
579
        gpgme_data_t dh, dh_gpg;
572
580
        size_t plain_len;
573
581
        char *plain_data;
574
582
        retvalue r;
576
584
        bool foundbroken = false;
577
585
 
578
586
        r = signature_init(false);
579
 
        if( RET_WAS_ERROR(r) )
 
587
        if (RET_WAS_ERROR(r))
580
588
                return r;
581
589
 
582
590
        err = gpgme_data_new_from_mem(&dh_gpg, buffer, bufferlen, 0);
583
 
        if( err != 0 )
 
591
        if (err != 0)
584
592
                return gpgerror(err);
585
593
 
586
594
        err = gpgme_data_new(&dh);
587
 
        if( err != 0 ) {
 
595
        if (err != 0) {
588
596
                gpgme_data_release(dh_gpg);
589
597
                return gpgerror(err);
590
598
        }
591
599
        err = gpgme_op_verify(context, dh_gpg, NULL, dh);
592
 
        if( gpg_err_code(err) == GPG_ERR_NO_DATA ) {
593
 
                if( verbose > 5 )
594
 
                        fprintf(stderr,"Data seems not to be signed trying to use directly....\n");
 
600
        if (gpg_err_code(err) == GPG_ERR_NO_DATA) {
 
601
                if (verbose > 5)
 
602
                        fprintf(stderr,
 
603
"Data seems not to be signed trying to use directly....\n");
595
604
                gpgme_data_release(dh);
596
605
                gpgme_data_release(dh_gpg);
597
606
                return RET_NOTHING;
598
607
        } else {
599
 
                if( err != 0 ) {
 
608
                if (err != 0) {
600
609
                        gpgme_data_release(dh_gpg);
601
610
                        gpgme_data_release(dh);
602
611
                        return gpgerror(err);
603
612
                }
604
 
                if( signatures_p != NULL || brokensignature != NULL ) {
 
613
                if (signatures_p != NULL || brokensignature != NULL) {
605
614
                        r = checksigs(filenametoshow,
606
615
                                (signatures_p!=NULL)?&signatures:NULL,
607
616
                                (brokensignature!=NULL)?&foundbroken:NULL);
608
 
                        if( RET_WAS_ERROR(r) ) {
 
617
                        if (RET_WAS_ERROR(r)) {
609
618
                                gpgme_data_release(dh_gpg);
610
619
                                gpgme_data_release(dh);
611
620
                                return r;
612
621
                        }
613
622
                }
614
623
                gpgme_data_release(dh_gpg);
615
 
                plain_data = gpgme_data_release_and_get_mem(dh,&plain_len);
616
 
                if( plain_data == NULL ) {
 
624
                plain_data = gpgme_data_release_and_get_mem(dh, &plain_len);
 
625
                if (plain_data == NULL) {
617
626
                        fprintf(stderr,
618
627
"(not yet fatal) ERROR: libgpgme failed to extract the plain data out of\n"
619
628
"'%s'.\n"
626
635
                        signatures_free(signatures);
627
636
                        return RET_NOTHING;
628
637
                }
629
 
                if( signatures != NULL ) {
 
638
                if (signatures != NULL) {
630
639
                        r = check_primary_keys(signatures);
631
 
                        if( RET_WAS_ERROR(r) ) {
 
640
                        if (RET_WAS_ERROR(r)) {
632
641
                                signatures_free(signatures);
633
642
                                return r;
634
643
                        }
635
644
                }
636
645
        }
637
646
 
638
 
        if( plain_data == NULL )
 
647
        if (FAILEDTOALLOC(plain_data))
639
648
                r = RET_ERROR_OOM;
640
649
        else {
641
650
                // TODO: check if the new extractchunk can be used...
642
651
 
643
652
                startofchanges = plain_data;
644
 
                while( (size_t)(startofchanges - plain_data) < plain_len &&
645
 
                                *startofchanges != '\0' && xisspace(*startofchanges)) {
 
653
                while ((size_t)(startofchanges - plain_data) < plain_len
 
654
                                && *startofchanges != '\0'
 
655
                                && xisspace(*startofchanges)) {
646
656
                        startofchanges++;
647
657
                }
648
 
                if( (size_t)(startofchanges - plain_data) >= plain_len ) {
 
658
                if ((size_t)(startofchanges - plain_data) >= plain_len) {
649
659
                        fprintf(stderr,
650
660
"Could only find spaces within '%s'!\n",
651
661
                                        filenametoshow);
653
663
                } else
654
664
                        r = RET_OK;
655
665
        }
656
 
        if( RET_IS_OK(r) ) {
 
666
        if (RET_IS_OK(r)) {
657
667
                endofchanges = startofchanges;
658
 
                while( (size_t)(endofchanges - plain_data) < plain_len &&
 
668
                while ((size_t)(endofchanges - plain_data) < plain_len &&
659
669
                                *endofchanges != '\0' &&
660
 
                                ( *endofchanges != '\n' || *(endofchanges-1)!= '\n')) {
 
670
                                (*endofchanges != '\n'
 
671
                                 || *(endofchanges-1)!= '\n')) {
661
672
                        endofchanges++;
662
673
                }
663
674
                afterchanges = endofchanges;
664
 
                while( (size_t)(afterchanges - plain_data) < plain_len &&
665
 
                                *afterchanges != '\0' && xisspace(*afterchanges)) {
 
675
                while ((size_t)(afterchanges - plain_data) < plain_len
 
676
                                && *afterchanges != '\0'
 
677
                                && xisspace(*afterchanges)) {
666
678
                        afterchanges++;
667
679
                }
668
 
                if( (size_t)(afterchanges - plain_data) != plain_len ) {
669
 
                        if( *afterchanges == '\0' )
 
680
                if ((size_t)(afterchanges - plain_data) != plain_len) {
 
681
                        if (*afterchanges == '\0')
670
682
                                fprintf(stderr,
671
683
"Unexpected \\0 character within '%s'!\n",
672
684
                                        filenametoshow);
677
689
                        r = RET_ERROR;
678
690
                }
679
691
        }
680
 
        if( RET_IS_OK(r) ) {
681
 
                chunk = strndup(startofchanges,endofchanges-startofchanges);
682
 
                if( chunk == NULL )
 
692
        if (RET_IS_OK(r)) {
 
693
                chunk = strndup(startofchanges, endofchanges - startofchanges);
 
694
                if (FAILEDTOALLOC(chunk))
683
695
                        r = RET_ERROR_OOM;
684
696
                else
685
697
                        *chunkread = chunk;
689
701
#else
690
702
        free(plain_data);
691
703
#endif
692
 
        if( RET_IS_OK(r) ) {
693
 
                if( signatures_p != NULL )
 
704
        if (RET_IS_OK(r)) {
 
705
                if (signatures_p != NULL)
694
706
                        *signatures_p = signatures;
695
 
                if( brokensignature != NULL )
 
707
                if (brokensignature != NULL)
696
708
                        *brokensignature = foundbroken;
697
709
        } else {
698
710
                signatures_free(signatures);
704
716
/* Read a single chunk from a file, that may be signed. */
705
717
retvalue signature_readsignedchunk(const char *filename, const char *filenametoshow, char **chunkread, /*@null@*/ /*@out@*/struct signatures **signatures_p, bool *brokensignature) {
706
718
        char *chunk, *h, *afterchunk;
707
 
        const char *startofchanges,*endofchanges,*afterchanges;
 
719
        const char *startofchanges, *endofchanges, *afterchanges;
708
720
        size_t chunklen, len;
709
721
        retvalue r;
710
722
        bool failed = false;
711
723
 
712
724
        r = readtextfile(filename, filenametoshow, &chunk, &chunklen);
713
 
        if( !RET_IS_OK(r) )
 
725
        if (!RET_IS_OK(r))
714
726
                return r;
715
727
 
716
 
        if( chunklen == 0 ) {
 
728
        if (chunklen == 0) {
717
729
                fprintf(stderr, "Unexpected empty file '%s'!\n",
718
730
                                        filenametoshow);
719
731
                free(chunk);
721
733
        }
722
734
 
723
735
        extractchunk(chunk, &startofchanges, &endofchanges, &afterchanges);
724
 
        if( endofchanges == startofchanges ) {
 
736
        if (endofchanges == startofchanges) {
725
737
                fprintf(stderr, "Could only find spaces within '%s'!\n",
726
738
                                        filenametoshow);
727
739
                free(chunk);
729
741
        }
730
742
 
731
743
        /* fast-track unsigned chunks: */
732
 
        if( startofchanges[0] != '-' && *afterchanges == '\0' ) {
733
 
                if( verbose > 5 )
734
 
                        fprintf(stderr,"Data seems not to be signed trying to use directly...\n");
 
744
        if (startofchanges[0] != '-' && *afterchanges == '\0') {
 
745
                if (verbose > 5 && strncmp(startofchanges, "Format:", 7) != 0
 
746
                                && strncmp(startofchanges, "Source:", 7) != 0)
 
747
                        fprintf(stderr,
 
748
"Data seems not to be signed trying to use directly...\n");
735
749
                len = chunk_extract(chunk, chunk, &afterchunk);
736
 
                assert( *afterchunk == '\0' );
737
 
                assert( chunk[len] == '\0' );
 
750
                assert (*afterchunk == '\0');
 
751
                assert (chunk[len] == '\0');
738
752
                h = realloc(chunk, len + 1);
739
 
                if( h != NULL )
 
753
                if (h != NULL)
740
754
                        chunk = h;
741
755
                *chunkread = chunk;
742
 
                if( signatures_p != NULL )
 
756
                if (signatures_p != NULL)
743
757
                        *signatures_p = NULL;
744
 
                if( brokensignature != NULL )
 
758
                if (brokensignature != NULL)
745
759
                        *brokensignature = false;
746
760
                return RET_OK;
747
761
        }
748
762
 
749
 
        if( startofchanges[0] != '-' ) {
750
 
                fprintf(stderr, "Error parsing '%s': Seems not to be signed but has spurious empty line.\n", filenametoshow);
 
763
        if (startofchanges[0] != '-') {
 
764
                fprintf(stderr,
 
765
"Error parsing '%s': Seems not to be signed but has spurious empty line.\n",
 
766
                                filenametoshow);
751
767
                free(chunk);
752
768
                return RET_ERROR;
753
769
        }
755
771
#ifdef HAVE_LIBGPGME
756
772
        r = extract_signed_data(chunk, chunklen, filenametoshow, chunkread,
757
773
                        signatures_p, brokensignature, &failed);
758
 
        if( r != RET_NOTHING ) {
 
774
        if (r != RET_NOTHING) {
759
775
                free(chunk);
760
776
                return r;
761
777
        }
764
780
        /* We have no libgpgme, it failed, or could not find signature data,
765
781
         * trying to extract it manually, ignoring signatures: */
766
782
 
767
 
        if( *afterchanges == '\0' ) {
 
783
        if (*afterchanges == '\0') {
768
784
                fprintf(stderr,
769
785
"First non-space character is a '-' but there is no empty line in\n"
770
786
"'%s'.\n"
772
788
                free(chunk);
773
789
                return RET_ERROR;
774
790
        }
775
 
        if( strncmp(startofchanges, "-----BEGIN", 10) != 0 ) {
 
791
        if (strncmp(startofchanges, "-----BEGIN", 10) != 0) {
776
792
                fprintf(stderr,
777
793
"Strange content of '%s': First non-space character is '-',\n"
778
794
"but it does not begin with '-----BEGIN'.\n", filenametoshow);
787
803
 
788
804
        len = chunk_extract(chunk, afterchanges, &afterchunk);
789
805
 
790
 
        if( len == 0 ) {
791
 
                fprintf(stderr,"Could not find any data within '%s'!\n",
 
806
        if (len == 0) {
 
807
                fprintf(stderr, "Could not find any data within '%s'!\n",
792
808
                                filenametoshow);
793
809
                free(chunk);
794
810
                return RET_ERROR;
795
811
        }
796
812
 
797
 
        if( *afterchunk == '\0' ) {
 
813
        if (*afterchunk == '\0') {
798
814
                const char *endmarker;
799
815
 
800
816
                endmarker = strstr(chunk, "\n-----");
801
 
                if( endmarker != NULL ) {
 
817
                if (endmarker != NULL) {
802
818
                        endmarker++;
803
 
                        assert( (size_t)(endmarker-chunk) < len );
 
819
                        assert ((size_t)(endmarker-chunk) < len);
804
820
                        len = endmarker-chunk;
805
821
                        chunk[len] = '\0';
806
822
                } else {
811
827
                        free(chunk);
812
828
                        return RET_ERROR;
813
829
                }
814
 
        } else if( strncmp(afterchunk, "-----", 5) != 0 ) {
815
 
                fprintf(stderr,"ERROR: Spurious empty line within '%s'.\n"
 
830
        } else if (strncmp(afterchunk, "-----", 5) != 0) {
 
831
                fprintf(stderr, "ERROR: Spurious empty line within '%s'.\n"
816
832
"Cannot determine what is data and what is not!\n",
817
833
                                filenametoshow);
818
834
                free(chunk);
819
835
                return RET_ERROR;
820
836
        }
821
837
 
822
 
        assert( chunk[len] == '\0' );
 
838
        assert (chunk[len] == '\0');
823
839
        h = realloc(chunk, len + 1);
824
 
        if( h != NULL )
 
840
        if (h != NULL)
825
841
                chunk = h;
826
 
        if( signatures_p != NULL ) {
 
842
        if (signatures_p != NULL) {
827
843
                /* pointer to structure with count 0 to make clear
828
844
                 * it is not unsigned */
829
845
                *signatures_p = calloc(1, sizeof(struct signatures));
830
 
                if( FAILEDTOALLOC(*signatures_p) ) {
 
846
                if (FAILEDTOALLOC(*signatures_p)) {
831
847
                        free(chunk);
832
848
                        return RET_ERROR_OOM;
833
849
                }
834
850
        }
835
851
        *chunkread = chunk;
836
 
        if( brokensignature != NULL )
 
852
        if (brokensignature != NULL)
837
853
                *brokensignature = false;
838
854
        return RET_OK;
839
855
}
852
868
retvalue signature_startsignedfile(const char *directory, const char *basefilename, const char *inlinefilename, struct signedfile **out) {
853
869
        struct signedfile *n;
854
870
 
855
 
        n = calloc(1, sizeof(struct signedfile));
856
 
        if( n == NULL )
 
871
        n = zNEW(struct signedfile);
 
872
        if (FAILEDTOALLOC(n))
857
873
                return RET_ERROR_OOM;
858
874
        n->plainfilename = calc_dirconcat(directory, basefilename);
859
 
        if( n->plainfilename == NULL ) {
 
875
        if (FAILEDTOALLOC(n->plainfilename)) {
860
876
                free(n);
861
877
                return RET_ERROR_OOM;
862
878
        }
863
879
        n->inlinefilename = calc_dirconcat(directory, inlinefilename);
864
 
        if( n->inlinefilename == NULL ) {
 
880
        if (FAILEDTOALLOC(n->inlinefilename)) {
865
881
                free(n->plainfilename);
866
882
                free(n);
867
883
                return RET_ERROR_OOM;
870
886
        n->bufferlen = 0;
871
887
        n->buffersize = DATABUFFERUNITS;
872
888
        n->buffer = malloc(n->buffersize);
873
 
        if( FAILEDTOALLOC(n->buffer) ) {
 
889
        if (FAILEDTOALLOC(n->buffer)) {
874
890
                free(n->plainfilename);
875
891
                free(n->inlinefilename);
876
892
                free(n);
881
897
}
882
898
 
883
899
void signedfile_free(struct signedfile *f, bool cleanup) {
884
 
        if( f == NULL )
 
900
        if (f == NULL)
885
901
                return;
886
 
        if( f->newplainfilename != NULL ) {
887
 
                if( cleanup )
 
902
        if (f->newplainfilename != NULL) {
 
903
                if (cleanup)
888
904
                        (void)unlink(f->newplainfilename);
889
905
                free(f->newplainfilename);
890
906
        }
891
907
        free(f->plainfilename);
892
 
        if( f->newsignfilename != NULL ) {
893
 
                if( cleanup )
 
908
        if (f->newsignfilename != NULL) {
 
909
                if (cleanup)
894
910
                        (void)unlink(f->newsignfilename);
895
911
                free(f->newsignfilename);
896
912
        }
897
913
        free(f->signfilename);
898
 
        if( f->newinlinefilename != NULL ) {
899
 
                if( cleanup )
 
914
        if (f->newinlinefilename != NULL) {
 
915
                if (cleanup)
900
916
                        (void)unlink(f->newinlinefilename);
901
917
                free(f->newinlinefilename);
902
918
        }
911
927
void signedfile_write(struct signedfile *f, const void *data, size_t len) {
912
928
 
913
929
        /* no need to try anything if there already was an error */
914
 
        if( RET_WAS_ERROR(f->result) )
 
930
        if (RET_WAS_ERROR(f->result))
915
931
                return;
916
932
 
917
 
        if( len > f->buffersize - f->bufferlen ) {
 
933
        if (len > f->buffersize - f->bufferlen) {
918
934
                size_t blocks = (len + f->bufferlen)/DATABUFFERUNITS;
919
935
                size_t newsize = (blocks + 1) * DATABUFFERUNITS;
920
936
                char *newbuffer;
921
937
 
922
938
                /* realloc is wasteful, but should not happen too often */
923
939
                newbuffer = realloc(f->buffer, newsize);
924
 
                if( newbuffer == NULL ) {
 
940
                if (FAILEDTOALLOC(newbuffer)) {
925
941
                        free(f->buffer);
926
942
                        f->buffer = NULL;
927
943
                        f->result = RET_ERROR_OOM;
929
945
                }
930
946
                f->buffer = newbuffer;
931
947
                f->buffersize = newsize;
932
 
                assert( f->bufferlen < f->buffersize );
 
948
                assert (f->bufferlen < f->buffersize);
933
949
        }
934
 
        assert( len <= f->buffersize - f->bufferlen );
 
950
        assert (len <= f->buffersize - f->bufferlen);
935
951
        memcpy(f->buffer + f->bufferlen, data, len);
936
952
        f->bufferlen += len;
937
 
        assert( f->bufferlen <= f->buffersize );
 
953
        assert (f->bufferlen <= f->buffersize);
938
954
}
939
955
 
940
956
retvalue signedfile_prepare(struct signedfile *f, const struct strlist *options, bool willcleanup) {
941
957
        size_t len, ofs;
942
958
        int fd, ret;
943
959
 
944
 
        if( RET_WAS_ERROR(f->result) )
 
960
        if (RET_WAS_ERROR(f->result))
945
961
                return f->result;
946
962
 
947
963
        /* write content to file */
948
964
 
949
965
        f->newplainfilename = calc_addsuffix(f->plainfilename, "new");
950
 
        if( FAILEDTOALLOC(f->newplainfilename) )
 
966
        if (FAILEDTOALLOC(f->newplainfilename))
951
967
                return RET_ERROR_OOM;
952
968
 
953
969
        (void)dirs_make_parent(f->newplainfilename);
954
970
        (void)unlink(f->newplainfilename);
955
971
 
956
972
        fd = open(f->newplainfilename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
957
 
        if( fd < 0 ) {
 
973
        if (fd < 0) {
958
974
                int e = errno;
959
975
                fprintf(stderr, "Error creating file '%s': %s\n",
960
976
                                f->newplainfilename,
965
981
        }
966
982
        ofs = 0;
967
983
        len = f->bufferlen;
968
 
        while( len > 0 ) {
 
984
        while (len > 0) {
969
985
                ssize_t written;
970
986
 
971
987
                written = write(fd, f->buffer + ofs, len);
972
 
                if( written < 0 ) {
 
988
                if (written < 0) {
973
989
                        int e = errno;
974
990
                        fprintf(stderr, "Error %d writing to file '%s': %s\n",
975
991
                                        e, f->newplainfilename,
980
996
                        f->newplainfilename = NULL;
981
997
                        return RET_ERRNO(e);
982
998
                }
983
 
                assert( (size_t)written <= len );
 
999
                assert ((size_t)written <= len);
984
1000
                ofs += written;
985
1001
                len -= written;
986
1002
        }
987
1003
        ret = close(fd);
988
 
        if( ret < 0 ) {
 
1004
        if (ret < 0) {
989
1005
                int e = errno;
990
1006
                fprintf(stderr, "Error %d writing to file '%s': %s\n",
991
1007
                                e, f->newplainfilename,
996
1012
                return RET_ERRNO(e);
997
1013
        }
998
1014
        /* now do the actual signing */
999
 
        if( options != NULL && options->count > 0 ) {
 
1015
        if (options != NULL && options->count > 0) {
1000
1016
                retvalue r;
1001
1017
 
1002
 
                assert( f->newplainfilename != NULL );
 
1018
                assert (f->newplainfilename != NULL);
1003
1019
                f->signfilename = calc_addsuffix(f->plainfilename, "gpg");
1004
 
                if( f->signfilename == NULL )
 
1020
                if (FAILEDTOALLOC(f->signfilename))
1005
1021
                        return RET_ERROR_OOM;
1006
1022
                f->newsignfilename = calc_addsuffix(f->signfilename, "new");
1007
 
                if( f->newsignfilename == NULL )
 
1023
                if (FAILEDTOALLOC(f->newsignfilename))
1008
1024
                        return RET_ERROR_OOM;
1009
1025
                f->newinlinefilename = calc_addsuffix(f->inlinefilename, "new");
1010
 
                if( FAILEDTOALLOC(f->newinlinefilename) )
 
1026
                if (FAILEDTOALLOC(f->newinlinefilename))
1011
1027
                        return RET_ERROR_OOM;
1012
1028
 
1013
1029
                r = signature_sign(options,
1016
1032
                                f->newsignfilename,
1017
1033
                                f->newinlinefilename,
1018
1034
                                willcleanup);
1019
 
                if( RET_WAS_ERROR(r) )
 
1035
                if (RET_WAS_ERROR(r))
1020
1036
                        return r;
1021
1037
        }
1022
1038
        return RET_OK;
1026
1042
        retvalue result = RET_OK, r;
1027
1043
        int e;
1028
1044
 
1029
 
        if( f->newsignfilename != NULL && f->signfilename != NULL ) {
 
1045
        if (f->newsignfilename != NULL && f->signfilename != NULL) {
1030
1046
                e = rename(f->newsignfilename, f->signfilename);
1031
 
                if( e < 0 ) {
 
1047
                if (e < 0) {
1032
1048
                        e = errno;
1033
1049
                        fprintf(stderr, "Error %d moving %s to %s: %s!\n", e,
1034
1050
                                        f->newsignfilename,
1036
1052
                        result = RET_ERRNO(e);
1037
1053
                        /* after something was done, do not stop
1038
1054
                         * but try to do as much as possible */
1039
 
                        if( !*toolate )
 
1055
                        if (!*toolate)
1040
1056
                                return result;
1041
1057
                } else {
1042
1058
                        /* does not need deletion any more */
1045
1061
                        *toolate = true;
1046
1062
                }
1047
1063
        }
1048
 
        if( f->newinlinefilename != NULL && f->inlinefilename != NULL ) {
 
1064
        if (f->newinlinefilename != NULL && f->inlinefilename != NULL) {
1049
1065
                e = rename(f->newinlinefilename, f->inlinefilename);
1050
 
                if( e < 0 ) {
 
1066
                if (e < 0) {
1051
1067
                        e = errno;
1052
1068
                        fprintf(stderr, "Error %d moving %s to %s: %s!\n", e,
1053
1069
                                        f->newinlinefilename,
1055
1071
                        result = RET_ERRNO(e);
1056
1072
                        /* after something was done, do not stop
1057
1073
                         * but try to do as much as possible */
1058
 
                        if( !*toolate )
 
1074
                        if (!*toolate)
1059
1075
                                return result;
1060
1076
                } else {
1061
1077
                        /* does not need deletion any more */
1065
1081
                }
1066
1082
        }
1067
1083
        e = rename(f->newplainfilename, f->plainfilename);
1068
 
        if( e < 0 ) {
 
1084
        if (e < 0) {
1069
1085
                e = errno;
1070
1086
                fprintf(stderr, "Error %d moving %s to %s: %s!\n", e,
1071
1087
                                f->newplainfilename,