参考gsoap代码中sslclient.c:

int main()
{ struct soap soap;
  double a, b, result;
  /* Init SSL */
  soap_ssl_init(); --------里面调用SSL_library_init,OpenSSL_add_all_algorithms,SSL_load_error_strings,RAND_load_file
  if (CRYPTO_thread_setup()) ------ 用于多线程
  { fprintf(stderr, "Cannot setup thread mutex for OpenSSL\n");
    exit(1);
  }
  a = 10.0;
  b = 20.0;
  /* Init gSOAP context */
  soap_init(&soap); -------- 调用soap_versioning(soap_init)(struct soap *soap, soap_mode imode, soap_mode omode)。调用soap_init_mht,soap_init_logs等。会调用SSL_CTX_new。如果没有调用过soap_ssl_init,里面会调用。

  /* The supplied server certificate "server.pem" assumes that the server is
    running on 'localhost', so clients can only connect from the same host when
    verifying the server's certificate. Use SOAP_SSL_NO_AUTHENTICATION to omit
    the authentication of the server and use encryption directly from any site.
    To verify the certificates of third-party services, they must provide a
    certificate issued by Verisign or another trusted CA. At the client-side,
    the capath parameter should point to a directory that contains these
    trusted (root) certificates or the cafile parameter should refer to one
    file will all certificates. To help you out, the supplied "cacerts.pem"
    file contains the certificates issued by various CAs. You should use this
    file for the cafile parameter instead of "cacert.pem" to connect to trusted
    servers.  Note that the client may fail to connect if the server's
    credentials have problems (e.g. expired). Use SOAP_SSL_NO_AUTHENTICATION
    and set cacert to NULL to encrypt messages if you don't care about the
    trustworthyness of the server.
    Note 1: the password and capath are not used with GNUTLS
    Note 2: setting capath may not work on Windows.
  */
  if (soap_ssl_client_context(&soap, ------------ 设置上下文。
    /* SOAP_SSL_NO_AUTHENTICATION, */ /* for encryption w/o authentication */
    /* SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK, */	/* if we don't want the host name checks since these will change from machine to machine */
    SOAP_SSL_DEFAULT,	/* use SOAP_SSL_DEFAULT in production code */
    NULL, 		/* keyfile (cert+key): required only when client must authenticate to server (see SSL docs to create this file) */
    NULL, 		/* password to read the keyfile */
    "cacert.pem",	/* optional cacert file to store trusted certificates, use cacerts.pem for all public certificates issued by common CAs */
    NULL,		/* optional capath to directory with trusted certificates */
    NULL		/* if randfile!=NULL: use a file with random data to seed randomness */ 
  ))
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  soap.connect_timeout = 60;	/* try to connect for 1 minute */
  soap.send_timeout = soap.recv_timeout = 30;	/* if I/O stalls, then timeout after 30 seconds */
  if (soap_call_ns__add(&soap, server, "", a, b, &result) == SOAP_OK)--------------编译出的soap桩接口
    fprintf(stdout, "Result: %f + %f = %f\n", a, b, result);
  else
    soap_print_fault(&soap, stderr);
  soap_destroy(&soap); /* C++ */
  soap_end(&soap);
  soap_done(&soap);
  CRYPTO_thread_cleanup();
  return 0;
}


sslserver.c:

int main()
{ SOAP_SOCKET m;
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
  pthread_t tid;
#endif
  struct soap soap, *tsoap;
  /* Need SIGPIPE handler on Unix/Linux systems to catch broken pipes: */
  signal(SIGPIPE, sigpipe_handle); -------------- 只有这样,pipe对端断开连接,本端才能接收到EPIPE信号。
  if (CRYPTO_thread_setup())  --- 多线程
  { fprintf(stderr, "Cannot setup thread mutex for OpenSSL\n");
    exit(1);
  }
  /* init gsoap context and SSL */
  soap_init(&soap);  --- 初始化context。里面会调用soap_ssl_init等

  /* The supplied server certificate "server.pem" assumes that the server is
    running on 'localhost', so clients can only connect from the same host when
    verifying the server's certificate.
    To verify the certificates of third-party services, they must provide a
    certificate issued by Verisign or another trusted CA. At the client-side,
    the capath parameter should point to a directory that contains these
    trusted (root) certificates or the cafile parameter should refer to one
    file will all certificates. To help you out, the supplied "cacerts.pem"
    file contains the certificates issued by various CAs. You should use this
    file for the cafile parameter instead of "cacert.pem" to connect to trusted
    servers. Note that the client may fail to connect if the server's
    credentials have problems (e.g. expired).
    Note 1: the password and capath are not used with GNUTLS
    Note 2: setting capath may not work on Windows.
  */
  if (soap_ssl_server_context(&soap,  ------------ server context
    SOAP_SSL_DEFAULT,	/* use SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION to verify clients: client must provide a key file e.g. "client.pem" and "password" */
    "server.pem",	/* keyfile (cert+key): see SSL docs to create this file */
    "password",		/* password to read the private key in the key file */
    "cacert.pem",	/* cacert file to store trusted certificates (to authenticate clients) */
    NULL,		/* capath */
    "dh512.pem",	/* DH file name or DH param key len bits (e.g. "1024"), if NULL use RSA 2048 bits (SOAP_SSL_RSA_BITS) */
    NULL,		/* if randfile!=NULL: use a file with random data to seed randomness */ 
    "sslserver"		/* server identification for SSL session cache (unique server name, e.g. use argv[0]) */
  ))
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  soap.accept_timeout = 60;	/* server times out after 1 minute inactivity */
  soap.send_timeout = soap.recv_timeout = 30;	/* if I/O stalls, then timeout after 30 seconds */
  m = soap_bind(&soap, NULL, 18081, 100);
  if (!soap_valid_socket(m))
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  fprintf(stderr, "Bind successful: socket = %d\n", m);
  for (;;)
  { SOAP_SOCKET s = soap_accept(&soap);
    if (!soap_valid_socket(s))
    { if (soap.errnum)
        soap_print_fault(&soap, stderr);
      else
        fprintf(stderr, "Server timed out (timeout set to %d seconds)\n", soap.accept_timeout);
      break;
    }
    fprintf(stderr, "Socket %d connection from IP %d.%d.%d.%d\n", s, (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
    tsoap = soap_copy(&soap);
    if (!tsoap)
    { soap_closesock(&soap);
      continue;
    }
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
    pthread_create(&tid, NULL, (void*(*)(void*))&process_request, tsoap);
#else
    process_request(tsoap);
#endif
  }
  soap_destroy(&soap);
  soap_end(&soap);
  soap_done(&soap); /* MUST call before CRYPTO_thread_cleanup */
  CRYPTO_thread_cleanup();
  return 0;
} 


void *process_request(struct soap *soap)
{
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
  pthread_detach(pthread_self());
#endif
  if (soap_ssl_accept(soap) != SOAP_OK) ---------- 会调用SSL_new,SSL_accept
  { /* when soap_ssl_accept() fails, socket is closed and SSL data reset */
    soap_print_fault(soap, stderr);
    fprintf(stderr, "SSL request failed, continue with next call...\n");
  }
  else
    soap_serve(soap);
  soap_destroy(soap); /* for C++ */
  soap_end(soap);
  soap_free(soap);
  return NULL;
}







Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