void copy_writer(SshStreamNotification op, void *context)
{
  int len;
  int len2;
  unsigned char buf[100];

  if (op != SSH_STREAM_CAN_OUTPUT)
    return;

  for (;;)
    {
      len = ssh_buffer_len(testdata) - test_data_index;
      len2 = ssh_rand() % 100000;
      if (len <= 0)
        {
          if (ssh_rand() % 2 == 0)
            ssh_stream_output_eof(ts1);
          ssh_stream_destroy(ts1);
          ts1 = NULL;
          destroy_count++;
          return;
        }
      if (len > len2)
        len = len2;
      len = ssh_stream_write(ts1, (unsigned char *)ssh_buffer_ptr(testdata) +
                             test_data_index, len);
      if (len == 0)
        {
          if (ssh_rand() % 2 == 0)
            ssh_stream_output_eof(ts1);
          ssh_stream_destroy(ts1);
          ts1 = NULL;
          destroy_count++;
          return; /* Eof while writing. */
        }
      if (len < 0)
        return; /* Cannot write more at this time */
      test_data_index += len;

      if (ssh_rand() % 5 == 0)
        {
          len = ssh_stream_read(ts1, buf, sizeof(buf));
          if (len == 0 && !reader_sent_eof)
            ssh_fatal("copy_writer: read returned EOF when not sent");
          if (len > 0)
            ssh_fatal("copy_writer: read > 0");
        }
    }
}
static Boolean
authentication_handler(SshHttpServerContext ctx,
                       SshHttpServerConnection conn,
                       SshStream stream, void *context)
{
  SshHttpAuthentication auth;
  char *name;
  char *password;

  auth = ssh_http_server_get_proxy_authentication(conn, &name, &password);

  switch (auth)
    {
    case SSH_HTTP_AUTHENTICATION_NONE:
      break;

    case SSH_HTTP_AUTHENTICATION_BASIC:
      fprintf(stderr, "%s: authentication: name=%s, password=%s\n",
              program, name, password);
      ssh_xfree(name);
      ssh_xfree(password);

      /* Allow access. */
      return FALSE;
      break;
    }

  /* Deny access. */
  ssh_http_server_error_proxy_authentication_required(conn, "WWW Proxy");
  ssh_stream_destroy(stream);
  return TRUE;
}
Exemple #3
0
void tcp_connect_socks_notify(SshStreamNotification notification,
                              void *context)
{
    SshFSMThread thread = (SshFSMThread) context;
    ConnectContext c = (ConnectContext) ssh_fsm_get_gdata(thread);

    c->handle = NULL;

    switch (notification)
    {
    case SSH_STREAM_INPUT_AVAILABLE:
    case SSH_STREAM_CAN_OUTPUT:
        /* Just retry the processing for the current state. */
        break;

    case SSH_STREAM_DISCONNECTED:
        SSH_DEBUG(1, ("ssh_socket_socks_notify: DISCONNECTED"));
        ssh_stream_destroy(c->stream);
        c->stream = NULL;
        /* Count this as a failure. */
        if (tcp_connect_register_failure(thread, SSH_TCP_FAILURE))
            break;
        if (c->socks_host)
        {
            if (c->socks_type == SSH_TCP_SOCKS5 &&
                    !c->host_addresses)
            {
                SSH_FSM_SET_NEXT(tcp_connect_socks_connect);
            }
            else if (c->socks_exceptions)
            {
                unsigned char *next;
                next = ssh_ustrchr(c->host_addresses, ',');
                if (next)
                    *next = '\0';
                if (ssh_inet_compare_netmask(c->socks_exceptions,
                                             c->host_addresses))
                    SSH_FSM_SET_NEXT(tcp_connect_host_connect);
                else
                    SSH_FSM_SET_NEXT(tcp_connect_socks_connect);
                if (next)
                    *next = ',';
            }
            else
            {
                SSH_FSM_SET_NEXT(tcp_connect_socks_connect);
            }
        }
        else
        {
            SSH_FSM_SET_NEXT(tcp_connect_host_connect);
        }
        break;

    default:
        ssh_fatal("ssh_socket_socks_notify: unexpected notification %d",
                  (int)notification);
    }
    ssh_fsm_continue(thread);
}
Exemple #4
0
void server1_read(SshStream stream)
{
  int ret;
  unsigned char buf[1024];

  for (;;)
    {
      ret = ssh_stream_read(stream, buf, sizeof(buf));
      if (ret < 0)
	return;
      if (ret == 0)
	{
	  if (read_count != send_count)
	    ssh_fatal("server1_read eof received, read_count %ld send_count %ld",
		  read_count, send_count);
	  break;
	}
      if (memcmp(buf, ssh_buffer_ptr(&expect_buffer), ret) != 0)
	ssh_fatal("server1_read data does not match");
      ssh_buffer_consume(&expect_buffer, ret);
      read_count += ret;
    }
  /* All data has been received. */
  ssh_stream_destroy(stream);
  exited1 = 1;
}
void copy_reader(SshStreamNotification op, void *context)
{
  unsigned char *buf;
  int len;

  if (op != SSH_STREAM_INPUT_AVAILABLE)
    return;

  buf = ssh_xmalloc(T_STREAMPAIR_BIG_BUF_LEN);

  for (;;)
    {
      len = ssh_stream_read(ts2, buf, T_STREAMPAIR_BIG_BUF_LEN);
      if (len == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return; /* EOF received */
        }
      if (len < 0)
        {
          ssh_xfree(buf);
          return;
        }
      ssh_buffer_append(received_data, buf, len);
      if (break_test && ssh_rand() % 10 == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return;
        }
      if (!reader_sent_eof && ssh_rand() % 10 == 0)
        {
          ssh_stream_output_eof(ts2);
          reader_sent_eof = TRUE;
        }
    }
  /*NOTREACHED*/
}
Exemple #6
0
void disconnect_test()
{
  SshStream server;
  SshStream s1, s2;
  unsigned char buf[8192];
  int len, i;
  
  ssh_stream_pair_create(&s1, &s2);

  /* Initialize server side. */
  server = ssh_transport_server_wrap(s1, random_state, TEST_VERSION, NULL,
                                     hostkey, serverkey,
                                     hostkey_blob, hostkey_blob_len,
                                     NULL, NULL);

  ssh_event_loop_run();
  
  if (random() % 5 == 0)
    len = 0;
  else
    len = random() % sizeof(buf);
  for (i = 0; i < len; i++)
    {
      buf[i] = random();
      if (buf[i] < 32 && buf[i] != '\n' && buf[i] != '\r')
        buf[i] = 'X';
    }

  ssh_stream_write(s2, buf, len);

  ssh_event_loop_run();

  ssh_stream_destroy(s2);

  ssh_event_loop_run();

  ssh_stream_destroy(server);

  ssh_event_loop_run();
}
Exemple #7
0
void ssh_packet_wrapper_destroy_now(SshPacketWrapper down)
{
  /* Close the downward stream. */
  ssh_stream_destroy(down->stream);

  /* Uninitialize buffers. */
  ssh_buffer_uninit(&down->incoming);
  ssh_buffer_uninit(&down->outgoing);
  ssh_buffer_uninit(&down->outgoing_packet);

  /* Fill the context with 'F' to ease debugging, and free it. */
  memset(down, 'F', sizeof(*down));
  ssh_xfree(down);
}
Exemple #8
0
void connect1_write(SshStream stream)
{
  int len;
  while (ssh_buffer_len(&send_buffer) > 0)
    {
      len = ssh_buffer_len(&send_buffer);
      len = ssh_stream_write(stream, ssh_buffer_ptr(&send_buffer), len);
      if (len < 0)
	return;
      if (len == 0)
	ssh_fatal("connect1_write failed");
      ssh_buffer_consume(&send_buffer, len);
    }
  ssh_stream_output_eof(stream);
  ssh_stream_destroy(stream);
}
Exemple #9
0
void ssh_pipe_stream_destroy(void *context)
{
    SshPipeStream pipes = (SshPipeStream)context;

    ssh_debug("ssh_pipe_stream_destroy");

    /* Cancel any pending input notification callbacks for this pipe. */
    ssh_cancel_timeouts(ssh_pipe_sigchld_do_callback, (void *)pipes);

    /* Unregister the sigchld handler for the stream. */
    ssh_sigchld_unregister(pipes->pid);

    /* Destroy the stream going to the master side. */
    ssh_stream_destroy(pipes->stdio_stream);

    /* Free our own data structures. */
    memset(pipes, 'F', sizeof(*pipes));
    ssh_xfree(pipes);
}
Exemple #10
0
/* Destroys the connection context. */
void tcp_connect_destroy_ctx(ConnectContext c)
{
    SSH_DEBUG(4, ("Destroying ConnectContext..."));
    SSH_PRECOND(c != NULL);
    if (c->handle)
        ssh_operation_abort(c->handle);

    ssh_cancel_timeout(&c->timeout);
    ssh_free(c->local_address);
    ssh_free(c->host_name);
    ssh_free(c->host_addresses);
    ssh_free(c->socks_host);
    ssh_free(c->socks_addresses);
    ssh_free(c->user_name);
    ssh_free(c->socks_exceptions);
    if (c->socks_buf)
        ssh_buffer_free(c->socks_buf);
    if (c->stream)
        ssh_stream_destroy(c->stream);
    if (c->upper_handle)
        ssh_operation_unregister(c->upper_handle);

    ssh_free(c);
}
Exemple #11
0
void t_tcpc_stream_callback(SshStreamNotification        notification,
                            void*                                 context)
{
  t_tcpc_context  pcontext = context;
  char                    buf[4096];
  int                             i;

  SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_stream_callback"));

  switch (notification)
    {
    case SSH_STREAM_INPUT_AVAILABLE:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_INPUT_AVAILABLE"));
      while ((i = ssh_stream_read(pcontext->pstream,
                                  buf,
                                  4096)) > 0)
        {
          buf[i] = 0;
          SSH_TRACE(SSH_D_MY, ("read: %s", buf));

          if (pcontext->phost_name_or_address)
            {
              ssh_buffer_append(pcontext->pbuffer,
                                buf,
                                i);
              t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT,
                                     pcontext);
            }
          else
            {
              SSH_TRACE(SSH_D_MY, ("output: %s", buf));
            }
        }
      break;
    case SSH_STREAM_CAN_OUTPUT:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_CAN_OUTPUT"));
      if (ssh_buffer_len(pcontext->pbuffer) > 0)
        {
          i = ssh_stream_write(pcontext->pstream,
                               ssh_buffer_ptr(pcontext->pbuffer),
                               ssh_buffer_len(pcontext->pbuffer));

          if (i > 0)
            {
              ssh_buffer_consume(pcontext->pbuffer,
                                 i);
            }
        }
      break;
    case SSH_STREAM_DISCONNECTED:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_DISCONNECTED"));
#if 0
      /* BUG BUG BUG */
      ssh_stream_destroy(pcontext->pstream);
#endif /* 0 */
      ssh_event_loop_abort();
      break;
    default:
      SSH_NOTREACHED;
      break;
    }
}
Exemple #12
0
static void
result_callback(SshHttpClientContext ctx, SshHttpResult result,
                SshTcpError ip_error, SshStream stream, void *callback_context)
{
  ProxyRequest *req = callback_context;
  SshBuffer error;
  char buf[256];

  switch (result)
    {
    case SSH_HTTP_RESULT_SUCCESS:
      {
        const char *value = NULL;
        SshCopyStreamCopyCb copy_cb = copy_data;

        if ((value = ssh_http_get_header_field(ctx, "Content-Type")))
          ssh_http_server_set_values(req->conn,
                                     SSH_HTTP_HDR_FIELD,
                                     "Content-Type", value,
                                     SSH_HTTP_HDR_END);

        req->client_stream = stream;

#if SMART_UPDATE
        if (value && strncmp(value, "text/html", 9) == 0)
          copy_cb = filter_html;
#endif

        ssh_copy_stream(req->server_stream, req->client_stream,
                        copy_cb, req_finish, req);
      }
      break;

    case SSH_HTTP_RESULT_MALFORMED_URL:
      error = ssh_buffer_allocate();

      ssh_buffer_append_cstrs(error, "<body><h1>Malformed URL</h1>n", NULL);
      ssh_http_server_send_buffer(req->conn, error);

      ssh_xfree(req);
      break;

    case SSH_HTTP_RESULT_REDIRECT_LIMIT_EXCEEDED:
      {
        const char *location = ssh_http_get_header_field(ctx, "Location");
        const char *reason_phrase;

        SSH_DEBUG(SSH_D_HIGHSTART, ("Redirect: %s", location));
        ssh_http_server_error(req->conn,
                              ssh_http_get_status_code(ctx, &reason_phrase),
                              SSH_HTTP_HDR_LOCATION, location,
                              SSH_HTTP_HDR_END);

        ssh_stream_destroy(req->server_stream);
        ssh_xfree(req);

      }
      break;

    case SSH_HTTP_RESULT_HTTP_ERROR:
      {
        const char *reason_phrase;
        SshUInt32 error_code;

        error_code = ssh_http_get_status_code(ctx, &reason_phrase);
        error = ssh_buffer_allocate();

        ssh_snprintf(buf, sizeof(buf), "%ld", error_code);

        ssh_http_server_error(req->conn, error_code,
                              SSH_HTTP_HDR_END);

        ssh_buffer_append_cstrs(error,
                                "<body><h1>HTTP Error (", buf,
                                ")</h1>\n<pre>\n",
                                reason_phrase, "\n", NULL);
        ssh_http_server_send_buffer(req->conn, error);

        ssh_xfree(req);
      }
      break;

    default:
      error = ssh_buffer_allocate();

      ssh_snprintf(buf, sizeof(buf), "%d", result);

      ssh_buffer_append_cstrs(error,
                              "<body><h1>HTTP Library Error ", buf, "</h1>\n",
                              NULL);
      ssh_http_server_send_buffer(req->conn, error);
      ssh_xfree(req);
      break;
    }
}
Exemple #13
0
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream,
                                          void *context)
{
  SshRemoteTcpForward fwd = (SshRemoteTcpForward)context;
  char ip[20], port[20];
  SshBuffer buffer;

  SSH_DEBUG(5, ("connection to forwarded TCP/IP port"));
  
  /* We should only receive new connection notifications. */
  if (error != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

  SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s",
                fwd->port, ip, port));
  ssh_log_event(fwd->common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Connection to forwarded port %s from %s:%s",
                fwd->port, fwd->common->remote_host, port);

  /* XXXXXXXX */
