Rather then implementing kafs in MIT Kerberos, I would like to suggest an alternative which has advantages to all parties. The OpenSSH sshd needs to do two things: (1) sets a PAG in the kernel, (2) obtains an AFS token storing it in the kernel. It can use the Kerberos credentials either obtained via GSSAPI delegation, PAM or other kerberos login code in the sshd. The above two actions can be accomplished by a separate process, which can be forked and execd by the sshd and passed the environment which may have a KREB5CCNAME pointing at the Kerberos ticket cache Other parameters such as the home directory could also be passed. This would then allow simple code in OpenSSH that does not depend on OpenAFS, Hiemdal or MIT code to fork/exec the process that does all the work. This would be called by the process that would eventially become the user's shell process and is run as the user. OpenSSH could be built on systems that may or may not have AFS installed and run on a system with or without AFS. The decision is based on the existence of the executable and any options in sshd_config. In its simplest form, all that is needed is: system("/usr/ssh/libexec/aklog -setpag") This is a little over simplified as there should be a test if the executable exists, processing of some return codes, making sure the environment is set, setting some time limit. etc. But the point is there is no compile dependence on OpenAFS, MIT or Hiemdal by the OpenSSH sshd, and any failure of the process will not effect the sshd. We have been using something like this for years which issues a syscall to set a PAG for the current process, then fork/exec ak5log. Our current mode to OpenSSH in session.c is as simple as: krb5_afs_pag_env(NULL, env); It is currently built with the MIT Kerberos code for historic reasons, but could be seperate as it has no real dependency on the MIT code. I would hope that the members of the OpenSSH community who use OpenAFS, Hiemdal and/or MIT could agree on a simple command line interface that would encourage the builders of OpenSSH to always have this enabled. -- Douglas E. Engert <DEEngert@anl.gov> Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444 ________________________________________________ Kerberos mailing list Kerberos@mit.edu https://mailman.mit.edu/mailman/listinfo/kerberos
I don't disagree with your proposal at all. Sounds good. It should make it easier to fix/change things in the future. But. . . Isn't the reason this keeps coming up that AFS client doesn't (can't?) behave like a normal Kerberos application and just get it's own service ticket when it needs one (based on an existing tgt)? The real reason this doesn't happen is that tickets are stored in a file in /tmp, but it's a different set of file system code inside the kernel that would need to access it to request the service ticket. Can't we figure a way to just make the kernel module get the service ticket (token) automatically, or fail if there is no tgt? That would make the whole problem go away and AFS would no longer need the special attention it does now. I note that on MacOS X tickets are stored in a MACH "security context" which acts a lot like a PAG. Furthermore it's accessible inside the kernel. Doesn't Windows have some similar in-memory storage mechanism? Has anyone thought about how congruent PAGs and terminal sessions are? I think X11 defined the latter, and Kerberos has tried to tie in to them rather than import the PAG concept. At 11:21 AM -0600 1/26/04, Douglas E. Engert wrote: >Rather then implementing kafs in MIT Kerberos, I would like to >suggest an alternative which has advantages to all parties. > >The OpenSSH sshd needs to do two things: > (1) sets a PAG in the kernel, > (2) obtains an AFS token storing it in the kernel. > >It can use the Kerberos credentials either obtained via GSSAPI >delegation, PAM or other kerberos login code in the sshd. > >The above two actions can be accomplished by a separate process, >which can be forked and execd by the sshd and passed the environment >which may have a KREB5CCNAME pointing at the Kerberos ticket cache >Other parameters such as the home directory could also be passed. > > >This would then allow simple code in OpenSSH that does not depend >on OpenAFS, Hiemdal or MIT code to fork/exec the process that does >all the work. This would be called by the process that would >eventially become the user's shell process and is run as the user. > >OpenSSH could be built on systems that may or may not have AFS >installed and run on a system with or without AFS. The decision >is based on the existence of the executable and any options >in sshd_config. > >In its simplest form, all that is needed is: > > system("/usr/ssh/libexec/aklog -setpag") > >This is a little over simplified as there should be a test if the >executable exists, processing of some return codes, making sure the >environment is set, setting some time limit. etc. But the point is >there is no compile dependence on OpenAFS, MIT or Hiemdal by the >OpenSSH sshd, and any failure of the process will not effect the sshd. > > > >We have been using something like this for years which issues a >syscall to set a PAG for the current process, then fork/exec ak5log. >Our current mode to OpenSSH in session.c is as simple as: > > krb5_afs_pag_env(NULL, env); > >It is currently built with the MIT Kerberos code for historic reasons, >but could be seperate as it has no real dependency on the MIT code. > >I would hope that the members of the OpenSSH community who use OpenAFS, >Hiemdal and/or MIT could agree on a simple command line interface that >would encourage the builders of OpenSSH to always have this enabled. > >-- > > Douglas E. Engert <DEEngert@anl.gov> > Argonne National Laboratory > 9700 South Cass Avenue > Argonne, Illinois 60439 > (630) 252-5444 -- The opinions expressed in this message are mine, not those of Caltech, JPL, NASA, or the US Government. Henry.B.Hotz@jpl.nasa.gov, or hbhotz@oxy.edu ________________________________________________ Kerberos mailing list Kerberos@mit.edu https://mailman.mit.edu/mailman/listinfo/kerberos
On Monday, January 26, 2004 11:23:34 -0800 "Henry B. Hotz" <hotz@jpl.nasa.gov> wrote: > Isn't the reason this keeps coming up that AFS client doesn't (can't?) > behave like a normal Kerberos application and just get it's own service > ticket when it needs one (based on an existing tgt)? The real reason > this doesn't happen is that tickets are stored in a file in /tmp, but > it's a different set of file system code inside the kernel that would > need to access it to request the service ticket. No; it's not that simple. Making the cache manager access ticket files would require first gaining a Kerberos dependency that we don't already have, and then importing lots of code into the kernel, much of which depends on network and filesystem interfaces that simply don't exist in kernel mode. Worse, it would not solve the problem. The trouble here is not that AFS tokens are stored in a kernel data structure instead of a file. It's that they are indexed by a value which must be set on login, inherited from each process by its children, and must not be changeable by the user (to prevent token stealing). OpenSSH loses not because you need special code to set tokens, and not even because you need special code to generate a new PAG -- those things can be done by a PAM module. OpenSSH loses because the PAM session module gets called outside the inheritance chain of the user's shell, which means it can't set a PAG or anything else that is inherited across a fork (e.g. groups, environment variables, resource limits, etc etc etc). > I note that on MacOS X tickets are stored in a MACH "security context" > which acts a lot like a PAG. Furthermore it's accessible inside the > kernel. Doesn't Windows have some similar in-memory storage mechanism? Windows' own credentials are managed by a trusted component (the LSA), which keeps a credential cache associated with each login session. This cache is read-only -- you can ask the LSA to obtain new tickets on your behalf, but you can't give it tickets to remember for you, and AFAIK you can't have more than one cache per login session. Both Windows and MacOS X have mechanisms for managing a security context which is inherited between processes, cannot be "stolen", and is independent of the mechanisms used for terminal control and session management. Other UNIX platforms lack such a mechanism; this is the purpose served by the PAG mechanism introduced by AFS. What is key is the existence of such a mechanism, not whether credentials are stored in a file or a kernel data structure or some trusted process. > Has anyone thought about how congruent PAGs and terminal sessions are? They're not. They have similar properties, but they are _not_ congruent. For example, if you run an X11 session with many xterms, each terminal (xterm) is a separate session, but shares the same PAG. You want this, so when you type 'klog' in one window, the resulting tokens are available in all windows. OTOH, if you run an AFS-aware su, the resulting subprocess will have a new PAG (you don't want it to share tokens with other windows), but it must be in the same session, so it will get a SIGHUP if the terminal is closed. One serious mistake is trying to overload the same inherited classification mechanism to perform more than one unrelated purpose. This is why SVR4 separates the concept of "process group" and "session" -- process groups and the concept of the controlling terminal alone were not sufficient for the task. > I > think X11 defined the latter, and Kerberos has tried to tie in to them > rather than import the PAG concept. AFAIK, the process group concept was introduced in BSD UNIX prior to 4.3BSD, and the session concept was introduced in SVR4. Neither was introduced by X11, which has no concept of terminals and thus no need to manage them, or by xterm, which used the existing pseudo-tty mechanism. Kerberos in most cases stores credential caches in files; the location of the ccache file is stored in the environment, which is another set of properties which is inherited between processes (but one which the kernel knows precious little about, and whose contents are completely alterable by the user and thus cannot be trusted). On certain platforms, Kerberos has indeed made use of PAG-like mechanisms provided by the operating system. -- Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu> Sr. Research Systems Programmer School of Computer Science - Research Computing Facility Carnegie Mellon University - Pittsburgh, PA ________________________________________________ Kerberos mailing list Kerberos@mit.edu https://mailman.mit.edu/mailman/listinfo/kerberos
On Monday, I proposed a alternative method of obtaining and AFS PAG and token when used with OpenSSH or any other deamon. I now have a test working using openssh-snap-20040122. This relies on an external program referred to as get-afs-token which accepts at least two parameters: -setpag - Use the AFS Kernel mods to set the AFS PAG of the parent process. -path <directory> - Get a AFS token for the cell containing this directory. The get-afs-token program would be provided by the OpenAFS or Kerberos communities, and could be a link to aklog, afslog or gssklog. I have tried this with my version of aklog, called ak5log, and with gssklog. The aklog already accepted these parameters and afslog only need a minor addition as did the gssklog. Here is the sample code used with OpenSSH. Note that the get_afs_token routine does not require any AFS or Kerberos header files. --- ./,session.c Tue Jan 20 18:00:46 2004 +++ ./session.c Fri Jan 30 11:38:02 2004 @@ -66,6 +66,10 @@ #include "ssh-gss.h" #endif +#ifdef ANL_AFS_PAG +int get_afs_token(char * pgm, char ** env, char *homedir, int setpag); +#endif + /* func */ Session *session_new(void); @@ -1419,6 +1423,14 @@ */ environ = env; +#ifdef ANL_AFS_PAG + /* Get PAG and AFS token using external program and KRB5CCNAME */ + if (options.kerberos_get_afs_token) { + debug("Getting AFS token"); + get_afs_token(NULL, env, pw->pw_dir, 1); + } +#endif + #if defined(HEIMDAL) && defined(AFS) /* * At this point, we check to see if AFS is active and if we have @@ -2216,3 +2228,119 @@ if (!use_privsep || mm_is_monitor()) session_destroy_all(session_pty_cleanup2); } + +#ifdef ANL_AFS_PAG +/* gafstoken.c + + A generic routine to get an AFS token by calling + an external program. + + This routine is generic in that it does not depend on + any specific implementation of AFS, or Kerberos. + This will allow a deamon to be configured, compiled + and linked without any AFS or Kerberos dependencies + and can thus avoid conflicts between these packages. + The resulting deamon executable can be run on a system with + or without AFS. + + Examples of external programs that could be called + are aklog, afslog, gssklog, klog, ak5log or even a script + to call one of these. + + The external program is expected to support + (or ignore) the -setpag and -path <homedir> + + Parameters to gafstoken: + + char * external_program - path to the executable + this would be set by configure, or defaulted + in some way. If NULL a built in location is used. + + char **env - Environment to run under. This + should include any environment variables needed + by the external program such as KRB5CCNAME + or X509_USER_PROXY These would have been set + by GSSAPI or PAM. If NULL, the current environment + is used. + + char * homedir - A file location, if in AFS the + external program will attempt to get a token + for the cell containing it. If NULL attempt + to get a token for the default cell of the client. + + int setpag - Used to tell external program to get + an AFS PAG. The caller's process must be a process + that will be an ancestor of the user's process. + + Returns: + -1 - some system error, see errno; + 0 - the external program if present was called and + MAY have worked. + + The caller should not need to test the return code, and should + continue with or without the AFS token or PAG. + + */ + +#ifndef _PATH_AFS_EXTERNAL_PROGRAM +#define _PATH_AFS_EXTERNAL_PROGRAM "/usr/libexec/get-afs-token" +#endif + +int +get_afs_token(char * external_program, + char ** env, + char * homedir, + int setpag) +{ + pid_t pid; + int status; + struct stat stx; + char * ppath = _PATH_AFS_EXTERNAL_PROGRAM; + char * args[5]; /* arg0, -setpag, -path, homedir, NULL */ + int argi = 0; + + if (external_program) + ppath = external_program; + + /* test if external program exists */ + if (stat(ppath, &stx)) + return 0; /* does not exist, skip getting PAG and token */ + + args[argi++] = "getafstoken"; + if (setpag) + args[argi++] = "-setpag"; + if (homedir) { + args[argi++] = "-path"; + args[argi++] = homedir; + } + args[argi] = NULL; + + if ((pid = fork()) < 0) { + return -1; /* see errno */ + } + + if (pid == 0) { + /* Don't want any output confusing the deamon */ + close(1); + open("/dev/null",O_WRONLY); + close(2); + open("/dev/null",O_WRONLY); + + if (env) + execve(ppath, args, env); + else + execv(ppath, args); + exit(127); /* exec failed! Should never get here */ + } + + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) + break; + } + + /* we could set a return code based on status, + * be we want to go on with or without a token */ + + return 0; +} +#endif --- ./,Makefile.in Fri Nov 21 06:48:55 2003 +++ ./Makefile.in Thu Jan 29 11:22:40 2004 @@ -22,6 +22,7 @@ VPATH=@srcdir@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass +AFS_EXTERNAL_PROGRAM=$(libexecdir)/get-afs-token SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign RAND_HELPER=$(libexecdir)/ssh-rand-helper @@ -32,6 +33,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ + -D_PATH_AFS_EXTERNAL_PROGRAM=\"$(AFS_EXTERNAL_PROGRAM)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ "Douglas E. Engert" wrote: > > Rather then implementing kafs in MIT Kerberos, I would like to > suggest an alternative which has advantages to all parties. > > The OpenSSH sshd needs to do two things: > (1) sets a PAG in the kernel, > (2) obtains an AFS token storing it in the kernel. > > It can use the Kerberos credentials either obtained via GSSAPI > delegation, PAM or other kerberos login code in the sshd. > > The above two actions can be accomplished by a separate process, > which can be forked and execd by the sshd and passed the environment > which may have a KREB5CCNAME pointing at the Kerberos ticket cache > Other parameters such as the home directory could also be passed. > > This would then allow simple code in OpenSSH that does not depend > on OpenAFS, Hiemdal or MIT code to fork/exec the process that does > all the work. This would be called by the process that would > eventially become the user's shell process and is run as the user. > > OpenSSH could be built on systems that may or may not have AFS > installed and run on a system with or without AFS. The decision > is based on the existence of the executable and any options > in sshd_config. > > In its simplest form, all that is needed is: > > system("/usr/ssh/libexec/aklog -setpag") > > This is a little over simplified as there should be a test if the > executable exists, processing of some return codes, making sure the > environment is set, setting some time limit. etc. But the point is > there is no compile dependence on OpenAFS, MIT or Hiemdal by the > OpenSSH sshd, and any failure of the process will not effect the sshd. > > We have been using something like this for years which issues a > syscall to set a PAG for the current process, then fork/exec ak5log. > Our current mode to OpenSSH in session.c is as simple as: > > krb5_afs_pag_env(NULL, env); > > It is currently built with the MIT Kerberos code for historic reasons, > but could be seperate as it has no real dependency on the MIT code. > > I would hope that the members of the OpenSSH community who use OpenAFS, > Hiemdal and/or MIT could agree on a simple command line interface that > would encourage the builders of OpenSSH to always have this enabled. > > -- > > Douglas E. Engert <DEEngert@anl.gov> > Argonne National Laboratory > 9700 South Cass Avenue > Argonne, Illinois 60439 > (630) 252-5444 -- Douglas E. Engert <DEEngert@anl.gov> Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444 ________________________________________________ Kerberos mailing list Kerberos@mit.edu https://mailman.mit.edu/mailman/listinfo/kerberos