Пример #1
0
value sys_catch_break(value onoff)
{
  if (Tag_val(onoff))
    mysignal(SIGINT, intr_handler);
  else
    mysignal(SIGINT, SIG_DFL);
  return Atom(0);
}
Пример #2
0
static void
handle_sigTSTP(int signo)
{
    sigset_t all_signals;
    int error, saved_errno = errno;

    DEBUG_RANDOM_SLEEP;
    sigfillset(&all_signals);

    DPRINTF2(DEBUG_SIGNALS, "got %s, sending it to pgid %d", signal_name(signo), command_pid);
    zero_select_timeout();
    /* Hand the SIGTSTP down to command and its process group */
    if (command_pid && (error = kill(-command_pid, SIGTSTP))) {
        myerror(FATAL|USE_ERRNO, "Failed to deliver SIGTSTP");
    }

    if (within_line_edit)
        save_rl_state();


    mysignal(SIGTSTP, SIG_DFL);   /* reset disposition to default (i.e. suspend) */
    sigprocmask(SIG_UNBLOCK, &all_signals, NULL); /* respond to sleep- and wake-up signals  */
    kill(getpid(), SIGTSTP); /* suspend */
    /* keyboard gathers dust, kingdoms crumble,.... */

    /* .... */

    /* Beautiful princess types "fg", (or her father tries to kill us...) and we wake up HERE: */
    sigprocmask(SIG_BLOCK, &all_signals, NULL);
    mysignal(SIGTSTP, &handle_sigTSTP);
    DPRINTF0(DEBUG_SIGNALS, "woken up");

    /* On most systems, command's process group will have been woken up by the handler of
       the signal that woke us up. This doesn't seem to happen for SIGCONT on QNX, so here goes: */

#ifdef __QNX__
    if (command_pid && (error = kill(-command_pid, SIGCONT))) {
        myerror(FATAL|USE_ERRNO, "Failed to deliver SIGCONT");
    }
#endif

    if (within_line_edit) {
        restore_rl_state();
    } else {
        set_echo(FALSE);
        cr();
        if (skip_rlwrap())
            return;
        move_cursor_to_start_of_prompt(ERASE);
        cook_prompt_if_necessary();
        my_putstr(saved_rl_state.cooked_prompt);
    }
    adapt_tty_winsize(STDIN_FILENO, master_pty_fd);       /* just in case */
    errno = saved_errno;
    sigprocmask(SIG_UNBLOCK, &all_signals, NULL);
}
Пример #3
0
value sys_catch_break(value onoff)    /* ML */
{
#ifdef WIN32
  catch_break = Tag_val(onoff);
#endif
  if (Tag_val(onoff))
    mysignal(SIGINT, intr_handler);
  else
    mysignal(SIGINT, SIG_DFL);
  return Atom(0);
}
Пример #4
0
void
server_loop2(Authctxt *authctxt)
{
	fd_set *readset = NULL, *writeset = NULL;
	int rekeying = 0, max_fd, nalloc = 0;

	debug("Entering interactive session for SSH2.");

	mysignal(SIGCHLD, sigchld_handler);
	child_terminated = 0;
	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, notify_pipe[0]);

	xxx_authctxt = authctxt;

	server_init_dispatch();

	for (;;) {
		process_buffered_input_packets();

		rekeying = (xxx_kex != NULL && !xxx_kex->done);

		if (!rekeying && packet_not_very_much_data_to_write())
			channel_output_poll();
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, 0);

		collect_children();
		if (!rekeying) {
			channel_after_select(readset, writeset);
			if (packet_need_rekeying()) {
				debug("need rekeying");
				xxx_kex->done = 0;
				kex_send_kexinit(xxx_kex);
			}
		}
		process_input(readset);
		if (connection_closed)
			break;
		process_output(writeset);
	}
	collect_children();

	if (readset)
		xfree(readset);
	if (writeset)
		xfree(writeset);

	/* free all channels, no more reads and writes */
	channel_free_all();

	/* free remaining sessions, e.g. remove wtmp entries */
	session_destroy_all(NULL);
}
Пример #5
0
void
install_signal_handlers()
{
    int i;
    mysignal(SIGCHLD, &child_died);
    mysignal(SIGTSTP, &handle_sigTSTP);
#ifndef DEBUG          /* we want core dumps when debugging, no polite excuses! */
    for (i = 1; i<MAX_SIG; i++)
        if (signals_program_error(i))
            mysignal(i, &handle_program_error_signal); /* make polite excuse */
#endif
    mysignal(SIGALRM, &handle_sigALRM);
    for (i = 1;  signals_to_be_passed_on[i]; i++) {
        assert(!signals_program_error(signals_to_be_passed_on[i]));
        mysignal(signals_to_be_passed_on[i], &pass_on_signal);
    }
    signal_handlers_were_installed = TRUE;
}
Пример #6
0
/* TODO: Perhaps change this one and intr_handler to something better */
void float_handler(int UNUSED(sig))
{
	mysignal (SIGFPE, float_handler);

	if (float_exn == Field(global_data, SYS__EXN_FAIL)) {
		failwith("floating point error");
	} else {
		raiseprimitive0(float_exn);
	}
}
Пример #7
0
sighandler_return_type float_handler(int sig)
{
#ifndef BSD_SIGNALS
  mysignal (SIGFPE, float_handler);
#endif
  if (float_exn == Field(global_data, SYS__EXN_FAIL))
    failwith("floating point error");
  else
    raiseprimitive0(float_exn);
}
Пример #8
0
MyWidget::MyWidget()
{
  connect( this, SIGNAL( mysignal() ), this, SLOT(myslot()) );
  // NOTE: DO NOT include the name of the paramter when using signals/slots with parameters.
  // It will compile, but give you "undefined signal" errors at runtime.
  // I.e. use
  // connect( this, SIGNAL( mysignal(QVector<double>) ), this, SLOT(myslot(QVector<double>)) );
  // instead of
  // connect( this, SIGNAL( mysignal(QVector<double> coord) ), this, SLOT(myslot(QVector<double> coord)) );
}
Пример #9
0
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
	int save_errno = errno;
	child_terminated = 1;
#ifndef _UNICOS
	mysignal(SIGCHLD, sigchld_handler);
#endif
	notify_parent();
	errno = save_errno;
}
Пример #10
0
sighandler_return_type intr_handler(int sig)
{
#ifndef BSD_SIGNALS
  mysignal (SIGINT, intr_handler);
#endif
#ifndef WIN32
  signal_handler = raise_break_exn;
  signal_number = 0;
  execute_signal();
#else
  sigint_pending = 1;
#endif
}
Пример #11
0
void intr_handler(int UNUSED(sig))
{
	mysignal (SIGINT, intr_handler);
	/* sigint_pending = 1; TODO: Where did this come from? */
}
Пример #12
0
/*
 * Receive a file.
 */
