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