f



OpenSSH, OpenAFS, Heimdal Kerberos and MIT Kerberos

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

0
deengert (574)
1/26/2004 5:57:19 PM
comp.protocols.kerberos 5541 articles. 1 followers. jwinius (31) is leader. Post Follow

3 Replies
1247 Views

Similar Articles

[PageSpeed] 10

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

0
hotz1420 (47)
1/26/2004 10:00:05 PM

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

0
jhutz1 (100)
1/26/2004 10:07:06 PM
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

0
deengert (574)
1/30/2004 6:21:26 PM
Reply: