Search code examples
sslopensslgsoap

gSOAP: No socket in soap_ssl_accept()


I am trying to setup an example gSOAP server with SSL. I created a self signed certificate as this:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

Then joined the certificates to one file:

cat cert.pem key.pem >both.pem

And then run this code:

#include <stdsoap2.h>
#include <stdexcept>
#include <sstream>
#include <iostream>

#define PORT 6667

int main(int argc, char **argv) {
    struct soap engine(SOAP_C_UTFSTRING);
    engine.bind_flags=SO_REUSEADDR;

    soap_ssl_noinit();

    int rc = soap_ssl_server_context(&engine,
            SOAP_SSL_DEFAULT,
            "both.pem", // keyfile
            nullptr, // password
            nullptr, // cacert
            nullptr, // capath
            nullptr, // dhfile
            nullptr, // randfile
            nullptr  // serverid
    );

    if (rc) {
            std::stringstream error;
            soap_stream_fault(&engine, error);
            throw std::runtime_error("soap_ssl_server context failed " + error.str());
    }

    rc = soap_bind(&engine, NULL, PORT, 100);
    if (rc < 0) {
            throw std::runtime_error("soap_bind failed " + std::to_string(rc));
    }

    int master_socket = rc;
    std::cout << "master socket: " << master_socket << std::endl;

    engine.accept_timeout = 50;
    engine.send_timeout = 50;
    engine.recv_timeout = 50;

    rc = soap_ssl_accept(&engine);
    if (rc) {
            soap_stream_fault(&engine, std::cout);
            throw std::runtime_error("soap_ssl_accept failed " + std::to_string(rc));
    }
    std::cout << "soap_ssl_accept " << rc << std::endl;

    return 0;
}

But I get this output:

master socket: 3
Error 30 fault detected[no subcode]
"SSL/TLS error"
Detail: No socket in soap_ssl_accept()
terminate called after throwing an instance of 'std::runtime_error'
  what():  soap_ssl_accept failed 30

What am I doing wrong?


Solution

  • I figured it out. One must call soap_accept before calling soap_ssl_accept. The correct code is:

        rc = soap_accept(&engine);
        if (rc) {
                soap_stream_fault(&engine, std::cout);
                throw std::runtime_error("soap_accept failed " + std::to_string(rc));
        }
    
        rc = soap_ssl_accept(&engine);
        if (rc) {
                soap_stream_fault(&engine, std::cout);
                throw std::runtime_error("soap_ssl_accept failed " + std::to_string(rc));
        }
    

    and then the error is fixed.