2016-11-19 4 views
0

Ich habe dieses einfache Programm:OpenSSL segfault

int main() 
{ 
     /* INITIALIZING OPENSSL */ 
     SSL_library_init();   
     SSL_load_error_strings(); 
     ERR_load_BIO_strings(); 
     OpenSSL_add_all_algorithms(); 

     BIO *bio; 
     connectServerSSL(bio); 
     login(bio); 
} 

Und diese Funktionen:

void connectServerSSL (BIO *bio) 
{ 
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); 
    SSL * ssl; 

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs")) 
    { 
     callError(ERR_LOADCERT); 
    } 

    bio = BIO_new_ssl_connect(ctx); 
    BIO_get_ssl(bio, &ssl); 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 

    BIO_set_conn_hostname(bio, hostnamePort); 
    if(BIO_do_connect(bio) <= 0) 
    { 
     callError(ERR_CONNECTION); 
    } 

    if(SSL_get_verify_result(ssl) != X509_V_OK) 
    { 
     callError(ERR_VALIDCERT); 
    } 
} 

Als ich diese verwenden:

BIO_write (bio, request.c_str(), request.size())

In f Verbindung conneServerSSL funktioniert es OK.

Aber wenn ich es in einer anderen Funktion verwenden möchten:

void login (BIO *bio) 
{ 
    BIO_write(bio, request.c_str(), request.size()); 
} 

I Segmentation fault bekommen (core dumped).

+2

Sie sind nicht Ihre 'bio' von' connectServerSSL' zurückzukehren. – tkausl

+0

Wie kann ich das bitte machen? –

Antwort

0

In C und C++ werden gerade Zeiger als Wert übergeben. So müssen Sie entweder den Parameter von connectServerSSL auf eine Bio verändern * & oder auch neu zu definieren es im C-Stil der Dinge:

void connectServerSSL (BIO ** bio_ptr) 
{ 
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); 
    SSL * ssl; 

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs")) 
    { 
     callError(ERR_LOADCERT); 
    } 

    BIO * bio = BIO_new_ssl_connect(ctx); 
    BIO_get_ssl(bio, &ssl); 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 

    BIO_set_conn_hostname(bio, hostnamePort); 
    if(BIO_do_connect(bio) <= 0) 
    { 
     callError(ERR_CONNECTION); 
    } 

    if(SSL_get_verify_result(ssl) != X509_V_OK) 
    { 
     callError(ERR_VALIDCERT); 
    } 
    *bio_ptr = bio; 
} 

// Example usage: 

void example() 
{ 
    BIO * bio; 
    connectServerSSL(&bio); 
    BIO_write(bio, request.c_str(), request.size()); 
} 
0

Ihre connectServerSSL() Funktion hat einen Parameter bio, und es schreibt nur auf diese temporäre Variable, nicht auf die bio Variable in main(), die nicht initialisiert ist benannt.

Ändern Sie die Signatur von connectServerSSL() in BIO* connectServerSSL(void) und rufen Sie sie unter bio = connectServerSSL() an. Sie könnten die Funktion auch mit einem BIO** newbio Argument aufrufen, es mit,aufrufen und *newbio setzen, wodurch die bio Variable in main() aktualisiert wird.

Einige gute Angewohnheiten, um Fehler wie diese zu vermeiden: Initialisieren Sie Ihre Variablen auf Standardwerte, verwenden Sie Assertions, um zu überprüfen, ob Ihre Eingaben gültig sind, und Einzelschritt in einem Debugger. Wenn Sie die Variable in main() zu BIO* bio = NULL oder noch besser BIO* const bio = connectServerSSL() initialisiert hätten, wäre es im Debugger offensichtlich gewesen, dass sie bei der Rückkehr noch nicht initialisiert war.