static void recvtftp(struct testcase *test, struct formats *pf)
{
  ssize_t n, size;
  recvblock = 0;
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, timer);
#endif
  rdp = w_init();
  rap = (struct tftphdr *)ackbuf;
  do {
    timeout = 0;
    rap->th_opcode = htons((u_short)opcode_ACK);
    rap->th_block = htons((u_short)recvblock);
    recvblock++;
#ifdef HAVE_SIGSETJMP
    (void) sigsetjmp(timeoutbuf, 1);
#endif
send_ack:
    if (swrite(peer, ackbuf, 4) != 4) {
      logmsg("write: fail\n");
      goto abort;
    }
    write_behind(test, pf->f_convert);
    for ( ; ; ) {
#ifdef HAVE_ALARM
      alarm(rexmtval);
#endif
      n = sread(peer, rdp, PKTSIZE);
#ifdef HAVE_ALARM
      alarm(0);
#endif
      if (n < 0) {                       /* really? */
        logmsg("read: fail\n");
        goto abort;
      }
      rdp->th_opcode = ntohs((u_short)rdp->th_opcode);
      rdp->th_block = ntohs((u_short)rdp->th_block);
      if (rdp->th_opcode == opcode_ERROR)
        goto abort;
      if (rdp->th_opcode == opcode_DATA) {
        if (rdp->th_block == recvblock) {
          break;                         /* normal */
        }
        /* Re-synchronize with the other side */
        (void) synchnet(peer);
        if (rdp->th_block == (recvblock-1))
          goto send_ack;                 /* rexmit */
      }
    }

    size = writeit(test, &rdp, (int)(n - 4), pf->f_convert);
    if (size != (n-4)) {                 /* ahem */
      if (size < 0)
        nak(ERRNO + 100);
      else
        nak(ENOSPACE);
      goto abort;
    }
  } while (size == SEGSIZE);
  write_behind(test, pf->f_convert);

  rap->th_opcode = htons((u_short)opcode_ACK);  /* send the "final" ack */
  rap->th_block = htons((u_short)recvblock);
  (void) swrite(peer, ackbuf, 4);
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, justtimeout);        /* just abort read on timeout */
  alarm(rexmtval);
#endif
  n = sread(peer, buf, sizeof(buf));     /* normally times out and quits */
#ifdef HAVE_ALARM
  alarm(0);
#endif
  if (n >= 4 &&                          /* if read some data */
      rdp->th_opcode == opcode_DATA &&   /* and got a data block */
      recvblock == rdp->th_block) {      /* then my last ack was lost */
    (void) swrite(peer, ackbuf, 4);      /* resend final ack */
  }
abort:
  return;
}
Пример #13
0
/*
 * Send the requested file.
 */
static void sendtftp(struct testcase *test, struct formats *pf)
{
  int size;
  ssize_t n;
  sendblock = 1;
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, timer);
#endif
  sdp = r_init();
  sap = (struct tftphdr *)ackbuf;
  do {
    size = readit(test, &sdp, pf->f_convert);
    if (size < 0) {
      nak(ERRNO + 100);
      return;
    }
    sdp->th_opcode = htons((u_short)opcode_DATA);
    sdp->th_block = htons((u_short)sendblock);
    timeout = 0;
#ifdef HAVE_SIGSETJMP
    (void) sigsetjmp(timeoutbuf, 1);
#endif
    send_data:
    if (swrite(peer, sdp, size + 4) != size + 4) {
      logmsg("write");
      return;
    }
    read_ahead(test, pf->f_convert);
    for ( ; ; ) {
#ifdef HAVE_ALARM
      alarm(rexmtval);        /* read the ack */
#endif
      n = sread(peer, ackbuf, sizeof (ackbuf));
#ifdef HAVE_ALARM
      alarm(0);
#endif
      if (n < 0) {
        logmsg("read: fail");
        return;
      }
      sap->th_opcode = ntohs((u_short)sap->th_opcode);
      sap->th_block = ntohs((u_short)sap->th_block);

      if (sap->th_opcode == opcode_ERROR) {
        logmsg("got ERROR");
        return;
      }

      if (sap->th_opcode == opcode_ACK) {
        if (sap->th_block == sendblock) {
          break;
        }
        /* Re-synchronize with the other side */
        (void) synchnet(peer);
        if (sap->th_block == (sendblock-1)) {
          goto send_data;
        }
      }

    }
    sendblock++;
  } while (size == SEGSIZE);
}
Пример #14
0
void
server_loop2(Authctxt *authctxt)
{
    fd_set *readset = NULL, *writeset = NULL;
    int rekeying = 0, max_fd, nalloc = 0;
    double start_time, total_time;

    debug("Entering interactive session for SSH2.");
    start_time = get_current_time();

    mysignal(SIGCHLD, sigchld_handler);
    child_terminated = 0;
    connection_in = packet_get_connection_in();
    connection_out = packet_get_connection_out();

    if (!use_privsep) {
        signal(SIGTERM, sigterm_handler);
        signal(SIGINT, sigterm_handler);
        signal(SIGQUIT, sigterm_handler);
    }

    notify_setup();

    max_fd = MAX(connection_in, connection_out);
    max_fd = MAX(max_fd, notify_pipe[0]);

    server_init_dispatch();

    for (;;) {
        process_buffered_input_packets();

        rekeying = (xxx_kex != NULL && !xxx_kex->done);

        if (!rekeying && packet_not_very_much_data_to_write())
            channel_output_poll();
        wait_until_can_do_something(&readset, &writeset, &max_fd,
                                    &nalloc, 0);

        if (received_sigterm) {
            logit("Exiting on signal %d", received_sigterm);
            /* Clean up sessions, utmp, etc. */
            cleanup_exit(255);
        }

        collect_children();
        if (!rekeying) {
            channel_after_select(readset, writeset);
            if (packet_need_rekeying()) {
                debug("need rekeying");
                xxx_kex->done = 0;
                kex_send_kexinit(xxx_kex);
            }
        }
        process_input(readset);
        if (connection_closed)
            break;
        process_output(writeset);
    }
    collect_children();

    if (readset)
        xfree(readset);
    if (writeset)
        xfree(writeset);

    /* free all channels, no more reads and writes */
    channel_free_all();

    /* free remaining sessions, e.g. remove wtmp entries */
    session_destroy_all(NULL);
    total_time = get_current_time() - start_time;
    logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
          get_remote_ipaddr(), get_remote_port(),
          stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time,
          fdout_bytes / total_time);
}
Пример #15
0
static void init_float_handler(void)
{
  mysignal(SIGFPE, float_handler);
}
Пример #16
0
void
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
{
	int fd;
#ifdef USE_VHANGUP
	void *old;
#endif /* USE_VHANGUP */

#ifdef _CRAY
	if (setsid() < 0)
		error("setsid: %.100s", strerror(errno));

	fd = open(ttyname, O_RDWR|O_NOCTTY);
	if (fd != -1) {
		mysignal(SIGHUP, SIG_IGN);
		ioctl(fd, TCVHUP, (char *)NULL);
		mysignal(SIGHUP, SIG_DFL);
		setpgid(0, 0);
		close(fd);
	} else {
		error("Failed to disconnect from controlling tty.");
	}

	debug("Setting controlling tty using TCSETCTTY.");
	ioctl(*ttyfd, TCSETCTTY, NULL);
	fd = open("/dev/tty", O_RDWR);
	if (fd < 0)
		error("%.100s: %.100s", ttyname, strerror(errno));
	close(*ttyfd);
       	*ttyfd = fd;
#else /* _CRAY */

	/* First disconnect from the old controlling tty. */
#ifdef TIOCNOTTY
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		(void) ioctl(fd, TIOCNOTTY, NULL);
		close(fd);
	}
