Guntherssl has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I'm having an issue that has cost me hours of testing. Please help. What I am trying to do; Connect raw to a site using openssl like this: openssl s_client -connect site:sslport That works great. When it connects, I can see the exchange and I am left with a blank STDIN. I type <ping> and receive a <pong> back. I have tried to reproduce this in perl and have been unable to do so. I faced this issue before and used IO::S::SSL to get me by. However, I'd really like to watch each part manually and interact with it live. In perl, I am able to use something like:

#!/usr/bin/perl $r = exec("openssl s_client -connect site:sslport"); print $r;
or
#!/usr/bin/perl open(FH,"-|","openssl s_client -connect site:sslport"); while(<FH>){ print $_; } close(FH);
However, whenever I try to add
print FH "<ping>";
or
print(FH, "<ping>");
Nothing happens. It stays at the regular STDIN as if I executed it on terminal and accepts ping the same way. I would love some help to achieve sending the ping programmatically while openssl is open and staying open. As I would like to then capture the PONG and do other interactive send and captures. Someone, please guide me. Thank you. PS: I am using perl5 and I'm able to install any module. Sorry for any typing mistakes, my phone works as good as my perl. Thanks again, Gunther

Replies are listed 'Best First'.
Re: Interactive openssl raw
by haukex (Archbishop) on Dec 06, 2016 at 11:59 UTC

    Hi Guntherssl,

    From exec:

    The exec function executes a system command and never returns; use system instead of exec if you want it to return.

    If you Use strict and warnings, normally Perl warns you about this (although not in the code you showed, as you're not using exec in void context).

    However, to communicate with a subprocess interactively, exec/system is not the right thing, the best way to go is use a module like IPC::Run or perhaps Expect.

    Lastly, you don't necessarily need to shell out to openssl for this, I don't see how IO::Socket::SSL would prevent you from "watch each part manually and interact with it live".

    Hope this helps,
    -- Hauke D

      That's my fault, I posted exec as that was my last test live. I had tried backticks, system and exec. I recall last time I attempted this I was going after the IPC2/3 modules without success. I have not or did not notice IPC::Run itself. I shall give that a look when I get home.

      I understand that not liking io::socket::SSL is just a personal choice. Until I understand perl better, I want to stay away from sysread and I was "forced" to use that with IO::S::SSL. Doing multiple handles without threading knowledge, sysread would read whatever was on the buffer. And the buffer itself would cause me issues for size and I spent more time dealing with it than I cared to. </p

      It comes down to, using openssl raw in terminal, I'm able to do everything i want in about 25 seconds. Using io:s:SSL, it takes me a lot longer and I spend time troubleshooting all types of noon bugs. That's why I was hoping to pipe in and out directly to openssl. I'll check out IPC again when I'm home.

      Thanks.

        Hi Guntherssl,

        Sure, Perl is a glue language and there's nothing inherently wrong with shelling out to other programs. There are just several things one has to watch out for, and people get these things wrong quite often. For example: knowing how to avoid issues with quoting command line arguments (such as knowing how to avoid the shell altogether), this includes potential security issues caused by interpolating Perl variables into the shell commands; correctly communicating with the subprocess including feeding it STDIN, capturing its STDOUT, and evaluating its exit code for success or failure; forgetting that the subprocess might write things to STDERR that might be relevant to capture; trying to use things like backticks/system when it's not appropriate and one should use modules instead; and lastly that many things are simply much more efficient with Perl builtins (a few examples of very many: `ls ...` vs. glob, or shelling out to sed or awk). So if you keep all that in mind, feel free to try out IPC::Run :-)

        Regards,
        -- Hauke D

        Update: Reduced wordiness slightly.