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