File Coverage

lib/SMB/v2/Command/Negotiate.pm
Criterion Covered Total %
statement 9 59 15.2
branch 0 12 0.0
condition 0 7 0.0
subroutine 3 8 37.5
pod 0 5 0.0
total 12 91 13.1


line stmt bran cond sub pod time code
1             # SMB Perl library, Copyright (C) 2014-2018 Mikhael Goikhman, migo@cpan.org
2             #
3             # This program is free software: you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation, either version 3 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package SMB::v2::Command::Negotiate;
17              
18 1     1   4 use strict;
  1         2  
  1         20  
19 1     1   3 use warnings;
  1         2  
  1         17  
20              
21 1     1   3 use parent 'SMB::v2::Command';
  1         2  
  1         3  
22              
23             sub new_from_v1 ($$) {
24 0     0 0   my $class = shift;
25 0           my $command1 = shift;
26              
27 0           my $header1 = $command1->header;
28              
29 0 0         my $flags = $header1->{flags} & SMB::v1::Header::FLAGS_RESPONSE ? SMB::v2::Header::FLAGS_RESPONSE : 0;
30             my $security_mode =
31             ($header1->{flags2} & SMB::v1::Header::FLAGS2_SECURITY_SIGNATURE ? 1 : 0) |
32 0 0         ($header1->{flags2} & SMB::v1::Header::FLAGS2_SECURITY_SIGNATURE_REQUIRED ? 2 : 0);
    0          
33              
34 0           my $header = SMB::v2::Header->new(
35             code => 0,
36             mid => 0,
37             flags => $flags,
38             status => $command1->status,
39             );
40              
41 0           my $self = $class->SUPER::new($header);
42              
43 0           $self->set(
44             security_mode => $security_mode,
45             dialects => [ 0x0202, 0x02ff ],
46             );
47              
48 0           return $self;
49             }
50              
51             sub init ($) {
52 0     0 0   $_[0]->set(
53             dialects => [ 0x0202 ],
54             dialect => 0x0202,
55             security_mode => 0,
56             capabilities => 0x7,
57             guid => "\5" x 16,
58             max_transact_size => 1 << 20,
59             max_read_size => 1 << 16,
60             max_write_size => 1 << 16,
61             current_time => 0,
62             boot_time => 0,
63             security_buffer => undef,
64             )
65             }
66              
67             sub parse ($$%) {
68 0     0 0   my $self = shift;
69 0           my $parser = shift;
70              
71 0 0         if ($self->is_response) {
72 0           $self->security_mode($parser->uint16);
73 0           $self->dialect($parser->uint16);
74 0           $parser->uint16; # reserved
75 0           $self->guid($parser->bytes(16));
76 0           $self->capabilities($parser->uint32);
77 0           $self->max_transact_size($parser->uint32);
78 0           $self->max_read_size($parser->uint32);
79 0           $self->max_write_size($parser->uint32);
80 0           $self->current_time($parser->uint64);
81 0           $self->boot_time($parser->uint64);
82 0           my $offset = $parser->uint16;
83 0           my $length = $parser->uint16;
84 0           $parser->uint32; # reserved2
85 0           $self->security_buffer($parser->bytes($length));
86             } else {
87 0           my $num_dialects = $parser->uint16;
88 0           $self->security_mode($parser->uint16);
89 0           $parser->uint16; # reserved
90 0           $self->capabilities($parser->uint32);
91 0           $self->guid($parser->bytes(16));
92 0           $self->boot_time($parser->uint64);
93 0           $self->dialects([ map { $parser->uint16 } 1 .. $num_dialects ]);
  0            
94             }
95              
96 0           return $self;
97             }
98              
99             sub pack ($$) {
100 0     0 0   my $self = shift;
101 0           my $packer = shift;
102              
103 0 0         if ($self->is_response) {
104 0   0       my $security_buffer = $self->security_buffer // die 'No security_buffer';
105              
106 0   0       $packer
107             ->uint16($self->security_mode)
108             ->uint16($self->dialects->[1] || $self->dialect)
109             ->uint16(0) # reserved
110             ->bytes ($self->guid)
111             ->uint32($self->capabilities)
112             ->uint32($self->max_transact_size)
113             ->uint32($self->max_read_size)
114             ->uint32($self->max_write_size)
115             ->uint64($self->current_time)
116             ->uint64($self->boot_time)
117             ->uint16($packer->diff('smb-header') + 8)
118             ->uint16(length $security_buffer)
119             ->uint32(0) # reserved2
120             ->bytes ($security_buffer)
121             ;
122             } else {
123 0           my $dialects = $self->dialects;
124 0           $packer
125             ->uint16(scalar @$dialects)
126             ->uint16($self->security_mode)
127             ->uint16(0) # reserved
128             ->uint32($self->capabilities)
129             ->bytes ($self->guid)
130             ->uint64($self->boot_time)
131             ;
132 0           $packer->uint16($_) for @$dialects;
133             }
134             }
135              
136             sub supports_smb_dialect ($$) {
137 0     0 0   my $self = shift;
138 0   0       my $dialect0 = shift || die;
139              
140 0           for my $dialect (@{$self->dialects}) {
  0            
141 0 0         return 1 if $dialect > $dialect0;
142             }
143              
144 0           return 0;
145             }
146              
147             1;