From bac2d8aa5e642a70045e713853b13d020b9c5d57 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 5 Sep 2000 16:13:06 +1100 Subject: [PATCH] - (djm) Merge cygwin support from Corinna Vinschen --- CREDITS | 1 + ChangeLog | 2 ++ Makefile.in | 37 +++++++++++++++++++------------------ acconfig.h | 6 ++++++ auth-passwd.c | 27 +++++++++++++++++++++++++++ auth1.c | 25 +++++++++++++++++++++++++ authfile.c | 8 +++++++- bsd-daemon.c | 7 +++++++ bsd-mktemp.c | 5 +++++ channels.c | 2 ++ configure.in | 14 ++++++++++++++ cygwin_util.c | 35 +++++++++++++++++++++++++++++++++++ defines.h | 4 ++++ includes.h | 12 ++++++++++++ loginrec.c | 4 +++- pty.c | 16 +++++++++------- readconf.c | 2 ++ scp.c | 9 +++++++++ session.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ ssh.c | 16 ++++++++++++++++ sshconnect.c | 4 ++++ sshd.c | 2 +- 22 files changed, 259 insertions(+), 28 deletions(-) create mode 100644 cygwin_util.c diff --git a/CREDITS b/CREDITS index 148a38a49..b2ea280dc 100644 --- a/CREDITS +++ b/CREDITS @@ -21,6 +21,7 @@ Chris Saia - SuSE packaging Chris, the Young One - Password auth fixes Christos Zoulas - Autoconf fixes Chun-Chung Chen - RPM fixes +Corinna Vinschen - Cygwin support Dan Brosemer - Autoconf support, build fixes Darren Hall - AIX patches David Agraz - Build fixes diff --git a/ChangeLog b/ChangeLog index 9aa9423c8..6b112b6c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,8 @@ [session.c] set SSH_ORIGINAL_COMMAND; from Leakin@dfw.nostrum.com, bet@rahul.net - (djm) Cleanup after import. Fix sftp-server compilation, Makefile + - (djm) Merge cygwin support from Corinna Vinschen + 20000903 - (djm) Fix Redhat init script diff --git a/Makefile.in b/Makefile.in index 7eb84ce63..f8a0ee291 100644 --- a/Makefile.in +++ b/Makefile.in @@ -29,12 +29,13 @@ INSTALL=@INSTALL@ PERL=@PERL@ ENT=@ENT@ LDFLAGS=-L. @LDFLAGS@ +EXEEXT=@EXEEXT@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ -TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server $(EXTRA_TARGETS) +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) $(EXTRA_TARGETS) -LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o +LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o cygwin_util.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o @@ -68,25 +69,25 @@ libssh.a: $(LIBSSH_OBJS) $(AR) rv $@ $(LIBSSH_OBJS) $(RANLIB) $@ -ssh: libopenbsd-compat.a libssh.a $(SSHOBJS) +ssh$(EXEEXT): libopenbsd-compat.a libssh.a $(SSHOBJS) $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -sshd: libssh.a libopenbsd-compat.a $(SSHDOBJS) +sshd$(EXEEXT): libssh.a libopenbsd-compat.a $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -scp: libopenbsd-compat.a libssh.a scp.o +scp$(EXEEXT): libopenbsd-compat.a libssh.a scp.o $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-add: libopenbsd-compat.a libssh.a ssh-add.o log-client.o +ssh-add$(EXEEXT): libopenbsd-compat.a libssh.a ssh-add.o log-client.o $(LD) -o $@ ssh-add.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-agent: libopenbsd-compat.a libssh.a ssh-agent.o log-client.o +ssh-agent$(EXEEXT): libopenbsd-compat.a libssh.a ssh-agent.o log-client.o $(LD) -o $@ ssh-agent.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keygen: libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o +ssh-keygen$(EXEEXT): libopenbsd-compat.a libssh.a ssh-keygen.o log-client.o $(LD) -o $@ ssh-keygen.o log-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -sftp-server: libopenbsd-compat.a libssh.a sftp-server.o log-server.o +sftp-server$(EXEEXT): libopenbsd-compat.a libssh.a sftp-server.o log-server.o $(LD) -o $@ sftp-server.o log-server.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) # test driver for the loginrec code - not built by default @@ -142,7 +143,7 @@ install-files: $(INSTALL) -m 644 sshd.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 $(INSTALL) -m 644 sftp-server.[08].out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(bindir)/slogin - ln -s ssh $(DESTDIR)$(bindir)/slogin + ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config -a ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ @@ -155,7 +156,7 @@ install-files: $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ fi -host-key: ssh-keygen +host-key: ssh-keygen$(EXEEXT) if [ -z "$(DESTDIR)" ] ; then \ if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ @@ -169,7 +170,7 @@ host-key: ssh-keygen fi ; \ fi ; -host-key-force: ssh-keygen +host-key-force: ssh-keygen$(EXEEXT) ./ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ./ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" @@ -186,12 +187,12 @@ uninstallall: uninstall -rmdir $(DESTDIR)$(libexecdir) uninstall: - -rm -f $(DESTDIR)$(bindir)/ssh - -rm -f $(DESTDIR)$(bindir)/scp - -rm -f $(DESTDIR)$(bindir)/ssh-add - -rm -f $(DESTDIR)$(bindir)/ssh-agent - -rm -f $(DESTDIR)$(bindir)/ssh-keygen - -rm -f $(DESTDIR)$(sbindir)/sshd + -rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) + -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 diff --git a/acconfig.h b/acconfig.h index c16ec2bf6..d855d887a 100644 --- a/acconfig.h +++ b/acconfig.h @@ -43,6 +43,9 @@ /* Define if your snprintf is busted */ #undef BROKEN_SNPRINTF +/* Define if you are on Cygwin */ +#undef HAVE_CYGWIN + /* Define if you are on NeXT */ #undef HAVE_NEXT @@ -243,6 +246,9 @@ /* getaddrinfo is broken (if present) */ #undef BROKEN_GETADDRINFO +/* vhangup is broken (if present) */ +#undef BROKEN_VHANGUP + /* Workaround more Linux IPv6 quirks */ #undef DONT_TRY_OTHER_AF diff --git a/auth-passwd.c b/auth-passwd.c index 93756e9e6..850e25834 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -37,6 +37,13 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.16 2000/06/20 01:39:38 markus Exp $"); # include "md5crypt.h" #endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ +#ifdef HAVE_CYGWIN +#undef ERROR +#include +#include +#define is_winnt (GetVersion() < 0x80000000) +#endif + /* * Tries to authenticate the user using password. Returns true if * authentication succeeds. @@ -63,11 +70,31 @@ auth_password(struct passwd * pw, const char *password) /* deny if no user. */ if (pw == NULL) return 0; +#ifndef HAVE_CYGWIN if (pw->pw_uid == 0 && options.permit_root_login == 2) return 0; +#endif +#ifdef HAVE_CYGWIN + /* + * Empty password is only possible on NT if the user has _really_ + * an empty password and authentication is done, though. + */ + if (!is_winnt) +#endif if (*password == '\0' && options.permit_empty_passwd == 0) return 0; +#ifdef HAVE_CYGWIN + if (is_winnt) { + HANDLE hToken = cygwin_logon_user(pw, password); + + if (hToken == INVALID_HANDLE_VALUE) + return 0; + cygwin_set_impersonation_token(hToken); + return 1; + } +#endif + #ifdef SKEY if (options.skey_authentication == 1) { int ret = auth_skey_password(pw, password); diff --git a/auth1.c b/auth1.c index b043e8a95..3720a7d28 100644 --- a/auth1.c +++ b/auth1.c @@ -23,6 +23,11 @@ RCSID("$OpenBSD: auth1.c,v 1.3 2000/08/20 18:42:40 millert Exp $"); # include #endif +#ifdef HAVE_CYGWIN +#include +#define is_winnt (GetVersion() < 0x80000000) +#endif + /* import */ extern ServerOptions options; extern char *forced_command; @@ -371,6 +376,23 @@ do_authloop(struct passwd * pw) break; } +#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) { + packet_disconnect("Authentication rejected for uid %d.", + (int) pw->pw_uid); + authenticated = 0; + } +#endif + /* * Check if the user is logging in as root and root logins * are disallowed. @@ -491,12 +513,15 @@ do_authentication() start_pam(pw); #endif +#ifndef HAVE_CYGWIN /* * If we are not running as root, the user must have the same uid as * the server. + * Rule not valid on Windows systems. */ if (getuid() != 0 && pw->pw_uid != getuid()) packet_disconnect("Cannot change user when server not running as root."); +#endif debug("Attempting authentication for %.100s.", pw->pw_name); diff --git a/authfile.c b/authfile.c index 71c4a5d84..4368cb941 100644 --- a/authfile.c +++ b/authfile.c @@ -457,7 +457,12 @@ load_private_key(const char *filename, const char *passphrase, Key *key, if (fd < 0) return 0; - /* check owner and modes */ +#ifndef HAVE_CYGWIN + /* + * check owner and modes. + * This won't work on Windows under all circumstances so we drop + * that check for now. + */ if (fstat(fd, &st) < 0 || (st.st_uid != 0 && st.st_uid != getuid()) || (st.st_mode & 077) != 0) { @@ -470,6 +475,7 @@ load_private_key(const char *filename, const char *passphrase, Key *key, 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) { diff --git a/bsd-daemon.c b/bsd-daemon.c index de829958c..f704a9048 100644 --- a/bsd-daemon.c +++ b/bsd-daemon.c @@ -51,6 +51,13 @@ daemon(nochdir, noclose) case 0: 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); } diff --git a/bsd-mktemp.c b/bsd-mktemp.c index e8ffd0219..9ed1bc80f 100644 --- a/bsd-mktemp.c +++ b/bsd-mktemp.c @@ -42,6 +42,11 @@ static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ +#ifdef HAVE_CYGWIN +#define open binary_open +extern int binary_open(); +#endif + static int _gettemp(char *, int *, int, int); int diff --git a/channels.c b/channels.c index c77f6b96a..4ac48a77a 100644 --- a/channels.c +++ b/channels.c @@ -1567,6 +1567,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports) hostname = packet_get_string(NULL); host_port = packet_get_int(); +#ifndef HAVE_CYGWIN /* * Check that an unprivileged user is not trying to forward a * privileged port. @@ -1574,6 +1575,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports) if (port < IPPORT_RESERVED && !is_root) packet_disconnect("Requested forwarding of port %d but user is not root.", port); +#endif /* * Initiate forwarding, */ diff --git a/configure.in b/configure.in index b1dd1d067..9fb78f1ff 100644 --- a/configure.in +++ b/configure.in @@ -54,6 +54,18 @@ case "$host" in MANTYPE='$(CATMAN)' mansubdir=cat ;; +*-*-cygwin*) + LIBS="$LIBS /usr/lib/textmode.o" + AC_DEFINE(HAVE_CYGWIN) + AC_DEFINE(DISABLE_PAM) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(IPV4_DEFAULT) + AC_DEFINE(IP_TOS_IS_BROKEN) + AC_DEFINE(BROKEN_VHANGUP) + no_pam=1 + no_libsocket=1 + no_libnsl=1 + ;; *-*-hpux10*) if test -z "$GCC"; then CFLAGS="$CFLAGS -Ae" @@ -1400,6 +1412,8 @@ if test ! -z "$blibpath" ; then AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile]) fi +AC_EXEEXT + AC_OUTPUT(Makefile ssh_prng_cmds) # Print summary of options diff --git a/cygwin_util.c b/cygwin_util.c new file mode 100644 index 000000000..13bd66347 --- /dev/null +++ b/cygwin_util.c @@ -0,0 +1,35 @@ +/* + * + * cygwin_util.c + * + * Author: Corinna Vinschen + * + * Copyright (c) 2000 Corinna Vinschen , Duisburg, Germany + * All rights reserved + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#include "config.h" + +#ifdef HAVE_CYGWIN +#include +#include + +int binary_open(const char *filename, int flags, mode_t mode) +{ + return open(filename, flags | O_BINARY, mode); +} + +int binary_pipe(int fd[2]) +{ + int ret = pipe(fd); + if (!ret) { + setmode (fd[0], O_BINARY); + setmode (fd[1], O_BINARY); + } +} +#endif diff --git a/defines.h b/defines.h index 6bbb5166b..69b8baf27 100644 --- a/defines.h +++ b/defines.h @@ -322,6 +322,10 @@ typedef int mode_t; # define atexit(a) on_exit(a) #endif /* !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT) */ +#if defined(HAVE_VHANGUP) && !defined(BROKEN_VHANGUP) +# define USE_VHANGUP +#endif /* defined(HAVE_VHANGUP) && !defined(BROKEN_VHANGUP) */ + /** ** login recorder definitions **/ diff --git a/includes.h b/includes.h index 5102c97ad..27569e18f 100644 --- a/includes.h +++ b/includes.h @@ -29,7 +29,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include #include +#ifndef HAVE_CYGWIN #include +#endif #include #include @@ -46,6 +48,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include #include #include +#ifdef HAVE_CYGWIN +#include +#endif #ifdef HAVE_BSTRING_H # include @@ -110,4 +115,11 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } */ /* #define USE_PIPES 1 */ +#ifdef HAVE_CYGWIN +#define open binary_open +#define pipe binary_pipe +extern int binary_open(); +extern int binary_pipe(); +#endif + #endif /* INCLUDES_H */ diff --git a/loginrec.c b/loginrec.c index 61bceb180..0e1f344b9 100644 --- a/loginrec.c +++ b/loginrec.c @@ -161,7 +161,7 @@ #include "xmalloc.h" #include "loginrec.h" -RCSID("$Id: loginrec.c,v 1.22 2000/08/29 03:30:37 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.23 2000/09/05 05:13:07 djm Exp $"); /** ** prototypes for helper functions in this file @@ -401,10 +401,12 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa, int login_write (struct logininfo *li) { +#ifndef HAVE_CYGWIN if ((int)geteuid() != 0) { log("Attempt to write login records by non-root user (aborting)"); return 1; } +#endif /* set the timestamp */ login_set_current_time(li); diff --git a/pty.c b/pty.c index f5bb86124..d610a4543 100644 --- a/pty.c +++ b/pty.c @@ -118,6 +118,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) close(*ptyfd); return 0; } +#ifndef HAVE_CYGWIN /* Push the appropriate streams modules, as described in Solaris pts(7). */ if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) error("ioctl I_PUSH ptem: %.100s", strerror(errno)); @@ -126,6 +127,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) #ifndef _HPUX_SOURCE if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); +#endif #endif return 1; #else /* HAVE_DEV_PTMX */ @@ -208,9 +210,9 @@ void pty_make_controlling_tty(int *ttyfd, const char *ttyname) { int fd; -#ifdef HAVE_VHANGUP +#ifdef USE_VHANGUP void *old; -#endif /* HAVE_VHANGUP */ +#endif /* USE_VHANGUP */ /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY @@ -242,21 +244,21 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) */ ioctl(*ttyfd, TIOCSCTTY, NULL); #endif /* TIOCSCTTY */ -#ifdef HAVE_VHANGUP +#ifdef USE_VHANGUP old = signal(SIGHUP, SIG_IGN); vhangup(); signal(SIGHUP, old); -#endif /* HAVE_VHANGUP */ +#endif /* USE_VHANGUP */ fd = open(ttyname, O_RDWR); if (fd < 0) { error("%.100s: %.100s", ttyname, strerror(errno)); } else { -#ifdef HAVE_VHANGUP +#ifdef USE_VHANGUP close(*ttyfd); *ttyfd = fd; -#else /* HAVE_VHANGUP */ +#else /* USE_VHANGUP */ close(fd); -#endif /* HAVE_VHANGUP */ +#endif /* USE_VHANGUP */ } /* Verify that we now have a controlling tty. */ fd = open("/dev/tty", O_WRONLY); diff --git a/readconf.c b/readconf.c index f31b1c4e6..c9e0f5944 100644 --- a/readconf.c +++ b/readconf.c @@ -174,9 +174,11 @@ add_local_forward(Options *options, u_short port, const char *host, u_short host_port) { Forward *fwd; +#ifndef HAVE_CYGWIN extern uid_t original_real_uid; if (port < IPPORT_RESERVED && original_real_uid != 0) fatal("Privileged ports can only be forwarded by root.\n"); +#endif if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->local_forwards[options->num_local_forwards++]; diff --git a/scp.c b/scp.c index 33bd0a5ff..23ecc41ca 100644 --- a/scp.c +++ b/scp.c @@ -1117,8 +1117,17 @@ foregroundproc() if (pgrp == -1) pgrp = getpgrp(); +#ifdef HAVE_CYGWIN + /* + * Cygwin only supports tcgetpgrp() for getting the controlling tty + * currently. + */ + return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 && + ctty_pgrp == pgrp); +#else return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && ctty_pgrp == pgrp)); +#endif } void diff --git a/session.c b/session.c index d5faf4cf3..a537efdd4 100644 --- a/session.c +++ b/session.c @@ -41,6 +41,12 @@ RCSID("$OpenBSD: session.c,v 1.35 2000/09/04 19:07:21 markus Exp $"); # include #endif +#ifdef HAVE_CYGWIN +#include +#include +#define is_winnt (GetVersion() < 0x80000000) +#endif + /* AIX limits */ #if defined(HAVE_GETUSERATTR) && !defined(S_UFSIZE_HARD) && defined(S_UFSIZE) # define S_UFSIZE_HARD S_UFSIZE "_hard" @@ -503,6 +509,10 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); /* NOTREACHED */ } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -594,6 +604,10 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) s->auth_data, s->tty); /* NOTREACHED */ } +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -973,7 +987,11 @@ do_child(const char *command, struct passwd * pw, const char *term, exit(1); } #else /* HAVE_OSF_SIA */ +#ifdef HAVE_CYGWIN + if (is_winnt) { +#else if (getuid() == 0 || geteuid() == 0) { +#endif # ifdef HAVE_GETUSERATTR set_limits_from_userattr(pw->pw_name); # endif /* HAVE_GETUSERATTR */ @@ -1018,6 +1036,9 @@ do_child(const char *command, struct passwd * pw, const char *term, } #endif /* HAVE_OSF_SIA */ +#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); } @@ -1047,6 +1068,22 @@ do_child(const char *command, struct passwd * pw, const char *term, env = xmalloc(envsize * sizeof(char *)); env[0] = NULL; +#ifdef HAVE_CYGWIN + /* + * The Windows environment contains some setting which are + * important for a running system. They must not be dropped. + */ + { + char **ep; + for (ep = environ; *ep; ++ep) { + char *esp = strchr(*ep, '='); + *esp = '\0'; + child_set_env(&env, &envsize, *ep, esp + 1); + *esp = '='; + } + } +#endif + if (!options.use_login) { /* Set basic environment. */ child_set_env(&env, &envsize, "USER", pw->pw_name); @@ -1056,7 +1093,15 @@ do_child(const char *command, struct passwd * pw, const char *term, (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); child_set_env(&env, &envsize, "PATH", getenv("PATH")); #else +#ifndef HAVE_CYGWIN + /* + * There's no standard path on Windows. The path contains + * important components pointing to the system directories, + * needed for loading shared libraries. So the path better + * remains intact here. + */ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +#endif #endif snprintf(buf, sizeof buf, "%.200s/%.50s", @@ -1234,11 +1279,13 @@ do_child(const char *command, struct passwd * pw, const char *term, "Running %.100s add %.100s %.100s %.100s\n", options.xauth_location, display, auth_proto, auth_data); +#ifndef HAVE_CYGWIN if (screen != NULL) fprintf(stderr, "Adding %.*s/unix%s %s %s\n", (int)(screen-display), display, screen, auth_proto, auth_data); +#endif } snprintf(cmd, sizeof cmd, "%s -q -", options.xauth_location); @@ -1246,10 +1293,12 @@ do_child(const char *command, struct passwd * pw, const char *term, if (f) { fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); +#ifndef HAVE_CYGWIN if (screen != NULL) fprintf(f, "add %.*s/unix%s %s %s\n", (int)(screen-display), display, screen, auth_proto, auth_data); +#endif pclose(f); } else { fprintf(stderr, "Could not run %s\n", diff --git a/ssh.c b/ssh.c index 71d8f96fe..c117ad5ed 100644 --- a/ssh.c +++ b/ssh.c @@ -215,6 +215,7 @@ main(int ac, char **av) original_real_uid = getuid(); original_effective_uid = geteuid(); +#ifndef HAVE_CYGWIN /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; @@ -222,6 +223,7 @@ main(int ac, char **av) if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } +#endif /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are @@ -253,8 +255,17 @@ main(int ac, char **av) cp = strrchr(av0, '/') + 1; else cp = av0; +#ifdef HAVE_CYGWIN + if (strcasecmp(cp, "rsh") && strcasecmp(cp, "ssh") && + strcasecmp(cp, "rlogin") && strcasecmp(cp, "slogin") && + strcasecmp(cp, "remsh") && + strcasecmp(cp, "rsh.exe") && strcasecmp(cp, "ssh.exe") && + strcasecmp(cp, "rlogin.exe") && strcasecmp(cp, "slogin.exe") && + strcasecmp(cp, "remsh.exe")) +#else if (strcmp(cp, "rsh") && strcmp(cp, "ssh") && strcmp(cp, "rlogin") && strcmp(cp, "slogin") && strcmp(cp, "remsh")) +#endif host = cp; for (optind = 1; optind < ac; optind++) { @@ -551,7 +562,12 @@ main(int ac, char **av) } } /* Disable rhosts authentication if not running as root. */ +#ifdef HAVE_CYGWIN + /* Ignore uid if running under Windows */ + if (!options.use_privileged_port) { +#else if (original_effective_uid != 0 || !options.use_privileged_port) { +#endif options.rhosts_authentication = 0; options.rhosts_rsa_authentication = 0; } diff --git a/sshconnect.c b/sshconnect.c index 21eff6c6b..7c47ebe94 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -243,7 +243,11 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, /* Create a socket for connecting. */ sock = ssh_create_socket(original_real_uid, +#ifdef HAVE_CYGWIN + !anonymous && port < IPPORT_RESERVED, +#else !anonymous && geteuid() == 0 && port < IPPORT_RESERVED, +#endif ai->ai_family); if (sock < 0) continue; diff --git a/sshd.c b/sshd.c index e3903c783..f01df902a 100644 --- a/sshd.c +++ b/sshd.c @@ -765,7 +765,7 @@ main(int ac, char **av) * fail if there already is a daemon, and this will * overwrite any old pid in the file. */ - f = fopen(options.pid_file, "w"); + f = fopen(options.pid_file, "wb"); if (f) { fprintf(f, "%u\n", (unsigned int) getpid()); fclose(f);