Hello community, here is the log from the commit of package autossh for openSUSE:Factory checked in at 2018-10-17 08:41:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/autossh (Old) and /work/SRC/openSUSE:Factory/.autossh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "autossh" Wed Oct 17 08:41:38 2018 rev:14 rq:642238 version:1.4f Changes: -------- --- /work/SRC/openSUSE:Factory/autossh/autossh.changes 2017-11-27 22:16:01.703823877 +0100 +++ /work/SRC/openSUSE:Factory/.autossh.new/autossh.changes 2018-10-17 08:42:37.409793569 +0200 @@ -1,0 +2,11 @@ +Mon Oct 15 02:59:43 UTC 2018 - [email protected] + +- Update to version 1.4f + + Change behavior when ssh exits on signal. + + Fix order of arguments to kill(). + + Ignore SIGPIPE. + + Should accept the default -1 with AUTOSSH_MAXSTART + + memset() sigaction structure before use +- autossh-makefile-destdir.patch: dropped + +------------------------------------------------------------------- Old: ---- autossh-1.4e.tgz autossh-makefile-destdir.patch New: ---- autossh-1.4f.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ autossh.spec ++++++ --- /var/tmp/diff_new_pack.aAZXFi/_old 2018-10-17 08:42:37.865793182 +0200 +++ /var/tmp/diff_new_pack.aAZXFi/_new 2018-10-17 08:42:37.865793182 +0200 @@ -1,7 +1,7 @@ # # spec file for package autossh # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -32,7 +32,7 @@ Group: Productivity/Networking/SSH Name: autossh -Version: 1.4e +Version: 1.4f Release: 0 Url: http://www.harding.motd.ca/autossh/ Source: http://www.harding.motd.ca/autossh/%{name}-%{version}.tgz @@ -41,7 +41,6 @@ Source3: autossh.service Source4: my.conf Source5: README.SUSE.md -Patch0: autossh-makefile-destdir.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build # configure checks is the ssh client exists @@ -65,7 +64,6 @@ %prep %setup -%patch0 -p1 cp %{S:4} . cp %{S:5} . ++++++ autossh-1.4e.tgz -> autossh-1.4f.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autossh-1.4e/CHANGES new/autossh-1.4f/CHANGES --- old/autossh-1.4e/CHANGES 2015-02-10 05:41:58.000000000 +0100 +++ new/autossh-1.4f/CHANGES 2018-03-20 17:01:21.000000000 +0100 @@ -1,4 +1,26 @@ +Version 1.4f +- Change behaviour when ssh child exits on signal. Previously + if SIGHUP, SIGTERM, or SIGKILL were used, autossh assumed that + it also was meant to exit. But it is possible that ssh was + killed because it had hung up or was unresponsive for some + reason. Restarting it is probably the better course. +- Fix order of arguments to kill(). Bug reported by Dapeng Gao. +- Ignore SIGPIPE. Issue noted and debugged by Rick van der Zwet. +- Note use of ExitOnForwardFailure and ClientAliveInterval in + README and man page (Till Maas). +- Should accept the default -1 with AUTOSSH_MAXSTART. Reported by + Daniel Hahler. +- Restart ssh when ssh exits with 2, which it can do if + setting up tunnel fails due to race with remote end + tearing down. (Daniel Sutcliffe). +- Daniel Hahler and Jindrich Makovich both reported that signals + will have no effect if before ssh started (sleeping in gatetime, + etc.) Signal handling is now set just just before monitoring the + child, and unset just after. +- Makefile should use LDFLAGS (Waldemar Brodkorb). +- memset() sigaction structure before use. + Version 1.4e - By default, changing the poll time should change the first poll time to match. Only have different times if AUTOSSH_FIRST_POLL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autossh-1.4e/Makefile.in new/autossh-1.4f/Makefile.in --- old/autossh-1.4e/Makefile.in 2015-02-10 05:41:58.000000000 +0100 +++ new/autossh-1.4f/Makefile.in 2018-03-20 17:01:21.000000000 +0100 @@ -1,8 +1,8 @@ -# $Id: Makefile.in,v 1.7 2015/02/10 04:31:16 harding Exp $ +# $Id: Makefile.in,v 1.8 2018/03/18 19:31:02 harding Exp $ # # @configure_input@ -VER= 1.4e +VER= 1.4f SSH= @path_ssh@ @@ -31,7 +31,7 @@ $(TARGET): $(OFILES) - $(CC) $(CPPFLAGS) -o $(TARGET) $(OFILES) $(LIBS) + $(CC) $(CPPFLAGS) $(LDFLAGS) -o $(TARGET) $(OFILES) $(LIBS) clean: - /bin/rm -f *.o *.a *.core *~ @@ -45,18 +45,18 @@ - /bin/rm -f Makefile install: $(TARGET) - mkdir -p -m 755 $(bindir) - mkdir -p -m 755 $(prefix)/share/doc/autossh - mkdir -p -m 755 $(datadir)/examples/autossh - mkdir -p -m 755 $(mandir)/man1 - cp $(TARGET) $(bindir) - cp CHANGES README $(datadir)/doc/autossh - cp autossh.host $(datadir)/examples/autossh - cp rscreen $(datadir)/examples/autossh - cp autossh.1 $(mandir)/man1 - chmod 755 $(bindir)/$(TARGET) - chmod 644 $(datadir)/doc/autossh/CHANGES - chmod 644 $(datadir)/doc/autossh/README - chmod 644 $(datadir)/examples/autossh/autossh.host - chmod 644 $(datadir)/examples/autossh/rscreen - chmod 644 $(mandir)/man1/autossh.1 + mkdir -p -m 755 $(DESTDIR)$(bindir) + mkdir -p -m 755 $(DESTDIR)$(prefix)/share/doc/autossh + mkdir -p -m 755 $(DESTDIR)$(datadir)/examples/autossh + mkdir -p -m 755 $(DESTDIR)$(mandir)/man1 + cp $(TARGET) $(DESTDIR)$(bindir) + cp CHANGES README $(DESTDIR)$(datadir)/doc/autossh + cp autossh.host $(DESTDIR)$(datadir)/examples/autossh + cp rscreen $(DESTDIR)$(datadir)/examples/autossh + cp autossh.1 $(DESTDIR)$(mandir)/man1 + chmod 755 $(DESTDIR)$(bindir)/$(TARGET) + chmod 644 $(DESTDIR)$(datadir)/doc/autossh/CHANGES + chmod 644 $(DESTDIR)$(datadir)/doc/autossh/README + chmod 644 $(DESTDIR)$(datadir)/examples/autossh/autossh.host + chmod 644 $(DESTDIR)$(datadir)/examples/autossh/rscreen + chmod 644 $(DESTDIR)$(mandir)/man1/autossh.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autossh-1.4e/README new/autossh-1.4f/README --- old/autossh-1.4e/README 2015-02-10 05:41:58.000000000 +0100 +++ new/autossh-1.4f/README 2018-03-20 17:01:21.000000000 +0100 @@ -77,7 +77,7 @@ -f Causes autossh to drop to the background before running ssh. The -f flag is stripped from arguments passed to ssh. Note that there - is a crucial a difference between the -f with autossh, and -f + is a crucial difference between the -f with autossh, and -f with ssh: when used with autossh, ssh will be *unable* to ask for passwords or passphrases. When -f is used, the "starting gate" time (see AUTOSSH_GATETIME) will be set to 0. @@ -206,6 +206,19 @@ of this possible use, AUTOSSH_PORT overrides the -M flag. +SSH Options +------------------ + +There are two particular OpenSSH options that are useful when using +autossh: + +1) ExitOnForwardFailure=yes on the client side to make sure forwardings +have succeeded when autossh assumes the connection is setup properly. + +2) ClientAliveInterval on the server side to make sure the listening +socket is closed on the server side if the connection closes on the +client side. + Logging and Syslog ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autossh-1.4e/autossh.1 new/autossh-1.4f/autossh.1 --- old/autossh-1.4e/autossh.1 2015-02-10 05:41:58.000000000 +0100 +++ new/autossh-1.4f/autossh.1 2018-03-20 17:01:21.000000000 +0100 @@ -1,7 +1,7 @@ .\" -*- nroff -*- .\" .\" Author: Carson Harding -.\" Copyright (c) 2002 Carson Harding. All rights reserved. +.\" Copyright (c) 2002-2018 Carson Harding. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted. @@ -17,9 +17,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $Id: autossh.1,v 1.23 2015/02/10 04:31:16 harding Exp $ +.\" $Id: autossh.1,v 1.24 2018/03/18 19:28:38 harding Exp $ .\" -.Dd Jul 20, 2004 +.Dd Mar 18, 2018 .Dt AUTOSSH 1 .Os .Sh NAME @@ -192,7 +192,7 @@ causes autossh to drop to the background before running ssh. The .Fl f flag is stripped from arguments passed to ssh. Note that there is a crucial -a difference between +difference between .Fl f with autossh, and .Fl f @@ -265,11 +265,27 @@ -M at some time. But because of this possible use, AUTOSSH_PORT overrides the -M flag. A value of 0 turns the monitoring function off. .El +.Sh ENVIRONMENT +There are two particular OpenSSH options that are useful when using +.Nm +: +.Fp +.Cm ExitOnForwardFailure=yes +on the client side to make sure forwardings +have succeeded when autossh assumes the connection is setup properly. +.Fp +.Cm ClientAliveInterval +on the server side to make sure the listening +socket is closed on the server side if the connection closes on the +client side. +.El .Sh AUTHOR .Nm was written by Carson Harding. .Sh SEE ALSO .Xr ssh 1 , +.Xr ssh_config 5, +.Xr sshd_config 5, .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autossh-1.4e/autossh.c new/autossh-1.4f/autossh.c --- old/autossh-1.4e/autossh.c 2015-02-10 05:41:58.000000000 +0100 +++ new/autossh-1.4f/autossh.c 2018-03-20 17:01:21.000000000 +0100 @@ -4,7 +4,7 @@ * * From the example of rstunnel. * - * Copyright (c) Carson Harding, 2002-2008. + * Copyright (c) Carson Harding, 2002-2018. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -21,6 +21,8 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $Id: autossh.c,v 1.89 2018/03/18 19:27:49 harding Exp $ + * */ #include "config.h" @@ -81,7 +83,7 @@ char *__progname; #endif -const char *rcsid = "$Id: autossh.c,v 1.84 2015/02/10 04:31:16 harding Exp $"; +const char *rcsid = "$Id: autossh.c,v 1.89 2018/03/18 19:27:49 harding Exp $"; #ifndef SSH_PATH # define SSH_PATH "/usr/bin/ssh" @@ -97,14 +99,17 @@ #define P_CONTINUE 0 /* continue monitoring */ #define P_RESTART 1 /* restart ssh process */ -#define P_EXIT 2 /* exit */ +#define P_EXITOK 2 /* exit ok */ +#define P_EXITERR 3 /* exit with error */ #define L_FILELOG 0x01 /* log to file */ #define L_SYSLOG 0x02 /* log to syslog */ #define NO_RD_SOCK -2 /* magic flag for echo: no read socket */ -#define OPTION_STRING "M:V1246ab:c:e:fgi:kl:m:no:p:qstvw:xyACD:F:I:MKL:NO:PR:S:TVXY" +#define N_FAST_TRIES 5 /* try this many times fast before slowing */ + +#define OPTION_STRING "M:V1246ab:c:e:fgi:kl:m:no:p:qstvw:xyACD:E:F:GI:MKL:NO:PQ:R:S:TW:XY" int logtype = L_SYSLOG; /* default log to syslog */ int loglevel = LOG_INFO; /* default loglevel */ @@ -140,6 +145,7 @@ int cchild; /* current child */ +volatile sig_atomic_t exit_signalled; /* signalled outside of monitor loop */ volatile sig_atomic_t restart_ssh; /* signalled to restart ssh child */ volatile sig_atomic_t dolongjmp; sigjmp_buf jumpbuf; @@ -148,7 +154,7 @@ void get_env_args(void); void add_arg(char *s); void strip_arg(char *arg, char ch, char *opts); -void ssh_run(int sock, char **argv); +int ssh_run(int sock, char **argv); int ssh_watch(int sock); int ssh_wait(int options); void ssh_kill(void); @@ -171,7 +177,10 @@ __attribute__ ((__format__ (__printf__, 2, 3))); void doerrlog(int level, char *fmt, va_list ap); char *timestr(void); -void sig_catch(int sig); +void set_exit_sig_handler(void); +void set_sig_handlers(void); +void unset_sig_handlers(void); +void sig_catch(int sig); int exceeded_lifetime(void); void @@ -265,6 +274,7 @@ char wmbuf[256], rmbuf[256]; FILE *pid_file; + int retval = 0; int sock = -1; int done_fwds = 0; int runasdaemon = 0; @@ -478,7 +488,7 @@ fclose(pid_file); } - ssh_run(sock, newav); + retval = ssh_run(sock, newav); if (sock >= 0) { shutdown(sock, SHUT_RDWR); @@ -488,6 +498,8 @@ if (logtype & L_SYSLOG) closelog(); + if (retval == P_EXITERR) + exit(1); exit(0); } @@ -624,7 +636,7 @@ if ((s = getenv("AUTOSSH_MAXSTART")) != NULL) { max_start = (int)strtol(s, &t, 0); - if (*s == '\0' || max_start < 0 || *t != '\0') + if (*s == '\0' || max_start < -1 || *t != '\0') xerrlog(LOG_ERR, "invalid max start number \"%s\"", s); } @@ -636,7 +648,6 @@ MAX_MESSAGE); } - if ((s = getenv("AUTOSSH_PORT")) != NULL) if (*s != '\0') env_port = s; @@ -699,26 +710,12 @@ /* * Run ssh */ -void +int ssh_run(int sock, char **av) { - struct sigaction act; + int retval; struct timeval tv; - act.sa_handler = sig_catch; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - - sigaction(SIGTERM, &act, NULL); - sigaction(SIGINT, &act, NULL); - sigaction(SIGHUP, &act, NULL); - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGUSR2, &act, NULL); - sigaction(SIGCHLD, &act, NULL); - - act.sa_flags |= SA_RESTART; - sigaction(SIGALRM, &act, NULL); - /* * There are much better things. and we all wait * for solaris to get /dev/random. @@ -726,12 +723,18 @@ gettimeofday(&tv, NULL); srandom(getpid() ^ tv.tv_usec ^ tv.tv_sec); + set_exit_sig_handler(); + while (max_start < 0 || start_count < max_start) { if (exceeded_lifetime()) - return; + return P_EXITOK; restart_ssh = 0; start_count++; grace_time(start_time); + if (exit_signalled) { + errlog(LOG_ERR, "signalled to exit"); + return P_EXITERR; + } time(&start_time); if (max_start < 0) errlog(LOG_INFO, "starting ssh (count %d)", @@ -742,12 +745,13 @@ cchild = fork(); switch (cchild) { case 0: - errlog(LOG_DEBUG, "execing %s", av[0]); + errlog(LOG_DEBUG, "child of %d execing %s", + getppid(), av[0]); execvp(av[0], av); - xerrlog(LOG_ERR, "%s: %s", av[0], strerror(errno)); + errlog(LOG_ERR, "%s: %s", av[0], strerror(errno)); /* else can loop restarting! */ - kill(SIGTERM, getppid()); - exit(1); + kill(getppid(), SIGTERM); + _exit(1); break; case -1: cchild = 0; @@ -755,13 +759,19 @@ break; default: errlog(LOG_INFO, "ssh child pid is %d", (int)cchild); - if (ssh_watch(sock) == P_EXIT) - return; + set_sig_handlers(); + retval = ssh_watch(sock); + dolongjmp = 0; + unset_sig_handlers(); + if (retval == P_EXITOK || retval == P_EXITERR) + return retval; break; } } - errlog(LOG_INFO, "max start count reached; exiting"); + errlog(LOG_INFO, "max start count reached; exiting"); + + return P_EXITOK; } /* @@ -820,6 +830,15 @@ alarm(secs_left); dolongjmp = 1; + + /* In case we were signalled while setting + all this up */ + if (exit_signalled) { + errlog(LOG_INFO, "signalled to exit"); + ssh_kill(); + return P_EXITERR; + } + pause(); } else { @@ -832,12 +851,12 @@ errlog(LOG_INFO, "received signal to exit (%d)", val); ssh_kill(); - return P_EXIT; + return P_EXITERR; break; case SIGALRM: if (exceeded_lifetime()) { ssh_kill(); - return P_EXIT; + return P_EXITOK; } if (writep && sock != -1 && @@ -895,10 +914,10 @@ * known dead child. * * If child was deliberately killed (TERM, INT, KILL), - * or if child called exit(0) or _exit(0), then pass - * message on return to give up (P_EXIT). Otherwise death - * was unnatural (or unintended), and pass message back - * to restart (P_RESTART). + * the pass message back to restart. If child called exit(0) + * or _exit(0), then pass message on return to give up (P_EXITOK). + * Otherwise death was unnatural (or unintended), and pass + * message back to restart (P_RESTART). * * However, if child died with exit(1) on first try, then * there is some startup error (anything from network @@ -931,6 +950,14 @@ if (waitpid(cchild, &status, options) > 0) { if (WIFSIGNALED(status)) { switch(WTERMSIG(status)) { +#if 0 + /* If someone kills the child, we assume + it was hung up or something and they + wished to restart it. Not entirely sure + want to keep this behaviour or what + signals it should apply to, therefore + the #if 0. + */ case SIGINT: case SIGTERM: case SIGKILL: @@ -938,8 +965,9 @@ errlog(LOG_INFO, "ssh exited on signal %d; parent exiting", WTERMSIG(status)); - return P_EXIT; + return P_EXITERR; break; +#endif default: /* continue on and restart */ errlog(LOG_INFO, @@ -960,7 +988,7 @@ "ssh exited prematurely " "with status %d; %s exiting", evalue, __progname); - return P_EXIT; + return P_EXITERR; } } switch(evalue) { @@ -981,6 +1009,19 @@ evalue); return P_RESTART; break; + case 0: /* exited on success */ +#if defined(__CYGWIN__) + if (ntservice) + return P_RESTART; +#endif + errlog(LOG_INFO, + "ssh exited with status %d; %s exiting", + evalue, __progname); + return P_EXITOK; + case 2: + /* can exit with 2 with temporary issues + setting up tunnels */ + /* FALLTHROUGH */ case 1: /* * the first time, it could be any of @@ -998,17 +1039,11 @@ return P_RESTART; } /* FALLTHROUGH */ - case 0: /* exited on success */ -#if defined(__CYGWIN__) - if (ntservice) - return P_RESTART; - /* FALLTHROUGH */ -#endif default: /* remote command error status */ errlog(LOG_INFO, "ssh exited with status %d; %s exiting", evalue, __progname); - return P_EXIT; + return P_EXITERR; break; } } @@ -1088,8 +1123,8 @@ errlog(LOG_DEBUG, "checking for grace period, tries = %d", tries); - if (tries > 5) { - t = (double)(tries - 5); + if (tries > N_FAST_TRIES) { + t = (double)(tries - N_FAST_TRIES); n = (int)((poll_time / 100.0) * (t * (t/3))); interval = (n > poll_time) ? poll_time : n; if (interval) { @@ -1101,6 +1136,68 @@ return; } +void +set_exit_sig_handler() +{ + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = sig_catch; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + sigaction(SIGTERM, &act, NULL); + sigaction(SIGINT, &act, NULL); +} + +void +set_sig_handlers(void) +{ + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = sig_catch; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + sigaction(SIGTERM, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGUSR1, &act, NULL); + sigaction(SIGUSR2, &act, NULL); + sigaction(SIGCHLD, &act, NULL); + + act.sa_flags |= SA_RESTART; + sigaction(SIGALRM, &act, NULL); + + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + sigaction(SIGPIPE, &act, NULL); +} + +void +unset_sig_handlers(void) +{ + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + /* We don't reset SIGTERM, as we want the + handler to persist in the run_ssh() loop */ + /* This seems a little hidden down in here... */ + /* sigaction(SIGTERM, &act, NULL); */ + /* sigaction(SIGINT, &act, NULL); */ + sigaction(SIGHUP, &act, NULL); + sigaction(SIGUSR1, &act, NULL); + sigaction(SIGUSR2, &act, NULL); + sigaction(SIGCHLD, &act, NULL); + sigaction(SIGALRM, &act, NULL); + sigaction(SIGPIPE, &act, NULL); +} + /* * If we're primed, longjump back. */ @@ -1109,6 +1206,8 @@ { if (sig == SIGUSR1) restart_ssh = 1; + else if (sig == SIGTERM || sig == SIGINT) + exit_signalled = 1; if (dolongjmp) { dolongjmp = 0; siglongjmp(jumpbuf, sig);
