Example #1
0
static void silc_thread_pool_unref(SilcThreadPool tp)
{
  tp->refcnt--;
  SILC_LOG_DEBUG(("Thread pool %p refcnt %d -> %d", tp, tp->refcnt + 1,
		  tp->refcnt));
  if (!tp->refcnt) {
    SilcStack stack = tp->stack;
    silc_mutex_unlock(tp->lock);
    silc_mutex_free(tp->lock);
    silc_cond_free(tp->pool_signal);
    silc_sfree(stack, tp);
    silc_stack_free(stack);
    return;
  }
  silc_mutex_unlock(tp->lock);
}
Example #2
0
static void silc_client_listener_completion(SilcSKE ske,
					    SilcSKEStatus status,
					    SilcSKESecurityProperties prop,
					    SilcSKEKeyMaterial keymat,
					    SilcSKERekeyMaterial rekey,
					    void *context)
{
  SilcClientConnection conn = context;
  SilcCipher send_key, receive_key;
  SilcHmac hmac_send, hmac_receive;

  SILC_LOG_DEBUG(("Key exchange completed"));

  if (status != SILC_SKE_STATUS_OK) {
    /* Key exchange failed */
    conn->callback(conn->client, conn,
		   status == SILC_SKE_STATUS_TIMEOUT ?
		   SILC_CLIENT_CONN_ERROR_TIMEOUT :
		   SILC_CLIENT_CONN_ERROR_KE, conn->internal->error,
		   conn->internal->disconnect_message,
		   conn->callback_context);
    return;
  }

  /* Allocate the cipher and HMAC contexts */
  if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
			 &hmac_send, &hmac_receive, &conn->internal->hash)) {
    conn->callback(conn->client, conn,
		   SILC_CLIENT_CONN_ERROR_KE, 0, NULL,
		   conn->callback_context);
    return;
  }

  /* Set the keys into the packet stream.  After this call packets will be
     encrypted with these keys. */
  if (!silc_packet_set_keys(conn->stream, send_key, receive_key, hmac_send,
			    hmac_receive, FALSE)) {
    conn->callback(conn->client, conn,
		   SILC_CLIENT_CONN_ERROR_KE, 0, NULL,
		   conn->callback_context);
    return;
  }

  /* Key exchange successful */
  conn->callback(conn->client, conn, SILC_CLIENT_CONN_SUCCESS, 0, NULL,
		 conn->callback_context);
}
Example #3
0
SilcBuffer silc_command_payload_encode(SilcCommand cmd,
				       SilcUInt32 argc,
				       unsigned char **argv,
				       SilcUInt32 *argv_lens,
				       SilcUInt32 *argv_types,
				       SilcUInt16 ident)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  SilcUInt32 len = 0;

  SILC_LOG_DEBUG(("Encoding command payload"));

  if (argc) {
    args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types);
    if (!args)
      return NULL;
    len = silc_buffer_len(args);
  }

  len += SILC_COMMAND_PAYLOAD_LEN;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer)
    return NULL;

  /* Create Command payload */
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(cmd),
		     SILC_STR_UI_CHAR(argc),
		     SILC_STR_UI_SHORT(ident),
		     SILC_STR_END);

  /* Add arguments */
  if (argc) {
    silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_format(buffer,
		       SILC_STR_UI_XNSTRING(args->data,
					    silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_free(args);
  }

  return buffer;
}
Example #4
0
SilcDList silc_attribute_payload_parse(const unsigned char *payload,
				       SilcUInt32 payload_len)
{
  SilcBufferStruct buffer;
  SilcDList list;
  SilcAttributePayload newp;
  SilcUInt32 len;
  int ret;

  SILC_LOG_DEBUG(("Parsing Attribute Payload list"));

  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
  list = silc_dlist_init();

  while (silc_buffer_len(&buffer)) {
    newp = silc_calloc(1, sizeof(*newp));
    if (!newp)
      goto err;
    ret = silc_buffer_unformat(&buffer,
			       SILC_STR_UI_CHAR(&newp->attribute),
			       SILC_STR_UI_CHAR(&newp->flags),
			       SILC_STR_UI16_NSTRING_ALLOC(&newp->data,
							   &newp->data_len),
			       SILC_STR_END);
    if (ret == -1)
      goto err;

    if (newp->data_len > silc_buffer_len(&buffer) - 4) {
      SILC_LOG_ERROR(("Incorrect attribute payload in list"));
      goto err;
    }

    len = 4 + newp->data_len;
    if (silc_buffer_len(&buffer) < len)
      break;
    silc_buffer_pull(&buffer, len);

    silc_dlist_add(list, newp);
  }

  return list;

 err:
  silc_attribute_payload_list_free(list);
  return NULL;
}
Example #5
0
static SilcBool silc_connauth_get_signature(SilcConnAuth connauth,
					    unsigned char **auth_data,
					    SilcUInt32 *auth_data_len)
{
  int len;
  SilcSKE ske;
  SilcPrivateKey private_key;
  SilcBuffer auth;

  SILC_LOG_DEBUG(("Compute signature"));

  ske = connauth->ske;
  private_key = connauth->auth_data;

  /* Make the authentication data. Protocol says it is HASH plus
     KE Start Payload. */
  len = ske->hash_len + silc_buffer_len(ske->start_payload_copy);
  auth = silc_buffer_alloc_size(len);
  if (!auth)
    return FALSE;
  silc_buffer_format(auth,
		     SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
		     SILC_STR_UI_XNSTRING(
			       ske->start_payload_copy->data,
			       silc_buffer_len(ske->start_payload_copy)),
		     SILC_STR_END);

  len = ((silc_pkcs_private_key_get_len(private_key) + 7) / 8) + 1;
  *auth_data = silc_calloc(len, sizeof(**auth_data));
  if (*auth_data == NULL) {
    silc_buffer_free(auth);
    return FALSE;
  }

  /* Compute signature */
  if (!silc_pkcs_sign(private_key, auth->data, silc_buffer_len(auth),
		      *auth_data, len, auth_data_len, TRUE, ske->prop->hash)) {
    silc_free(*auth_data);
    silc_buffer_free(auth);
    return FALSE;
  }

  silc_buffer_free(auth);
  return TRUE;
}
Example #6
0
SilcAsyncOperation
silc_client_key_exchange(SilcClient client,
			 SilcClientConnectionParams *params,
			 SilcPublicKey public_key,
			 SilcPrivateKey private_key,
			 SilcStream stream,
			 SilcConnectionType conn_type,
			 SilcClientConnectCallback callback,
			 void *context)
{
  SilcClientConnection conn;
  const char *host;
  SilcUInt16 port;

  SILC_LOG_DEBUG(("Performing key exchange"));

  if (!client || !stream)
    return NULL;

  if (client->internal->run_callback) {
    SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
		    "callback has not been called yet."));
    return NULL;
  }

  if (!silc_socket_stream_get_info(stream, NULL, &host, NULL, &port)) {
    SILC_LOG_ERROR(("Socket stream does not have remote host name set"));
    callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
    return NULL;
  }

  /* Add new connection */
  conn = silc_client_add_connection(client, conn_type, TRUE, params,
				    public_key, private_key,
				    (char *)host, port, callback, context);
  if (!conn) {
    callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
    return NULL;
  }
  conn->internal->user_stream = stream;

  /* Signal connection to start key exchange */
  conn->internal->key_exchange = TRUE;
  return conn->internal->cop;
}
Example #7
0
SilcBuffer silc_command_payload_encode_payload(SilcCommandPayload payload)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  SilcUInt32 len = 0;
  SilcUInt32 argc = 0;

  SILC_LOG_DEBUG(("Encoding command payload"));

  if (payload->args) {
    args = silc_argument_payload_encode_payload(payload->args);
    if (args)
      len = silc_buffer_len(args);
    argc = silc_argument_get_arg_num(payload->args);
  }

  len += SILC_COMMAND_PAYLOAD_LEN;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer) {
    if (args)
      silc_buffer_free(args);
    return NULL;
  }

  /* Create Command payload */
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(payload->cmd),
		     SILC_STR_UI_CHAR(argc),
		     SILC_STR_UI_SHORT(payload->ident),
		     SILC_STR_END);

  /* Add arguments */
  if (args) {
    silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_format(buffer,
		       SILC_STR_UI_XNSTRING(args->data,
					    silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_free(args);
  }

  return buffer;
}
Example #8
0
void silc_client_stop(SilcClient client, SilcClientStopped stopped,
		      void *context)
{
  SILC_LOG_DEBUG(("Stopping client"));

  if (!silc_fsm_is_started(&client->internal->fsm)) {
    SILC_LOG_WARNING(("Attempting to stop client library before it has been "
		      "started (silc_client_init not called)"));
    return;
  }

  client->internal->running = (SilcClientRunning)stopped;
  client->internal->running_context = context;

  /* Signal to stop */
  client->internal->stop = TRUE;
  SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event);
}
Example #9
0
static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
		      const unsigned char *data, SilcUInt32 data_len,
		      void *context)
{
  SilcSFTPHandle handle = (SilcSFTPHandle)context;

  if (status != SILC_SFTP_STATUS_OK) {
    SilcSFTPAttributesStruct attrs;

    fprintf(stderr, "Status %d\n", status);

    if (status != SILC_SFTP_STATUS_EOF) {
      SILC_LOG_DEBUG(("Error status"));
      success = FALSE;
      end_test();
      return;
    }

    if (!strcmp(file, "/sftp/sftp_server.c")) {
      fprintf(stderr, "FStatting file handle %s\n", file);
      silc_sftp_fstat(sftp, handle, sftp_attr, context);
      return;
    }

    /* Open another file */
    opendir = FALSE;
    memset(&attrs, 0, sizeof(attrs));
    file = "/sftp/sftp_server.c";
    fprintf(stderr, "Opening file %s\n", file);
    offset = 0;
    silc_sftp_open(sftp, file, SILC_SFTP_FXF_READ,
		   &attrs, sftp_handle, gclient);
    return;
  }

  SILC_LOG_HEXDUMP(("data"), (unsigned char *)data, data_len);

  offset += data_len;

  /* Attempt to read more */
  fprintf(stderr, "Reading more of file %s\n", file);
  silc_sftp_read(sftp, handle, offset, 2048, sftp_data, handle);
}
Example #10
0
SilcNotifyPayload silc_notify_payload_parse(const unsigned char *payload,
					    SilcUInt32 payload_len)
{
  SilcBufferStruct buffer;
  SilcNotifyPayload newp;
  SilcUInt16 len;
  int ret;

  SILC_LOG_DEBUG(("Parsing Notify payload"));

  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
  newp = silc_calloc(1, sizeof(*newp));
  if (!newp)
    return NULL;

  ret = silc_buffer_unformat(&buffer,
			     SILC_STR_UI_SHORT(&newp->type),
			     SILC_STR_UI_SHORT(&len),
			     SILC_STR_UI_CHAR(&newp->argc),
			     SILC_STR_END);
  if (ret == -1)
    goto err;

  if (len > silc_buffer_len(&buffer))
    goto err;

  if (newp->argc) {
    silc_buffer_pull(&buffer, 5);
    newp->args = silc_argument_payload_parse(buffer.data,
					     silc_buffer_len(&buffer),
					     newp->argc);
    if (!newp->args)
      goto err;
    silc_buffer_push(&buffer, 5);
  }

  return newp;

 err:
  silc_free(newp);
  return NULL;
}
Example #11
0
static void connect_callback(SilcNetStatus status, SilcStream stream,
			     void *context)
{
  Client client = context;

  if (!stream) {
    SILC_LOG_DEBUG(("Connect error"));
    success = FALSE;
    end_test();
  }

  /* Start SFTP session */
  client->stream = stream;
  client->sftp = silc_sftp_client_start(stream, client->schedule, sftp_version,
					sftp_error, client);
  if (!client->sftp) {
    success = FALSE;
    end_test();
  }
}
Example #12
0
static void silc_client_connect_abort(SilcAsyncOperation op, void *context)
{
  SilcClientConnection conn = context;

  SILC_LOG_DEBUG(("Connection %p aborted by application", conn));

  /* Connection callback will not be called after user aborted connecting */
  conn->callback = NULL;
  conn->internal->cop = NULL;

  /* Signal to close connection */
  if (!conn->internal->disconnected) {
    conn->internal->disconnected = TRUE;

    /* If user aborts before connection machine is even up yet, then don't
       send signal yet.  It will process this event when it comes up. */
    if (silc_fsm_is_started(&conn->internal->fsm))
      SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
  }
}
Example #13
0
static void
silc_server_command_status_reply(SilcServerCommand cmd,
				      SilcCommand command,
				      SilcStatus status,
				      SilcStatus error)
{
  SilcBuffer buffer;

  /* Statistics */
  cmd->thread->server->stat.commands_sent++;

  SILC_LOG_DEBUG(("Sending command status %d", status));
  buffer =
    silc_command_reply_payload_encode_va(command, status, error,
					 silc_command_get_ident(cmd->payload),
					 0);
  silc_packet_send(cmd->packet->stream, SILC_PACKET_COMMAND_REPLY, 0,
		   buffer->data, silc_buffer_len(buffer));
  silc_buffer_free(buffer);
}
SilcBool silc_socket_stream_notifier(SilcStream stream,
				     SilcSchedule schedule,
				     SilcStreamNotifier callback,
				     void *context)
{
  SilcSocketStream socket_stream = stream;

  SILC_LOG_DEBUG(("Setting stream notifier callback"));

  socket_stream->notifier = callback;
  socket_stream->notifier_context = context;
  socket_stream->schedule = schedule;

  if (socket_stream->notifier && socket_stream->schedule) {
    /* Set the socket to non-blocking mode */
    silc_net_set_socket_nonblock(socket_stream->sock);

    /* Add the socket to scheduler.  Safe to call if already added. */
    if (!silc_schedule_task_add_fd(socket_stream->schedule,
				   socket_stream->sock,
				   silc_socket_stream_io, socket_stream))
      return FALSE;

    /* Initially set socket for reading */
    if (!silc_schedule_set_listen_fd(socket_stream->schedule,
				     socket_stream->sock,
				     SILC_TASK_READ, FALSE))
      return FALSE;
  } else if (socket_stream->schedule) {
    /* Unschedule the socket */
    silc_schedule_unset_listen_fd(socket_stream->schedule,
				  socket_stream->sock);
    silc_schedule_task_del_by_fd(socket_stream->schedule,
				 socket_stream->sock);
  }

  if (socket_stream->schedule)
    silc_schedule_wakeup(socket_stream->schedule);

  return TRUE;
}
Example #15
0
SilcBool silc_config_register(SilcConfigEntity ent, const char *name,
			  SilcConfigType type, SilcConfigCallback cb,
			  const SilcConfigTable *subtable, void *context)
{
  SilcConfigOption *newopt;
  SILC_CONFIG_DEBUG(("Register new option=\"%s\" "
		     "type=%u cb=0x%08x context=0x%08x",
		     name, type, (SilcUInt32) cb, (SilcUInt32) context));

  /* if we are registering a block, make sure there is a specified sub-table */
  if (!ent || !name || ((type == SILC_CONFIG_ARG_BLOCK) && !subtable))
    return FALSE;

  /* don't register a reserved tag */
  if (!strcasecmp(name, "include"))
    return FALSE;

  /* check if an option was previously registered */
  if (silc_config_find_option(ent, name)) {
    SILC_LOG_DEBUG(("Error: Can't register \"%s\" twice.", name));
    return FALSE;
  }

  /* allocate and append the new option */
  newopt = silc_calloc(1, sizeof(*newopt));
  newopt->name = strdup(name);
  newopt->type = type;
  newopt->cb = cb;
  newopt->subtable = subtable;
  newopt->context = context;

  /* append this option to the list */
  if (!ent->opts)
    ent->opts = newopt;
  else {
    SilcConfigOption *tmp;
    for (tmp = ent->opts; tmp->next; tmp = tmp->next);
    tmp->next = newopt;
  }
  return TRUE;
}
Example #16
0
static void silc_client_listener_tcp_accept(SilcNetStatus status,
					    SilcStream stream,
					    void *context)
{
  SilcClientListener listener = context;
  SilcPacketStream packet_stream;

  SILC_LOG_DEBUG(("New incoming TCP connection"));

  /* Create packet stream */
  packet_stream =
    silc_packet_stream_create(listener->client->internal->packet_engine,
			      listener->schedule, stream);
  if (!packet_stream) {
    silc_stream_destroy(stream);
    return;
  }

  /* Process session */
  silc_client_listener_new_connection(listener, packet_stream);
}
Example #17
0
SilcBool silc_fd_stream_notifier(SilcStream stream,
				 SilcSchedule schedule,
				 SilcStreamNotifier callback,
				 void *context)
{
  SilcFDStream fd_stream = stream;

  SILC_LOG_DEBUG(("Setting stream notifier callback"));

  fd_stream->notifier = callback;
  fd_stream->notifier_context = context;
  fd_stream->schedule = schedule;

  /* Schedule the file descriptors */
  if (schedule) {
    if (fd_stream->fd2 > 0) {
      silc_schedule_task_add_fd(schedule, fd_stream->fd2,
				silc_fd_stream_io, stream);
      silc_file_set_nonblock(fd_stream->fd2);
    }
    if (fd_stream->fd1 > 0) {
      silc_schedule_task_add_fd(schedule, fd_stream->fd1,
				silc_fd_stream_io, stream);
      silc_schedule_set_listen_fd(schedule, fd_stream->fd1,
				  SILC_TASK_READ, FALSE);
      silc_file_set_nonblock(fd_stream->fd1);
      if (fd_stream->fd2 < 1)
	fd_stream->fd2 = fd_stream->fd1;
    }
  } else {
    if (fd_stream->schedule) {
      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1);
      silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2);
      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1);
      silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2);
    }
  }

  return TRUE;
}
Example #18
0
static void silc_client_ftp_readdir_name(SilcSFTP sftp,
					 SilcSFTPStatus status,
					 const SilcSFTPName name,
					 void *context)
{
  SilcClientFtpSession session = (SilcClientFtpSession)context;

  SILC_LOG_DEBUG(("Start"));

  if (status != SILC_SFTP_STATUS_OK) {
    /* Call monitor callback */
    if (session->monitor)
      (*session->monitor)(session->client, session->conn,
			  SILC_CLIENT_FILE_MONITOR_ERROR,
			  (status == SILC_SFTP_STATUS_NO_SUCH_FILE ?
			   SILC_CLIENT_FILE_NO_SUCH_FILE :
			   status == SILC_SFTP_STATUS_PERMISSION_DENIED ?
			   SILC_CLIENT_FILE_PERMISSION_DENIED :
			   SILC_CLIENT_FILE_ERROR), 0, 0,
			  session->client_entry, session->session_id,
			  session->filepath, session->monitor_context);
    return;
  }

  /* Save the important attributes like filename and file size */
  session->filepath = strdup(name->filename[0]);
  session->filesize = name->attrs[0]->size;

  /* If the path was not provided, ask from application where to save the
     downloaded file. */
  if (!session->path && session->ask_name) {
    session->ask_name(session->client, session->conn, session->session_id,
		      name->filename[0], silc_client_ftp_ask_name, session,
		      session->ask_name_context);
    return;
  }

  /* Start downloading immediately to current directory. */
  silc_client_ftp_ask_name(NULL, session);
}
Example #19
0
SilcAsyncOperation
silc_connauth_initiator(SilcConnAuth connauth,
			SilcConnectionType conn_type,
			SilcAuthMethod auth_method, void *auth_data,
			SilcUInt32 auth_data_len,
			SilcConnAuthCompletion completion,
			void *context)
{
  SILC_LOG_DEBUG(("Connection authentication as initiator"));

  if (auth_method == SILC_AUTH_PASSWORD && !auth_data) {
    completion(connauth, FALSE, context);
    return NULL;
  }

  if (auth_method == SILC_AUTH_PUBLIC_KEY && !auth_data) {
    completion(connauth, FALSE, context);
    return NULL;
  }

  connauth->conn_type = conn_type;
  connauth->auth_method = auth_method;
  connauth->auth_data = auth_data;
  connauth->auth_data_len = auth_data_len;
  connauth->completion = completion;
  connauth->context = context;

  /* Link to packet stream to get packets */
  silc_packet_stream_link(connauth->ske->stream,
			  &silc_connauth_stream_cbs, connauth, 1000000,
			  SILC_PACKET_SUCCESS,
			  SILC_PACKET_FAILURE, -1);

  /* Start the protocol */
  silc_async_init(&connauth->op, silc_connauth_abort, NULL, connauth);
  silc_fsm_start(connauth->fsm, silc_connauth_st_initiator_start);

  return &connauth->op;
}
Example #20
0
SilcAsyncOperation
silc_client_connect_to_server(SilcClient client,
			      SilcClientConnectionParams *params,
			      SilcPublicKey public_key,
			      SilcPrivateKey private_key,
			      char *remote_host, int port,
			      SilcClientConnectCallback callback,
			      void *context)
{
  SilcClientConnection conn;

  SILC_LOG_DEBUG(("Connecting to server"));

  if (!client || !remote_host)
    return NULL;

  if (client->internal->run_callback) {
    SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
		    "callback has not been called yet."));
    return NULL;
  }

  /* Add new connection */
  conn = silc_client_add_connection(client, SILC_CONN_SERVER, TRUE, params,
				    public_key, private_key, remote_host,
				    port, callback, context);
  if (!conn) {
    callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
    return NULL;
  }

  client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
			     "Connecting to port %d of server %s",
			     port, remote_host);

  /* Signal connection machine to start connecting */
  conn->internal->connect = TRUE;
  return conn->internal->cop;
}
Example #21
0
void silc_net_close_listener(SilcNetListener listener)
{
  int i;

  SILC_LOG_DEBUG(("Closing network listener"));

  if (!listener)
    return;

  for (i = 0; i < listener->socks_count; i++) {
    SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i];
    l->sock.CancelAll();
    l->sock.Close();
    l->ss.Close();
    if (l->new_conn)
      delete l->new_conn;
    delete l;
  }

  silc_free(listener->socks);
  silc_free(listener);
}
Example #22
0
SilcAsyncOperation
silc_client_connect_to_client(SilcClient client,
			      SilcClientConnectionParams *params,
			      SilcPublicKey public_key,
			      SilcPrivateKey private_key,
			      char *remote_host, int port,
			      SilcClientConnectCallback callback,
			      void *context)
{
  SilcClientConnection conn;

  SILC_LOG_DEBUG(("Connecting to client"));

  if (!client || !remote_host)
    return NULL;

  if (client->internal->run_callback) {
    SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
		    "callback has not been called yet."));
    return NULL;
  }

  if (params)
    params->no_authentication = TRUE;

  /* Add new connection */
  conn = silc_client_add_connection(client, SILC_CONN_CLIENT, TRUE, params,
				    public_key, private_key, remote_host,
				    port, callback, context);
  if (!conn) {
    callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
    return NULL;
  }

  /* Signal connection machine to start connecting */
  conn->internal->connect = TRUE;
  return conn->internal->cop;
}
Example #23
0
static void
silc_client_listener_verify_key(SilcSKE ske,
				SilcPublicKey public_key,
				void *context,
				SilcSKEVerifyCbCompletion completion,
				void *completion_context)
{
  SilcClientConnection conn = context;
  SilcClient client = conn->client;
  SilcVerifyKeyContext verify;

  /* If we provided repository for SKE and we got here the key was not
     found from the repository. */
  if (conn->internal->params.repository &&
      !conn->internal->params.verify_notfound) {
    completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
	       completion_context);
    return;
  }

  SILC_LOG_DEBUG(("Verify remote public key"));

  verify = silc_calloc(1, sizeof(*verify));
  if (!verify) {
    completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
	       completion_context);
    return;
  }
  verify->ske = ske;
  verify->completion = completion;
  verify->completion_context = completion_context;

  /* Verify public key in application */
  client->internal->ops->verify_public_key(client, conn,
					   SILC_CONN_CLIENT, public_key,
					   silc_client_listener_verify_key_cb,
					   verify);
}
Example #24
0
SilcBool silc_server_send_new_id(SilcPacketStream stream,
				 SilcBool broadcast,
				 void *id, SilcIdType id_type)
{
  SilcBuffer idp;
  SilcBool ret = FALSE;

  if (!stream || !id)
    return ret;

  SILC_LOG_DEBUG(("Sending new ID (%s)", silc_id_render(id, id_type)));

  idp = silc_id_payload_encode(id, id_type);
  if (!idp)
    return ret;

  ret = silc_packet_send(stream, SILC_PACKET_NEW_ID,
			 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
			 idp->data, silc_buffer_len(idp));

  silc_buffer_free(idp);
  return ret;
}
Example #25
0
static SilcBool
silc_client_send_private_message_key_request(SilcClient client,
					     SilcClientConnection conn,
					     SilcClientEntry client_entry)
{
  const char *cipher, *hmac;

  SILC_LOG_DEBUG(("Sending private message key request"));

  cipher = silc_cipher_get_name(client_entry->internal.send_key);
  hmac = silc_hmac_get_name(client_entry->internal.hmac_send);

  /* Send the packet */
  return silc_packet_send_va_ext(conn->stream,
				 SILC_PACKET_PRIVATE_MESSAGE_KEY,
				 0, 0, NULL, SILC_ID_CLIENT,
				 &client_entry->id, NULL, NULL,
				 SILC_STR_UI_SHORT(strlen(cipher)),
				 SILC_STR_DATA(cipher, strlen(cipher)),
				 SILC_STR_UI_SHORT(strlen(hmac)),
				 SILC_STR_DATA(hmac, strlen(hmac)),
				 SILC_STR_END);
}
Example #26
0
static void
silc_server_accept_verify_key(SilcSKE ske,
			      SilcSKEPKType pk_type,
			      SilcPublicKey public_key,
			      void *context,
			      SilcSKEVerifyCbCompletion completion,
			      void *completion_context)
{
  SilcServerAccept ac = context;

  SILC_LOG_DEBUG(("Verifying public key"));

  if (pk_type != SILC_SKE_PK_TYPE_SILC) {
    SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
		      ac->hostname, ac->ip, ac->port, pk_type));
    completion(ac->data.ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
	       completion_context);
    return;
  }

  /* We accept all keys without explicit verification */
  completion(ac->data.ske, SILC_SKE_STATUS_OK, completion_context);
}
Example #27
0
SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
{
#ifdef SILC_THREADS
  SilcWin32Thread self = (SilcWin32Thread)thread;

  SILC_LOG_DEBUG(("Waiting for thread %p", self));

  if (!self->waitable)
    return FALSE;

  /* The thread is waitable thus we will free all memory after the
     WaitForSingleObject returns, the thread is destroyed after that. */
  WaitForSingleObject(self->thread, INFINITE);
  CloseHandle(self->thread);

  if (exit_value)
    *exit_value = NULL;

  return TRUE;
#else
  return FALSE;
#endif
}
Example #28
0
static void silc_client_ftp_session_free(SilcClientFtpSession session)
{
  SILC_LOG_DEBUG(("Free session %d", session->session_id));

  silc_schedule_task_del_by_context(session->client->schedule, session);

  silc_dlist_del(session->client->internal->ftp_sessions, session);

  /* Abort connecting  */
  if (session->op)
    silc_async_abort(session->op, NULL, NULL);

  /* Destroy SFTP */
  if (session->sftp) {
    if (session->initiator)
      silc_sftp_server_shutdown(session->sftp);
    else
      silc_sftp_client_shutdown(session->sftp);
  }
  if (session->fs)
    silc_sftp_fs_memory_free(session->fs);

  /* Destroy listener */
  if (session->listener)
    silc_client_listener_free(session->listener);

  /* Destroy wrapped stream */
  if (session->stream)
    silc_stream_destroy(session->stream);

  silc_client_unref_client(session->client, session->server_conn,
			   session->client_entry);
  silc_free(session->hostname);
  silc_free(session->filepath);
  silc_free(session->path);
  silc_free(session);
}
Example #29
0
SilcStream silc_buffer_stream_create(SilcStream stream,
				     SilcBufferReceiveCallback receiver,
				     void *context)
{
  SilcBufferStream bs;

  if (!stream || !receiver) {
    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
    return NULL;
  }

  bs = silc_calloc(1, sizeof(*bs));
  if (!bs)
    return NULL;

  SILC_LOG_DEBUG(("Created new buffer stream %p", bs));

  bs->ops = &silc_buffer_stream_ops;
  bs->stream = stream;
  bs->receiver = receiver;
  bs->context = context;
  bs->inbuf = silc_buffer_alloc(32);
  bs->outbuf = silc_buffer_alloc(0);
  if (!bs->inbuf || !bs->outbuf) {
    silc_buffer_free(bs->inbuf);
    silc_buffer_free(bs->outbuf);
    silc_free(bs);
    return NULL;
  }

  /* Set IO callback to the underlaying stream */
  silc_stream_set_notifier(bs->stream,
			   silc_stream_get_schedule(bs->stream),
			   silc_buffer_stream_io, bs);

  return (SilcStream)bs;
}
Example #30
0
SilcBool silc_file_stat(const char *filename, SilcBool follow_symlinks,
			SilcFileStat return_stat)
{
  struct stat status;

  if (silc_unlikely(!filename)) {
    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
    return FALSE;
  }

  SILC_LOG_DEBUG(("Get status for file '%s'", filename));

  if (!follow_symlinks) {
    if (silc_unlikely(stat(filename, &status) != 0)) {
      silc_set_errno_posix(errno);
      return FALSE;
    }
  } else {
#ifdef HAVE_LSTAT
    if (silc_unlikely(lstat(filename, &status) != 0)) {
      silc_set_errno_posix(errno);
      return FALSE;
    }
#else
    if (silc_unlikely(stat(filename, &status) != 0)) {
      silc_set_errno_posix(errno);
      return FALSE;
    }
#endif /* HAVE_LSTAT */
  }

  if (return_stat)
    silc_file_fill_stat(&status, return_stat);

  return TRUE;
}