in reply to Re: Client/Server Question
in thread Client/Server Question

Thanks for your reply almut. I think I'm the one that's missed something as I'm completely new to Perl and a bit lost! So I do all of the processing server-side? Can you give me a quick example of how I might, for example, read in a name that someone's entered on the clint side and then check that name against a default name on the server side? I find Perl's syntax very fiddly and all of my attempts to do it so far have resulted in errors and infinite loops galore. Thanks so much for your help.

Replies are listed 'Best First'.
Re^3: Client/Server Question
by almut (Canon) on Mar 07, 2010 at 00:25 UTC

    The general problem with these things is that server and client have to agree on some protocol, i.e. that each party knows how to react in response to what the other side has done.  Here's your example modified to handle name and password checking with dynamic branching on the client side, in case re-entry of name or password is required.

    Server:

    #!/usr/bin/perl -w use strict; use IO::Socket; my $sock = new IO::Socket::INET( LocalHost => 'localhost', LocalPort => 7890, Proto => 'tcp', Listen => SOMAXCONN, Reuse => 1); $sock or die "no socket :$!"; STDOUT->autoflush(1); my $req_name = "Enter Name: \n"; my $req_pass = "Enter Password: \n"; my $req_none = "Enter \n"; sub verify_passw { my ($name, $pass) = @_; # print STDERR "name=$name, pass=$pass\n"; # debug # ... return 1; } while (my $new_sock = $sock->accept()) { my $name = ""; # lifetime is connection my $auth = 0; # ditto (storing state of session) while (<$new_sock>) { /^HELLO$/ and print($new_sock $req_name), next; /^NAME: (\w*)/ and do { $name = $1; if ($name && length($name)<=8) { print $new_sock "Ok, name: $name\n"; print $new_sock $req_pass; } else { print $new_sock "Invalid name: '$name'\n"; print $new_sock $req_name; } next }; /^PASS: (\w*)/ and do { my $pass = $1; if ($auth = verify_passw($name, $pass)) { # =, not == print $new_sock "Login ok\n"; print $new_sock $req_none; } else { print $new_sock "Invalid password!\n"; print $new_sock $req_pass; } next }; /^DATE$/ and print($new_sock scalar(localtime), "\n"), next; print $new_sock "DEFAULT\n"; } close $new_sock; }

    Client:

    #!/usr/bin/perl -w use strict; use IO::Socket; my $host = shift || 'localhost'; my $port = shift || 7890; my $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => $port, Proto => 'tcp'); $sock or die "no socket :$!"; my %handler = ( Name => \&name, Password => \&pass, ); sub show_reply_and_next { do { $_=<$sock>; print unless /Enter $/; } until /^Enter (\w*)/; # $1 holds what to do next if ($handler{$1}) { $handler{$1}->(); } # else just return } sub hello { print $sock "HELLO\n"; show_reply_and_next(); } sub name { my $name = <STDIN>; print $sock "NAME: $name"; show_reply_and_next(); } sub pass { my $pass = <STDIN>; print $sock "PASS: $pass"; show_reply_and_next(); } ### hello(); # initiates login print $sock "DATE\n"; print scalar <$sock>; print $sock "NONE\n"; print scalar <$sock>; close $sock;

    Sample session:

    $ ./827156_client.pl Enter Name: toooooooo_long Invalid name: 'toooooooo_long' Enter Name: Invalid name: '' Enter Name: almut Ok, name: almut Enter Password: foobar Login ok Sun Mar 7 01:10:53 2010 DEFAULT

    It's maybe worth noting that in real life the server should not allow access to any "protected" resources unless the login has successfully been completed. The idea being that a client program with possibly manipulated logic of flow will have no chance to bypass security checks.  This is not implemented so far — the code just sets $auth (which should then be used for subsequent checks).

      Brilliant! Thanks so mch for you help almut. I'll pore over this code later to make sense of it. Thanks also to jethro for your input. You guys are lifesavers.
Re^3: Client/Server Question
by jethro (Monsignor) on Mar 07, 2010 at 00:51 UTC

    If you didn't do the checking on the server side, you would have a big security hole. An attacker could just eliminate any checks in your client program or write his own client without any checking of a password.

    This would be similar to a security guard asking someone who wants to enter: "Do you know the password? Is it the correct one?" and when he gets the answer "Yes and yes" to let him in.