[PATCH]: Cygwin port of 2.2.0p1
Corinna Vinschen
vinschen at cygnus.com
Wed Sep 6 03:35:19 EST 2000
Damien Miller wrote:
> --- There are lots of cases where uid/euid == 0 checks are disabled.
> I assume because Win does not share Unix's root metaphor. Is this
> correct?
This is correct. NT/W2K has lots of special "user rights". Those
user rights can be given to any single user or group of users
explicitely. So, to be a member of the special group "administrators"
does only have a meaning after installation.
> If so, there should be some replacement check to prevent non admin users
> from doing things like setting up port forwards for ports < 1024, etc.
That's impossible. Windows doesn't check that you are some sort
of special user which has the right to use ports < 1024. Everyone
may use that ports. As mentioned above the membership in a user
group doesn't mean much. To get things worse, think of W95/W98
which doesn't know of the concept of different users either.
> --- In auth1.c you have:
>
> /*
> * 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 may change in future when a special openssh
> * subauthentication package is available.
> */
>
> Does this mean the only way to change Window's equivalent of uid is with
> a valid password?
Yes. Without special authentication packages you have no chance
to change the user context without knowing the NT password of that
user.
> The code adjacent to the above comment looks like it will disable
> authentication modes other than password, correct?
No. It doesn't disable other authentications at all. It only disables
non-password authentication _if_ ssh is running in NT/W2K (not 9X/ME)
and _if_ the user running the process is different from the user
trying to login. So you can run sshd under your own account to
login with non-password authentication, nevertheless. But _if_ you
want to change user context (your uid != sshd uid) you are only
able to do that with password auth in NT/W2K. That's the check for.
As I mentioned this may change in future. It's not easy to write
authentication packages for NT/W2K since the documentation is,
uhm, more or less nonexistant and you need special header files
which aren't part of the standard MS development environment.
However, I'm investigating.
> I can't see anything similar done for protocol v2 though.
You doesn't see that for v2? Wait, just looking through the code...
[time passes]
You're right. Patch related to openssh-SNAP-20000905 attached.
> ---- Also in auth1.c:
>
> /*
> * check owner and modes.
> * This won't work on Windows under all circumstances so we drop
> * that check for now.
> */
>
> How does it fail? I don't want to _remove_ security checks.
FAT filesystems doesn't support that modes.
NTFS does support that modes but NTFS is very complex in that it
doesn't support UNIX modes but access control lists. I have written
a security module for Cygwin called "ntsec" which allows a mapping
between POSIX and NTFS permissions but it's users choice to use
it and it's inside of the Cygwin subsystem so I can't rely on that
nor can I change the setting from inside a running application.
I didn't want to flood the OpenSSH code with special Win32 code for
checking file systems and getting/setting access control lists.
Hmmm, I _could_ check for the setting of "ntsec" and, if it's set,
remain the aforementioned security check active....
[more time passes]
Ok. It's also in the attached patch. A bit more than I thought
but it's well commented (cygwin_util.c function `check_ntsec').
> --- In session.c you copy the parent's whole environment to the child.
> Is there any way to limit this to specific variables, or (better still)
> initialise them from scratch?
Hmmmm. Windows uses dozens of special env vars. I _could_ figure
out which one to use and which one to drop but it wouldn't make
the code really nicer...
However, I will note that for a later patch.
> I have made a snapshot with your changes merged + a couple of others
> picked up over the last few days.
>
> http://www.mindrot.org/misc/openssh/openssh-SNAP-20000905.tar.gz
>
> -d
Thanks :)
Now to the attached patch. I have created a new function `check_nt_auth'
in cygwin_util.c which is called from auth1.c and auth2.c. I would like
to put the `packet_disconnect' call into cygwin_util.c as well but
unfortunately this requires changing ssh-add.c so that `int IPv4orv6'
is defined :-(
The new function `check_ntsec' checks if a later file security check
makes sense.
In `binary_pipe' I forgot a `return' statement.
ChangeLog:
==========
- auth1.c: Change check for password authentication under Windows
NT/W2K. Call `check_nt_auth' now.
- auth2.c: Add check for password authentication under Windows NT/W2K
by calling `check_nt_auth'.
- authfile.c: Change checking file permissions for Cygwin by calling
`check_ntsec' now.
- cygwin_util.c: New function check_nt_auth().
New function check_ntsec().
Add missing return statement in binary_pipe().
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Developer mailto:cygwin at sources.redhat.com
Red Hat, Inc.
mailto:vinschen at cygnus.com
-------------- next part --------------
Index: auth1.c
===================================================================
RCS file: /src/cvsroot//openssh-20000905/auth1.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 auth1.c
--- auth1.c 2000/09/05 11:23:12 1.1.1.1
+++ auth1.c 2000/09/05 12:45:59
@@ -23,11 +23,6 @@ RCSID("$OpenBSD: auth1.c,v 1.3 2000/08/2
# include <siad.h>
#endif
-#ifdef HAVE_CYGWIN
-#include <windows.h>
-#define is_winnt (GetVersion() < 0x80000000)
-#endif
-
/* import */
extern ServerOptions options;
extern char *forced_command;
@@ -377,16 +372,8 @@ do_authloop(struct passwd * pw)
}
#ifdef HAVE_CYGWIN
- /*
- * 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 may change in future when a special openssh
- * subauthentication package is available.
- */
- if (is_winnt && type != SSH_CMSG_AUTH_PASSWORD &&
- authenticated && geteuid() != pw->pw_uid) {
+ if (authenticated &&
+ !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
packet_disconnect("Authentication rejected for uid %d.",
(int) pw->pw_uid);
authenticated = 0;
Index: auth2.c
===================================================================
RCS file: /src/cvsroot//openssh-20000905/auth2.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 auth2.c
--- auth2.c 2000/09/05 11:23:12 1.1.1.1
+++ auth2.c 2000/09/05 12:45:29
@@ -186,6 +186,15 @@ input_userauth_request(int type, int ple
authenticated = ssh2_auth_pubkey(pw, service);
}
}
+
+#ifdef HAVE_CYGWIN
+ if (authenticated && !check_nt_auth(strcmp(method, "password") == 0, pw->pw_uid)) {
+ packet_disconnect("Authentication rejected for uid %d.",
+ (int) pw->pw_uid);
+ authenticated = 0;
+ }
+#endif
+
if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
authenticated = 0;
log("ROOT LOGIN REFUSED FROM %.200s",
@@ -193,8 +202,8 @@ input_userauth_request(int type, int ple
}
#ifdef USE_PAM
- if (authenticated && !do_pam_account(pw->pw_name, NULL))
- authenticated = 0;
+ if (authenticated && !do_pam_account(pw->pw_name, NULL))
+ authenticated = 0;
#endif /* USE_PAM */
/* Raise logging level */
Index: authfile.c
===================================================================
RCS file: /src/cvsroot//openssh-20000905/authfile.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 authfile.c
--- authfile.c 2000/09/05 11:23:12 1.1.1.1
+++ authfile.c 2000/09/05 15:22:08
@@ -457,12 +457,10 @@ load_private_key(const char *filename, c
if (fd < 0)
return 0;
-#ifndef HAVE_CYGWIN
- /*
- * check owner and modes.
- * This won't work on Windows under all circumstances so we drop
- * that check for now.
- */
+ /* check owner and modes. */
+#ifdef HAVE_CYGWIN
+ if (check_ntsec(filename))
+#endif
if (fstat(fd, &st) < 0 ||
(st.st_uid != 0 && st.st_uid != getuid()) ||
(st.st_mode & 077) != 0) {
@@ -475,7 +473,6 @@ load_private_key(const char *filename, c
error("It is recommended that your private key files are NOT accessible by others.");
return 0;
}
-#endif
switch (key->type) {
case KEY_RSA:
if (key->rsa->e != NULL) {
Index: cygwin_util.c
===================================================================
RCS file: /src/cvsroot//openssh-20000905/cygwin_util.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 cygwin_util.c
--- cygwin_util.c 2000/09/05 11:23:14 1.1.1.1
+++ cygwin_util.c 2000/09/05 16:20:09
@@ -18,6 +18,10 @@
#ifdef HAVE_CYGWIN
#include <fcntl.h>
#include <io.h>
+#include <stdlib.h>
+#include <sys/vfs.h>
+#include <windows.h>
+#define is_winnt (GetVersion() < 0x80000000)
int binary_open(const char *filename, int flags, mode_t mode)
{
@@ -31,5 +35,67 @@ int binary_pipe(int fd[2])
setmode (fd[0], O_BINARY);
setmode (fd[1], O_BINARY);
}
+ return ret;
+}
+
+int check_nt_auth (int pwd_authenticated, uid_t uid)
+{
+ /*
+ * 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 may change in future when a special openssh
+ * subauthentication package is available.
+ */
+ if (is_winnt && !pwd_authenticated && geteuid() != uid)
+ return 0;
+ return 1;
+}
+
+int check_ntsec (const char *filename)
+{
+ char *cygwin;
+ int allow_ntea = 0;
+ int allow_ntsec = 0;
+ struct statfs fsstat;
+
+ /* Windows 95/98/ME don't support file system security at all. */
+ if (!is_winnt)
+ return 0;
+
+ /* Evaluate current CYGWIN settings. */
+ if ((cygwin = getenv("CYGWIN")) != NULL) {
+ if (strstr(cygwin, "ntea") && !strstr(cygwin, "nontea"))
+ allow_ntea = 1;
+ if (strstr(cygwin, "ntsec") && !strstr(cygwin, "nontsec"))
+ allow_ntsec = 1;
+ }
+
+ /*
+ * `ntea' is an emulation of POSIX attributes. It doesn't support
+ * real file level security as ntsec on NTFS file systems does
+ * but it supports FAT filesystems. `ntea' is minimum requirement
+ * for security checks.
+ */
+ if (allow_ntea)
+ return 1;
+
+ /*
+ * Retrieve file system flags. In Cygwin, file system flags are
+ * copied to f_type which has no meaning in Win32 itself.
+ */
+ if (statfs(filename, &fsstat))
+ return 1;
+
+ /*
+ * Only file systems supporting ACLs are able to set permissions.
+ * `ntsec' is the setting in Cygwin which switches using of NTFS
+ * ACLs to support POSIX permissions on files.
+ */
+ if (fsstat.f_type & FS_PERSISTENT_ACLS)
+ return allow_ntsec;
+
+ return 0;
}
#endif
More information about the openssh-unix-dev
mailing list