Why is this password check not working as expected? - perl

I am trying to expand from php. Here is a basic problem I have and can not figure it out...
password.pl
#!/usr/bin/perl
use CGI;
$q = new CGI;
print "Content-type:text/html\r\n\r\n";
print '<html>';
print '<head>';
print '<title>Card</title>';
print '</head>';
print '<body>';
print '<FORM METHOD=POST ACTION=/card.pl>';
print '<INPUT TYPE=password NAME=password SIZE=25>';
print '<input type=submit value=Submit>';
print '</FORM>';
print '</body>';
print '</html>';
1;
card.pl
#!/usr/bin/perl
use CGI;
$q = new CGI;
$password = $q->param("password");
print $password;
if ($password == pass)
{
print 'Yup';
}
else
{
print 'Wrong Password';
}
1;
Nothing is passing to card.pl from the password.pl form? I have used a simular example before with no problem?
More coffee...

use strict;, use warnings; and look in your error logs. Also validate your HTML.
Then you'll be alerted to problems like:
Bareword "pass" not allowed while "strict subs" in use at card.pl line 7.
You probably want:
($password eq 'pass')

In my continuing quest to disabuse the abuse of CGI.pm, your first script would be much better as–
use strict;
use warnings;
use CGI qw( :standard );
print
header(),
start_html("O HAI CARD"),
start_form(-action => "card.pl"),
fieldset(
legend("None Shall Pass!"),
password_field(-name => "password",
-size => 25),
submit(-value => "Submit"),
),
end_form(),
end_html();
Your second as, perhaps, just for example, et cetera–
use strict;
use warnings;
use CGI;
my $q = CGI->new;
print
$q->header,
$q->start_html("O HAI CARD");
my $password = $q->param("password");
if ( $password eq "pass" )
{
print $q->h2("You're all good");
}
else
{
print $q->h2({-style => "color:#a00"},
"You're all good");
}
print $q->end_html();
Or, maybe better, all together–
use strict;
use warnings;
no warnings "uninitialized";
use CGI qw( :standard );
print
header(),
start_html("O HAI CARD");
print param("password") eq "pass" ?
h2("Yes!") : h2({-style => "color:#a00"}, ":(");
print
start_form(),
fieldset(
legend("None Shall Pass!"),
password_field(-name => "password",
-size => 25),
submit(-value => "Submit"),
),
end_form(),
end_html();
RIF, read the docs: CGI.

Related

issues with CGI::Minimal

My existing code works fine with vanilla cgi
#!/usr/bin/env perl
use strict;
use CGI;
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use CGI::Session;
my ( $session, $cgi);
$cgi = new CGI();
$cgi->charset('UTF-8');
$session = new CGI::Session( "driver:File;serializer:Storable",
$cgi, { Directory => '../home/tmp' } );
$session->expire( 'authorized', '1440m' );
changing over to CGI::Minimal causes CGI::Session to error out
#!/usr/bin/env perl
use strict;
use CGI::Minimal;
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use CGI::Session;
my ( $session, $cgi);
my $cgi = CGI::Minimal->new;
$session = new CGI::Session( "driver:File;serializer:Storable",
$cgi, { Directory => '../web/tmp' } ) or or die CGI::Session->errstr();
$session->expire( 'authorized', '1440m' );
The error
Can't call method "expire" on an undefined value at /var/webserver/iris/htdocs/index.cgi line 13.
Edit: after or die CGI::Session->errstr() is added
new(): failed: query object CGI::Minimal=HASH(0x9916a64) does not support cookie() and param() methods:
Not really sure what causes this, really appreciate any insight.
Since CGI::Minimal is indeed rather minimal you'd have to handle Cookies yourself and pass the manually retrieved session_id, instead of the cgi object, to the CGI::Session constructor.
use warnings;
use strict;
use CGI::Cookie;
use CGI::Minimal;
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use CGI::Session;
my $cgi = CGI::Minimal->new();
my %cookies = CGI::Cookie->fetch;
my $session_id;
if( defined $cookies{'SESSION_ID'} ){
$session_id = $cookies{'SESSION_ID'}->value;
}
my $session = CGI::Session->new(
"driver:File;serializer:Storable",
$session_id,
{ Directory => '../web/tmp' }
) or die CGI::Session->errstr();
$session->expire( 'authorized', '1440m' );
my $session_cookie = CGI::Cookie->new(-name => 'SESSION_ID',-value => $session->id());
print $session->header(-cookie=>[$session_cookie]);
print 'ok with session_id: ' . $session->id();