#endif /* TIOCNOTTY */
	if (setsid() < 0)
		error("setsid: %.100s", strerror(errno));

	/*
	 * Verify that we are successfully disconnected from the controlling
	 * tty.
	 */
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		error("Failed to disconnect from controlling tty.");
		close(fd);
	}
	/* Make it our controlling tty. */
#ifdef TIOCSCTTY
	debug("Setting controlling tty using TIOCSCTTY.");
	if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0)
		error("ioctl(TIOCSCTTY): %.100s", strerror(errno));
#endif /* TIOCSCTTY */
#ifdef HAVE_NEWS4
	if (setpgrp(0,0) < 0)
		error("SETPGRP %s",strerror(errno));
#endif /* HAVE_NEWS4 */
#ifdef USE_VHANGUP
	old = mysignal(SIGHUP, SIG_IGN);
	vhangup();
	mysignal(SIGHUP, old);
#endif /* USE_VHANGUP */
	fd = open(ttyname, O_RDWR);
	if (fd < 0) {
		error("%.100s: %.100s", ttyname, strerror(errno));
	} else {
#ifdef USE_VHANGUP
		close(*ttyfd);
		*ttyfd = fd;
#else /* USE_VHANGUP */
		close(fd);
#endif /* USE_VHANGUP */
	}
	/* Verify that we now have a controlling tty. */
	fd = open(_PATH_TTY, O_WRONLY);
	if (fd < 0)
		error("open /dev/tty failed - could not set controlling tty: %.100s",
		    strerror(errno));
	else {
		close(fd);
	}
#endif /* _CRAY */
}
Пример #17
0
void
seed_rng(void)
{
#ifndef OPENSSL_PRNG_ONLY
    int devnull;
    int p[2];
    pid_t pid;
    int ret;
    unsigned char buf[RANDOM_SEED_SIZE];
    mysig_t old_sigchld;

    if (RAND_status() == 1) {
        debug3("RNG is ready, skipping seeding");
        return;
    }

    debug3("Seeding PRNG from %s", SSH_RAND_HELPER);

    if ((devnull = open("/dev/null", O_RDWR)) == -1)
        fatal("Couldn't open /dev/null: %s", strerror(errno));
    if (pipe(p) == -1)
        fatal("pipe: %s", strerror(errno));

    old_sigchld = mysignal(SIGCHLD, SIG_DFL);
    if ((pid = fork()) == -1)
        fatal("Couldn't fork: %s", strerror(errno));
    if (pid == 0) {
        dup2(devnull, STDIN_FILENO);
        dup2(p[1], STDOUT_FILENO);
        /* Keep stderr open for errors */
        close(p[0]);
        close(p[1]);
        close(devnull);

        if (original_uid != original_euid &&
                ( seteuid(getuid()) == -1 ||
                  setuid(original_uid) == -1) ) {
            fprintf(stderr, "(rand child) setuid(%d): %s\n",
                    original_uid, strerror(errno));
            _exit(1);
        }

        execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
        fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
                SSH_RAND_HELPER, strerror(errno));
        _exit(1);
    }

    close(devnull);
    close(p[1]);

    memset(buf, '\0', sizeof(buf));
    ret = atomicio(read, p[0], buf, sizeof(buf));
    if (ret == -1)
        fatal("Couldn't read from ssh-rand-helper: %s",
              strerror(errno));
    if (ret != sizeof(buf))
        fatal("ssh-rand-helper child produced insufficient data");

    close(p[0]);

    if (waitpid(pid, &ret, 0) == -1)
        fatal("Couldn't wait for ssh-rand-helper completion: %s",
              strerror(errno));
    mysignal(SIGCHLD, old_sigchld);

    /* We don't mind if the child exits upon a SIGPIPE */
    if (!WIFEXITED(ret) &&
            (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE))
        fatal("ssh-rand-helper terminated abnormally");
    if (WEXITSTATUS(ret) != 0)
        fatal("ssh-rand-helper exit with exit status %d", ret);

    RAND_add(buf, sizeof(buf), sizeof(buf));
    memset(buf, '\0', sizeof(buf));

#endif /* OPENSSL_PRNG_ONLY */
    if (RAND_status() != 1)
        fatal("PRNG is not seeded");
}
Пример #18
0
static void uninstall_signal_handlers() {
    int i;
    for(i=1; i<MAX_SIG; i++)
        mysignal(i, SIG_DFL);
    signal_handlers_were_installed = FALSE;
}
Пример #19
0
/*
 * Performs the interactive session.  This handles data transmission between
 * the client and the program.  Note that the notion of stdin, stdout, and
 * stderr in this function is sort of reversed: this function writes to
 * stdin (of the child program), and reads from stdout and stderr (of the
 * child program).
 */
void
server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
{
	fd_set *readset = NULL, *writeset = NULL;
	int max_fd = 0;
	u_int nalloc = 0;
	int wait_status;	/* Status returned by wait(). */
	pid_t wait_pid;		/* pid returned by wait(). */
	int waiting_termination = 0;	/* Have displayed waiting close message. */
	u_int64_t max_time_milliseconds;
	u_int previous_stdout_buffer_bytes;
	u_int stdout_buffer_bytes;
	int type;

	debug("Entering interactive session.");

	/* Initialize the SIGCHLD kludge. */
	child_terminated = 0;
	mysignal(SIGCHLD, sigchld_handler);

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	/* Initialize our global variables. */
	fdin = fdin_arg;
	fdout = fdout_arg;
	fderr = fderr_arg;

	/* nonblocking IO */
	set_nonblock(fdin);
	set_nonblock(fdout);
	/* we don't have stderr for interactive terminal sessions, see below */
	if (fderr != -1)
		set_nonblock(fderr);

	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
		fdin_is_tty = 1;

	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	previous_stdout_buffer_bytes = 0;

	/* Set approximate I/O buffer size. */
	if (packet_is_interactive())
		buffer_high = 4096;
	else
		buffer_high = 64 * 1024;

#if 0
	/* Initialize max_fd to the maximum of the known file descriptors. */
	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, fdin);
	max_fd = MAX(max_fd, fdout);
	if (fderr != -1)
		max_fd = MAX(max_fd, fderr);
