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