#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);

    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port " \
                            "%s refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);
    
        return;
      }
    signal(SIGCHLD, old_handler);
        
    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "Remote fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Register that we have an open channel. */
  ssh_common_new_channel(fwd->common);
  
  /* Send a request to open a channel and connect it to the given port. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                    fwd->address_to_bind, strlen(fwd->address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port),
                    SSH_FORMAT_UINT32_STR, ip, strlen(ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL,
                             ssh_channel_tcp_connection_destroy,
                             (void *)fwd->common, NULL, NULL);
  ssh_buffer_uninit(&buffer);
}  
Exemple #14
0
void tcp_connect_socks_connect_done_cb(SshTcpError error,
                                       SshStream stream,
                                       void *context)
{
    SshFSMThread thread = (SshFSMThread) context;
    ConnectContext c = (ConnectContext) ssh_fsm_get_gdata(thread);
    struct SocksInfoRec socksinfo;
    SocksError ret;
    unsigned char host_port[64], *next = NULL;

    c->handle = NULL;

    if (error != SSH_TCP_OK)
    {
        /* Get next address. */
        if (ssh_ustrchr(c->socks_next_address, ','))
        {
            c->socks_next_address =
                ssh_ustrchr(c->socks_next_address, ',') + 1;
        }
        else
        {   /* At end of list; consider it as a failure. */
            if (tcp_connect_register_failure(thread, error))
            {
                SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
                return;
            }
            c->socks_next_address = c->socks_addresses;
        }
        /* Try connecting again. */
        SSH_FSM_SET_NEXT(tcp_connect_socks_connect);
        SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
        return;
    }

    /* Save the stream. */
    c->stream = stream;

    /* Set the callback so that we'll get any required read/write
       notifications. */
    ssh_stream_set_callback(stream, tcp_connect_socks_notify, thread);

    if (c->next_address &&
            (next = ssh_ustrchr(c->next_address, ',')) != NULL)
    {
        *next = '\0';
        next++;
    }

    if (c->socks_type == SSH_TCP_SOCKS5)
    {
        socksinfo.socks_version_number = 5;
        socksinfo.command_code = SSH_SOCKS5_COMMAND_CODE_CONNECT;
        if (c->next_address)
            socksinfo.ip = (unsigned char *) c->next_address;
        else
            socksinfo.ip = c->host_name;
    }
    else
    {
        socksinfo.socks_version_number = 4;
        socksinfo.command_code = SSH_SOCKS4_COMMAND_CODE_CONNECT;
        socksinfo.ip = (unsigned char *) c->next_address;
    }
    ssh_snprintf(host_port, sizeof(host_port), "%d", c->host_port);
    socksinfo.port = host_port;
    socksinfo.username = c->user_name;

    ssh_buffer_clear(c->socks_buf);



    SSH_FSM_SET_NEXT(tcp_connect_socks_send);
    ret = ssh_socks_client_generate_methods(c->socks_buf, &socksinfo);
    if (ret == SSH_SOCKS_SUCCESS)
        ret = ssh_socks_client_generate_open(c->socks_buf, &socksinfo);
    if (ret != SSH_SOCKS_SUCCESS)
    {
        if (next != NULL)
        {
            c->stream = NULL;
            ssh_stream_destroy(stream);
            c->next_address = next;
            SSH_FSM_SET_NEXT(tcp_connect_socks_lookup);
        }
        else
        {
            if (ret == SSH_SOCKS_ERROR_INVALID_ARGUMENT)
                c->error = SSH_TCP_NO_ADDRESS;
            else
                c->error = SSH_TCP_FAILURE;
            SSH_FSM_SET_NEXT(tcp_connect_finish);
        }
    }
    SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
}
Exemple #15
0
void handler_callback(SshStreamNotification notification, void *context)
{
  Handler c = context;
  SshTransportStatistics stats;
  Boolean cont = FALSE;
  
#ifdef DEBUG
  ssh_debug("\n** %s: handler_callback %s **\n", c->side,
            opnames[c->script->op]);
#endif

  do
    {
      switch (notification)
        {
        case SSH_STREAM_INPUT_AVAILABLE:
          cont = handler_input(c);
          if (cont)
            notification = SSH_STREAM_CAN_OUTPUT;
          break;
        case SSH_STREAM_CAN_OUTPUT:
          cont = handler_output(c);
          if (cont)
            notification = SSH_STREAM_INPUT_AVAILABLE;
          break;
        case SSH_STREAM_DISCONNECTED:
          ssh_fatal("%s: handler_callback: DISCONNECT", c->side);
          
        default:
          ssh_fatal("%s: handler_callback: unexpected %d",
                    c->side, (int)notification);
        }

      if (c->script->op == OP_END)
        {
          /* End of script reached.  Destroy handler. */
#ifdef DEBUG
          ssh_debug("%s: End of script reached", c->side);
#endif
          cont = FALSE;
          ssh_transport_get_statistics(c->stream, &stats);
#ifdef DEBUG

          ssh_debug("%s: %lu/%lu bytes in, %lu/%lu out, %lu packets in, "
                    "%lu out\n",
                    c->side,
                    stats.compressed_incoming_bytes,
                    stats.uncompressed_incoming_bytes,
                    stats.compressed_outgoing_bytes,
                    stats.uncompressed_outgoing_bytes,
                    stats.incoming_packets, stats.outgoing_packets);
#endif

          ssh_stream_destroy(c->stream);
          memset(c, 'F', sizeof(*c));
          ssh_xfree(c);
          end_of_script_count++;
        }
    }
  while (cont);
}
Exemple #16
0
SshServer ssh_server_wrap(SshStream stream, SshConfig config,
                          SshRandomState random_state,
                          SshPrivateKey private_server_key,
                          SshServerDisconnectProc disconnect,
                          SshServerDebugProc debug,
                          SshVersionCallback version_check,
                          SshAuthPolicyProc auth_policy_proc,
                          SshCommonAuthenticatedNotify authenticated_notify,
                          void *context)
{
  SshServer server;
  SshStream trans, auth;
  SshTransportParams params;

  /* Create parameters. */
  params = ssh_transport_create_params();
  if (!ssh_server_update_transport_params(config, params))
    {
      ssh_stream_destroy(stream);
      ssh_transport_destroy_params(params);
      return NULL;
    }

  /* Check the host key. */

  if (config->private_host_key == NULL || 
      config->public_host_key_blob == NULL)
    ssh_fatal("ssh_server_wrap: no host key !");

  /* Create the server object. */
  server = ssh_xcalloc(1, sizeof(*server));
  server->config = config;
  
  /* Create a transport layer protocol object. */
  ssh_debug("ssh_server_wrap: creating transport protocol");
  trans = ssh_transport_server_wrap(stream, random_state, 
                                    SSH2_PROTOCOL_VERSION_STRING,
                                    params, config->private_host_key,
                                    private_server_key,
                                    config->public_host_key_blob,
                                    config->public_host_key_blob_len,
                                    version_check,
                                    (void *)context);

  
  ssh_transport_get_compatibility_flags(trans, &server->compat_flags);
  
  /* Create the authentication methods array for the server. */
  server->methods = ssh_server_authentication_initialize();
  /* XXX config data */
  
  /* Create an authentication protocol object. */
  ssh_debug("ssh_server_wrap: creating userauth protocol");
  /* XXX policy_proc */
  auth = ssh_auth_server_wrap(trans, auth_policy_proc, (void *)server,
                              server->methods, (void *)server);

  /* Create the common part of client/server objects. */
  server->common = ssh_common_wrap(stream, auth, FALSE, config, random_state,
                                   NULL,
                                   disconnect, debug, authenticated_notify,
                                   context);

  if (server->common == NULL)
    {
      ssh_server_authentication_uninitialize(server->methods);
      ssh_xfree(server);
      return NULL;
    }
  
  return server;
}
Exemple #17
0
/* The URI handler. */
static Boolean
proxy_handler(SshHttpServerContext ctx,
              SshHttpServerConnection conn,
              SshStream stream, void *context)
{
  const char *method = ssh_http_server_get_method(conn);
  const char *uri = ssh_http_server_get_uri(conn);
  SshHttpClientParams params;
  ProxyRequest *req;
  SshBuffer error;
  ProxyCensor *c;

  SSH_DEBUG(SSH_D_HIGHSTART,
            ("method=%s, uri=%s", method, uri));

  for (c = censor; c; c = c->next)
    if (ssh_match_pattern(uri, c->pattern))
      {
        SSH_DEBUG(SSH_D_HIGHSTART,
                  ("censored by pattern `%s'", c->pattern));
        ssh_http_server_error(conn, 301,
                              SSH_HTTP_HDR_LOCATION,
                              "http://people.ssh.fi/mtr/censor.jpg",
                              SSH_HTTP_HDR_FIELD,
                              "Content-Type", "text/html",
                              SSH_HTTP_HDR_END);
        ssh_stream_destroy(stream);
        return TRUE;
      }

  memset(&params, 0, sizeof(params));
  params.http_proxy_url = proxy_url;
  params.num_redirections = 0;

  req = ssh_xcalloc(1, sizeof(*req));
  req->server = ctx;
  req->conn = conn;
  req->server_stream = stream;

  req->client = ssh_http_client_init(&params);

  if (strcmp(method, "GET") == 0)
    ssh_http_get(req->client, uri, result_callback, req,
                 SSH_HTTP_HDR_END);
  else if (strcmp(method, "HEAD") == 0)
    ssh_http_head(req->client, uri, result_callback, req,
                  SSH_HTTP_HDR_END);
  else if (strcmp(method, "POST") == 0
           || strcmp(method, "PUT") == 0)
    {
      SSH_DEBUG(SSH_D_ERROR, ("%s not implemented yet", method));
      ssh_xfree(req);

      error = ssh_buffer_allocate();
      ssh_buffer_append_cstrs(error, "<body><h1>Method `", method,
                              "' not implemented yet</h1>\n", NULL);
      ssh_http_server_send_buffer(conn, error);
    }
  else
    {
      SSH_DEBUG(SSH_D_ERROR, ("unknown method `%s'", method));
      ssh_xfree(req);

      error = ssh_buffer_allocate();
      ssh_buffer_append_cstrs(error, "<body><h1>Unknown method `",
                              method, "'</h1>\n", NULL);

      ssh_http_server_send_buffer(conn, error);
    }

  return TRUE;
}
Exemple #18
0
void ssh_channel_dtcp_incoming_connection(SshStreamNotification op,
                                          SshStream stream, void *context)
{
  SshLocalTcpForward fwd = (SshLocalTcpForward)context;
  char ip[20], port[20];

  /* We should only receive new connection notifications. */
  if (op != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_dtcp_incoming_connection: op %d", (int)op);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);
    
    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port %s "
                            "refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_log_event(fwd->common->config->log_facility, SSH_LOG_WARNING,
                      "Fwd connection from %.500s to local port %s "
                      "refused by tcp_wrappers.",
                      eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);

        return;
      }
    signal(SIGCHLD, old_handler);

    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "direct fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Send a request to open a channel and connect it to the given port. */
  ssh_channel_dtcp_open_to_remote(fwd->common, stream,
                                  fwd->connect_to_host,
                                  fwd->connect_to_port,
                                  ip, port);
}
Exemple #19
0
/* This function reads complete payload from the HTTP stream described
   at the context argument (also the thread running this session is
   identified b the context's upper context), and calls the input
   processing thread when done. This gets called when the CA replies
   to the clients message or poll. */