#endif

	/* Initialize Initialize buffers. */
	buffer_init(&stdin_buffer);
	buffer_init(&stdout_buffer);
	buffer_init(&stderr_buffer);

	/*
	 * If we have no separate fderr (which is the case when we have a pty
	 * - there we cannot make difference between data sent to stdout and
	 * stderr), indicate that we have seen an EOF from stderr.  This way
	 * we don't need to check the descriptor everywhere.
	 */
	if (fderr == -1)
		fderr_eof = 1;

	server_init_dispatch();

	/* Main loop of the server for the interactive session mode. */
	for (;;) {

		/* Process buffered packets from the client. */
		process_buffered_input_packets();

		/*
		 * If we have received eof, and there is no more pending
		 * input data, cause a real eof by closing fdin.
		 */
		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
			if (fdin != fdout)
				close(fdin);
			else
				shutdown(fdin, SHUT_WR); /* We will no longer send. */
			fdin = -1;
		}
		/* Make packets from buffered stderr data to send to the client. */
		make_packets_from_stderr_data();

		/*
		 * Make packets from buffered stdout data to send to the
		 * client. If there is very little to send, this arranges to
		 * not send them now, but to wait a short while to see if we
		 * are getting more data. This is necessary, as some systems
		 * wake up readers from a pty after each separate character.
		 */
		max_time_milliseconds = 0;
		stdout_buffer_bytes = buffer_len(&stdout_buffer);
		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
			/* try again after a while */
			max_time_milliseconds = 10;
		} else {
			/* Send it now. */
			make_packets_from_stdout_data();
		}
		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);

		/* Send channel data to the client. */
		if (packet_not_very_much_data_to_write())
			channel_output_poll();

		/*
		 * Bail out of the loop if the program has closed its output
		 * descriptors, and we have no more data to send to the
		 * client, and there is no pending buffered data.
		 */
		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
			if (!channel_still_open())
				break;
			if (!waiting_termination) {
				const char *s = "Waiting for forwarded connections to terminate... (press ~& to background)\r\n";
				char *cp;
				waiting_termination = 1;
				buffer_append(&stderr_buffer, s, strlen(s));

				/* Display list of open channels. */
				cp = channel_open_message();
				buffer_append(&stderr_buffer, cp, strlen(cp));
				free(cp);
			}
		}
		max_fd = MAX(connection_in, connection_out);
		max_fd = MAX(max_fd, fdin);
		max_fd = MAX(max_fd, fdout);
		max_fd = MAX(max_fd, fderr);
		max_fd = MAX(max_fd, notify_pipe[0]);

		/* Sleep in select() until we can do something. */
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, max_time_milliseconds);

		if (received_sigterm) {
			logit("Exiting on signal %d", (int)received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		/* Process any channel events. */
		channel_after_select(readset, writeset);

		/* Process input from the client and from program stdout/stderr. */
		process_input(readset);

		/* Process output to the client and to program stdin. */
		process_output(writeset);
	}
	free(readset);
	free(writeset);

	/* Cleanup and termination code. */

	/* Wait until all output has been sent to the client. */
	drain_output();

	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);

	/* Free and clear the buffers. */
	buffer_free(&stdin_buffer);
	buffer_free(&stdout_buffer);
	buffer_free(&stderr_buffer);

	/* Close the file descriptors. */
	if (fdout != -1)
		close(fdout);
	fdout = -1;
	fdout_eof = 1;
	if (fderr != -1)
		close(fderr);
	fderr = -1;
	fderr_eof = 1;
	if (fdin != -1)
		close(fdin);
	fdin = -1;

	channel_free_all();

	/* We no longer want our SIGCHLD handler to be called. */
	mysignal(SIGCHLD, SIG_DFL);

	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
		if (errno != EINTR)
			packet_disconnect("wait: %.100s", strerror(errno));
	if (wait_pid != pid)
		error("Strange, wait returned pid %ld, expected %ld",
		    (long)wait_pid, (long)pid);

	/* Check if it exited normally. */
	if (WIFEXITED(wait_status)) {
		/* Yes, normal exit.  Get exit status and send it to the client. */
		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
		packet_start(SSH_SMSG_EXITSTATUS);
		packet_put_int(WEXITSTATUS(wait_status));
		packet_send();
		packet_write_wait();

		/*
		 * Wait for exit confirmation.  Note that there might be
		 * other packets coming before it; however, the program has
		 * already died so we just ignore them.  The client is
		 * supposed to respond with the confirmation when it receives
		 * the exit status.
		 */
		do {
			type = packet_read();
		}
		while (type != SSH_CMSG_EXIT_CONFIRMATION);

		debug("Received exit confirmation.");
		return;
	}
	/* Check if the program terminated due to a signal. */
	if (WIFSIGNALED(wait_status))
		packet_disconnect("Command terminated on signal %d.",
				  WTERMSIG(wait_status));

	/* Some weird exit cause.  Just exit. */
	packet_disconnect("wait returned status %04x.", wait_status);
	/* NOTREACHED */
}
Пример #20
0
void main(void)
{
	if(mysignal(SIGQUIT,func)==SIG_ERR)
		err_sys("signal error");
	sleep(10);
}
Пример #21
0
/*
 * Send the requested file.
 */
