Permission denied while accessing Hypertable in CGI program - perl

I'm trying to develop a Web app in Perl using Hypertable. Sample code:
#!/usr/bin/perl -w
use strict;
use warnings;
use CGI;
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use CGI::Session ('-ip_match');
use Hypertable::ThriftClient;
use Data::Dumper;
my $q = new CGI;
print $q->header(-cache_control => "no-cache, no-store, must-revalidate");
eval {
my $client = new Hypertable::ThriftClient("localhost", 38080);
my $namespace = $client->open_namespace("glinpe");
my $result = $client->hql_exec($namespace, "select * from words where row=\"maths\" keys_only");
};
if ($#) {
if ($#->isa('Thrift::TException')) {
print Dumper($#);
} else {
print Dumper($#);
}
}
print "<h1>works</h1>";
The problem is when trying to execute from a web browser I get an error:
$VAR1 = bless( { 'code' => 0, 'message' => 'TSocket: Could not connect to localhost:38080 (Permission denied)' }, 'Thrift::TException' );
The scripts works properly when running from a terminal(under apache user), and as well in a browser if remove all Hypertable code.
I have 38080 port opened in iptables:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 38080 -j ACCEPT
OS: Centos 5.6.

The error message says you're missing permission, so that would be the answer (user apache, doesn't have permission to create socket to localhost:38080)
update: to elaborate, when you run it from a terminal, it is running as a regular user, but when apache runs it, most often it is running under apache user account, which may not have permission to open sockets
It could be you're using SELinux in which case see 'man chcon'
or search for "SELinux tutorial: Configuring RHEL 5 and Web servers"

OK, so there is two solution to this particular problem:
1. disable selinux - change configuration in /etc/selinux/config
2. run command:
setsebool -P httpd_can_network_connect 1
Thanks to previous answer for putting me back on track.

Related

Perl - Can't get data from metasploit RPC server

What I have used as resource : https://metasploit.help.rapid7.com/v1/docs/rpc-api
First I have started msf rpc server :
msfrpcd -U msf -P test -f -S -a 127.0.0.1
[*] MSGRPC starting on 127.0.0.1:55553 (NO SSL):Msg...
[*] MSGRPC ready at 2019-01-11 00:56:29 +0900.
after that the server is up and is showing up via browser in http://127.0.0.1:55553
The script I have used while using XML::RPC to get data
use XML::RPC;
use strict;
use warnings;
my $fm = XML::RPC->new( 'http://127.0.0.1:55553/api/' );
my $session = $fm->call( 'auth.login', { username => 'msf', password => 'test' });
my $x = $fm->call('group.command'); #api
The error when I run the script :
no data at /usr/local/share/perl/5.26.1/XML/RPC.pm line 288.
It seems that the api used is not working or perphaps something wrong
Do you have any better way to get data from msf rpc server?

Perl and Selenium::Remote::Driver

EDITED AGAIN
I have a server on AWS somewhere in Northern Virginia and this is my monitoring server. I ssh into this Ubuntu server from another State to do system administration. I want to do web automation tests on this server which will test a web application on the Internet hitting a URL and verify that I can selenium test a login and authenticate successfully. This server is on an AWS cloud I'm not quite sure which Perl module to use since I'm accessing it remotely.
There are two CPAN modules: Selenium::Remote::Driver and WWW::Selenium. I have tried both and they are giving me issues. And I really don't know which is appropriate for my scenario. When I use Selenium::Remote::Driver, I get the following error:
Selenium server did not return proper status at /usr/local/share/perl/5.18.2/Selenium/Remote/Driver.pm line 401.
When I use WWW::Selenium, I get this error:
Failed to start new browser session: org.openqa.selenium.server.RemoteCommandException: Error while launching browser
I was able to launch firefox manually from the AWS monitoring server by exporting the DISPLAY but it was really slow. I have heard that I can use a headless browser but I would have to export the DISPLAY by:
export DISPLAY=:5
But remember, I'm sshing into this AWS/Selenium server from my desktop so I'm assuming I use the above command on the AWS/Selenium Server while I'm ssh into it from my desktop? Actually, at this point, I'm not sure I'm doing here. Can somebody help?
The problem in this type of questions is that the variety of configurations and binaries in your setup might be so broad that the it is hard to actually provide a straight and correct answer for YOUR SETUP.
This answer has the following assumptions:
you have downloaded the selenium-server-standalone.jar into /usr/lib/
you have jdk 1.8 ( run the java -version in the shell
you have installed and configured the xvfb-run ( it is a fight on it's own )
So :
```
# ssh to your server , obs the -X !
ssh -X user-name#server-name
# start the selenium-server-standalone on the server
xvfb-run -e /dev/stdout java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/lib/selenium-server-standalone.jar &
# one liner test - this is one veery long one
perl -e 'use strict ; use warnings ; use Data::Printer ; my $host="127.0.0.1"; use Selenium::Remote::Driver;my $driver = Selenium::Remote::Driver->new( "browser_name" =>"chrome", "error_handler" => sub { print $_[1]; croak 'goodbye'; }, "remote_server_addr" => "$host","port"=> "4444");$driver->debug_on();$driver->get("http://www.google.com"); print $driver->get_title();$driver->quit();' &
```
Here is the code in the one-liner as a perl script
#!/usr/bin/env perl
use strict ;
use warnings ;
use Carp ;
use Data::Printer ;
use Selenium::Remote::Driver;
my $host="127.0.0.1";
my $driver = Selenium::Remote::Driver->new(
"browser_name" =>"chrome"
, "error_handler" => sub { print $_[1]; croak 'goodbye' ; }
, "remote_server_addr" => "$host"
, "port"=> "4444") ;
$driver->debug_on() ;
$driver->get("http://www.google.com");
print $driver->get_title();
$driver->quit();
The output should look something like:
```
Prepping get
Executing get
REQ: POST, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/url, {"url":"http://www.google.com"}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
Prepping getTitle
Executing getTitle
REQ: GET, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/title, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":"Google"}
GooglePrepping quit
Executing quit
REQ: DELETE, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
```
Try running the below code:
#!/usr/bin/perl
use warnings;
use strict;
use Selenium::Remote::Driver;
my $host = "10.10.1.1"; //Enter your server IP in this place
my $driver = new Selenium::Remote::Driver('remote_server_addr' => $host,
'port' => '4444',
'auto_close' => 0);
$driver->get('http://www.google.com');

can't ssh:unable to establish master SSH connection: bad password or master process exited unexpectedly

I have problem with perl modules, i 'm trying to connect to the remote server using the OpenSSH module from CPAN and i have given the username and password correctly but when i run my CGI from browser i see the following error message "
can't ssh:unable to establish master SSH connection: bad password or
master process exited unexpectedly
in need of immediate reply's and awaiting,
Thanks in Advance.
Here is my code
#!/usr/bin/perl -w
use CGI;
use Data::Dumper;
use strict;
use CGI::Carp qw(fatalsToBrowser);
use Net::OpenSSH;
my $query = CGI->new();
#my $mach_name=$query->param('mach_name');
my $mach_name= '****.cce.***.com';
my $user='root';
my $passwd='*******';
my $ssh = Net::OpenSSH->new("$mach_name",user => "$user" , passwd => "$passwd
", master_opts => [-o => "strictHostKeyChecking=no"]);
$ssh->error and die "can't ssh:" . $ssh->error;
my $mem_info =$ssh->capture("ioscan -m lun");
print "$mem_info";
print "Content-type: text/html\n\n";
print "<html><head><title>test page</title></head>\n";
print "<body><p>Dicovering Machine Please wait....</p>\n";
print "<p>$mach_name</p>";
print "<p><b>Swap Memory :$mem_info </b> </p>";
print "</body></html>";
The same program if i run through the command line it is getting the o/p but through the browser i'm seeing the above error i have given the passwd and username correctly
My problem was solved when I've increased the timeout from 10 seconds to 15 seconds, because the device is using an older SSH daemon version, but my linux server that made the client connection is upgraded and of course it probes first the newer ciphers.
my $ssh = Net::OpenSSH->new(
$host,
port => $port,
user => $user,
password => $pass,
timeout => 15, # <= this was 10 and now is 15
kill_ssh_on_timeout => 1,
strict_mode => 0,
master_opts => [-o => "StrictHostKeyChecking=no", '-vvv'], #<= -vvv helped much
ctl_dir =>'/tmp/libnet-openssh-perl',
Looks like some permissions issue. Run ssh in verbose mode:
my $ssh = Net::OpenSSH->new("$mach_name",
user => "$user",
passwd => "$passwd",
master_opts => '-vvv',
master_stderr_fh => \*LOG);
If that doesn't give you enough information about the cause of the problem, then, you can use truss to see what's happening at the OS level.
Also check .ssh/known_hosts, make sure .ssh directory is writeable by Apache. .libnet-openssh-perl directory should be writeable by Apache.
For example, my Apache user is apache with a home directory of /var/www
I have /var/www/.ssh owned by apache, and /var/www/.libnet-openssh-perl owned by apache. I ssh to devices using my own account, then copy my known_hosts file to /var/www/.ssh/known_hosts

How do I discover on what server the app.psgi process is running?

Is there a way to discover on what server app.psgi is running?
For example, I am looking for some idea for how to solve the next code fragment from app.psgi:
#app.psgi
use Modern::Perl;
use Plack::Builder;
my $app = sub { ... };
my $server = MyApp::GetServerType(); # <--- I need some idea for how to write this...
given($server) {
when (/plackup/) { ... do something ... };
when (/Starman/) { ... do something other ... };
default { die "Unknown" };
}
$app;
Checking the PLACK_ENV environment variable is not a solution...
Short answer, inspect the caller:
#app.psgi
# use Modern::Perl;
use feature qw(switch say);
use Carp qw(longmess);
use Plack::Builder;
my $app = sub {
return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Hello World' ] ];
};
# This hack gets what we need out of the call stack
my $stack = longmess("Stack:");
# say STDERR $stack;
given($stack) {
when (/plackup/) { say STDERR "Server: plackup" };
when (/Starman/) { say STDERR "Server: starman" };
default { die "Server: Unknown" };
}
return $app;
However, doing this in the app.psgi will make your code less portable. If you die on an unknown server people won't be able to run your code in an unknown location.
Also, be aware that this code may be run multiple times depending on how the server is implemented so any side effects may occur multiple times.
For example, here is the output for plackup:
plackup --app /usr/lusers/bburnett/dev/trunk/getserver.psgi
Server: plackup
HTTP::Server::PSGI: Accepting connections at http://0:5000/
So far so good. But here is the output for starman:
starman --app /usr/lusers/bburnett/dev/trunk/getserver.psgi
2014/02/21-16:09:46 Starman::Server (type Net::Server::PreFork) starting! pid(27365)
Resolved [*]:5000 to [0.0.0.0]:5000, IPv4
Binding to TCP port 5000 on host 0.0.0.0 with IPv4
Setting gid to "15 15 0 0 15 20920 20921 20927"
Server: starman
Server: starman
Server: starman
Server: starman
Server: starman
Here it gets run once for the master and once per child (defaults to four children).
If you really want something different to happen for these different servers a more robust way may be to subclass them yourself and put the code into each subclass passing -s My::Starman::Wrapper to plackup and starman as needed.
If you really want a switch statement and to put the code in one place, you could look into writing some code that calls Plack::Loader or Plack::Runner. Take a look at the source for plackup, and you'll see how it wraps Plack::Runner. Take a look at the source for Plack::Loader, and you'll see how it gets the backend to run and then loads the appropriate server class.

Why can't I connect to my CAS server with Perl's AuthCAS?

I'm attempting to use an existing CAS server to authenticate login for a Perl CGI web script and am using the AuthCAS Perl module (v 1.3.1). I can connect to the CAS server to get the service ticket but when I try to connect to validate the ticket my script returns with the following error from the IO::Socket::SSL module:
500 Can't connect to [CAS Server]:443 (Bad hostname '[CAS Server]')
([CAS Server] substituted for real server name)
Symptoms/Tests:
If I type the generated URL for the authentication into the web browser's location bar it returns just fine with the expected XML snippet. So it is not a bad host name.
If I generate a script without using the AuthCAS module but using the IO::Socket::SSL module directly to query the CAS server for validation on the generated service ticket the Perl script will run fine from the command line but not in the browser.
If I add the AuthCAS module into the script in item 2, the script no longer works on the command line and still doesn't work in the browser.
Here is the bare-bones script that produces the error:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use AuthCAS;
use CGI::Carp qw( fatalsToBrowser );
my $id = $ENV{QUERY_STRING};
my $q = new CGI;
my $target = "http://localhost/cgi-bin/testCAS.cgi";
my $cas = new AuthCAS(casUrl => 'https://cas_server/cas');
if ($id eq ""){
my $login_url = $cas->getServerLoginURL($target);
printf "Location: $login_url\n\n";
exit 0;
} else {
print $q->header();
print "CAS TEST<br>\n";
## When coming back from the CAS server a ticket is provided in the QUERY_STRING
print "QUERY_STRING = " . $id . "</br>\n";
## $ST should contain the received Service Ticket
my $ST = $q->param('ticket');
my $user = $cas->validateST($target, $ST); #### This is what fails
printf "Error: %s\n", &AuthCAS::get_errors() unless (defined $user);
}
Any ideas on where the conflict might be?
The error is coming from the line directly above the snippet Cebjyre quoted namely
$ssl_socket = new IO::Socket::SSL(%ssl_options);
namely the socket creation. All of the input parameters are correct. I had edited the module to put in debug statements and print out all the parameters just before that call and they are all fine. Looks like I'm going to have to dive deeper into the IO::Socket::SSL module.
As usually happens when I post questions like this, I found the problem. It turns out the Crypt::SSLeay module was not installed or at least not up to date. Of course the error messages didn't give me any clues. Updating it and all the problems go away and things are working fine now.
Well, from the module source it looks like that IO::Socket error is coming from get_https2
[...]
unless ($ssl_socket) {
$errors = sprintf "error %s unable to connect https://%s:%s/\n",&IO::Socket::SSL::errstr,$host,$port;
return undef;
}
[...]
which is called by callCAS, which is called by validateST.
One option is to temporarily edit the module file to put some debug statements in if you can, but if I had to guess, I'd say the casUrl you are supplying isn't matching up to the _parse_url regex properly - maybe you have three slashes after the https?