2012-02-20 106 views
1

我發現這個源碼在網絡上浮動,我希望有人可以解決爲什麼這個程序只是關閉而不是偵聽連接。這個源打算打開服務器套接字,但是,不。OpenSSL,RSA和Winsock和C++

#include <openssl/bio.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 

#include <iostream> 
#include <stdio.h> 
#include <winsock2.h> 

#define PASSWORD "passme" 

int main(int argc, char** argv) 
{ 
    CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use 
    SSL_library_init(); // Initialize OpenSSL's SSL libraries 
    SSL_load_error_strings(); // Load SSL error strings 
    ERR_load_BIO_strings(); // Load BIO error strings 
    OpenSSL_add_all_algorithms(); // Load all available encryption algorithms 

    return 0; 
} 

void serverThread() 
{ 
    // First, we need to initialize Winsock. 
    WSADATA wsadata; 
    int ret = WSAStartup(0x101, &wsadata); 
    if (ret != 0) { 
     printf("WSAStartup() failed with: %d!\n", GetLastError()); 
     return; 
    } 

    // Next we need to create a server socket. 
    SOCKET server = socket(AF_INET, SOCK_STREAM, 0); 
    sockaddr_in sockaddrin; 
    // Internet socket 
    sockaddrin.sin_family = AF_INET; 
    // Accept any IP 
    sockaddrin.sin_addr.s_addr = INADDR_ANY; 
    // Use port 6789 
    sockaddrin.sin_port = htons(6789); 

    // Valid socket? 
    if (server == INVALID_SOCKET) { 
     printf("Error creating server socket!"); 
     return; 
    } 

    // Now bind to the port 
    ret = bind(server, (sockaddr*) &(sockaddrin), sizeof(sockaddrin)); 
    if (ret != 0) { 
     printf("Error binding to port!\n"); 
     return; 
    } 

    // Start listening for connections 
    // Second param is max number of connections 
    ret = listen(server, 50); 
    if (ret != 0) { 
     printf("Error listening for connections!\n"); 
     return; 
    } 

    // Set up to accept connections 
    SOCKET client; 
    sockaddr_in clientsockaddrin; 
    int len = sizeof(clientsockaddrin); 
    printf("Server ready to accept connections!\n"); 

    while (1) { 
     // Block until a connection is ready 
     client = accept(server, (sockaddr*) &clientsockaddrin, &len); 
     printf("Connection recieved from %s!\n", inet_ntoa(clientsockaddrin.sin_addr)); 

     // Notice that we use server_method instead of client_method 
     SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); 
     BIO* bio = BIO_new_file("dh1024.pem", "r"); 
     // Did we get a handle to the file? 
     if (bio == NULL) { 
      printf("Couldn't open DH param file!\n"); 
      break; 
     } 

     // Read in the DH params. 
     DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 
     // Free up the BIO object. 
     BIO_free(bio); 
     // Set up our SSL_CTX to use the DH parameters. 
     if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) { 
      printf("Couldn't set DH parameters!\n"); 
      break; 
     } 

     // Now we need to generate a RSA key for use. 
     // 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096. 
     RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL); 

     // Set up our SSL_CTX to use the generated RSA key. 
     if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) { 
      printf("Couldn't set RSA key!\n"); 
      // We don't break out here because it's not a requirement for the RSA key to be set. It does help to have it. 
     } 
     // Free up the RSA structure. 
     RSA_free(rsa); 

     SSL_CTX_set_cipher_list(ctx, "ALL"); 
     // Set up our SSL object as before 
     SSL* ssl = SSL_new(ctx); 
     // Set up our BIO object to use the client socket 
     BIO* sslclient = BIO_new_socket(client, BIO_NOCLOSE); 
     // Set up our SSL object to use the BIO. 
     SSL_set_bio(ssl, sslclient, sslclient); 

     // Do SSL handshaking. 
     int r = SSL_accept(ssl); 
     // Something failed. Print out all the error information, since all of it may be relevant to the problem. 
     if (r != 1) { 
      printf("SSL_accept() returned %d\n", r); 
      printf("Error in SSL_accept(): %d\n", SSL_get_error(ssl, r)); 
      char error[65535]; 
      ERR_error_string_n(ERR_get_error(), error, 65535); 
      printf("Error: %s\n\n", error); 
      ERR_print_errors(sslclient); 
      int err = WSAGetLastError(); 
      printf("WSA: %d\n", err); 
      break; 
     } 
    } 
} 

int password_callback(char* buffer, int num, int rwflag, void* userdata) 
{ 
    if (num < (strlen(PASSWORD) + 1)) { 
     return(0); 
    } 
    strcpy(buffer, PASSWORD); 
    return strlen(PASSWORD); 
} 

int verify_callback(int ok, X509_STORE_CTX* store) 
{ 
    char data[255]; 

    if (!ok) { 
     X509* cert = X509_STORE_CTX_get_current_cert(store); 
     int depth = X509_STORE_CTX_get_error_depth(store); 
     int err = X509_STORE_CTX_get_error(store); 

     printf("Error with certificate at depth: %d!\n", depth); 
     X509_NAME_oneline(X509_get_issuer_name(cert), data, 255); 
     printf("\tIssuer: %s\n", data); 
     X509_NAME_oneline(X509_get_subject_name(cert), data, 255); 
     printf("\tSubject: %s\n", data); 
     printf("\tError %d: %s\n", err, X509_verify_cert_error_string(err)); 
    } 

    return ok; 
} 

回答

0

你永遠不啓動主

+0

的ServerThread你能解釋一下如何啓動ServerThread?對不起,如果我的聲音N00bish – Confident 2012-02-20 10:53:40

+0

我應該只是調用函數? – Confident 2012-02-20 10:55:35

+0

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx用lpStartAddress作爲ServerThread,或者你可以在main結束之前調用它(因爲你這樣做沒有其他主要的) – Ofir 2012-02-20 10:56:57