]>
Commit | Line | Data |
---|---|---|
a3faa083 AM |
1 | diff -urN cvs-1.11.9.org/src/client.c cvs-1.11.9/src/client.c |
2 | --- cvs-1.11.9.org/src/client.c 2003-10-15 19:28:25.000000000 +0200 | |
3 | +++ cvs-1.11.9/src/client.c 2003-10-15 19:28:34.000000000 +0200 | |
4 | @@ -80,7 +80,7 @@ | |
a9093753 JB |
5 | /* This is needed for GSSAPI encryption. */ |
6 | static gss_ctx_id_t gcontext; | |
7 | ||
8 | -static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *)); | |
9 | +static int connect_to_gserver PROTO((cvsroot_t *, int, char *)); | |
10 | ||
11 | # endif /* HAVE_GSSAPI */ | |
12 | ||
a3faa083 | 13 | @@ -131,7 +131,7 @@ |
a9093753 JB |
14 | static size_t try_read_from_server PROTO ((char *, size_t)); |
15 | ||
16 | static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *, | |
17 | - int, int, struct hostent *)); | |
18 | + int, int, char *)); | |
19 | ||
20 | /* We need to keep track of the list of directories we've sent to the | |
21 | server. This list, along with the current CVSROOT, will help us | |
a3faa083 | 22 | @@ -3487,30 +3487,6 @@ |
a9093753 JB |
23 | |
24 | ||
25 | #if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) | |
26 | -static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *, | |
27 | - unsigned int)); | |
28 | - | |
29 | -static struct hostent * | |
30 | -init_sockaddr (name, hostname, port) | |
31 | - struct sockaddr_in *name; | |
32 | - char *hostname; | |
33 | - unsigned int port; | |
34 | -{ | |
35 | - struct hostent *hostinfo; | |
36 | - unsigned short shortport = port; | |
37 | - | |
38 | - memset (name, 0, sizeof (*name)); | |
39 | - name->sin_family = AF_INET; | |
40 | - name->sin_port = htons (shortport); | |
41 | - hostinfo = gethostbyname (hostname); | |
42 | - if (hostinfo == NULL) | |
43 | - { | |
44 | - fprintf (stderr, "Unknown host %s.\n", hostname); | |
45 | - error_exit (); | |
46 | - } | |
47 | - name->sin_addr = *(struct in_addr *) hostinfo->h_addr; | |
48 | - return hostinfo; | |
49 | -} | |
50 | ||
51 | ||
52 | ||
a3faa083 | 53 | @@ -3685,34 +3661,59 @@ |
a9093753 JB |
54 | int do_gssapi; |
55 | { | |
56 | int sock; | |
57 | - int port_number; | |
58 | - struct sockaddr_in client_sai; | |
59 | - struct hostent *hostinfo; | |
60 | + int gerr; | |
61 | + struct addrinfo hints, *res, *res0; | |
62 | + char pbuf[32]; | |
63 | struct buffer *to_server, *from_server; | |
64 | ||
65 | - sock = socket (AF_INET, SOCK_STREAM, 0); | |
66 | - if (sock == -1) | |
67 | + sprintf (pbuf, "%u", get_cvs_port_number (root)); | |
68 | + pbuf[sizeof(pbuf)-1] = '\0'; | |
69 | + memset (&hints, 0, sizeof (hints)); | |
70 | + hints.ai_family = af; | |
71 | + hints.ai_socktype = SOCK_STREAM; | |
72 | + gerr = getaddrinfo (root->hostname, pbuf, &hints, &res0); | |
73 | + if (gerr) | |
74 | { | |
75 | - error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); | |
76 | + fprintf (stderr, "Unknown host %s.\n", root->hostname); | |
77 | + error_exit (); | |
78 | } | |
79 | - port_number = get_cvs_port_number (root); | |
80 | - hostinfo = init_sockaddr (&client_sai, root->hostname, port_number); | |
81 | - if (trace) | |
82 | + | |
83 | + /* Try connect to current_parsed_root->hostname using all available families */ | |
84 | + for (res = res0; res != NULL; res = res->ai_next) | |
85 | { | |
86 | - fprintf (stderr, " -> Connecting to %s(%s):%d\n", | |
87 | - root->hostname, | |
88 | - inet_ntoa (client_sai.sin_addr), port_number); | |
89 | - } | |
90 | - if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai)) | |
91 | - < 0) | |
92 | - error (1, 0, "connect to %s(%s):%d failed: %s", | |
93 | - root->hostname, | |
94 | - inet_ntoa (client_sai.sin_addr), | |
95 | - port_number, SOCK_STRERROR (SOCK_ERRNO)); | |
96 | + sock = socket (res->ai_family, res->ai_socktype, 0); | |
97 | + if (sock == -1) { | |
98 | + if (res->ai_next) | |
99 | + continue; | |
100 | + else { | |
101 | + char *sock_error = SOCK_STRERROR (SOCK_ERRNO); | |
102 | + freeaddrinfo(res0); | |
103 | + error (1, 0, "cannot create socket: %s", sock_error); | |
104 | + } | |
105 | + } | |
106 | + | |
107 | + if (connect (sock, res->ai_addr, res->ai_addrlen) < 0) | |
108 | + { | |
109 | + if (res->ai_next) | |
110 | + { | |
111 | + close(sock); | |
112 | + continue; | |
113 | + } | |
114 | + else | |
115 | + { | |
116 | + char *sock_error = SOCK_STRERROR (SOCK_ERRNO); | |
117 | + freeaddrinfo(res0); | |
118 | + error (1, 0, "connect to [%s]:%s failed: %s", root->hostname, | |
119 | + pbuf, sock_error); | |
120 | + } | |
121 | + } | |
122 | + /* success */ | |
123 | + break; | |
124 | + } | |
125 | ||
126 | make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1); | |
127 | ||
128 | - auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo); | |
129 | + auth_server (root, to_server, from_server, verify_only, do_gssapi, root->hostname); | |
130 | ||
131 | if (verify_only) | |
132 | { | |
a3faa083 | 133 | @@ -3746,13 +3747,13 @@ |
a9093753 JB |
134 | |
135 | ||
136 | static void | |
137 | -auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo) | |
138 | +auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostname) | |
139 | cvsroot_t *root; | |
140 | struct buffer *lto_server; | |
141 | struct buffer *lfrom_server; | |
142 | int verify_only; | |
143 | int do_gssapi; | |
144 | - struct hostent *hostinfo; | |
145 | + char *hostname; | |
146 | { | |
147 | char *username; /* the username we use to connect */ | |
148 | char no_passwd = 0; /* gets set if no password found */ | |
a3faa083 | 149 | @@ -3782,7 +3783,7 @@ |
a9093753 JB |
150 | error (1, 0, "gserver currently only enabled for socket connections"); |
151 | } | |
152 | ||
153 | - if (! connect_to_gserver (root, fd, hostinfo)) | |
154 | + if (! connect_to_gserver (root, fd, hostname)) | |
155 | { | |
156 | error (1, 0, | |
157 | "authorization failed: server %s rejected access to %s", | |
a3faa083 | 158 | @@ -3798,7 +3799,7 @@ |
a9093753 JB |
159 | char *begin = NULL; |
160 | char *password = NULL; | |
161 | char *end = NULL; | |
162 | - | |
163 | + | |
164 | if (verify_only) | |
165 | { | |
166 | begin = "BEGIN VERIFICATION REQUEST"; | |
d3347b40 | 167 | @@ -3979,36 +3980,75 @@ |
a9093753 JB |
168 | int s; |
169 | const char *portenv; | |
170 | int port; | |
171 | - struct hostent *hp; | |
172 | - struct sockaddr_in sin; | |
173 | + int gerr; | |
174 | + struct addrinfo hints, *res, *res0; | |
175 | char *hname; | |
176 | - | |
177 | - s = socket (AF_INET, SOCK_STREAM, 0); | |
178 | - if (s < 0) | |
179 | - error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); | |
180 | + char pbuf[32], hbuf[1025]; | |
181 | ||
182 | port = get_cvs_port_number (root); | |
183 | ||
184 | - hp = init_sockaddr (&sin, root->hostname, port); | |
185 | - | |
d3347b40 | 186 | - hname = xstrdup (hp->h_name); |
a9093753 JB |
187 | - |
188 | - if (trace) | |
189 | + sprintf (pbuf, "%u", port); | |
190 | + pbuf[sizeof(pbuf)-1] = '\0'; | |
191 | + memset (&hints, 0, sizeof(hints)); | |
192 | + hints.ai_family = af; | |
193 | + hints.ai_socktype = SOCK_STREAM; | |
194 | + gerr = getaddrinfo (root->hostname, pbuf, &hints, &res0); | |
195 | + if (gerr) | |
196 | { | |
197 | - fprintf (stderr, " -> Connecting to %s(%s):%d\n", | |
198 | - root->hostname, | |
199 | - inet_ntoa (sin.sin_addr), port); | |
200 | + fprintf (stderr, "Unknown host %s.\n", root->hostname); | |
201 | + error_exit (); | |
202 | } | |
203 | ||
204 | - if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) | |
205 | - error (1, 0, "connect to %s(%s):%d failed: %s", | |
206 | - root->hostname, | |
207 | - inet_ntoa (sin.sin_addr), | |
208 | - port, SOCK_STRERROR (SOCK_ERRNO)); | |
209 | + /* Try connect to current_parsed_root->hostname using all available families */ | |
210 | + gerr = -1; | |
211 | + for (res = res0; res != NULL; res = res->ai_next) | |
212 | + { | |
213 | + s = socket (res->ai_family, res->ai_socktype, 0); | |
214 | + if (s < 0) | |
215 | + { | |
216 | + if (res->ai_next) | |
217 | + continue; | |
218 | + else | |
219 | + { | |
220 | + char *sock_error = SOCK_STRERROR (SOCK_ERRNO); | |
221 | + freeaddrinfo(res0); | |
222 | + error (1, 0, "cannot create socket: %s", sock_error); | |
223 | + } | |
224 | + } | |
225 | + if (trace) | |
226 | + { | |
227 | + char hbuf[1025]; | |
228 | + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | |
229 | + NULL, 0, NI_NUMERICHOST); | |
230 | + fprintf (stderr, " -> Connecting to %s(%s):%d\n", | |
231 | + root->hostname, hbuf, port); | |
232 | + } | |
233 | + | |
234 | + if (connect (s, res->ai_addr, res->ai_addrlen) < 0) | |
235 | + { | |
236 | + if (res->ai_next) | |
237 | + { | |
238 | + close(s); | |
239 | + continue; | |
240 | + } | |
241 | + else | |
242 | + { | |
243 | + char *sock_error = SOCK_STRERROR (SOCK_ERRNO); | |
244 | + freeaddrinfo(res0); | |
245 | + error (1, 0, "connect to [%s]:%s failed: %s", | |
246 | + root->hostname, pbuf, sock_error); | |
247 | + } | |
248 | + } | |
249 | + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, 0); | |
d3347b40 | 250 | + hname = xstrdup (hbuf); |
a9093753 JB |
251 | + /* success */ |
252 | + break; | |
253 | + } | |
254 | + freeaddrinfo(res0); | |
255 | ||
256 | { | |
257 | const char *realm; | |
258 | - struct sockaddr_in laddr; | |
259 | + struct sockaddr_storage laddr; | |
260 | int laddrlen; | |
261 | KTEXT_ST ticket; | |
262 | MSG_DAT msg_data; | |
a3faa083 | 263 | @@ -4084,10 +4124,10 @@ |
a9093753 JB |
264 | */ |
265 | #define BUFSIZE 1024 | |
266 | static int | |
267 | -connect_to_gserver (root, sock, hostinfo) | |
268 | +connect_to_gserver (root, sock, hostname) | |
269 | cvsroot_t *root; | |
270 | int sock; | |
271 | - struct hostent *hostinfo; | |
272 | + char *hostname; | |
273 | { | |
274 | char *str; | |
275 | char buf[BUFSIZE]; | |
a3faa083 | 276 | @@ -4100,9 +4140,9 @@ |
a9093753 JB |
277 | if (send (sock, str, strlen (str), 0) < 0) |
278 | error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); | |
279 | ||
280 | - if (strlen (hostinfo->h_name) > BUFSIZE - 5) | |
281 | + if (strlen (hostname) > BUFSIZE - 5) | |
282 | error (1, 0, "Internal error: hostname exceeds length of buffer"); | |
283 | - sprintf (buf, "cvs@%s", hostinfo->h_name); | |
284 | + sprintf (buf, "cvs@%s", hostname); | |
285 | tok_in.length = strlen (buf); | |
286 | tok_in.value = buf; | |
287 | gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, | |
a3faa083 AM |
288 | diff -urN cvs-1.11.9.org/src/cvs.h cvs-1.11.9/src/cvs.h |
289 | --- cvs-1.11.9.org/src/cvs.h 2003-10-15 19:28:25.000000000 +0200 | |
290 | +++ cvs-1.11.9/src/cvs.h 2003-10-15 19:28:34.000000000 +0200 | |
291 | @@ -366,6 +366,7 @@ | |
a9093753 JB |
292 | extern int really_quiet, quiet; |
293 | extern int use_editor; | |
294 | extern int cvswrite; | |
295 | +extern int af; | |
296 | extern mode_t cvsumask; | |
297 | ||
298 | ||
a3faa083 AM |
299 | diff -urN cvs-1.11.9.org/src/main.c cvs-1.11.9/src/main.c |
300 | --- cvs-1.11.9.org/src/main.c 2003-10-15 19:28:25.000000000 +0200 | |
301 | +++ cvs-1.11.9/src/main.c 2003-10-15 19:28:34.000000000 +0200 | |
a9093753 JB |
302 | @@ -13,6 +13,7 @@ |
303 | */ | |
304 | ||
305 | #include <assert.h> | |
306 | +#include <sys/socket.h> | |
307 | #include "cvs.h" | |
308 | ||
309 | #ifdef HAVE_WINSOCK_H | |
310 | @@ -42,6 +43,7 @@ | |
311 | int trace = 0; | |
312 | int noexec = 0; | |
313 | int logoff = 0; | |
314 | +int af = AF_UNSPEC; | |
315 | ||
316 | /* Set if we should be writing CVSADM directories at top level. At | |
317 | least for now we'll make the default be off (the CVS 1.9, not CVS | |
318 | @@ -162,7 +164,7 @@ | |
319 | in --help as it is a rather different format from the rest. */ | |
320 | ||
321 | "Usage: %s [cvs-options] command [command-options-and-arguments]\n", | |
322 | - " where cvs-options are -q, -n, etc.\n", | |
323 | + " where cvs-options are -4, -6,-q, -n, etc.\n", | |
324 | " (specify --help-options for a list of options)\n", | |
325 | " where command is add, admin, etc.\n", | |
326 | " (specify --help-commands for a list of commands\n", | |
a3faa083 | 327 | @@ -406,7 +408,7 @@ |
a9093753 JB |
328 | int help = 0; /* Has the user asked for help? This |
329 | lets us support the `cvs -H cmd' | |
330 | convention to give help for cmd. */ | |
c44cb12a | 331 | - static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa"; |
4abf4443 | 332 | + static const char short_options[] = "+46Qqrwtnvb:T:e:d:Hfz:s:xa"; |
a9093753 JB |
333 | static struct option long_options[] = |
334 | { | |
335 | {"help", 0, NULL, 'H'}, | |
a3faa083 | 336 | @@ -519,6 +521,12 @@ |
a9093753 JB |
337 | /* --allow-root */ |
338 | root_allow_add (optarg); | |
339 | break; | |
340 | + case '4': | |
341 | + af = AF_INET; | |
342 | + break; | |
343 | + case '6': | |
344 | + af = AF_INET6; | |
345 | + break; | |
346 | case 'Q': | |
347 | really_quiet = 1; | |
348 | /* FALL THROUGH */ | |
a3faa083 AM |
349 | diff -urN cvs-1.11.9.org/src/server.c cvs-1.11.9/src/server.c |
350 | --- cvs-1.11.9.org/src/server.c 2003-10-15 19:28:25.000000000 +0200 | |
351 | +++ cvs-1.11.9/src/server.c 2003-10-15 19:29:16.000000000 +0200 | |
352 | @@ -5756,8 +5756,8 @@ | |
a9093753 JB |
353 | { |
354 | int status; | |
355 | char instance[INST_SZ]; | |
356 | - struct sockaddr_in peer; | |
357 | - struct sockaddr_in laddr; | |
358 | + struct sockaddr_storage peer; | |
359 | + struct sockaddr_storage laddr; | |
360 | int len; | |
361 | KTEXT_ST ticket; | |
362 | AUTH_DAT auth; | |
a3faa083 | 363 | @@ -5834,7 +5834,8 @@ |
a9093753 JB |
364 | gserver_authenticate_connection () |
365 | { | |
366 | char hostname[MAXHOSTNAMELEN]; | |
367 | - struct hostent *hp; | |
368 | + char hbuf[1025]; | |
369 | + struct addrinfo hints, *res0; | |
370 | gss_buffer_desc tok_in, tok_out; | |
371 | char buf[1024]; | |
372 | OM_uint32 stat_min, ret; | |
a3faa083 | 373 | @@ -5844,11 +5845,16 @@ |
a9093753 JB |
374 | gss_OID mechid; |
375 | ||
376 | gethostname (hostname, sizeof hostname); | |
377 | - hp = gethostbyname (hostname); | |
378 | - if (hp == NULL) | |
379 | + hostname[sizeof(hostname)-1] = '\0'; | |
380 | + memset (&hints, 0, sizeof(hints)); | |
381 | + hints.ai_family = af; | |
382 | + hints.ai_socktype = SOCK_STREAM; | |
383 | + hints.ai_flags = AI_CANONNAME; | |
a3faa083 | 384 | + if (getaddrinfo (hostname, NULL, &hints, &res0)) |
a9093753 JB |
385 | error (1, 0, "can't get canonical hostname"); |
386 | ||
387 | - sprintf (buf, "cvs@%s", hp->h_name); | |
388 | + sprintf (buf, "cvs@%s", res0->ai_canonname); | |
389 | + freeaddrinfo (res0); | |
390 | tok_in.value = buf; | |
391 | tok_in.length = strlen (buf); | |
392 |