Passing Variable with redirect in cgi/perl

I have two cgi script. Login.cgi and welcome.cgi
I want to pass variable between these two pages
Here are the two pages i have
#!C:/Perl/bin/perl.exe -w
#login.cgi
use strict;
use warnings;
use CGI::Pretty qw(:all);
my $cgi = new CGI;
my $username = $cgi->param('username');
my $password = $cgi->param('password');
if ( ( $cgi->param('username') eq 'demo' ) && ( $cgi->param('password') eq 'demo' ) ) {
print $cgi->redirect("welcome.cgi");
}
else {
print header();
print start_html( -title => "Login" );
if ( $cgi->param('username') or $cgi->param('password') ) {
print center( font( { -color => 'red' }, "Invalid input" ) );
}
print generate_form();
print end_html();
}
sub generate_form {
return start_form,
h1("Please Login"),
p( "username", textfield('username') ),
p( "password", textfield('password') ), p(submit),
end_form;
}
Another page welcome.cgi
#!C:/Perl/bin/perl.exe -w
#welcome.cgi
use warnings;
use CGI::Pretty qw(:all);
use strict;
my $cgi=new CGI;
my $username;
print header();
print start_html("Welcome"),h1("Hello, $username");
print end_html();
How do I get the username variable passed to welcome.cgi?
use CGI::Session.
For a tutorial on all the different ways to pass information between scripts and why this implementation is a good choice, read CGI::Session::Tutorial
Implemented in your login script:
#login.cgi
use strict;
use warnings;
use CGI::Pretty qw(:all);
use CGI::Session;
my $cgi = new CGI;
my $session = CGI::Session->new($cgi) or die CGI->Session->errstr;
my $username = $cgi->param('username') // '';
my $password = $cgi->param('password') // '';
if ( $username eq 'demo' && $password eq 'demo' ) {
$session->param(username => $username);
print $cgi->redirect("welcome.cgi");
exit;
}
print $session->header();
print start_html( -title => "Login" );
if ( $username or $cgi->param('password') ) {
print center( font( { -color => 'red' }, "Invalid input" ) );
}
print start_form,
h1("Please Login"),
p( "username", textfield('username') ),
p( "password", textfield('password') ), p(submit),
end_form,
end_html();
And in your welcome script:
#welcome.cgi
use strict;
use warnings;
use CGI::Pretty qw(:all);
use CGI::Session;
my $cgi = new CGI;
my $session = CGI::Session->new($cgi) or die CGI->Session->errstr;
my $username = $session->param('username');
print header();
print start_html("Welcome"),h1("Hello, $username");
print end_html();
You can either pass it directly (by encoding it in a query string and adding that to the URL you are redirecting to) or you can store it in a cookie or a session and then retrieve it in the other script.
I would have to slightly disagree with Mr.Miller here. CGI::Session is at present outdated in many regards especially due to:
The method to set cookies is outdated, and does not adhere to the RFC6265
The Cookie ID algorithm is not secure enough, the author has moved on to other projects.
And thus should not be used unless for educational purposes.
With regards to the original question, you can look at this simple tutorial
http://practicalperl5.blogspot.in/2014/07/perl-login-script.html

Perl - How to solve the trouble with encoding in windows console?

Trying to use russian lettaz and console acts like a donkey, because does not react on use utf8/utf-8 or cp1251 directives.
What the encoding of the text marked by red colour I don't know.
Anybody knows how to solve that ? Code listing below:
#!/usr/bin/perl -w
use strict;
use warnings;
use Tie::IxHash;
tie my %hash, "Tie::IxHash";
%hash = (
'шляпа' => 'серая',
'водка' => 'горькая',
'вобла' => 'вкусная');
print "В упорядоченной вставке список хеша такой:\n";
foreach my $qwerty (keys %hash){
print " $qwerty\n";
}
print "Кроме того, предметы обладают некоторыми свойствами:\n";
while((my($predmet, $opredelenie)) = each %hash){
print "$predmet $opredelenie","\n";
}
You need to specify STDOUT encoding. This script is utf-8 encoded:
use strict;
use warnings;
#use Tie::IxHash;
use utf8;
binmode STDOUT, ":encoding(cp866)";
my %hash = (
'шляпа' => 'серая',
'водка' => 'горькая',
'вобла' => 'вкусная'
);
print "В упорядоченной вставке список хеша такой:\n";
foreach my $qwerty ( keys %hash ) {
print " $qwerty\n";
}
print "Кроме того, предметы обладают некоторыми свойствами:\n";
while ( ( my ( $predmet, $opredelenie ) ) = each %hash ) {
print "$predmet $opredelenie", "\n";
}

