Deleted Added
full compact
login.c (107487) login.c (128269)
1/*
2 * Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
3 *
4 * You may distribute under the terms of the GNU General Public License as
5 * specified in the README file that comes with CVS.
6 *
7 * Allow user to log in for an authenticating server.
8 *
1/*
2 * Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
3 *
4 * You may distribute under the terms of the GNU General Public License as
5 * specified in the README file that comes with CVS.
6 *
7 * Allow user to log in for an authenticating server.
8 *
9 * $FreeBSD: head/contrib/cvs/src/login.c 107487 2002-12-02 03:17:49Z peter $
9 * $FreeBSD: head/contrib/cvs/src/login.c 128269 2004-04-15 01:17:28Z peter $
10 */
11
12#include "cvs.h"
13#include "getline.h"
14
15#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
16
10 */
11
12#include "cvs.h"
13#include "getline.h"
14
15#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
16
17#ifdef HAVE_GETPASSPHRASE
18#define GETPASS getpassphrase
19#else
20#define GETPASS getpass
21#endif
22
23/* There seems to be very little agreement on which system header
24 getpass is declared in. With a lot of fancy autoconfiscation,
25 we could perhaps detect this, but for now we'll just rely on
26 _CRAY, since Cray is perhaps the only system on which our own
27 declaration won't work (some Crays declare the 2#$@% thing as
28 varadic, believe it or not). On Cray, getpass will be declared
29 in either stdlib.h or unistd.h. */
17/* There seems to be very little agreement on which system header
18 getpass is declared in. With a lot of fancy autoconfiscation,
19 we could perhaps detect this, but for now we'll just rely on
20 _CRAY, since Cray is perhaps the only system on which our own
21 declaration won't work (some Crays declare the 2#$@% thing as
22 varadic, believe it or not). On Cray, getpass will be declared
23 in either stdlib.h or unistd.h. */
30#ifndef _CRAY
31extern char *GETPASS ();
32#endif
33
34#ifndef CVS_PASSWORD_FILE
35#define CVS_PASSWORD_FILE ".cvspass"
36#endif
37
38/* If non-NULL, get_cvs_password() will just return this. */
39static char *cvs_password = NULL;
40

--- 185 unchanged lines hidden (view full) ---

226 * cvsroot_t *root,
227 * char *newpassword
228 * );
229 *
230 * Search the password file and depending on the value of operation:
231 *
232 * Mode Action
233 * password_entry_lookup Return the password
24
25#ifndef CVS_PASSWORD_FILE
26#define CVS_PASSWORD_FILE ".cvspass"
27#endif
28
29/* If non-NULL, get_cvs_password() will just return this. */
30static char *cvs_password = NULL;
31

--- 185 unchanged lines hidden (view full) ---

217 * cvsroot_t *root,
218 * char *newpassword
219 * );
220 *
221 * Search the password file and depending on the value of operation:
222 *
223 * Mode Action
224 * password_entry_lookup Return the password
234 * password_entry_delete Delete the entry from the file, if it exists
235 * password_entry_add Replace the line with the new one, else append it
225 * password_entry_delete Delete the entry from the file, if it
226 * exists.
227 * password_entry_add Replace the line with the new one, else
228 * append it.
236 *
237 * Because the user might be accessing multiple repositories, with
238 * different passwords for each one, the format of ~/.cvspass is:
239 *
240 * [user@]host:[port]/path Aencoded_password
241 * [user@]host:[port]/path Aencoded_password
242 * ...
243 *

--- 44 unchanged lines hidden (view full) ---

