STDIN/STDOUT auf Socket binden bei Multiclient-Server
-
Hallo zusammen,
das hier ist mein erster Beitrag hier weil ich mit Google und Co kein richtiges/passendes Ergebnis gefunden habe.
Ich schreibe zur Zeit an einer Remoteshell a la NetCat oder SSH aber habe Probleme damit die STDIN und STDOUT Handles an das Socket zu binden. Ich habe gelesen dass es mit dup2 oder über STARTUPINFORMATION gehen soll. Jedoch haben die Beispiele die ich gefunden habe "das Problem" dass sie nur mit einem socket funktionieren ich hingegen habe aber einen Multiclient Server. Lange Rede kurzer Sinn hier ist der Source mit dem es nicht so recht klappen will.
Der Teil um den es geht ist ab dem Kommentar RemoteShell zu finden. Meine (unvollständigen) versuche habe ich auskommentiert.
Ich hoffe hier weiss jemand wie es richtig funktioniert.
//#define WIN32_LEAN_AND_MEAN #define WINVER 0x0500 #include "..\socket.h" #include "redirect.h" #include <iostream> #include <cstring> #include <string.h> #include <process.h> #include <windows.h> #include <winsock2.h> #include <fstream> #include <unistd.h> using namespace std; int main( int argc, char *argv[] ) { int i, ready, sock_max, max = -1; int client_sock[FD_SETSIZE]; fd_set gesamt_sock, lese_sock; try { Socket sock1, sock2, sock3,sock4; sock1.create(); sock1.bind(15000); sock1.listen(); sock_max = sock1.get_m_sock(); for( i=0; i<FD_SETSIZE; i++) { client_sock[i] = -1; } FD_ZERO( &gesamt_sock ); FD_SET( sock1.get_m_sock(), &gesamt_sock ); while(1) { //aktuallisiere bei jedem event lese_sock = gesamt_sock; //auf neue verbindungen warten ready = select( sock_max+1, &lese_sock, NULL, NULL, NULL ); //Neuer Client? if( FD_ISSET(sock1.get_m_sock(), &lese_sock)) { sock1.accept( sock2 ); //Speicher für neuen Client freigeben for( i=0; i<FD_SETSIZE; i++ ) { if( client_sock[i] < 0 ) { client_sock[i] = sock2.get_m_sock(); break; } } //Max. clients sind FD_SETSIZE if ( i == FD_SETSIZE ) { throw SockExcept( "Max. Clients erreicht" ); } //Neuen Socket zur gesamtsocketmenge hinzufügen FD_SET( sock2.get_m_sock(), &gesamt_sock ); //select die höchste socket nr übergeben if ( sock2.get_m_sock() > sock_max ) { sock_max = sock2.get_m_sock(); } //gesamt anzahl an socket nr für anzahl an lese-sikriptoren benötigt if ( i > max ) { max = i; } if ( --ready <= 0 ) { continue; } } //schliesse if( FD_ISSET... //auf neue verbindungen von clients warten und //lese-diskriptoren bereitstellen for (i=0; i<=max; i++) { string s,client; char clientbuf[5]; sock3.set_m_sock( client_sock[i] ); if ( ( sock3.get_m_sock() ) < 0 ) { continue; } if( FD_ISSET( sock3.get_m_sock(), &lese_sock ) ) { //ankommende daten lesen sock3.recv(s); //authentifizierung der clients if( s == "HI" ) { sock3.send("Willkommen!!"); } //ausgabe der client-nachricht am server cout << "nachricht: " << s << endl; cout.flush(); //antwort des servers an alle sock3.send("Nachricht " + s + " erhalten"); //befehle die der server interpretieren soll //da switch-case keine strings kann mit if.. //lösbar mit lookup-table?? int -> string if ( s == "quit" ) { sock3.close(); //aus der socket menge entfernen FD_CLR( sock3.get_m_sock(), &gesamt_sock ); //ausgabe auf dem server cout << "Client" << client_sock[i] << " hat verbindung beendet" << endl; //client socket schliessen indem index auf -1 gestzt wird client_sock[i] = -1; } // RemoteShell if ( s == "shell" ) { sock3.send("Starte Remote Shell..."); PROCESS_INFORMATION pi; STARTUPINFO si; SECURITY_ATTRIBUTES sa; DWORD pc; SetConsoleTitle("!!!!new!!!!"); //HWND hwndFound; HWND hWnd = GetConsoleWindow(); //ShowWindow( hWnd, SW_HIDE ); //hwndFound=FindWindow(NULL, "!!!!"); HINSTANCE hInstC = GetModuleHandle( 0 ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); sock3.send("vars gesetzt"); // si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; // if ( dup2(client_sock[i], STDIN_FILENO) < 0 ) { sock3.send("FEHLER STDIN HANDLE "); } // if ( dup2(client_sock[i], STDOUT_FILENO) < 0 ) { cout << "FEHLER STDOUT HANDLE " << endl; } // if ( dup2(client_sock[i], STDERR_FILENO) < 0 ) { cout << "FEHLER STDERR HANDLE " << endl; } //si.hStdInput = (HANDLE) // si.hStdOutput = HANDLE)client_sock[i]; // si.hStdError = (HANDLE)client_sock[i]; //si.hStdInput = si.hStdOutput = si.hStdError = (void*)sock3.get_m_sock(); CreateProcess( NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); //sock3.send(hStdOut); //sock3.send(si.hStdOutput); WaitForSingleObject( pi.hProcess, INFINITE ); //GetExitCodeProcess( pi.hProcess, &pc ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } //Noch Clients/ lese-diskriptoren vorhanden? if ( --ready <= 0 ) { break; } } //schliesse if( FD_ISSET( sock3 ... } //schliesse for (i=0 ... } //schliesse while(1) ... } //schliesse try { ... //Esception fangen catch ( SockExcept& e ) { cout << "!!Fehler: " << e.get_SockExcept() << endl; } return 0; }
Ich hoffe ich habe mit meinem ersten Post auch gleich das richtige Unterforum getroffen.
Viele Grüße,
Ravenmaster
-
Wolf-Alarm!
-
Jetzt nachdem wir wissen dass es aus dem Buch ist, kann mir jemand bei dem Problem helfen?