package Spline::Socketmap::Srs; use strict; use warnings; use base qw( Spline::Socketmap ); use Spline::Srs; sub lookup($$) { my $self = shift; my ($map, $key) = @_; my $result; eval { $result = $self->{srs}->handle($map, $key); }; my $err = $@; if ($err) { if ($err =~ m/(Invalid hash|Invalid timestamp)/) { $self->log(0, "Error: $err"); return "PERM $err"; } } if (defined $result) { if ($result eq $key) { $self->log(1, 'Not mapping "' . $key . '"'); return 'NOTFOUND '; } $self->log(1, 'Mapping "' . $key . '" to "' . $result . '"'); return "OK $result"; } return 'NOTFOUND '; } sub options($$) { my $self = shift; my $template = shift; my $prop = $self->{server}; $self->SUPER::options($template); # single value options for my $opt (qw(alias secret_file max_age hash_length hash_min ignore_time srsalt_fallback)) { $template->{$opt} = \$prop->{$opt}; } # array options for my $opt (qw(excludes secret)) { if (! defined $prop->{$opt}) { $prop->{$opt} = []; } elsif (! ref $prop->{$opt}) { $prop->{$opt} = [$prop->{$opt}]; } $template->{$opt} = $prop->{$opt}; } } sub post_configure_hook { my $self = shift; my $prop = $self->{'server'}; # boolean values for my $opt (qw(ignore_time srsalt_fallback)) { if (defined $prop->{$opt}) { $prop->{$opt} = 1; } else { $prop->{$opt} = 0; } } # secrets my @secrets = (); if (defined $prop->{secret_file}) { my $filename = $prop->{secret_file}; # Replace ~ and ~user: $filename =~ s{^~([^/]*)}{ $1 ? (getpwnam($1))[7] : (getpwuid($<))[7] }ex; if (open(my $file, '<', $filename)) { while (<$file>) { chomp; push @secrets, $_; } close($file); } else { $self->log(0, 'ERROR: Cannot open secret_file: "' . $filename . '"'); } } if (defined $prop->{secret} && scalar @{$prop->{secret}} ne 0) { if (scalar @secrets gt 0) { $self->log(1, 'WARNING: Using both "--secret" and "--secret-file" will '. 'use the first line from the file for generating hashes'); } for (@{$prop->{secret}}) { push @secrets, $_; } } # default values my %defaults = ( max_age => 49, hash_length => 5, hash_min => 5, ); for my $opt (keys %defaults) { if (!defined($prop->{$opt}) || $prop->{$opt} !~ m/^\d+$/ || $prop->{$opt} le 0) { if (defined $prop->{$opt}) { $self->log(2, "Invalid value for '$opt', using default value '$defaults{$opt}'"); } $prop->{$opt} = $defaults{$opt}; } } $self->{srs} = new Spline::Srs({ alias => $prop->{alias}, excludes => $prop->{excludes}, secret => \@secrets, max_age => $prop->{max_age}, hash_length => $prop->{hash_length}, hash_min => $prop->{hash_min}, ignore_time => $prop->{ignore_time}, srsalt_fallback => $prop->{srsalt_fallback}, }); } 1; # vim: set et ts=4: