How do I get SSL working in fsockopen?

38,533

This may sound obvious, but have you tried this instead?

if ($fp = fsockopen('ssl://'. $host, 443, $errno, $errstr, 30)) {

I'm not sure if the // is required or not, but the ssl and tls examples on the PHP Internet Transports page have them.

P.S. I also have a "thing" about included variables in strings, in case you're wondering why it uses string concatenation now.

Share:
38,533
donok
Author by

donok

I program things in Python. I'm AWS certified. I love Terraform. In the past I've programmed things in C#, Java, PHP, and more.

Updated on September 28, 2020

Comments

  • donok
    donok over 3 years

    I'm running PHP 5.2.6 on Windows, I have extension=php_curl.dll and extension=php_openssl.dll uncommented in php.ini; as such I can see the following in phpinfo:

    curl
    cURL support        enabled
    cURL Information    libcurl/7.16.0 OpenSSL/0.9.8g zlib/1.2.3
    
    openssl
    OpenSSL support     enabled
    OpenSSL Version     OpenSSL 0.9.8g 19 Oct 2007
    

    I'm not sure that having cURL enabled is vital to this, but since it mentioned OpenSSL I thought I'd include it here anyway for completeness.


    What I want to do is simple: make a POST request to another server over SSL using fsockopen.
    My code so far is this:

    $host = 'www.redacted.com';
    $data = 'user=redacted&pass=redacted&action=redacted';
    $response = "";
    
    if ( $fp = fsockopen("ssl:{$host}", 443, $errno, $errstr, 30) ) {
    
        $msg  = 'POST /wsAPI.php HTTP/1.1' . "\r\n";
        $msg .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n";
        $msg .= 'Content-Length: ' . strlen($data) . "\r\n";
        $msg .= 'Host: ' . $host . "\r\n";
        $msg .= 'Connection: close' . "\r\n\r\n";
        $msg .= $data;
        if ( fwrite($fp, $msg) ) {
            while ( !feof($fp) ) {
                $response .= fgets($fp, 1024);
            }
        }
        fclose($fp);
    
    } else {
        $response = false;
    }
    

    This works fine of course if I just pass in $host and use port 80. But I really need to send this over SSL, and right now it's not working. $response gets set to false, $errno stays at 0, and $errstr gets set to php_network_getaddresses: getaddrinfo failed: No such host is known.. I know that it's not an issue of the server being down, or a typo in the host name, etc., because it DOES work if I go over port 80 unsecurely. The problems only start when I try to switch to SSL.

    What do I do to get this working?

  • donok
    donok over 14 years
    Gosh I feel like such an idiot. All it took was this! Thank you so much. And I don't mind the pet peeve about included vs concatenated variables. We all have our quirks.
  • David Spector
    David Spector over 4 years
    This did not work for me in a different application: sending an email. It works when I send insecure and the server accepts insecure sending, but not if I make these changes to the scheme and port. I get an infinite loop.
  • David Spector
    David Spector over 4 years
    Stupid me. My port was 25, so the secure port for email has to be 465, not 443. With this change my code sent an email successfully (with my server set to secured). I have edited this answer.
  • Powerlord
    Powerlord over 4 years
    @DavidSpector For email, it's one of those questions about whether the server supports TLS over SMTP or if it supports SMTPS instead. The former is on port 25 and the latter is on port 465.
  • David Spector
    David Spector over 4 years
    Port 25 (insecure access to a mailserver) should NEVER be used anymore. It exposes your mailserver to compromise by malicious users and provides little or no benefit. I agree with the Let's Encrypt project that the entire Web (and email) should be made secure.