static void sendtftp(struct testcase *test, struct formats *pf)
{
  int size;
  ssize_t n;
  /* These are volatile to live through a siglongjmp */
  volatile unsigned short sendblock; /* block count */
  struct tftphdr * volatile sdp = r_init(); /* data buffer */
  struct tftphdr * const sap = &ackbuf.hdr; /* ack buffer */

  sendblock = 1;
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, timer);
#endif
  do {
    size = readit(test, (struct tftphdr **)&sdp, pf->f_convert);
    if(size < 0) {
      nak(errno + 100);
      return;
    }
    sdp->th_opcode = htons((unsigned short)opcode_DATA);
    sdp->th_block = htons(sendblock);
    timeout = 0;
#ifdef HAVE_SIGSETJMP
    (void) sigsetjmp(timeoutbuf, 1);
#endif
    if(test->writedelay) {
      logmsg("Pausing %d seconds before %d bytes", test->writedelay,
             size);
      wait_ms(1000*test->writedelay);
    }

    send_data:
    if(swrite(peer, sdp, size + 4) != size + 4) {
      logmsg("write");
      return;
    }
    read_ahead(test, pf->f_convert);
    for(;;) {
#ifdef HAVE_ALARM
      alarm(rexmtval);        /* read the ack */
#endif
      n = sread(peer, &ackbuf.storage[0], sizeof(ackbuf.storage));
#ifdef HAVE_ALARM
      alarm(0);
#endif
      if(got_exit_signal)
        return;
      if(n < 0) {
        logmsg("read: fail");
        return;
      }
      sap->th_opcode = ntohs((unsigned short)sap->th_opcode);
      sap->th_block = ntohs(sap->th_block);

      if(sap->th_opcode == opcode_ERROR) {
        logmsg("got ERROR");
        return;
      }

      if(sap->th_opcode == opcode_ACK) {
        if(sap->th_block == sendblock) {
          break;
        }
        /* Re-synchronize with the other side */
        (void) synchnet(peer);
        if(sap->th_block == (sendblock-1)) {
          goto send_data;
        }
      }

    }
    sendblock++;
  } while(size == SEGSIZE);
}
Пример #22
0
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
{
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
	/* openpty(3) exists in OSF/1 and some other os'es */
	char *name;
	int i;

	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
	if (i < 0) {
		error("openpty: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ttyfd);
	if (!name)
		fatal("openpty returns device for which ttyname fails.");

	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
	return 1;
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
	if (slave == NULL) {
		error("_getpty: %.100s", strerror(errno));
		return 0;
	}
	strlcpy(namebuf, slave, namebuflen);
	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.200s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	mysig_t old_signal;

	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
	if (ptm < 0) {
		error("/dev/ptmx: %.100s", strerror(errno));
		return 0;
	}
	old_signal = mysignal(SIGCHLD, SIG_DFL);
	if (grantpt(ptm) < 0) {
		error("grantpt: %.100s", strerror(errno));
		return 0;
	}
	mysignal(SIGCHLD, old_signal);
	if (unlockpt(ptm) < 0) {
		error("unlockpt: %.100s", strerror(errno));
		return 0;
	}
	pts = ptsname(ptm);
	if (pts == NULL)
		error("Slave pty side name could not be obtained.");
	strlcpy(namebuf, pts, namebuflen);
	*ptyfd = ptm;

	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.100s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
#ifndef HAVE_CYGWIN
	/*
	 * Push the appropriate streams modules, as described in Solaris pts(7).
	 * HP-UX pts(7) doesn't have ttcompat module.
	 */
	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
		error("ioctl I_PUSH ptem: %.100s", strerror(errno));
	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
		error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
#ifndef __hpux
	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
		error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
#endif
#endif
	return 1;
#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
	/* AIX-style pty code. */
	const char *name;

	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
	if (*ptyfd < 0) {
		error("Could not open /dev/ptc: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ptyfd);
	if (!name)
		fatal("Open of /dev/ptc returns device for which ttyname fails.");
	strlcpy(namebuf, name, namebuflen);
	*ttyfd = open(name, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("Could not open pty slave side %.100s: %.100s",
		    name, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE_DEV_PTS_AND_PTC */
#ifdef _CRAY
	char buf[64];
  	int i;
  	int highpty;

#ifdef _SC_CRAY_NPTY
	highpty = sysconf(_SC_CRAY_NPTY);
	if (highpty == -1)
		highpty = 128;
#else
	highpty = 128;
#endif

	for (i = 0; i < highpty; i++) {
		snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
		*ptyfd = open(buf, O_RDWR|O_NOCTTY);
		if (*ptyfd < 0)
			continue;
		snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		return 1;
	}
	return 0;
#else
	/* BSD-style pty code. */
	char buf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
			 ptyminors[i % num_minors]);
		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
		if (*ptyfd < 0) {
			/* Try SCO style naming */
			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
			if (*ptyfd < 0)
				continue;
		}

		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*ptyfd, &tio) < 0)
			log("Getting tty modes for pty failed: %.100s", strerror(errno));
		else {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;

			/* Set the new modes for the terminal. */
			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
				log("Setting tty modes for pty failed: %.100s", strerror(errno));
		}

		return 1;
	}
	return 0;
#endif /* CRAY */
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */
}
Пример #23
0
/*
 * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
 * listening either on 'tcp_port', or via Unix domain socket at *
 * 'socket_path'.
 * Either a non-zero tcp_port or a non-null socket_path must be
 * supplied.
 * Returns 0 on success, -1 on error
 */
int
get_random_bytes_prngd(unsigned char *buf, int len,
    unsigned short tcp_port, char *socket_path)
{
	int fd, addr_len, rval, errors;
	u_char msg[2];
	struct sockaddr_storage addr;
	struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
	struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
	mysig_t old_sigpipe;

	/* Sanity checks */
	if (socket_path == NULL && tcp_port == 0)
		fatal("You must specify a port or a socket");
	if (socket_path != NULL &&
	    strlen(socket_path) >= sizeof(addr_un->sun_path))
		fatal("Random pool path is too long");
	if (len <= 0 || len > 255)
		fatal("Too many bytes (%d) to read from PRNGD", len);

	memset(&addr, '\0', sizeof(addr));

	if (tcp_port != 0) {
		addr_in->sin_family = AF_INET;
		addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		addr_in->sin_port = htons(tcp_port);
		addr_len = sizeof(*addr_in);
	} else {
		addr_un->sun_family = AF_UNIX;
		strlcpy(addr_un->sun_path, socket_path,
		    sizeof(addr_un->sun_path));
		addr_len = offsetof(struct sockaddr_un, sun_path) +
		    strlen(socket_path) + 1;
	}

	old_sigpipe = mysignal(SIGPIPE, SIG_IGN);

	errors = 0;
	rval = -1;
reopen:
	fd = socket(addr.ss_family, SOCK_STREAM, 0);
	if (fd == -1) {
		error("Couldn't create socket: %s", strerror(errno));
		goto done;
	}

	if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
		if (tcp_port != 0) {
			error("Couldn't connect to PRNGD port %d: %s",
			    tcp_port, strerror(errno));
		} else {
			error("Couldn't connect to PRNGD socket \"%s\": %s",
			    addr_un->sun_path, strerror(errno));
		}
		goto done;
	}

	/* Send blocking read request to PRNGD */
	msg[0] = 0x02;
	msg[1] = len;

	if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't write to PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	if (atomicio(read, fd, buf, len) != (size_t)len) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't read from PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	rval = 0;
done:
	mysignal(SIGPIPE, old_sigpipe);
	if (fd != -1)
		close(fd);
	return rval;
}
Пример #24
0
void
ignore_sigchld()
{
    mysignal(SIGCHLD, &do_nothing);
}
Пример #25
0
void
pty_make_controlling_tty(int *ttyfd, const char *tty_name)
{
	int fd;
#ifdef USE_VHANGUP
	void *old;
#endif /* USE_VHANGUP */

	/* Solaris has a problem with TIOCNOTTY for a bg process, so
	 * we disable the signal which would STOP the process - matt */
	signal(SIGTTOU, SIG_IGN);

	/* First disconnect from the old controlling tty. */
#ifdef TIOCNOTTY
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		(void) ioctl(fd, TIOCNOTTY, NULL);
		close(fd);
	}
#endif /* TIOCNOTTY */
	if (setsid() < 0) {
		dropbear_log(LOG_ERR,
			"setsid: %.100s", strerror(errno));
	}

	/*
	 * Verify that we are successfully disconnected from the controlling
	 * tty.
	 */
	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
	if (fd >= 0) {
		dropbear_log(LOG_ERR,
				"Failed to disconnect from controlling tty.\n");
		close(fd);
	}
	/* Make it our controlling tty. */
#ifdef TIOCSCTTY
	if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) {
		dropbear_log(LOG_ERR,
			"ioctl(TIOCSCTTY): %.100s", strerror(errno));
	}
