How to use ssh-agent with Net:OpenSSH Perl - perl

I got three servers, MyServer (centos7), Jumper and DestinationServer. I need to establish SSH connection from MyServer through Jumper to DestinationServer using Perl script with Net:OpenSSH lib.
on the MyServer i have a private rsa key.
on the Jumper and DestinationServer i have a public rsa key to authorize ssh connection.
on the Jumper i can only use the remote command which is an user#servername to connect to the third server.
with Bash it works really fine, i just enable ssh-agent and add rsa key:
ssh-agent -s
ssh-add ~/.ssh/id_rsa
ssh -A user#Jumper user#DestinationServer ls -l
which results in remote display of the command
But code in Perl:
#!/user/bin/perl
use Net::OpenSSH
my $ssh = Net::OpenSSH->new($JumperIP, user =>$user, forward_agent => 1);
$ssh-> capture('user#DestinationServer ls -l');
returns same error as Bash code with no agent forwarding (-A):
Permission denied, please try again.
Received disconnect from DestinationServerIP port 22:2 Too many authentication failures for user
Disconnected from DestinationServerIP port 22
in the documentation (https://metacpan.org/pod/Net::OpenSSH ) it says only
"forward_agent => 1
Note that Net::OpenSSH will not run ssh-agent for you. This has to be done ahead of time and the environment variable SSH_AUTH_SOCK set pointing to the proper place."
so i got no idea how to attach enabled ssh-agent.
EDIT:
With:
BEGIN {
$Net::OpenSSH::debug_fh = $out;
$Net::OpenSSH::debug = ~0;
}
i get that output:
# open_ex: ['ssh','-V']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 48 at offset 0
#> 4f 70 65 6e 53 53 48 5f 37 2e 34 70 31 2c 20 4f 70 65 6e 53 53 4c 20 31 2e 30 2e 32 6b 2d 66 69 | OpenSSH_7.4p1, OpenSSL 1.0.2k-fi
#> 70 73 20 20 32 36 20 4a 61 6e 20 32 30 31 37 0a | ps 26 Jan 2017.
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 48
# leaving _io3()
# _waitpid(14949) => pid: 14949, rc:
# OpenSSH verion is 7.4p1,
# ctl_path: /home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827, ctl_dir: /home/$USER/.libnet-openssh-perl/
# _is_secure_path(dir: /home/$USER/.libnet-openssh-perl, file mode: 16832, file uid: 1084, euid: 1084
# _is_secure_path(dir: /home/$USER, file mode: 16872, file uid: 1084, euid: 1084
# set_error(0 - 0)
# call args: ['ssh','-o','ServerAliveInterval=30','-o','ControlPersist=no','-2MNAx','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--']
# file object not yet found at /home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827, state: waiting_for_mux_socket
# tracer attached, ssh pid: 14950, tracer pid: 14951
# file object found at /home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827
# call args: ['ssh','-O','check','-T','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--']
# open_ex: ['ssh','-O','check','-T','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 28 at offset 0
#> 4d 61 73 74 65 72 20 72 75 6e 6e 69 6e 67 20 28 70 69 64 3d 31 34 39 35 30 29 0d 0a | Master running (pid=14950)..
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 28
# leaving _io3()
# _waitpid(15022) => pid: 15022, rc:
# call args: ['ssh','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--','$USER#DestinationServer ls -l']
# open_ex: ['ssh','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--','$USER#DestinationServer ls -l']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
Permission denied, please try again.
Permission denied, please try again.
Received disconnect from $DestinationIP port 22:2: Too many authentication failures for $USER
Disconnected from $DestinationIP port 22
# stdout, bytes read: 0 at offset 0
# leaving _io3()
# _waitpid(15023) => pid: 15023, rc:
# DESTROY(Net::OpenSSH=HASH(0x2832240), pid: 14950)
# killing master
# sending exit control to master
# call args: ['ssh','-O','exit','-T','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--']
# open_ex: ['ssh','-O','exit','-T','-S','/home/$USER/.libnet-openssh-perl/$USER-$IP.-14948-620827','-l','$USER','$IP','--']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 20 at offset 0
#> 45 78 69 74 20 72 65 71 75 65 73 74 20 73 65 6e 74 2e 0d 0a | Exit request sent...
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 20
# leaving _io3()
# _waitpid(15025) => pid: 15025, rc:
# _kill_master: 14950
# waitpid(master: 14950) => pid: 14950, rc:
I'm not sure, but i do not see -A flag of agent forwarding in that debug or maybe I'm thinking wrong, but I use:
SSH_AUTH_SOCK=/tmp/ssh-numbers/agent.28101; export SSH_AUTH_SOCK;
SSH_AGENT_PID=28102; export SSH_AGENT_PID;
echo Agent pid 28102;
to set ENV by Bash shell before starting Perl script.

Related

SNMPTT let hex string sometimes

Here is a part of the snmptt log file :
Tue May 17 22:20:47 2016 .1.3.6.1.4.1.31023.1.1.1.0.1 Normal "Status Events" ssav02 - ef47e072-c8e1-46ef-8c70-645a69bdd489 Backup Job 1 Success
Tue May 17 23:00:03 2016 .1.3.6.1.4.1.1302.3.1.2.8.0.5 INFORMATIONAL "Status Events" ssav02 - User advised of event: 42 61 63 6B 75 70 20 45 78 65 63 3A 20 44 E9 62 75 74 20 64 75 20 74 72 61 76 61 69 6C Job:53 53 41 56 30 32 20 2D 20 53 61 75 76 65 67 61 72 64 65 20 56 65 65 61 6D 2D 43 6F 6D 70 6C E8 74 65 4C 65 20 74 72 61 76 61 69 6C 20 61 20 64 E9 6D 61 72 72 E9 2E
Wed May 18 01:04:03 2016 .1.3.6.1.4.1.1302.3.1.2.8.0.7 MINOR "Status Events" ssav02 - User advised of event: Backup Exec: Avertissement de travail
There associated to this :
EVENT onVmBackupCompleted .1.3.6.1.4.1.31023.1.1.1.0.2 "Status Events" Normal
FORMAT $*
EXEC /usr/local/nagios/libexec/eventhandlers/submit_check_result $2 "Backup Veeam" 0 "$2 : $4 ($5)"
SDESC
This trap is sent on vm backup/replica completed.
Variables:
1: backupJobName
2: vmName
3: sourceHostName
4: vmBackupResult
5: vmBackupComment
EDESC
EVENT jobStarted .1.3.6.1.4.1.1302.3.1.2.8.0.5 "Status Events" INFORMATIONAL
FORMAT User advised of event: $1 Job:$3 $4
EXEC /usr/local/nagios/libexec/eventhandlers/submit_check_result $r "Sauvegarde ${3}" 0 "User advised of event: $1 Job:$3 $4"
SDESC
The Job has started.
Variables:
1: messageText
2: serverName
3: jobName
4: additionalText
EDESC
EVENT jobWarning .1.3.6.1.4.1.1302.3.1.2.8.0.7 "Status Events" MINOR
FORMAT User advised of event: $1
EXEC /usr/local/nagios/libexec/eventhandlers/submit_check_result $r TRAP 1 "User advised of event: $1"
SDESC
The job has a warning.
Variables:
1: messageText
EDESC
As you can see, for some trap, the message is not properly encoded, and the message generated is indescriptible.
So why is my message sometime Hex-string encoded ? How to fix this ?

perl: What would cause perl to not find a file that exists?

Running a perl cgi script I got the error it couldn't find the file it was trying to open. I check apache error log /var/log/apache2/error.log:
[Tue Jan 13 20:59:17 2015] [error] [client ::1] [Tue Jan 13 20:59:17 2015] submit.cgi: [Tue Jan 13 20:59:17 2015] submit.cgi:
/home/jddancks/Documents/perl/homeworks/hw13/grades4.txt: No such file or directory at /var/www/homeworks/hw13/CreateExam.pm line 48., referer: http://localhost/homeworks/hw13/test.cgi
double check:
root#debian-macbook:/var/log/apache2# ls -l /home/jddancks/Documents/perl/homeworks/hw13/grades4.txt
-rwxrwxrwx 1 jddancks jddancks 2095 Jan 7 12:25 /home/jddancks/Documents/perl/homeworks/hw13/grades4.txt
Why would this happen? This is a debian machine running apache 2.2 IDK if that helps.
There are 2 files: submit.cgi and CreateExam.pm.
submit.cgi:
use CreateExam;
...
my $path = `pwd`;
...
my $check = CreateExam->new("${path}/exam4.txt","${path}/answers4.txt","${path}/grades4.txt",$pathroot);
$check->entergrades($cookie_value,$cgi->Vars());
CreateExam.pm:
package CreateExam;
sub new {
my ($class,$file,$answers,$grades,$script) = #_;
#print "<p>in new: file: $file, grades: $grades</p>\n";
return bless {'file'=>$file,'answers'=>$answers,'gradefile'=>$grades,'script'=>$script},$class;
}
sub tooktest {
my ($self,$person) = #_;
#print "<p>in tooktest: person: $person</p>\n";
my $grades = $self->{'gradefile'};
open(ANS,"< $grades") or die "$grades: $!";
my $found = 0;
LAST: while(my $line = <ANS>) {
if($line =~ /\<test taker=$person/) { $found = 1; last LAST;}
}
return $found==1;
}
Data::Dumper:
$VAR1 = "/home/jddancks/Documents/perl/homeworks/hw13"; (in browser)
hexdump:
jddancks#debian-macbook:~/Documents/perl/homeworks/hw13$ perl -e 'print qx(pwd)' | hexdump -C
00000000 2f 68 6f 6d 65 2f 6a 64 64 61 6e 63 6b 73 2f 44 |/home/jddancks/D|
00000010 6f 63 75 6d 65 6e 74 73 2f 70 65 72 6c 2f 68 6f |ocuments/perl/ho|
00000020 6d 65 77 6f 72 6b 73 2f 68 77 31 33 0a |meworks/hw13.|
0000002d
As your hexdump shows, pwd returns the working directory followed by a newline, and that is what is you are assigning to $path. Then you try to open "/home/jddancks/Documents/perl/homeworks/hw13\n/grades4.txt" which indeed has a directory that does not exist.
Try doing:
chomp( my $path = `pwd` );
If Apache is configured to run in a chroot it does not see /home on the host system at all.

How to make AT command to automatically return caller ID?

So, I'm using AT Commands with Matlab to return the Caller ID. It DOES work, but I have to manually ask for it. I what it to return Caller ID automatically whenever I ring on the phone.
Here is what I write before I ring:
>> s = serial('COM8');
>> fopen(s)
And I type this when my phone rings:
>> fwrite(s, [65 84 43 67 82 67 61 49 13])
Then I ask for the returned value(the caller phone number):
>> s
Serial Port Object : Serial-COM8
Communication Settings
Port: COM8
BaudRate: 9600
Terminator: 'LF'
Communication State
Status: open
RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 47
ValuesReceived: 0
ValuesSent: 18
>> fread(s, 47)
and it returns me 47 ASCII numbers like this(note that I have deleted most of the returned code):
ans =
65
84
43
67
82
67
61
49
13
Which translates to the following(changed the number for safety reasons):
+CRING:VOICE +CLIP: "+359888888888",145AT+CRC=1OK
What I want to happen is when the phone rings to immediately send the computer the output of
>> fwrite(s, [65 84 43 67 82 67 61 49 13])
>> fread(s, 47)

Sending a trap with Perl's Net::SNMP

I'm trying to send a trap as part of a larger Perl script. I've copied the trapsending code to another file, and am running it by itself. The code seems to think the trap sends successfully, yet I'm not seeing the trap on either machine that I have a trap listener running on.
Here's the code:
#! /usr/local/bin/perl
use strict;
use warnings;
use Net::SNMP;
#messy hardcoding
my $snmp_target = '192.168.129.50';
#my $snmp_target = '10.200.6.105'; # Server running trap listener
my $enterprise = '1.3.6.1.4.1.27002.1';
my ($sess, $err) = Net::SNMP->session(
-hostname => $snmp_target,
-version => 1, #trap() requires v1
);
if (!defined $sess) {
print "Error connecting to target ". $snmp_target . ": ". $err;
next;
}
my #vars = qw();
my $varcounter = 1;
push (#vars, $enterprise . '.' . $varcounter);
push (#vars, OCTET_STRING);
push (#vars, "Test string");
my $result = $sess->trap(
-varbindlist => \#vars,
-enterprise => $enterprise,
-specifictrap => 1,
);
if (! $result)
{
print "An error occurred sending the trap: " . $sess->error();
}
EDIT: Added $sess->debug(255) call, here's the output:
debug: [440] Net::SNMP::Dispatcher::_event_insert(): created new head and tail [ARRAY(0x1af1fea8)]
debug: [687] Net::SNMP::Message::send(): transport address 192.168.129.50:161
debug: [2058] Net::SNMP::Message::_buffer_dump(): 70 bytes
[0000] 30 44 02 01 00 04 06 70 75 62 6C 69 63 A4 37 06 0D.....public.7.
[0016] 09 2B 06 01 04 01 81 D2 7A 01 40 04 C0 A8 81 85 .+......z.#.....
[0032] 02 01 06 02 01 01 43 01 00 30 1B 30 19 06 0A 2B ......C..0.0...+
[0048] 06 01 04 01 81 D2 7A 01 01 04 0B 54 65 73 74 20 ......z....Test
[0064] 73 74 72 69 6E 67 string
debug: [517] Net::SNMP::Dispatcher::_event_delete(): deleted [ARRAY(0x1af1fea8)], list is now empty
EDIT: Can anyone running a trap listener try this code on their machine and let me know if it works?
EDIT: Tried it from my MBP. Same result. Then noticed that the debug info says it is sending to port 161. Forced -port => 162 parameter, and it works. That leaves me with a couple of questions:
Why does the trap sender default to 161?
I get this error when I run with debug on. What does it mean?
error: [97] Net::SNMP::Transport::IPv4::UDP::agent_addr(): Failed to disconnect: Address family not supported by protocol family
Fixed by changing 'Port' setting from default 161 to 162.

Hex dump parsing in perl

I have a hex dump of a message in a file which i want to get it in an array
so i can perform the decoding logic on it.
I was wondering if that was a easier way to parse a message which looks like this.
37 39 30 35 32 34 35 34 3B 32 31 36 39 33 34 35
3B 32 31 36 39 33 34 36 00 00 01 08 40 00 00 15
6C 71 34 34 73 69 6D 31 5F 33 30 33 31 00 00 00
00 00 01 28 40 00 00 15 74 65 6C 63 6F 72 64 69
74 65 6C 63 6F 72 64 69
Note that the data can be max 16 bytes on any row. But any row can contain fewer bytes too (minimum :1 )
Is there a nice and elegant way rather than to read 2 chars at a time in perl ?
Perl has a hex operator that performs the decoding logic for you.
hex EXPR
hex
Interprets EXPR as a hex string and returns the corresponding value. (To convert strings that might start with either 0, 0x, or 0b, see oct.) If EXPR is omitted, uses $_.
print hex '0xAf'; # prints '175'
print hex 'aF'; # same
Remember that the default behavior of split chops up a string at whitespace separators, so for example
$ perl -le '$_ = "a b c"; print for split'
a
b
c
For every line of the input, separate it into hex values, convert the values to numbers, and push them onto an array for later processing.
#! /usr/bin/perl
use warnings;
use strict;
my #values;
while (<>) {
push #values => map hex($_), split;
}
# for example
my $sum = 0;
$sum += $_ for #values;
print $sum, "\n";
Sample run:
$ ./sumhex mtanish-input
4196
I would read a line at a time, strip the whitespace, and use pack 'H*' to convert it. It's hard to be more specific without knowing what kind of "decoding logic" you're trying to apply. For example, here's a version that converts each byte to decimal:
while (<>) {
s/\s+//g;
my #bytes = unpack('C*', pack('H*', $_));
print "#bytes\n";
}
Output from your sample file:
55 57 48 53 50 52 53 52 59 50 49 54 57 51 52 53
59 50 49 54 57 51 52 54 0 0 1 8 64 0 0 21
108 113 52 52 115 105 109 49 95 51 48 51 49 0 0 0
0 0 1 40 64 0 0 21 116 101 108 99 111 114 100 105
116 101 108 99 111 114 100 105
I think reading in two characters at a time is the appropriate way to parse a stream whose logical tokens are two-character units.
Is there some reason you think that's ugly?
If you're trying to extract a particular sequence, you could do that with whitespace-insensitive regular expressions.