How to search a string in web page and print that full line in which search string is present?

I'm new to programming, learning perl as well.
Here's my question: How do I search a string in web page and print that full line in which search string is present?
Is it possible to find/hit directly that string and then print that full line in which search string is present? Do we need to use xpaths compulsory for this?
If it is just a very basic string you are looking for you can use LWP::Simple and a small regular expression like this:
use LWP::Simple;
my $doc = get('http://stackoverflow.com/q/11771655/479133') || die "GET failed";
foreach my $line (split("\n", $doc)) {
print $line and last if $line =~ m/Here's my query/;
}
There are countless modules available on CPAN to do such things. Have a look at Task::Kensho::WebCrawling if you need something "bigger".
LWP::UserAgent and HTML::Parser can be used:
#!/usr/bin/env perl
use strict;
use warnings;
use HTML::Parser;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
my $response = $ua->get('http://search.cpan.org/');
if ( !$response->is_success ) {
print "No matches\n";
exit 1;
}
my $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
$parser->parse( $response->decoded_content );
sub text_handler {
chomp( my $text = shift );
if ( $text =~ /language/i ) {
print "Matched: $text\n";
}
}

how to get POST values in perl

I am trying to customize a script and need to get a POST value from a form using perl.
I have no background of perl but this is a fairly simple thing so I guess it should not be hard.
This is the php version of the code I would like to have in PERL:
<?php
$download = ($_POST['dl']) ? '1' : '0';
?>
I know this may not be at all related to the PERL version but it could help I guess clarifying what exactly I am looking to do.
Well, in that case please have a look at this simple code: This would help you:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
sub output_top($);
sub output_end($);
sub display_results($);
sub output_form($);
my $q = new CGI;
print $q->header();
# Output stylesheet, heading etc
output_top($q);
if ($q->param()) {
# Parameters are defined, therefore the form has been submitted
display_results($q);
} else {
# We're here for the first time, display the form
output_form($q);
}
# Output footer and end html
output_end($q);
exit 0;
# Outputs the start html tag, stylesheet and heading
sub output_top($) {
my ($q) = #_;
print $q->start_html(
-title => 'A Questionaire',
-bgcolor => 'white');
}
# Outputs a footer line and end html tags
sub output_end($) {
my ($q) = #_;
print $q->div("My Web Form");
print $q->end_html;
}
# Displays the results of the form
sub display_results($) {
my ($q) = #_;
my $username = $q->param('user_name');
}
# Outputs a web form
sub output_form($) {
my ($q) = #_;
print $q->start_form(
-name => 'main',
-method => 'POST',
);
print $q->start_table;
print $q->Tr(
$q->td('Name:'),
$q->td(
$q->textfield(-name => "user_name", -size => 50)
)
);
print $q->Tr(
$q->td($q->submit(-value => 'Submit')),
$q->td(' ')
);
print $q->end_table;
print $q->end_form;
}
Style advice: you almost never need to assign 0 or 1 to a variable. Simply evaluate the value itself in bool context.
In CGI.pm (CGI), the param method merges POST and GET parameters, so we need to inspect the request method separately:
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use CGI qw();
my $c = CGI->new;
print $c->header('text/plain');
if ('POST' eq $c->request_method && $c->param('dl')) {
# yes, parameter exists
} else {
# no
}
print 'Do not taunt happy fun CGI.';
With Plack::Request (PSGI), you have different methods for POST (body_parameters) and GET (query_parameters) in addition to the mixed interface (parameters):
#!/usr/bin/env plackup
use strict;
use warnings FATAL => 'all';
use Plack::Request qw();
my $app = sub {
my ($env) = #_;
my $req = Plack::Request->new($env);
if ($req->body_parameters->get_all('dl')) {
# yes
} else {
# no
}
return [200, [Content_Type => 'text/plain'], ['Do not taunt happy fun Plack.']];
};
Here's a good place to start: The Fool's Guide to CGI.pm,
the Perl module for CGI scripting.
This will show you "...how to get the POST value (from a submitted form) and assign it to a variable."
Hope this helps!
The above examples are bit complicated. The below code reads POST values into a variable. You can extract Key Value from that. If its GET then its better to use CGI module.
#!/usr/bin/perl
my $FormData = '';
read(STDIN, $FormData, $ENV{'CONTENT_LENGTH'});
## Variable $FormData holds all POST values passed
use CGI;
my $cgi = new CGI;
print $cgi->header();
print "$FormData";