#endif /* TIOCSCTTY */
#ifdef HAVE_NEWS4
	if (setpgrp(0,0) < 0) {
		dropbear_log(LOG_ERR,
			error("SETPGRP %s",strerror(errno)));
	}
#endif /* HAVE_NEWS4 */
#ifdef USE_VHANGUP
	old = mysignal(SIGHUP, SIG_IGN);
	vhangup();
	mysignal(SIGHUP, old);
#endif /* USE_VHANGUP */
	fd = open(tty_name, O_RDWR);
	if (fd < 0) {
		dropbear_log(LOG_ERR,
			"%.100s: %.100s", tty_name, strerror(errno));
	} else {
#ifdef USE_VHANGUP
		close(*ttyfd);
		*ttyfd = fd;
#else /* USE_VHANGUP */
		close(fd);
#endif /* USE_VHANGUP */
	}
	/* Verify that we now have a controlling tty. */
	fd = open(_PATH_TTY, O_WRONLY);
	if (fd < 0) {
		dropbear_log(LOG_ERR,
			"open /dev/tty failed - could not set controlling tty: %.100s",
		    strerror(errno));
	} else {
		close(fd);
	}
}
Пример #26
0
/*
 *----------------------------------------------------------------------
 *
 * Main -
 *
 *----------------------------------------------------------------------
 */
int main(int argc, char *argv[])
{
   int ret;
   int childpid;
   int opt;
   FILE *pidf;
   sigset_t mask;

   int listener_fd;
   int client_fd;
   struct sockaddr_storage client_addr;
   socklen_t client_addr_len;

   time_t	cert_mtime = 0;
   edg_wll_GssStatus	gss_stat;
   edg_wll_GssCred	cred = NULL;


   setlinebuf(stdout);
   setlinebuf(stderr);

   /* welcome */
   fprintf(stdout,"\
This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n");

   /* get arguments */
   while ((opt = getopt_long(argc,argv,
	"h"  /* help */
	"V"  /* version */
	"d"  /* debug */
	"p:" /* port */
	"f:" /* file prefix */
	"c:" /* certificate */
	"k:" /* key */
	"C:" /* CA dir */
	"s:" /* socket */
	"i:" /* pidfile */
	"x"  /* noAuth */
	"y"  /* noIPC */
	"z",  /* noParse */
	long_options, (int *) 0)) != EOF) {

	switch (opt) {
		case 'V': fprintf(stdout,"%s:\t%s\n",argv[0],rcsid); exit(0);
		case 'd': debug = 1; break;
		case 'p': port = atoi(optarg); break;
		case 'f': prefix = optarg; break;
		case 'c': cert_file = optarg; break;
		case 'k': key_file = optarg; break;
		case 'C': CAcert_dir = optarg; break;
		case 's': socket_path = optarg; break;
		case 'i': pidfile = optarg; break;
		case 'x': noAuth = 1; break;
		case 'y': noIPC = 1; break;
		case 'z': noParse = 1; break;
		case 'h':
		default:
			usage(argv[0]); exit(0);
	}
   }
   if (glite_common_log_init()) {
	fprintf(stderr,"glite_common_log_init() failed, exiting.");
	exit(1);
   }
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Initializing...\n");

   /* check noParse */
   if (noParse) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [yes]\n");
   }

   /* check noIPC */
   if (noIPC) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [yes]\n");
   }

   /* check prefix correctness */
   if (strlen(prefix) > FILENAME_MAX - 34) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Too long prefix (%s) for file names, would not be able to write to log files. Exiting.\n",prefix);
	exit(1);
   }
   /* TODO: check for write permisions */
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Messages will be stored with the filename prefix \"%s\".\n",prefix);

   if (CAcert_dir)
	setenv("X509_CERT_DIR", CAcert_dir, 1);

#ifdef LB_PERF
   glite_wll_perftest_init(NULL, NULL, NULL, NULL, 0);
#endif
 
   /* daemonize */
   if (debug) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [yes]\n");
	if (daemon(0,0) < 0) {
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to run as daemon. Exiting.\n");
		glite_common_log_SYS_ERROR("daemon");
		exit(1);
	}
   }

   edg_wll_gss_initialize();
   ret = edg_wll_gss_watch_creds(cert_file,&cert_mtime);
   if (ret < 0)
   	glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n");
   /* XXX DK: support noAuth */
   ret = edg_wll_gss_acquire_cred(cert_file, key_file, GSS_C_ACCEPT, &cred, &gss_stat);
   if (ret) {
	/* XXX DK: call edg_wll_gss_get_error() */
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to get GSI credentials. Exiting.\n");
	exit(1);
   }

   if (cred->name!=NULL) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running with certificate: %s\n",cred->name);
   } else if (noAuth) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running without certificate\n");
   }

   /* initialize signal handling */
#if 1
   if(edg_wll_gss_set_signal_handler(SIGUSR1, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGUSR2, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGPIPE, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGHUP, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGINT, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGQUIT, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGTERM, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGCHLD, handle_signal) < 0) { perror("signal"); exit(1); }
#else
   if (mysignal(SIGUSR1, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGUSR2, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGPIPE, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGHUP,  handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGINT,  handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGQUIT, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGTERM, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGCHLD, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }

   sigemptyset(&mask);
   sigaddset(&mask, SIGUSR1);
   sigaddset(&mask, SIGUSR2);
   sigaddset(&mask, SIGPIPE);
   sigaddset(&mask, SIGHUP);
   sigaddset(&mask, SIGINT);
   sigaddset(&mask, SIGQUIT);
   sigaddset(&mask, SIGTERM);
   sigaddset(&mask, SIGCHLD);
   sigprocmask(SIG_UNBLOCK, &mask, NULL);
#endif

   /* do listen */
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Listening on port %d\n",port);
   listener_fd = do_listen(port);
   if (listener_fd == -1) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to listen on port %d\n",port);
	edg_wll_gss_release_cred(&cred, NULL);
	exit(-1);
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Listener's socket descriptor is '%d'\n",listener_fd);
   }

   client_addr_len = sizeof(client_addr);
   bzero((char *) &client_addr, client_addr_len);

