An old new idea, and a Cygwin patch (was Re: Call for testing: openssh-5.2)

Corinna Vinschen vinschen at redhat.com
Thu Mar 5 00:32:35 EST 2009


Ping?

On Feb 25 17:22, Corinna Vinschen wrote:
> On Feb 17 08:11, Damien Miller wrote:
> > On Mon, 16 Feb 2009, Corinna Vinschen wrote:
> > > On Feb 16 15:32, Damien Miller wrote:
> > > > OpenSSH 5.2 is almost ready for release, [...]
> > > 
> > > Builds and runs fine on Cygwin 1.7.  Since I won't support any new
> > > OpenSSH package for Cygwin 1.5, and since Cygwin 1.7 will stop
> > > supporting Windows 9x, I'm wondering if it's ok to strip all Windows 9x
> > > support, as well as the *really* old Cygwin version considerations from
> > > OpenSSH at this point.  It will strip some extra Cygwin-only code from
> > > portable SSH.  Or, maybe we should do that right after the 5.2p1 release?
> > 
> > Yes, we can do this after the release of 5.2p1.
> 
> Below is the patch to remove support for Windows 95/98/Me as well
> as support for very old versions of Cygwin.  Please apply.
> 
> What's still missing in the upstream sources is code which abstracts the
> idea of the root user to the idea of a user with certain privileges.
> Cygwin/Windows is not the only platform which has the capability to give
> finer grained user rights to a user, so that certain types of tasks are
> not necessarily run by the root user.  Given that, the hardcoded checks
> for uid == 0 don't make sense in many environments.  To reiterate an
> idea I'm proposing for quite some time now:
> 
>   Instead of checks as
>   
>     if (getuid() == 0)
>       do_foo_bar ();
>     else
>       EEEEK!
>      
>    openssh should have checks along the lines of
> 
>     if (uid_has_capability (getuid (), CAP_foo_bar))
>       do_foo_bar ();
>     else
>       EEEEK!
> 
> The function uid_has_capability() would be quite simple on systems
> which don't have fine-grained user rights:
> 
>     int
>     uid_has_capability (uid_t uid, int capability)
>     {
>       return uid == 0;
>     }
> 
> but could be much more elaborate on other platforms like Linux, Solaris,
> or Cygwin.  And, again, I'm willing to help with this stuff in terms of
> coding.
> 
> 
> Corinna
> 
> 
> Index: auth-passwd.c
> ===================================================================
> RCS file: /cvs/openssh/auth-passwd.c,v
> retrieving revision 1.89
> diff -u -p -r1.89 auth-passwd.c
> --- auth-passwd.c	26 Oct 2007 04:25:12 -0000	1.89
> +++ auth-passwd.c	25 Feb 2009 16:06:53 -0000
> @@ -102,7 +102,7 @@ auth_password(Authctxt *authctxt, const 
>  	}
>  #endif
>  #ifdef HAVE_CYGWIN
> -	if (is_winnt) {
> +	{
>  		HANDLE hToken = cygwin_logon_user(pw, password);
>  
>  		if (hToken == INVALID_HANDLE_VALUE)
> Index: auth1.c
> ===================================================================
> RCS file: /cvs/openssh/auth1.c,v
> retrieving revision 1.124
> diff -u -p -r1.124 auth1.c
> --- auth1.c	9 Jul 2008 10:54:05 -0000	1.124
> +++ auth1.c	25 Feb 2009 16:06:53 -0000
> @@ -318,15 +318,7 @@ do_authloop(Authctxt *authctxt)
>  		}
>  #endif /* _UNICOS */
>  
> -#ifdef HAVE_CYGWIN
> -		if (authenticated &&
> -		    !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,
> -		    authctxt->pw)) {
> -			packet_disconnect("Authentication rejected for uid %d.",
> -			    authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
> -			authenticated = 0;
> -		}
> -#else
> +#ifndef HAVE_CYGWIN
>  		/* Special handling for root */
>  		if (authenticated && authctxt->pw->pw_uid == 0 &&
>  		    !auth_root_allowed(meth->name)) {
> Index: auth2-kbdint.c
> ===================================================================
> RCS file: /cvs/openssh/auth2-kbdint.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 auth2-kbdint.c
> --- auth2-kbdint.c	1 Sep 2006 05:38:36 -0000	1.7
> +++ auth2-kbdint.c	25 Feb 2009 16:06:53 -0000
> @@ -58,10 +58,6 @@ userauth_kbdint(Authctxt *authctxt)
>  
>  	xfree(devs);
>  	xfree(lang);
> -#ifdef HAVE_CYGWIN
> -	if (check_nt_auth(0, authctxt->pw) == 0)
> -		authenticated = 0;
> -#endif
>  	return authenticated;
>  }
>  
> Index: auth2-none.c
> ===================================================================
> RCS file: /cvs/openssh/auth2-none.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 auth2-none.c
> --- auth2-none.c	2 Jul 2008 12:56:09 -0000	1.19
> +++ auth2-none.c	25 Feb 2009 16:06:53 -0000
> @@ -61,10 +61,6 @@ userauth_none(Authctxt *authctxt)
>  {
>  	none_enabled = 0;
>  	packet_check_eom();
> -#ifdef HAVE_CYGWIN
> -	if (check_nt_auth(1, authctxt->pw) == 0)
> -		return (0);
> -#endif
>  	if (options.password_authentication)
>  		return (PRIVSEP(auth_password(authctxt, "")));
>  	return (0);
> Index: auth2-passwd.c
> ===================================================================
> RCS file: /cvs/openssh/auth2-passwd.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 auth2-passwd.c
> --- auth2-passwd.c	5 Aug 2006 02:39:39 -0000	1.11
> +++ auth2-passwd.c	25 Feb 2009 16:06:53 -0000
> @@ -68,10 +68,6 @@ userauth_passwd(Authctxt *authctxt)
>  		logit("password change not supported");
>  	else if (PRIVSEP(auth_password(authctxt, password)) == 1)
>  		authenticated = 1;
> -#ifdef HAVE_CYGWIN
> -	if (check_nt_auth(1, authctxt->pw) == 0)
> -		authenticated = 0;
> -#endif
>  	memset(password, 0, len);
>  	xfree(password);
>  	return authenticated;
> Index: auth2-pubkey.c
> ===================================================================
> RCS file: /cvs/openssh/auth2-pubkey.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 auth2-pubkey.c
> --- auth2-pubkey.c	4 Jul 2008 02:54:25 -0000	1.20
> +++ auth2-pubkey.c	25 Feb 2009 16:06:53 -0000
> @@ -170,10 +170,6 @@ done:
>  		key_free(key);
>  	xfree(pkalg);
>  	xfree(pkblob);
> -#ifdef HAVE_CYGWIN
> -	if (check_nt_auth(0, authctxt->pw) == 0)
> -		authenticated = 0;
> -#endif
>  	return authenticated;
>  }
>  
> Index: session.c
> ===================================================================
> RCS file: /cvs/openssh/session.c,v
> retrieving revision 1.380
> diff -u -p -r1.380 session.c
> --- session.c	28 Jan 2009 05:29:49 -0000	1.380
> +++ session.c	25 Feb 2009 16:06:54 -0000
> @@ -571,8 +571,7 @@ do_exec_no_pty(Session *s, const char *c
>  	signal(WJSIGNAL, cray_job_termination_handler);
>  #endif /* _UNICOS */
>  #ifdef HAVE_CYGWIN
> -	if (is_winnt)
> -		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
> +	cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
>  #endif
>  
>  	s->pid = pid;
> @@ -726,8 +725,7 @@ do_exec_pty(Session *s, const char *comm
>  	signal(WJSIGNAL, cray_job_termination_handler);
>  #endif /* _UNICOS */
>  #ifdef HAVE_CYGWIN
> -	if (is_winnt)
> -		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
> +	cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
>  #endif
>  
>  	s->pid = pid;
> @@ -1116,7 +1114,7 @@ do_setup_env(Session *s, const char *she
>  	u_int i, envsize;
>  	char **env, *laddr;
>  	struct passwd *pw = s->pw;
> -#ifndef HAVE_LOGIN_CAP
> +#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
>  	char *path = NULL;
>  #endif
>  
> @@ -1551,9 +1549,6 @@ do_setusercontext(struct passwd *pw)
>  #endif
>  	}
>  
> -#ifdef HAVE_CYGWIN
> -	if (is_winnt)
> -#endif
>  	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
>  		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
>  
> Index: openbsd-compat/bsd-cygwin_util.c
> ===================================================================
> RCS file: /cvs/openssh/openbsd-compat/bsd-cygwin_util.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 bsd-cygwin_util.c
> --- openbsd-compat/bsd-cygwin_util.c	17 Jul 2008 09:03:49 -0000	1.20
> +++ openbsd-compat/bsd-cygwin_util.c	25 Feb 2009 16:06:54 -0000
> @@ -39,9 +39,6 @@
>  #endif
>  
>  #include <sys/types.h>
> -#include <sys/stat.h>
> -#include <sys/utsname.h>
> -#include <sys/vfs.h>
>  
>  #include <fcntl.h>
>  #include <stdlib.h>
> @@ -49,11 +46,6 @@
>  #include <windows.h>
>  
>  #include "xmalloc.h"
> -#define is_winnt       (GetVersion() < 0x80000000)
> -
> -#define ntsec_on(c)	((c) && strstr((c),"ntsec") && !strstr((c),"nontsec"))
> -#define ntsec_off(c)	((c) && strstr((c),"nontsec"))
> -#define ntea_on(c)	((c) && strstr((c),"ntea") && !strstr((c),"nontea"))
>  
>  int 
>  binary_open(const char *filename, int flags, ...)
> @@ -79,126 +71,10 @@ binary_pipe(int fd[2])
>  	return (ret);
>  }
>  
> -#define HAS_CREATE_TOKEN 1
> -#define HAS_NTSEC_BY_DEFAULT 2
> -#define HAS_CREATE_TOKEN_WO_NTSEC 3
> -
> -static int 
> -has_capability(int what)
> -{
> -	static int inited;
> -	static int has_create_token;
> -	static int has_ntsec_by_default;
> -	static int has_create_token_wo_ntsec;
> -
> -	/* 
> -	 * has_capability() basically calls uname() and checks if
> -	 * specific capabilities of Cygwin can be evaluated from that.
> -	 * This simplifies the calling functions which only have to ask
> -	 * for a capability using has_capability() instead of having
> -	 * to figure that out by themselves.
> -	 */
> -	if (!inited) {
> -		struct utsname uts;
> -		
> -		if (!uname(&uts)) {
> -			int major_high = 0, major_low = 0, minor = 0;
> -			int api_major_version = 0, api_minor_version = 0;
> -			char *c;
> -
> -			sscanf(uts.release, "%d.%d.%d", &major_high,
> -			    &major_low, &minor);
> -			if ((c = strchr(uts.release, '(')) != NULL) {
> -				sscanf(c + 1, "%d.%d", &api_major_version,
> -				    &api_minor_version);
> -			}
> -			if (major_high > 1 ||
> -			    (major_high == 1 && (major_low > 3 ||
> -			    (major_low == 3 && minor >= 2))))
> -				has_create_token = 1;
> -			if (api_major_version > 0 || api_minor_version >= 56)
> -				has_ntsec_by_default = 1;
> -			if (major_high > 1 ||
> -			    (major_high == 1 && major_low >= 5))
> -				has_create_token_wo_ntsec = 1;
> -			inited = 1;
> -		}
> -	}
> -	switch (what) {
> -	case HAS_CREATE_TOKEN:
> -		return (has_create_token);
> -	case HAS_NTSEC_BY_DEFAULT:
> -		return (has_ntsec_by_default);
> -	case HAS_CREATE_TOKEN_WO_NTSEC:
> -		return (has_create_token_wo_ntsec);
> -	}
> -	return (0);
> -}
> -
> -int
> -check_nt_auth(int pwd_authenticated, struct passwd *pw)
> -{
> -	/*
> -	* The only authentication which is able to change the user
> -	* context on NT systems is the password authentication. So
> -	* we deny all requsts for changing the user context if another
> -	* authentication method is used.
> -	*
> -	* This doesn't apply to Cygwin versions >= 1.3.2 anymore which
> -	* uses the undocumented NtCreateToken() call to create a user
> -	* token if the process has the appropriate privileges and if
> -	* CYGWIN ntsec setting is on.
> -	*/
> -	static int has_create_token = -1;
> -
> -	if (pw == NULL)
> -		return 0;
> -	if (is_winnt) {
> -		if (has_create_token < 0) {
> -			char *cygwin = getenv("CYGWIN");
> -
> -			has_create_token = 0;
> -			if (has_capability(HAS_CREATE_TOKEN) &&
> -			    (ntsec_on(cygwin) ||
> -			    (has_capability(HAS_NTSEC_BY_DEFAULT) &&
> -			     !ntsec_off(cygwin)) ||
> -			     has_capability(HAS_CREATE_TOKEN_WO_NTSEC)))
> -				has_create_token = 1;
> -		}
> -		if (has_create_token < 1 &&
> -		    !pwd_authenticated && geteuid() != pw->pw_uid)
> -			return (0);
> -	}
> -	return (1);
> -}
> -
>  int
>  check_ntsec(const char *filename)
>  {
>  	return (pathconf(filename, _PC_POSIX_PERMISSIONS));
> -}
> -
> -void
> -register_9x_service(void)
> -{
> -        HINSTANCE kerneldll;
> -        DWORD (*RegisterServiceProcess)(DWORD, DWORD);
> -
> -	/* The service register mechanism in 9x/Me is pretty different from
> -	 * NT/2K/XP.  In NT/2K/XP we're using a special service starter
> -	 * application to register and control sshd as service.  This method
> -	 * doesn't play nicely with 9x/Me.  For that reason we register here
> -	 * as service when running under 9x/Me.  This function is only called
> -	 * by the child sshd when it's going to daemonize.
> -	 */
> -	if (is_winnt)
> -		return;
> -	if (!(kerneldll = LoadLibrary("KERNEL32.DLL")))
> -		return;
> -	if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD))
> -		GetProcAddress(kerneldll, "RegisterServiceProcess")))
> -		return;
> -	RegisterServiceProcess(0, 1);
>  }
>  
>  #define NL(x) x, (sizeof (x) - 1)
> Index: openbsd-compat/daemon.c
> ===================================================================
> RCS file: /cvs/openssh/openbsd-compat/daemon.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 daemon.c
> --- openbsd-compat/daemon.c	2 Aug 2006 13:33:55 -0000	1.9
> +++ openbsd-compat/daemon.c	25 Feb 2009 16:06:54 -0000
> @@ -57,18 +57,8 @@ daemon(int nochdir, int noclose)
>  	case -1:
>  		return (-1);
>  	case 0:
> -#ifdef HAVE_CYGWIN
> -		register_9x_service();
> -#endif
>  		break;
>  	default:
> -#ifdef HAVE_CYGWIN
> -		/*
> -		 * This sleep avoids a race condition which kills the
> -		 * child process if parent is started by a NT/W2K service.
> -		 */
> -		sleep(1);
> -#endif
>  		_exit(0);
>  	}
>  
> 
> -- 
> Corinna Vinschen
> Cygwin Project Co-Leader
> Red Hat
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


More information about the openssh-unix-dev mailing list