Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //This thread method reads the network socket, replacing the process's stdin with a pipe
- //that it feeds network output to.
- void* snet::inthread(void* args)
- {
- //Create and direct the pipe
- int inpipe[2];
- pipe(inpipe);
- dup2(inpipe[READ_END], STDIN_FILENO);
- //set up input
- int len;
- char input[4096] = {0};
- //send network input to shell input
- while(true)
- {
- while((len = read(snet::sock, input, 4096)) >0)
- {
- write(inpipe[WRITE_END], input, len);
- }
- }
- }
- //This thread replaces the process's stdout with a pipe that sends its output to the client.
- void* snet::outthread(void* args)
- {
- //create and direct the pipe
- int oldin = dup(STDOUT_FILENO); //save old stdin for verbose
- int outpipe[2];
- pipe(outpipe);
- dup2(outpipe[WRITE_END], STDOUT_FILENO);
- //set up output
- int len;
- char output[4096] = {0};
- while(true)
- {
- while((len = read(outpipe[READ_END], output, 4096)) >0)
- {
- if(snet::verbose) {write(oldin, output, len);}
- write(snet::sock, output, len);
- }
- }
- }
- //Creates an open TCP connection and waits for a client. Once connected, accepts commands
- //and becomes a remote shell.
- void snet::slisten(vector<string>& cmds)
- {
- //get args, port--if no port, return with error
- snet::verbose = false;
- bool isPort = false;
- int port = -1;
- for(unsigned int i = 0; i < cmds.size(); i++)
- {
- if(cmds[i].at(0) == '-') //grab argument if it starts with -
- {
- if(cmds[i] == "-v")
- {
- snet::verbose = true;
- }
- }
- if(snet::isNumber(cmds[i])) //if it was a number, then we assign it to port
- {
- port = atoi(cmds[i].c_str());
- }
- }
- //If the user didn't specify a port, return.
- if(port == -1)
- {
- cout << "Error: No port specified. Please specify a port." << endl;
- exit(0);
- }
- //set up socket
- int shellsocket = socket(AF_INET, SOCK_STREAM, 0);
- struct sockaddr_in listenaddr;
- memset(&listenaddr, 0, sizeof(sockaddr_in));
- listenaddr.sin_family = AF_INET;
- listenaddr.sin_port = htons(port);
- inet_aton("127.0.0.1", &listenaddr.sin_addr);
- bind(shellsocket, (struct sockaddr*) &listenaddr, sizeof(listenaddr));
- //listen for incoming connection
- struct sockaddr_in remoteaddr;
- socklen_t remoteaddrlen = sizeof(remoteaddr);
- listen(shellsocket, 5);
- snet::sock = accept(shellsocket, (struct sockaddr*) &remoteaddr, &remoteaddrlen);
- close(shellsocket);
- //the socket has served it's purpose
- close(shellsocket);
- //set up threads for monitoring and writing
- pthread_t in, out;
- pthread_create(&in, NULL, inthread, NULL);
- pthread_create(&out, NULL, outthread, NULL);
- pthread_detach(in);
- pthread_detach(out);
- //return to main--this continues until the server does ctrl + c or client exits
- return;
- }
- //Reads from the socket's output and prints to stdout
- void* snet::clinthread(void* args)
- {
- char input[4096];
- int inlen = 0;
- while(true)
- {
- while((inlen = read(snet::sock, input, 4096)) >0)
- {
- write(STDOUT_FILENO, input, inlen);
- }
- }
- }
- //Connects to a given IP and port (probably another shell of this type)
- //to send commands and receive output.
- void snet::sconnect(vector<string>& cmds)
- {
- //return if no args or if no/invalid port
- if(cmds.size() < 3)
- {
- cout << "Please specify both an IP address and port." << endl;
- exit(0);
- }
- if(!snet::isNumber(cmds[2]))
- {
- cout << "That port is invalid. Please specify a port." << endl;
- exit(0);
- }
- //obtain args
- string ip = cmds[1];
- int port = atoi(cmds[2].c_str());
- //set up connection socket and connection address
- snet::sock = socket(AF_INET, SOCK_STREAM, 0);
- struct sockaddr_in connectaddr;
- memset(&connectaddr, 0, sizeof(sockaddr_in));
- connectaddr.sin_family = AF_INET;
- connectaddr.sin_port = htons(port);
- inet_aton(ip.c_str(), &connectaddr.sin_addr);
- //connect, return if fail or show if succeed
- socklen_t len = sizeof(connectaddr);
- if((connect(snet::sock,(sockaddr *) &connectaddr, len)) == -1)
- {
- cout << "Connection failed." << endl;
- exit(0);
- }
- cout << "Connection established. Exit to return to your own shell." << endl;
- //set up in/out loop
- //set up threads for monitoring and writing
- pthread_t serverout;
- pthread_create(&serverout, NULL, clinthread, NULL);
- pthread_detach(serverout);
- string cmd = "";
- cin.clear();
- while(cmd != "exit")
- {
- //get user cmd, send it over the socket
- getline(cin, cmd);
- cin.clear();
- cmd += "\n";
- write(snet::sock, cmd.c_str(), cmd.size());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement