implement the use of new ftp -S session=... for https
authorespie <espie@openbsd.org>
Sat, 10 Feb 2018 10:35:09 +0000 (10:35 +0000)
committerespie <espie@openbsd.org>
Sat, 10 Feb 2018 10:35:09 +0000 (10:35 +0000)
- add a setup_session hook that creates an anonymous tempfile in the ::HTTPS
class
- parse tls connection resumed messages and tell on servers that do not
support this
- remove the CLOEXE flag on the fd just before running ftp, so that other
processes do not see it at all.

This makes https somewhat more bearable, though still slower than http... :(

thanks to jsing@ et al  for the design of session

usr.sbin/pkg_add/OpenBSD/PackageRepository.pm

index c752be0..9fd7528 100644 (file)
@@ -1,5 +1,5 @@
 # ex:ts=8 sw=4:
-# $OpenBSD: PackageRepository.pm,v 1.155 2018/02/07 11:38:38 espie Exp $
+# $OpenBSD: PackageRepository.pm,v 1.156 2018/02/10 10:35:09 espie Exp $
 #
 # Copyright (c) 2003-2010 Marc Espie <espie@openbsd.org>
 #
@@ -292,6 +292,7 @@ sub parse_problems
        my $broken = 0;
        my $signify_error = 0;
        $self->{last_error} = 0;
+       $self->{count}++;
        while(<$fh>) {
                if (m/^Redirected to (https?)\:\/\/([^\/]*)/) {
                        my ($scheme, $newhost) = ($1, $2);
@@ -300,6 +301,7 @@ sub parse_problems
                        $self->{state}->syslog("Redirected from #1 to #2",
                            $self->{host}, $newhost);
                        $self->{host} = $newhost;
+                       $self->setup_session;
                        $baseurl = $self->url;
                        next;
                }
@@ -319,6 +321,18 @@ sub parse_problems
                        $broken = 1;
                        next;
                }
+               if (m/^tls session resumed\: (\w+)/) {
+                       my $s = $1;
+                       if ($s eq 'yes') {
+                               # everything okay for now
+                               $self->{said_slow} = 0;
+                               next;
+                       }
+                       next if $self->{count} < 2 || $self->{said_slow};
+                       $self->{said_slow} = 1;
+                       $self->{state}->say("#1: no session resumption on connection ##2, https will be slow", $self->{host}, $self->{count});
+                       next;
+               }
                # http error
                if (m/^ftp: Error retrieving file: 404/o) {
                        if (!defined $object) {
@@ -587,6 +601,11 @@ sub baseurl
        return "//$self->{host}$self->{path}";
 }
 
+sub setup_session
+{
+       # nothing to do except for https
+}
+
 sub parse_url
 {
        my ($class, $r, $state) = @_;
@@ -601,6 +620,7 @@ sub parse_url
                        $o->can_be_empty;
                        $$r = $class->urlscheme."://$o->{host}$o->{release}:$$r";
                }
+               $o->setup_session;
                return $o;
        } else {
                return undef;
@@ -983,19 +1003,40 @@ sub urlscheme
        return 'https';
 }
 
-OpenBSD::Auto::cache(session_file,
-    sub {
+sub setup_session
+{
        my $self = shift;
-       require OpenBSD::Temp;
 
+       require OpenBSD::Temp;
+       $self->{count} = 0;
        local ($>, $));
        my ($uid, $gid, $user) = $self->fetch_id;
        if (defined $uid) {
                $> = $uid;
                $) = "$gid $gid";
        }
-       return OpenBSD::Temp->file;
-    });
+       my ($fh, undef) = OpenBSD::Temp::fh_file("session",
+               sub { unlink(shift); });
+       if (!defined $fh) {
+               $self->{state}->fatal("Can't write session into tmp directory");
+       }
+       $self->{fh} = $fh; # XXX store the full fh and not the fileno
+}
+
+sub ftp_cmd
+{
+       my $self = shift;
+       return $self->SUPER::ftp_cmd." -S session=/dev/fd/".fileno($self->{fh});
+}
+
+sub drop_privileges_and_setup_env
+{
+       my $self = shift;
+       $self->SUPER::drop_privileges_and_setup_env;
+       # reset the CLOEXEC flag on that one
+       use Fcntl;
+       fcntl($self->{fh}, F_SETFD, 0);
+}
 
 package OpenBSD::PackageRepository::FTP;
 our @ISA=qw(OpenBSD::PackageRepository::HTTPorFTP);