View | Details | Raw Unified | Return to bug 8897
Collapse All | Expand All

(-)a/C4/GnuPG.pm (+119 lines)
Line 0 Link Here
1
package C4::GnuPG;
2
3
# Copyright 2012 Mirko Tietgen
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
use C4::Context;
23
use Crypt::GPG;
24
25
=head1 C4::GnuPG
26
27
C4::GnuPG
28
29
=head1 Description
30
31
Provides methods to interact with GnuPG via Crypt::GPG for the purpose of encrypting emails to patrons
32
33
=cut
34
35
my $gpg = new Crypt::GPG;
36
$gpg->gpgbin('/usr/bin/gpg');
37
$gpg->encryptsafe(0); # we have to allow untrusted keys
38
39
=head2 encrypt
40
41
Take email content and patron's email address, send back encrypted content. Call like
42
43
$content = C4::GnuPG->encrypt($content, $patronemail);
44
45
=cut
46
47
sub encrypt {
48
    my ($self, $content, $patronemail) = @_;
49
    $content = $gpg->encrypt($content, $patronemail);
50
    return $content;
51
}
52
53
=head2 does_exist
54
55
Check if there is a GnuPG key for the patron's email address. Call like
56
57
if ( C4::GnuPG->does_exist($patronemail) = 1 ) {
58
    # … encrypt …
59
}
60
61
=cut
62
63
sub does_exist {
64
    # TODO: check if gpg binary is found before encrypting to avoid errors
65
    my ($self, $patronemail) = @_;
66
    if ( $gpg->keydb($patronemail) ) {
67
        return 1;
68
    }
69
    else {
70
        return 0;
71
    }
72
}
73
74
=head2 add_key
75
76
Add or replace a patron's key. If there is already a key present, delete. Then add the new key.
77
78
=cut
79
80
sub add_key {
81
    my ($self, $key, $patronemail) = @_;
82
    # check if it is a public key before doing anything
83
    if ( $key =~ /BEGIN PGP PUBLIC KEY BLOCK/ ) {
84
        # if we already got a key, delete
85
        if ( does_exist($patronemail) ) {
86
            my @oldkey = $gpg->keydb($patronemail);
87
            if ( $oldkey[0] ) {
88
                $gpg->delkey($oldkey[0]);
89
            }
90
        }
91
        # … add new key
92
        $gpg->addkey($key);
93
    }
94
    else {
95
        return 0;
96
    }
97
}
98
99
sub del_key {
100
    my ($self, $patronemail) = @_;
101
    my @key = $gpg->keydb($patronemail);
102
    $gpg->delkey($key[0]);
103
}
104
105
=head2 get_key
106
107
=cut
108
109
sub get_key {
110
    # TODO: check security issue: can i get a secret key with this?
111
    my ($self, $patronemail) = @_;
112
    my @key = $gpg->keydb($patronemail);
113
    my $keystring = $gpg->export($key[0]);
114
    if ( $keystring =~ /BEGIN PGP PUBLIC KEY BLOCK/) {
115
        return $keystring;
116
    }
117
}
118
119
1;
(-)a/C4/Installer/PerlDependencies.pm (+5 lines)
Lines 689-694 our $PERL_DEPS = { Link Here
689
        'required' => '1',
689
        'required' => '1',
690
        'min_ver'  => '0.22',
690
        'min_ver'  => '0.22',
691
    },
691
    },
692
    'Crypt::GPG' => {
693
        'usage'    => 'Messaging (encryption)',
694
        'required'  => '1',
695
        'min_ver'  => '1.52',
696
    },
692
};
697
};
693
698
694
1;
699
1;
(-)a/C4/Letters.pm (-3 / +13 lines)
Lines 29-34 use C4::Branch; Link Here
29
use C4::Log;
29
use C4::Log;
30
use C4::SMS;
30
use C4::SMS;
31
use C4::Debug;
31
use C4::Debug;
32
use C4::GnuPG;
32
use Koha::DateUtils;
33
use Koha::DateUtils;
33
use Date::Calc qw( Add_Delta_Days );
34
use Date::Calc qw( Add_Delta_Days );
34
use Encode;
35
use Encode;
Lines 300-312 sub SendAlerts { Link Here
300
                },
301
                },
301
                want_librarian => 1,
302
                want_librarian => 1,
302
            ) or return;
303
            ) or return;
303
304
            my $subject = Encode::encode( "utf8", "" . $letter->{title} );
305
            my $content = Encode::encode( "utf8", "" . $letter->{content} );
306
            if ( C4::GnuPG->does_exist($email) ) {
307
                $subject = 'A message from your library';
308
                $content = C4::GnuPG->encrypt($content, $email);
309
            }
