c++ - 带 SSL 的简单 gSoap 服务器和客户端

标签 c++ ssl openssl gsoap

调用 soap_ssl_accept 总是导致错误 SSL23_GET_CLIENT_HELLO:unknown protocol。我通过设置 SOAP_SSL_NO_AUTHENTICATION 使其尽可能简单并关闭了服务器身份验证。我将其分解为以下服务器和客户端代码。你能帮我举个例子吗?

服务器端:

#include <cstdio>
#include "ADService.nsmap" // get namespace bindings
#include "stdsoap2.h"
#include "soapH.h"

int ns1__add(struct soap *soap, xsd__int a, xsd__int b, xsd__int& c) {
    c = a + b;
    return SOAP_OK;
}


int main() {
    int m, s;
    struct soap soap;
    soap_ssl_init(); // init OpenSSL (just once)
    soap_init(&soap);
    if (soap_ssl_server_context(&soap,
        SOAP_SSL_NO_AUTHENTICATION,
        NULL, // keyfile: required when server must authenticate to clients
        NULL, // password to read the key file
        NULL, // optional cacert file to store trusted certificates
        NULL, // optional capath to directory with trusted certificates
        NULL, // DH file name or DH key len bits 
        NULL, // if randfile!=NULL: use a file with random data
        NULL)) {
        soap_print_fault(&soap, stderr);
        exit(1);
    }
    m = soap_bind(&soap, NULL, 18000, 100); // use port 18000
    if (m < 0) {
        soap_print_fault(&soap, stderr);
        exit(1);
    }
    printf("Socket connection successful: master socket = %d\n", m);
    for (;;) {
        s = soap_accept(&soap);
        printf("Socket connection successful: slave socket = %d\n", s);
        if (s < 0) {
            soap_print_fault(&soap, stderr);
            break;
        }
        if (soap_ssl_accept(&soap))
            soap_print_fault(&soap, stderr);
        else
            soap_serve(&soap);
        soap_destroy(&soap);
        soap_end(&soap);
        soap_free(&soap); // done and free context  
    }
    soap_done(&soap); /* deallocates SSL context */
    return 0;
}

客户端:

#include <iostream>
#include "soapH.h" // obtain the generated stub 
#include "ADService.nsmap" // obtain the namespace mapping table 

int main(int argc, const char* argv[]) {
    soap soap;
    soap_ssl_init();
    soap_init(&soap);
    if (soap_ssl_client_context(&soap,
       SOAP_SSL_NO_AUTHENTICATION,
       NULL, // keyfile: required only when client must authenticate to server
       NULL, // password to read the key file (not used with GNUTLS)
       NULL, // cacert file to store trusted certificates
       NULL, // capath to directory with trusted certificates
       NULL  // if randfile!=NULL: use a file with random data to seed randomness
    )) {
       soap_print_fault(&soap, stderr);
       return 1;
    }
    xsd__int result;
    if(soap_call_ns1__add(
        &soap, "localhost:18000", 0, 1, 2, result) != SOAP_OK) {
        soap_print_fault(&soap, stderr);
        soap_print_fault_location(&soap, stderr);
        return 1;
    }
    printf("Result = %d", result);
    soap_destroy(&soap);
    soap_end(&soap);
    soap_done(&soap);
    return 0;
}

服务器端输出:

Socket connection successful: master socket = 1916
Socket connection successful: slave socket = 1912
Error 30 fault: SOAP-ENV:Server [no subcode]
"SSL_ERROR_SSL
error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown > protocol"
Detail: SSL_accept() failed in soap_ssl_accept()
Press any key to continue

最佳答案

这不是一个确定的答案。但可能会有所帮助。我是如何以你所看到的错误结束的:

3077928696:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:628

它发生在与服务器成功建立 TCP 连接时,客户端发送格式错误的 client_hello 消息。我基本上在我的测试中在 TCP 连接后发送了垃圾字节。

捕获 tcpdump b/w 服务器和客户端并查看客户端输出的内容。

关于c++ - 带 SSL 的简单 gSoap 服务器和客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29946807/

相关文章:

ssl - ERR_SSL_VERSION_OR_CIPHER_MISMATCH 从 AWS API 网关到 Lambda

c++ - 指示 OpenSSL 在设置新 BIO 时不要释放 BIO 对象

c++ - 访问冲突读取位置 0x000000004

c# - 从 C# 启动 Debug模式应用程序

c++ - SSL_shutdown() 返回 -1 且 errno 为 0

java - 启用 SSL 的 kafka 配置 : Error : no suitable method found in creating map/configuration

php - 来自 nginx : should the application use it somehow? 的 $ssl_early_data

c++ - 在应用程序中嵌入 SSL key

c++ - 使用回调初始化 vector

C++11 lambda 表达式