From c810aa389a5c13aa1f9539d9e2d4404aeaa7e039 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 17 Jun 2016 20:28:37 +0200 Subject: More Progress Add config libsrs_alt fallback More tests --- Spline/Srs.pm | 105 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 18 deletions(-) (limited to 'Spline') diff --git a/Spline/Srs.pm b/Spline/Srs.pm index d7fc795..8acb188 100644 --- a/Spline/Srs.pm +++ b/Spline/Srs.pm @@ -9,34 +9,47 @@ use Spline::Netstring; use base 'Exporter'; our @EXPORT = qw( ); our @EXPORT_OK = qw( + config_set + config_get check_exclude srs_forward srs_reverse ); -our $alias = 'spline.inf.fu-berlin.de'; -our @excludes = ( - 'spline.inf.fu-berlin.de', - '.spline.inf.fu-berlin.de', - 'spline.de', - '.spline.de', -); +my $config = { + alias => '', + excludes => [], + secret => '', + max_age => 49, + hash_length => 5, + hash_min => 5, + ignore_time => 0, + srsalt_fallback => 0, +}; + +my $srs = undef; + +sub config_set($$) { + my ($key, $value) = @_; + return unless defined $config->{$key}; + + $config->{$key} = $value; + $srs = undef; +} -my $srs = new Mail::SRS( - Secret => "", - MaxAge => 49, - HashLength => 5, - HashMin => 4, -); +sub config_get($) { + my $key = shift; + return $config->{$key}; +} sub check_exclude($@) { - my $addr = shift; - my @excludes = @_; + my ($addr, $excludes) = @_; + return 0 unless ref($excludes) eq 'ARRAY'; my @parts = split(/@/, $addr); my $domain = $parts[-1]; - for my $exclude (@excludes) { + for my $exclude (@$excludes) { if ($exclude =~ m/^\./) { return 1 if $domain =~ m/\Q$exclude\E$/; } @@ -48,18 +61,74 @@ sub check_exclude($@) { return 0; } +sub replace_srsalt_chars($) { + my $addr = shift; + if ($addr =~ m/^(SRS[01][=+-])([^=]+)(=.*)$/) { + my ($srs, $hash, $rest) = ($1, $2, $3); + $hash =~ s#_#+#g; + $hash =~ s#\.#/#g; + return "$srs$hash$rest"; + } + + return $addr; +} + sub srs_forward($) { my $addr = shift; - return if check_exclude($addr, @excludes); - return $srs->forward($addr, $alias); + return $addr if check_exclude($addr, $config->{excludes}); + + check_configured(); + return $srs->forward($addr, $config->{alias}); } sub srs_reverse($) { my $addr = shift; + + check_configured(); + + if ($config->{srsalt_fallback}) { + my $result; + eval { + $result = $srs->reverse($addr); + }; + + my $err = $@; + if ($err) { + if ($err =~ m/Invalid hash/) { + my $fallback = replace_srsalt_chars($addr); + return $srs->reverse($fallback); + } + + die $err; + } + + return $result; + } + return $srs->reverse($addr); } +sub check_configured() { + return if defined $srs; + + if (length($config->{secret}) < 20) { + die 'You need to configure a suitable secret'; + } + + if (!$config->{alias}) { + die 'You need to configure an alias domain'; + } + + $srs = new Mail::SRS( + Secret => $config->{secret}, + MaxAge => $config->{max_age}, + HashLength => $config->{hash_length}, + HashMin => $config->{hash_min}, + IgnoreTimestamp => $config->{ignore_time}, + ); +} + sub handle($$) { my ($map, $key) = @_; my $result; -- cgit v1.2.3-1-g7c22