2
* Purpose: "Reverse telnet" helper utility for OSS technical support
5
* The osspartysh program is an utility that permits safe access to the
6
* customer systems by the OSS support staff.
8
* Unlike usual ssh/telnet access this program works in revewrse way. The
9
* person who gives technical support can establish a termibal server using
10
* osspartysh -d -p <TCP port>. The client can then connect to this
11
* terminal server program by executing osspartysh -h <the support host> -p <port>.
12
* Outgoing TCP connections can easily pass usual firewall and NAT settings
13
* which makes establishing the connection very easy. After the connection is
14
* open both sides can type commands and see what happens in the system. If
15
* the customer thiks the tech suport guy is doing something too dangerous he
16
* can always hit ^C or ^Z and unplug the ethernet connector.
20
* This file is part of Open Sound System.
22
* Copyright (C) 4Front Technologies 1996-2008.
24
* This this source file is released under GPL v2 license (no other versions).
25
* See the COPYING file included in the main directory of this source
26
* distribution for the license terms and conditions.
31
#include <sys/types.h>
33
#include <sys/socket.h>
34
#include <sys/select.h>
36
#include <netinet/in.h>
37
#include <netinet/tcp.h>
38
#include <arpa/inet.h>
53
#define PARTYSH_MAGIC "ParTySH"
54
#define PARTYSH_VERSION "0100" // 1.0
55
#define PARTYSH_HDRSIZE 250
59
struct termios saved_tc;
64
#define max(a, b) ((a>b) ? a : b)
67
restore_terminal(void)
69
if (tcsetattr(localfd, 0, &saved_tc) == -1)
78
if (tcgetattr(0, &tc)==-1)
84
if (tcgetattr(0, &saved_tc)==-1)
90
atexit(restore_terminal);
92
tc.c_lflag &= ~(ICANON|ECHO|ISIG);
96
if (tcsetattr(0, 0, &tc) == -1)
103
if (listen(listenfd, 1) == -1)
109
printf("Waiting for a new connection - hit ^C to exit.\n");
111
if ((connfd=accept(listenfd, NULL, NULL))==-1)
117
printf("Connected\n\n");fflush(stdout);
119
printf("You may need to type ^L after running vi.\n");
121
printf("Hit enter couple of times after exiting the shell so that\n");
122
printf("you can kill the osspartysh program. If the program is left\n");
123
printf("running after a session then new clients can connect the same host/port again.\n");
124
printf("\n");fflush(stdout);
126
setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
132
terminal_loop(int connfd)
143
FD_SET(connfd, &readfds);
145
if ((n=select(connfd+1, &readfds, NULL, NULL, NULL))==-1)
151
if (FD_ISSET(0, &readfds))
153
if ((l=read(0, buf, sizeof(buf)))<0)
159
if (write(connfd, buf, l)!=l)
161
perror("write(conn)");
166
if (FD_ISSET(connfd, &readfds))
168
if ((l=read(connfd, buf, sizeof(buf)))<0)
170
perror("read(conn)");
174
if (write(1, buf, l)!=l)
184
shell_loop(int connfd, int infd, int outfd)
194
FD_SET(infd, &readfds);
197
FD_SET(connfd, &readfds);
199
if ((n=select(max(infd, connfd)+1, &readfds, NULL, NULL, NULL))==-1)
205
if (FD_ISSET(infd, &readfds))
207
if ((l=read(infd, buf, sizeof(buf)))<0)
211
printf("Disconnected\n");
215
perror("read(infd)");
219
if (write(connfd, buf, l)!=l)
221
perror("write(conn)");
225
if (write(1, buf, l)!=l) // Echo to the local terminal
229
if (FD_ISSET(connfd, &readfds))
231
if ((l=read(connfd, buf, sizeof(buf)))<0)
233
perror("read(conn)");
237
if (write(outfd, buf, l)!=l)
239
perror("write(outfd)");
243
// write(1, buf, l); // Echo to the local terminal
246
if (infd != 0 && FD_ISSET(0, &readfds))
248
if ((l=read(0, buf, sizeof(buf)))<0)
254
if (write(outfd, buf, l)!=l)
256
perror("write(outfd)");
260
// write(1, buf, l); // Echo to the local terminal
266
handle_connection(int connfd)
268
char welcomebuf[PARTYSH_HDRSIZE] = {0};
270
sprintf(welcomebuf, PARTYSH_MAGIC " " PARTYSH_VERSION " Just testing");
271
if (write(connfd, welcomebuf, PARTYSH_HDRSIZE) != PARTYSH_HDRSIZE)
273
perror("send welcome");
274
fprintf(stderr, "Cannot send the welcome string\n");
286
printf("Session closed1\n");fflush(stdout);
291
terminal_loop(connfd);
300
struct sockaddr_in servaddr;
304
fprintf(stderr, "Please give a port (-p)\n");
308
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
314
bzero(&servaddr, sizeof(servaddr));
315
servaddr.sin_family = AF_INET;
316
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
317
servaddr.sin_port = htons(port);
319
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))==-1)
330
perror("wait connection");
334
handle_connection(connfd);
343
pty_session(int connfd)
349
char tmpl[32]="/tmp/osspartyshXXXXXX";
352
if ((fd = mkstemp(tmpl)) == -1)
360
if ((f = fdopen(fd, "w")) != NULL)
362
fprintf(f, "PS1=\"[SHARED]@\\h:\\w $ \"\n");
363
fprintf(f, "export PS1\n");
368
if ((pid=forkpty(&ptyfd, NULL, NULL, NULL))==-1)
379
shell_loop(connfd, ptyfd, ptyfd);
385
execlp("bash", "bash", "--rcfile", tmpl, NULL);
390
run_client(char *host, int port)
393
struct sockaddr_in sa;
396
char welcomebuf[PARTYSH_HDRSIZE];
402
fprintf(stderr, "Please give a host (-h)\n");
408
fprintf(stderr, "Please give a port (-p)\n");
412
if ((sockfd = socket (PF_INET, SOCK_STREAM, 0)) == -1)
418
printf("Looking for the server\n");
420
if ((he = gethostbyname (host)) == NULL)
423
fprintf(stderr, "Cannot find the support host\n");
427
sa.sin_family = AF_INET;
428
sa.sin_port = htons (port);
430
printf ("Connecting to the support center at %s:%d\n", host, port);
432
memcpy ((void *) &sa.sin_addr, *he->h_addr_list, he->h_length);
433
if ((connfd = connect (sockfd, (void *) &sa, sizeof (sa))) == -1)
436
fprintf(stderr, "Cannot connect to the support center\n");
440
if (read(sockfd, welcomebuf, PARTYSH_HDRSIZE) != PARTYSH_HDRSIZE)
442
perror("receive welcome");
446
// printf("Welcome %s\n", welcomebuf);
448
if (strncmp(welcomebuf, PARTYSH_MAGIC, strlen(PARTYSH_MAGIC))!=0)
450
fprintf(stderr, "Didn't receive valid velcome string - abort\n");
454
if ((ps1=getenv("PS1")) != NULL)
460
if (*p == '#') *p= '$';
461
if (*p == '>') *p= '<';
464
//printf("PS1='%s'\n", ps1);
466
setenv("PS1", ps1, 1);
467
} else setenv("PS1", "ossremote> ", 1);
469
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
470
printf("*** Established connection - You are now sharing this session ***\n\n");fflush(stdout);
471
printf("You may need to type ^L after running vi.\n");
483
printf("Now connected to the remote system - Hit ^C to disconnect\n");fflush(stdout);
485
execlp("bash", "bash", "-i", NULL);
486
//execlp("sh", "sh", NULL);
491
shell_loop(sockfd, 0, 1);
500
int main(int argc, char *argv[])
507
while ((i = getopt(argc, argv, "dp:h:")) != EOF)
524
exit(run_daemon(port));
526
exit(run_client(host, port));