Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Hello,

I finally switched to POE, It works great for what I need and today I was working in a script with SSL support and works great. Here is the code

#!/usr/bin/perl use warnings; use strict; use POE qw(Component::Server::TCP); use POE::Component::SSLify qw(Server_SSLify SSLify_Options); my @allowed_ips = ('127.0.0.1', '172.16.0.17', '172.16.0.1', '172.1 +6.0.225'); my $listen_address = '172.16.0.224'; my $listen_port = '1337'; my $listen_conns = '-1'; my $listen_alias = 'rc-listener'; my $output = '/home/projects/perl/rc-listener/unknown-commands +.txt'; my $ssl = 1; my $ssl_certfile = '/home/projects/perl/rc-listener/cert.crt'; my $ssl_keyfile = '/home/projects/perl/rc-listener/cert.key'; my $ssl_version = 'default'; POE::Component::Server::TCP->new( # Listen options Address => $listen_address, Port => $listen_port, Concurrency => $listen_conns, Alias => $listen_alias, # Server handlers Error => \&handle_server_error, Started => \&handle_server_started, Stopped => \&handle_server_stopped, # Client handlers ClientPreConnect => \&handle_client_pre_connect, ClientConnected => \&handle_client_connect, ClientDisconnected => \&handle_client_disconnect, ClientInput => \&handle_client_input, ClientError => \&handle_client_error, ClientFlushed => \&handle_client_flushed, ); # Start the server. POE::Kernel->run(); exit 0; sub handle_client_pre_connect { my ($session, $heap, $socket) = @_[SESSION, HEAP, ARG0]; my $session_id = $session->ID; my $remote_ip = $heap->{remote_ip}; my $remote_port = $heap->{remote_port}; my $remote = "[${remote_ip}]:${remote_port}"; unless (client_allowed($remote_ip)){ warn "ERROR > Connection from ${remote} with Session-ID ${sess +ion_id} denied by IP Policy.\n"; return undef; } if($ssl){ eval { SSLify_Options($ssl_keyfile, $ssl_certfile, $ssl_versio +n) }; if($@){ warn "ERROR > Server unable to load key or certificate fil +e.\n"; return undef; } my $ssl_socket = eval { Server_SSLify($socket) }; if($@){ warn "ERROR > Server unable to make an SSL connection.\n"; return undef; } return $ssl_socket; } else { return $socket; } } sub handle_client_connect { my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0]; my $session_id = $session->ID; my $client = $heap->{client}; my $remote_ip = $heap->{remote_ip}; my $remote_port = $heap->{remote_port}; my $remote = "[${remote_ip}]:${remote_port}"; $client->put("Welcome ${remote} your Session-ID is ${session_id}") +; $client->put("Type 'help' for a complete list of accepted commands +"); warn "WARN > Client ${remote} connected with Session-ID ${session +_id}\n"; } sub handle_client_disconnect { my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0]; my $session_id = $session->ID; my $client = $heap->{client}; my $remote_ip = $heap->{remote_ip}; my $remote_port = $heap->{remote_port}; my $remote = "[${remote_ip}]:${remote_port}"; warn "WARN > Client ${remote} with Session-ID ${session_id} disco +nnected\n"; } sub handle_client_input { my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0]; my $session_id = $session->ID; my $client = $heap->{client}; my $remote_ip = $heap->{remote_ip}; my $remote_port = $heap->{remote_port}; my $remote = "[${remote_ip}]:${remote_port}"; if ($input eq "quit") { $client->put("Goodbye ${remote}"); $_[KERNEL]->yield("shutdown"); return; } if ($input eq "ping") { $client->put("pong"); return; } if ($input eq "whoami") { $client->put("Your IP Address is ${remote_ip}"); $client->put("Your port is ${remote_port}"); return; } if ($input eq "help") { $client->put("Really? C'mon, just type something!"); return; } open(my $fh, '>>', $output) or die "Could not open file '$output' +$!"; print $fh "${input}\n"; #$heap->{client}->put("Received input: ".$input); warn "WARN > Client ${remote} Session-ID ${session_id}: ${input}\ +n"; } sub handle_client_error { my ($syscall_name, $err_num, $err_str) = @_[ARG0..ARG2]; warn "ERROR > Client: ${err_num} - ${err_str}\n"; } sub handle_client_flushed { my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0]; my $session_id = $session->ID; my $client = $heap->{client}; my $remote_ip = $heap->{remote_ip}; my $remote_port = $heap->{remote_port}; my $remote = "[${remote_ip}]:${remote_port}"; warn "INFO > Client ${remote} flushed\n"; } sub handle_server_started { warn "INFO > Server [${listen_address}]:${listen_port} started\n" +; } sub handle_server_stopped { warn "INFO > Server [".$listen_address."]:".$listen_port." stoppe +d\n"; } sub handle_server_error { my ($syscall_name, $err_num, $err_str) = @_[ARG0..ARG2]; warn "ERROR > Server: ${err_num} - ${err_str}\n"; } sub client_allowed { my $client_ip = shift; return grep { $_ eq $client_ip || $_ eq '0/0' || $_ eq '0.0.0.0/0' + } @allowed_ips; }

It's working like I want, obviusly still need a lot of work but hey, for now it's working pretty good

Now the next thing I want is to make some authentication mechanism, any hint?

What I was thinking is to save a plain text "database" or a postgresql table with a relation of ip address and token and match each IP address with the token

The database connector and checks it's not the big deal here, what I need is some type of auth in the connect handle or something to not be very database intensive, for example I'm thinking to load the entire table to an array on load the listener and make it "static" and refresh the array every 30 seconds with a subroutine or something

Really this is the "thing" I don't know how to do, what I'm trying to do is to make some bolean variable with the session-id and after first check insert it into the array and on each read/write from the client check it with the array

I'm near to the answer or anyone have another mechanism to achieve this?

Thanks for all, I really appreciate all the comments


In reply to Re: Client-Server app by radu
in thread Client-Server app by radu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-25 13:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found