Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client-side ALPN support #5107

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
05777e1
tls: move server-side ALPN negotiation into tls_start_servertls
elliefm Nov 1, 2024
afb11b4
tls: add client-side ALPN negotiation to tls_start_clienttls
elliefm Oct 30, 2024
616c4bc
protocol: add alpn_map field
elliefm Oct 29, 2024
4a85a87
backend: plumb through protocol alpn_map
elliefm Oct 29, 2024
5746c29
various: add client-side ALPN maps for IANA registered protocols
elliefm Oct 30, 2024
45a5b08
backend.testc: neater HAVE_SSL conditionalisation
elliefm Oct 30, 2024
027bf0e
tls: make struct tls_alpn_t shallow-copyable
elliefm Oct 30, 2024
ccbf838
backend.testc: add client-side ALPN tests
elliefm Nov 1, 2024
0703542
tls: add tls_get_alpn_protocol()
elliefm Nov 6, 2024
4148f4e
backend.test: check that alpn tests got the expected protocol
elliefm Nov 6, 2024
ed29b2f
WIP httpd: decouple h2_is_available from http2_start_session
elliefm Nov 6, 2024
8868103
WIP tls: use server's preference for alpn selection, not client's
elliefm Nov 8, 2024
2ab8d5a
cyr_buildinfo: add dependency.openssl_alpn
elliefm Nov 11, 2024
5cc4a06
ALPN: add tests for imap using starttls
elliefm Nov 11, 2024
924db75
IMAPMessageStore: overrideable default ALPN map for SSL
elliefm Nov 13, 2024
2ca00c2
ALPN: add tests for imaps (no starttls)
elliefm Nov 13, 2024
6aeab78
ALPN: check to see if we got the expected protocol
elliefm Nov 13, 2024
1bfce64
ServiceFactory: recognise 'https' service
elliefm Nov 12, 2024
40ba069
WIP TestCase: support https for http service objects
elliefm Nov 12, 2024
8b73732
WIP ALPN: add tests for https
elliefm Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
425 changes: 425 additions & 0 deletions cassandane/Cassandane/Cyrus/ALPN.pm

Large diffs are not rendered by default.

35 changes: 14 additions & 21 deletions cassandane/Cassandane/Cyrus/TestCase.pm
Original file line number Diff line number Diff line change
Expand Up @@ -795,49 +795,42 @@ sub _setup_http_service_objects
{
my ($self) = @_;

# nothing to do if no http service
require Mail::JMAPTalk;
require Net::CalDAVTalk;
require Net::CardDAVTalk;

# nothing to do if no http or https service
my $service = $self->{instance}->get_service("http");
$service ||= $self->{instance}->get_service("https");
return if !$service;

my %common_args = (
user => 'cassandane',
password => 'pass',
host => $service->host(),
port => $service->port(),
scheme => ($service->is_ssl() ? 'https' : 'http'),
);

if ($self->{instance}->{config}->get_bit('httpmodules', 'carddav')) {
require Net::CardDAVTalk;
$self->{carddav} = Net::CardDAVTalk->new(
user => 'cassandane',
password => 'pass',
host => $service->host(),
port => $service->port(),
scheme => 'http',
%common_args,
url => '/',
expandurl => 1,
);
}
if ($self->{instance}->{config}->get_bit('httpmodules', 'caldav')) {
require Net::CalDAVTalk;
$self->{caldav} = Net::CalDAVTalk->new(
user => 'cassandane',
password => 'pass',
host => $service->host(),
port => $service->port(),
scheme => 'http',
%common_args,
url => '/',
expandurl => 1,
);
$self->{caldav}->UpdateAddressSet("Test User",
"cassandane\@example.com");
"cassandane\@example.com");
}
if ($self->{instance}->{config}->get_bit('httpmodules', 'jmap')) {
require Mail::JMAPTalk;
$ENV{DEBUGJMAP} = 1;
$self->{jmap} = Mail::JMAPTalk->new(
user => 'cassandane',
password => 'pass',
host => $service->host(),
port => $service->port(),
scheme => 'http',
%common_args,
url => '/jmap/',
);
}
Expand Down
5 changes: 5 additions & 0 deletions cassandane/Cassandane/IMAPMessageStore.pm
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ sub connect

if ($self->{ssl}) {
my $ca_file = abs_path("data/certs/cacert.pem");
my $alpn_map = exists $params{OverrideALPN}
? delete $params{OverrideALPN}
: [ 'imap' ];

# XXX https://github.com/noxxi/p5-io-socket-ssl/issues/121
# XXX With newer IO::Socket::SSL, hostname verification fails
# XXX because our hostname is an IP address and the certificate
Expand All @@ -111,6 +115,7 @@ sub connect
UseSSL => $self->{ssl},
SSL_ca_file => $ca_file,
SSL_verifycn_scheme => 'none',
SSL_alpn_protocols => $alpn_map,
UseBlocking => 1, # must be blocking for SSL
Pedantic => 1,
PreserveINBOX => 1,
Expand Down
9 changes: 9 additions & 0 deletions cassandane/Cassandane/Service.pm
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ sub set_port
return $self->{_listener}->set_port($port);
}

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

# assume '-s' service argument indicates SSL and its absense
# indicates plaintext
return scalar grep { $_ eq '-s' } @{$self->{argv}};
}

# Return a hash of parameters suitable for passing
# to MessageStoreFactory::create.
sub store_params
Expand Down
22 changes: 8 additions & 14 deletions cassandane/Cassandane/ServiceFactory.pm
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,23 @@ sub create
}

# try and guess some service-specific defaults
if ($name =~ m/imaps/)
if ($name =~ m/imap(s?)/)
{
return Cassandane::IMAPService->new(
argv => ['imapd', '-s'],
%params);
}
elsif ($name =~ m/imap/)
{
return Cassandane::IMAPService->new(
argv => ['imapd'],
%params);
my @argv = 'imapd';
push @argv, '-s' if $1;
return Cassandane::IMAPService->new(argv => \@argv, %params);
}
elsif ($name =~ m/sync/)
{
return Cassandane::Service->new(
argv => ['imapd'],
%params);
}
elsif ($name =~ m/http/)
elsif ($name =~ m/http(s?)/)
{
return Cassandane::Service->new(
argv => ['httpd'],
%params);
my @argv = 'httpd';
push @argv, '-s' if $1;
return Cassandane::Service->new(argv => \@argv, %params);
}
elsif ($name =~ m/lmtp/)
{
Expand Down
Loading