/* just try it before deamonizing to be able to complain aloud */
  if (!(pidf = fopen(pidfile,"w"))) {
        perror(pidfile);
        exit(-1);
  }
  fclose(pidf);


  pidf = fopen(pidfile,"w"); assert(pidf); /* XXX */
  fprintf(pidf,"%d\n",getpid());
  fclose(pidf);

  umask(S_IRWXG | S_IRWXO);

   /*
    * Main loop
    */
   while (1) {
        int opt,my_errno;
	fd_set fds;
	struct timeval tv;


	glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_INFO,"Accepting incomming connections...\n");
	client_fd = 0;
	while(0 == client_fd) {
		FD_ZERO(&fds);
		FD_SET(listener_fd, &fds);
		tv.tv_sec = 2;
		tv.tv_usec = 0;

		client_fd = select(listener_fd + 1, &fds, NULL, NULL, &tv);
		do_handle_signal();
		if(client_fd < 0) {
			glite_common_log_SYS_ERROR("select");
			client_fd = 0;
		}
	}
	client_fd = accept(listener_fd, (struct sockaddr *) &client_addr,
			&client_addr_len);
	my_errno = errno;
	if (client_fd < 0) {
		if (my_errno == EINTR) continue;
		close(listener_fd);
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_FATAL,"Failed to accept incomming connections\n");
		glite_common_log_SYS_ERROR("accept");
		edg_wll_gss_release_cred(&cred, NULL);
		exit(-1);
	} else {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Incomming connection on socket '%d'\n",client_fd);
	}

	opt = 0;
	if (setsockopt(client_fd,IPPROTO_TCP,TCP_CORK,(const void *) &opt,sizeof opt)) {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't reset TCP_CORK\n");
	}
	opt = 1;
	if (setsockopt(client_fd,IPPROTO_TCP,TCP_NODELAY,(const void *) &opt,sizeof opt)) {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't set TCP_NODELAY\n");
	}

	switch (edg_wll_gss_watch_creds(cert_file,&cert_mtime)) {
	edg_wll_GssCred newcred;
	case 0: break;
	case 1:
		ret = edg_wll_gss_acquire_cred(cert_file,key_file, GSS_C_ACCEPT, &newcred,&gss_stat);
		if (ret) {
			glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"Reloading credentials failed, continue with older\n");
		} else {
			glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"Reloading credentials succeeded\n");
			edg_wll_gss_release_cred(&cred, NULL);
			cred = newcred;
		}
		break;
	case -1:
		glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n");
		break;
	}

	/* FORK - change next line if fork() is not needed (for debugging for example) */
#if 1
	if ((childpid = fork()) < 0) {
		glite_common_log_SYS_ERROR("fork");
		if (client_fd) close(client_fd);
	}
	if (childpid == 0) {
		ret = doit(client_fd,cred,prefix,noIPC,noParse);
		if (client_fd) close(client_fd);
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Exiting.\n");
		exit(0);
	}
	if (childpid > 0) {
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Forked a new child with PID %d\n",childpid);
		if (client_fd) close(client_fd);
	}
#else
	ret = doit(client_fd,cred,prefix,noIPC,noParse);
	if (client_fd) close(client_fd);

#endif
    } /* while */

	if (listener_fd) close(listener_fd);
	edg_wll_gss_release_cred(&cred, NULL);
	exit(ret);
}
Пример #27
0
/*
 * Send the requested file.
 */
