This file is indexed.

/usr/share/qpsmtpd/plugins/tls_cert is in qpsmtpd 0.94-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
#!/usr/bin/perl

use strict;
use warnings;

# Very basic script to create TLS certificates for qpsmtpd
use File::Temp qw/ tempfile tempdir /;
use Getopt::Long;

my %opts = ();
chomp (my $hostname = `hostname --fqdn`);
if ($?) {
    chomp($hostname = `hostname`);
}
print "Using hostname: $hostname\n";
my %defaults = (
    C  => 'XY',
    ST => 'unknown',
    L  => 'unknown',
    O  => 'QSMTPD',
    OU => 'Server',
    CN => $hostname,
);

GetOptions(\%opts, 
    'C|Country:s',
    'ST|State:s',
    'L|Locality|City:s',
    'O|Organization:s',
    'OU|OrganizationalUnit|U:s',
    'CN|CommonName|N:s',
    'emailAddress|email|E:s',
    'help|H',
);

usage() if $opts{help};

# initialize defaults
foreach my $key ( keys %defaults ) {
    $opts{$key} = $defaults{$key} unless $opts{$key}
}
$opts{emailAddress} = 'postmaster@'.$opts{CN};

mkdir('ssl') unless -d 'ssl';

my $CA_key = 'ssl/qpsmtpd-ca.key';
my $CA_crt = 'ssl/qpsmtpd-ca.crt';
my $CA_serial = 'ssl/.cert.serial';

my $template;
my ($CA, $CAfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);

print ${CA} return_cfg('CA');
close ${CA};

system('openssl', 'genrsa', '-out', $CA_key, 2048) == 0 
    or die "Cannot create CA key: $?";

system('openssl', 'req', '-config', $CAfilename, '-new', '-x509',
	'-days', (365*6), '-key', $CA_key,
	'-out', $CA_crt) == 0
    or die "Cannot create CA cert: $?";

my $SERVER_key = 'ssl/qpsmtpd-server.key';
my $SERVER_csr = 'ssl/qpsmtpd-server.csr';
my $SERVER_crt = 'ssl/qpsmtpd-server.crt';

my ($SERVER, $SERVERfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);
print ${SERVER} return_cfg($opts{OU});
close ${SERVER};

system('openssl', 'genrsa', '-out', $SERVER_key, 1024) == 0 
    or die "Cannot create server key: $?";

system('openssl', 'req', '-config', $SERVERfilename, '-new', 
	'-key', $SERVER_key, '-out', $SERVER_csr) == 0
    or die "Cannot create server cert: $?";

my ($SIGN, $SIGNfilename) = tempfile( $template, DIR => "ssl", UNLINK => 1);
print ${SIGN} <<"EOT";
extensions = x509v3
[ x509v3 ]
subjectAltName   = email:copy
nsComment        = tls certificate
nsCertType       = server
EOT
close ${SIGN};

open my $SERIAL, '>', $CA_serial;
print ${SERIAL} "01\n";
close ${SERIAL};

system('openssl', 'x509', '-extfile', $SIGNfilename, '-days', (365*2),
	'-CAserial', $CA_serial, '-CA', $CA_crt,
	'-CAkey', $CA_key, '-in', $SERVER_csr,
	'-req', '-out', $SERVER_crt) == 0
    or die "Cannot sign cert: $?";

exit(0);
	
sub return_cfg {
    my $OU = shift;
    my $RANDOM = int(rand(1000)).'RAN'.int(rand(1000)).'DOM';
    my $cfg = <<"EOT";
[ req ]
default_bits           = 1024
default_keyfile        = keyfile.pem
distinguished_name     = req_distinguished_name
attributes             = req_attributes
prompt                 = no
output_password        = mypass

[ req_distinguished_name ]
C                      = $opts{C}
ST                     = $opts{ST}
L                      = $opts{L}
O                      = $opts{O}
OU                     = $OU
CN                     = $opts{CN}
emailAddress           = $opts{emailAddress}

[ req_attributes ]
challengePassword      = $RANDOM challenge password
EOT
    return $cfg;
}

sub usage {
    print STDERR <<"EOT";

 $0 will generate a TLS certificate "the quick way",
 i.e. without interaction.  You can change some defaults however.
    
 These options are recognized:             Default:

  --C       Country (two letters, e.g. DE) $defaults{C}
  --ST      State (spelled out)            $defaults{ST}
  --L       City                           $defaults{L}
  --O       Organization                   $defaults{O}
  --OU      Organizational Unit            $defaults{OU}
  --CN      Common name                    $defaults{CN}
  --email   Email address of postmaster    postmaster\@CN
  --help    Show usage

EOT
    exit(1);
}