示例#1
0
void ssh_stream_fd_request(SshFdStream sdata)
{
  unsigned int read_request, write_request;

  assert(!sdata->destroyed);

  if (sdata->read_has_failed)
    read_request = SSH_IO_READ;
  else
    read_request = 0;

  if (sdata->write_has_failed)
    write_request = SSH_IO_WRITE;
  else
    write_request = 0;

  if (sdata->readfd == sdata->writefd)
    {
      if (sdata->readfd >= 0)
        ssh_io_set_fd_request(sdata->readfd, read_request | write_request);
    }
  else
    {
      if (sdata->readfd >= 0)
          ssh_io_set_fd_request(sdata->readfd, read_request);
      if (sdata->writefd >= 0)
          ssh_io_set_fd_request(sdata->writefd, write_request);
    }
}
示例#2
0
/* Open interface to tls acceleration */
Boolean tls_accel_open(void (*rd_cb)(unsigned int, void *))
{
#ifdef __linux__
  const char *name = "/proc/quicksec/hwaccel";

  if (device_fd >= 0)
    return TRUE;

  /* Try to open the device. */
  device_fd = open(name, O_RDWR);
  device_rd_fd = open(name, O_RDWR);

  if (device_fd == -1 || device_rd_fd == -1)
    {
      SSH_DEBUG(1 , ("Hardware accelerator n/a"));
      tls_accel_close();
      return FALSE;
    }

  registered = ssh_io_register_fd(device_rd_fd, rd_cb, NULL);
  if (!registered)
    {
      SSH_DEBUG(SSH_D_FAIL, ("ssh_io_register_fd failed"));
      tls_accel_close();
      return FALSE;
    }
  ssh_io_set_fd_request(device_rd_fd, SSH_IO_READ);

  return TRUE;
#else
  return FALSE;
#endif /* __linux__ */
}
示例#3
0
SshLocalListener ssh_local_make_listener(const char *path,
        SshLocalCallback callback,
        void *context)
{
    int sock;
    struct sockaddr_un sunaddr;
    SshLocalListener listener;

    /* Create a socket for the listener. */
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0)
    {
        ssh_warning("Can not create local domain socket: %.200s",
                    strerror(errno));
        return NULL;

    }

    /* Initialize a unix-domain address structure. */
    memset(&sunaddr, 0, sizeof(sunaddr));
    sunaddr.sun_family = AF_UNIX;
    strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));

    /* Bind the socket to the address.  This will create the socket in the file
       system, and will fail if the socket already exists. */
    if (bind(sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)) < 0)
    {
        close(sock);
        ssh_warning("Can not bind local address %.200s: %.200s",
                    path, strerror(errno));
        return NULL;
    }

    /* Start listening for connections to the socket. */
    if (listen(sock, 5) < 0)
    {
        close(sock);
        ssh_warning("Can not listen to local address %.200s: %.200s",
                    path, strerror(errno));
        return NULL;
    }

    /* Allocate and initialize the listener structure. */
    listener = ssh_xmalloc(sizeof(*listener));
    listener->sock = sock;
    listener->path = ssh_xstrdup(path);
    listener->callback = callback;
    listener->context = context;

    /* ssh_local_listen_callback will call the user supplied callback
       when after new connection is accepted. It also creates stream
       object for the new connection and calls callback. */
    ssh_io_register_fd(sock, ssh_local_listen_callback, (void *)listener);
    ssh_io_set_fd_request(sock, SSH_IO_READ);

    return listener;
}
示例#4
0
void ssh_local_listen_callback(unsigned int events, void *context)
{
    SshLocalListener listener = (SshLocalListener)context;
    int sock, addrlen;
    struct sockaddr_un sunaddr;

    if (events & SSH_IO_READ)
    {
        addrlen = sizeof(sunaddr);
        sock = accept(listener->sock, (struct sockaddr *)&sunaddr, &addrlen);
        if (sock < 0)
        {
            ssh_debug("ssh_local_listen_callback: accept failed");
            return;
        }

        /* Re-enable requests on the listener. */
        ssh_io_set_fd_request(listener->sock, SSH_IO_READ);

        /* Inform user callback of the new socket.  Note that this might
           destroy the listener. */
        (*listener->callback)(ssh_stream_fd_wrap(sock, TRUE), listener->context);
    }
}
示例#5
0
void ssh_local_connect_try(unsigned int events, void *context)
{
    SshLocalConnect c = (SshLocalConnect)context;
    int ret;
    struct sockaddr_un sunaddr;

    /* Initialize the address to connect to. */
    memset(&sunaddr, 0, sizeof(sunaddr));
    sunaddr.sun_family = AF_UNIX;
    strncpy(sunaddr.sun_path, c->path, sizeof(sunaddr.sun_path));

    /* Make a non-blocking connect attempt. */
    ret = connect(c->sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr));
    if (ret >= 0 || errno == EISCONN) /* Connection is ready. */
    {
        /* Successful connection. */
        ssh_io_unregister_fd(c->sock, FALSE);
        (*c->callback)(ssh_stream_fd_wrap(c->sock, TRUE), c->context);
        ssh_xfree(c->path);
        ssh_xfree(c);
        return;
    }
    if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EALREADY)
    {
        /* Connection still in progress.  */
        ssh_io_set_fd_request(c->sock, SSH_IO_WRITE);
        return;
    }

    /* Connection failed. */
    ssh_io_unregister_fd(c->sock, FALSE);
    close(c->sock);
    (*c->callback)(NULL, c->context);
    ssh_xfree(c->path);
    ssh_xfree(c);
}