static void
pkix_http_stream_callback(SshStreamNotification not, void *context)
{
  int i;
  size_t len;
  SshUInt8 type_or_version;
  unsigned char input[256], *data;
  PkixHttpReadContext c = (PkixHttpReadContext)context;
  SshFSMThread thread = (SshFSMThread) c->upper_context;
  SshPkiThreadData tdata = ssh_fsm_get_tdata(thread);
  SshPkiGlobalData gdata = ssh_fsm_get_gdata(thread);

  while (TRUE)
    {
      i = ssh_stream_read(c->http_stream, input, sizeof(input));
      if (i == 0)
        {
          if ((len = ssh_buffer_len(c->input)) > 5)
            {
              data = ssh_buffer_ptr(c->input);
              len = SSH_GET_32BIT(data);
              type_or_version = data[4];

              if (type_or_version < 10)
                {
                  tdata->input_version = SSH_PKI_VERSION_0;
                  tdata->input_flags = 0;
                  tdata->input_type = type_or_version;
                  tdata->input_len = len - 1;
                  tdata->input = ssh_memdup(data + 5, tdata->input_len);
                }
              else
                {
                  if (type_or_version == 10)
                    {
                      data += 4; /* skip to end of length */
                      tdata->input_version = SSH_PKI_VERSION_1;
                      tdata->input_len = len - 3;
                      tdata->input_flags = data[1];
                      tdata->input_type  = data[2];
                      data += 3;
                      tdata->input = ssh_memdup(data, tdata->input_len);
                    }
                  else
                    {
                      tdata->input_version = type_or_version;
                      tdata->input_type = SSH_PKI_MSG_ERRORREP;
                    }
                }

              if (tdata->input == NULL)
                tdata->input_type = SSH_PKI_MSG_ERRORREP;

              ssh_buffer_free(c->input);
              ssh_stream_destroy(c->http_stream);
              ssh_fsm_continue(gdata->input_thread);
              ssh_free(c);
              return;
            }
          else
            {
            error:
              tdata->input_type = SSH_PKI_MSG_ERRORREP;
              ssh_fsm_set_next(thread, pkix_aborted);
              ssh_fsm_continue(gdata->input_thread);
              ssh_stream_destroy(c->http_stream);
              ssh_buffer_free(c->input);
              ssh_free(c);
              return;
            }
        }
      else if (i < 0)
        {
          return;
        }
      else
        {
          if (ssh_buffer_append(c->input, input, i) != SSH_BUFFER_OK)
            {
              goto error;
            }
        }

    }
}