288 cvsroot_t *root;
289 char *newpassword;
290{
291 char *passfile;
292 FILE *fp;
293 char *cvsroot_canonical = NULL;
294 char *password = NULL;
295 int line_length;
229 *
230 * Because the user might be accessing multiple repositories, with
231 * different passwords for each one, the format of ~/.cvspass is:
232 *
233 * [user@]host:[port]/path Aencoded_password
234 * [user@]host:[port]/path Aencoded_password
235 * ...
236 *

--- 44 unchanged lines hidden (view full) ---

281 cvsroot_t *root;
282 char *newpassword;
283{
284 char *passfile;
285 FILE *fp;
286 char *cvsroot_canonical = NULL;
287 char *password = NULL;
288 int line_length;
296 long line;
289 long line = -1;
297 char *linebuf = NULL;
298 size_t linebuf_len;
299 char *p;
300 int save_errno = 0;
301
302 if (root->method != pserver_method)
303 {
290 char *linebuf = NULL;
291 size_t linebuf_len;
292 char *p;
293 int save_errno = 0;
294
295 if (root->method != pserver_method)
296 {
304 error (0, 0, "internal error: can only call password_entry_operation with pserver method");
297 error (0, 0, "\
298internal error: can only call password_entry_operation with pserver method");
305 error (1, 0, "CVSROOT: %s", root->original);
306 }
307
308 cvsroot_canonical = normalize_cvsroot (root);
309
310 /* Yes, the method below reads the user's password file twice when we have
311 * to delete an entry. It's inefficient, but we're not talking about a gig of
312 * data here.

--- 7 unchanged lines hidden (view full) ---

320 goto process;
321 }
322
323 /* Check each line to see if we have this entry already. */
324 line = 0;
325 while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
326 {
327 line++;
299 error (1, 0, "CVSROOT: %s", root->original);
300 }
301
302 cvsroot_canonical = normalize_cvsroot (root);
303
304 /* Yes, the method below reads the user's password file twice when we have
305 * to delete an entry. It's inefficient, but we're not talking about a gig of
306 * data here.

--- 7 unchanged lines hidden (view full) ---

314 goto process;
315 }
316
317 /* Check each line to see if we have this entry already. */
318 line = 0;
319 while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
320 {
321 line++;
328 password = password_entry_parseline(cvsroot_canonical, 1, line, linebuf);
322 password = password_entry_parseline (cvsroot_canonical, 1, line,
323 linebuf);
329 if (password != NULL)
330 /* this is it! break out and deal with linebuf */
331 break;
332 }
333 if (line_length < 0 && !feof (fp))
334 {
335 error (0, errno, "cannot read %s", passfile);
336 goto error_exit;

--- 33 unchanged lines hidden (view full) ---

370 * anything else if we're in lookup mode
371 */
372
373 /* copy the file with the entry deleted unless we're in add
374 * mode and the line we found contains the same password we're supposed to
375 * add
376 */
377 if (!noexec && password != NULL && (operation == password_entry_delete
324 if (password != NULL)
325 /* this is it! break out and deal with linebuf */
326 break;
327 }
328 if (line_length < 0 && !feof (fp))
329 {
330 error (0, errno, "cannot read %s", passfile);
331 goto error_exit;

--- 33 unchanged lines hidden (view full) ---

365 * anything else if we're in lookup mode
366 */
367
368 /* copy the file with the entry deleted unless we're in add
369 * mode and the line we found contains the same password we're supposed to
370 * add
371 */
372 if (!noexec && password != NULL && (operation == password_entry_delete
378 || (operation == password_entry_add && strcmp (password, newpassword))))
373 || (operation == password_entry_add
374 && strcmp (password, newpassword))))
379 {
380 long found_at = line;
381 char *tmp_name;
382 FILE *tmp_fp;
383
384 /* open the original file again */
385 fp = CVS_FOPEN (passfile, "r");
386 if (fp == NULL)

--- 4 unchanged lines hidden (view full) ---

391 error (1, errno, "unable to open temp file %s", tmp_name);
392
393 line = 0;
394 while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
395 {
396 line++;
397 if (line < found_at
398 || (line != found_at
375 {
376 long found_at = line;
377 char *tmp_name;
378 FILE *tmp_fp;
379
380 /* open the original file again */
381 fp = CVS_FOPEN (passfile, "r");
382 if (fp == NULL)

--- 4 unchanged lines hidden (view full) ---

387 error (1, errno, "unable to open temp file %s", tmp_name);
388
389 line = 0;
390 while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
391 {
392 line++;
393 if (line < found_at
394 || (line != found_at
399 && !password_entry_parseline(cvsroot_canonical, 0, line, linebuf)))
395 && !password_entry_parseline (cvsroot_canonical, 0, line,
396 linebuf)))
400 {
401 if (fprintf (tmp_fp, "%s", linebuf) == EOF)
402 {
403 /* try and clean up anyhow */
404 error (0, errno, "fatal error: cannot write %s", tmp_name);
405 if (fclose (tmp_fp) == EOF)
406 error (0, errno, "cannot close %s", tmp_name);
407 /* call CVS_UNLINK instead of unlink_file since the file

--- 130 unchanged lines hidden (view full) ---

538
539 if (current_parsed_root->password)
540 {
541 typed_password = scramble (current_parsed_root->password);
542 }
543 else
544 {
545 char *tmp;
397 {
398 if (fprintf (tmp_fp, "%s", linebuf) == EOF)
399 {
400 /* try and clean up anyhow */
401 error (0, errno, "fatal error: cannot write %s", tmp_name);
402 if (fclose (tmp_fp) == EOF)
403 error (0, errno, "cannot close %s", tmp_name);
404 /* call CVS_UNLINK instead of unlink_file since the file

--- 130 unchanged lines hidden (view full) ---

535
536 if (current_parsed_root->password)
537 {
538 typed_password = scramble (current_parsed_root->password);
539 }
540 else
541 {
542 char *tmp;
546 tmp = GETPASS ("CVS password: ");
543 tmp = getpass ("CVS password: ");
547 /* Must deal with a NULL return value here. I haven't managed to
548 * disconnect the CVS process from the tty and force a NULL return
549 * in sanity.sh, but the Linux version of getpass is documented
550 * to return NULL when it can't open /dev/tty...
551 */
552 if (!tmp) error (1, errno, "login: Failed to read password.");
553 typed_password = scramble (tmp);
554 memset (tmp, 0, strlen (tmp));
555 }
556
557 /* Force get_cvs_password() to use this one (when the client
558 * confirms the new password with the server), instead of
559 * consulting the file. We make a new copy because cvs_password
560 * will get zeroed by connect_to_server(). */
561 cvs_password = xstrdup (typed_password);
562
563 connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0);
564
544 /* Must deal with a NULL return value here. I haven't managed to
545 * disconnect the CVS process from the tty and force a NULL return
546 * in sanity.sh, but the Linux version of getpass is documented
547 * to return NULL when it can't open /dev/tty...
548 */
549 if (!tmp) error (1, errno, "login: Failed to read password.");
550 typed_password = scramble (tmp);
551 memset (tmp, 0, strlen (tmp));
552 }
553
554 /* Force get_cvs_password() to use this one (when the client
555 * confirms the new password with the server), instead of
556 * consulting the file. We make a new copy because cvs_password
557 * will get zeroed by connect_to_server(). */
558 cvs_password = xstrdup (typed_password);
559
560 connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0);
561
565 password_entry_operation (password_entry_add, current_parsed_root, typed_password);
562 password_entry_operation (password_entry_add, current_parsed_root,
563 typed_password);
566
567 memset (typed_password, 0, strlen (typed_password));
568 free (typed_password);
569
570 free (cvs_password);
571 free (cvsroot_canonical);
572 cvs_password = NULL;
573
574 return 0;
575}
576
564
565 memset (typed_password, 0, strlen (typed_password));
566 free (typed_password);
567
568 free (cvs_password);
569 free (cvsroot_canonical);
570 cvs_password = NULL;
571
572 return 0;
573}
574
575
576
577/* Returns the _scrambled_ password. The server must descramble
578 before hashing and comparing. If password file not found, or
579 password not found in the file, just return NULL. */
580char *
581get_cvs_password ()
582{
583 if (current_parsed_root->password)
577/* Returns the _scrambled_ password. The server must descramble
578 before hashing and comparing. If password file not found, or
579 password not found in the file, just return NULL. */
580char *
581get_cvs_password ()
582{
583 if (current_parsed_root->password)
584 return (scramble(current_parsed_root->password));
584 return scramble (current_parsed_root->password);
585
586 /* If someone (i.e., login()) is calling connect_to_pserver() out of
587 context, then assume they have supplied the correct, scrambled
588 password. */
589 if (cvs_password)
590 return cvs_password;
591
592 if (getenv ("CVS_PASSWORD") != NULL)

--- 11 unchanged lines hidden (view full) ---

604 }
605
606 if (current_parsed_root->method != pserver_method)
607 {
608 error (0, 0, "can only call get_cvs_password with pserver method");
609 error (1, 0, "CVSROOT: %s", current_parsed_root->original);
610 }
611
585
586 /* If someone (i.e., login()) is calling connect_to_pserver() out of
587 context, then assume they have supplied the correct, scrambled
588 password. */
589 if (cvs_password)
590 return cvs_password;
591
592 if (getenv ("CVS_PASSWORD") != NULL)

--- 11 unchanged lines hidden (view full) ---

604 }
605
606 if (current_parsed_root->method != pserver_method)
607 {
608 error (0, 0, "can only call get_cvs_password with pserver method");
609 error (1, 0, "CVSROOT: %s", current_parsed_root->original);
610 }
611
612 return password_entry_operation (password_entry_lookup, current_parsed_root, NULL);
612 return password_entry_operation (password_entry_lookup,
613 current_parsed_root, NULL);
613}
614
614}
615
616
617
615static const char *const logout_usage[] =
616{
617 "Usage: %s %s\n",
618 "(Specify the --help global option for a list of other help options)\n",
619 NULL
620};
621
622/* Remove any entry for the CVSRoot repository found in .cvspass. */

--- 38 unchanged lines hidden ---
618static const char *const logout_usage[] =
619{
620 "Usage: %s %s\n",
621 "(Specify the --help global option for a list of other help options)\n",
622 NULL
623};
624
625/* Remove any entry for the CVSRoot repository found in .cvspass. */

--- 38 unchanged lines hidden ---