2017-02-16 13 views
17

Ich arbeite an einem Projekt, wo ich Port-Weiterleitung an MySQL mit libssh2 in C++ bin. Ich habe es funktioniert für Benutzername/Passwort-Authentifizierung, aber ich will es jetzt mit öffentlichen/privaten Schlüssel Authentifizierung tun. Die Dokumentation für libssh2 ist ziemlich dürftig, daher habe ich Schwierigkeiten herauszufinden, was ich tun muss.SSH Public Key Authentifizierung mit Libssh2 C++

Was ich versuche zu tun ist, eine Android-App Daten in meine C++ App zu veröffentlichen, wo C++ die SSH-Details zusammen mit dem Auth-Schlüssel gegeben wird und es den SSH-Tunnel erstellt. C++ bekommt den Schlüssel gut und dann mache ich folgendes um die Public Key Authentifizierung zu machen.

else if (this->getAuthMethod() == SupportedAuthMethods::AUTH_PUBLICKEY) 
    { 

     string test = this->getSSHPrivateKey(); 

     boost::replace_all(test, "\n", ""); 

     unsigned char * key = (unsigned char *)test.c_str(); 

     size_t sizeofkey = strlen((char*)key); 
     cout << key << endl; 
     stringstream logstream; 
     logstream << "Using public key authentication for SSH Host: " << this->getSSHHostnameOrIPAddress(); 
     this->bitsLibrary->writeToLog(logstream.str(), "SSHTunnelForwarder", "authenticateSSHServer"); 
     if (chosenAuthMethod & SupportedAuthMethods::AUTH_PUBLICKEY) 
     { 
      //int result = 0; 
      int result = libssh2_userauth_publickey(this->session, this->getUsername().c_str(), key, sizeofkey, SSHTunnelForwarder::publicKeyAuthComplete, 0); 
      if (result != 0) 
      { 
       char * error = NULL; 
       int len = 0; 
       int errbuf = 0; 
       libssh2_session_last_error(this->session, &error, &len, errbuf); 
       this->bitsLibrary->writeToLog(std::string(error), "SSHTunnelForwarder", "auth"); 
       JSONResponseGenerator jsonResponse; 
       jsonResponse.generateJSONResponse(API_AUTH_FAILURE, "InvalidPublicKey"); 
       return jsonResponse.getJSONString(); 

      } 
     } 
    } 

ich irgendwo gelesen, dass es keine neuen Linien haben sollte, ist, warum ich die \ n für Leer bin zu ersetzen, aber mit oder ohne diese es keinen Unterschied machen.

Die grundlegende Dokumentation erwähnt, dass eines der Argumente für libssh2_userauth_publickey ein Rückruf ist wie folgt:

int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);

aber ich kann keine Informationen überall finden, was dieser Rückruf ist oder was es enthalten soll. In meiner Funktion Aufruf libssh2_userauth_publickey gehe ich in SSHTunnelForwarder::publicKeyAuthComplete und derzeit diese Funktion hat nur die folgende:

int SSHTunnelForwarder::publicKeyAuthComplete(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, 
    const unsigned char *data, size_t data_len, void **abstract) 
{ 
    cout << "In SSH Auth Callback" << endl; 
    return 0; 
} 

Diese Methode oben nicht genannt bekommt, obwohl ich erwarte, dass dies nicht einmal annähernd korrekt sein .

Wenn ich meinen Code oben ausführen, ist das Ergebnis von libssh2_userauth_publickey 19 und der Fehler, der von der get_last_message() Methode zurückgegeben wird, ist invalid public key. Ich weiß, dass die öffentliche Schlüsseldatei in Ordnung ist, da ich sie in einer SSH-App auf Android verwenden kann und mich erfolgreich mit meinem Server authentifizieren kann.

Vielen Dank für Ihre Hilfe.

UPDATE 1

Ich habe es geschafft, einige Fortschritte zu machen, fand ich es eine Funktion namens:

libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase); 

Die libssh2 Version, die ich von NuGet Package Manager war hatte und festgestellt, dass Die neueste Version ist ziemlich alt, daher habe ich die neueste Version 1.7.0 von GitHub in Visual Studio erstellt und mein Projekt erneut mit dieser neuen Version verknüpft.

Ich habe ersetzt nun die ursprüngliche publickey Auth Funktion, die ich mit dieser Version so jetzt mein Code wie folgt stattdessen sieht unter Verwendung wurde:

int result = libssh2_userauth_publickey_frommemory(this->session, username.c_str(), username.length(), nullptr, 0, test.c_str(), sizeofkey, nullptr); 

Diese Funktion verwirrt mich ein wenig, dass es den öffentlichen Schlüssel will und den privaten Schlüssel, für alles, was ich über SSH weiß (zugegebenermaßen keine große Menge), bleibt der öffentliche Schlüssel auf dem Server, und der Benutzer, der sich anmelden möchte, hat nur Zugriff auf den privaten Schlüssel.

Ich habe festgestellt, dass jemand anderes dies fragte und ein Patch wurde ausgeführt, um einen Null-Zeiger für den öffentlichen Schlüssel zu ermöglichen, also habe ich nullptr für den öffentlichen Schlüssel und 0 für die öffentliche Schlüssellänge übergeben. Ich habe auch eine Nullptr für die Zertifikats-Passphrase, da dies nicht festgelegt wurde.

Wenn ich diesen Code jetzt ausführen, erhalte ich jetzt den Fehler -18, der invalid username/public key combination ist. Wiederum weiß ich, dass der Benutzername und die private Schlüsseldatei, die ich verwende, korrekt sind, da ich sie in einer SSH-Client-Anwendung auf Android verwenden kann, um eine Verbindung zu meinem SSH-Server herzustellen.

Antwort

6

Ich habe die Lösung gefunden. Was ich in Update 1 getan habe, war das eigentliche Update, aber mein Serverschlüssel wurde aus irgendeinem Grund geändert, nicht sicher, warum, also als es sagte, dass es den Benutzernamen nicht mit dem Schlüssel verknüpfen konnte, war es korrekt.

Der komplette Update ist wie folgt:

nicht die libssh2 von NuGet seine sehr alten anwenden. Ich habe die neueste Quelle von GitHub unter https://github.com/libssh2/libssh2/releases heruntergeladen und dann die folgenden Schritte zum Erstellen von libssh2 in Visual Studio ausgeführt.

  • Shove alle .c-Dateien in libssh2/src in eine leere Win32 C++ (DLL oder Static Library) Projekt außer libgcrypt.c/openssl.c, von denen Sie nur das eine entsprechend Ihrer Krypto-Bibliothek auswählen .
  • Fügen Sie Ihre OpenSSL oder libgcrypt Verzeichnis zum Projekt gehören Pfad
  • hinzufügen libssh2/umfassen zum Projekt gehören Pfad umfassen
  • libssh2/win32 zum Projekt hinzufügen umfassen Pfad
  • die entsprechenden Krypto-Bibliotheken dem Projekt hinzufügen additonal Bibliotheken Liste
  • Build-
  • Job gemacht

Schritte oben aus https://www.libssh2.org/mail/libssh2-devel-archive-2012-09/0029.shtml genommen

Die libssh2 wurde während der Kompilierung mit openssl verknüpft.

Verknüpfen Sie Ihr Projekt auf den neuesten haben Sie gerade für libssh2 getan und die Methode

libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase); 

Und das ist es.

Verwandte Themen