1 /* This program is free software; you can redistribute it and/or modify 2 it under the terms of the GNU General Public License as published by 3 the Free Software Foundation; either version 2, or (at your option) 4 any later version. 5 6 This program is distributed in the hope that it will be useful, 7 but WITHOUT ANY WARRANTY; without even the implied warranty of 8 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 GNU General Public License for more details. */ 10 11 #include <assert.h> 12 #include "cvs.h" 13 #include "watch.h" 14 #include "edit.h" 15 #include "fileattr.h" 16 #include "getline.h" 17 #include "buffer.h" 18 19 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) 20 # ifdef HAVE_GSSAPI 21 /* This stuff isn't included solely with SERVER_SUPPORT since some of these 22 * functions (encryption & the like) get compiled with or without server 23 * support. 24 * 25 * FIXME - They should be in a different file. 26 */ 27 # include <netdb.h> 28 # include "xgssapi.h" 29 /* We use Kerberos 5 routines to map the GSSAPI credential to a user 30 name. */ 31 # include <krb5.h> 32 33 /* We need this to wrap data. */ 34 static gss_ctx_id_t gcontext; 35 36 static void gserver_authenticate_connection PROTO((void)); 37 38 /* Whether we are already wrapping GSSAPI communication. */ 39 static int cvs_gssapi_wrapping; 40 41 # ifdef ENCRYPTION 42 /* Whether to encrypt GSSAPI communication. We use a global variable 43 like this because we use the same buffer type (gssapi_wrap) to 44 handle both authentication and encryption, and we don't want 45 multiple instances of that buffer in the communication stream. */ 46 int cvs_gssapi_encrypt; 47 # endif 48 # endif /* HAVE_GSSAPI */ 49 #endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */ 50 51 #ifdef SERVER_SUPPORT 52 53 #ifdef HAVE_WINSOCK_H 54 #include <winsock.h> 55 #endif 56 57 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) 58 #include <sys/socket.h> 59 #endif 60 61 #ifdef HAVE_SYSLOG_H 62 #include <syslog.h> 63 #endif 64 65 #ifdef HAVE_KERBEROS 66 # include <netinet/in.h> 67 # include <krb.h> 68 # ifndef HAVE_KRB_GET_ERR_TEXT 69 # define krb_get_err_text(status) krb_err_txt[status] 70 # endif 71 72 /* Information we need if we are going to use Kerberos encryption. */ 73 static C_Block kblock; 74 static Key_schedule sched; 75 76 #endif 77 78 /* for select */ 79 #include "xselect.h" 80 81 #ifndef O_NONBLOCK 82 #define O_NONBLOCK O_NDELAY 83 #endif 84 85 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will 86 return it, rather than EAGAIN, for nonblocking writes. */ 87 #ifdef EWOULDBLOCK 88 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN) 89 #else 90 #define blocking_error(err) ((err) == EAGAIN) 91 #endif 92 93 /* For initgroups(). */ 94 #if HAVE_INITGROUPS 95 #include <grp.h> 96 #endif /* HAVE_INITGROUPS */ 97 98 # ifdef AUTH_SERVER_SUPPORT 99 100 # ifdef HAVE_GETSPNAM 101 # include <shadow.h> 102 # endif 103 104 /* The cvs username sent by the client, which might or might not be 105 the same as the system username the server eventually switches to 106 run as. CVS_Username gets set iff password authentication is 107 successful. */ 108 char *CVS_Username = NULL; 109 110 /* Used to check that same repos is transmitted in pserver auth and in 111 later CVS protocol. Exported because root.c also uses. */ 112 static char *Pserver_Repos = NULL; 113 114 /* Should we check for system usernames/passwords? Can be changed by 115 CVSROOT/config. */ 116 int system_auth = 1; 117 118 /* Should we disable Update-prog/Checkin-prog? Can be changed by 119 CVSROOT/config. */ 120 int disable_x_prog = 0; 121 122 # endif /* AUTH_SERVER_SUPPORT */ 123 124 125 /* While processing requests, this buffer accumulates data to be sent to 126 the client, and then once we are in do_cvs_command, we use it 127 for all the data to be sent. */ 128 static struct buffer *buf_to_net; 129 130 /* This buffer is used to read input from the client. */ 131 static struct buffer *buf_from_net; 132 133 /* 134 * This is where we stash stuff we are going to use. Format string 135 * which expects a single directory within it, starting with a slash. 136 */ 137 static char *server_temp_dir; 138 139 /* This is the original value of server_temp_dir, before any possible 140 changes inserted by serve_max_dotdot. */ 141 static char *orig_server_temp_dir; 142 143 /* Nonzero if we should keep the temp directory around after we exit. */ 144 static int dont_delete_temp; 145 146 static void server_write_entries PROTO((void)); 147 148 /* All server communication goes through buffer structures. Most of 149 the buffers are built on top of a file descriptor. This structure 150 is used as the closure field in a buffer. */ 151 152 struct fd_buffer 153 { 154 /* The file descriptor. */ 155 int fd; 156 /* Nonzero if the file descriptor is in blocking mode. */ 157 int blocking; 158 }; 159 160 static struct buffer *fd_buffer_initialize 161 PROTO ((int, int, void (*) (struct buffer *))); 162 static int fd_buffer_input PROTO((void *, char *, int, int, int *)); 163 static int fd_buffer_output PROTO((void *, const char *, int, int *)); 164 static int fd_buffer_flush PROTO((void *)); 165 static int fd_buffer_block PROTO((void *, int)); 166 static int fd_buffer_shutdown PROTO((void *)); 167 168 /* Initialize a buffer built on a file descriptor. FD is the file 169 descriptor. INPUT is nonzero if this is for input, zero if this is 170 for output. MEMORY is the function to call when a memory error 171 occurs. */ 172 173 static struct buffer * 174 fd_buffer_initialize (fd, input, memory) 175 int fd; 176 int input; 177 void (*memory) PROTO((struct buffer *)); 178 { 179 struct fd_buffer *n; 180 181 n = (struct fd_buffer *) xmalloc (sizeof *n); 182 n->fd = fd; 183 n->blocking = 1; 184 return buf_initialize (input ? fd_buffer_input : NULL, 185 input ? NULL : fd_buffer_output, 186 input ? NULL : fd_buffer_flush, 187 fd_buffer_block, 188 fd_buffer_shutdown, 189 memory, 190 n); 191 } 192 193 /* The buffer input function for a buffer built on a file descriptor. */ 194 195 static int 196 fd_buffer_input (closure, data, need, size, got) 197 void *closure; 198 char *data; 199 int need; 200 int size; 201 int *got; 202 { 203 struct fd_buffer *fd = (struct fd_buffer *) closure; 204 int nbytes; 205 206 if (! fd->blocking) 207 nbytes = read (fd->fd, data, size); 208 else 209 { 210 /* This case is not efficient. Fortunately, I don't think it 211 ever actually happens. */ 212 nbytes = read (fd->fd, data, need == 0 ? 1 : need); 213 } 214 215 if (nbytes > 0) 216 { 217 *got = nbytes; 218 return 0; 219 } 220 221 *got = 0; 222 223 if (nbytes == 0) 224 { 225 /* End of file. This assumes that we are using POSIX or BSD 226 style nonblocking I/O. On System V we will get a zero 227 return if there is no data, even when not at EOF. */ 228 return -1; 229 } 230 231 /* Some error occurred. */ 232 233 if (blocking_error (errno)) 234 { 235 /* Everything's fine, we just didn't get any data. */ 236 return 0; 237 } 238 239 return errno; 240 } 241 242 /* The buffer output function for a buffer built on a file descriptor. */ 243 244 static int 245 fd_buffer_output (closure, data, have, wrote) 246 void *closure; 247 const char *data; 248 int have; 249 int *wrote; 250 { 251 struct fd_buffer *fd = (struct fd_buffer *) closure; 252 253 *wrote = 0; 254 255 while (have > 0) 256 { 257 int nbytes; 258 259 nbytes = write (fd->fd, data, have); 260 261 if (nbytes <= 0) 262 { 263 if (! fd->blocking 264 && (nbytes == 0 || blocking_error (errno))) 265 { 266 /* A nonblocking write failed to write any data. Just 267 return. */ 268 return 0; 269 } 270 271 /* Some sort of error occurred. */ 272 273 if (nbytes == 0) 274 return EIO; 275 276 return errno; 277 } 278 279 *wrote += nbytes; 280 data += nbytes; 281 have -= nbytes; 282 } 283 284 return 0; 285 } 286 287 /* The buffer flush function for a buffer built on a file descriptor. */ 288 289 /*ARGSUSED*/ 290 static int 291 fd_buffer_flush (closure) 292 void *closure; 293 { 294 /* Nothing to do. File descriptors are always flushed. */ 295 return 0; 296 } 297 298 /* The buffer block function for a buffer built on a file descriptor. */ 299 300 static int 301 fd_buffer_block (closure, block) 302 void *closure; 303 int block; 304 { 305 struct fd_buffer *fd = (struct fd_buffer *) closure; 306 int flags; 307 308 flags = fcntl (fd->fd, F_GETFL, 0); 309 if (flags < 0) 310 return errno; 311 312 if (block) 313 flags &= ~O_NONBLOCK; 314 else 315 flags |= O_NONBLOCK; 316 317 if (fcntl (fd->fd, F_SETFL, flags) < 0) 318 return errno; 319 320 fd->blocking = block; 321 322 return 0; 323 } 324 325 /* The buffer shutdown function for a buffer built on a file descriptor. */ 326 327 static int 328 fd_buffer_shutdown (closure) 329 void *closure; 330 { 331 free (closure); 332 return 0; 333 } 334 335 /* Populate all of the directories between BASE_DIR and its relative 336 subdirectory DIR with CVSADM directories. Return 0 for success or 337 errno value. */ 338 static int create_adm_p PROTO((char *, char *)); 339 340 static int 341 create_adm_p (base_dir, dir) 342 char *base_dir; 343 char *dir; 344 { 345 char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp; 346 int retval, done; 347 FILE *f; 348 349 if (strcmp (dir, ".") == 0) 350 return 0; /* nothing to do */ 351 352 /* Allocate some space for our directory-munging string. */ 353 p = malloc (strlen (dir) + 1); 354 if (p == NULL) 355 return ENOMEM; 356 357 dir_where_cvsadm_lives = malloc (strlen (base_dir) + strlen (dir) + 100); 358 if (dir_where_cvsadm_lives == NULL) 359 return ENOMEM; 360 361 /* Allocate some space for the temporary string in which we will 362 construct filenames. */ 363 tmp = malloc (strlen (base_dir) + strlen (dir) + 100); 364 if (tmp == NULL) 365 return ENOMEM; 366 367 368 /* We make several passes through this loop. On the first pass, 369 we simply create the CVSADM directory in the deepest directory. 370 For each subsequent pass, we try to remove the last path 371 element from DIR, create the CVSADM directory in the remaining 372 pathname, and register the subdirectory in the newly created 373 CVSADM directory. */ 374 375 retval = done = 0; 376 377 strcpy (p, dir); 378 strcpy (dir_where_cvsadm_lives, base_dir); 379 strcat (dir_where_cvsadm_lives, "/"); 380 strcat (dir_where_cvsadm_lives, p); 381 dir_to_register = NULL; 382 383 while (1) 384 { 385 /* Create CVSADM. */ 386 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM); 387 if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST)) 388 { 389 retval = errno; 390 goto finish; 391 } 392 393 /* Create CVSADM_REP. */ 394 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP); 395 if (! isfile (tmp)) 396 { 397 /* Use Emptydir as the placeholder until the client sends 398 us the real value. This code is similar to checkout.c 399 (emptydir_name), but the code below returns errors 400 differently. */ 401 402 char *empty; 403 empty = malloc (strlen (current_parsed_root->directory) 404 + sizeof (CVSROOTADM) 405 + sizeof (CVSNULLREPOS) 406 + 3); 407 if (! empty) 408 { 409 retval = ENOMEM; 410 goto finish; 411 } 412 413 /* Create the directory name. */ 414 (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory, 415 CVSROOTADM, CVSNULLREPOS); 416 417 /* Create the directory if it doesn't exist. */ 418 if (! isfile (empty)) 419 { 420 mode_t omask; 421 omask = umask (cvsumask); 422 if (CVS_MKDIR (empty, 0777) < 0) 423 { 424 retval = errno; 425 free (empty); 426 goto finish; 427 } 428 (void) umask (omask); 429 } 430 431 432 f = CVS_FOPEN (tmp, "w"); 433 if (f == NULL) 434 { 435 retval = errno; 436 free (empty); 437 goto finish; 438 } 439 /* Write the directory name to CVSADM_REP. */ 440 if (fprintf (f, "%s\n", empty) < 0) 441 { 442 retval = errno; 443 fclose (f); 444 free (empty); 445 goto finish; 446 } 447 if (fclose (f) == EOF) 448 { 449 retval = errno; 450 free (empty); 451 goto finish; 452 } 453 454 /* Clean up after ourselves. */ 455 free (empty); 456 } 457 458 /* Create CVSADM_ENT. We open in append mode because we 459 don't want to clobber an existing Entries file. */ 460 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT); 461 f = CVS_FOPEN (tmp, "a"); 462 if (f == NULL) 463 { 464 retval = errno; 465 goto finish; 466 } 467 if (fclose (f) == EOF) 468 { 469 retval = errno; 470 goto finish; 471 } 472 473 if (dir_to_register != NULL) 474 { 475 /* FIXME: Yes, this results in duplicate entries in the 476 Entries.Log file, but it doesn't currently matter. We 477 might need to change this later on to make sure that we 478 only write one entry. */ 479 480 Subdir_Register ((List *) NULL, dir_where_cvsadm_lives, 481 dir_to_register); 482 } 483 484 if (done) 485 break; 486 487 dir_to_register = strrchr (p, '/'); 488 if (dir_to_register == NULL) 489 { 490 dir_to_register = p; 491 strcpy (dir_where_cvsadm_lives, base_dir); 492 done = 1; 493 } 494 else 495 { 496 *dir_to_register = '\0'; 497 dir_to_register++; 498 strcpy (dir_where_cvsadm_lives, base_dir); 499 strcat (dir_where_cvsadm_lives, "/"); 500 strcat (dir_where_cvsadm_lives, p); 501 } 502 } 503 504 finish: 505 free (tmp); 506 free (dir_where_cvsadm_lives); 507 free (p); 508 return retval; 509 } 510 511 /* 512 * Make directory DIR, including all intermediate directories if necessary. 513 * Returns 0 for success or errno code. 514 */ 515 static int mkdir_p PROTO((char *)); 516 517 static int 518 mkdir_p (dir) 519 char *dir; 520 { 521 char *p; 522 char *q = malloc (strlen (dir) + 1); 523 int retval; 524 525 if (q == NULL) 526 return ENOMEM; 527 528 retval = 0; 529 530 /* 531 * Skip over leading slash if present. We won't bother to try to 532 * make '/'. 533 */ 534 p = dir + 1; 535 while (1) 536 { 537 while (*p != '/' && *p != '\0') 538 ++p; 539 if (*p == '/') 540 { 541 strncpy (q, dir, p - dir); 542 q[p - dir] = '\0'; 543 if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0) 544 { 545 int saved_errno = errno; 546 547 if (saved_errno != EEXIST 548 && ((saved_errno != EACCES && saved_errno != EROFS) 549 || !isdir (q))) 550 { 551 retval = saved_errno; 552 goto done; 553 } 554 } 555 ++p; 556 } 557 else 558 { 559 if (CVS_MKDIR (dir, 0777) < 0) 560 retval = errno; 561 goto done; 562 } 563 } 564 done: 565 free (q); 566 return retval; 567 } 568 569 /* 570 * Print the error response for error code STATUS. The caller is 571 * reponsible for making sure we get back to the command loop without 572 * any further output occuring. 573 * Must be called only in contexts where it is OK to send output. 574 */ 575 static void 576 print_error (status) 577 int status; 578 { 579 char *msg; 580 char tmpstr[80]; 581 582 buf_output0 (buf_to_net, "error "); 583 msg = strerror (status); 584 if (msg == NULL) 585 { 586 sprintf (tmpstr, "unknown error %d", status); 587 msg = tmpstr; 588 } 589 buf_output0 (buf_to_net, msg); 590 buf_append_char (buf_to_net, '\n'); 591 592 buf_flush (buf_to_net, 0); 593 } 594 595 static int pending_error; 596 /* 597 * Malloc'd text for pending error. Each line must start with "E ". The 598 * last line should not end with a newline. 599 */ 600 static char *pending_error_text; 601 602 /* If an error is pending, print it and return 1. If not, return 0. 603 Must be called only in contexts where it is OK to send output. */ 604 static int 605 print_pending_error () 606 { 607 if (pending_error_text) 608 { 609 buf_output0 (buf_to_net, pending_error_text); 610 buf_append_char (buf_to_net, '\n'); 611 if (pending_error) 612 print_error (pending_error); 613 else 614 buf_output0 (buf_to_net, "error \n"); 615 616 buf_flush (buf_to_net, 0); 617 618 pending_error = 0; 619 free (pending_error_text); 620 pending_error_text = NULL; 621 return 1; 622 } 623 else if (pending_error) 624 { 625 print_error (pending_error); 626 pending_error = 0; 627 return 1; 628 } 629 else 630 return 0; 631 } 632 633 /* Is an error pending? */ 634 #define error_pending() (pending_error || pending_error_text) 635 636 static int alloc_pending PROTO ((size_t size)); 637 638 /* Allocate SIZE bytes for pending_error_text and return nonzero 639 if we could do it. */ 640 static int 641 alloc_pending (size) 642 size_t size; 643 { 644 if (error_pending ()) 645 /* Probably alloc_pending callers will have already checked for 646 this case. But we might as well handle it if they don't, I 647 guess. */ 648 return 0; 649 pending_error_text = malloc (size); 650 if (pending_error_text == NULL) 651 { 652 pending_error = ENOMEM; 653 return 0; 654 } 655 return 1; 656 } 657 658 static void serve_is_modified PROTO ((char *)); 659 660 static int supported_response PROTO ((char *)); 661 662 static int 663 supported_response (name) 664 char *name; 665 { 666 struct response *rs; 667 668 for (rs = responses; rs->name != NULL; ++rs) 669 if (strcmp (rs->name, name) == 0) 670 return rs->status == rs_supported; 671 error (1, 0, "internal error: testing support for unknown response?"); 672 /* NOTREACHED */ 673 return 0; 674 } 675 676 static void 677 serve_valid_responses (arg) 678 char *arg; 679 { 680 char *p = arg; 681 char *q; 682 struct response *rs; 683 do 684 { 685 q = strchr (p, ' '); 686 if (q != NULL) 687 *q++ = '\0'; 688 for (rs = responses; rs->name != NULL; ++rs) 689 { 690 if (strcmp (rs->name, p) == 0) 691 break; 692 } 693 if (rs->name == NULL) 694 /* 695 * It is a response we have never heard of (and thus never 696 * will want to use). So don't worry about it. 697 */ 698 ; 699 else 700 rs->status = rs_supported; 701 p = q; 702 } while (q != NULL); 703 for (rs = responses; rs->name != NULL; ++rs) 704 { 705 if (rs->status == rs_essential) 706 { 707 buf_output0 (buf_to_net, "E response `"); 708 buf_output0 (buf_to_net, rs->name); 709 buf_output0 (buf_to_net, "' not supported by client\nerror \n"); 710 711 /* FIXME: This call to buf_flush could conceivably 712 cause deadlock, as noted in server_cleanup. */ 713 buf_flush (buf_to_net, 1); 714 715 /* I'm doing this manually rather than via error_exit () 716 because I'm not sure whether we want to call server_cleanup. 717 Needs more investigation.... */ 718 719 #ifdef SYSTEM_CLEANUP 720 /* Hook for OS-specific behavior, for example socket subsystems on 721 NT and OS2 or dealing with windows and arguments on Mac. */ 722 SYSTEM_CLEANUP (); 723 #endif 724 725 exit (EXIT_FAILURE); 726 } 727 else if (rs->status == rs_optional) 728 rs->status = rs_not_supported; 729 } 730 } 731 732 static void 733 serve_root (arg) 734 char *arg; 735 { 736 char *env; 737 char *path; 738 739 if (error_pending()) return; 740 741 if (!isabsolute (arg)) 742 { 743 if (alloc_pending (80 + strlen (arg))) 744 sprintf (pending_error_text, 745 "E Root %s must be an absolute pathname", arg); 746 return; 747 } 748 749 /* Sending "Root" twice is illegal. 750 751 The other way to handle a duplicate Root requests would be as a 752 request to clear out all state and start over as if it was a 753 new connection. Doing this would cause interoperability 754 headaches, so it should be a different request, if there is 755 any reason why such a feature is needed. */ 756 if (current_parsed_root != NULL) 757 { 758 if (alloc_pending (80 + strlen (arg))) 759 sprintf (pending_error_text, 760 "E Protocol error: Duplicate Root request, for %s", arg); 761 return; 762 } 763 764 #ifdef AUTH_SERVER_SUPPORT 765 if (Pserver_Repos != NULL) 766 { 767 if (strcmp (Pserver_Repos, arg) != 0) 768 { 769 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg))) 770 /* The explicitness is to aid people who are writing clients. 771 I don't see how this information could help an 772 attacker. */ 773 sprintf (pending_error_text, "\ 774 E Protocol error: Root says \"%s\" but pserver says \"%s\"", 775 arg, Pserver_Repos); 776 } 777 } 778 #endif 779 780 if (current_parsed_root != NULL) 781 free_cvsroot_t (current_parsed_root); 782 current_parsed_root = local_cvsroot (arg); 783 784 /* For pserver, this will already have happened, and the call will do 785 nothing. But for rsh, we need to do it now. */ 786 parse_config (current_parsed_root->directory); 787 788 path = malloc (strlen (current_parsed_root->directory) 789 + sizeof (CVSROOTADM) 790 + 2); 791 if (path == NULL) 792 { 793 pending_error = ENOMEM; 794 return; 795 } 796 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM); 797 if (readonlyfs == 0 && !isaccessible (path, R_OK | X_OK)) 798 { 799 int save_errno = errno; 800 if (alloc_pending (80 + strlen (path))) 801 sprintf (pending_error_text, "E Cannot access %s", path); 802 pending_error = save_errno; 803 } 804 free (path); 805 806 #ifdef HAVE_PUTENV 807 env = malloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2); 808 if (env == NULL) 809 { 810 pending_error = ENOMEM; 811 return; 812 } 813 (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory); 814 (void) putenv (env); 815 /* do not free env, as putenv has control of it */ 816 #endif 817 } 818 819 static int max_dotdot_limit = 0; 820 821 /* Is this pathname OK to recurse into when we are running as the server? 822 If not, call error() with a fatal error. */ 823 void 824 server_pathname_check (path) 825 char *path; 826 { 827 /* An absolute pathname is almost surely a path on the *client* machine, 828 and is unlikely to do us any good here. It also is probably capable 829 of being a security hole in the anonymous readonly case. */ 830 if (isabsolute (path)) 831 /* Giving an error is actually kind of a cop-out, in the sense 832 that it would be nice for "cvs co -d /foo/bar/baz" to work. 833 A quick fix in the server would be requiring Max-dotdot of 834 at least one if pathnames are absolute, and then putting 835 /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff. 836 A cleaner fix in the server might be to decouple the 837 pathnames we pass back to the client from pathnames in our 838 temp directory (this would also probably remove the need 839 for Max-dotdot). A fix in the client would have the client 840 turn it into "cd /foo/bar; cvs co -d baz" (more or less). 841 This probably has some problems with pathnames which appear 842 in messages. */ 843 error (1, 0, "absolute pathname `%s' illegal for server", path); 844 if (pathname_levels (path) > max_dotdot_limit) 845 { 846 /* Similar to the isabsolute case in security implications. */ 847 error (0, 0, "protocol error: `%s' contains more leading ..", path); 848 error (1, 0, "than the %d which Max-dotdot specified", 849 max_dotdot_limit); 850 } 851 } 852 853 static int outside_root PROTO ((char *)); 854 855 /* Is file or directory REPOS an absolute pathname within the 856 current_parsed_root->directory? If yes, return 0. If no, set pending_error 857 and return 1. */ 858 static int 859 outside_root (repos) 860 char *repos; 861 { 862 size_t repos_len = strlen (repos); 863 size_t root_len = strlen (current_parsed_root->directory); 864 865 /* I think isabsolute (repos) should always be true, and that 866 any RELATIVE_REPOS stuff should only be in CVS/Repository 867 files, not the protocol (for compatibility), but I'm putting 868 in the isabsolute check just in case. */ 869 if (!isabsolute (repos)) 870 { 871 if (alloc_pending (repos_len + 80)) 872 sprintf (pending_error_text, "\ 873 E protocol error: %s is not absolute", repos); 874 return 1; 875 } 876 877 if (repos_len < root_len 878 || strncmp (current_parsed_root->directory, repos, root_len) != 0) 879 { 880 not_within: 881 if (alloc_pending (strlen (current_parsed_root->directory) 882 + strlen (repos) 883 + 80)) 884 sprintf (pending_error_text, "\ 885 E protocol error: directory '%s' not within root '%s'", 886 repos, current_parsed_root->directory); 887 return 1; 888 } 889 if (repos_len > root_len) 890 { 891 if (repos[root_len] != '/') 892 goto not_within; 893 if (pathname_levels (repos + root_len + 1) > 0) 894 goto not_within; 895 } 896 return 0; 897 } 898 899 static int outside_dir PROTO ((char *)); 900 901 /* Is file or directory FILE outside the current directory (that is, does 902 it contain '/')? If no, return 0. If yes, set pending_error 903 and return 1. */ 904 static int 905 outside_dir (file) 906 char *file; 907 { 908 if (strchr (file, '/') != NULL) 909 { 910 if (alloc_pending (strlen (file) 911 + 80)) 912 sprintf (pending_error_text, "\ 913 E protocol error: directory '%s' not within current directory", 914 file); 915 return 1; 916 } 917 return 0; 918 } 919 920 /* 921 * Add as many directories to the temp directory as the client tells us it 922 * will use "..", so we never try to access something outside the temp 923 * directory via "..". 924 */ 925 static void 926 serve_max_dotdot (arg) 927 char *arg; 928 { 929 int lim = atoi (arg); 930 int i; 931 char *p; 932 933 if (lim < 0) 934 return; 935 p = malloc (strlen (server_temp_dir) + 2 * lim + 10); 936 if (p == NULL) 937 { 938 pending_error = ENOMEM; 939 return; 940 } 941 strcpy (p, server_temp_dir); 942 for (i = 0; i < lim; ++i) 943 strcat (p, "/d"); 944 if (server_temp_dir != orig_server_temp_dir) 945 free (server_temp_dir); 946 server_temp_dir = p; 947 max_dotdot_limit = lim; 948 } 949 950 static char *dir_name; 951 952 static void 953 dirswitch (dir, repos) 954 char *dir; 955 char *repos; 956 { 957 int status; 958 FILE *f; 959 size_t dir_len; 960 961 server_write_entries (); 962 963 if (error_pending()) return; 964 965 /* Check for bad directory name. 966 967 FIXME: could/should unify these checks with server_pathname_check 968 except they need to report errors differently. */ 969 if (isabsolute (dir)) 970 { 971 if (alloc_pending (80 + strlen (dir))) 972 sprintf (pending_error_text, 973 "E absolute pathname `%s' illegal for server", dir); 974 return; 975 } 976 if (pathname_levels (dir) > max_dotdot_limit) 977 { 978 if (alloc_pending (80 + strlen (dir))) 979 sprintf (pending_error_text, 980 "E protocol error: `%s' has too many ..", dir); 981 return; 982 } 983 984 dir_len = strlen (dir); 985 986 /* Check for a trailing '/'. This is not ISDIRSEP because \ in the 987 protocol is an ordinary character, not a directory separator (of 988 course, it is perhaps unwise to use it in directory names, but that 989 is another issue). */ 990 if (dir_len > 0 991 && dir[dir_len - 1] == '/') 992 { 993 if (alloc_pending (80 + dir_len)) 994 sprintf (pending_error_text, 995 "E protocol error: invalid directory syntax in %s", dir); 996 return; 997 } 998 999 if (dir_name != NULL) 1000 free (dir_name); 1001 1002 dir_name = malloc (strlen (server_temp_dir) + dir_len + 40); 1003 if (dir_name == NULL) 1004 { 1005 pending_error = ENOMEM; 1006 return; 1007 } 1008 1009 strcpy (dir_name, server_temp_dir); 1010 strcat (dir_name, "/"); 1011 strcat (dir_name, dir); 1012 1013 status = mkdir_p (dir_name); 1014 if (status != 0 1015 && status != EEXIST) 1016 { 1017 if (alloc_pending (80 + strlen (dir_name))) 1018 sprintf (pending_error_text, "E cannot mkdir %s", dir_name); 1019 pending_error = status; 1020 return; 1021 } 1022 1023 /* We need to create adm directories in all path elements because 1024 we want the server to descend them, even if the client hasn't 1025 sent the appropriate "Argument xxx" command to match the 1026 already-sent "Directory xxx" command. See recurse.c 1027 (start_recursion) for a big discussion of this. */ 1028 1029 status = create_adm_p (server_temp_dir, dir); 1030 if (status != 0) 1031 { 1032 if (alloc_pending (80 + strlen (dir_name))) 1033 sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name); 1034 pending_error = status; 1035 return; 1036 } 1037 1038 if ( CVS_CHDIR (dir_name) < 0) 1039 { 1040 int save_errno = errno; 1041 if (alloc_pending (80 + strlen (dir_name))) 1042 sprintf (pending_error_text, "E cannot change to %s", dir_name); 1043 pending_error = save_errno; 1044 return; 1045 } 1046 /* 1047 * This is pretty much like calling Create_Admin, but Create_Admin doesn't 1048 * report errors in the right way for us. 1049 */ 1050 if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST)) 1051 { 1052 int save_errno = errno; 1053 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM))) 1054 sprintf (pending_error_text, 1055 "E cannot mkdir %s/%s", dir_name, CVSADM); 1056 pending_error = save_errno; 1057 return; 1058 } 1059 1060 /* The following will overwrite the contents of CVSADM_REP. This 1061 is the correct behavior -- mkdir_p may have written a 1062 placeholder value to this file and we need to insert the 1063 correct value. */ 1064 1065 f = CVS_FOPEN (CVSADM_REP, "w"); 1066 if (f == NULL) 1067 { 1068 int save_errno = errno; 1069 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) 1070 sprintf (pending_error_text, 1071 "E cannot open %s/%s", dir_name, CVSADM_REP); 1072 pending_error = save_errno; 1073 return; 1074 } 1075 if (fprintf (f, "%s", repos) < 0) 1076 { 1077 int save_errno = errno; 1078 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) 1079 sprintf (pending_error_text, 1080 "E error writing %s/%s", dir_name, CVSADM_REP); 1081 pending_error = save_errno; 1082 fclose (f); 1083 return; 1084 } 1085 /* Non-remote CVS handles a module representing the entire tree 1086 (e.g., an entry like ``world -a .'') by putting /. at the end 1087 of the Repository file, so we do the same. */ 1088 if (strcmp (dir, ".") == 0 1089 && current_parsed_root != NULL 1090 && current_parsed_root->directory != NULL 1091 && strcmp (current_parsed_root->directory, repos) == 0) 1092 { 1093 if (fprintf (f, "/.") < 0) 1094 { 1095 int save_errno = errno; 1096 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) 1097 sprintf (pending_error_text, 1098 "E error writing %s/%s", dir_name, CVSADM_REP); 1099 pending_error = save_errno; 1100 fclose (f); 1101 return; 1102 } 1103 } 1104 if (fprintf (f, "\n") < 0) 1105 { 1106 int save_errno = errno; 1107 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) 1108 sprintf (pending_error_text, 1109 "E error writing %s/%s", dir_name, CVSADM_REP); 1110 pending_error = save_errno; 1111 fclose (f); 1112 return; 1113 } 1114 if (fclose (f) == EOF) 1115 { 1116 int save_errno = errno; 1117 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) 1118 sprintf (pending_error_text, 1119 "E error closing %s/%s", dir_name, CVSADM_REP); 1120 pending_error = save_errno; 1121 return; 1122 } 1123 /* We open in append mode because we don't want to clobber an 1124 existing Entries file. */ 1125 f = CVS_FOPEN (CVSADM_ENT, "a"); 1126 if (f == NULL) 1127 { 1128 int save_errno = errno; 1129 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1130 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); 1131 pending_error = save_errno; 1132 return; 1133 } 1134 if (fclose (f) == EOF) 1135 { 1136 int save_errno = errno; 1137 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1138 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); 1139 pending_error = save_errno; 1140 return; 1141 } 1142 } 1143 1144 static void 1145 serve_repository (arg) 1146 char *arg; 1147 { 1148 if (alloc_pending (80)) 1149 strcpy (pending_error_text, 1150 "E Repository request is obsolete; aborted"); 1151 return; 1152 } 1153 1154 static void 1155 serve_directory (arg) 1156 char *arg; 1157 { 1158 int status; 1159 char *repos; 1160 1161 status = buf_read_line (buf_from_net, &repos, (int *) NULL); 1162 if (status == 0) 1163 { 1164 if (!outside_root (repos)) 1165 dirswitch (arg, repos); 1166 free (repos); 1167 } 1168 else if (status == -2) 1169 { 1170 pending_error = ENOMEM; 1171 } 1172 else 1173 { 1174 pending_error_text = malloc (80 + strlen (arg)); 1175 if (pending_error_text == NULL) 1176 { 1177 pending_error = ENOMEM; 1178 } 1179 else if (status == -1) 1180 { 1181 sprintf (pending_error_text, 1182 "E end of file reading mode for %s", arg); 1183 } 1184 else 1185 { 1186 sprintf (pending_error_text, 1187 "E error reading mode for %s", arg); 1188 pending_error = status; 1189 } 1190 } 1191 } 1192 1193 static void 1194 serve_static_directory (arg) 1195 char *arg; 1196 { 1197 FILE *f; 1198 1199 if (error_pending ()) return; 1200 1201 f = CVS_FOPEN (CVSADM_ENTSTAT, "w+"); 1202 if (f == NULL) 1203 { 1204 int save_errno = errno; 1205 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) 1206 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT); 1207 pending_error = save_errno; 1208 return; 1209 } 1210 if (fclose (f) == EOF) 1211 { 1212 int save_errno = errno; 1213 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) 1214 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT); 1215 pending_error = save_errno; 1216 return; 1217 } 1218 } 1219 1220 static void 1221 serve_sticky (arg) 1222 char *arg; 1223 { 1224 FILE *f; 1225 1226 if (error_pending ()) return; 1227 1228 f = CVS_FOPEN (CVSADM_TAG, "w+"); 1229 if (f == NULL) 1230 { 1231 int save_errno = errno; 1232 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1233 sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG); 1234 pending_error = save_errno; 1235 return; 1236 } 1237 if (fprintf (f, "%s\n", arg) < 0) 1238 { 1239 int save_errno = errno; 1240 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1241 sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG); 1242 pending_error = save_errno; 1243 return; 1244 } 1245 if (fclose (f) == EOF) 1246 { 1247 int save_errno = errno; 1248 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1249 sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG); 1250 pending_error = save_errno; 1251 return; 1252 } 1253 } 1254 1255 /* 1256 * Read SIZE bytes from buf_from_net, write them to FILE. 1257 * 1258 * Currently this isn't really used for receiving parts of a file -- 1259 * the file is still sent over in one chunk. But if/when we get 1260 * spiffy in-process gzip support working, perhaps the compressed 1261 * pieces could be sent over as they're ready, if the network is fast 1262 * enough. Or something. 1263 */ 1264 static void 1265 receive_partial_file (size, file) 1266 int size; 1267 int file; 1268 { 1269 while (size > 0) 1270 { 1271 int status, nread; 1272 char *data; 1273 1274 status = buf_read_data (buf_from_net, size, &data, &nread); 1275 if (status != 0) 1276 { 1277 if (status == -2) 1278 pending_error = ENOMEM; 1279 else 1280 { 1281 pending_error_text = malloc (80); 1282 if (pending_error_text == NULL) 1283 pending_error = ENOMEM; 1284 else if (status == -1) 1285 { 1286 sprintf (pending_error_text, 1287 "E premature end of file from client"); 1288 pending_error = 0; 1289 } 1290 else 1291 { 1292 sprintf (pending_error_text, 1293 "E error reading from client"); 1294 pending_error = status; 1295 } 1296 } 1297 return; 1298 } 1299 1300 size -= nread; 1301 1302 while (nread > 0) 1303 { 1304 int nwrote; 1305 1306 nwrote = write (file, data, nread); 1307 if (nwrote < 0) 1308 { 1309 int save_errno = errno; 1310 if (alloc_pending (40)) 1311 strcpy (pending_error_text, "E unable to write"); 1312 pending_error = save_errno; 1313 1314 /* Read and discard the file data. */ 1315 while (size > 0) 1316 { 1317 int status, nread; 1318 char *data; 1319 1320 status = buf_read_data (buf_from_net, size, &data, &nread); 1321 if (status != 0) 1322 return; 1323 size -= nread; 1324 } 1325 1326 return; 1327 } 1328 nread -= nwrote; 1329 data += nwrote; 1330 } 1331 } 1332 } 1333 1334 /* Receive SIZE bytes, write to filename FILE. */ 1335 static void 1336 receive_file (size, file, gzipped) 1337 int size; 1338 char *file; 1339 int gzipped; 1340 { 1341 int fd; 1342 char *arg = file; 1343 1344 /* Write the file. */ 1345 fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1346 if (fd < 0) 1347 { 1348 int save_errno = errno; 1349 if (alloc_pending (40 + strlen (arg))) 1350 sprintf (pending_error_text, "E cannot open %s", arg); 1351 pending_error = save_errno; 1352 return; 1353 } 1354 1355 if (gzipped) 1356 { 1357 /* Using gunzip_and_write isn't really a high-performance 1358 approach, because it keeps the whole thing in memory 1359 (contiguous memory, worse yet). But it seems easier to 1360 code than the alternative (and less vulnerable to subtle 1361 bugs). Given that this feature is mainly for 1362 compatibility, that is the better tradeoff. */ 1363 1364 int toread = size; 1365 char *filebuf; 1366 char *p; 1367 1368 filebuf = malloc (size); 1369 p = filebuf; 1370 /* If NULL, we still want to read the data and discard it. */ 1371 1372 while (toread > 0) 1373 { 1374 int status, nread; 1375 char *data; 1376 1377 status = buf_read_data (buf_from_net, toread, &data, &nread); 1378 if (status != 0) 1379 { 1380 if (status == -2) 1381 pending_error = ENOMEM; 1382 else 1383 { 1384 pending_error_text = malloc (80); 1385 if (pending_error_text == NULL) 1386 pending_error = ENOMEM; 1387 else if (status == -1) 1388 { 1389 sprintf (pending_error_text, 1390 "E premature end of file from client"); 1391 pending_error = 0; 1392 } 1393 else 1394 { 1395 sprintf (pending_error_text, 1396 "E error reading from client"); 1397 pending_error = status; 1398 } 1399 } 1400 return; 1401 } 1402 1403 toread -= nread; 1404 1405 if (filebuf != NULL) 1406 { 1407 memcpy (p, data, nread); 1408 p += nread; 1409 } 1410 } 1411 if (filebuf == NULL) 1412 { 1413 pending_error = ENOMEM; 1414 goto out; 1415 } 1416 1417 if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size)) 1418 { 1419 if (alloc_pending (80)) 1420 sprintf (pending_error_text, 1421 "E aborting due to compression error"); 1422 } 1423 free (filebuf); 1424 } 1425 else 1426 receive_partial_file (size, fd); 1427 1428 if (pending_error_text) 1429 { 1430 char *p = realloc (pending_error_text, 1431 strlen (pending_error_text) + strlen (arg) + 30); 1432 if (p) 1433 { 1434 pending_error_text = p; 1435 sprintf (p + strlen (p), ", file %s", arg); 1436 } 1437 /* else original string is supposed to be unchanged */ 1438 } 1439 1440 out: 1441 if (close (fd) < 0 && !error_pending ()) 1442 { 1443 int save_errno = errno; 1444 if (alloc_pending (40 + strlen (arg))) 1445 sprintf (pending_error_text, "E cannot close %s", arg); 1446 pending_error = save_errno; 1447 return; 1448 } 1449 } 1450 1451 /* Kopt for the next file sent in Modified or Is-modified. */ 1452 static char *kopt; 1453 1454 /* Timestamp (Checkin-time) for next file sent in Modified or 1455 Is-modified. */ 1456 static int checkin_time_valid; 1457 static time_t checkin_time; 1458 1459 static void serve_modified PROTO ((char *)); 1460 1461 static void 1462 serve_modified (arg) 1463 char *arg; 1464 { 1465 int size, status; 1466 char *size_text; 1467 char *mode_text; 1468 1469 int gzipped = 0; 1470 1471 /* 1472 * This used to return immediately if error_pending () was true. 1473 * However, that fails, because it causes each line of the file to 1474 * be echoed back to the client as an unrecognized command. The 1475 * client isn't reading from the socket, so eventually both 1476 * processes block trying to write to the other. Now, we try to 1477 * read the file if we can. 1478 */ 1479 1480 status = buf_read_line (buf_from_net, &mode_text, (int *) NULL); 1481 if (status != 0) 1482 { 1483 if (status == -2) 1484 pending_error = ENOMEM; 1485 else 1486 { 1487 pending_error_text = malloc (80 + strlen (arg)); 1488 if (pending_error_text == NULL) 1489 pending_error = ENOMEM; 1490 else 1491 { 1492 if (status == -1) 1493 sprintf (pending_error_text, 1494 "E end of file reading mode for %s", arg); 1495 else 1496 { 1497 sprintf (pending_error_text, 1498 "E error reading mode for %s", arg); 1499 pending_error = status; 1500 } 1501 } 1502 } 1503 return; 1504 } 1505 1506 status = buf_read_line (buf_from_net, &size_text, (int *) NULL); 1507 if (status != 0) 1508 { 1509 if (status == -2) 1510 pending_error = ENOMEM; 1511 else 1512 { 1513 pending_error_text = malloc (80 + strlen (arg)); 1514 if (pending_error_text == NULL) 1515 pending_error = ENOMEM; 1516 else 1517 { 1518 if (status == -1) 1519 sprintf (pending_error_text, 1520 "E end of file reading size for %s", arg); 1521 else 1522 { 1523 sprintf (pending_error_text, 1524 "E error reading size for %s", arg); 1525 pending_error = status; 1526 } 1527 } 1528 } 1529 free (mode_text); 1530 return; 1531 } 1532 if (size_text[0] == 'z') 1533 { 1534 gzipped = 1; 1535 size = atoi (size_text + 1); 1536 } 1537 else 1538 size = atoi (size_text); 1539 free (size_text); 1540 1541 if (error_pending ()) 1542 { 1543 /* Now that we know the size, read and discard the file data. */ 1544 while (size > 0) 1545 { 1546 int status, nread; 1547 char *data; 1548 1549 status = buf_read_data (buf_from_net, size, &data, &nread); 1550 if (status != 0) 1551 return; 1552 size -= nread; 1553 } 1554 free (mode_text); 1555 return; 1556 } 1557 1558 if (outside_dir (arg)) 1559 { 1560 free (mode_text); 1561 return; 1562 } 1563 1564 if (size >= 0) 1565 { 1566 receive_file (size, arg, gzipped); 1567 if (error_pending ()) 1568 { 1569 free (mode_text); 1570 return; 1571 } 1572 } 1573 1574 if (checkin_time_valid) 1575 { 1576 struct utimbuf t; 1577 1578 memset (&t, 0, sizeof (t)); 1579 t.modtime = t.actime = checkin_time; 1580 if (utime (arg, &t) < 0) 1581 { 1582 int save_errno = errno; 1583 if (alloc_pending (80 + strlen (arg))) 1584 sprintf (pending_error_text, "E cannot utime %s", arg); 1585 pending_error = save_errno; 1586 free (mode_text); 1587 return; 1588 } 1589 checkin_time_valid = 0; 1590 } 1591 1592 { 1593 int status = change_mode (arg, mode_text, 0); 1594 free (mode_text); 1595 if (status) 1596 { 1597 if (alloc_pending (40 + strlen (arg))) 1598 sprintf (pending_error_text, 1599 "E cannot change mode for %s", arg); 1600 pending_error = status; 1601 return; 1602 } 1603 } 1604 1605 /* Make sure that the Entries indicate the right kopt. We probably 1606 could do this even in the non-kopt case and, I think, save a stat() 1607 call in time_stamp_server. But for conservatism I'm leaving the 1608 non-kopt case alone. */ 1609 if (kopt != NULL) 1610 serve_is_modified (arg); 1611 } 1612 1613 1614 static void 1615 serve_enable_unchanged (arg) 1616 char *arg; 1617 { 1618 } 1619 1620 struct an_entry { 1621 struct an_entry *next; 1622 char *entry; 1623 }; 1624 1625 static struct an_entry *entries; 1626 1627 static void serve_unchanged PROTO ((char *)); 1628 1629 static void 1630 serve_unchanged (arg) 1631 char *arg; 1632 { 1633 struct an_entry *p; 1634 char *name; 1635 char *cp; 1636 char *timefield; 1637 1638 if (error_pending ()) 1639 return; 1640 1641 if (outside_dir (arg)) 1642 return; 1643 1644 /* Rewrite entries file to have `=' in timestamp field. */ 1645 for (p = entries; p != NULL; p = p->next) 1646 { 1647 name = p->entry + 1; 1648 cp = strchr (name, '/'); 1649 if (cp != NULL 1650 && strlen (arg) == cp - name 1651 && strncmp (arg, name, cp - name) == 0) 1652 { 1653 timefield = strchr (cp + 1, '/') + 1; 1654 if (*timefield != '=') 1655 { 1656 cp = timefield + strlen (timefield); 1657 cp[1] = '\0'; 1658 while (cp > timefield) 1659 { 1660 *cp = cp[-1]; 1661 --cp; 1662 } 1663 *timefield = '='; 1664 } 1665 break; 1666 } 1667 } 1668 } 1669 1670 static void 1671 serve_is_modified (arg) 1672 char *arg; 1673 { 1674 struct an_entry *p; 1675 char *name; 1676 char *cp; 1677 char *timefield; 1678 /* Have we found this file in "entries" yet. */ 1679 int found; 1680 1681 if (error_pending ()) 1682 return; 1683 1684 if (outside_dir (arg)) 1685 return; 1686 1687 /* Rewrite entries file to have `M' in timestamp field. */ 1688 found = 0; 1689 for (p = entries; p != NULL; p = p->next) 1690 { 1691 name = p->entry + 1; 1692 cp = strchr (name, '/'); 1693 if (cp != NULL 1694 && strlen (arg) == cp - name 1695 && strncmp (arg, name, cp - name) == 0) 1696 { 1697 timefield = strchr (cp + 1, '/') + 1; 1698 if (!(timefield[0] == 'M' && timefield[1] == '/')) 1699 { 1700 cp = timefield + strlen (timefield); 1701 cp[1] = '\0'; 1702 while (cp > timefield) 1703 { 1704 *cp = cp[-1]; 1705 --cp; 1706 } 1707 *timefield = 'M'; 1708 } 1709 if (kopt != NULL) 1710 { 1711 if (alloc_pending (strlen (name) + 80)) 1712 sprintf (pending_error_text, 1713 "E protocol error: both Kopt and Entry for %s", 1714 arg); 1715 free (kopt); 1716 kopt = NULL; 1717 return; 1718 } 1719 found = 1; 1720 break; 1721 } 1722 } 1723 if (!found) 1724 { 1725 /* We got Is-modified but no Entry. Add a dummy entry. 1726 The "D" timestamp is what makes it a dummy. */ 1727 p = (struct an_entry *) malloc (sizeof (struct an_entry)); 1728 if (p == NULL) 1729 { 1730 pending_error = ENOMEM; 1731 return; 1732 } 1733 p->entry = malloc (strlen (arg) + 80); 1734 if (p->entry == NULL) 1735 { 1736 pending_error = ENOMEM; 1737 free (p); 1738 return; 1739 } 1740 strcpy (p->entry, "/"); 1741 strcat (p->entry, arg); 1742 strcat (p->entry, "//D/"); 1743 if (kopt != NULL) 1744 { 1745 strcat (p->entry, kopt); 1746 free (kopt); 1747 kopt = NULL; 1748 } 1749 strcat (p->entry, "/"); 1750 p->next = entries; 1751 entries = p; 1752 } 1753 } 1754 1755 static void serve_entry PROTO ((char *)); 1756 1757 static void 1758 serve_entry (arg) 1759 char *arg; 1760 { 1761 struct an_entry *p; 1762 char *cp; 1763 if (error_pending()) return; 1764 p = (struct an_entry *) malloc (sizeof (struct an_entry)); 1765 if (p == NULL) 1766 { 1767 pending_error = ENOMEM; 1768 return; 1769 } 1770 /* Leave space for serve_unchanged to write '=' if it wants. */ 1771 cp = malloc (strlen (arg) + 2); 1772 if (cp == NULL) 1773 { 1774 pending_error = ENOMEM; 1775 return; 1776 } 1777 strcpy (cp, arg); 1778 p->next = entries; 1779 p->entry = cp; 1780 entries = p; 1781 } 1782 1783 static void serve_kopt PROTO ((char *)); 1784 1785 static void 1786 serve_kopt (arg) 1787 char *arg; 1788 { 1789 if (error_pending ()) 1790 return; 1791 1792 if (kopt != NULL) 1793 { 1794 if (alloc_pending (80 + strlen (arg))) 1795 sprintf (pending_error_text, 1796 "E protocol error: duplicate Kopt request: %s", arg); 1797 return; 1798 } 1799 1800 /* Do some sanity checks. In particular, that it is not too long. 1801 This lets the rest of the code not worry so much about buffer 1802 overrun attacks. Probably should call RCS_check_kflag here, 1803 but that would mean changing RCS_check_kflag to handle errors 1804 other than via exit(), fprintf(), and such. */ 1805 if (strlen (arg) > 10) 1806 { 1807 if (alloc_pending (80 + strlen (arg))) 1808 sprintf (pending_error_text, 1809 "E protocol error: invalid Kopt request: %s", arg); 1810 return; 1811 } 1812 1813 kopt = malloc (strlen (arg) + 1); 1814 if (kopt == NULL) 1815 { 1816 pending_error = ENOMEM; 1817 return; 1818 } 1819 strcpy (kopt, arg); 1820 } 1821 1822 static void serve_checkin_time PROTO ((char *)); 1823 1824 static void 1825 serve_checkin_time (arg) 1826 char *arg; 1827 { 1828 if (error_pending ()) 1829 return; 1830 1831 if (checkin_time_valid) 1832 { 1833 if (alloc_pending (80 + strlen (arg))) 1834 sprintf (pending_error_text, 1835 "E protocol error: duplicate Checkin-time request: %s", 1836 arg); 1837 return; 1838 } 1839 1840 checkin_time = get_date (arg, NULL); 1841 if (checkin_time == (time_t)-1) 1842 { 1843 if (alloc_pending (80 + strlen (arg))) 1844 sprintf (pending_error_text, "E cannot parse date %s", arg); 1845 return; 1846 } 1847 checkin_time_valid = 1; 1848 } 1849 1850 static void 1851 server_write_entries () 1852 { 1853 FILE *f; 1854 struct an_entry *p; 1855 struct an_entry *q; 1856 1857 if (entries == NULL) 1858 return; 1859 1860 f = NULL; 1861 /* Note that we free all the entries regardless of errors. */ 1862 if (!error_pending ()) 1863 { 1864 /* We open in append mode because we don't want to clobber an 1865 existing Entries file. If we are checking out a module 1866 which explicitly lists more than one file in a particular 1867 directory, then we will wind up calling 1868 server_write_entries for each such file. */ 1869 f = CVS_FOPEN (CVSADM_ENT, "a"); 1870 if (f == NULL) 1871 { 1872 int save_errno = errno; 1873 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1874 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); 1875 pending_error = save_errno; 1876 } 1877 } 1878 for (p = entries; p != NULL;) 1879 { 1880 if (!error_pending ()) 1881 { 1882 if (fprintf (f, "%s\n", p->entry) < 0) 1883 { 1884 int save_errno = errno; 1885 if (alloc_pending (80 + strlen(CVSADM_ENT))) 1886 sprintf (pending_error_text, 1887 "E cannot write to %s", CVSADM_ENT); 1888 pending_error = save_errno; 1889 } 1890 } 1891 free (p->entry); 1892 q = p->next; 1893 free (p); 1894 p = q; 1895 } 1896 entries = NULL; 1897 if (f != NULL && fclose (f) == EOF && !error_pending ()) 1898 { 1899 int save_errno = errno; 1900 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1901 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); 1902 pending_error = save_errno; 1903 } 1904 } 1905 1906 struct notify_note { 1907 /* Directory in which this notification happens. malloc'd*/ 1908 char *dir; 1909 1910 /* malloc'd. */ 1911 char *filename; 1912 1913 /* The following three all in one malloc'd block, pointed to by TYPE. 1914 Each '\0' terminated. */ 1915 /* "E" or "U". */ 1916 char *type; 1917 /* time+host+dir */ 1918 char *val; 1919 char *watches; 1920 1921 struct notify_note *next; 1922 }; 1923 1924 static struct notify_note *notify_list; 1925 /* Used while building list, to point to the last node that already exists. */ 1926 static struct notify_note *last_node; 1927 1928 static void serve_notify PROTO ((char *)); 1929 1930 static void 1931 serve_notify (arg) 1932 char *arg; 1933 { 1934 struct notify_note *new = NULL; 1935 char *data = NULL; 1936 int status; 1937 1938 if (error_pending ()) return; 1939 1940 if (outside_dir (arg)) 1941 return; 1942 1943 if (dir_name == NULL) 1944 goto error; 1945 1946 new = (struct notify_note *) malloc (sizeof (struct notify_note)); 1947 if (new == NULL) 1948 { 1949 pending_error = ENOMEM; 1950 return; 1951 } 1952 new->dir = malloc (strlen (dir_name) + 1); 1953 new->filename = malloc (strlen (arg) + 1); 1954 if (new->dir == NULL || new->filename == NULL) 1955 { 1956 pending_error = ENOMEM; 1957 if (new->dir != NULL) 1958 free (new->dir); 1959 free (new); 1960 return; 1961 } 1962 strcpy (new->dir, dir_name); 1963 strcpy (new->filename, arg); 1964 1965 status = buf_read_line (buf_from_net, &data, (int *) NULL); 1966 if (status != 0) 1967 { 1968 if (status == -2) 1969 pending_error = ENOMEM; 1970 else 1971 { 1972 pending_error_text = malloc (80 + strlen (arg)); 1973 if (pending_error_text == NULL) 1974 pending_error = ENOMEM; 1975 else 1976 { 1977 if (status == -1) 1978 sprintf (pending_error_text, 1979 "E end of file reading notification for %s", arg); 1980 else 1981 { 1982 sprintf (pending_error_text, 1983 "E error reading notification for %s", arg); 1984 pending_error = status; 1985 } 1986 } 1987 } 1988 free (new->filename); 1989 free (new->dir); 1990 free (new); 1991 } 1992 else 1993 { 1994 char *cp; 1995 1996 if (strchr (data, '+')) 1997 goto error; 1998 1999 new->type = data; 2000 if (data[1] != '\t') 2001 goto error; 2002 data[1] = '\0'; 2003 cp = data + 2; 2004 new->val = cp; 2005 cp = strchr (cp, '\t'); 2006 if (cp == NULL) 2007 goto error; 2008 *cp++ = '+'; 2009 cp = strchr (cp, '\t'); 2010 if (cp == NULL) 2011 goto error; 2012 *cp++ = '+'; 2013 cp = strchr (cp, '\t'); 2014 if (cp == NULL) 2015 goto error; 2016 *cp++ = '\0'; 2017 new->watches = cp; 2018 /* If there is another tab, ignore everything after it, 2019 for future expansion. */ 2020 cp = strchr (cp, '\t'); 2021 if (cp != NULL) 2022 { 2023 *cp = '\0'; 2024 } 2025 2026 new->next = NULL; 2027 2028 if (last_node == NULL) 2029 { 2030 notify_list = new; 2031 } 2032 else 2033 last_node->next = new; 2034 last_node = new; 2035 } 2036 return; 2037 error: 2038 pending_error = 0; 2039 if (alloc_pending (80)) 2040 strcpy (pending_error_text, 2041 "E Protocol error; misformed Notify request"); 2042 if (data != NULL) 2043 free (data); 2044 if (new != NULL) 2045 { 2046 free (new->filename); 2047 free (new->dir); 2048 free (new); 2049 } 2050 return; 2051 } 2052 2053 /* Process all the Notify requests that we have stored up. Returns 0 2054 if successful, if not prints error message (via error()) and 2055 returns negative value. */ 2056 static int 2057 server_notify () 2058 { 2059 struct notify_note *p; 2060 char *repos; 2061 2062 while (notify_list != NULL) 2063 { 2064 if ( CVS_CHDIR (notify_list->dir) < 0) 2065 { 2066 error (0, errno, "cannot change to %s", notify_list->dir); 2067 return -1; 2068 } 2069 repos = Name_Repository (NULL, NULL); 2070 2071 lock_dir_for_write (repos); 2072 2073 fileattr_startdir (repos); 2074 2075 notify_do (*notify_list->type, notify_list->filename, getcaller(), 2076 notify_list->val, notify_list->watches, repos); 2077 2078 buf_output0 (buf_to_net, "Notified "); 2079 { 2080 char *dir = notify_list->dir + strlen (server_temp_dir) + 1; 2081 if (dir[0] == '\0') 2082 buf_append_char (buf_to_net, '.'); 2083 else 2084 buf_output0 (buf_to_net, dir); 2085 buf_append_char (buf_to_net, '/'); 2086 buf_append_char (buf_to_net, '\n'); 2087 } 2088 buf_output0 (buf_to_net, repos); 2089 buf_append_char (buf_to_net, '/'); 2090 buf_output0 (buf_to_net, notify_list->filename); 2091 buf_append_char (buf_to_net, '\n'); 2092 free (repos); 2093 2094 p = notify_list->next; 2095 free (notify_list->filename); 2096 free (notify_list->dir); 2097 free (notify_list->type); 2098 free (notify_list); 2099 notify_list = p; 2100 2101 fileattr_write (); 2102 fileattr_free (); 2103 2104 Lock_Cleanup (); 2105 } 2106 2107 last_node = NULL; 2108 2109 /* The code used to call fflush (stdout) here, but that is no 2110 longer necessary. The data is now buffered in buf_to_net, 2111 which will be flushed by the caller, do_cvs_command. */ 2112 2113 return 0; 2114 } 2115 2116 static int argument_count; 2117 static char **argument_vector; 2118 static int argument_vector_size; 2119 2120 static void 2121 serve_argument (arg) 2122 char *arg; 2123 { 2124 char *p; 2125 2126 if (error_pending()) return; 2127 2128 if (argument_vector_size <= argument_count) 2129 { 2130 argument_vector_size *= 2; 2131 argument_vector = 2132 (char **) realloc ((char *)argument_vector, 2133 argument_vector_size * sizeof (char *)); 2134 if (argument_vector == NULL) 2135 { 2136 pending_error = ENOMEM; 2137 return; 2138 } 2139 } 2140 p = malloc (strlen (arg) + 1); 2141 if (p == NULL) 2142 { 2143 pending_error = ENOMEM; 2144 return; 2145 } 2146 strcpy (p, arg); 2147 argument_vector[argument_count++] = p; 2148 } 2149 2150 static void 2151 serve_argumentx (arg) 2152 char *arg; 2153 { 2154 char *p; 2155 2156 if (error_pending()) return; 2157 2158 p = argument_vector[argument_count - 1]; 2159 p = realloc (p, strlen (p) + 1 + strlen (arg) + 1); 2160 if (p == NULL) 2161 { 2162 pending_error = ENOMEM; 2163 return; 2164 } 2165 strcat (p, "\n"); 2166 strcat (p, arg); 2167 argument_vector[argument_count - 1] = p; 2168 } 2169 2170 static void 2171 serve_global_option (arg) 2172 char *arg; 2173 { 2174 if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0') 2175 { 2176 error_return: 2177 if (alloc_pending (strlen (arg) + 80)) 2178 sprintf (pending_error_text, 2179 "E Protocol error: bad global option %s", 2180 arg); 2181 return; 2182 } 2183 switch (arg[1]) 2184 { 2185 case 'n': 2186 noexec = 1; 2187 break; 2188 case 'q': 2189 quiet = 1; 2190 break; 2191 case 'r': 2192 cvswrite = 0; 2193 break; 2194 case 'Q': 2195 really_quiet = 1; 2196 break; 2197 case 'l': 2198 logoff = 1; 2199 break; 2200 case 't': 2201 trace = 1; 2202 break; 2203 default: 2204 goto error_return; 2205 } 2206 } 2207 2208 static void 2209 serve_set (arg) 2210 char *arg; 2211 { 2212 /* FIXME: This sends errors immediately (I think); they should be 2213 put into pending_error. */ 2214 variable_set (arg); 2215 } 2216 2217 #ifdef ENCRYPTION 2218 2219 #ifdef HAVE_KERBEROS 2220 2221 static void 2222 serve_kerberos_encrypt (arg) 2223 char *arg; 2224 { 2225 /* All future communication with the client will be encrypted. */ 2226 2227 buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched, 2228 kblock, 2229 buf_to_net->memory_error); 2230 buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched, 2231 kblock, 2232 buf_from_net->memory_error); 2233 } 2234 2235 #endif /* HAVE_KERBEROS */ 2236 2237 #ifdef HAVE_GSSAPI 2238 2239 static void 2240 serve_gssapi_encrypt (arg) 2241 char *arg; 2242 { 2243 if (cvs_gssapi_wrapping) 2244 { 2245 /* We're already using a gssapi_wrap buffer for stream 2246 authentication. Flush everything we've output so far, and 2247 turn on encryption for future data. On the input side, we 2248 should only have unwrapped as far as the Gssapi-encrypt 2249 command, so future unwrapping will become encrypted. */ 2250 buf_flush (buf_to_net, 1); 2251 cvs_gssapi_encrypt = 1; 2252 return; 2253 } 2254 2255 /* All future communication with the client will be encrypted. */ 2256 2257 cvs_gssapi_encrypt = 1; 2258 2259 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, 2260 gcontext, 2261 buf_to_net->memory_error); 2262 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, 2263 gcontext, 2264 buf_from_net->memory_error); 2265 2266 cvs_gssapi_wrapping = 1; 2267 } 2268 2269 #endif /* HAVE_GSSAPI */ 2270 2271 #endif /* ENCRYPTION */ 2272 2273 #ifdef HAVE_GSSAPI 2274 2275 static void 2276 serve_gssapi_authenticate (arg) 2277 char *arg; 2278 { 2279 if (cvs_gssapi_wrapping) 2280 { 2281 /* We're already using a gssapi_wrap buffer for encryption. 2282 That includes authentication, so we don't have to do 2283 anything further. */ 2284 return; 2285 } 2286 2287 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, 2288 gcontext, 2289 buf_to_net->memory_error); 2290 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, 2291 gcontext, 2292 buf_from_net->memory_error); 2293 2294 cvs_gssapi_wrapping = 1; 2295 } 2296 2297 #endif /* HAVE_GSSAPI */ 2298 2299 #ifdef SERVER_FLOWCONTROL 2300 /* The maximum we'll queue to the remote client before blocking. */ 2301 # ifndef SERVER_HI_WATER 2302 # define SERVER_HI_WATER (2 * 1024 * 1024) 2303 # endif /* SERVER_HI_WATER */ 2304 /* When the buffer drops to this, we restart the child */ 2305 # ifndef SERVER_LO_WATER 2306 # define SERVER_LO_WATER (1 * 1024 * 1024) 2307 # endif /* SERVER_LO_WATER */ 2308 2309 static int set_nonblock_fd PROTO((int)); 2310 2311 /* 2312 * Set buffer BUF to non-blocking I/O. Returns 0 for success or errno 2313 * code. 2314 */ 2315 2316 static int 2317 set_nonblock_fd (fd) 2318 int fd; 2319 { 2320 int flags; 2321 2322 flags = fcntl (fd, F_GETFL, 0); 2323 if (flags < 0) 2324 return errno; 2325 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0) 2326 return errno; 2327 return 0; 2328 } 2329 2330 #endif /* SERVER_FLOWCONTROL */ 2331 2332 static void serve_questionable PROTO((char *)); 2333 2334 static void 2335 serve_questionable (arg) 2336 char *arg; 2337 { 2338 static int initted; 2339 2340 if (!initted) 2341 { 2342 /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server, 2343 and CVSIGNORE on server. */ 2344 ign_setup (); 2345 initted = 1; 2346 } 2347 2348 if (dir_name == NULL) 2349 { 2350 buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing"); 2351 return; 2352 } 2353 2354 if (outside_dir (arg)) 2355 return; 2356 2357 if (!ign_name (arg)) 2358 { 2359 char *update_dir; 2360 2361 buf_output (buf_to_net, "M ? ", 4); 2362 update_dir = dir_name + strlen (server_temp_dir) + 1; 2363 if (!(update_dir[0] == '.' && update_dir[1] == '\0')) 2364 { 2365 buf_output0 (buf_to_net, update_dir); 2366 buf_output (buf_to_net, "/", 1); 2367 } 2368 buf_output0 (buf_to_net, arg); 2369 buf_output (buf_to_net, "\n", 1); 2370 } 2371 } 2372 2373 static void serve_case PROTO ((char *)); 2374 2375 static void 2376 serve_case (arg) 2377 char *arg; 2378 { 2379 ign_case = 1; 2380 } 2381 2382 static struct buffer *protocol; 2383 2384 /* This is the output which we are saving up to send to the server, in the 2385 child process. We will push it through, via the `protocol' buffer, when 2386 we have a complete line. */ 2387 static struct buffer *saved_output; 2388 /* Likewise, but stuff which will go to stderr. */ 2389 static struct buffer *saved_outerr; 2390 2391 static void 2392 protocol_memory_error (buf) 2393 struct buffer *buf; 2394 { 2395 error (1, ENOMEM, "Virtual memory exhausted"); 2396 } 2397 2398 /* 2399 * Process IDs of the subprocess, or negative if that subprocess 2400 * does not exist. 2401 */ 2402 static pid_t command_pid; 2403 2404 static void 2405 outbuf_memory_error (buf) 2406 struct buffer *buf; 2407 { 2408 static const char msg[] = "E Fatal server error\n\ 2409 error ENOMEM Virtual memory exhausted.\n"; 2410 if (command_pid > 0) 2411 kill (command_pid, SIGTERM); 2412 2413 /* 2414 * We have arranged things so that printing this now either will 2415 * be legal, or the "E fatal error" line will get glommed onto the 2416 * end of an existing "E" or "M" response. 2417 */ 2418 2419 /* If this gives an error, not much we could do. syslog() it? */ 2420 write (STDOUT_FILENO, msg, sizeof (msg) - 1); 2421 #ifdef HAVE_SYSLOG_H 2422 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted"); 2423 #endif 2424 error_exit (); 2425 } 2426 2427 static void 2428 input_memory_error (buf) 2429 struct buffer *buf; 2430 { 2431 outbuf_memory_error (buf); 2432 } 2433 2434 2435 2436 /* If command is legal, return 1. 2437 * Else if command is illegal and croak_on_illegal is set, then die. 2438 * Else just return 0 to indicate that command is illegal. 2439 */ 2440 static int 2441 check_command_legal_p (cmd_name) 2442 char *cmd_name; 2443 { 2444 /* Right now, only pserver notices illegal commands -- namely, 2445 * write attempts by a read-only user. Therefore, if CVS_Username 2446 * is not set, this just returns 1, because CVS_Username unset 2447 * means pserver is not active. 2448 */ 2449 #ifdef AUTH_SERVER_SUPPORT 2450 if (CVS_Username == NULL) 2451 return 1; 2452 2453 if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY) 2454 { 2455 /* This command has the potential to modify the repository, so 2456 * we check if the user have permission to do that. 2457 * 2458 * (Only relevant for remote users -- local users can do 2459 * whatever normal Unix file permissions allow them to do.) 2460 * 2461 * The decision method: 2462 * 2463 * If $CVSROOT/CVSADMROOT_READERS exists and user is listed 2464 * in it, then read-only access for user. 2465 * 2466 * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT 2467 * listed in it, then also read-only access for user. 2468 * 2469 * Else read-write access for user. 2470 */ 2471 2472 char *linebuf = NULL; 2473 int num_red = 0; 2474 size_t linebuf_len = 0; 2475 char *fname; 2476 size_t flen; 2477 FILE *fp; 2478 int found_it = 0; 2479 2480 /* else */ 2481 flen = strlen (current_parsed_root->directory) 2482 + strlen (CVSROOTADM) 2483 + strlen (CVSROOTADM_READERS) 2484 + 3; 2485 2486 fname = xmalloc (flen); 2487 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, 2488 CVSROOTADM, CVSROOTADM_READERS); 2489 2490 fp = fopen (fname, "r"); 2491 2492 if (fp == NULL) 2493 { 2494 if (!existence_error (errno)) 2495 { 2496 /* Need to deny access, so that attackers can't fool 2497 us with some sort of denial of service attack. */ 2498 error (0, errno, "cannot open %s", fname); 2499 free (fname); 2500 return 0; 2501 } 2502 } 2503 else /* successfully opened readers file */ 2504 { 2505 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) 2506 { 2507 /* Hmmm, is it worth importing my own readline 2508 library into CVS? It takes care of chopping 2509 leading and trailing whitespace, "#" comments, and 2510 newlines automatically when so requested. Would 2511 save some code here... -kff */ 2512 2513 /* Chop newline by hand, for strcmp()'s sake. */ 2514 if (linebuf[num_red - 1] == '\n') 2515 linebuf[num_red - 1] = '\0'; 2516 2517 if (strcmp (linebuf, CVS_Username) == 0) 2518 goto handle_illegal; 2519 } 2520 if (num_red < 0 && !feof (fp)) 2521 error (0, errno, "cannot read %s", fname); 2522 2523 /* If not listed specifically as a reader, then this user 2524 has write access by default unless writers are also 2525 specified in a file . */ 2526 if (fclose (fp) < 0) 2527 error (0, errno, "cannot close %s", fname); 2528 } 2529 free (fname); 2530 2531 /* Now check the writers file. */ 2532 2533 flen = strlen (current_parsed_root->directory) 2534 + strlen (CVSROOTADM) 2535 + strlen (CVSROOTADM_WRITERS) 2536 + 3; 2537 2538 fname = xmalloc (flen); 2539 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, 2540 CVSROOTADM, CVSROOTADM_WRITERS); 2541 2542 fp = fopen (fname, "r"); 2543 2544 if (fp == NULL) 2545 { 2546 if (linebuf) 2547 free (linebuf); 2548 if (existence_error (errno)) 2549 { 2550 /* Writers file does not exist, so everyone is a writer, 2551 by default. */ 2552 free (fname); 2553 return 1; 2554 } 2555 else 2556 { 2557 /* Need to deny access, so that attackers can't fool 2558 us with some sort of denial of service attack. */ 2559 error (0, errno, "cannot read %s", fname); 2560 free (fname); 2561 return 0; 2562 } 2563 } 2564 2565 found_it = 0; 2566 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) 2567 { 2568 /* Chop newline by hand, for strcmp()'s sake. */ 2569 if (linebuf[num_red - 1] == '\n') 2570 linebuf[num_red - 1] = '\0'; 2571 2572 if (strcmp (linebuf, CVS_Username) == 0) 2573 { 2574 found_it = 1; 2575 break; 2576 } 2577 } 2578 if (num_red < 0 && !feof (fp)) 2579 error (0, errno, "cannot read %s", fname); 2580 2581 if (found_it) 2582 { 2583 if (fclose (fp) < 0) 2584 error (0, errno, "cannot close %s", fname); 2585 if (linebuf) 2586 free (linebuf); 2587 free (fname); 2588 return 1; 2589 } 2590 else /* writers file exists, but this user not listed in it */ 2591 { 2592 handle_illegal: 2593 if (fclose (fp) < 0) 2594 error (0, errno, "cannot close %s", fname); 2595 if (linebuf) 2596 free (linebuf); 2597 free (fname); 2598 return 0; 2599 } 2600 } 2601 #endif /* AUTH_SERVER_SUPPORT */ 2602 2603 /* If ever reach end of this function, command must be legal. */ 2604 return 1; 2605 } 2606 2607 2608 2609 /* Execute COMMAND in a subprocess with the approriate funky things done. */ 2610 2611 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain; 2612 static int max_command_fd; 2613 2614 #ifdef SERVER_FLOWCONTROL 2615 static int flowcontrol_pipe[2]; 2616 #endif /* SERVER_FLOWCONTROL */ 2617 2618 static void 2619 do_cvs_command (cmd_name, command) 2620 char *cmd_name; 2621 int (*command) PROTO((int argc, char **argv)); 2622 { 2623 /* 2624 * The following file descriptors are set to -1 if that file is not 2625 * currently open. 2626 */ 2627 2628 /* Data on these pipes is a series of '\n'-terminated lines. */ 2629 int stdout_pipe[2]; 2630 int stderr_pipe[2]; 2631 2632 /* 2633 * Data on this pipe is a series of counted (see buf_send_counted) 2634 * packets. Each packet must be processed atomically (i.e. not 2635 * interleaved with data from stdout_pipe or stderr_pipe). 2636 */ 2637 int protocol_pipe[2]; 2638 2639 int dev_null_fd = -1; 2640 2641 int errs; 2642 2643 command_pid = -1; 2644 stdout_pipe[0] = -1; 2645 stdout_pipe[1] = -1; 2646 stderr_pipe[0] = -1; 2647 stderr_pipe[1] = -1; 2648 protocol_pipe[0] = -1; 2649 protocol_pipe[1] = -1; 2650 2651 server_write_entries (); 2652 2653 if (print_pending_error ()) 2654 goto free_args_and_return; 2655 2656 /* Global `command_name' is probably "server" right now -- only 2657 serve_export() sets it to anything else. So we will use local 2658 parameter `cmd_name' to determine if this command is legal for 2659 this user. */ 2660 if (!check_command_legal_p (cmd_name)) 2661 { 2662 buf_output0 (buf_to_net, "E "); 2663 buf_output0 (buf_to_net, program_name); 2664 buf_output0 (buf_to_net, " [server aborted]: \""); 2665 buf_output0 (buf_to_net, cmd_name); 2666 buf_output0 (buf_to_net, "\" requires write access to the repository\n\ 2667 error \n"); 2668 goto free_args_and_return; 2669 } 2670 2671 (void) server_notify (); 2672 2673 /* 2674 * We use a child process which actually does the operation. This 2675 * is so we can intercept its standard output. Even if all of CVS 2676 * were written to go to some special routine instead of writing 2677 * to stdout or stderr, we would still need to do the same thing 2678 * for the RCS commands. 2679 */ 2680 2681 if (pipe (stdout_pipe) < 0) 2682 { 2683 buf_output0 (buf_to_net, "E pipe failed\n"); 2684 print_error (errno); 2685 goto error_exit; 2686 } 2687 if (pipe (stderr_pipe) < 0) 2688 { 2689 buf_output0 (buf_to_net, "E pipe failed\n"); 2690 print_error (errno); 2691 goto error_exit; 2692 } 2693 if (pipe (protocol_pipe) < 0) 2694 { 2695 buf_output0 (buf_to_net, "E pipe failed\n"); 2696 print_error (errno); 2697 goto error_exit; 2698 } 2699 #ifdef SERVER_FLOWCONTROL 2700 if (pipe (flowcontrol_pipe) < 0) 2701 { 2702 buf_output0 (buf_to_net, "E pipe failed\n"); 2703 print_error (errno); 2704 goto error_exit; 2705 } 2706 set_nonblock_fd (flowcontrol_pipe[0]); 2707 set_nonblock_fd (flowcontrol_pipe[1]); 2708 #endif /* SERVER_FLOWCONTROL */ 2709 2710 dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY); 2711 if (dev_null_fd < 0) 2712 { 2713 buf_output0 (buf_to_net, "E open /dev/null failed\n"); 2714 print_error (errno); 2715 goto error_exit; 2716 } 2717 2718 /* We shouldn't have any partial lines from cvs_output and 2719 cvs_outerr, but we handle them here in case there is a bug. */ 2720 /* FIXME: appending a newline, rather than using "MT" as we 2721 do in the child process, is probably not really a very good 2722 way to "handle" them. */ 2723 if (! buf_empty_p (saved_output)) 2724 { 2725 buf_append_char (saved_output, '\n'); 2726 buf_copy_lines (buf_to_net, saved_output, 'M'); 2727 } 2728 if (! buf_empty_p (saved_outerr)) 2729 { 2730 buf_append_char (saved_outerr, '\n'); 2731 buf_copy_lines (buf_to_net, saved_outerr, 'E'); 2732 } 2733 2734 /* Flush out any pending data. */ 2735 buf_flush (buf_to_net, 1); 2736 2737 /* Don't use vfork; we're not going to exec(). */ 2738 command_pid = fork (); 2739 if (command_pid < 0) 2740 { 2741 buf_output0 (buf_to_net, "E fork failed\n"); 2742 print_error (errno); 2743 goto error_exit; 2744 } 2745 if (command_pid == 0) 2746 { 2747 int exitstatus; 2748 2749 /* Since we're in the child, and the parent is going to take 2750 care of packaging up our error messages, we can clear this 2751 flag. */ 2752 error_use_protocol = 0; 2753 2754 protocol = fd_buffer_initialize (protocol_pipe[1], 0, 2755 protocol_memory_error); 2756 2757 /* At this point we should no longer be using buf_to_net and 2758 buf_from_net. Instead, everything should go through 2759 protocol. */ 2760 buf_to_net = NULL; 2761 buf_from_net = NULL; 2762 2763 /* These were originally set up to use outbuf_memory_error. 2764 Since we're now in the child, we should use the simpler 2765 protocol_memory_error function. */ 2766 saved_output->memory_error = protocol_memory_error; 2767 saved_outerr->memory_error = protocol_memory_error; 2768 2769 if (dup2 (dev_null_fd, STDIN_FILENO) < 0) 2770 error (1, errno, "can't set up pipes"); 2771 if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0) 2772 error (1, errno, "can't set up pipes"); 2773 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0) 2774 error (1, errno, "can't set up pipes"); 2775 close (dev_null_fd); 2776 close (stdout_pipe[0]); 2777 close (stdout_pipe[1]); 2778 close (stderr_pipe[0]); 2779 close (stderr_pipe[1]); 2780 close (protocol_pipe[0]); 2781 close_on_exec (protocol_pipe[1]); 2782 #ifdef SERVER_FLOWCONTROL 2783 close_on_exec (flowcontrol_pipe[0]); 2784 close (flowcontrol_pipe[1]); 2785 #endif /* SERVER_FLOWCONTROL */ 2786 2787 /* 2788 * Set this in .bashrc if you want to give yourself time to attach 2789 * to the subprocess with a debugger. 2790 */ 2791 if (getenv ("CVS_SERVER_SLEEP")) 2792 { 2793 int secs = atoi (getenv ("CVS_SERVER_SLEEP")); 2794 sleep (secs); 2795 } 2796 2797 exitstatus = (*command) (argument_count, argument_vector); 2798 2799 /* Output any partial lines. If the client doesn't support 2800 "MT", we go ahead and just tack on a newline since the 2801 protocol doesn't support anything better. */ 2802 if (! buf_empty_p (saved_output)) 2803 { 2804 buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M "); 2805 buf_append_buffer (protocol, saved_output); 2806 buf_output (protocol, "\n", 1); 2807 buf_send_counted (protocol); 2808 } 2809 /* For now we just discard partial lines on stderr. I suspect 2810 that CVS can't write such lines unless there is a bug. */ 2811 2812 /* 2813 * When we exit, that will close the pipes, giving an EOF to 2814 * the parent. 2815 */ 2816 buf_free (protocol); 2817 exit (exitstatus); 2818 } 2819 2820 /* OK, sit around getting all the input from the child. */ 2821 { 2822 struct buffer *stdoutbuf; 2823 struct buffer *stderrbuf; 2824 struct buffer *protocol_inbuf; 2825 /* Number of file descriptors to check in select (). */ 2826 int num_to_check; 2827 int count_needed = 1; 2828 #ifdef SERVER_FLOWCONTROL 2829 int have_flowcontrolled = 0; 2830 #endif /* SERVER_FLOWCONTROL */ 2831 2832 FD_ZERO (&command_fds_to_drain.fds); 2833 num_to_check = stdout_pipe[0]; 2834 FD_SET (stdout_pipe[0], &command_fds_to_drain.fds); 2835 if (stderr_pipe[0] > num_to_check) 2836 num_to_check = stderr_pipe[0]; 2837 FD_SET (stderr_pipe[0], &command_fds_to_drain.fds); 2838 if (protocol_pipe[0] > num_to_check) 2839 num_to_check = protocol_pipe[0]; 2840 FD_SET (protocol_pipe[0], &command_fds_to_drain.fds); 2841 if (STDOUT_FILENO > num_to_check) 2842 num_to_check = STDOUT_FILENO; 2843 max_command_fd = num_to_check; 2844 /* 2845 * File descriptors are numbered from 0, so num_to_check needs to 2846 * be one larger than the largest descriptor. 2847 */ 2848 ++num_to_check; 2849 if (num_to_check > FD_SETSIZE) 2850 { 2851 buf_output0 (buf_to_net, 2852 "E internal error: FD_SETSIZE not big enough.\n\ 2853 error \n"); 2854 goto error_exit; 2855 } 2856 2857 stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1, 2858 input_memory_error); 2859 2860 stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1, 2861 input_memory_error); 2862 2863 protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1, 2864 input_memory_error); 2865 2866 set_nonblock (buf_to_net); 2867 set_nonblock (stdoutbuf); 2868 set_nonblock (stderrbuf); 2869 set_nonblock (protocol_inbuf); 2870 2871 if (close (stdout_pipe[1]) < 0) 2872 { 2873 buf_output0 (buf_to_net, "E close failed\n"); 2874 print_error (errno); 2875 goto error_exit; 2876 } 2877 stdout_pipe[1] = -1; 2878 2879 if (close (stderr_pipe[1]) < 0) 2880 { 2881 buf_output0 (buf_to_net, "E close failed\n"); 2882 print_error (errno); 2883 goto error_exit; 2884 } 2885 stderr_pipe[1] = -1; 2886 2887 if (close (protocol_pipe[1]) < 0) 2888 { 2889 buf_output0 (buf_to_net, "E close failed\n"); 2890 print_error (errno); 2891 goto error_exit; 2892 } 2893 protocol_pipe[1] = -1; 2894 2895 #ifdef SERVER_FLOWCONTROL 2896 if (close (flowcontrol_pipe[0]) < 0) 2897 { 2898 buf_output0 (buf_to_net, "E close failed\n"); 2899 print_error (errno); 2900 goto error_exit; 2901 } 2902 flowcontrol_pipe[0] = -1; 2903 #endif /* SERVER_FLOWCONTROL */ 2904 2905 if (close (dev_null_fd) < 0) 2906 { 2907 buf_output0 (buf_to_net, "E close failed\n"); 2908 print_error (errno); 2909 goto error_exit; 2910 } 2911 dev_null_fd = -1; 2912 2913 while (stdout_pipe[0] >= 0 2914 || stderr_pipe[0] >= 0 2915 || protocol_pipe[0] >= 0 2916 || count_needed <= 0) 2917 { 2918 fd_set readfds; 2919 fd_set writefds; 2920 int numfds; 2921 #ifdef SERVER_FLOWCONTROL 2922 int bufmemsize; 2923 struct timeval *timeout_ptr; 2924 struct timeval timeout; 2925 2926 /* 2927 * See if we are swamping the remote client and filling our VM. 2928 * Tell child to hold off if we do. 2929 */ 2930 bufmemsize = buf_count_mem (buf_to_net); 2931 if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER)) 2932 { 2933 if (write(flowcontrol_pipe[1], "S", 1) == 1) 2934 have_flowcontrolled = 1; 2935 } 2936 else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER)) 2937 { 2938 if (write(flowcontrol_pipe[1], "G", 1) == 1) 2939 have_flowcontrolled = 0; 2940 } 2941 #endif /* SERVER_FLOWCONTROL */ 2942 2943 FD_ZERO (&readfds); 2944 FD_ZERO (&writefds); 2945 2946 if (count_needed <= 0) 2947 { 2948 /* there is data pending which was read from the protocol pipe 2949 * so don't block if we don't find any data 2950 */ 2951 timeout.tv_sec = 0; 2952 timeout.tv_usec = 0; 2953 timeout_ptr = &timeout; 2954 } 2955 else 2956 { 2957 /* block indefinately */ 2958 timeout_ptr = NULL; 2959 } 2960 2961 if (! buf_empty_p (buf_to_net)) 2962 FD_SET (STDOUT_FILENO, &writefds); 2963 2964 if (stdout_pipe[0] >= 0) 2965 { 2966 FD_SET (stdout_pipe[0], &readfds); 2967 } 2968 if (stderr_pipe[0] >= 0) 2969 { 2970 FD_SET (stderr_pipe[0], &readfds); 2971 } 2972 if (protocol_pipe[0] >= 0) 2973 { 2974 FD_SET (protocol_pipe[0], &readfds); 2975 } 2976 2977 /* This process of selecting on the three pipes means that 2978 we might not get output in the same order in which it 2979 was written, thus producing the well-known 2980 "out-of-order" bug. If the child process uses 2981 cvs_output and cvs_outerr, it will send everything on 2982 the protocol_pipe and avoid this problem, so the 2983 solution is to use cvs_output and cvs_outerr in the 2984 child process. */ 2985 do { 2986 /* This used to select on exceptions too, but as far 2987 as I know there was never any reason to do that and 2988 SCO doesn't let you select on exceptions on pipes. */ 2989 numfds = select (num_to_check, &readfds, &writefds, 2990 (fd_set *)0, timeout_ptr); 2991 if (numfds < 0 2992 && errno != EINTR) 2993 { 2994 buf_output0 (buf_to_net, "E select failed\n"); 2995 print_error (errno); 2996 goto error_exit; 2997 } 2998 } while (numfds < 0); 2999 3000 if (numfds == 0) 3001 { 3002 FD_ZERO (&readfds); 3003 FD_ZERO (&writefds); 3004 } 3005 3006 if (FD_ISSET (STDOUT_FILENO, &writefds)) 3007 { 3008 /* What should we do with errors? syslog() them? */ 3009 buf_send_output (buf_to_net); 3010 } 3011 3012 if (protocol_pipe[0] >= 0 3013 && (FD_ISSET (protocol_pipe[0], &readfds))) 3014 { 3015 int status; 3016 int count_read; 3017 3018 status = buf_input_data (protocol_inbuf, &count_read); 3019 3020 if (status == -1) 3021 { 3022 close (protocol_pipe[0]); 3023 protocol_pipe[0] = -1; 3024 } 3025 else if (status > 0) 3026 { 3027 buf_output0 (buf_to_net, "E buf_input_data failed\n"); 3028 print_error (status); 3029 goto error_exit; 3030 } 3031 3032 /* 3033 * We only call buf_copy_counted if we have read 3034 * enough bytes to make it worthwhile. This saves us 3035 * from continually recounting the amount of data we 3036 * have. 3037 */ 3038 count_needed -= count_read; 3039 } 3040 /* this is still part of the protocol pipe procedure, but it is 3041 * outside the above conditional so that unprocessed data can be 3042 * left in the buffer and stderr/stdout can be read when a flush 3043 * signal is received and control can return here without passing 3044 * through the select code and maybe blocking 3045 */ 3046 while (count_needed <= 0) 3047 { 3048 int special = 0; 3049 3050 count_needed = buf_copy_counted (buf_to_net, 3051 protocol_inbuf, 3052 &special); 3053 3054 /* What should we do with errors? syslog() them? */ 3055 buf_send_output (buf_to_net); 3056 3057 /* If SPECIAL got set to <0, it means that the child 3058 * wants us to flush the pipe & maybe stderr or stdout. 3059 * 3060 * After that we break to read stderr & stdout again before 3061 * going back to the protocol pipe 3062 * 3063 * Upon breaking, count_needed = 0, so the next pass will only 3064 * perform a non-blocking select before returning here to finish 3065 * processing data we already read from the protocol buffer 3066 */ 3067 if (special == -1) 3068 { 3069 cvs_flushout(); 3070 break; 3071 } 3072 if (special == -2) 3073 { 3074 /* If the client supports the 'F' command, we send it. */ 3075 if (supported_response ("F")) 3076 { 3077 buf_append_char (buf_to_net, 'F'); 3078 buf_append_char (buf_to_net, '\n'); 3079 } 3080 cvs_flusherr (); 3081 break; 3082 } 3083 } 3084 3085 if (stdout_pipe[0] >= 0 3086 && (FD_ISSET (stdout_pipe[0], &readfds))) 3087 { 3088 int status; 3089 3090 status = buf_input_data (stdoutbuf, (int *) NULL); 3091 3092 buf_copy_lines (buf_to_net, stdoutbuf, 'M'); 3093 3094 if (status == -1) 3095 { 3096 close (stdout_pipe[0]); 3097 stdout_pipe[0] = -1; 3098 } 3099 else if (status > 0) 3100 { 3101 buf_output0 (buf_to_net, "E buf_input_data failed\n"); 3102 print_error (status); 3103 goto error_exit; 3104 } 3105 3106 /* What should we do with errors? syslog() them? */ 3107 buf_send_output (buf_to_net); 3108 } 3109 3110 if (stderr_pipe[0] >= 0 3111 && (FD_ISSET (stderr_pipe[0], &readfds))) 3112 { 3113 int status; 3114 3115 status = buf_input_data (stderrbuf, (int *) NULL); 3116 3117 buf_copy_lines (buf_to_net, stderrbuf, 'E'); 3118 3119 if (status == -1) 3120 { 3121 close (stderr_pipe[0]); 3122 stderr_pipe[0] = -1; 3123 } 3124 else if (status > 0) 3125 { 3126 buf_output0 (buf_to_net, "E buf_input_data failed\n"); 3127 print_error (status); 3128 goto error_exit; 3129 } 3130 3131 /* What should we do with errors? syslog() them? */ 3132 buf_send_output (buf_to_net); 3133 } 3134 } 3135 3136 /* 3137 * OK, we've gotten EOF on all the pipes. If there is 3138 * anything left on stdoutbuf or stderrbuf (this could only 3139 * happen if there was no trailing newline), send it over. 3140 */ 3141 if (! buf_empty_p (stdoutbuf)) 3142 { 3143 buf_append_char (stdoutbuf, '\n'); 3144 buf_copy_lines (buf_to_net, stdoutbuf, 'M'); 3145 } 3146 if (! buf_empty_p (stderrbuf)) 3147 { 3148 buf_append_char (stderrbuf, '\n'); 3149 buf_copy_lines (buf_to_net, stderrbuf, 'E'); 3150 } 3151 if (! buf_empty_p (protocol_inbuf)) 3152 buf_output0 (buf_to_net, 3153 "E Protocol error: uncounted data discarded\n"); 3154 3155 #ifdef SERVER_FLOWCONTROL 3156 close (flowcontrol_pipe[1]); 3157 flowcontrol_pipe[1] = -1; 3158 #endif /* SERVER_FLOWCONTROL */ 3159 3160 errs = 0; 3161 3162 while (command_pid > 0) 3163 { 3164 int status; 3165 pid_t waited_pid; 3166 waited_pid = waitpid (command_pid, &status, 0); 3167 if (waited_pid < 0) 3168 { 3169 /* 3170 * Intentionally ignoring EINTR. Other errors 3171 * "can't happen". 3172 */ 3173 continue; 3174 } 3175 3176 if (WIFEXITED (status)) 3177 errs += WEXITSTATUS (status); 3178 else 3179 { 3180 int sig = WTERMSIG (status); 3181 char buf[50]; 3182 /* 3183 * This is really evil, because signals might be numbered 3184 * differently on the two systems. We should be using 3185 * signal names (either of the "Terminated" or the "SIGTERM" 3186 * variety). But cvs doesn't currently use libiberty...we 3187 * could roll our own.... FIXME. 3188 */ 3189 buf_output0 (buf_to_net, "E Terminated with fatal signal "); 3190 sprintf (buf, "%d\n", sig); 3191 buf_output0 (buf_to_net, buf); 3192 3193 /* Test for a core dump. Is this portable? */ 3194 if (status & 0x80) 3195 { 3196 buf_output0 (buf_to_net, "E Core dumped; preserving "); 3197 buf_output0 (buf_to_net, orig_server_temp_dir); 3198 buf_output0 (buf_to_net, " on server.\n\ 3199 E CVS locks may need cleaning up.\n"); 3200 dont_delete_temp = 1; 3201 } 3202 ++errs; 3203 } 3204 if (waited_pid == command_pid) 3205 command_pid = -1; 3206 } 3207 3208 /* 3209 * OK, we've waited for the child. By now all CVS locks are free 3210 * and it's OK to block on the network. 3211 */ 3212 set_block (buf_to_net); 3213 buf_flush (buf_to_net, 1); 3214 buf_shutdown (protocol_inbuf); 3215 buf_free (protocol_inbuf); 3216 buf_shutdown (stderrbuf); 3217 buf_free (stderrbuf); 3218 buf_shutdown (stdoutbuf); 3219 buf_free (stdoutbuf); 3220 } 3221 3222 if (errs) 3223 /* We will have printed an error message already. */ 3224 buf_output0 (buf_to_net, "error \n"); 3225 else 3226 buf_output0 (buf_to_net, "ok\n"); 3227 goto free_args_and_return; 3228 3229 error_exit: 3230 if (command_pid > 0) 3231 kill (command_pid, SIGTERM); 3232 3233 while (command_pid > 0) 3234 { 3235 pid_t waited_pid; 3236 waited_pid = waitpid (command_pid, (int *) 0, 0); 3237 if (waited_pid < 0 && errno == EINTR) 3238 continue; 3239 if (waited_pid == command_pid) 3240 command_pid = -1; 3241 } 3242 3243 close (dev_null_fd); 3244 close (protocol_pipe[0]); 3245 close (protocol_pipe[1]); 3246 close (stderr_pipe[0]); 3247 close (stderr_pipe[1]); 3248 close (stdout_pipe[0]); 3249 close (stdout_pipe[1]); 3250 #ifdef SERVER_FLOWCONTROL 3251 close (flowcontrol_pipe[0]); 3252 close (flowcontrol_pipe[1]); 3253 #endif /* SERVER_FLOWCONTROL */ 3254 3255 free_args_and_return: 3256 /* Now free the arguments. */ 3257 { 3258 /* argument_vector[0] is a dummy argument, we don't mess with it. */ 3259 char **cp; 3260 for (cp = argument_vector + 1; 3261 cp < argument_vector + argument_count; 3262 ++cp) 3263 free (*cp); 3264 3265 argument_count = 1; 3266 } 3267 3268 /* Flush out any data not yet sent. */ 3269 set_block (buf_to_net); 3270 buf_flush (buf_to_net, 1); 3271 3272 return; 3273 } 3274 3275 #ifdef SERVER_FLOWCONTROL 3276 /* 3277 * Called by the child at convenient points in the server's execution for 3278 * the server child to block.. ie: when it has no locks active. 3279 */ 3280 void 3281 server_pause_check() 3282 { 3283 int paused = 0; 3284 char buf[1]; 3285 3286 while (read (flowcontrol_pipe[0], buf, 1) == 1) 3287 { 3288 if (*buf == 'S') /* Stop */ 3289 paused = 1; 3290 else if (*buf == 'G') /* Go */ 3291 paused = 0; 3292 else 3293 return; /* ??? */ 3294 } 3295 while (paused) { 3296 int numfds, numtocheck; 3297 fd_set fds; 3298 3299 FD_ZERO (&fds); 3300 FD_SET (flowcontrol_pipe[0], &fds); 3301 numtocheck = flowcontrol_pipe[0] + 1; 3302 3303 do { 3304 numfds = select (numtocheck, &fds, (fd_set *)0, 3305 (fd_set *)0, (struct timeval *)NULL); 3306 if (numfds < 0 3307 && errno != EINTR) 3308 { 3309 buf_output0 (buf_to_net, "E select failed\n"); 3310 print_error (errno); 3311 return; 3312 } 3313 } while (numfds < 0); 3314 3315 if (FD_ISSET (flowcontrol_pipe[0], &fds)) 3316 { 3317 int got; 3318 3319 while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1) 3320 { 3321 if (*buf == 'S') /* Stop */ 3322 paused = 1; 3323 else if (*buf == 'G') /* Go */ 3324 paused = 0; 3325 else 3326 return; /* ??? */ 3327 } 3328 3329 /* This assumes that we are using BSD or POSIX nonblocking 3330 I/O. System V nonblocking I/O returns zero if there is 3331 nothing to read. */ 3332 if (got == 0) 3333 error (1, 0, "flow control EOF"); 3334 if (got < 0 && ! blocking_error (errno)) 3335 { 3336 error (1, errno, "flow control read failed"); 3337 } 3338 } 3339 } 3340 } 3341 #endif /* SERVER_FLOWCONTROL */ 3342 3343 /* This variable commented in server.h. */ 3344 char *server_dir = NULL; 3345 3346 static void output_dir PROTO((char *, char *)); 3347 3348 static void 3349 output_dir (update_dir, repository) 3350 char *update_dir; 3351 char *repository; 3352 { 3353 if (server_dir != NULL) 3354 { 3355 buf_output0 (protocol, server_dir); 3356 buf_output0 (protocol, "/"); 3357 } 3358 if (update_dir[0] == '\0') 3359 buf_output0 (protocol, "."); 3360 else 3361 buf_output0 (protocol, update_dir); 3362 buf_output0 (protocol, "/\n"); 3363 buf_output0 (protocol, repository); 3364 buf_output0 (protocol, "/"); 3365 } 3366 3367 /* 3368 * Entries line that we are squirreling away to send to the client when 3369 * we are ready. 3370 */ 3371 static char *entries_line; 3372 3373 /* 3374 * File which has been Scratch_File'd, we are squirreling away that fact 3375 * to inform the client when we are ready. 3376 */ 3377 static char *scratched_file; 3378 3379 /* 3380 * The scratched_file will need to be removed as well as having its entry 3381 * removed. 3382 */ 3383 static int kill_scratched_file; 3384 3385 void 3386 server_register (name, version, timestamp, options, tag, date, conflict) 3387 char *name; 3388 char *version; 3389 char *timestamp; 3390 char *options; 3391 char *tag; 3392 char *date; 3393 char *conflict; 3394 { 3395 int len; 3396 3397 if (options == NULL) 3398 options = ""; 3399 3400 if (trace) 3401 { 3402 (void) fprintf (stderr, 3403 "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n", 3404 CLIENT_SERVER_STR, 3405 name, version, timestamp ? timestamp : "", options, 3406 tag ? tag : "", date ? date : "", 3407 conflict ? conflict : ""); 3408 } 3409 3410 if (entries_line != NULL) 3411 { 3412 /* 3413 * If CVS decides to Register it more than once (which happens 3414 * on "cvs update foo/foo.c" where foo and foo.c are already 3415 * checked out), use the last of the entries lines Register'd. 3416 */ 3417 free (entries_line); 3418 } 3419 3420 /* 3421 * I have reports of Scratch_Entry and Register both happening, in 3422 * two different cases. Using the last one which happens is almost 3423 * surely correct; I haven't tracked down why they both happen (or 3424 * even verified that they are for the same file). 3425 */ 3426 if (scratched_file != NULL) 3427 { 3428 free (scratched_file); 3429 scratched_file = NULL; 3430 } 3431 3432 len = (strlen (name) + strlen (version) + strlen (options) + 80); 3433 if (tag) 3434 len += strlen (tag); 3435 if (date) 3436 len += strlen (date); 3437 3438 entries_line = xmalloc (len); 3439 sprintf (entries_line, "/%s/%s/", name, version); 3440 if (conflict != NULL) 3441 { 3442 strcat (entries_line, "+="); 3443 } 3444 strcat (entries_line, "/"); 3445 strcat (entries_line, options); 3446 strcat (entries_line, "/"); 3447 if (tag != NULL) 3448 { 3449 strcat (entries_line, "T"); 3450 strcat (entries_line, tag); 3451 } 3452 else if (date != NULL) 3453 { 3454 strcat (entries_line, "D"); 3455 strcat (entries_line, date); 3456 } 3457 } 3458 3459 void 3460 server_scratch (fname) 3461 char *fname; 3462 { 3463 /* 3464 * I have reports of Scratch_Entry and Register both happening, in 3465 * two different cases. Using the last one which happens is almost 3466 * surely correct; I haven't tracked down why they both happen (or 3467 * even verified that they are for the same file). 3468 * 3469 * Don't know if this is what whoever wrote the above comment was 3470 * talking about, but this can happen in the case where a join 3471 * removes a file - the call to Register puts the '-vers' into the 3472 * Entries file after the file is removed 3473 */ 3474 if (entries_line != NULL) 3475 { 3476 free (entries_line); 3477 entries_line = NULL; 3478 } 3479 3480 if (scratched_file != NULL) 3481 { 3482 buf_output0 (protocol, 3483 "E CVS server internal error: duplicate Scratch_Entry\n"); 3484 buf_send_counted (protocol); 3485 return; 3486 } 3487 scratched_file = xstrdup (fname); 3488 kill_scratched_file = 1; 3489 } 3490 3491 void 3492 server_scratch_entry_only () 3493 { 3494 kill_scratched_file = 0; 3495 } 3496 3497 /* Print a new entries line, from a previous server_register. */ 3498 static void 3499 new_entries_line () 3500 { 3501 if (entries_line) 3502 { 3503 buf_output0 (protocol, entries_line); 3504 buf_output (protocol, "\n", 1); 3505 } 3506 else 3507 /* Return the error message as the Entries line. */ 3508 buf_output0 (protocol, 3509 "CVS server internal error: Register missing\n"); 3510 free (entries_line); 3511 entries_line = NULL; 3512 } 3513 3514 3515 static void 3516 serve_ci (arg) 3517 char *arg; 3518 { 3519 do_cvs_command ("commit", commit); 3520 } 3521 3522 static void 3523 checked_in_response (file, update_dir, repository) 3524 char *file; 3525 char *update_dir; 3526 char *repository; 3527 { 3528 if (supported_response ("Mode")) 3529 { 3530 struct stat sb; 3531 char *mode_string; 3532 3533 if ( CVS_STAT (file, &sb) < 0) 3534 { 3535 /* Not clear to me why the file would fail to exist, but it 3536 was happening somewhere in the testsuite. */ 3537 if (!existence_error (errno)) 3538 error (0, errno, "cannot stat %s", file); 3539 } 3540 else 3541 { 3542 buf_output0 (protocol, "Mode "); 3543 mode_string = mode_to_string (sb.st_mode); 3544 buf_output0 (protocol, mode_string); 3545 buf_output0 (protocol, "\n"); 3546 free (mode_string); 3547 } 3548 } 3549 3550 buf_output0 (protocol, "Checked-in "); 3551 output_dir (update_dir, repository); 3552 buf_output0 (protocol, file); 3553 buf_output (protocol, "\n", 1); 3554 new_entries_line (); 3555 } 3556 3557 void 3558 server_checked_in (file, update_dir, repository) 3559 char *file; 3560 char *update_dir; 3561 char *repository; 3562 { 3563 if (noexec) 3564 return; 3565 if (scratched_file != NULL && entries_line == NULL) 3566 { 3567 /* 3568 * This happens if we are now doing a "cvs remove" after a previous 3569 * "cvs add" (without a "cvs ci" in between). 3570 */ 3571 buf_output0 (protocol, "Remove-entry "); 3572 output_dir (update_dir, repository); 3573 buf_output0 (protocol, file); 3574 buf_output (protocol, "\n", 1); 3575 free (scratched_file); 3576 scratched_file = NULL; 3577 } 3578 else 3579 { 3580 checked_in_response (file, update_dir, repository); 3581 } 3582 buf_send_counted (protocol); 3583 } 3584 3585 void 3586 server_update_entries (file, update_dir, repository, updated) 3587 char *file; 3588 char *update_dir; 3589 char *repository; 3590 enum server_updated_arg4 updated; 3591 { 3592 if (noexec) 3593 return; 3594 if (updated == SERVER_UPDATED) 3595 checked_in_response (file, update_dir, repository); 3596 else 3597 { 3598 if (!supported_response ("New-entry")) 3599 return; 3600 buf_output0 (protocol, "New-entry "); 3601 output_dir (update_dir, repository); 3602 buf_output0 (protocol, file); 3603 buf_output (protocol, "\n", 1); 3604 new_entries_line (); 3605 } 3606 3607 buf_send_counted (protocol); 3608 } 3609 3610 static void 3611 serve_update (arg) 3612 char *arg; 3613 { 3614 do_cvs_command ("update", update); 3615 } 3616 3617 static void 3618 serve_diff (arg) 3619 char *arg; 3620 { 3621 do_cvs_command ("diff", diff); 3622 } 3623 3624 static void 3625 serve_log (arg) 3626 char *arg; 3627 { 3628 do_cvs_command ("log", cvslog); 3629 } 3630 3631 static void 3632 serve_rlog (arg) 3633 char *arg; 3634 { 3635 /* Tell cvslog() to behave like rlog not log. */ 3636 command_name = "rlog"; 3637 do_cvs_command ("rlog", cvslog); 3638 } 3639 3640 static void 3641 serve_add (arg) 3642 char *arg; 3643 { 3644 do_cvs_command ("add", add); 3645 } 3646 3647 static void 3648 serve_remove (arg) 3649 char *arg; 3650 { 3651 do_cvs_command ("remove", cvsremove); 3652 } 3653 3654 static void 3655 serve_status (arg) 3656 char *arg; 3657 { 3658 do_cvs_command ("status", cvsstatus); 3659 } 3660 3661 static void 3662 serve_rdiff (arg) 3663 char *arg; 3664 { 3665 do_cvs_command ("rdiff", patch); 3666 } 3667 3668 static void 3669 serve_tag (arg) 3670 char *arg; 3671 { 3672 do_cvs_command ("cvstag", cvstag); 3673 } 3674 3675 static void 3676 serve_rtag (arg) 3677 char *arg; 3678 { 3679 /* Tell cvstag() to behave like rtag not tag. */ 3680 command_name = "rtag"; 3681 do_cvs_command ("rtag", cvstag); 3682 } 3683 3684 static void 3685 serve_import (arg) 3686 char *arg; 3687 { 3688 do_cvs_command ("import", import); 3689 } 3690 3691 static void 3692 serve_admin (arg) 3693 char *arg; 3694 { 3695 do_cvs_command ("admin", admin); 3696 } 3697 3698 static void 3699 serve_history (arg) 3700 char *arg; 3701 { 3702 do_cvs_command ("history", history); 3703 } 3704 3705 static void 3706 serve_release (arg) 3707 char *arg; 3708 { 3709 do_cvs_command ("release", release); 3710 } 3711 3712 static void serve_watch_on PROTO ((char *)); 3713 3714 static void 3715 serve_watch_on (arg) 3716 char *arg; 3717 { 3718 do_cvs_command ("watch_on", watch_on); 3719 } 3720 3721 static void serve_watch_off PROTO ((char *)); 3722 3723 static void 3724 serve_watch_off (arg) 3725 char *arg; 3726 { 3727 do_cvs_command ("watch_off", watch_off); 3728 } 3729 3730 static void serve_watch_add PROTO ((char *)); 3731 3732 static void 3733 serve_watch_add (arg) 3734 char *arg; 3735 { 3736 do_cvs_command ("watch_add", watch_add); 3737 } 3738 3739 static void serve_watch_remove PROTO ((char *)); 3740 3741 static void 3742 serve_watch_remove (arg) 3743 char *arg; 3744 { 3745 do_cvs_command ("watch_remove", watch_remove); 3746 } 3747 3748 static void serve_watchers PROTO ((char *)); 3749 3750 static void 3751 serve_watchers (arg) 3752 char *arg; 3753 { 3754 do_cvs_command ("watchers", watchers); 3755 } 3756 3757 static void serve_editors PROTO ((char *)); 3758 3759 static void 3760 serve_editors (arg) 3761 char *arg; 3762 { 3763 do_cvs_command ("editors", editors); 3764 } 3765 3766 static void serve_noop PROTO ((char *)); 3767 3768 static void 3769 serve_noop (arg) 3770 char *arg; 3771 { 3772 3773 server_write_entries (); 3774 if (!print_pending_error ()) 3775 { 3776 (void) server_notify (); 3777 buf_output0 (buf_to_net, "ok\n"); 3778 } 3779 buf_flush (buf_to_net, 1); 3780 } 3781 3782 static void serve_version PROTO ((char *)); 3783 3784 static void 3785 serve_version (arg) 3786 char *arg; 3787 { 3788 do_cvs_command ("version", version); 3789 } 3790 3791 static void serve_init PROTO ((char *)); 3792 3793 static void 3794 serve_init (arg) 3795 char *arg; 3796 { 3797 if (!isabsolute (arg)) 3798 { 3799 if (alloc_pending (80 + strlen (arg))) 3800 sprintf (pending_error_text, 3801 "E Root %s must be an absolute pathname", arg); 3802 /* Fall through to do_cvs_command which will return the 3803 actual error. */ 3804 } 3805 3806 if (current_parsed_root != NULL) 3807 free_cvsroot_t (current_parsed_root); 3808 current_parsed_root = local_cvsroot (arg); 3809 3810 do_cvs_command ("init", init); 3811 } 3812 3813 static void serve_annotate PROTO ((char *)); 3814 3815 static void 3816 serve_annotate (arg) 3817 char *arg; 3818 { 3819 do_cvs_command ("annotate", annotate); 3820 } 3821 3822 static void serve_rannotate PROTO ((char *)); 3823 3824 static void 3825 serve_rannotate (arg) 3826 char *arg; 3827 { 3828 /* Tell annotate() to behave like rannotate not annotate. */ 3829 command_name = "rannotate"; 3830 do_cvs_command ("rannotate", annotate); 3831 } 3832 3833 static void 3834 serve_co (arg) 3835 char *arg; 3836 { 3837 char *tempdir; 3838 int status; 3839 3840 if (print_pending_error ()) 3841 return; 3842 3843 if (!isdir (CVSADM)) 3844 { 3845 /* 3846 * The client has not sent a "Repository" line. Check out 3847 * into a pristine directory. 3848 */ 3849 tempdir = malloc (strlen (server_temp_dir) + 80); 3850 if (tempdir == NULL) 3851 { 3852 buf_output0 (buf_to_net, "E Out of memory\n"); 3853 return; 3854 } 3855 strcpy (tempdir, server_temp_dir); 3856 strcat (tempdir, "/checkout-dir"); 3857 status = mkdir_p (tempdir); 3858 if (status != 0 && status != EEXIST) 3859 { 3860 buf_output0 (buf_to_net, "E Cannot create "); 3861 buf_output0 (buf_to_net, tempdir); 3862 buf_append_char (buf_to_net, '\n'); 3863 print_error (errno); 3864 free (tempdir); 3865 return; 3866 } 3867 3868 if ( CVS_CHDIR (tempdir) < 0) 3869 { 3870 buf_output0 (buf_to_net, "E Cannot change to directory "); 3871 buf_output0 (buf_to_net, tempdir); 3872 buf_append_char (buf_to_net, '\n'); 3873 print_error (errno); 3874 free (tempdir); 3875 return; 3876 } 3877 free (tempdir); 3878 } 3879 3880 /* Compensate for server_export()'s setting of command_name. 3881 * 3882 * [It probably doesn't matter if do_cvs_command() gets "export" 3883 * or "checkout", but we ought to be accurate where possible.] 3884 */ 3885 do_cvs_command ((strcmp (command_name, "export") == 0) ? 3886 "export" : "checkout", 3887 checkout); 3888 } 3889 3890 static void 3891 serve_export (arg) 3892 char *arg; 3893 { 3894 /* Tell checkout() to behave like export not checkout. */ 3895 command_name = "export"; 3896 serve_co (arg); 3897 } 3898 3899 void 3900 server_copy_file (file, update_dir, repository, newfile) 3901 char *file; 3902 char *update_dir; 3903 char *repository; 3904 char *newfile; 3905 { 3906 /* At least for now, our practice is to have the server enforce 3907 noexec for the repository and the client enforce it for the 3908 working directory. This might want more thought, and/or 3909 documentation in cvsclient.texi (other responses do it 3910 differently). */ 3911 3912 if (!supported_response ("Copy-file")) 3913 return; 3914 buf_output0 (protocol, "Copy-file "); 3915 output_dir (update_dir, repository); 3916 buf_output0 (protocol, file); 3917 buf_output0 (protocol, "\n"); 3918 buf_output0 (protocol, newfile); 3919 buf_output0 (protocol, "\n"); 3920 } 3921 3922 /* See server.h for description. */ 3923 3924 void 3925 server_modtime (finfo, vers_ts) 3926 struct file_info *finfo; 3927 Vers_TS *vers_ts; 3928 { 3929 char date[MAXDATELEN]; 3930 char outdate[MAXDATELEN]; 3931 3932 assert (vers_ts->vn_rcs != NULL); 3933 3934 if (!supported_response ("Mod-time")) 3935 return; 3936 3937 if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1) 3938 /* FIXME? should we be printing some kind of warning? For one 3939 thing I'm not 100% sure whether this happens in non-error 3940 circumstances. */ 3941 return; 3942 date_to_internet (outdate, date); 3943 buf_output0 (protocol, "Mod-time "); 3944 buf_output0 (protocol, outdate); 3945 buf_output0 (protocol, "\n"); 3946 } 3947 3948 /* See server.h for description. */ 3949 3950 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) 3951 /* Need to prototype because mode_t might be smaller than int. */ 3952 void 3953 server_updated ( 3954 struct file_info *finfo, 3955 Vers_TS *vers, 3956 enum server_updated_arg4 updated, 3957 mode_t mode, 3958 unsigned char *checksum, 3959 struct buffer *filebuf) 3960 #else 3961 void 3962 server_updated (finfo, vers, updated, mode, checksum, filebuf) 3963 struct file_info *finfo; 3964 Vers_TS *vers; 3965 enum server_updated_arg4 updated; 3966 mode_t mode; 3967 unsigned char *checksum; 3968 struct buffer *filebuf; 3969 #endif 3970 { 3971 if (noexec) 3972 { 3973 /* Hmm, maybe if we did the same thing for entries_file, we 3974 could get rid of the kludges in server_register and 3975 server_scratch which refrain from warning if both 3976 Scratch_Entry and Register get called. Maybe. */ 3977 if (scratched_file) 3978 { 3979 free (scratched_file); 3980 scratched_file = NULL; 3981 } 3982 return; 3983 } 3984 3985 if (entries_line != NULL && scratched_file == NULL) 3986 { 3987 FILE *f; 3988 struct buffer_data *list, *last; 3989 unsigned long size; 3990 char size_text[80]; 3991 3992 /* The contents of the file will be in one of filebuf, 3993 list/last, or here. */ 3994 unsigned char *file; 3995 size_t file_allocated; 3996 size_t file_used; 3997 3998 if (filebuf != NULL) 3999 { 4000 size = buf_length (filebuf); 4001 if (mode == (mode_t) -1) 4002 error (1, 0, "\ 4003 CVS server internal error: no mode in server_updated"); 4004 } 4005 else 4006 { 4007 struct stat sb; 4008 4009 if ( CVS_STAT (finfo->file, &sb) < 0) 4010 { 4011 if (existence_error (errno)) 4012 { 4013 /* If we have a sticky tag for a branch on which 4014 the file is dead, and cvs update the directory, 4015 it gets a T_CHECKOUT but no file. So in this 4016 case just forget the whole thing. */ 4017 free (entries_line); 4018 entries_line = NULL; 4019 goto done; 4020 } 4021 error (1, errno, "reading %s", finfo->fullname); 4022 } 4023 size = sb.st_size; 4024 if (mode == (mode_t) -1) 4025 { 4026 /* FIXME: When we check out files the umask of the 4027 server (set in .bashrc if rsh is in use) affects 4028 what mode we send, and it shouldn't. */ 4029 mode = sb.st_mode; 4030 } 4031 } 4032 4033 if (checksum != NULL) 4034 { 4035 static int checksum_supported = -1; 4036 4037 if (checksum_supported == -1) 4038 { 4039 checksum_supported = supported_response ("Checksum"); 4040 } 4041 4042 if (checksum_supported) 4043 { 4044 int i; 4045 char buf[3]; 4046 4047 buf_output0 (protocol, "Checksum "); 4048 for (i = 0; i < 16; i++) 4049 { 4050 sprintf (buf, "%02x", (unsigned int) checksum[i]); 4051 buf_output0 (protocol, buf); 4052 } 4053 buf_append_char (protocol, '\n'); 4054 } 4055 } 4056 4057 if (updated == SERVER_UPDATED) 4058 { 4059 Node *node; 4060 Entnode *entnode; 4061 4062 if (!(supported_response ("Created") 4063 && supported_response ("Update-existing"))) 4064 buf_output0 (protocol, "Updated "); 4065 else 4066 { 4067 assert (vers != NULL); 4068 if (vers->ts_user == NULL) 4069 buf_output0 (protocol, "Created "); 4070 else 4071 buf_output0 (protocol, "Update-existing "); 4072 } 4073 4074 /* Now munge the entries to say that the file is unmodified, 4075 in case we end up processing it again (e.g. modules3-6 4076 in the testsuite). */ 4077 node = findnode_fn (finfo->entries, finfo->file); 4078 entnode = (Entnode *)node->data; 4079 free (entnode->timestamp); 4080 entnode->timestamp = xstrdup ("="); 4081 } 4082 else if (updated == SERVER_MERGED) 4083 buf_output0 (protocol, "Merged "); 4084 else if (updated == SERVER_PATCHED) 4085 buf_output0 (protocol, "Patched "); 4086 else if (updated == SERVER_RCS_DIFF) 4087 buf_output0 (protocol, "Rcs-diff "); 4088 else 4089 abort (); 4090 output_dir (finfo->update_dir, finfo->repository); 4091 buf_output0 (protocol, finfo->file); 4092 buf_output (protocol, "\n", 1); 4093 4094 new_entries_line (); 4095 4096 { 4097 char *mode_string; 4098 4099 mode_string = mode_to_string (mode); 4100 buf_output0 (protocol, mode_string); 4101 buf_output0 (protocol, "\n"); 4102 free (mode_string); 4103 } 4104 4105 list = last = NULL; 4106 4107 file = NULL; 4108 file_allocated = 0; 4109 file_used = 0; 4110 4111 if (size > 0) 4112 { 4113 /* Throughout this section we use binary mode to read the 4114 file we are sending. The client handles any line ending 4115 translation if necessary. */ 4116 4117 if (file_gzip_level 4118 /* 4119 * For really tiny files, the gzip process startup 4120 * time will outweigh the compression savings. This 4121 * might be computable somehow; using 100 here is just 4122 * a first approximation. 4123 */ 4124 && size > 100) 4125 { 4126 /* Basing this routine on read_and_gzip is not a 4127 high-performance approach. But it seems easier 4128 to code than the alternative (and less 4129 vulnerable to subtle bugs). Given that this feature 4130 is mainly for compatibility, that is the better 4131 tradeoff. */ 4132 4133 int fd; 4134 4135 /* Callers must avoid passing us a buffer if 4136 file_gzip_level is set. We could handle this case, 4137 but it's not worth it since this case never arises 4138 with a current client and server. */ 4139 if (filebuf != NULL) 4140 error (1, 0, "\ 4141 CVS server internal error: unhandled case in server_updated"); 4142 4143 fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0); 4144 if (fd < 0) 4145 error (1, errno, "reading %s", finfo->fullname); 4146 if (read_and_gzip (fd, finfo->fullname, &file, 4147 &file_allocated, &file_used, 4148 file_gzip_level)) 4149 error (1, 0, "aborting due to compression error"); 4150 size = file_used; 4151 if (close (fd) < 0) 4152 error (1, errno, "reading %s", finfo->fullname); 4153 /* Prepending length with "z" is flag for using gzip here. */ 4154 buf_output0 (protocol, "z"); 4155 } 4156 else if (filebuf == NULL) 4157 { 4158 long status; 4159 4160 f = CVS_FOPEN (finfo->file, "rb"); 4161 if (f == NULL) 4162 error (1, errno, "reading %s", finfo->fullname); 4163 status = buf_read_file (f, size, &list, &last); 4164 if (status == -2) 4165 (*protocol->memory_error) (protocol); 4166 else if (status != 0) 4167 error (1, ferror (f) ? errno : 0, "reading %s", 4168 finfo->fullname); 4169 if (fclose (f) == EOF) 4170 error (1, errno, "reading %s", finfo->fullname); 4171 } 4172 } 4173 4174 sprintf (size_text, "%lu\n", size); 4175 buf_output0 (protocol, size_text); 4176 4177 if (file != NULL) 4178 { 4179 buf_output (protocol, (char *) file, file_used); 4180 free (file); 4181 file = NULL; 4182 } 4183 else if (filebuf == NULL) 4184 buf_append_data (protocol, list, last); 4185 else 4186 { 4187 buf_append_buffer (protocol, filebuf); 4188 buf_free (filebuf); 4189 } 4190 /* Note we only send a newline here if the file ended with one. */ 4191 4192 /* 4193 * Avoid using up too much disk space for temporary files. 4194 * A file which does not exist indicates that the file is up-to-date, 4195 * which is now the case. If this is SERVER_MERGED, the file is 4196 * not up-to-date, and we indicate that by leaving the file there. 4197 * I'm thinking of cases like "cvs update foo/foo.c foo". 4198 */ 4199 if ((updated == SERVER_UPDATED 4200 || updated == SERVER_PATCHED 4201 || updated == SERVER_RCS_DIFF) 4202 && filebuf == NULL 4203 /* But if we are joining, we'll need the file when we call 4204 join_file. */ 4205 && !joining ()) 4206 { 4207 if (CVS_UNLINK (finfo->file) < 0) 4208 error (0, errno, "cannot remove temp file for %s", 4209 finfo->fullname); 4210 } 4211 } 4212 else if (scratched_file != NULL && entries_line == NULL) 4213 { 4214 if (strcmp (scratched_file, finfo->file) != 0) 4215 error (1, 0, 4216 "CVS server internal error: `%s' vs. `%s' scratched", 4217 scratched_file, 4218 finfo->file); 4219 free (scratched_file); 4220 scratched_file = NULL; 4221 4222 if (kill_scratched_file) 4223 buf_output0 (protocol, "Removed "); 4224 else 4225 buf_output0 (protocol, "Remove-entry "); 4226 output_dir (finfo->update_dir, finfo->repository); 4227 buf_output0 (protocol, finfo->file); 4228 buf_output (protocol, "\n", 1); 4229 /* keep the vers structure up to date in case we do a join 4230 * - if there isn't a file, it can't very well have a version number, can it? 4231 * 4232 * we do it here on the assumption that since we just told the client 4233 * to remove the file/entry, it will, and we want to remember that. 4234 * If it fails, that's the client's problem, not ours 4235 */ 4236 if (vers && vers->vn_user != NULL) 4237 { 4238 free (vers->vn_user); 4239 vers->vn_user = NULL; 4240 } 4241 if (vers && vers->ts_user != NULL) 4242 { 4243 free (vers->ts_user); 4244 vers->ts_user = NULL; 4245 } 4246 } 4247 else if (scratched_file == NULL && entries_line == NULL) 4248 { 4249 /* 4250 * This can happen with death support if we were processing 4251 * a dead file in a checkout. 4252 */ 4253 } 4254 else 4255 error (1, 0, 4256 "CVS server internal error: Register *and* Scratch_Entry.\n"); 4257 buf_send_counted (protocol); 4258 done:; 4259 } 4260 4261 /* Return whether we should send patches in RCS format. */ 4262 4263 int 4264 server_use_rcs_diff () 4265 { 4266 return supported_response ("Rcs-diff"); 4267 } 4268 4269 void 4270 server_set_entstat (update_dir, repository) 4271 char *update_dir; 4272 char *repository; 4273 { 4274 static int set_static_supported = -1; 4275 if (set_static_supported == -1) 4276 set_static_supported = supported_response ("Set-static-directory"); 4277 if (!set_static_supported) return; 4278 4279 buf_output0 (protocol, "Set-static-directory "); 4280 output_dir (update_dir, repository); 4281 buf_output0 (protocol, "\n"); 4282 buf_send_counted (protocol); 4283 } 4284 4285 void 4286 server_clear_entstat (update_dir, repository) 4287 char *update_dir; 4288 char *repository; 4289 { 4290 static int clear_static_supported = -1; 4291 if (clear_static_supported == -1) 4292 clear_static_supported = supported_response ("Clear-static-directory"); 4293 if (!clear_static_supported) return; 4294 4295 if (noexec) 4296 return; 4297 4298 buf_output0 (protocol, "Clear-static-directory "); 4299 output_dir (update_dir, repository); 4300 buf_output0 (protocol, "\n"); 4301 buf_send_counted (protocol); 4302 } 4303 4304 void 4305 server_set_sticky (update_dir, repository, tag, date, nonbranch) 4306 char *update_dir; 4307 char *repository; 4308 char *tag; 4309 char *date; 4310 int nonbranch; 4311 { 4312 static int set_sticky_supported = -1; 4313 4314 assert (update_dir != NULL); 4315 4316 if (set_sticky_supported == -1) 4317 set_sticky_supported = supported_response ("Set-sticky"); 4318 if (!set_sticky_supported) return; 4319 4320 if (noexec) 4321 return; 4322 4323 if (tag == NULL && date == NULL) 4324 { 4325 buf_output0 (protocol, "Clear-sticky "); 4326 output_dir (update_dir, repository); 4327 buf_output0 (protocol, "\n"); 4328 } 4329 else 4330 { 4331 buf_output0 (protocol, "Set-sticky "); 4332 output_dir (update_dir, repository); 4333 buf_output0 (protocol, "\n"); 4334 if (tag != NULL) 4335 { 4336 if (nonbranch) 4337 buf_output0 (protocol, "N"); 4338 else 4339 buf_output0 (protocol, "T"); 4340 buf_output0 (protocol, tag); 4341 } 4342 else 4343 { 4344 buf_output0 (protocol, "D"); 4345 buf_output0 (protocol, date); 4346 } 4347 buf_output0 (protocol, "\n"); 4348 } 4349 buf_send_counted (protocol); 4350 } 4351 4352 struct template_proc_data 4353 { 4354 char *update_dir; 4355 char *repository; 4356 }; 4357 4358 /* Here as a static until we get around to fixing Parse_Info to pass along 4359 a void * for it. */ 4360 static struct template_proc_data *tpd; 4361 4362 static int 4363 template_proc (repository, template) 4364 char *repository; 4365 char *template; 4366 { 4367 FILE *fp; 4368 char buf[1024]; 4369 size_t n; 4370 struct stat sb; 4371 struct template_proc_data *data = tpd; 4372 4373 if (!supported_response ("Template")) 4374 /* Might want to warn the user that the rcsinfo feature won't work. */ 4375 return 0; 4376 buf_output0 (protocol, "Template "); 4377 output_dir (data->update_dir, data->repository); 4378 buf_output0 (protocol, "\n"); 4379 4380 fp = CVS_FOPEN (template, "rb"); 4381 if (fp == NULL) 4382 { 4383 error (0, errno, "Couldn't open rcsinfo template file %s", template); 4384 return 1; 4385 } 4386 if (fstat (fileno (fp), &sb) < 0) 4387 { 4388 error (0, errno, "cannot stat rcsinfo template file %s", template); 4389 return 1; 4390 } 4391 sprintf (buf, "%ld\n", (long) sb.st_size); 4392 buf_output0 (protocol, buf); 4393 while (!feof (fp)) 4394 { 4395 n = fread (buf, 1, sizeof buf, fp); 4396 buf_output (protocol, buf, n); 4397 if (ferror (fp)) 4398 { 4399 error (0, errno, "cannot read rcsinfo template file %s", template); 4400 (void) fclose (fp); 4401 return 1; 4402 } 4403 } 4404 if (fclose (fp) < 0) 4405 error (0, errno, "cannot close rcsinfo template file %s", template); 4406 return 0; 4407 } 4408 4409 void 4410 server_template (update_dir, repository) 4411 char *update_dir; 4412 char *repository; 4413 { 4414 struct template_proc_data data; 4415 data.update_dir = update_dir; 4416 data.repository = repository; 4417 tpd = &data; 4418 (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1); 4419 } 4420 4421 static void 4422 serve_gzip_contents (arg) 4423 char *arg; 4424 { 4425 int level; 4426 level = atoi (arg); 4427 if (level == 0) 4428 level = 6; 4429 file_gzip_level = level; 4430 } 4431 4432 static void 4433 serve_gzip_stream (arg) 4434 char *arg; 4435 { 4436 int level; 4437 level = atoi (arg); 4438 if (level == 0) 4439 level = 6; 4440 4441 /* All further communication with the client will be compressed. */ 4442 4443 buf_to_net = compress_buffer_initialize (buf_to_net, 0, level, 4444 buf_to_net->memory_error); 4445 buf_from_net = compress_buffer_initialize (buf_from_net, 1, level, 4446 buf_from_net->memory_error); 4447 } 4448 4449 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */ 4450 static void 4451 serve_wrapper_sendme_rcs_options (arg) 4452 char *arg; 4453 { 4454 /* Actually, this is kind of sdrawkcab-ssa: the client wants 4455 * verbatim lines from a cvswrappers file, but the server has 4456 * already parsed the cvswrappers file into the wrap_list struct. 4457 * Therefore, the server loops over wrap_list, unparsing each 4458 * entry before sending it. 4459 */ 4460 char *wrapper_line = NULL; 4461 4462 wrap_setup (); 4463 4464 for (wrap_unparse_rcs_options (&wrapper_line, 1); 4465 wrapper_line; 4466 wrap_unparse_rcs_options (&wrapper_line, 0)) 4467 { 4468 buf_output0 (buf_to_net, "Wrapper-rcsOption "); 4469 buf_output0 (buf_to_net, wrapper_line); 4470 buf_output0 (buf_to_net, "\012");; 4471 free (wrapper_line); 4472 } 4473 4474 buf_output0 (buf_to_net, "ok\012"); 4475 4476 /* The client is waiting for us, so we better send the data now. */ 4477 buf_flush (buf_to_net, 1); 4478 } 4479 4480 4481 static void 4482 serve_ignore (arg) 4483 char *arg; 4484 { 4485 /* 4486 * Just ignore this command. This is used to support the 4487 * update-patches command, which is not a real command, but a signal 4488 * to the client that update will accept the -u argument. 4489 */ 4490 } 4491 4492 static int 4493 expand_proc (argc, argv, where, mwhere, mfile, shorten, 4494 local_specified, omodule, msg) 4495 int argc; 4496 char **argv; 4497 char *where; 4498 char *mwhere; 4499 char *mfile; 4500 int shorten; 4501 int local_specified; 4502 char *omodule; 4503 char *msg; 4504 { 4505 int i; 4506 char *dir = argv[0]; 4507 4508 /* If mwhere has been specified, the thing we're expanding is a 4509 module -- just return its name so the client will ask for the 4510 right thing later. If it is an alias or a real directory, 4511 mwhere will not be set, so send out the appropriate 4512 expansion. */ 4513 4514 if (mwhere != NULL) 4515 { 4516 buf_output0 (buf_to_net, "Module-expansion "); 4517 if (server_dir != NULL) 4518 { 4519 buf_output0 (buf_to_net, server_dir); 4520 buf_output0 (buf_to_net, "/"); 4521 } 4522 buf_output0 (buf_to_net, mwhere); 4523 if (mfile != NULL) 4524 { 4525 buf_append_char (buf_to_net, '/'); 4526 buf_output0 (buf_to_net, mfile); 4527 } 4528 buf_append_char (buf_to_net, '\n'); 4529 } 4530 else 4531 { 4532 /* We may not need to do this anymore -- check the definition 4533 of aliases before removing */ 4534 if (argc == 1) 4535 { 4536 buf_output0 (buf_to_net, "Module-expansion "); 4537 if (server_dir != NULL) 4538 { 4539 buf_output0 (buf_to_net, server_dir); 4540 buf_output0 (buf_to_net, "/"); 4541 } 4542 buf_output0 (buf_to_net, dir); 4543 buf_append_char (buf_to_net, '\n'); 4544 } 4545 else 4546 { 4547 for (i = 1; i < argc; ++i) 4548 { 4549 buf_output0 (buf_to_net, "Module-expansion "); 4550 if (server_dir != NULL) 4551 { 4552 buf_output0 (buf_to_net, server_dir); 4553 buf_output0 (buf_to_net, "/"); 4554 } 4555 buf_output0 (buf_to_net, dir); 4556 buf_append_char (buf_to_net, '/'); 4557 buf_output0 (buf_to_net, argv[i]); 4558 buf_append_char (buf_to_net, '\n'); 4559 } 4560 } 4561 } 4562 return 0; 4563 } 4564 4565 static void 4566 serve_expand_modules (arg) 4567 char *arg; 4568 { 4569 int i; 4570 int err; 4571 DBM *db; 4572 err = 0; 4573 4574 server_expanding = 1; 4575 db = open_module (); 4576 for (i = 1; i < argument_count; i++) 4577 err += do_module (db, argument_vector[i], 4578 CHECKOUT, "Updating", expand_proc, 4579 NULL, 0, 0, 0, 0, 4580 (char *) NULL); 4581 close_module (db); 4582 server_expanding = 0; 4583 { 4584 /* argument_vector[0] is a dummy argument, we don't mess with it. */ 4585 char **cp; 4586 for (cp = argument_vector + 1; 4587 cp < argument_vector + argument_count; 4588 ++cp) 4589 free (*cp); 4590 4591 argument_count = 1; 4592 } 4593 if (err) 4594 /* We will have printed an error message already. */ 4595 buf_output0 (buf_to_net, "error \n"); 4596 else 4597 buf_output0 (buf_to_net, "ok\n"); 4598 4599 /* The client is waiting for the module expansions, so we must 4600 send the output now. */ 4601 buf_flush (buf_to_net, 1); 4602 } 4603 4604 void 4605 server_prog (dir, name, which) 4606 char *dir; 4607 char *name; 4608 enum progs which; 4609 { 4610 if (!supported_response ("Set-checkin-prog")) 4611 { 4612 buf_output0 (buf_to_net, "E \ 4613 warning: this client does not support -i or -u flags in the modules file.\n"); 4614 return; 4615 } 4616 switch (which) 4617 { 4618 case PROG_CHECKIN: 4619 buf_output0 (buf_to_net, "Set-checkin-prog "); 4620 break; 4621 case PROG_UPDATE: 4622 buf_output0 (buf_to_net, "Set-update-prog "); 4623 break; 4624 } 4625 buf_output0 (buf_to_net, dir); 4626 buf_append_char (buf_to_net, '\n'); 4627 buf_output0 (buf_to_net, name); 4628 buf_append_char (buf_to_net, '\n'); 4629 } 4630 4631 static void 4632 serve_checkin_prog (arg) 4633 char *arg; 4634 { 4635 FILE *f; 4636 4637 /* Before we do anything we first check if this command is not 4638 disabled. */ 4639 if (disable_x_prog) 4640 { 4641 if (alloc_pending (80)) 4642 sprintf (pending_error_text, "\ 4643 E Checkin-prog disabled by configuration"); 4644 return; 4645 } 4646 4647 f = CVS_FOPEN (CVSADM_CIPROG, "w+"); 4648 if (f == NULL) 4649 { 4650 int save_errno = errno; 4651 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4652 sprintf (pending_error_text, "E cannot open %s", CVSADM_CIPROG); 4653 pending_error = save_errno; 4654 return; 4655 } 4656 if (fprintf (f, "%s\n", arg) < 0) 4657 { 4658 int save_errno = errno; 4659 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4660 sprintf (pending_error_text, 4661 "E cannot write to %s", CVSADM_CIPROG); 4662 pending_error = save_errno; 4663 return; 4664 } 4665 if (fclose (f) == EOF) 4666 { 4667 int save_errno = errno; 4668 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4669 sprintf (pending_error_text, "E cannot close %s", CVSADM_CIPROG); 4670 pending_error = save_errno; 4671 return; 4672 } 4673 } 4674 4675 static void 4676 serve_update_prog (arg) 4677 char *arg; 4678 { 4679 FILE *f; 4680 4681 /* Before we do anything we first check if this command is not 4682 disabled. */ 4683 if (disable_x_prog) 4684 { 4685 if (alloc_pending (80)) 4686 sprintf (pending_error_text, "\ 4687 E Update-prog disabled by configuration"); 4688 return; 4689 } 4690 4691 /* Before we do anything we need to make sure we are not in readonly 4692 mode. */ 4693 if (!check_command_legal_p ("commit")) 4694 { 4695 /* I might be willing to make this a warning, except we lack the 4696 machinery to do so. */ 4697 if (alloc_pending (80)) 4698 sprintf (pending_error_text, "\ 4699 E Flag -u in modules not allowed in readonly mode"); 4700 return; 4701 } 4702 4703 f = CVS_FOPEN (CVSADM_UPROG, "w+"); 4704 if (f == NULL) 4705 { 4706 int save_errno = errno; 4707 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4708 sprintf (pending_error_text, "E cannot open %s", CVSADM_UPROG); 4709 pending_error = save_errno; 4710 return; 4711 } 4712 if (fprintf (f, "%s\n", arg) < 0) 4713 { 4714 int save_errno = errno; 4715 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4716 sprintf (pending_error_text, "E cannot write to %s", CVSADM_UPROG); 4717 pending_error = save_errno; 4718 return; 4719 } 4720 if (fclose (f) == EOF) 4721 { 4722 int save_errno = errno; 4723 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4724 sprintf (pending_error_text, "E cannot close %s", CVSADM_UPROG); 4725 pending_error = save_errno; 4726 return; 4727 } 4728 } 4729 4730 static void serve_valid_requests PROTO((char *arg)); 4731 4732 #endif /* SERVER_SUPPORT */ 4733 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) 4734 4735 /* 4736 * Parts of this table are shared with the client code, 4737 * but the client doesn't need to know about the handler 4738 * functions. 4739 */ 4740 4741 struct request requests[] = 4742 { 4743 #ifdef SERVER_SUPPORT 4744 #define REQ_LINE(n, f, s) {n, f, s} 4745 #else 4746 #define REQ_LINE(n, f, s) {n, s} 4747 #endif 4748 4749 REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS), 4750 REQ_LINE("Valid-responses", serve_valid_responses, 4751 RQ_ESSENTIAL | RQ_ROOTLESS), 4752 REQ_LINE("valid-requests", serve_valid_requests, 4753 RQ_ESSENTIAL | RQ_ROOTLESS), 4754 REQ_LINE("Repository", serve_repository, 0), 4755 REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL), 4756 REQ_LINE("Max-dotdot", serve_max_dotdot, 0), 4757 REQ_LINE("Static-directory", serve_static_directory, 0), 4758 REQ_LINE("Sticky", serve_sticky, 0), 4759 REQ_LINE("Checkin-prog", serve_checkin_prog, 0), 4760 REQ_LINE("Update-prog", serve_update_prog, 0), 4761 REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL), 4762 REQ_LINE("Kopt", serve_kopt, 0), 4763 REQ_LINE("Checkin-time", serve_checkin_time, 0), 4764 REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL), 4765 REQ_LINE("Is-modified", serve_is_modified, 0), 4766 4767 /* The client must send this request to interoperate with CVS 1.5 4768 through 1.9 servers. The server must support it (although it can 4769 be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */ 4770 REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS), 4771 4772 REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL), 4773 REQ_LINE("Notify", serve_notify, 0), 4774 REQ_LINE("Questionable", serve_questionable, 0), 4775 REQ_LINE("Case", serve_case, 0), 4776 REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL), 4777 REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL), 4778 REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS), 4779 REQ_LINE("Gzip-stream", serve_gzip_stream, 0), 4780 REQ_LINE("wrapper-sendme-rcsOptions", 4781 serve_wrapper_sendme_rcs_options, 4782 0), 4783 REQ_LINE("Set", serve_set, RQ_ROOTLESS), 4784 #ifdef ENCRYPTION 4785 # ifdef HAVE_KERBEROS 4786 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0), 4787 # endif 4788 # ifdef HAVE_GSSAPI 4789 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0), 4790 # endif 4791 #endif 4792 #ifdef HAVE_GSSAPI 4793 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0), 4794 #endif 4795 REQ_LINE("expand-modules", serve_expand_modules, 0), 4796 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL), 4797 REQ_LINE("co", serve_co, RQ_ESSENTIAL), 4798 REQ_LINE("update", serve_update, RQ_ESSENTIAL), 4799 REQ_LINE("diff", serve_diff, 0), 4800 REQ_LINE("log", serve_log, 0), 4801 REQ_LINE("rlog", serve_rlog, 0), 4802 REQ_LINE("add", serve_add, 0), 4803 REQ_LINE("remove", serve_remove, 0), 4804 REQ_LINE("update-patches", serve_ignore, 0), 4805 REQ_LINE("gzip-file-contents", serve_gzip_contents, 0), 4806 REQ_LINE("status", serve_status, 0), 4807 REQ_LINE("rdiff", serve_rdiff, 0), 4808 REQ_LINE("tag", serve_tag, 0), 4809 REQ_LINE("rtag", serve_rtag, 0), 4810 REQ_LINE("import", serve_import, 0), 4811 REQ_LINE("admin", serve_admin, 0), 4812 REQ_LINE("export", serve_export, 0), 4813 REQ_LINE("history", serve_history, 0), 4814 REQ_LINE("release", serve_release, 0), 4815 REQ_LINE("watch-on", serve_watch_on, 0), 4816 REQ_LINE("watch-off", serve_watch_off, 0), 4817 REQ_LINE("watch-add", serve_watch_add, 0), 4818 REQ_LINE("watch-remove", serve_watch_remove, 0), 4819 REQ_LINE("watchers", serve_watchers, 0), 4820 REQ_LINE("editors", serve_editors, 0), 4821 REQ_LINE("init", serve_init, RQ_ROOTLESS), 4822 REQ_LINE("annotate", serve_annotate, 0), 4823 REQ_LINE("rannotate", serve_rannotate, 0), 4824 REQ_LINE("noop", serve_noop, RQ_ROOTLESS), 4825 REQ_LINE("version", serve_version, RQ_ROOTLESS), 4826 REQ_LINE(NULL, NULL, 0) 4827 4828 #undef REQ_LINE 4829 }; 4830 4831 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */ 4832 #ifdef SERVER_SUPPORT 4833 4834 static void 4835 serve_valid_requests (arg) 4836 char *arg; 4837 { 4838 struct request *rq; 4839 if (print_pending_error ()) 4840 return; 4841 buf_output0 (buf_to_net, "Valid-requests"); 4842 for (rq = requests; rq->name != NULL; rq++) 4843 { 4844 if (rq->func != NULL) 4845 { 4846 buf_append_char (buf_to_net, ' '); 4847 buf_output0 (buf_to_net, rq->name); 4848 } 4849 } 4850 buf_output0 (buf_to_net, "\nok\n"); 4851 4852 /* The client is waiting for the list of valid requests, so we 4853 must send the output now. */ 4854 buf_flush (buf_to_net, 1); 4855 } 4856 4857 #ifdef SUNOS_KLUDGE 4858 /* 4859 * Delete temporary files. SIG is the signal making this happen, or 4860 * 0 if not called as a result of a signal. 4861 */ 4862 static int command_pid_is_dead; 4863 static void wait_sig (sig) 4864 int sig; 4865 { 4866 int status; 4867 int save_errno = errno; 4868 4869 pid_t r = wait (&status); 4870 if (r == command_pid) 4871 command_pid_is_dead++; 4872 errno = save_errno; 4873 } 4874 #endif /* SUNOS_KLUDGE */ 4875 4876 void 4877 server_cleanup (sig) 4878 int sig; 4879 { 4880 /* Do "rm -rf" on the temp directory. */ 4881 int status; 4882 int save_noexec; 4883 4884 if (buf_to_net != NULL) 4885 { 4886 /* FIXME: If this is not the final call from server, this 4887 could deadlock, because the client might be blocked writing 4888 to us. This should not be a problem in practice, because 4889 we do not generate much output when the client is not 4890 waiting for it. */ 4891 set_block (buf_to_net); 4892 buf_flush (buf_to_net, 1); 4893 4894 /* The calls to buf_shutdown are currently only meaningful 4895 when we are using compression. First we shut down 4896 BUF_FROM_NET. That will pick up the checksum generated 4897 when the client shuts down its buffer. Then, after we have 4898 generated any final output, we shut down BUF_TO_NET. */ 4899 4900 status = buf_shutdown (buf_from_net); 4901 if (status != 0) 4902 { 4903 error (0, status, "shutting down buffer from client"); 4904 buf_flush (buf_to_net, 1); 4905 } 4906 } 4907 4908 if (dont_delete_temp) 4909 { 4910 if (buf_to_net != NULL) 4911 (void) buf_shutdown (buf_to_net); 4912 return; 4913 } 4914 4915 /* What a bogus kludge. This disgusting code makes all kinds of 4916 assumptions about SunOS, and is only for a bug in that system. 4917 So only enable it on Suns. */ 4918 #ifdef SUNOS_KLUDGE 4919 if (command_pid > 0) 4920 { 4921 /* To avoid crashes on SunOS due to bugs in SunOS tmpfs 4922 triggered by the use of rename() in RCS, wait for the 4923 subprocess to die. Unfortunately, this means draining output 4924 while waiting for it to unblock the signal we sent it. Yuck! */ 4925 int status; 4926 pid_t r; 4927 4928 signal (SIGCHLD, wait_sig); 4929 if (sig) 4930 /* Perhaps SIGTERM would be more correct. But the child 4931 process will delay the SIGINT delivery until its own 4932 children have exited. */ 4933 kill (command_pid, SIGINT); 4934 /* The caller may also have sent a signal to command_pid, so 4935 always try waiting. First, though, check and see if it's still 4936 there.... */ 4937 do_waitpid: 4938 r = waitpid (command_pid, &status, WNOHANG); 4939 if (r == 0) 4940 ; 4941 else if (r == command_pid) 4942 command_pid_is_dead++; 4943 else if (r == -1) 4944 switch (errno) 4945 { 4946 case ECHILD: 4947 command_pid_is_dead++; 4948 break; 4949 case EINTR: 4950 goto do_waitpid; 4951 } 4952 else 4953 /* waitpid should always return one of the above values */ 4954 abort (); 4955 while (!command_pid_is_dead) 4956 { 4957 struct timeval timeout; 4958 struct fd_set_wrapper readfds; 4959 char buf[100]; 4960 int i; 4961 4962 /* Use a non-zero timeout to avoid eating up CPU cycles. */ 4963 timeout.tv_sec = 2; 4964 timeout.tv_usec = 0; 4965 readfds = command_fds_to_drain; 4966 switch (select (max_command_fd + 1, &readfds.fds, 4967 (fd_set *)0, (fd_set *)0, 4968 &timeout)) 4969 { 4970 case -1: 4971 if (errno != EINTR) 4972 abort (); 4973 case 0: 4974 /* timeout */ 4975 break; 4976 case 1: 4977 for (i = 0; i <= max_command_fd; i++) 4978 { 4979 if (!FD_ISSET (i, &readfds.fds)) 4980 continue; 4981 /* this fd is non-blocking */ 4982 while (read (i, buf, sizeof (buf)) >= 1) 4983 ; 4984 } 4985 break; 4986 default: 4987 abort (); 4988 } 4989 } 4990 } 4991 #endif /* SUNOS_KLUDGE */ 4992 4993 CVS_CHDIR (Tmpdir); 4994 /* Temporarily clear noexec, so that we clean up our temp directory 4995 regardless of it (this could more cleanly be handled by moving 4996 the noexec check to all the unlink_file_dir callers from 4997 unlink_file_dir itself). */ 4998 save_noexec = noexec; 4999 noexec = 0; 5000 /* FIXME? Would be nice to not ignore errors. But what should we do? 5001 We could try to do this before we shut down the network connection, 5002 and try to notify the client (but the client might not be waiting 5003 for responses). We could try something like syslog() or our own 5004 log file. */ 5005 unlink_file_dir (orig_server_temp_dir); 5006 noexec = save_noexec; 5007 5008 if (buf_to_net != NULL) 5009 (void) buf_shutdown (buf_to_net); 5010 } 5011 5012 int server_active = 0; 5013 int server_expanding = 0; 5014 5015 int 5016 server (argc, argv) 5017 int argc; 5018 char **argv; 5019 { 5020 if (argc == -1) 5021 { 5022 static const char *const msg[] = 5023 { 5024 "Usage: %s %s\n", 5025 " Normally invoked by a cvs client on a remote machine.\n", 5026 NULL 5027 }; 5028 usage (msg); 5029 } 5030 /* Ignore argc and argv. They might be from .cvsrc. */ 5031 5032 buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, 5033 outbuf_memory_error); 5034 buf_from_net = stdio_buffer_initialize (stdin, 1, outbuf_memory_error); 5035 5036 saved_output = buf_nonio_initialize (outbuf_memory_error); 5037 saved_outerr = buf_nonio_initialize (outbuf_memory_error); 5038 5039 /* Since we're in the server parent process, error should use the 5040 protocol to report error messages. */ 5041 error_use_protocol = 1; 5042 5043 /* OK, now figure out where we stash our temporary files. */ 5044 { 5045 char *p; 5046 5047 /* The code which wants to chdir into server_temp_dir is not set 5048 up to deal with it being a relative path. So give an error 5049 for that case. */ 5050 if (!isabsolute (Tmpdir)) 5051 { 5052 if (alloc_pending (80 + strlen (Tmpdir))) 5053 sprintf (pending_error_text, 5054 "E Value of %s for TMPDIR is not absolute", Tmpdir); 5055 5056 /* FIXME: we would like this error to be persistent, that 5057 is, not cleared by print_pending_error. The current client 5058 will exit as soon as it gets an error, but the protocol spec 5059 does not require a client to do so. */ 5060 } 5061 else 5062 { 5063 int status; 5064 int i = 0; 5065 5066 server_temp_dir = malloc (strlen (Tmpdir) + 80); 5067 if (server_temp_dir == NULL) 5068 { 5069 /* 5070 * Strictly speaking, we're not supposed to output anything 5071 * now. But we're about to exit(), give it a try. 5072 */ 5073 printf ("E Fatal server error, aborting.\n\ 5074 error ENOMEM Virtual memory exhausted.\n"); 5075 5076 /* I'm doing this manually rather than via error_exit () 5077 because I'm not sure whether we want to call server_cleanup. 5078 Needs more investigation.... */ 5079 5080 #ifdef SYSTEM_CLEANUP 5081 /* Hook for OS-specific behavior, for example socket 5082 subsystems on NT and OS2 or dealing with windows 5083 and arguments on Mac. */ 5084 SYSTEM_CLEANUP (); 5085 #endif 5086 5087 exit (EXIT_FAILURE); 5088 } 5089 strcpy (server_temp_dir, Tmpdir); 5090 5091 /* Remove a trailing slash from TMPDIR if present. */ 5092 p = server_temp_dir + strlen (server_temp_dir) - 1; 5093 if (*p == '/') 5094 *p = '\0'; 5095 5096 /* 5097 * I wanted to use cvs-serv/PID, but then you have to worry about 5098 * the permissions on the cvs-serv directory being right. So 5099 * use cvs-servPID. 5100 */ 5101 strcat (server_temp_dir, "/cvs-serv"); 5102 5103 p = server_temp_dir + strlen (server_temp_dir); 5104 sprintf (p, "%ld", (long) getpid ()); 5105 5106 orig_server_temp_dir = server_temp_dir; 5107 5108 /* Create the temporary directory, and set the mode to 5109 700, to discourage random people from tampering with 5110 it. */ 5111 while ((status = mkdir_p (server_temp_dir)) == EEXIST) 5112 { 5113 static const char suffix[] = "abcdefghijklmnopqrstuvwxyz"; 5114 5115 if (i >= sizeof suffix - 1) break; 5116 if (i == 0) p = server_temp_dir + strlen (server_temp_dir); 5117 p[0] = suffix[i++]; 5118 p[1] = '\0'; 5119 } 5120 if (status != 0) 5121 { 5122 if (alloc_pending (80 + strlen (server_temp_dir))) 5123 sprintf (pending_error_text, 5124 "E can't create temporary directory %s", 5125 server_temp_dir); 5126 pending_error = status; 5127 } 5128 #ifndef CHMOD_BROKEN 5129 else if (chmod (server_temp_dir, S_IRWXU) < 0) 5130 { 5131 int save_errno = errno; 5132 if (alloc_pending (80 + strlen (server_temp_dir))) 5133 sprintf (pending_error_text, 5134 "E cannot change permissions on temporary directory %s", 5135 server_temp_dir); 5136 pending_error = save_errno; 5137 } 5138 #endif 5139 else if (CVS_CHDIR (server_temp_dir) < 0) 5140 { 5141 int save_errno = errno; 5142 if (alloc_pending (80 + strlen (server_temp_dir))) 5143 sprintf (pending_error_text, 5144 "E cannot change to temporary directory %s", 5145 server_temp_dir); 5146 pending_error = save_errno; 5147 } 5148 } 5149 } 5150 5151 #ifdef SIGABRT 5152 (void) SIG_register (SIGABRT, server_cleanup); 5153 #endif 5154 #ifdef SIGHUP 5155 (void) SIG_register (SIGHUP, server_cleanup); 5156 #endif 5157 #ifdef SIGINT 5158 (void) SIG_register (SIGINT, server_cleanup); 5159 #endif 5160 #ifdef SIGQUIT 5161 (void) SIG_register (SIGQUIT, server_cleanup); 5162 #endif 5163 #ifdef SIGPIPE 5164 (void) SIG_register (SIGPIPE, server_cleanup); 5165 #endif 5166 #ifdef SIGTERM 5167 (void) SIG_register (SIGTERM, server_cleanup); 5168 #endif 5169 5170 /* Now initialize our argument vector (for arguments from the client). */ 5171 5172 /* Small for testing. */ 5173 argument_vector_size = 1; 5174 argument_vector = 5175 (char **) malloc (argument_vector_size * sizeof (char *)); 5176 if (argument_vector == NULL) 5177 { 5178 /* 5179 * Strictly speaking, we're not supposed to output anything 5180 * now. But we're about to exit(), give it a try. 5181 */ 5182 printf ("E Fatal server error, aborting.\n\ 5183 error ENOMEM Virtual memory exhausted.\n"); 5184 5185 /* I'm doing this manually rather than via error_exit () 5186 because I'm not sure whether we want to call server_cleanup. 5187 Needs more investigation.... */ 5188 5189 #ifdef SYSTEM_CLEANUP 5190 /* Hook for OS-specific behavior, for example socket subsystems on 5191 NT and OS2 or dealing with windows and arguments on Mac. */ 5192 SYSTEM_CLEANUP (); 5193 #endif 5194 5195 exit (EXIT_FAILURE); 5196 } 5197 5198 argument_count = 1; 5199 /* This gets printed if the client supports an option which the 5200 server doesn't, causing the server to print a usage message. 5201 FIXME: probably should be using program_name here. 5202 FIXME: just a nit, I suppose, but the usage message the server 5203 prints isn't literally true--it suggests "cvs server" followed 5204 by options which are for a particular command. Might be nice to 5205 say something like "client apparently supports an option not supported 5206 by this server" or something like that instead of usage message. */ 5207 argument_vector[0] = "cvs server"; 5208 5209 while (1) 5210 { 5211 char *cmd, *orig_cmd; 5212 struct request *rq; 5213 int status; 5214 5215 status = buf_read_line (buf_from_net, &cmd, (int *) NULL); 5216 if (status == -2) 5217 { 5218 buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\ 5219 error ENOMEM Virtual memory exhausted.\n"); 5220 break; 5221 } 5222 if (status != 0) 5223 break; 5224 5225 orig_cmd = cmd; 5226 for (rq = requests; rq->name != NULL; ++rq) 5227 if (strncmp (cmd, rq->name, strlen (rq->name)) == 0) 5228 { 5229 int len = strlen (rq->name); 5230 if (cmd[len] == '\0') 5231 cmd += len; 5232 else if (cmd[len] == ' ') 5233 cmd += len + 1; 5234 else 5235 /* 5236 * The first len characters match, but it's a different 5237 * command. e.g. the command is "cooperate" but we matched 5238 * "co". 5239 */ 5240 continue; 5241 5242 if (!(rq->flags & RQ_ROOTLESS) 5243 && current_parsed_root == NULL) 5244 { 5245 /* For commands which change the way in which data 5246 is sent and received, for example Gzip-stream, 5247 this does the wrong thing. Since the client 5248 assumes that everything is being compressed, 5249 unconditionally, there is no way to give this 5250 error to the client without turning on 5251 compression. The obvious fix would be to make 5252 Gzip-stream RQ_ROOTLESS (with the corresponding 5253 change to the spec), and that might be a good 5254 idea but then again I can see some settings in 5255 CVSROOT about what compression level to allow. 5256 I suppose a more baroque answer would be to 5257 turn on compression (say, at level 1), just 5258 enough to give the "Root request missing" 5259 error. For now we just lose. */ 5260 if (alloc_pending (80)) 5261 sprintf (pending_error_text, 5262 "E Protocol error: Root request missing"); 5263 } 5264 else 5265 (*rq->func) (cmd); 5266 break; 5267 } 5268 if (rq->name == NULL) 5269 { 5270 if (!print_pending_error ()) 5271 { 5272 buf_output0 (buf_to_net, "error unrecognized request `"); 5273 buf_output0 (buf_to_net, cmd); 5274 buf_append_char (buf_to_net, '\''); 5275 buf_append_char (buf_to_net, '\n'); 5276 } 5277 } 5278 free (orig_cmd); 5279 } 5280 server_cleanup (0); 5281 return 0; 5282 } 5283 5284 5285 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) 5286 static void switch_to_user PROTO((const char *)); 5287 5288 static void 5289 switch_to_user (username) 5290 const char *username; 5291 { 5292 struct passwd *pw; 5293 5294 pw = getpwnam (username); 5295 if (pw == NULL) 5296 { 5297 /* Normally this won't be reached; check_password contains 5298 a similar check. */ 5299 5300 printf ("E Fatal error, aborting.\n\ 5301 error 0 %s: no such user\n", username); 5302 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5303 error_exit (); 5304 } 5305 5306 #if HAVE_INITGROUPS 5307 if (initgroups (pw->pw_name, pw->pw_gid) < 0 5308 # ifdef EPERM 5309 /* At least on the system I tried, initgroups() only works as root. 5310 But we do still want to report ENOMEM and whatever other 5311 errors initgroups() might dish up. */ 5312 && errno != EPERM 5313 # endif 5314 ) 5315 { 5316 /* This could be a warning, but I'm not sure I see the point 5317 in doing that instead of an error given that it would happen 5318 on every connection. We could log it somewhere and not tell 5319 the user. But at least for now make it an error. */ 5320 printf ("error 0 initgroups failed: %s\n", strerror (errno)); 5321 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5322 error_exit (); 5323 } 5324 #endif /* HAVE_INITGROUPS */ 5325 5326 #ifdef SETXID_SUPPORT 5327 /* honor the setgid bit iff set*/ 5328 if (getgid() != getegid()) 5329 { 5330 if (setgid (getegid ()) < 0) 5331 { 5332 /* See comments at setuid call below for more discussion. */ 5333 printf ("error 0 setgid failed: %s\n", strerror (errno)); 5334 /* Don't worry about server_cleanup; 5335 server_active isn't set yet. */ 5336 error_exit (); 5337 } 5338 } 5339 else 5340 #endif 5341 { 5342 if (setgid (pw->pw_gid) < 0) 5343 { 5344 /* See comments at setuid call below for more discussion. */ 5345 printf ("error 0 setgid failed: %s\n", strerror (errno)); 5346 /* Don't worry about server_cleanup; 5347 server_active isn't set yet. */ 5348 error_exit (); 5349 } 5350 } 5351 5352 if (setuid (pw->pw_uid) < 0) 5353 { 5354 /* Note that this means that if run as a non-root user, 5355 CVSROOT/passwd must contain the user we are running as 5356 (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems 5357 cleaner than ignoring the error like CVS 1.10 and older but 5358 it does mean that some people might need to update their 5359 CVSROOT/passwd file. */ 5360 printf ("error 0 setuid failed: %s\n", strerror (errno)); 5361 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5362 error_exit (); 5363 } 5364 5365 /* We don't want our umask to change file modes. The modes should 5366 be set by the modes used in the repository, and by the umask of 5367 the client. */ 5368 umask (0); 5369 5370 #ifdef AUTH_SERVER_SUPPORT 5371 /* Make sure our CVS_Username has been set. */ 5372 if (CVS_Username == NULL) 5373 CVS_Username = xstrdup (username); 5374 #endif 5375 5376 #if HAVE_PUTENV 5377 /* Set LOGNAME, USER and CVS_USER in the environment, in case they 5378 are already set to something else. */ 5379 { 5380 char *env; 5381 #ifdef AUTH_SERVER_SUPPORT 5382 char *cvs_user; 5383 #endif 5384 5385 env = xmalloc (sizeof "LOGNAME=" + strlen (username)); 5386 (void) sprintf (env, "LOGNAME=%s", username); 5387 (void) putenv (env); 5388 5389 env = xmalloc (sizeof "USER=" + strlen (username)); 5390 (void) sprintf (env, "USER=%s", username); 5391 (void) putenv (env); 5392 5393 #ifdef AUTH_SERVER_SUPPORT 5394 cvs_user = NULL != CVS_Username ? CVS_Username : ""; 5395 env = xmalloc (sizeof "CVS_USER=" + strlen (cvs_user)); 5396 (void) sprintf (env, "CVS_USER=%s", cvs_user); 5397 (void) putenv (env); 5398 #endif 5399 } 5400 #endif /* HAVE_PUTENV */ 5401 } 5402 #endif 5403 5404 #ifdef AUTH_SERVER_SUPPORT 5405 5406 extern char *crypt PROTO((const char *, const char *)); 5407 5408 5409 /* 5410 * 0 means no entry found for this user. 5411 * 1 means entry found and password matches (or found password is empty) 5412 * 2 means entry found, but password does not match. 5413 * 5414 * If 1, host_user_ptr will be set to point at the system 5415 * username (i.e., the "real" identity, which may or may not be the 5416 * CVS username) of this user; caller may free this. Global 5417 * CVS_Username will point at an allocated copy of cvs username (i.e., 5418 * the username argument below). 5419 * kff todo: FIXME: last sentence is not true, it applies to caller. 5420 */ 5421 static int 5422 check_repository_password (username, password, repository, host_user_ptr) 5423 char *username, *password, *repository, **host_user_ptr; 5424 { 5425 int retval = 0; 5426 FILE *fp; 5427 char *filename; 5428 char *linebuf = NULL; 5429 size_t linebuf_len; 5430 int found_it = 0; 5431 int namelen; 5432 5433 /* We don't use current_parsed_root->directory because it hasn't been set yet 5434 * -- our `repository' argument came from the authentication 5435 * protocol, not the regular CVS protocol. 5436 */ 5437 5438 filename = xmalloc (strlen (repository) 5439 + 1 5440 + strlen (CVSROOTADM) 5441 + 1 5442 + strlen (CVSROOTADM_PASSWD) 5443 + 1); 5444 5445 (void) sprintf (filename, "%s/%s/%s", repository, 5446 CVSROOTADM, CVSROOTADM_PASSWD); 5447 5448 fp = CVS_FOPEN (filename, "r"); 5449 if (fp == NULL) 5450 { 5451 if (!existence_error (errno)) 5452 error (0, errno, "cannot open %s", filename); 5453 return 0; 5454 } 5455 5456 /* Look for a relevant line -- one with this user's name. */ 5457 namelen = strlen (username); 5458 while (getline (&linebuf, &linebuf_len, fp) >= 0) 5459 { 5460 if ((strncmp (linebuf, username, namelen) == 0) 5461 && (linebuf[namelen] == ':')) 5462 { 5463 found_it = 1; 5464 break; 5465 } 5466 } 5467 if (ferror (fp)) 5468 error (0, errno, "cannot read %s", filename); 5469 if (fclose (fp) < 0) 5470 error (0, errno, "cannot close %s", filename); 5471 5472 /* If found_it, then linebuf contains the information we need. */ 5473 if (found_it) 5474 { 5475 char *found_password, *host_user_tmp; 5476 char *non_cvsuser_portion; 5477 5478 /* We need to make sure lines such as 5479 * 5480 * "username::sysuser\n" 5481 * "username:\n" 5482 * "username: \n" 5483 * 5484 * all result in a found_password of NULL, but we also need to 5485 * make sure that 5486 * 5487 * "username: :sysuser\n" 5488 * "username: <whatever>:sysuser\n" 5489 * 5490 * continues to result in an impossible password. That way, 5491 * an admin would be on safe ground by going in and tacking a 5492 * space onto the front of a password to disable the account 5493 * (a technique some people use to close accounts 5494 * temporarily). 5495 */ 5496 5497 /* Make `non_cvsuser_portion' contain everything after the CVS 5498 username, but null out any final newline. */ 5499 non_cvsuser_portion = linebuf + namelen; 5500 strtok (non_cvsuser_portion, "\n"); 5501 5502 /* If there's a colon now, we just want to inch past it. */ 5503 if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion) 5504 non_cvsuser_portion++; 5505 5506 /* Okay, after this conditional chain, found_password and 5507 host_user_tmp will have useful values: */ 5508 5509 if ((non_cvsuser_portion == NULL) 5510 || (strlen (non_cvsuser_portion) == 0) 5511 || ((strspn (non_cvsuser_portion, " \t")) 5512 == strlen (non_cvsuser_portion))) 5513 { 5514 found_password = NULL; 5515 host_user_tmp = NULL; 5516 } 5517 else if (strncmp (non_cvsuser_portion, ":", 1) == 0) 5518 { 5519 found_password = NULL; 5520 host_user_tmp = non_cvsuser_portion + 1; 5521 if (strlen (host_user_tmp) == 0) 5522 host_user_tmp = NULL; 5523 } 5524 else 5525 { 5526 found_password = strtok (non_cvsuser_portion, ":"); 5527 host_user_tmp = strtok (NULL, ":"); 5528 } 5529 5530 /* Of course, maybe there was no system user portion... */ 5531 if (host_user_tmp == NULL) 5532 host_user_tmp = username; 5533 5534 /* Verify blank passwords directly, otherwise use crypt(). */ 5535 if ((found_password == NULL) 5536 || ((strcmp (found_password, crypt (password, found_password)) 5537 == 0))) 5538 { 5539 /* Give host_user_ptr permanent storage. */ 5540 *host_user_ptr = xstrdup (host_user_tmp); 5541 retval = 1; 5542 } 5543 else 5544 { 5545 *host_user_ptr = NULL; 5546 retval = 2; 5547 } 5548 } 5549 else /* Didn't find this user, so deny access. */ 5550 { 5551 *host_user_ptr = NULL; 5552 retval = 0; 5553 } 5554 5555 free (filename); 5556 if (linebuf) 5557 free (linebuf); 5558 5559 return retval; 5560 } 5561 5562 5563 /* Return a hosting username if password matches, else NULL. */ 5564 static char * 5565 check_password (username, password, repository) 5566 char *username, *password, *repository; 5567 { 5568 int rc; 5569 char *host_user = NULL; 5570 5571 /* First we see if this user has a password in the CVS-specific 5572 password file. If so, that's enough to authenticate with. If 5573 not, we'll check /etc/passwd. */ 5574 5575 rc = check_repository_password (username, password, repository, 5576 &host_user); 5577 5578 if (rc == 2) 5579 return NULL; 5580 5581 /* else */ 5582 5583 if (rc == 1) 5584 { 5585 /* host_user already set by reference, so just return. */ 5586 goto handle_return; 5587 } 5588 else if (rc == 0 && system_auth) 5589 { 5590 /* No cvs password found, so try /etc/passwd. */ 5591 5592 const char *found_passwd = NULL; 5593 struct passwd *pw; 5594 #ifdef HAVE_GETSPNAM 5595 struct spwd *spw; 5596 5597 spw = getspnam (username); 5598 if (spw != NULL) 5599 { 5600 found_passwd = spw->sp_pwdp; 5601 } 5602 #endif 5603 5604 if (found_passwd == NULL && (pw = getpwnam (username)) != NULL) 5605 { 5606 found_passwd = pw->pw_passwd; 5607 } 5608 5609 if (found_passwd == NULL) 5610 { 5611 printf ("E Fatal error, aborting.\n\ 5612 error 0 %s: no such user\n", username); 5613 5614 /* I'm doing this manually rather than via error_exit () 5615 because I'm not sure whether we want to call server_cleanup. 5616 Needs more investigation.... */ 5617 5618 #ifdef SYSTEM_CLEANUP 5619 /* Hook for OS-specific behavior, for example socket subsystems on 5620 NT and OS2 or dealing with windows and arguments on Mac. */ 5621 SYSTEM_CLEANUP (); 5622 #endif 5623 5624 exit (EXIT_FAILURE); 5625 } 5626 5627 if (*found_passwd) 5628 { 5629 /* user exists and has a password */ 5630 host_user = ((! strcmp (found_passwd, 5631 crypt (password, found_passwd))) 5632 ? xstrdup (username) : NULL); 5633 goto handle_return; 5634 } 5635 else if (password && *password) 5636 { 5637 /* user exists and has no system password, but we got 5638 one as parameter */ 5639 host_user = xstrdup (username); 5640 goto handle_return; 5641 } 5642 else 5643 { 5644 /* user exists but has no password at all */ 5645 host_user = NULL; 5646 goto handle_return; 5647 } 5648 } 5649 else if (rc == 0) 5650 { 5651 /* Note that the message _does_ distinguish between the case in 5652 which we check for a system password and the case in which 5653 we do not. It is a real pain to track down why it isn't 5654 letting you in if it won't say why, and I am not convinced 5655 that the potential information disclosure to an attacker 5656 outweighs this. */ 5657 printf ("error 0 no such user %s in CVSROOT/passwd\n", username); 5658 5659 /* I'm doing this manually rather than via error_exit () 5660 because I'm not sure whether we want to call server_cleanup. 5661 Needs more investigation.... */ 5662 5663 #ifdef SYSTEM_CLEANUP 5664 /* Hook for OS-specific behavior, for example socket subsystems on 5665 NT and OS2 or dealing with windows and arguments on Mac. */ 5666 SYSTEM_CLEANUP (); 5667 #endif 5668 exit (EXIT_FAILURE); 5669 } 5670 else 5671 { 5672 /* Something strange happened. We don't know what it was, but 5673 we certainly won't grant authorization. */ 5674 host_user = NULL; 5675 goto handle_return; 5676 } 5677 5678 handle_return: 5679 if (host_user) 5680 { 5681 /* Set CVS_Username here, in allocated space. 5682 It might or might not be the same as host_user. */ 5683 CVS_Username = xmalloc (strlen (username) + 1); 5684 strcpy (CVS_Username, username); 5685 } 5686 5687 return host_user; 5688 } 5689 5690 #endif /* AUTH_SERVER_SUPPORT */ 5691 5692 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) 5693 5694 /* Read username and password from client (i.e., stdin). 5695 If correct, then switch to run as that user and send an ACK to the 5696 client via stdout, else send NACK and die. */ 5697 void 5698 pserver_authenticate_connection () 5699 { 5700 char *tmp = NULL; 5701 size_t tmp_allocated = 0; 5702 #ifdef AUTH_SERVER_SUPPORT 5703 char *repository = NULL; 5704 size_t repository_allocated = 0; 5705 char *username = NULL; 5706 size_t username_allocated = 0; 5707 char *password = NULL; 5708 size_t password_allocated = 0; 5709 5710 char *host_user; 5711 char *descrambled_password; 5712 #endif /* AUTH_SERVER_SUPPORT */ 5713 int verify_and_exit = 0; 5714 5715 /* The Authentication Protocol. Client sends: 5716 * 5717 * BEGIN AUTH REQUEST\n 5718 * <REPOSITORY>\n 5719 * <USERNAME>\n 5720 * <PASSWORD>\n 5721 * END AUTH REQUEST\n 5722 * 5723 * Server uses above information to authenticate, then sends 5724 * 5725 * I LOVE YOU\n 5726 * 5727 * if it grants access, else 5728 * 5729 * I HATE YOU\n 5730 * 5731 * if it denies access (and it exits if denying). 5732 * 5733 * When the client is "cvs login", the user does not desire actual 5734 * repository access, but would like to confirm the password with 5735 * the server. In this case, the start and stop strings are 5736 * 5737 * BEGIN VERIFICATION REQUEST\n 5738 * 5739 * and 5740 * 5741 * END VERIFICATION REQUEST\n 5742 * 5743 * On a verification request, the server's responses are the same 5744 * (with the obvious semantics), but it exits immediately after 5745 * sending the response in both cases. 5746 * 5747 * Why is the repository sent? Well, note that the actual 5748 * client/server protocol can't start up until authentication is 5749 * successful. But in order to perform authentication, the server 5750 * needs to look up the password in the special CVS passwd file, 5751 * before trying /etc/passwd. So the client transmits the 5752 * repository as part of the "authentication protocol". The 5753 * repository will be redundantly retransmitted later, but that's no 5754 * big deal. 5755 */ 5756 5757 #ifdef SO_KEEPALIVE 5758 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever 5759 if the client dies while we are waiting for input. */ 5760 { 5761 int on = 1; 5762 5763 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, 5764 (char *) &on, sizeof on) < 0) 5765 { 5766 #ifdef HAVE_SYSLOG_H 5767 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); 5768 #endif 5769 } 5770 } 5771 #endif 5772 5773 /* Make sure the protocol starts off on the right foot... */ 5774 if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0) 5775 /* FIXME: what? We could try writing error/eof, but chances 5776 are the network connection is dead bidirectionally. log it 5777 somewhere? */ 5778 ; 5779 5780 if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0) 5781 verify_and_exit = 1; 5782 else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0) 5783 ; 5784 else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0) 5785 { 5786 #ifdef HAVE_GSSAPI 5787 free (tmp); 5788 gserver_authenticate_connection (); 5789 return; 5790 #else 5791 error (1, 0, "GSSAPI authentication not supported by this server"); 5792 #endif 5793 } 5794 else 5795 error (1, 0, "bad auth protocol start: %s", tmp); 5796 5797 #ifndef AUTH_SERVER_SUPPORT 5798 5799 error (1, 0, "Password authentication not supported by this server"); 5800 5801 #else /* AUTH_SERVER_SUPPORT */ 5802 5803 /* Get the three important pieces of information in order. */ 5804 /* See above comment about error handling. */ 5805 getline_safe (&repository, &repository_allocated, stdin, PATH_MAX); 5806 getline_safe (&username, &username_allocated, stdin, PATH_MAX); 5807 getline_safe (&password, &password_allocated, stdin, PATH_MAX); 5808 5809 /* Make them pure. */ 5810 strip_trailing_newlines (repository); 5811 strip_trailing_newlines (username); 5812 strip_trailing_newlines (password); 5813 5814 /* ... and make sure the protocol ends on the right foot. */ 5815 /* See above comment about error handling. */ 5816 getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX); 5817 if (strcmp (tmp, 5818 verify_and_exit ? 5819 "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") 5820 != 0) 5821 { 5822 error (1, 0, "bad auth protocol end: %s", tmp); 5823 } 5824 if (!root_allow_ok (repository)) 5825 { 5826 printf ("error 0 %s: no such repository\n", repository); 5827 #ifdef HAVE_SYSLOG_H 5828 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository); 5829 #endif 5830 goto i_hate_you; 5831 } 5832 5833 /* OK, now parse the config file, so we can use it to control how 5834 to check passwords. If there was an error parsing the config 5835 file, parse_config already printed an error. We keep going. 5836 Why? Because if we didn't, then there would be no way to check 5837 in a new CVSROOT/config file to fix the broken one! */ 5838 parse_config (repository); 5839 5840 /* We need the real cleartext before we hash it. */ 5841 descrambled_password = descramble (password); 5842 host_user = check_password (username, descrambled_password, repository); 5843 memset (descrambled_password, 0, strlen (descrambled_password)); 5844 free (descrambled_password); 5845 if (host_user == NULL) 5846 { 5847 #ifdef HAVE_SYSLOG_H 5848 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository); 5849 #ifdef LOG_AUTHPRIV 5850 syslog (LOG_AUTHPRIV | LOG_NOTICE, "login failure by %s / %s (for %s)", 5851 username, descrambled_password, repository); 5852 #endif 5853 #endif 5854 i_hate_you: 5855 printf ("I HATE YOU\n"); 5856 fflush (stdout); 5857 5858 /* Don't worry about server_cleanup, server_active isn't set 5859 yet. */ 5860 error_exit (); 5861 } 5862 5863 /* Don't go any farther if we're just responding to "cvs login". */ 5864 if (verify_and_exit) 5865 { 5866 printf ("I LOVE YOU\n"); 5867 fflush (stdout); 5868 5869 #ifdef SYSTEM_CLEANUP 5870 /* Hook for OS-specific behavior, for example socket subsystems on 5871 NT and OS2 or dealing with windows and arguments on Mac. */ 5872 SYSTEM_CLEANUP (); 5873 #endif 5874 5875 exit (0); 5876 } 5877 5878 /* Set Pserver_Repos so that we can check later that the same 5879 repository is sent in later client/server protocol. */ 5880 Pserver_Repos = xmalloc (strlen (repository) + 1); 5881 strcpy (Pserver_Repos, repository); 5882 5883 /* Switch to run as this user. */ 5884 switch_to_user (host_user); 5885 free (host_user); 5886 free (tmp); 5887 free (repository); 5888 free (username); 5889 free (password); 5890 5891 printf ("I LOVE YOU\n"); 5892 fflush (stdout); 5893 #endif /* AUTH_SERVER_SUPPORT */ 5894 } 5895 5896 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */ 5897 5898 5899 #ifdef HAVE_KERBEROS 5900 void 5901 kserver_authenticate_connection () 5902 { 5903 int status; 5904 char instance[INST_SZ]; 5905 struct sockaddr_in peer; 5906 struct sockaddr_in laddr; 5907 int len; 5908 KTEXT_ST ticket; 5909 AUTH_DAT auth; 5910 char version[KRB_SENDAUTH_VLEN]; 5911 char user[ANAME_SZ]; 5912 5913 strcpy (instance, "*"); 5914 len = sizeof peer; 5915 if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0 5916 || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr, 5917 &len) < 0) 5918 { 5919 printf ("E Fatal error, aborting.\n\ 5920 error %s getpeername or getsockname failed\n", strerror (errno)); 5921 #ifdef SYSTEM_CLEANUP 5922 /* Hook for OS-specific behavior, for example socket subsystems on 5923 NT and OS2 or dealing with windows and arguments on Mac. */ 5924 SYSTEM_CLEANUP (); 5925 #endif 5926 exit (EXIT_FAILURE); 5927 } 5928 5929 #ifdef SO_KEEPALIVE 5930 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever 5931 if the client dies while we are waiting for input. */ 5932 { 5933 int on = 1; 5934 5935 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, 5936 (char *) &on, sizeof on) < 0) 5937 { 5938 #ifdef HAVE_SYSLOG_H 5939 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); 5940 #endif 5941 } 5942 } 5943 #endif 5944 5945 status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd", 5946 instance, &peer, &laddr, &auth, "", sched, 5947 version); 5948 if (status != KSUCCESS) 5949 { 5950 printf ("E Fatal error, aborting.\n\ 5951 error 0 kerberos: %s\n", krb_get_err_text(status)); 5952 #ifdef SYSTEM_CLEANUP 5953 /* Hook for OS-specific behavior, for example socket subsystems on 5954 NT and OS2 or dealing with windows and arguments on Mac. */ 5955 SYSTEM_CLEANUP (); 5956 #endif 5957 exit (EXIT_FAILURE); 5958 } 5959 5960 memcpy (kblock, auth.session, sizeof (C_Block)); 5961 5962 /* Get the local name. */ 5963 status = krb_kntoln (&auth, user); 5964 if (status != KSUCCESS) 5965 { 5966 printf ("E Fatal error, aborting.\n\ 5967 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status)); 5968 #ifdef SYSTEM_CLEANUP 5969 /* Hook for OS-specific behavior, for example socket subsystems on 5970 NT and OS2 or dealing with windows and arguments on Mac. */ 5971 SYSTEM_CLEANUP (); 5972 #endif 5973 exit (EXIT_FAILURE); 5974 } 5975 5976 /* Switch to run as this user. */ 5977 switch_to_user (user); 5978 } 5979 #endif /* HAVE_KERBEROS */ 5980 5981 #ifdef HAVE_GSSAPI 5982 5983 #ifndef MAXHOSTNAMELEN 5984 #define MAXHOSTNAMELEN (256) 5985 #endif 5986 5987 /* Authenticate a GSSAPI connection. This is called from 5988 pserver_authenticate_connection, and it handles success and failure 5989 the same way. */ 5990 5991 static void 5992 gserver_authenticate_connection () 5993 { 5994 char hostname[MAXHOSTNAMELEN]; 5995 struct hostent *hp; 5996 gss_buffer_desc tok_in, tok_out; 5997 char buf[1024]; 5998 OM_uint32 stat_min, ret; 5999 gss_name_t server_name, client_name; 6000 gss_cred_id_t server_creds; 6001 int nbytes; 6002 gss_OID mechid; 6003 6004 gethostname (hostname, sizeof hostname); 6005 hp = gethostbyname (hostname); 6006 if (hp == NULL) 6007 error (1, 0, "can't get canonical hostname"); 6008 6009 sprintf (buf, "cvs@%s", hp->h_name); 6010 tok_in.value = buf; 6011 tok_in.length = strlen (buf); 6012 6013 if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, 6014 &server_name) != GSS_S_COMPLETE) 6015 error (1, 0, "could not import GSSAPI service name %s", buf); 6016 6017 /* Acquire the server credential to verify the client's 6018 authentication. */ 6019 if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET, 6020 GSS_C_ACCEPT, &server_creds, 6021 NULL, NULL) != GSS_S_COMPLETE) 6022 error (1, 0, "could not acquire GSSAPI server credentials"); 6023 6024 gss_release_name (&stat_min, &server_name); 6025 6026 /* The client will send us a two byte length followed by that many 6027 bytes. */ 6028 if (fread (buf, 1, 2, stdin) != 2) 6029 error (1, errno, "read of length failed"); 6030 6031 nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff); 6032 assert (nbytes <= sizeof buf); 6033 6034 if (fread (buf, 1, nbytes, stdin) != nbytes) 6035 error (1, errno, "read of data failed"); 6036 6037 gcontext = GSS_C_NO_CONTEXT; 6038 tok_in.length = nbytes; 6039 tok_in.value = buf; 6040 6041 if (gss_accept_sec_context (&stat_min, 6042 &gcontext, /* context_handle */ 6043 server_creds, /* verifier_cred_handle */ 6044 &tok_in, /* input_token */ 6045 NULL, /* channel bindings */ 6046 &client_name, /* src_name */ 6047 &mechid, /* mech_type */ 6048 &tok_out, /* output_token */ 6049 &ret, 6050 NULL, /* ignore time_rec */ 6051 NULL) /* ignore del_cred_handle */ 6052 != GSS_S_COMPLETE) 6053 { 6054 error (1, 0, "could not verify credentials"); 6055 } 6056 6057 /* FIXME: Use Kerberos v5 specific code to authenticate to a user. 6058 We could instead use an authentication to access mapping. */ 6059 { 6060 krb5_context kc; 6061 krb5_principal p; 6062 gss_buffer_desc desc; 6063 6064 krb5_init_context (&kc); 6065 if (gss_display_name (&stat_min, client_name, &desc, 6066 &mechid) != GSS_S_COMPLETE 6067 || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0 6068 || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0 6069 || krb5_kuserok (kc, p, buf) != TRUE) 6070 { 6071 error (1, 0, "access denied"); 6072 } 6073 krb5_free_principal (kc, p); 6074 krb5_free_context (kc); 6075 } 6076 6077 if (tok_out.length != 0) 6078 { 6079 char cbuf[2]; 6080 6081 cbuf[0] = (tok_out.length >> 8) & 0xff; 6082 cbuf[1] = tok_out.length & 0xff; 6083 if (fwrite (cbuf, 1, 2, stdout) != 2 6084 || (fwrite (tok_out.value, 1, tok_out.length, stdout) 6085 != tok_out.length)) 6086 error (1, errno, "fwrite failed"); 6087 } 6088 6089 switch_to_user (buf); 6090 6091 printf ("I LOVE YOU\n"); 6092 fflush (stdout); 6093 } 6094 6095 #endif /* HAVE_GSSAPI */ 6096 6097 #endif /* SERVER_SUPPORT */ 6098 6099 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) 6100 6101 /* This global variable is non-zero if the user requests encryption on 6102 the command line. */ 6103 int cvsencrypt; 6104 6105 /* This global variable is non-zero if the users requests stream 6106 authentication on the command line. */ 6107 int cvsauthenticate; 6108 6109 #ifdef HAVE_GSSAPI 6110 6111 /* An buffer interface using GSSAPI. This is built on top of a 6112 packetizing buffer. */ 6113 6114 /* This structure is the closure field of the GSSAPI translation 6115 routines. */ 6116 6117 struct cvs_gssapi_wrap_data 6118 { 6119 /* The GSSAPI context. */ 6120 gss_ctx_id_t gcontext; 6121 }; 6122 6123 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int)); 6124 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int, 6125 int *)); 6126 6127 /* Create a GSSAPI wrapping buffer. We use a packetizing buffer with 6128 GSSAPI wrapping routines. */ 6129 6130 struct buffer * 6131 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory) 6132 struct buffer *buf; 6133 int input; 6134 gss_ctx_id_t gcontext; 6135 void (*memory) PROTO((struct buffer *)); 6136 { 6137 struct cvs_gssapi_wrap_data *gd; 6138 6139 gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd); 6140 gd->gcontext = gcontext; 6141 6142 return (packetizing_buffer_initialize 6143 (buf, 6144 input ? cvs_gssapi_wrap_input : NULL, 6145 input ? NULL : cvs_gssapi_wrap_output, 6146 gd, 6147 memory)); 6148 } 6149 6150 /* Unwrap data using GSSAPI. */ 6151 6152 static int 6153 cvs_gssapi_wrap_input (fnclosure, input, output, size) 6154 void *fnclosure; 6155 const char *input; 6156 char *output; 6157 int size; 6158 { 6159 struct cvs_gssapi_wrap_data *gd = 6160 (struct cvs_gssapi_wrap_data *) fnclosure; 6161 gss_buffer_desc inbuf, outbuf; 6162 OM_uint32 stat_min; 6163 int conf; 6164 6165 inbuf.value = (void *) input; 6166 inbuf.length = size; 6167 6168 if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL) 6169 != GSS_S_COMPLETE) 6170 { 6171 error (1, 0, "gss_unwrap failed"); 6172 } 6173 6174 if (outbuf.length > size) 6175 abort (); 6176 6177 memcpy (output, outbuf.value, outbuf.length); 6178 6179 /* The real packet size is stored in the data, so we don't need to 6180 remember outbuf.length. */ 6181 6182 gss_release_buffer (&stat_min, &outbuf); 6183 6184 return 0; 6185 } 6186 6187 /* Wrap data using GSSAPI. */ 6188 6189 static int 6190 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated) 6191 void *fnclosure; 6192 const char *input; 6193 char *output; 6194 int size; 6195 int *translated; 6196 { 6197 struct cvs_gssapi_wrap_data *gd = 6198 (struct cvs_gssapi_wrap_data *) fnclosure; 6199 gss_buffer_desc inbuf, outbuf; 6200 OM_uint32 stat_min; 6201 int conf_req, conf; 6202 6203 inbuf.value = (void *) input; 6204 inbuf.length = size; 6205 6206 #ifdef ENCRYPTION 6207 conf_req = cvs_gssapi_encrypt; 6208 #else 6209 conf_req = 0; 6210 #endif 6211 6212 if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT, 6213 &inbuf, &conf, &outbuf) != GSS_S_COMPLETE) 6214 error (1, 0, "gss_wrap failed"); 6215 6216 /* The packetizing buffer only permits us to add 100 bytes. 6217 FIXME: I don't know what, if anything, is guaranteed by GSSAPI. 6218 This may need to be increased for a different GSSAPI 6219 implementation, or we may need a different algorithm. */ 6220 if (outbuf.length > size + 100) 6221 abort (); 6222 6223 memcpy (output, outbuf.value, outbuf.length); 6224 6225 *translated = outbuf.length; 6226 6227 gss_release_buffer (&stat_min, &outbuf); 6228 6229 return 0; 6230 } 6231 6232 #endif /* HAVE_GSSAPI */ 6233 6234 #ifdef ENCRYPTION 6235 6236 #ifdef HAVE_KERBEROS 6237 6238 /* An encryption interface using Kerberos. This is built on top of a 6239 packetizing buffer. */ 6240 6241 /* This structure is the closure field of the Kerberos translation 6242 routines. */ 6243 6244 struct krb_encrypt_data 6245 { 6246 /* The Kerberos key schedule. */ 6247 Key_schedule sched; 6248 /* The Kerberos DES block. */ 6249 C_Block block; 6250 }; 6251 6252 static int krb_encrypt_input PROTO((void *, const char *, char *, int)); 6253 static int krb_encrypt_output PROTO((void *, const char *, char *, int, 6254 int *)); 6255 6256 /* Create a Kerberos encryption buffer. We use a packetizing buffer 6257 with Kerberos encryption translation routines. */ 6258 6259 struct buffer * 6260 krb_encrypt_buffer_initialize (buf, input, sched, block, memory) 6261 struct buffer *buf; 6262 int input; 6263 Key_schedule sched; 6264 C_Block block; 6265 void (*memory) PROTO((struct buffer *)); 6266 { 6267 struct krb_encrypt_data *kd; 6268 6269 kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd); 6270 memcpy (kd->sched, sched, sizeof (Key_schedule)); 6271 memcpy (kd->block, block, sizeof (C_Block)); 6272 6273 return packetizing_buffer_initialize (buf, 6274 input ? krb_encrypt_input : NULL, 6275 input ? NULL : krb_encrypt_output, 6276 kd, 6277 memory); 6278 } 6279 6280 /* Decrypt Kerberos data. */ 6281 6282 static int 6283 krb_encrypt_input (fnclosure, input, output, size) 6284 void *fnclosure; 6285 const char *input; 6286 char *output; 6287 int size; 6288 { 6289 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; 6290 int tcount; 6291 6292 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, 6293 size, kd->sched, &kd->block, 0); 6294 6295 /* SIZE is the size of the buffer, which is set by the encryption 6296 routine. The packetizing buffer will arrange for the first two 6297 bytes in the decrypted buffer to be the real (unaligned) 6298 length. As a safety check, make sure that the length in the 6299 buffer corresponds to SIZE. Note that the length in the buffer 6300 is just the length of the data. We must add 2 to account for 6301 the buffer count itself. */ 6302 tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff); 6303 if (((tcount + 2 + 7) & ~7) != size) 6304 error (1, 0, "Decryption failure"); 6305 6306 return 0; 6307 } 6308 6309 /* Encrypt Kerberos data. */ 6310 6311 static int 6312 krb_encrypt_output (fnclosure, input, output, size, translated) 6313 void *fnclosure; 6314 const char *input; 6315 char *output; 6316 int size; 6317 int *translated; 6318 { 6319 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; 6320 int aligned; 6321 6322 /* For security against a known plaintext attack, we should 6323 initialize any padding bytes to random values. Instead, we 6324 just pick up whatever is on the stack, which is at least better 6325 than using zero. */ 6326 6327 /* Align SIZE to an 8 byte boundary. Note that SIZE includes the 6328 two byte buffer count at the start of INPUT which was added by 6329 the packetizing buffer. */ 6330 aligned = (size + 7) & ~7; 6331 6332 /* We use des_cbc_encrypt rather than krb_mk_priv because the 6333 latter sticks a timestamp in the block, and krb_rd_priv expects 6334 that timestamp to be within five minutes of the current time. 6335 Given the way the CVS server buffers up data, that can easily 6336 fail over a long network connection. We trust krb_recvauth to 6337 guard against a replay attack. */ 6338 6339 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned, 6340 kd->sched, &kd->block, 1); 6341 6342 *translated = aligned; 6343 6344 return 0; 6345 } 6346 6347 #endif /* HAVE_KERBEROS */ 6348 #endif /* ENCRYPTION */ 6349 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ 6350 6351 /* Output LEN bytes at STR. If LEN is zero, then output up to (not including) 6352 the first '\0' byte. */ 6353 6354 void 6355 cvs_output (str, len) 6356 const char *str; 6357 size_t len; 6358 { 6359 if (len == 0) 6360 len = strlen (str); 6361 #ifdef SERVER_SUPPORT 6362 if (error_use_protocol) 6363 { 6364 buf_output (saved_output, str, len); 6365 buf_copy_lines (buf_to_net, saved_output, 'M'); 6366 } 6367 else if (server_active) 6368 { 6369 buf_output (saved_output, str, len); 6370 buf_copy_lines (protocol, saved_output, 'M'); 6371 buf_send_counted (protocol); 6372 } 6373 else 6374 #endif 6375 { 6376 size_t written; 6377 size_t to_write = len; 6378 const char *p = str; 6379 6380 /* For symmetry with cvs_outerr we would call fflush (stderr) 6381 here. I guess the assumption is that stderr will be 6382 unbuffered, so we don't need to. That sounds like a sound 6383 assumption from the manpage I looked at, but if there was 6384 something fishy about it, my guess is that calling fflush 6385 would not produce a significant performance problem. */ 6386 6387 while (to_write > 0) 6388 { 6389 written = fwrite (p, 1, to_write, stdout); 6390 if (written == 0) 6391 break; 6392 p += written; 6393 to_write -= written; 6394 } 6395 } 6396 } 6397 6398 /* Output LEN bytes at STR in binary mode. If LEN is zero, then 6399 output zero bytes. */ 6400 6401 void 6402 cvs_output_binary (str, len) 6403 char *str; 6404 size_t len; 6405 { 6406 #ifdef SERVER_SUPPORT 6407 if (error_use_protocol || server_active) 6408 { 6409 struct buffer *buf; 6410 char size_text[40]; 6411 6412 if (error_use_protocol) 6413 buf = buf_to_net; 6414 else 6415 buf = protocol; 6416 6417 if (!supported_response ("Mbinary")) 6418 { 6419 error (0, 0, "\ 6420 this client does not support writing binary files to stdout"); 6421 return; 6422 } 6423 6424 buf_output0 (buf, "Mbinary\012"); 6425 sprintf (size_text, "%lu\012", (unsigned long) len); 6426 buf_output0 (buf, size_text); 6427 6428 /* Not sure what would be involved in using buf_append_data here 6429 without stepping on the toes of our caller (which is responsible 6430 for the memory allocation of STR). */ 6431 buf_output (buf, str, len); 6432 6433 if (!error_use_protocol) 6434 buf_send_counted (protocol); 6435 } 6436 else 6437 #endif 6438 { 6439 size_t written; 6440 size_t to_write = len; 6441 const char *p = str; 6442 6443 /* For symmetry with cvs_outerr we would call fflush (stderr) 6444 here. I guess the assumption is that stderr will be 6445 unbuffered, so we don't need to. That sounds like a sound 6446 assumption from the manpage I looked at, but if there was 6447 something fishy about it, my guess is that calling fflush 6448 would not produce a significant performance problem. */ 6449 #ifdef USE_SETMODE_STDOUT 6450 int oldmode; 6451 6452 /* It is possible that this should be the same ifdef as 6453 USE_SETMODE_BINARY but at least for the moment we keep them 6454 separate. Mostly this is just laziness and/or a question 6455 of what has been tested where. Also there might be an 6456 issue of setmode vs. _setmode. */ 6457 /* The Windows doc says to call setmode only right after startup. 6458 I assume that what they are talking about can also be helped 6459 by flushing the stream before changing the mode. */ 6460 fflush (stdout); 6461 oldmode = _setmode (_fileno (stdout), OPEN_BINARY); 6462 if (oldmode < 0) 6463 error (0, errno, "failed to setmode on stdout"); 6464 #endif 6465 6466 while (to_write > 0) 6467 { 6468 written = fwrite (p, 1, to_write, stdout); 6469 if (written == 0) 6470 break; 6471 p += written; 6472 to_write -= written; 6473 } 6474 #ifdef USE_SETMODE_STDOUT 6475 fflush (stdout); 6476 if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY) 6477 error (0, errno, "failed to setmode on stdout"); 6478 #endif 6479 } 6480 } 6481 6482 /* Like CVS_OUTPUT but output is for stderr not stdout. */ 6483 6484 void 6485 cvs_outerr (str, len) 6486 const char *str; 6487 size_t len; 6488 { 6489 if (len == 0) 6490 len = strlen (str); 6491 #ifdef SERVER_SUPPORT 6492 if (error_use_protocol) 6493 { 6494 buf_output (saved_outerr, str, len); 6495 buf_copy_lines (buf_to_net, saved_outerr, 'E'); 6496 } 6497 else if (server_active) 6498 { 6499 buf_output (saved_outerr, str, len); 6500 buf_copy_lines (protocol, saved_outerr, 'E'); 6501 buf_send_counted (protocol); 6502 } 6503 else 6504 #endif 6505 { 6506 size_t written; 6507 size_t to_write = len; 6508 const char *p = str; 6509 6510 /* Make sure that output appears in order if stdout and stderr 6511 point to the same place. For the server case this is taken 6512 care of by the fact that saved_outerr always holds less 6513 than a line. */ 6514 fflush (stdout); 6515 6516 while (to_write > 0) 6517 { 6518 written = fwrite (p, 1, to_write, stderr); 6519 if (written == 0) 6520 break; 6521 p += written; 6522 to_write -= written; 6523 } 6524 } 6525 } 6526 6527 /* Flush stderr. stderr is normally flushed automatically, of course, 6528 but this function is used to flush information from the server back 6529 to the client. */ 6530 6531 void 6532 cvs_flusherr () 6533 { 6534 #ifdef SERVER_SUPPORT 6535 if (error_use_protocol) 6536 { 6537 /* skip the actual stderr flush in this case since the parent process 6538 * on the server should only be writing to stdout anyhow 6539 */ 6540 /* Flush what we can to the network, but don't block. */ 6541 buf_flush (buf_to_net, 0); 6542 } 6543 else if (server_active) 6544 { 6545 /* make sure stderr is flushed before we send the flush count on the 6546 * protocol pipe 6547 */ 6548 fflush (stderr); 6549 /* Send a special count to tell the parent to flush. */ 6550 buf_send_special_count (protocol, -2); 6551 } 6552 else 6553 #endif 6554 fflush (stderr); 6555 } 6556 6557 /* Make it possible for the user to see what has been written to 6558 stdout (it is up to the implementation to decide exactly how far it 6559 should go to ensure this). */ 6560 6561 void 6562 cvs_flushout () 6563 { 6564 #ifdef SERVER_SUPPORT 6565 if (error_use_protocol) 6566 { 6567 /* Flush what we can to the network, but don't block. */ 6568 buf_flush (buf_to_net, 0); 6569 } 6570 else if (server_active) 6571 { 6572 /* Just do nothing. This is because the code which 6573 cvs_flushout replaces, setting stdout to line buffering in 6574 main.c, didn't get called in the server child process. But 6575 in the future it is quite plausible that we'll want to make 6576 this case work analogously to cvs_flusherr. 6577 6578 FIXME - DRP - I tried to implement this and triggered the following 6579 error: "Protocol error: uncounted data discarded". I don't need 6580 this feature right now, so I'm not going to bother with it yet. 6581 */ 6582 buf_send_special_count (protocol, -1); 6583 } 6584 else 6585 #endif 6586 fflush (stdout); 6587 } 6588 6589 /* Output TEXT, tagging it according to TAG. There are lots more 6590 details about what TAG means in cvsclient.texi but for the simple 6591 case (e.g. non-client/server), TAG is just "newline" to output a 6592 newline (in which case TEXT must be NULL), and any other tag to 6593 output normal text. 6594 6595 Note that there is no way to output either \0 or \n as part of TEXT. */ 6596 6597 void 6598 cvs_output_tagged (tag, text) 6599 char *tag; 6600 char *text; 6601 { 6602 if (text != NULL && strchr (text, '\n') != NULL) 6603 /* Uh oh. The protocol has no way to cope with this. For now 6604 we dump core, although that really isn't such a nice 6605 response given that this probably can be caused by newlines 6606 in filenames and other causes other than bugs in CVS. Note 6607 that we don't want to turn this into "MT newline" because 6608 this case is a newline within a tagged item, not a newline 6609 as extraneous sugar for the user. */ 6610 assert (0); 6611 6612 /* Start and end tags don't take any text, per cvsclient.texi. */ 6613 if (tag[0] == '+' || tag[0] == '-') 6614 assert (text == NULL); 6615 6616 #ifdef SERVER_SUPPORT 6617 if (server_active && supported_response ("MT")) 6618 { 6619 struct buffer *buf; 6620 6621 if (error_use_protocol) 6622 buf = buf_to_net; 6623 else 6624 buf = protocol; 6625 6626 buf_output0 (buf, "MT "); 6627 buf_output0 (buf, tag); 6628 if (text != NULL) 6629 { 6630 buf_output (buf, " ", 1); 6631 buf_output0 (buf, text); 6632 } 6633 buf_output (buf, "\n", 1); 6634 6635 if (!error_use_protocol) 6636 buf_send_counted (protocol); 6637 } 6638 else 6639 #endif 6640 { 6641 if (strcmp (tag, "newline") == 0) 6642 cvs_output ("\n", 1); 6643 else if (text != NULL) 6644 cvs_output (text, 0); 6645 } 6646 } 6647