1*50bf276cStholo #include <stdio.h>
2*50bf276cStholo #include <string.h>
3*50bf276cStholo #include <stdlib.h>
4*50bf276cStholo #include <unixio.h>
5*50bf276cStholo
6*50bf276cStholo #include <errno.h>
7*50bf276cStholo #include <sys/socket.h>
8*50bf276cStholo #include <netinet/in.h>
9*50bf276cStholo #include <netdb.h>
10*50bf276cStholo
rcmd(char ** remote_hostname,int remote_port,char * local_user,char * remote_user,char * command,int zero)11*50bf276cStholo int rcmd(char **remote_hostname, int remote_port,
12*50bf276cStholo char *local_user, char *remote_user,
13*50bf276cStholo char *command, int zero)
14*50bf276cStholo {
15*50bf276cStholo struct hostent *remote_hp;
16*50bf276cStholo struct hostent *local_hp;
17*50bf276cStholo struct sockaddr_in remote_isa;
18*50bf276cStholo struct sockaddr_in local_isa;
19*50bf276cStholo char local_hostname[80];
20*50bf276cStholo char ch;
21*50bf276cStholo int s;
22*50bf276cStholo int local_port;
23*50bf276cStholo int rs;
24*50bf276cStholo
25*50bf276cStholo remote_hp = gethostbyname(*remote_hostname);
26*50bf276cStholo if(!remote_hp)
27*50bf276cStholo {
28*50bf276cStholo perror("couldn't get remote host address");
29*50bf276cStholo exit(-1);
30*50bf276cStholo }
31*50bf276cStholo
32*50bf276cStholo /* Copy remote IP address into socket address structure */
33*50bf276cStholo remote_isa.sin_family = AF_INET;
34*50bf276cStholo remote_isa.sin_port = htons(remote_port);
35*50bf276cStholo memcpy(&remote_isa.sin_addr, remote_hp->h_addr, sizeof(remote_isa.sin_addr));
36*50bf276cStholo
37*50bf276cStholo gethostname(local_hostname, 80);
38*50bf276cStholo local_hp = gethostbyname(local_hostname);
39*50bf276cStholo if(!local_hp)
40*50bf276cStholo {
41*50bf276cStholo perror("couldn't get local host address");
42*50bf276cStholo exit(-1);
43*50bf276cStholo }
44*50bf276cStholo
45*50bf276cStholo /* Copy local IP address into socket address structure */
46*50bf276cStholo local_isa.sin_family = AF_INET;
47*50bf276cStholo memcpy(&local_isa.sin_addr, local_hp->h_addr, sizeof(local_isa.sin_addr));
48*50bf276cStholo
49*50bf276cStholo /* Create the local socket */
50*50bf276cStholo s = socket(AF_INET, SOCK_STREAM, 0);
51*50bf276cStholo if(s < 0)
52*50bf276cStholo {
53*50bf276cStholo perror("socket failed\n");
54*50bf276cStholo exit(-1);
55*50bf276cStholo }
56*50bf276cStholo
57*50bf276cStholo /* Bind local socket with a port from IPPORT_RESERVED/2 to IPPORT_RESERVED - 1
58*50bf276cStholo this requires the OPER privilege under VMS -- to allow communication with
59*50bf276cStholo a stock rshd under UNIX */
60*50bf276cStholo
61*50bf276cStholo for(local_port = IPPORT_RESERVED - 1; local_port >= IPPORT_RESERVED/2; local_port--)
62*50bf276cStholo {
63*50bf276cStholo local_isa.sin_port = htons(local_port);
64*50bf276cStholo rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa));
65*50bf276cStholo if(rs == 0)
66*50bf276cStholo break;
67*50bf276cStholo }
68*50bf276cStholo
69*50bf276cStholo /* Bind local socket to an unprivileged port. A normal rshd will drop the
70*50bf276cStholo connection; you must be running a patched rshd invoked through inetd for
71*50bf276cStholo this connection method to work */
72*50bf276cStholo
73*50bf276cStholo if (rs != 0)
74*50bf276cStholo for(local_port = IPPORT_USERRESERVED - 1;
75*50bf276cStholo local_port > IPPORT_RESERVED;
76*50bf276cStholo local_port--)
77*50bf276cStholo {
78*50bf276cStholo local_isa.sin_port = htons(local_port);
79*50bf276cStholo rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa));
80*50bf276cStholo if(rs == 0)
81*50bf276cStholo break;
82*50bf276cStholo }
83*50bf276cStholo
84*50bf276cStholo rs = connect(s, (struct sockaddr *) &remote_isa, sizeof(remote_isa));
85*50bf276cStholo if(rs == -1)
86*50bf276cStholo {
87*50bf276cStholo fprintf(stderr, "connect: errno = %d\n", errno);
88*50bf276cStholo close(s);
89*50bf276cStholo exit(-2);
90*50bf276cStholo }
91*50bf276cStholo
92*50bf276cStholo /* Now supply authentication information */
93*50bf276cStholo
94*50bf276cStholo /* Auxiliary port number for error messages, we don't use it */
95*50bf276cStholo write(s, "0\0", 2);
96*50bf276cStholo
97*50bf276cStholo /* Who are we */
98*50bf276cStholo write(s, local_user, strlen(local_user) + 1);
99*50bf276cStholo
100*50bf276cStholo /* Who do we want to be */
101*50bf276cStholo write(s, remote_user, strlen(remote_user) + 1);
102*50bf276cStholo
103*50bf276cStholo /* What do we want to run */
104*50bf276cStholo write(s, command, strlen(command) + 1);
105*50bf276cStholo
106*50bf276cStholo /* NUL is sent back to us if information is acceptable */
107*50bf276cStholo read(s, &ch, 1);
108*50bf276cStholo if(ch != '\0')
109*50bf276cStholo {
110*50bf276cStholo errno = EPERM;
111*50bf276cStholo return -1;
112*50bf276cStholo }
113*50bf276cStholo
114*50bf276cStholo return s;
115*50bf276cStholo }
116