From 34831612fc1897f9063c81233e1762e3d3683bf7 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Thu, 1 Feb 1996 05:56:27 +0000 Subject: [PATCH] * rcp (client mode) now uses rsh -x but still supports the old encryption in server mode. * krshd will work in encrypting mode even when the port for stderr is null. * rcp will work if stdin isn't not a socket, but is a pipe in remote mode * krshd destroys forwarded credentials properly * For rsh, the secure_message got moved to the client; if you use a new client with an old server, you get secure_message twice, but it should be a useful change long-term. * Fixed typo in rcp man page. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7423 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/bsd/ChangeLog | 35 +++++--- src/appl/bsd/configure.in | 1 + src/appl/bsd/krcp.c | 173 +++++++++----------------------------- src/appl/bsd/krsh.c | 7 ++ src/appl/bsd/krshd.c | 38 +++++---- src/appl/bsd/rcp.M | 2 +- 6 files changed, 92 insertions(+), 164 deletions(-) diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 02696fed1..289ce69ce 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,6 +1,29 @@ +Thu Feb 1 00:09:13 1996 Sam Hartman + + * rcp.M: Fix typo. + + * krcp.c (des_write): If rcp tries to write to stdin, redirect it + to stdout. That way it works with pipes; the right thing is for + rcp to not try and do this, but introducing remread and remwrite + as variables is significantly more work for only slightly better + code. + (main): Use rsh encryption; not user-to-user. Note that we still + support the answer_auth mechanism for incoming connections + so older clients work, but this is depricated. + (send_auth): expunged with pleasure; answer_auth should go in a + a version or two. + Wed Jan 31 16:24:50 1996 Sam Hartman - * krlogind.c (recvauth): Psas ccache to rd_and_store_for_creds + * krsh.c (main): Print SECURE_MESSAGE when appropriate. + + * krshd.c (doit): Fork and handle pipes either if stderr signal + processing is enabled *or* encryption is enabled. Rsh always + enables stderr, but rcp won't. + (SECURE_MESSAGE): Moving to client where it belongs, so the stderr + lchannel doesn't get corrupted for rcp. Besides, the client can determine if it is talking to a tty and only print this message to a tty. + + * krlogind.c (recvauth): Pas ccache to rd_and_store_for_creds * krshd.c (recvauth): Pass address of ccache to rd_and_store_for_creds (ccache): new global variable. @@ -19,16 +42,6 @@ Tue Jan 30 17:56:49 1996 Sam Hartman beset, so our position cannot be fixed. - - - - done - - - - - Auto-saving...Use execle because AIX doesn't use envron for the initial environment. - Sat Jan 27 18:40:31 1996 Sam Hartman * kcmd.c (kcmd): We no longer need F_SETOWN as nothing in appl/bsd diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in index 56df16ac0..de267b7b2 100644 --- a/src/appl/bsd/configure.in +++ b/src/appl/bsd/configure.in @@ -35,6 +35,7 @@ AC_VFORK AC_TYPE_MODE_T AC_FUNC_CHECK(strsave,AC_DEFINE(HAS_STRSAVE)) AC_FUNC_CHECK(utimes,AC_DEFINE(HAS_UTIMES)) +AC_CHECK_FUNCS(isatty) AC_FUNC_CHECK(getutent,AC_DEFINE(HAVE_GETUTENT)) AC_FUNC_CHECK(gettosbyname,AC_DEFINE(HAVE_GETTOSBYNAME)) AC_FUNC_CHECK(killpg,AC_DEFINE(HAVE_KILLPG)) diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c index c97897d58..f46e16352 100644 --- a/src/appl/bsd/krcp.c +++ b/src/appl/bsd/krcp.c @@ -97,7 +97,7 @@ char **save_argv(); char *strsave(); #endif int des_write(), des_read(); -void send_auth(), answer_auth(); +void answer_auth(); int encryptflag = 0; #ifndef UCB_RCP @@ -161,7 +161,7 @@ main(argc, argv) krb5_error_code status; int euid; char **orig_argv = save_argv(argc, argv); - + krb5_init_context(&bsd_context); krb5_init_ets(bsd_context); desinbuf.data = des_inbuf; @@ -243,16 +243,18 @@ main(argc, argv) if (encryptflag) answer_auth(krb_config, krb_cache); #endif /* KERBEROS */ + (void) response(); source(--argc, ++argv); exit(errs); case 't': /* "to" */ iamremote = 1; -#if defined(KERBEROS) +#if defined(KERBEROS) if (encryptflag) answer_auth(krb_config, krb_cache); #endif /* KERBEROS */ + sink(--argc, ++argv); exit(errs); @@ -300,9 +302,10 @@ main(argc, argv) fprintf(stderr, "rcp: Cannot malloc.\n"); exit(1); } - (void) sprintf(cmd, "rcp%s%s%s%s%s%s%s%s%s%s", + (void) sprintf(cmd, "%srcp %s%s%s%s%s%s%s%s%s", + encryptflag ? "-x " : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", - encryptflag ? " -x" : "", targetshouldbedirectory ? " -d" : "", krb_realm != NULL ? " -k " : "", krb_realm != NULL ? krb_realm : "", @@ -399,6 +402,7 @@ main(argc, argv) thost, targ); (void) susystem(buf); } else { /* local to remote */ +krb5_creds *cred; if (rem == -1) { (void) sprintf(buf, "%s -t %s", cmd, targ); @@ -414,7 +418,7 @@ main(argc, argv) 0, "host", krb_realm, - 0, /* No return cred */ + &cred, 0, /* No seq # */ 0, /* No server seq # */ (struct sockaddr_in *) 0, @@ -430,8 +434,15 @@ main(argc, argv) } else { rem = sock; - if (encryptflag) - send_auth(); + session_key = &cred->keyblock; + + krb5_use_enctype(bsd_context, &eblock, session_key->enctype); + if ( status = krb5_process_key(bsd_context, &eblock, + session_key)){ + fprintf(stderr, "rcp: send_auth failed krb5_process_key: %s\n", + error_message(status)); + exit(1); + } } #else rem = rcmd(&host, port, pwd->pw_name, @@ -478,6 +489,7 @@ main(argc, argv) argv[i], argv[argc - 1]); (void) susystem(buf); } else { /* remote to local */ + krb5_creds *cred; *src++ = 0; if (*src == 0) src = "."; @@ -503,7 +515,7 @@ main(argc, argv) 0, "host", krb_realm, - 0, /* No return cred */ + &cred, 0, /* No seq # */ 0, /* No server seq # */ (struct sockaddr_in *) 0, @@ -519,8 +531,16 @@ main(argc, argv) } else { rem = sock; - if (encryptflag) - send_auth(); + session_key = &cred->keyblock; + + krb5_use_enctype(bsd_context, &eblock, session_key->enctype); + if ( status = krb5_process_key(bsd_context, &eblock, + session_key)){ + fprintf(stderr, "rcp: send_auth failed krb5_process_key: %s\n", + error_message(status)); + exit(1); + } + } euid = geteuid(); #ifdef HAVE_SETREUID @@ -1238,132 +1258,8 @@ char **save_argv(argc, argv) #define SIZEOF_INADDR sizeof(struct in_addr) #endif -void send_auth() -{ - int sin_len; - char *princ; /* principal in credentials cache */ - krb5_ccache cc; - krb5_creds in_creds, *out_creds; - krb5_data reply, princ_data; - krb5_error_code status; - krb5_address faddr; - krb5_ticket * ticket = NULL; - krb5_auth_context auth_context = NULL; - - - if (status = krb5_cc_default(bsd_context, &cc)){ - fprintf(stderr,"rcp: send_auth failed krb5_cc_default : %s\n", - error_message(status)); - exit(1); - } - - memset ((char*)&in_creds, 0, sizeof(krb5_creds)); - - if (status = krb5_cc_get_principal(bsd_context, cc, &in_creds.client)){ - fprintf(stderr, - "rcp: send_auth failed krb5_cc_get_principal : %s\n", - error_message(status)); - krb5_cc_close(bsd_context, cc); - exit(1); - } - - if (status = krb5_unparse_name(bsd_context, in_creds.client, &princ)){ - fprintf(stderr,"rcp: send_auth failed krb5_parse_name : %s\n", - error_message(status)); - krb5_cc_close(bsd_context, cc); - exit(1); - } - if (status = krb5_build_principal_ext(bsd_context, &in_creds.server, - krb5_princ_realm(bsd_context,in_creds.client)->length, - krb5_princ_realm(bsd_context,in_creds.client)->data, - 6, "krbtgt", - krb5_princ_realm(bsd_context,in_creds.client)->length, - krb5_princ_realm(bsd_context,in_creds.client)->data, - 0)){ - fprintf(stderr, - "rcp: send_auth failed krb5_build_principal_ext : %s\n", - error_message(status)); - krb5_cc_close(bsd_context, cc); - exit(1); - } - - /* Get TGT from credentials cache */ - if (status = krb5_get_credentials(bsd_context, KRB5_GC_CACHED, cc, - &in_creds, &out_creds)){ - fprintf(stderr, - "rcp: send_auth failed krb5_get_credentials: %s\n", - error_message(status)); - krb5_cc_close(bsd_context, cc); - exit(1); - } - krb5_cc_close(bsd_context, cc); - - princ_data.data = princ; - princ_data.length = strlen(princ_data.data) + 1; /* include null - terminator for - server's convenience */ - status = krb5_write_message(bsd_context, (krb5_pointer) &rem, &princ_data); - if (status){ - fprintf(stderr, - "rcp: send_auth failed krb5_write_message: %s\n", - error_message(status)); - exit(1); - } - krb5_xfree(princ); - status = krb5_write_message(bsd_context, (krb5_pointer)&rem, - &out_creds->ticket); - if (status){ - fprintf(stderr, - "rcp: send_auth failed krb5_write_message: %s\n", - error_message(status)); - exit(1); - } - - if (status = krb5_read_message(bsd_context, (krb5_pointer) &rem, &reply)) { - fprintf(stderr, "rcp: send_auth failed krb5_read_message: %s\n", - error_message(status)); - exit(1); - } - - sin_len = SIZEOF_INADDR; - faddr.addrtype = foreign.sin_family; - faddr.length = SIZEOF_INADDR; - faddr.contents = (krb5_octet *) &foreign.sin_addr; - if (krb5_auth_con_init(bsd_context, &auth_context)) - exit(1); - krb5_auth_con_setaddrs(bsd_context, auth_context, NULL, &faddr); - - if (krb5_auth_con_setuseruserkey(bsd_context, auth_context, - &out_creds->keyblock)) - exit(1); - - /* read the ap_req to get the session key */ - status = krb5_rd_req(bsd_context, &auth_context, &reply, - 0, /* don't know server's name... */ - NULL, /* default keytab */ - NULL, & ticket); - krb5_xfree(reply.data); - if (status) { - fprintf(stderr, "rcp: send_auth failed krb5_rd_req: %s\n", - error_message(status)); - exit(1); - } - - krb5_copy_keyblock(bsd_context, ticket->enc_part2->session, - &session_key); - krb5_free_creds(bsd_context, out_creds); - - krb5_use_enctype(bsd_context, &eblock, session_key->enctype); - if ( status = krb5_process_key(bsd_context, &eblock, - session_key)){ - fprintf(stderr, "rcp: send_auth failed krb5_process_key: %s\n", - error_message(status)); - exit(1); - } - -} void answer_auth(config_file, ccache_file) @@ -1526,7 +1422,14 @@ int des_write(fd, buf, len) int len; { unsigned char len_buf[4]; +/* Note that rcp depends on the same + * file descriptor being both input and output to the remote + * side. This is bogus, especially when rcp + * is being run by a rsh that pipes. Fix it here because + * it would require significantly more work in other places. --hartmans 1/96*/ + if (fd == 0) + fd = 1; if (!encryptflag) return(write(fd, buf, len)); diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c index 8aaa588ca..e9162e8d7 100644 --- a/src/appl/bsd/krsh.c +++ b/src/appl/bsd/krsh.c @@ -70,6 +70,7 @@ char copyright[] = /* * rsh - remote shell */ +#define SECURE_MESSAGE "This rsh session is using DES encryption for all data transmissions.\r\n" int error(); @@ -372,6 +373,12 @@ main(argc, argv0) argv0, error_message(status)); exit(1); } +#ifdef HAVE_ISATTY + if(isatty(2)) { + write(2,SECURE_MESSAGE, strlen(SECURE_MESSAGE)); + } +#endif + #else /* !KERBEROS */ rem = rcmd(&host, debug_port, pwd->pw_name, user ? user : pwd->pw_name, args, &rfd2); diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c index 6e264bdde..98d49744c 100644 --- a/src/appl/bsd/krshd.c +++ b/src/appl/bsd/krshd.c @@ -157,7 +157,6 @@ char copyright[] = #define ARGSTR "rek54cD:S:M:AP:?" -#define SECURE_MESSAGE "This rsh session is using DES encryption for all data transmissions.\r\n" #define RSHD_BUFSIZ 5120 @@ -1091,8 +1090,8 @@ if (require_encrypt&&(!do_encrypt)) { (void) write(2, "", 1); - if (port) { - if (pipe(pv) < 0) { + if (port||do_encrypt) { + if (port&&(pipe(pv) < 0)) { error("Can't make pipe.\n"); goto signout_please; } @@ -1130,22 +1129,23 @@ if (require_encrypt&&(!do_encrypt)) { #endif (void) close(0); (void) close(1); (void) close(2); - (void) close(pv[1]); +if(port) + (void) close(pv[1]); (void) close(pw[1]); (void) close(px[0]); - ioctl(pv[0], FIONBIO, (char *)&one); +if(port) + ioctl(pv[0], FIONBIO, (char *)&one); ioctl(pw[0], FIONBIO, (char *)&one); /* should set s nbio! */ - if (do_encrypt) - if (((*des_write)(s, SECURE_MESSAGE, sizeof(SECURE_MESSAGE))) < 0) - fatal(pw[0], "Cannot encrypt-write network."); FD_ZERO(&readfrom); FD_SET(f, &readfrom); - FD_SET(s, &readfrom); - FD_SET(pv[0], &readfrom); +if(port) + FD_SET(s, &readfrom); +if(port) + FD_SET(pv[0], &readfrom); FD_SET(pw[0], &readfrom); do { @@ -1157,7 +1157,7 @@ if (require_encrypt&&(!do_encrypt)) { else break; } - if (FD_ISSET(s, &ready)) { + if (port&&FD_ISSET(s, &ready)) { if ((*des_read)(s, &sig, 1) <= 0) FD_CLR(s, &readfrom); else { @@ -1180,7 +1180,7 @@ if (require_encrypt&&(!do_encrypt)) { } else (void) write(px[1], buf, cc); } - if (FD_ISSET(pv[0], &ready)) { + if (port&&FD_ISSET(pv[0], &ready)) { errno = 0; cc = read(pv[0], buf, sizeof (buf)); if (cc <= 0) { @@ -1198,9 +1198,9 @@ if (require_encrypt&&(!do_encrypt)) { } else (void) (*des_write)(f, buf, cc); } - } while (FD_ISSET(s, &readfrom) || + } while ((port&&FD_ISSET(s, &readfrom)) || FD_ISSET(f, &readfrom) || - FD_ISSET(pv[0], &readfrom) || + (port&&FD_ISSET(pv[0], &readfrom) )|| FD_ISSET(pw[0], &readfrom)); #ifdef KERBEROS syslog(LOG_INFO , @@ -1222,16 +1222,20 @@ if (ccache) (void) close(s); (void) close(f); (void) close(pw[0]); - (void) close(pv[0]); + if (port) + (void) close(pv[0]); (void) close(px[1]); (void) dup2(px[0], 0); (void) dup2(pw[1], 1); - (void) dup2(pv[1], 2); + if(port) + (void) dup2(pv[1], 2); + else dup2(pw[1], 2); (void) close(px[0]); (void) close(pw[1]); - (void) close(pv[1]); + if(port) + (void) close(pv[1]); } /* We are simply execing a program over rshd : log entry into wtmp, diff --git a/src/appl/bsd/rcp.M b/src/appl/bsd/rcp.M index b8b0a476a..39b13c40e 100644 --- a/src/appl/bsd/rcp.M +++ b/src/appl/bsd/rcp.M @@ -100,7 +100,7 @@ Kerberos principal name of the form .IR principal/instance@realm . If there is a ~/.k5login file, then access is granted to the account if and only if the originater user is authenticated to one of the -princiapls named in the ~/.k5login file. Otherwise, the originating +principals named in the ~/.k5login file. Otherwise, the originating user will be granted access to the account if and only if the authenticated principal name of the user can be mapped to the local account name using the aname -> lname mapping rules (see \fIkrb5_anadd(8)\fP -- 2.26.2