ssh (sshfs) login in c++
-
Hallo liebe C++ommunity,
ich sitze nun schon viel zu lange an einem Problem, das durch googeln für mich bisher nicht zu lösen war. Bin c++ Einsteiger (und werde es wohl auch bleiben) und schreibe ein Programm, mit dem sich User auf einem Linux-Rechner mittles Secure Shell an einem (nicht von mir administrierten) Server anmelden sollen.
Mit Qt4 habe ich bereits in c++ ein Fenster gestaltet, so weit alles in Ordnung. Probleme bereitet mir jetzt das Anmelden am Server, das ich im Terminal mitsshfs user@server: directory -oreconnect
umsetzen würde.
Beisystem("sshfs user@server: directory -oreconnect");
wird die Eingabe eines Passwortes erwartet, das ich in einem String vorher abgefragt habe.
Wie kann ich dieses Passwort nun in meinem c++-Programm übergeben?
Pipen? Bisherige Versuche blieben erfolglos. Login ohne Passwort kommt nicht in Frage.Liebe Grüße
t-rags
-
hallo,
also mit einer pipe à la popen sollte es eigentlich funktionieren. popen funktioniert wie open nur dass man auf stdin / stdout eines programms zugreifen kann anstatt einer datei. theoretisch musst du dann einfach das passwort und ein \n in die pipe schreiben und es sollte funktionieren.
probiert habe ich es zwar noch nicht aber ich seh momentan kein grund warum es nicht funktionieren sollte.
blan
-
Wieso benutzt Du nicht eine C++-Bibliothek, mit der Du die SSH-Kommandos absetzen kannst? Ist auf alle Fälle einfacher, als irgendwelche Systemkommandos abzusetzen und dann umständlich die Ausgabe zu parsen. Außerdem wärst Du dann plattformunabhängig.
Und abgesehen davon: Was spricht gegen schlüsselbasierte Authentifizierung? Ist i.A. sicherer als ein passwortbasiertes Verfahren, und Du würdest auch keine interaktive Eingabe eines Passworts(*) benötigen.
(*) Es sei denn, Du benutzt eine Passphrase, um die Sicherheit noch einmal zu erhöhen.
-
Oh oh!
Ich hab's befürchtet: Lost in outer spaC++e.
Was spricht gegen schlüsselbasierte Authentifizierung?
1. Also nochmal: der ssh-Server ist für mich nicht (legal) administrierbar. Der public key muss ja erstmal auf die Accounts. Dafür bedarf es mindestens eines einmaligen Logins und zwar mit Passwort!
2. Auf dem Client wird ein temporärer default-user-Account genutzt, der $HOME-Daten entweder auf den Server zurückschickt oder löscht, da hat kein private key auf dem Client irgendwas zu suchen.
3. Dass die passwortlose Authentifizierung (ohne Passphrase) sicherer ist, halte ich darüber hinaus für geradezu naiv: Dieser Server (und garantiert tausende andere auch) hat derartig offene Scheunentore, dass es für Netzwerk-Hacker ein Kinderspiel wäre, an die ~/.ssh/id_dsa zu gelangen. Aber das ist ja hier nicht Thema.Die Idee mit der ssh-Bibliothek klingt gut, habe es auch mit ne77ssh probiert, was aber schon daran scheiterte, dass die Sources nicht gefunden wurden, obwohl sie im Quellverzeichnis lagen. Eine gute Anleitung für Einsteiger hab ich auch nicht gefunden (kann gerade mal "Hallo Welt!" in c++).
Da werden manche sagen: "Dann lass es besser!". Ich brauche aber mittlfristig ein gui und kein Terminal für das Programm, und weil ich Qt ganz flott einsetzen konnte, hielt ich diesen Weg für angemessen.
Eigentlich kann das ja auch mit der Pipe gar nicht so'n Problem sein. Habe allerdings im web nur Anleitungen für pipe gefunden. Das ist aber c. Bisher sieht mein Lösungsweg so aus:
string command = "sshfs user@server: directory -oreconnect"; string password = "geheim"; FILE * pipefile; int pid = fork(); if (pid==0){ // child process cout << command << endl; // check command pipefile = popen(command.c_str(), "r"); exit (0); } else if (pid > 0){ // parent process sleep (3); // Hier muss Papa oder Mama jetzt das Passwort übergeben }
Wahrscheinlich sagt der Profi: Oh Gott! Aber ich habe nicht die Zeit, 100% sauberes c++ zu erlernen. Vielleicht kann mir jemand trotzdem eine nette Hilfe anbieten.
-
also ich seh jetzt kein problem außer, dass du die pipe nicht nur lesend öffnen solltest denn sonst wird das schreiben in die pipe recht kompliziert
in die pipe kannst du dann mit fwrite schreiben.
blan
-
mit popen kann man nicht gleichzeitig zum schreiben und lesen öffnen.
und ausserdem ginge das eh nicht weil das ssh-programm nicht einfach von stdin liest (oder sonstwie verhindert das echo hallo|ssh geht).
-
Das war jetzt aber 'n Tiefschlag!
Ist denn das Folgende was ganz anderes?
Ein weiteres praktisches Beispiel für eine nicht-interaktive Verbindung ist das Pipen von Daten. Da SSH die Ein- und Ausgabekanäle transparent umleitet, können Sie auch Pipes benutzen. Im Beispiel wird ein Verzeichnis inklusiv der darunter liegenden Dateien mit tar über eine verschlüsselte Verbindung in das Verzeichnis /tmp des entfernten Servers kopiert.
tar cf - /foobar | ssh oh@10.0.0.20 “cd /tmp && tar xf –“
Quelle:
http://entwickler-magazin.de/zonen/portale/psecom,id,101,online,1138,neu,1.html
-
t-rags schrieb:
Das war jetzt aber 'n Tiefschlag!
Ist denn das Folgende was ganz anderes?
nein. Die Passworteingabe ist wohl eine Ausnahme.
-
Wieso benutzt du nicht einfach libssh?
http://freshmeat.net/projects/libssh/\1:
libssh is a C library to access SSH services from a program. It can remotely execute programs, transfer files, and serve as a secure and transparent tunnel for remote programs. Its Secure FTP implementation can play with remote files easily, without third-party programs others than libcrypto (from OpenSSL) of libgcrypt.
-
google mal nach expect. damit funktioniert das.
-
Yesss! Genau danach habe ich gesucht. Danke only-olli (und den anderen natürlich auch)! Es gibt zu expect sogar die grafische Variante expectk, die Tk implementiert. Damit braucht man nicht einmal c! Werde trotzdem mein Qt-Fenster mit expect weiter programmieren, finde ich schöner.
Achtung: Habe etliche Stunden gebraucht, um herauszufinden, dass expect mit folgendem Befehl bei mir so nicht funktioniert:
spawn sshfs user@server: directory -oreconnect
Erst mit der spawn-Option -ignore HUP hatte ich die Nuss geknackt:
spawn [c]-ignore HUP[/c] sshfs user@server: directory -oreconnect
Vielen Dank noch einmal!
t-rags
-
t-rags schrieb:
3. Dass die passwortlose Authentifizierung (ohne Passphrase) sicherer ist, halte ich darüber hinaus für geradezu naiv: Dieser Server (und garantiert tausende andere auch) hat derartig offene Scheunentore, dass es für Netzwerk-Hacker ein Kinderspiel wäre, an die ~/.ssh/id_dsa zu gelangen. Aber das ist ja hier nicht Thema.
es ist sicherer. Außerdem zwingt dich keiner, ~/.ssh/id_dsa zu benutzen. Ich hab z.b. meine SSH-Keys ganz wo anders.