NAME

    POE::Component::TLSify - Makes using SSL/TLS in the world of POE easy!

VERSION

    version 0.06

SYNOPSIS

      # look at the DESCRIPTION for client and server example code

DESCRIPTION

    This component is a method to simplify the TLSification of a socket
    before it is passed to a POE::Wheel::ReadWrite wheel in your
    application.

    Based on POE::Component::SSLify, instead of directly wrapping
    Net::SSLeay it uses IO::Socket::SSL and has slight differences in API
    as a result.

 Client usage

            # Import the module
            use POE::Component::TLSify qw( Client_TLSify );
    
            # Create a normal SocketFactory wheel and connect to a TLS-enabled server
            my $factory = POE::Wheel::SocketFactory->new;
    
            # Time passes, SocketFactory gives you a socket when it connects in SuccessEvent
            # Convert the socket into a TLS socket POE can communicate with
            my $socket = shift;
            eval { $socket = Client_TLSify( $socket ) };
            if ( $@ ) {
                    # Unable to TLSify it...
            }
    
            # Now, hand it off to ReadWrite
            my $rw = POE::Wheel::ReadWrite->new(
                    Handle  =>   $socket,
                    # other options as usual
            );

 Server usage

            # !!! Make sure you have a public key + certificate
            # excellent howto: http://www.akadia.com/services/ssh_test_certificate.html
    
            # Import the module
            use POE::Component::TLSify qw( Server_TLSify );
    
            # Create a normal SocketFactory wheel to listen for connections
            my $factory = POE::Wheel::SocketFactory->new;
    
            # Time passes, SocketFactory gives you a socket when it gets a connection in SuccessEvent
            # Convert the socket into a SSL socket POE can communicate with
            my $socket = shift;
    
            # Set the key + certificate file options to pass to IO::Socket::SSL
            my $io_socket_ssl_args = {
                SSL_cert_file => 'server.crt',
                SSL_key_file  => 'server.key',
            };
            eval { $socket = Server_TLSify( $socket, $io_socket_ssl_args ) };
            if ( $@ ) {
                    # Unable to TLSify it...
            }
    
            # Now, hand it off to ReadWrite
            my $rw = POE::Wheel::ReadWrite->new(
                    Handle  =>   $socket,
                    # other options as usual
            );

FUNCTIONS

 Client_TLSify

    This function tlsifies a client-side socket. You can pass several
    options to it:

      my $socket = shift;
      $socket = Client_TLSify( $socket, $io_socket_ssl_args, $callback );
    
      $socket is the non-ssl socket you got from somewhere ( required )
      $io_socket_ssl_args is a hashref of IO::Socket::SSL options to pass to that module
      $callback is the callback hook on success/failure of tlsification
    
      # This is an example of the callback and you should pass it as Client_SSLify( $socket, ... , \&callback );
      sub callback {
          my( $socket, $status, $errval ) = @_;
          # $socket is the original sslified socket in case you need to play with it
          # $status is either 1 or 0; with 1 signifying success and 0 failure
          # $errval will be defined if $status == 0; it's whatever IO::Socket::SSL returned from errstr
    
          # The return value from the callback is discarded
      }

    The function uses IO::Socket::SSL start_SSL to start tlsification and
    calls connect_SSL. The hashref of options passed in are passed to
    start_SSL so you can adjust the tlsification to taste, such as adding
    client certificates, etc.

    The callback unlike in POE::Component::SSLify must be the third
    argument. As with POE::Component::SSLify the callback can be a POE
    event, see postback/callback stuff in POE::Session.

 Server_TLSify

    This function sslifies a server-side socket. You can pass several
    options to it:

      my $socket = shift;
      my $io_socket_ssl_args = {
         SSL_cert_file => 'server.crt',
         SSL_key_file  => 'server.key',
      };
      $socket = Server_TLSify( $socket, $io_socket_ssl_args, $callback );
    
      $socket is the non-ssl socket you got from somewhere ( required )
      $io_socket_ssl_args is a hashref of IO::Socket::SSL options to pass to that module
      $callback is the callback hook on success/failure of tlsification

    The function uses IO::Socket::SSL start_SSL to start tlsification and
    calls accept_SSL. The hashref of options passed in are passed to
    start_SSL so you can adjust the tlsification to taste. At a minimum for
    a server you will require a certificate and key that should be passed
    with the SSL_cert_file and SSL_key_file options.

    Please look at "Client_SSLify" for more details on the callback hook.

 TLSify_GetSocket

    Returns the actual IO::Socket::SSL socket used by the TLSified socket,
    useful for stuff like getpeername()/getsockname()

      print "Remote IP is: " . inet_ntoa( ( unpack_sockaddr_in( getpeername( SSLify_GetSocket( $sslified_sock ) ) ) )[1] ) . "\n";

    and all the other methods that IO::Socket::SSL provides.

 TLSify_GetCipher

    Returns the cipher used by the TLSified socket

       print "SSL Cipher is: " . TLSify_GetCipher( $tlsified_sock ) . "\n";

    NOTE: Doing this immediately after Client_TLSify or Server_TLSify will
    result in "(NONE)" because the SSL handshake is not done yet. The
    socket is nonblocking, so you will have to wait a little bit for it to
    get ready.

