1a7c91847Schristos /* CVS rsh client stuff.
2a7c91847Schristos
3a7c91847Schristos This program is free software; you can redistribute it and/or modify
4a7c91847Schristos it under the terms of the GNU General Public License as published by
5a7c91847Schristos the Free Software Foundation; either version 2, or (at your option)
6a7c91847Schristos any later version.
7a7c91847Schristos
8a7c91847Schristos This program is distributed in the hope that it will be useful,
9a7c91847Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
10a7c91847Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11a7c91847Schristos GNU General Public License for more details. */
125a6c14c8Schristos #include <sys/cdefs.h>
13*74e8c71cSchristos __RCSID("$NetBSD: rsh-client.c,v 1.3 2017/08/22 10:06:57 christos Exp $");
14a7c91847Schristos
15a7c91847Schristos #include <config.h>
16a7c91847Schristos
17a7c91847Schristos #include "cvs.h"
18a7c91847Schristos #include "buffer.h"
19a7c91847Schristos
20a7c91847Schristos #ifdef CLIENT_SUPPORT
21a7c91847Schristos
22a7c91847Schristos #include "rsh-client.h"
23a7c91847Schristos
24a7c91847Schristos #ifndef NO_EXT_METHOD
25a7c91847Schristos
26a7c91847Schristos /* Contact the server by starting it with rsh. */
27a7c91847Schristos
28a7c91847Schristos /* Right now, we have two different definitions for this function,
29a7c91847Schristos depending on whether we start the rsh server using popenRW or not.
30a7c91847Schristos This isn't ideal, and the best thing would probably be to change
31a7c91847Schristos the OS/2 port to be more like the regular Unix client (i.e., by
32a7c91847Schristos implementing piped_child)... but I'm doing something else at the
33a7c91847Schristos moment, and wish to make only one change at a time. -Karl */
34a7c91847Schristos
35a7c91847Schristos # ifdef START_RSH_WITH_POPEN_RW
36a7c91847Schristos
37a7c91847Schristos
38a7c91847Schristos
39a7c91847Schristos /* This is actually a crock -- it's OS/2-specific, for no one else
40a7c91847Schristos uses it. If I get time, I want to make piped_child and all the
41a7c91847Schristos other stuff in os2/run.c work right. In the meantime, this gets us
42a7c91847Schristos up and running, and that's most important. */
43a7c91847Schristos void
start_rsh_server(cvsroot_t * root,struct buffer ** to_server_p,struct buffer ** from_server_p)44a7c91847Schristos start_rsh_server (cvsroot_t *root, struct buffer **to_server_p,
45a7c91847Schristos struct buffer **from_server_p)
46a7c91847Schristos {
47a7c91847Schristos int pipes[2];
48a7c91847Schristos int child_pid;
49a7c91847Schristos
50a7c91847Schristos /* If you're working through firewalls, you can set the
51a7c91847Schristos CVS_RSH environment variable to a script which uses rsh to
52a7c91847Schristos invoke another rsh on a proxy machine. */
53a7c91847Schristos char *cvs_rsh = (root->cvs_rsh != NULL
54a7c91847Schristos ? root->cvs_rsh : getenv ("CVS_RSH"));
55a7c91847Schristos char *cvs_server = (root->cvs_server != NULL
56a7c91847Schristos ? root->cvs_server : getenv ("CVS_SERVER"));
57a7c91847Schristos int i = 0;
58*74e8c71cSchristos /* This needs to fit "rsh", "-b", "-l", "USER", "--", "host",
59a7c91847Schristos "cmd (w/ args)", and NULL. We leave some room to grow. */
60*74e8c71cSchristos char *rsh_argv[16];
61a7c91847Schristos
62*74e8c71cSchristos if (!cvs_rsh || !*cvs_rsh)
63a7c91847Schristos /* People sometimes suggest or assume that this should default
64a7c91847Schristos to "remsh" on systems like HPUX in which that is the
65a7c91847Schristos system-supplied name for the rsh program. However, that
66a7c91847Schristos causes various problems (keep in mind that systems such as
67a7c91847Schristos HPUX might have non-system-supplied versions of "rsh", like
68a7c91847Schristos a Kerberized one, which one might want to use). If we
69a7c91847Schristos based the name on what is found in the PATH of the person
70a7c91847Schristos who runs configure, that would make it harder to
71a7c91847Schristos consistently produce the same result in the face of
72a7c91847Schristos different people producing binary distributions. If we
73a7c91847Schristos based it on "remsh" always being the default for HPUX
74a7c91847Schristos (e.g. based on uname), that might be slightly better but
75a7c91847Schristos would require us to keep track of what the defaults are for
76a7c91847Schristos each system type, and probably would cope poorly if the
77a7c91847Schristos existence of remsh or rsh varies from OS version to OS
78a7c91847Schristos version. Therefore, it seems best to have the default
79a7c91847Schristos remain "rsh", and tell HPUX users to specify remsh, for
80a7c91847Schristos example in CVS_RSH or other such mechanisms to be devised,
81a7c91847Schristos if that is what they want (the manual already tells them
82a7c91847Schristos that). */
83a7c91847Schristos cvs_rsh = RSH_DFLT;
84a7c91847Schristos if (!cvs_server)
85a7c91847Schristos cvs_server = "cvs";
86a7c91847Schristos
87a7c91847Schristos /* The command line starts out with rsh. */
88a7c91847Schristos rsh_argv[i++] = cvs_rsh;
89a7c91847Schristos
90a7c91847Schristos # ifdef RSH_NEEDS_BINARY_FLAG
91a7c91847Schristos /* "-b" for binary, under OS/2. */
92a7c91847Schristos rsh_argv[i++] = "-b";
93a7c91847Schristos # endif /* RSH_NEEDS_BINARY_FLAG */
94a7c91847Schristos
95a7c91847Schristos /* Then we strcat more things on the end one by one. */
96a7c91847Schristos if (root->username != NULL)
97a7c91847Schristos {
98a7c91847Schristos rsh_argv[i++] = "-l";
99a7c91847Schristos rsh_argv[i++] = root->username;
100a7c91847Schristos }
101a7c91847Schristos
102*74e8c71cSchristos /* Only non-option arguments from here. (CVE-2017-12836) */
103*74e8c71cSchristos rsh_argv[i++] = "--";
104*74e8c71cSchristos
105a7c91847Schristos rsh_argv[i++] = root->hostname;
106a7c91847Schristos rsh_argv[i++] = cvs_server;
107a7c91847Schristos rsh_argv[i++] = "server";
108a7c91847Schristos
109a7c91847Schristos /* Mark the end of the arg list. */
110a7c91847Schristos rsh_argv[i] = NULL;
111a7c91847Schristos
112a7c91847Schristos if (trace)
113a7c91847Schristos {
114a7c91847Schristos fprintf (stderr, " -> Starting server: ");
115a7c91847Schristos for (i = 0; rsh_argv[i]; i++)
116a7c91847Schristos fprintf (stderr, "%s ", rsh_argv[i]);
117a7c91847Schristos putc ('\n', stderr);
118a7c91847Schristos }
119a7c91847Schristos
120a7c91847Schristos /* Do the deed. */
121a7c91847Schristos child_pid = popenRW (rsh_argv, pipes);
122a7c91847Schristos if (child_pid < 0)
123a7c91847Schristos error (1, errno, "cannot start server via rsh");
124a7c91847Schristos
125a7c91847Schristos /* Give caller the file descriptors in a form it can deal with. */
126a7c91847Schristos make_bufs_from_fds (pipes[0], pipes[1], child_pid, to_server_p,
127a7c91847Schristos from_server_p, 0);
128a7c91847Schristos }
129a7c91847Schristos
130a7c91847Schristos # else /* ! START_RSH_WITH_POPEN_RW */
131a7c91847Schristos
132a7c91847Schristos void
start_rsh_server(cvsroot_t * root,struct buffer ** to_server_p,struct buffer ** from_server_p)133a7c91847Schristos start_rsh_server (cvsroot_t *root, struct buffer **to_server_p,
134a7c91847Schristos struct buffer **from_server_p)
135a7c91847Schristos {
136a7c91847Schristos /* If you're working through firewalls, you can set the
137a7c91847Schristos CVS_RSH environment variable to a script which uses rsh to
138a7c91847Schristos invoke another rsh on a proxy machine. */
139a7c91847Schristos char *cvs_rsh = (root->cvs_rsh != NULL
140a7c91847Schristos ? root->cvs_rsh : getenv ("CVS_RSH"));
141a7c91847Schristos char *cvs_server = (root->cvs_server != NULL
142a7c91847Schristos ? root->cvs_server : getenv ("CVS_SERVER"));
143a7c91847Schristos char *command;
144a7c91847Schristos int tofd, fromfd;
145a7c91847Schristos int child_pid;
146a7c91847Schristos
147a7c91847Schristos if (!cvs_rsh)
148a7c91847Schristos cvs_rsh = RSH_DFLT;
149a7c91847Schristos if (!cvs_server)
150a7c91847Schristos cvs_server = "cvs";
151a7c91847Schristos
152a7c91847Schristos /* Pass the command to rsh as a single string. This shouldn't
153a7c91847Schristos * affect most rsh servers at all, and will pacify some buggy
154a7c91847Schristos * versions of rsh that grab switches out of the middle of the
155a7c91847Schristos * command (they're calling the GNU getopt routines incorrectly).
156a7c91847Schristos *
157a7c91847Schristos * If you are running a very old (Nov 3, 1994, before 1.5)
158a7c91847Schristos * version of the server, you need to make sure that your .bashrc
159a7c91847Schristos * on the server machine does not set CVSROOT to something
160a7c91847Schristos * containing a colon (or better yet, upgrade the server).
161a7c91847Schristos */
162a7c91847Schristos command = Xasprintf ("%s server", cvs_server);
163a7c91847Schristos
164a7c91847Schristos {
165*74e8c71cSchristos char *argv[16];
166a7c91847Schristos char **p = argv;
167a7c91847Schristos
168a7c91847Schristos *p++ = cvs_rsh;
169a7c91847Schristos
170a7c91847Schristos /* If the login names differ between client and server
171a7c91847Schristos * pass it on to rsh.
172a7c91847Schristos */
173a7c91847Schristos if (root->username != NULL)
174a7c91847Schristos {
175a7c91847Schristos *p++ = "-l";
176a7c91847Schristos *p++ = root->username;
177a7c91847Schristos }
178a7c91847Schristos
179*74e8c71cSchristos *p++ = "--";
180*74e8c71cSchristos
181a7c91847Schristos *p++ = root->hostname;
182a7c91847Schristos *p++ = command;
183a7c91847Schristos *p++ = NULL;
184a7c91847Schristos
185a7c91847Schristos if (trace)
186a7c91847Schristos {
187a7c91847Schristos int i;
188a7c91847Schristos
189a7c91847Schristos fprintf (stderr, " -> Starting server: ");
190a7c91847Schristos for (i = 0; argv[i]; i++)
191a7c91847Schristos fprintf (stderr, "%s ", argv[i]);
192a7c91847Schristos putc ('\n', stderr);
193a7c91847Schristos }
194a7c91847Schristos child_pid = piped_child (argv, &tofd, &fromfd, true);
195a7c91847Schristos
196a7c91847Schristos if (child_pid < 0)
197a7c91847Schristos error (1, errno, "cannot start server via rsh");
198a7c91847Schristos }
199a7c91847Schristos free (command);
200a7c91847Schristos
201a7c91847Schristos make_bufs_from_fds (tofd, fromfd, child_pid, root, to_server_p,
202a7c91847Schristos from_server_p, 0);
203a7c91847Schristos }
204a7c91847Schristos
205a7c91847Schristos # endif /* START_RSH_WITH_POPEN_RW */
206a7c91847Schristos
207a7c91847Schristos #endif /* NO_EXT_METHOD */
208a7c91847Schristos
209a7c91847Schristos #endif /* CLIENT_SUPPORT */
210