304
            # ... then send mail
310
            # ... then send mail
305
            my %mail = (
311
            my %mail = (
306
                To      => $email,
312
                To      => $email,
307
                From    => $email,
313
                From    => $email,
308
                Subject => Encode::encode( "utf8", "" . $letter->{title} ),
314
                Subject => $subject,
309
                Message => Encode::encode( "utf8", "" . $letter->{content} ),
315
                Message => $content,
310
                'Content-Type' => 'text/plain; charset="utf8"',
316
                'Content-Type' => 'text/plain; charset="utf8"',
311
                );
317
                );
312
            sendmail(%mail) or carp $Mail::Sendmail::error;
318
            sendmail(%mail) or carp $Mail::Sendmail::error;
Lines 944-949 sub _send_message_by_email { Link Here
944
    my $content = encode('utf8', $message->{'content'});
950
    my $content = encode('utf8', $message->{'content'});
945
    my $content_type = $message->{'content_type'} || 'text/plain; charset="UTF-8"';
951
    my $content_type = $message->{'content_type'} || 'text/plain; charset="UTF-8"';
946
    my $is_html = $content_type =~ m/html/io;
952
    my $is_html = $content_type =~ m/html/io;
953
    if ( C4::GnuPG->does_exist($to_address) ) {
954
        $subject = 'A message from your library';
955
        $content = C4::GnuPG->encrypt($content, $to_address);
956
    }
947
    my %sendmail_params = (
957
    my %sendmail_params = (
948
        To   => $to_address,
958
        To   => $to_address,
949
        From => $message->{'from_address'} || C4::Context->preference('KohaAdminEmailAddress'),
959
        From => $message->{'from_address'} || C4::Context->preference('KohaAdminEmailAddress'),
(-)a/debian/control (+3 lines)
Lines 25-30 Build-Depends: libalgorithm-checkdigits-perl, Link Here
25
 libcgi-session-serialize-yaml-perl,
25
 libcgi-session-serialize-yaml-perl,
26
 libclass-accessor-perl,
26
 libclass-accessor-perl,
27
 libclass-factory-util-perl,
27
 libclass-factory-util-perl,
28
 libcrypt-gpg-perl,
28
 libdata-ical-perl,
29
 libdata-ical-perl,
29
 libdata-paginator-perl,
30
 libdata-paginator-perl,
30
 libdate-calc-perl,
31
 libdate-calc-perl,
Lines 174-179 Depends: ${misc:Depends}, Link Here
174
 at,
175
 at,
175
 daemon,
176
 daemon,
176
 debconf,
177
 debconf,
178
 gnupg,
177
 idzebra-2.0,
179
 idzebra-2.0,
178
 libjs-jquery,
180
 libjs-jquery,
179
 libjs-yui,
181
 libjs-yui,
Lines 211-216 Depends: libalgorithm-checkdigits-perl, Link Here
211
 libcgi-session-serialize-yaml-perl,
213
 libcgi-session-serialize-yaml-perl,
212
 libclass-accessor-perl,
214
 libclass-accessor-perl,
213
 libclass-factory-util-perl,
215
 libclass-factory-util-perl,
216
 libcrypt-gpg-perl,
214
 libdata-ical-perl,
217
 libdata-ical-perl,
215
 libdata-paginator-perl,
218
 libdata-paginator-perl,
216
 libdate-calc-perl,
219
 libdate-calc-perl,
(-)a/debian/control.in (+1 lines)
Lines 66-71 Depends: ${misc:Depends}, Link Here
66
 at,
66
 at,
67
 daemon,
67
 daemon,
68
 debconf,
68
 debconf,
69
 gnupg,
69
 idzebra-2.0,
70
 idzebra-2.0,
70
 libjs-jquery,
71
 libjs-jquery,
71
 libjs-yui,
72
 libjs-yui,
(-)a/install_misc/debian.packages (+2 lines)
Lines 2-7 apache2 install Link Here
2
at install
2
at install
3
cvs	install
3
cvs	install
4
daemon install
4
daemon install
5
gnupg install
5
gcc install
6
gcc install
6
gettext install
7
gettext install
7
idzebra-2.0	install
8
idzebra-2.0	install
Lines 23-28 libcgi-session-perl install Link Here
23
libcgi-session-serialize-yaml-perl install
24
libcgi-session-serialize-yaml-perl install
24
libclass-accessor-perl		install
25
libclass-accessor-perl		install
25
libclass-factory-util-perl	install
26
libclass-factory-util-perl	install
27
libcypt-gpg-perl	install
26
libdata-ical-perl	install
28
libdata-ical-perl	install
27
libdata-paginator-perl		install
29
libdata-paginator-perl		install
28
libdate-calc-perl install
30
libdate-calc-perl install
(-)a/install_misc/ubuntu.10.04.packages (+2 lines)
Lines 35-40 libidzebra-2.0-modules install Link Here
35
35
36
# crypto packages
36
# crypto packages
37
37
38
gnupg					install
38
libgcrypt11				install
39
libgcrypt11				install
39
libgcrypt11-dev				install
40
libgcrypt11-dev				install
40
41
Lines 62-67 libcgi-session-perl install Link Here
62
libcgi-session-serialize-yaml-perl	install
63
libcgi-session-serialize-yaml-perl	install
63
libclass-accessor-perl		install
64
libclass-accessor-perl		install
64
libclass-factory-util-perl		install
65
libclass-factory-util-perl		install
66
libcrypt-gpg-perl			install
65
libdata-ical-perl			install
67
libdata-ical-perl			install
66
libdata-paginator-perl		install
68
libdata-paginator-perl		install
67
libdate-calc-perl			install
69
libdate-calc-perl			install
(-)a/install_misc/ubuntu.12.04.packages (+2 lines)
Lines 34-39 libidzebra-2.0-modules install Link Here
34
34
35
# crypto packages
35
# crypto packages
36
36
37
gnupg					install
37
libgcrypt11				install
38
libgcrypt11				install
38
libgcrypt11-dev				install
39
libgcrypt11-dev				install
39
40
Lines 64-69 libchi-driver-memcached-perl install Link Here
64
libchi-perl				install
65
libchi-perl				install
65
libclass-accessor-perl			install
66
libclass-accessor-perl			install
66
libclass-factory-util-perl		install
67
libclass-factory-util-perl		install
68
libcrypt-gpg-perl			install
67
libdata-ical-perl			install
69
libdata-ical-perl			install
68
libdata-paginator-perl		install
70
libdata-paginator-perl		install
69
libdate-calc-perl			install
71
libdate-calc-perl			install
(-)a/install_misc/ubuntu.packages (+2 lines)
Lines 34-39 libidzebra-2.0-modules install Link Here
34
34
35
# crypto packages
35
# crypto packages
36
36
37
gnupg					install
37
libgcrypt11				install
38
libgcrypt11				install
38
libgcrypt11-dev				install
39
libgcrypt11-dev				install
39
40
Lines 64-69 libchi-driver-memcached-perl install Link Here
64
libchi-perl				install
65
libchi-perl				install
65
libclass-accessor-perl			install
66
libclass-accessor-perl			install
66
libclass-factory-util-perl		install
67
libclass-factory-util-perl		install
68
libcrypt-gpg-perl			install
67
libdata-ical-perl			install
69
libdata-ical-perl			install
68
libdata-paginator-perl		install
70
libdata-paginator-perl		install
69
libdate-calc-perl			install
71
libdate-calc-perl			install
(-)a/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc (+1 lines)
Lines 12-17 Link Here
12
  [% IF ( OpacPasswordChange ) %]
12
  [% IF ( OpacPasswordChange ) %]
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
14
  [% END %]
14
  [% END %]
15
  [% IF ( gnupgview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-gnupg.pl">email encryption</a></li>
15
  [% IF ( ShowOpacRecentSearchLink ) %]
16
  [% IF ( ShowOpacRecentSearchLink ) %]
16
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
17
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
17
  [% END %]
18
  [% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-gnupg.tt (+59 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Add or change your GPG key
2
[% INCLUDE 'doc-head-close.inc' %]
3
</head>
4
<body id="opac-passwd">
5
<div id="doc3" class="yui-t1">
6
   <div id="bd">
7
[% INCLUDE 'masthead.inc' %]
8
9
	<div id="yui-main">
10
	<div class="yui-b"><div class="yui-g">
11
	<div id="usergnupg" class="container">
12
    <h3><a href="/cgi-bin/koha/opac-gnupg.pl">[% firstname %] [% surname %]'s account</a> &#8674; Add or change your GPG key </h3>
13
    <p>If you paste your GPG <strong>public</strong> key here, we will try to encrypt the emails we send you.<br />
14
    If you want to learn about email encryption, you will find some information at link</p>
15
16
    [% IF ( Error_messages ) %]
17
        <div class="dialog error">        <h3>There was a problem with your submission</h3>
18
            <p>
19
                [% IF ( NoGnuPG ) %]
20
                    Could not find the path to GnuPG. This has to be set by the library for encryption to work. Please ask our staff about it.
21
                [% END %]
22
            </p></div>
23
    [% END %]
24
25
    <p>Path to GPG [% IF (gpgbinary) %]found[% ELSE %]not found[% END %].</p>
26
27
    <form action="/cgi-bin/koha/opac-gnupg.pl" name="mainform" id="mainform" method="post">
28
    <fieldset class="brief">
29
        <p><label for="PublicKey">
30
            [% IF ( does_exist ) %]
31
                We have the following public key for your email address:
32
            [% ELSE %]
33
                Paste your public key here:
34
            [% END %]
35
        </p>
36
        <ol><li><textarea id="PublicKey" name="PublicKey" cols="70" rows="30">[% IF (keythingy) %][% keythingy %][% END %]</textarea></li></ol>
37
    </fieldset>
38
    <fieldset class="action"><input type="submit" value="Save" class="submit" /> <a href="/cgi-bin/koha/opac-user.pl" class="cancel">Cancel</a></fieldset>
39
    </form>
40
41
    [% IF ( does_exist ) %]
42
    <p>Delete the key from our server if you wish to receive unencrypted emails in the future.</p>
43
    <form action="/cgi-bin/koha/opac-gnupg.pl" name="deleteform" id="deleteform" method="post">
44
        <input type="hidden" name="DeleteKey" value="1" />
45
        <fieldset class="action"><input type="submit" value="Delete my public key" class="submit" /></fieldset>
46
    </form>
47
    [% END %]
48
    
49
</div>
50
</div>
51
</div>
52
</div>
53
<div class="yui-b">
54
<div id="leftmenus" class="container">
55
[% INCLUDE 'navigation.inc' IsPatronPage=1 %]
56
</div>
57
</div>
58
</div>
59
[% INCLUDE 'opac-bottom.inc' %]
(-)a/opac/opac-gnupg.pl (+81 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2013 Mirko Tietgen
4
#
5
# This file is part of Koha
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
23
use CGI;
24
25
use C4::Auth;    # checkauth, getborrowernumber.
26
use C4::Context;
27
use Digest::MD5 qw(md5_base64);
28
use C4::Circulation;
29
use C4::Members;
30
use C4::Output;
31
use C4::GnuPG;
32
33
my $query = new CGI;
34
my $dbh   = C4::Context->dbh;
35
36
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
37
    {
38
        template_name   => "opac-gnupg.tt",
39
        query           => $query,
40
        type            => "opac",
41
        authnotrequired => 0,
42
        flagsrequired   => { borrow => 1 },
43
        debug           => 1,
44
    }
45
);
46
47
# get borrower information ....
48
my ( $borr ) = GetMemberDetails( $borrowernumber );
49
my $patronemail = $borr->{'email'};
50
# save key if key received
51
if ( $query->param('PublicKey') ) {
52
    C4::GnuPG->add_key($query->param('PublicKey'), $patronemail); 
53
#    $template->param( 'addedkey' => $query->param('PublicKey') );
54
#    $template->param( 'added' => '1' );
55
}
56
elsif ( $query->param('DeleteKey') ) {
57
    C4::GnuPG->del_key($patronemail);
58
}
59
    if ( C4::GnuPG->does_exist($patronemail) ) {
60
        # TODO: display public key if present
61
        my $keythingy = C4::GnuPG->get_key($patronemail);
62
        $template->param( 'does_exist' => '1' );
63
        $template->param( 'keythingy' => $keythingy );
64
    }
65
    # ask for key
66
    #$template->param( 'Ask_data'       => '1' );
67
    #$template->param( 'Error_messages' => '1' );
68
69
 my $gnupgbinary = '/usr/bin/gpg';
70
 if (-e $gnupgbinary) {
71
     $template->param( 'gpgbinary' => '1' );
72
 } 
73
74
$template->param(
75
    firstname => $borr->{'firstname'},
76
    surname => $borr->{'surname'},
77
    patronemail => $patronemail,
78
    gnupgview => 1,
79
);
80
81
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/opac/opac-sendbasket.pl (-4 / +19 lines)
Lines 33-38 use C4::Auth; Link Here
33
use C4::Output;
33
use C4::Output;
34
use C4::Biblio;
34
use C4::Biblio;
35
use C4::Members;
35
use C4::Members;
36
use C4::GnuPG;
36
37
37
my $query = new CGI;
38
my $query = new CGI;
38
39
Lines 149-154 if ( $email_add ) { Link Here
149
    my $boundary = "====" . time() . "====";
150
    my $boundary = "====" . time() . "====";
150
151
151
    $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
152
    $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
153
154
    my $email_header_and_body = $email_header . $body;
155
156
    my $attachmentfilename;
157
    # encrypt the attachment if we have a key
158
    if ( C4::GnuPG->does_exist($email_add) ) {
159
        $mail{'subject'} = "A message from your library";
160
        $email_header_and_body = C4::GnuPG->encrypt($email_header_and_body, $email_add);
161
        $iso2709 = C4::GnuPG->encrypt($iso2709, $email_add);
162
        $attachmentfilename = 'attachment.gpg';
163
    }
164
    else {
165
        $attachmentfilename = 'basket.iso2709';
166
    }
167
152
    my $isofile = encode_base64(encode("UTF-8", $iso2709));
168
    my $isofile = encode_base64(encode("UTF-8", $iso2709));
153
    $boundary = '--' . $boundary;
169
    $boundary = '--' . $boundary;
154
    $mail{body} = <<END_OF_BODY;
170
    $mail{body} = <<END_OF_BODY;
Lines 157-168 MIME-Version: 1.0 Link Here
157
Content-Type: text/plain; charset="UTF-8"
173
Content-Type: text/plain; charset="UTF-8"
158
Content-Transfer-Encoding: quoted-printable
174
Content-Transfer-Encoding: quoted-printable
159
175
160
$email_header
176
$email_header_and_body
161
$body
162
$boundary
177
$boundary
163
Content-Type: application/octet-stream; name="basket.iso2709"
178
Content-Type: application/octet-stream; name=$attachmentfilename
164
Content-Transfer-Encoding: base64
179
Content-Transfer-Encoding: base64
165
Content-Disposition: attachment; filename="basket.iso2709"
180
Content-Disposition: attachment; filename=$attachmentfilename
166
181
167
$isofile
182
$isofile
168
$boundary--
183
$boundary--
(-)a/opac/opac-sendshelf.pl (-6 / +21 lines)
Lines 33-38 use C4::Items; Link Here
33
use C4::Output;
33
use C4::Output;
34
use C4::VirtualShelves;
34
use C4::VirtualShelves;
35
use C4::Members;
35
use C4::Members;
36
use C4::GnuPG;
36
37
37
my $query = new CGI;
38
my $query = new CGI;
38
39
Lines 138-151 if ( $email ) { Link Here
138
        $email_file = $1;
139
        $email_file = $1;
139
    }
140
    }
140
141
141
    if ( $template_res =~ /<MESSAGE>\n(.*)\n<END_MESSAGE>/s ) { $body = encode_qp($1); }
142
    if ( $template_res =~ /<MESSAGE>\n(.*)\n<END_MESSAGE>/s ) {
143
        $body = encode_qp($1);
144
    }
142
145
143
    my $boundary = "====" . time() . "====";
146
    my $boundary = "====" . time() . "====";
144
147
145
    # We set and put the multipart content
148
    # We set and put the multipart content
146
    $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
149
    $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
147
150
151
    my $email_header_and_body = $email_header . $body;
152
153
    my $attachmentfilename;
154
    # encrypt the attachment if we have a key
155
    if ( C4::GnuPG->does_exist($email) ) {
156
        $mail{'subject'} = "A message from your library";
157
        $email_header_and_body = C4::GnuPG->encrypt($email_header_and_body, $email);
158
        $iso2709 = C4::GnuPG->encrypt($iso2709, $email);
159
        $attachmentfilename = 'attachment.gpg';
160
    }
161
    else {
162
        $attachmentfilename = 'shelf.iso2709';
163
    }
148
    my $isofile = encode_base64(encode("UTF-8", $iso2709));
164
    my $isofile = encode_base64(encode("UTF-8", $iso2709));
165
149
    $boundary = '--' . $boundary;
166
    $boundary = '--' . $boundary;
150
167
151
    $mail{body} = <<END_OF_BODY;
168
    $mail{body} = <<END_OF_BODY;
Lines 153-164 $boundary Link Here
153
Content-Type: text/plain; charset="utf-8"
170
Content-Type: text/plain; charset="utf-8"
154
Content-Transfer-Encoding: quoted-printable
171
Content-Transfer-Encoding: quoted-printable
155
172
156
$email_header
173
$email_header_and_body
157
$body
158
$boundary
174
$boundary
159
Content-Type: application/octet-stream; name="shelf.iso2709"
175
Content-Type: application/octet-stream; name=$attachmentfilename
160
Content-Transfer-Encoding: base64
176
Content-Transfer-Encoding: base64
161
Content-Disposition: attachment; filename="shelf.iso2709"
177
Content-Disposition: attachment; filename=$attachmentfilename
162
178
163
$isofile
179
$isofile
164
$boundary--
180
$boundary--
165
- 

Return to bug 8897