static void sendtftp(struct testcase *test, struct formats *pf)
{
  struct tftphdr *dp;
  struct tftphdr *ap;    /* ack packet */
  unsigned short block = 1;
  int size, n;
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, timer);
#endif
  dp = r_init();
  ap = (struct tftphdr *)ackbuf;
  do {
    size = readit(test, &dp, pf->f_convert);
    if (size < 0) {
      nak(errno + 100);
      return;
    }
    dp->th_opcode = htons((u_short)DATA);
    dp->th_block = htons((u_short)block);
    timeout = 0;
#ifdef HAVE_SIGSETJMP
    (void) sigsetjmp(timeoutbuf, 1);
#endif
    send_data:
    if (send(peer, dp, size + 4, 0) != size + 4) {
      logmsg("write\n");
      return;
    }
    read_ahead(test, pf->f_convert);
    for ( ; ; ) {
#ifdef HAVE_ALARM
      alarm(rexmtval);        /* read the ack */
#endif
      n = recv(peer, ackbuf, sizeof (ackbuf), 0);
#ifdef HAVE_ALARM
      alarm(0);
#endif
      if (n < 0) {
        logmsg("read: fail\n");
        return;
      }
      ap->th_opcode = ntohs((u_short)ap->th_opcode);
      ap->th_block = ntohs((u_short)ap->th_block);

      if (ap->th_opcode == ERROR) {
        logmsg("got ERROR");
        return;
      }

      if (ap->th_opcode == ACK) {
        if (ap->th_block == block) {
          break;
        }
        /* Re-synchronize with the other side */
        (void) synchnet(peer);
        if (ap->th_block == (block -1)) {
          goto send_data;
        }
      }

    }
    block++;
  } while (size == SEGSIZE);
}
Пример #28
0
int main(int argc, char **argv)
{
  struct ftio ftio;
  struct ftprof ftp;
  struct ftstat ftstat;
  struct ftstat_def *ftsd;
  struct ftver ftv;
  struct ftvar ftvar;
  struct ftset ftset;
  struct fts3rec_offsets fo;
  char *rec;
  const char *fname, *dname;
  uint32_t total_flows;
  int i, split, done;
  int usage_call;

  /* init fterr */
  fterr_setid(argv[0]);

  bzero(&ftv, sizeof ftv);
  bzero(&ftvar, sizeof ftvar);
  total_flows = 0;
  usage_call = 0;

  /* init var binding */
  if (ftvar_new(&ftvar) < 0)
    fterr_errx(1, "ftvar_new(): failed");

  fname = FT_PATH_CFG_STAT;
  dname = "default";

  /* configure signal handler */
  if (mysignal(SIGPIPE, sig_pipe) == SIG_ERR)
    fterr_err(1, "signal(SIGPIPE)");

  /* defaults + no compression */
  ftset_init(&ftset, 0);

  while ((i = getopt(argc, argv, "b:C:d:h?s:S:kz:v:")) != -1)

    switch (i) {

    case 'd': /* debug */
      debug = atoi(optarg);
      break;

    case 's': /* stat file name */
      fname = optarg;
      break;

    case 'S': /* stat definition name */
      dname = optarg;
      break;

    case 'v': /* variable */
      if (ftvar_pset(&ftvar, optarg) < 0)
        fterr_errx(1, "ftvar_pset(%s): failed", optarg);
      break;

    case 'h': /* help */
    case '?': 
      usage();
      ++usage_call;
      break;

    default:
      usage();
      exit(1);
      break;

    } /* switch */

  if (argc - optind)
    fterr_errx(1, "Extra arguments starting with %s.", argv[optind]);

  if (usage_call)
    exit(0);

  /* initialize and load stats config */
  if (ftstat_load(&ftstat, &ftvar, fname))
    fterr_errx(1, "ftstat_load(): failed");

  if (!(ftsd = ftstat_def_find(&ftstat, dname))) 
    fterr_errx(1, "ftstat_find_def(%s): failed", dname);

  /* input is stdin */
  if (ftio_init(&ftio, 0, FT_IO_FLAG_READ) < 0)
    fterr_errx(1, "ftio_init(): failed");

  ftio_get_ver(&ftio, &ftv);

  if (ftstat_def_test_xfields(ftsd, ftrec_xfield(&ftv)))
    fterr_errx(1, "Report definition references a field not in flow.");

  fts3rec_compute_offsets(&fo, &ftv);

  /* profile */
  ftprof_start (&ftp);

  if (ftstat_def_new(ftsd)) {
    fterr_errx(1, "ftstat_new(%s): failed.",ftsd->name);
  }

  while ((rec = ftio_read(&ftio))) {

    ++total_flows;

    done = 0;

    if ((split = ftstat_def_accum(ftsd, rec, &fo)) < 0) {
      fterr_errx(1, "ftstat_eval(%s): failed.",ftsd->name);
    }

    if (split) {

      if (ftstat_def_calc(ftsd)) {
        fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name);
      }

      if (ftstat_def_dump(&ftio, ftsd)) {
        fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name);
      }

      if (ftstat_def_reset(ftsd)) {
        fterr_errx(1, "ftstat_def_reset(%s): failed.",ftsd->name);
      }

      if ((split = ftstat_def_accum(ftsd, rec, &fo)) < 0) {
        fterr_errx(1, "ftstat_eval(%s): failed.",ftsd->name);
      }

      if (split == 1)
        fterr_errx(1, "ftstat_def_accum(): looping on split");

    } /* split */

  } /* while more flows */

  if (ftstat_def_calc(ftsd)) {
    fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name);
  }

  if (ftstat_def_dump(&ftio, ftsd)) {
    fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name);
  }

  if (ftstat_def_free(ftsd)) {
    fterr_errx(1, "ftstat_def_free(%s): failed.",ftsd->name);
  }

  if (ftio_close(&ftio) < 0)
    fterr_errx(1, "ftio_close(): failed");

  if (debug > 0) {
    ftprof_end (&ftp, total_flows);
    ftprof_print(&ftp, argv[0], stderr);
  }

  ftstat_free(&ftstat);

  ftvar_free(&ftvar);

  return 0;

} /* main */
Пример #29
0
void
server_loop2(Authctxt *authctxt)
{
	fd_set *readset = NULL, *writeset = NULL;
	int rekeying = 0, max_fd;
	u_int nalloc = 0;
	u_int64_t rekey_timeout_ms = 0;

	debug("Entering interactive session for SSH2.");

	mysignal(SIGCHLD, sigchld_handler);
	child_terminated = 0;
	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	notify_setup();

	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, notify_pipe[0]);

	server_init_dispatch();
	for (;;) {
		process_buffered_input_packets();

		rekeying = (xxx_kex != NULL && !xxx_kex->done);

		if (!rekeying && packet_not_very_much_data_to_write())
			channel_output_poll();
		if (options.rekey_interval > 0 && compat20 && !rekeying)
			rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
		else
			rekey_timeout_ms = 0;

		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, rekey_timeout_ms);

		if (received_sigterm) {
			logit("Exiting on signal %d", (int)received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		collect_children();
		if (!rekeying) {
			channel_after_select(readset, writeset);
			if (packet_need_rekeying()) {
				debug("need rekeying");
				xxx_kex->done = 0;
				kex_send_kexinit(xxx_kex);
			}
		}
		process_input(readset);
		if (connection_closed)
			break;
		process_output(writeset);
	}
	collect_children();

	free(readset);
	free(writeset);

	/* free all channels, no more reads and writes */
	channel_free_all();

	/* free remaining sessions, e.g. remove wtmp entries */
	session_destroy_all(NULL);
}
Пример #30
0
/*
 * Receive a file.
 */
static void recvtftp(struct testcase *test, struct formats *pf)
{
  struct tftphdr *dp;
  struct tftphdr *ap;    /* ack buffer */
  unsigned short block = 0;
  int n, size;
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, timer);
#endif
  dp = w_init();
  ap = (struct tftphdr *)ackbuf;
  do {
    timeout = 0;
    ap->th_opcode = htons((u_short)ACK);
    ap->th_block = htons((u_short)block);
    block++;
#ifdef HAVE_SIGSETJMP
    (void) sigsetjmp(timeoutbuf, 1);
#endif
send_ack:
    if (send(peer, ackbuf, 4, 0) != 4) {
      logmsg("write: fail\n");
      goto abort;
    }
    write_behind(test, pf->f_convert);
    for ( ; ; ) {
#ifdef HAVE_ALARM
      alarm(rexmtval);
#endif
      n = recv(peer, dp, PKTSIZE, 0);
#ifdef HAVE_ALARM
      alarm(0);
#endif
      if (n < 0) {                       /* really? */
        logmsg("read: fail\n");
        goto abort;
      }
      dp->th_opcode = ntohs((u_short)dp->th_opcode);
      dp->th_block = ntohs((u_short)dp->th_block);
      if (dp->th_opcode == ERROR)
        goto abort;
      if (dp->th_opcode == DATA) {
        if (dp->th_block == block) {
          break;                         /* normal */
        }
        /* Re-synchronize with the other side */
        (void) synchnet(peer);
        if (dp->th_block == (block-1))
          goto send_ack;                 /* rexmit */
      }
    }

    size = writeit(test, &dp, n - 4, pf->f_convert);
    if (size != (n-4)) {                 /* ahem */
      if (size < 0)
        nak(errno + 100);
      else
        nak(ENOSPACE);
      goto abort;
    }
  } while (size == SEGSIZE);
  write_behind(test, pf->f_convert);

  ap->th_opcode = htons((u_short)ACK);   /* send the "final" ack */
  ap->th_block = htons((u_short)(block));
  (void) send(peer, ackbuf, 4, 0);
#if defined(HAVE_ALARM) && defined(SIGALRM)
  mysignal(SIGALRM, justquit);           /* just quit on timeout */
  alarm(rexmtval);
#endif
  n = recv(peer, buf, sizeof (buf), 0);  /* normally times out and quits */
#ifdef HAVE_ALARM
  alarm(0);
#endif
  if (n >= 4 &&                          /* if read some data */
      dp->th_opcode == DATA &&           /* and got a data block */
      block == dp->th_block) {           /* then my last ack was lost */
    (void) send(peer, ackbuf, 4, 0);     /* resend final ack */
  }
abort:
  return;
}