NOTES

 Certificate Verification

    POE::Component::SSLify did not do certificate validation and
    verification. IO::Socket::SSL does by default. It would be useful to
    make yourself aware of this default behaviour and check out the
    documentation for the following options SSL_verify_mode,
    SSL_verify_callback and SSL_ocsp_mode.

 Socket methods doesn't work

    The new socket this module gives you actually is tied socket magic, so
    you cannot do stuff like getpeername() or getsockname(). The only way
    to do it is to use "TLSify_GetSocket" and then operate on the
    IO::Socket::SSL socket it returns.

 Dying to meet you ...

    This module will die() if TLSification process fails. So, it is
    recommended that you check for errors and not use SSL, like so:

       eval { use POE::Component::TLSify };
       if ( $@ ) {
         $sslavailable = 0;
       }
       else {
         $sslavailable = 1;
       }
    
       # Make socket SSL!
       if ( $sslavailable ) {
         eval { $socket = POE::Component::TLSify::Client_TLSify( $socket ) };
         if ( $@ ) {
            # Unable to TLSify the socket...
         }
       }

 IO::Socket::SSL methods

    The underlying socket is a IO::Socket::SSL so you may use any of the
    supported methods on the socket object. Use "TLSify_GetSocket" to
    retrieve that object.

 Upgrading a non-ssl socket to SSL

    You can have a normal plaintext socket, and convert it to TLS anytime.
    Just keep in mind that the client and the server must agree to tlsify
    at the same time, or they will be waiting on each other forever!

 Downgrading a SSL socket to non-ssl

    As of now this is unsupported. If you need this feature please let us
    know and we'll work on it together! In theory IO::Socket::SSL does
    provide a stop_SSL method, so this should be possible.

ACKNOWLEDGEMENTS

      Original POE::Component::SSLify:
    
      Original code is entirely Rocco Caputo ( Creator of POE ) -> I (APOCAL) simply
      packaged up the code into something everyone could use and accepted the burden
      of maintaining it :)
    
      POE::Component::TLSify is based on POE::Component::SSLify, I (BINGOS) simply
      ported the code to use IO::Socket::SSL instead of using Net::SSLeay
    
      Thanks also to Paul Evans (PEVANS), the IO::Async author, whose IO::Async::SSL
      provided inspiration for using IO::Socket::SSL

AUTHORS

      * Chris Williams <chris@bingosnet.co.uk>

      * Apocalypse <APOCAL@cpan.org>

COPYRIGHT AND LICENSE

    This software is copyright (c) 2020 by Chris Williams, Apocalypse.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

