File Coverage

blib/lib/SRS/EPP/Command/Login.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1              
2              
3             package SRS::EPP::Command::Login;
4              
5 1     1   1554 use Moose;
  0            
  0            
6             extends 'SRS::EPP::Command';
7             use MooseX::Method::Signatures;
8             use Crypt::Password;
9             use Data::Dumper;
10              
11             with 'MooseX::Log::Log4perl::Easy';
12              
13             sub action {
14             "login";
15             }
16              
17             sub authenticated { 0 }
18              
19             has "uid" =>
20             is => "rw",
21             isa => "XML::SRS::RegistrarId",
22             ;
23              
24             has "server_id" =>
25             is => "rw",
26             isa => "Str",
27             lazy => 1,
28             default => sub {
29             my $self = shift;
30             $self->session->new_server_id;
31             },
32             ;
33              
34             has "session" =>
35             is => "rw",
36             isa => "SRS::EPP::Session",
37             weak_ref => 1,
38             ;
39              
40             has "password" =>
41             is => "rw",
42             isa => "Str",
43             ;
44              
45             has "login_ok" =>
46             is => "rw",
47             isa => "Bool",
48             ;
49              
50             has "new_password" =>
51             is => "rw",
52             isa => "Str",
53             ;
54              
55             method process( SRS::EPP::Session $session ) {
56             $self->session($session);
57             my $epp = $self->message;
58             my $login = $epp->message->argument;
59             my $uid = $login->client_id;
60             $self->password($login->password);
61             $self->new_password($login->new_password)
62             if $login->new_password;
63             $self->uid($uid);
64             $self->session->want_user($uid);
65             $session->stalled(1);
66              
67             return (XML::SRS::Registrar::Query->new(
68             registrar_id => $uid,
69             ),
70             XML::SRS::ACL::Query->new(
71             Resource => "epp_connect",
72             List => "allow",
73             Type => "registrar_ip",
74             filter_types => ["AddressFilter", "RegistrarIdFilter"],
75             filter => [$session->peerhost, $uid],
76             ),
77             ($session->proxy->rfc_compliant_ssl ?
78             (
79             XML::SRS::ACL::Query->new(
80             Resource => "epp_client_certs",
81             List => "allow",
82             Type => "registrar_domain",
83             filter_types => ["DomainNameFilter", "RegistrarIdFilter"],
84             filter => [$session->peer_cn, $uid],
85             )) : () ),
86             );
87             }
88              
89              
90             method notify( SRS::EPP::SRSResponse @rs ) {
91             if ( @rs > 1 ) {
92             # response to login
93             my $registrar = $rs[0];
94             my $ip_ok_acl = $rs[1];
95             my $cn_ok_acl = $rs[2];
96              
97             # fail by default
98             $self->login_ok(0);
99              
100             # check the password
101             my $password_ok;
102             if ( my $auth = eval {
103             $registrar->message->response->epp_auth
104             } ) {
105             $self->log_debug("checking provided password (".$self->password.") against ".Dumper($auth->crypted));
106             $password_ok = $auth->check($self->password);
107             $self->log_info("supplied password does not match")
108             if !$password_ok;
109             }
110             else {
111             $self->log_info("could not fetch password (denying login): $@");
112             }
113              
114             # must be an entry on the allow list
115             my $ip_ok;
116             if ( my $entry = eval {
117             $ip_ok_acl->message->response->entries->[0]
118             }) {
119             $ip_ok = 1;
120             $self->log_info("IP ACL found for ".$entry->Address);
121             }
122             else {
123             $self->log_info("no IP ACL found; denying login");
124             }
125              
126             # the certificate must also have an entry
127             my $cn_ok = $cn_ok_acl ? 0 : 1;
128             if ( $cn_ok_acl && (my $entry = eval {
129             $cn_ok_acl->message->response->entries->[0];
130             })) {
131             $self->log_info("Domain ACL found for: "
132             .$entry->DomainName);
133             $cn_ok = 1;
134             }
135             else {
136             $self->log_info("no common name ACL found; denying login");
137             }
138              
139             if ( $password_ok and $ip_ok and $cn_ok ) {
140             $self->log_info("login as registrar ".$self->uid." successful");
141             $self->login_ok(1);
142             $self->session->user($self->uid);
143             }
144             else {
145             $self->log_info("login as registrar ".$self->uid." unsuccessful");
146             }
147             $self->session->clear_want_user;
148             $self->session->stalled(0);
149              
150             # Wrap it up...
151             if ( $self->login_ok ) {
152             if ( $self->new_password() ) {
153             return XML::SRS::Registrar::Update->new(
154             registrar_id => $self->uid,
155             epp_auth => Crypt::Password::password( $self->new_password ),
156             action_id => $self->server_id,
157             );
158             }
159             return $self->make_response(code => 1000);
160             }
161             return $self->make_response(code => 2200);
162             }
163             else {
164             # response to a password update
165             my $registrar = $rs[0];
166             if ( my $auth = eval {
167             $registrar->message->response->epp_auth
168             }) {
169             my $ok = $auth->check($self->new_password);
170             if ( $ok ) {
171             $self->log_info("changed password successfully");
172             return $self->make_response(code => 1000);
173             }
174             else {
175             $self->log_error("failed to change password!");
176             return $self->make_response(code => 2400);
177             }
178             }
179             }
180              
181             };
182              
183             1;