summaryrefslogtreecommitdiff
path: root/lib/GnuPG/Options.pm
blob: 9b946534a31beec295d315a8e92b6d5af263a713 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
#  Options.pm
#    - providing an object-oriented approach to GnuPG's options
#
#  Copyright (C) 2000 Frank J. Tobin <ftobin@cpan.org>
#
#  This module is free software; you can redistribute it and/or modify it
#  under the same terms as Perl itself.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
#  $Id: Options.pm,v 1.14 2001/08/21 13:31:50 ftobin Exp $
#

package GnuPG::Options;
use Moo;
use MooX::late;
use MooX::HandlesVia;
with qw(GnuPG::HashInit);

use constant BOOLEANS => qw(
    armor
    no_greeting
    verbose
    no_verbose
    quiet
    batch
    always_trust
    rfc1991
    openpgp
    force_v3_sigs
    no_options
    textmode
    meta_pgp_5_compatible
    meta_pgp_2_compatible
    meta_interactive
    ignore_mdc_error
    keyring
    no_default_keyring
);

use constant SCALARS => qw(
    homedir
    default_key
    comment
    status_fd
    logger_fd
    passphrase_fd
    command_fd
    compress_algo
    options
    meta_signing_key
    meta_signing_key_id
    debug_level
    logger_file
);

use constant LISTS => qw(
    encrypt_to
    recipients
    meta_recipients_keys
    meta_recipients_key_ids
    extra_args
);

has $_ => (
    isa     => 'Bool',
    is      => 'rw',
    clearer => 'clear_' . $_,
) for BOOLEANS;

has $_ => (
    isa     => 'Any',
    is      => 'rw',
    clearer => 'clear_' . $_,
) for SCALARS;

for my $list (LISTS) {
    my $ref = $list . "_ref";
    has $ref => (
        handles_via => 'Array',
        is          => 'rw',
        lazy        => 1,
        clearer     => "clear_$list",
        default     => sub { [] },
        handles     => {
            "push_$list" => 'push',
        },
    );

    no strict 'refs';
    *{$list} = sub {
        my $self = shift;
        return wantarray ? @{$self->$ref(@_)} : $self->$ref(@_);
    };
}

sub BUILD {
    my ( $self, $args ) = @_;
    # Newer GnuPG will force failure for old ciphertext unless set
    $args->{ignore_mdc_error} //= 1;

    $self->hash_init( meta_interactive => 1 );
    $self->hash_init(%$args);
}

sub copy {
    my ($self) = @_;

    my $new = ( ref $self )->new();

    foreach my $field ( BOOLEANS, SCALARS, LISTS ) {
        my $value = $self->$field();
        next unless defined $value;
        $new->$field($value);
    }

    return $new;
}

sub get_args {
    my ($self) = @_;

    return (
        $self->get_meta_args(),
        $self->get_option_args(),
        $self->extra_args(),
    );
}

sub get_option_args {
    my ($self) = @_;

    my @args = ();

    push @args, '--homedir', $self->homedir() if $self->homedir();
    push @args, '--options', $self->options() if $self->options();
    push @args, '--no-options' if $self->no_options();
    push @args, '--armor'      if $self->armor();
    push @args, '--textmode'   if $self->textmode();
    push @args, '--default-key', $self->default_key() if $self->default_key();
    push @args, '--no-greeting'  if $self->no_greeting();
    push @args, '--verbose'      if $self->verbose();
    push @args, '--no-verbose'   if $self->no_verbose();
    push @args, '--quiet'        if $self->quiet();
    push @args, '--batch'        if $self->batch();
    push @args, '--trust-model=always' if $self->always_trust();
    push @args, '--comment', $self->comment() if defined $self->comment();
    push @args, '--force-v3-sigs' if $self->force_v3_sigs();
    push @args, '--rfc1991'       if $self->rfc1991;
    push @args, '--openpgp'       if $self->openpgp();
    push @args, '--compress-algo', $self->compress_algo()
        if defined $self->compress_algo();

    push @args, '--status-fd', $self->status_fd()
        if defined $self->status_fd();
    push @args, '--logger-fd', $self->logger_fd()
        if defined $self->logger_fd();
    push @args, '--passphrase-fd', $self->passphrase_fd()
        if defined $self->passphrase_fd();
    push @args, '--command-fd', $self->command_fd()
        if defined $self->command_fd();

    push @args, map { ( '--recipient',  $_ ) } $self->recipients();
    push @args, map { ( '--encrypt-to', $_ ) } $self->encrypt_to();

    push @args, '--debug-level', $self->debug_level() if ($self->debug_level);
    push @args, '--logger-file', $self->logger_file() if ($self->logger_file());

    push @args, '--ignore-mdc-error' if ($self->ignore_mdc_error());
    push @args, '--keyring' if ( $self->keyring() );
    push @args, '--no-default-keyring' if ( $self->no_default_keyring() );

    return @args;
}

sub get_meta_args {
    my ($self) = @_;

    my @args = ();

    push @args, '--compress-algo', 1, '--force-v3-sigs'
        if $self->meta_pgp_5_compatible();
    push @args, '--rfc1991' if $self->meta_pgp_2_compatible();
    push @args, '--batch', '--no-tty' if not $self->meta_interactive();

    # To eliminate confusion, we'll move to having any options
    # that deal with keys end in _id(s) if they only take
    # an id; otherwise we assume that a GnuPG::Key
    push @args, '--default-key', $self->meta_signing_key_id()
        if $self->meta_signing_key_id();
    push @args, '--default-key', $self->meta_signing_key()->hex_id()
        if $self->meta_signing_key();

    push @args,
        map { ( '--recipient', $_ ) } $self->meta_recipients_key_ids();
    push @args,
        map { ( '--recipient', $_->hex_id() ) } $self->meta_recipients_keys();

    return @args;
}

1;

__END__

=head1 NAME

GnuPG::Options - GnuPG options embodiment

=head1 SYNOPSIS

  # assuming $gnupg is a GnuPG::Interface object
  $gnupg->options->armor( 1 );
  $gnupg->options->push_recipients( 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' );

=head1 DESCRIPTION

GnuPG::Options objects are generally not instantiated on their
own, but rather as part of a GnuPG::Interface object.

=head1 OBJECT METHODS

=over 4

=item new( I<%initialization_args> )

This methods creates a new object.  The optional arguments are
initialization of data members.

=item hash_init( I<%args> ).


=item copy

Returns a copy of this object.  Useful for 'saving' options.

=item get_args

Returns a list of arguments to be passed to GnuPG based
on data members which are 'meta_' options, regular options,
and then I<extra_args>, in that order.

=back

=head1 OBJECT DATA MEMBERS

=over 4

=item homedir

=item armor

=item textmode

=item default_key

=item no_greeting

=item verbose

=item no_verbose

=item quiet

=item batch

=item always_trust

=item comment

=item status_fd

=item logger_fd

=item passphrase_fd

=item compress_algo

=item force_v3_sigs

=item rfc1991

=item openpgp

=item options

=item no_options

=item encrypt_to

=item recipients

=back

These options correlate directly to many GnuPG options.  For those that
are boolean to GnuPG, simply that argument is passed.  For those
that are associated with a scalar, that scalar is passed passed
as an argument appropriate.  For those that can be specified more
than once, such as B<recipients>, those are considered lists
and passed accordingly.  Each are undefined or false to begin.

=head2 Meta Options

Meta options are those which do not correlate directly to any
option in GnuPG, but rather are generally a bundle of options
used to accomplish a specific goal, such as obtaining
compatibility with PGP 5.  The actual arguments each of these
reflects may change with time.  Each defaults to false unless
otherwise specified.

These options are being designed and to provide a non-GnuPG-specific
abstraction, to help create compatibility with a possible
PGP::Interface module.

To help avoid confusion, methods with take a form of a key as
an object shall be prepended with I<_id(s)> if they only
take an id; otherwise assume an object of type GnuPG::Key
is required.

=over 4

=item meta_pgp_5_compatible

If true, arguments are generated to try to be compatible with PGP 5.x.

=item meta_pgp_2_compatible

If true, arguments are generated to try to be compatible with PGP 2.x.

=item meta_interactive

If false, arguments are generated to try to help the using program
use GnuPG in a non-interactive environment, such as CGI scripts.
Default is true.

=item meta_signing_key_id

This scalar reflects the key used to sign messages.
Currently this is synonymous with I<default-key>.

=item meta_signing_key

This GnuPG::Key object reflects the key used to sign messages.

=item meta_recipients_key_ids

This list of scalar key ids are used to generate the
appropriate arguments having these keys as recipients.

=item meta_recipients_keys

This list of keys of the type GnuPG::Key are used to generate the
appropriate arguments having these keys as recipients.
You probably want to have this list be of the inherited class
GnuPG::SubKey, as in most instances, OpenPGP keypairs have
the encyrption key as the subkey of the primary key, which is
used for signing.

=back

=head2 Other Data Members

=over 4

=item extra_args

This is a list of any other arguments used to pass to GnuPG.
Useful to pass an argument not yet covered in this package.

=back

=head1 SEE ALSO

L<GnuPG::Interface>,

=cut