File Coverage

blib/lib/Metabrik/Client/Smbclient.pm
Criterion Covered Total %
statement 9 98 9.1
branch 0 56 0.0
condition 0 24 0.0
subroutine 3 8 37.5
pod 1 4 25.0
total 13 190 6.8


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # client::smbclient Brik
5             #
6             package Metabrik::Client::Smbclient;
7 2     2   697 use strict;
  2         5  
  2         57  
8 2     2   10 use warnings;
  2         3  
  2         56  
9              
10 2     2   9 use base qw(Metabrik::Shell::Command Metabrik::System::Package);
  2         4  
  2         2601  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             datadir => [ qw(datadir) ],
20             domain => [ qw(domain) ],
21             user => [ qw(username) ],
22             password => [ qw(password) ],
23             host => [ qw(host) ],
24             share => [ qw(path) ],
25             remote_path => [ qw(path) ],
26             },
27             attributes_default => {
28             domain => 'WORKGROUP',
29             user => 'Administrator',
30             host => '127.0.0.1',
31             share => 'c$',
32             remote_path => '\\windows\\temp',
33             },
34             commands => {
35             install => [ ], # Inherited
36             upload => [ qw(file|file_list remote_path|OPTIONAL) ],
37             download => [ qw(file|file_list output_dir|OPTIONAL remote_path|OPTIONAL) ],
38             download_in_background => [ qw(file|file_list output_dir|OPTIONAL remote_path|OPTIONAL) ],
39             },
40             require_modules => {
41             'Metabrik::System::Process' => [ ],
42             },
43             require_binaries => {
44             smbclient => [ ],
45             },
46             need_packages => {
47             ubuntu => [ qw(smbclient) ],
48             debian => [ qw(smbclient) ],
49             kali => [ qw(smbclient) ],
50             },
51             };
52             }
53              
54             #
55             # More good stuff here: https://github.com/jrmdev/smbwrapper
56             #
57              
58             #
59             # run client::smbclient upload $file \\windows\temp\ c$
60             #
61             sub upload {
62 0     0 0   my $self = shift;
63 0           my ($files, $remote_path, $share) = @_;
64              
65 0   0       $remote_path ||= $self->remote_path;
66 0   0       $share ||= $self->share;
67 0 0         $self->brik_help_run_undef_arg('upload', $files) or return;
68 0 0         my $ref = $self->brik_help_run_invalid_arg('upload', $files, 'ARRAY', 'SCALAR')
69             or return;
70              
71 0           my $domain = $self->domain;
72 0           my $username = $self->user;
73 0           my $password = $self->password;
74 0           my $host = $self->host;
75 0 0         $self->brik_help_set_undef_arg('upload', $domain) or return;
76 0 0         $self->brik_help_set_undef_arg('upload', $username) or return;
77 0 0         $self->brik_help_set_undef_arg('upload', $password) or return;
78 0 0         $self->brik_help_set_undef_arg('upload', $host) or return;
79              
80 0 0         if ($ref eq 'ARRAY') {
81 0           my @files = ();
82 0           for my $file (@$files) {
83 0 0         my $this = $self->upload($file, $remote_path, $share) or next;
84 0           push @files, $this;
85             }
86              
87 0           return \@files;
88             }
89             else {
90 0           my ($this_file) = $files =~ m{^(?:.*/)?(.*)$};
91 0           my $cmd = "smbclient -U $domain/$username%$password //$host/$share -c ".
92             "'put \"$files\" $remote_path\\$this_file'";
93              
94 0           (my $cmd_hidden = $cmd) =~ s{$password}{XXX};
95 0           $self->log->verbose("upload: cmd[$cmd_hidden]");
96              
97 0           my $level = $self->log->level;
98 0           $self->log->level(0);
99 0 0         $self->system($cmd) or return;
100 0           $self->log->level($level);
101              
102 0           return "$remote_path\\$this_file";
103             }
104              
105 0           return $self->log->error("upload: unhandled exception");
106             }
107              
108             #
109             # run client::smbclient download c:\\windows\temp\file.txt /tmp/
110             #
111             sub download {
112 0     0 0   my $self = shift;
113 0           my ($files, $output_dir, $share) = @_;
114              
115 0   0       $output_dir ||= defined($self->shell) && $self->shell->full_pwd || '/tmp';
      0        
116 0   0       $share ||= $self->share;
117 0 0         $self->brik_help_run_undef_arg('download', $files) or return;
118 0 0         my $ref = $self->brik_help_run_invalid_arg('download', $files, 'ARRAY', 'SCALAR')
119             or return;
120              
121 0           my $domain = $self->domain;
122 0           my $username = $self->user;
123 0           my $password = $self->password;
124 0           my $host = $self->host;
125 0 0         $self->brik_help_set_undef_arg('download', $domain) or return;
126 0 0         $self->brik_help_set_undef_arg('download', $username) or return;
127 0 0         $self->brik_help_set_undef_arg('download', $password) or return;
128 0 0         $self->brik_help_set_undef_arg('download', $host) or return;
129              
130 0 0         if ($ref eq 'ARRAY') {
131 0           my @files = ();
132 0           for my $file (@$files) {
133 0 0         my $this = $self->download($file, $output_dir, $share) or next;
134 0           push @files, $this;
135             }
136              
137 0           return \@files;
138             }
139             else {
140             # Convert path to \\ and remove potentiel initial drive letter
141 0           $files =~ s{/}{\\}g;
142 0           my ($drive) = $files =~ m{^([a-zA-Z]):};
143 0           my ($output_file) = $files =~ m{\\([^\\]+)$};
144 0           $files =~ s{^[a-zA-Z]:}{};
145 0 0         $drive ? ($drive .= '$') : ($drive = $share);
146 0   0       $output_file ||= '';
147              
148 0 0         my $output = $output_dir ? "$output_dir/$output_file" : $output_file;
149              
150 0           my $cmd = "smbclient -U $domain/$username%$password //$host/$drive -c ".
151             "'get $files $output'";
152              
153 0           (my $cmd_hidden = $cmd) =~ s{$password}{XXX};
154 0           $self->log->verbose("download: cmd[$cmd_hidden]");
155              
156 0           my $level = $self->log->level;
157 0           $self->log->level(0);
158 0 0         $self->system($cmd) or return;
159 0           $self->log->level($level);
160              
161 0           return $output;
162             }
163              
164 0           return $self->log->error("download: unhandled exception");
165             }
166              
167             sub download_in_background {
168 0     0 0   my $self = shift;
169 0           my ($files, $output_dir, $share) = @_;
170              
171 0   0       $output_dir ||= defined($self->shell) && $self->shell->full_pwd || '/tmp';
      0        
172 0   0       $share ||= $self->share;
173 0 0         $self->brik_help_run_undef_arg('download_in_background', $files) or return;
174 0 0         my $ref = $self->brik_help_run_invalid_arg('download_in_background', $files,
175             'ARRAY', 'SCALAR') or return;
176              
177 0           my $domain = $self->domain;
178 0           my $username = $self->user;
179 0           my $password = $self->password;
180 0           my $host = $self->host;
181 0 0         $self->brik_help_set_undef_arg('download_in_background', $domain) or return;
182 0 0         $self->brik_help_set_undef_arg('download_in_background', $username) or return;
183 0 0         $self->brik_help_set_undef_arg('download_in_background', $password) or return;
184 0 0         $self->brik_help_set_undef_arg('download_in_background', $host) or return;
185              
186 0 0         my $sp = Metabrik::System::Process->new_from_brik_init($self) or return;
187 0           $sp->close_output_on_start(1);
188              
189             # Convert SCALAR to ARRAY
190 0 0         if (ref($files) eq '') {
191 0           $files = [ $files ];
192             }
193              
194 0           for my $this ($files) {
195             $sp->start(sub {
196 0     0     $self->download($this, $output_dir, $share);
197 0           });
198             }
199              
200 0           return 1;
201             }
202              
203             1;
204              
205             __END__