if($usessl) {
my $defaultdomain = $self->{config}->{sslconfig}->{ssldefaultdomain};
my $encrypted;
my $ok = 0;
eval {
$encrypted = IO::Socket::SSL->start_SSL($client,
SSL_server => 1,
SSL_key_file=> $self->{config}->{sslconfig}->{ssldomains}->{$defaultdomain}->{sslkey},
SSL_cert_file=> $self->{config}->{sslconfig}->{ssldomains}->{$defaultdomain}->{sslcert},
SSL_cipher_list => $self->{config}->{sslconfig}->{sslciphers},
SSL_create_ctx_callback => sub {
my $ctx = shift;
#print STDERR "******************* CREATING NEW CONTEXT ********************\n";
# Enable workarounds for broken clients
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
# Disable session resumption completely
Net::SSLeay::CTX_set_session_cache_mode($ctx, $SSL_SESS_CACHE_OFF);
# Disable session tickets
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_NO_TICKET);
# Load certificate chain
my $defaultdomain = $self->{config}->{sslconfig}->{ssldefaultdomain};
Net::SSLeay::CTX_use_certificate_chain_file($ctx, $self->{config}->{sslconfig}->{ssldomains}->{$defaultdomain}->{sslcert});
# Check requested server name
Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub {
my $ssl = shift;
my $h = Net::SSLeay::get_servername($ssl);
if(!defined($h)) {
#print STDERR "SSL: No Hostname given during SSL setup\n";
return;
}
if(!defined($self->{config}->{sslconfig}->{ssldomains}->{$h})) {
#print STDERR "SSL: Hostname $h not configured\n";
#print STDERR Dumper($self->{config}->{sslconfig}->{ssldomains});
return;
}
if(defined($self->{config}->{sslconfig}->{ssldomains}->{$h}->{internal_socket})) {
# This SSL connection uses a different backend
$selectedbackend = $self->{config}->{sslconfig}->{ssldomains}->{$h}->{internal_socket};
}
if($h eq $self->{config}->{sslconfig}->{ssldefaultdomain}) {
# Already the correct CTX setting, just return
return;
}
#print STDERR "§§§§§§§§§§§§§§§§§§§§§§§ Requested Hostname: $h §§§\n";
my $newctx;
if(defined($self->{config}->{sslconfig}->{ssldomains}->{$h}->{ctx})) {
$newctx = $self->{config}->{sslconfig}->{ssldomains}->{$h}->{ctx};
} else {
$newctx = Net::SSLeay::CTX_new or croak("Can't create new SSL CTX");
Net::SSLeay::CTX_set_cipher_list($newctx, $self->{config}->{sslconfig}->{sslciphers});
Net::SSLeay::set_cert_and_key($newctx, $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert},
$self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslkey})
or croak("Can't set cert and key file");
Net::SSLeay::CTX_use_certificate_chain_file($newctx, $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert});
#print STDERR "Cert: ", $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert}, " Key: ", $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslkey}, "\n";
$self->{config}->{sslconfig}->{ssldomains}->{$h}->{ctx} = $newctx;
}
Net::SSLeay::set_SSL_CTX($ssl, $newctx);
});
# Prepared/tested for future ALPN needs (e.g. HTTP/2)
## Advertise supported HTTP versions
#Net::SSLeay::CTX_set_alpn_select_cb($ctx, ['http/1.1', 'http/2.0']);
},
);
$ok = 1;
};
if(!$ok) {
print "EVAL ERROR: ", $EVAL_ERROR, "\n";
$self->endprogram();
} elsif(!$ok || !defined($encrypted) || !$encrypted) {
print "startSSL failed: ", $SSL_ERROR, "\n";
$self->endprogram();
}
}
####
# Enable workarounds for broken clients
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
# Disable session resumption completely
Net::SSLeay::CTX_set_session_cache_mode($ctx, $SSL_SESS_CACHE_OFF);
# Disable session tickets
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_NO_TICKET);
##
##
Net::SSLeay::CTX_use_certificate_chain_file($ctx, $self->{config}->{sslconfig}->{ssldomains}->{$defaultdomain}->{sslcert});
##
##
Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub {
my $ssl = shift;
my $h = Net::SSLeay::get_servername($ssl);
if(!defined($h)) {
#print STDERR "SSL: No Hostname given during SSL setup\n";
return;
}
...
# ---- THIS SELECTS THE CORRECT BACKEND -----
if(defined($self->{config}->{sslconfig}->{ssldomains}->{$h}->{internal_socket})) {
# This SSL connection uses a different backend
$selectedbackend = $self->{config}->{sslconfig}->{ssldomains}->{$h}->{internal_socket};
}
if($h eq $self->{config}->{sslconfig}->{ssldefaultdomain}) {
# Already the correct CTX setting, just return
return;
}
...
# Switch over to the new certificate key and chain
$newctx = Net::SSLeay::CTX_new or croak("Can't create new SSL CTX");
Net::SSLeay::CTX_set_cipher_list($newctx, $self->{config}->{sslconfig}->{sslciphers});
Net::SSLeay::set_cert_and_key($newctx, $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert},
$self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslkey})
or croak("Can't set cert and key file");
Net::SSLeay::CTX_use_certificate_chain_file($newctx, $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert});
#print STDERR "Cert: ", $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslcert}, " Key: ", $self->{config}->{sslconfig}->{ssldomains}->{$h}->{sslkey}, "\n";
$self->{config}->{sslconfig}->{ssldomains}->{$h}->{ctx} = $newctx;
}
Net::SSLeay::set_SSL_CTX($ssl, $newctx);
});
...
},