/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright © 2009 Codethink Limited
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2 of the licence or (at
 * your option) any later version.
 *
 * See the included COPYING file for more information.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gunixconnection.h"
#include "gnetworking.h"
#include "gsocket.h"
#include "gsocketcontrolmessage.h"
#include "gunixcredentialsmessage.h"
#include "gunixfdmessage.h"
#include "glibintl.h"

#include <errno.h>
#include <string.h>
#include <unistd.h>

/**
 * SECTION:gunixconnection
 * @title: GUnixConnection
 * @short_description: A UNIX domain GSocketConnection
 * @include: gio/gunixconnection.h
 * @see_also: #GSocketConnection.
 *
 * This is the subclass of #GSocketConnection that is created
 * for UNIX domain sockets.
 *
 * It contains functions to do some of the UNIX socket specific
 * functionality like passing file descriptors.
 *
 * Note that <filename>&lt;gio/gunixconnection.h&gt;</filename> belongs to
 * the UNIX-specific GIO interfaces, thus you have to use the
 * <filename>gio-unix-2.0.pc</filename> pkg-config file when using it.
 *
 * Since: 2.22
 */

G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection,
			 G_TYPE_SOCKET_CONNECTION,
  g_socket_connection_factory_register_type (g_define_type_id,
					     G_SOCKET_FAMILY_UNIX,
					     G_SOCKET_TYPE_STREAM,
					     G_SOCKET_PROTOCOL_DEFAULT);
			 );

/**
 * g_unix_connection_send_fd:
 * @connection: a #GUnixConnection
 * @fd: a file descriptor
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: (allow-none): #GError for error reporting, or %NULL to ignore.
 *
 * Passes a file descriptor to the receiving side of the
 * connection. The receiving end has to call g_unix_connection_receive_fd()
 * to accept the file descriptor.
 *
 * As well as sending the fd this also writes a single byte to the
 * stream, as this is required for fd passing to work on some
 * implementations.
 *
 * Returns: a %TRUE on success, %NULL on error.
 *
 * Since: 2.22
 */
gboolean
g_unix_connection_send_fd (GUnixConnection  *connection,
                           gint              fd,
                           GCancellable     *cancellable,
                           GError          **error)
{
  GSocketControlMessage *scm;
  GSocket *socket;

  g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
  g_return_val_if_fail (fd >= 0, FALSE);

  scm = g_unix_fd_message_new ();

  if (!g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (scm), fd, error))
    {
      g_object_unref (scm);
      return FALSE;
    }

  g_object_get (connection, "socket", &socket, NULL);
  if (g_socket_send_message (socket, NULL, NULL, 0, &scm, 1, 0, cancellable, error) != 1)
    /* XXX could it 'fail' with zero? */
    {
      g_object_unref (socket);
      g_object_unref (scm);

      return FALSE;
    }

  g_object_unref (socket);
  g_object_unref (scm);

  return TRUE;
}

/**
 * g_unix_connection_receive_fd:
 * @connection: a #GUnixConnection
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
 * @error: (allow-none): #GError for error reporting, or %NULL to ignore
 *
 * Receives a file descriptor from the sending end of the connection.
 * The sending end has to call g_unix_connection_send_fd() for this
 * to work.
 *
 * As well as reading the fd this also reads a single byte from the
 * stream, as this is required for fd passing to work on some
 * implementations.
 *
 * Returns: a file descriptor on success, -1 on error.
 *
 * Since: 2.22
 **/
gint
g_unix_connection_receive_fd (GUnixConnection  *connection,
                              GCancellable     *cancellable,
                              GError          **error)
{
  GSocketControlMessage **scms;
  gint *fds, nfd, fd, nscm;
  GUnixFDMessage *fdmsg;
  GSocket *socket;

  g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), -1);

  g_object_get (connection, "socket", &socket, NULL);
  if (g_socket_receive_message (socket, NULL, NULL, 0,
                                &scms, &nscm, NULL, cancellable, error) != 1)
    /* XXX it _could_ 'fail' with zero. */
    {
      g_object_unref (socket);

      return -1;
    }

  g_object_unref (socket);

  if (nscm != 1)
    {
      gint i;

      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
		   _("Expecting 1 control message, got %d"), nscm);

      for (i = 0; i < nscm; i++)
        g_object_unref (scms[i]);

      g_free (scms);

      return -1;
    }

  if (!G_IS_UNIX_FD_MESSAGE (scms[0]))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Unexpected type of ancillary data"));
      g_object_unref (scms[0]);
      g_free (scms);

      return -1;
    }

  fdmsg = G_UNIX_FD_MESSAGE (scms[0]);
  g_free (scms);

  fds = g_unix_fd_message_steal_fds (fdmsg, &nfd);
  g_object_unref (fdmsg);

  if (nfd != 1)
    {
      gint i;

      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
		   _("Expecting one fd, but got %d\n"), nfd);

      for (i = 0; i < nfd; i++)
        close (fds[i]);

      g_free (fds);

      return -1;
    }

  fd = *fds;
  g_free (fds);

  if (fd < 0)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Received invalid fd"));
      fd = -1;
    }

  return fd;
}

static void
g_unix_connection_init (GUnixConnection *connection)
{
}

static void
g_unix_connection_class_init (GUnixConnectionClass *class)
{
}

/* TODO: Other stuff we might want to add are:
void                    g_unix_connection_send_fd_async                 (GUnixConnection      *connection,
                                                                         gint                  fd,
                                                                         gboolean              close,
                                                                         gint                  io_priority,
                                                                         GAsyncReadyCallback   callback,
                                                                         gpointer              user_data);
gboolean                g_unix_connection_send_fd_finish                (GUnixConnection      *connection,
                                                                         GError              **error);

gboolean                g_unix_connection_send_fds                      (GUnixConnection      *connection,
                                                                         gint                 *fds,
                                                                         gint                  nfds,
                                                                         GError              **error);
void                    g_unix_connection_send_fds_async                (GUnixConnection      *connection,
                                                                         gint                 *fds,
                                                                         gint                  nfds,
                                                                         gint                  io_priority,
                                                                         GAsyncReadyCallback   callback,
                                                                         gpointer              user_data);
gboolean                g_unix_connection_send_fds_finish               (GUnixConnection      *connection,
                                                                         GError              **error);

void                    g_unix_connection_receive_fd_async              (GUnixConnection      *connection,
                                                                         gint                  io_priority,
                                                                         GAsyncReadyCallback   callback,
                                                                         gpointer              user_data);
gint                    g_unix_connection_receive_fd_finish             (GUnixConnection      *connection,
                                                                         GError              **error);


gboolean                g_unix_connection_send_fake_credentials         (GUnixConnection      *connection,
                                                                         guint64               pid,
                                                                         guint64               uid,
                                                                         guint64               gid,
                                                                         GError              **error);
void                    g_unix_connection_send_fake_credentials_async   (GUnixConnection      *connection,
                                                                         guint64               pid,
                                                                         guint64               uid,
                                                                         guint64               gid,
                                                                         gint                  io_priority,
                                                                         GAsyncReadyCallback   callback,
                                                                         gpointer              user_data);
gboolean                g_unix_connection_send_fake_credentials_finish  (GUnixConnection      *connection,
                                                                         GError              **error);

gboolean                g_unix_connection_create_pair                   (GUnixConnection     **one,
                                                                         GUnixConnection     **two,
                                                                         GError              **error);
*/


/**
 * g_unix_connection_send_credentials:
 * @connection: A #GUnixConnection.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Passes the credentials of the current user the receiving side
 * of the connection. The receiving end has to call
 * g_unix_connection_receive_credentials() (or similar) to accept the
 * credentials.
 *
 * As well as sending the credentials this also writes a single NUL
 * byte to the stream, as this is required for credentials passing to
 * work on some implementations.
 *
 * Other ways to exchange credentials with a foreign peer includes the
 * #GUnixCredentialsMessage type and g_socket_get_credentials() function.
 *
 * Returns: %TRUE on success, %FALSE if @error is set.
 *
 * Since: 2.26
 */
gboolean
g_unix_connection_send_credentials (GUnixConnection      *connection,
                                    GCancellable         *cancellable,
                                    GError              **error)
{
  GCredentials *credentials;
  GSocketControlMessage *scm;
  GSocket *socket;
  gboolean ret;
  GOutputVector vector;
  guchar nul_byte[1] = {'\0'};
  gint num_messages;

  g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = FALSE;

  credentials = g_credentials_new ();

  vector.buffer = &nul_byte;
  vector.size = 1;

  if (g_unix_credentials_message_is_supported ())
    {
      scm = g_unix_credentials_message_new_with_credentials (credentials);
      num_messages = 1;
    }
  else
    {
      scm = NULL;
      num_messages = 0;
    }

  g_object_get (connection, "socket", &socket, NULL);
  if (g_socket_send_message (socket,
                             NULL, /* address */
                             &vector,
                             1,
                             &scm,
                             num_messages,
                             G_SOCKET_MSG_NONE,
                             cancellable,
                             error) != 1)
    {
      g_prefix_error (error, _("Error sending credentials: "));
      goto out;
    }

  ret = TRUE;

 out:
  g_object_unref (socket);
  if (scm != NULL)
    g_object_unref (scm);
  g_object_unref (credentials);
  return ret;
}

static void
send_credentials_async_thread (GTask         *task,
			       gpointer       source_object,
			       gpointer       task_data,
			       GCancellable  *cancellable)
{
  GError *error = NULL;

  if (g_unix_connection_send_credentials (G_UNIX_CONNECTION (source_object),
					  cancellable,
					  &error))
    g_task_return_boolean (task, TRUE);
  else
    g_task_return_error (task, error);
  g_object_unref (task);
}

/**
 * g_unix_connection_send_credentials_async:
 * @connection: A #GUnixConnection.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Asynchronously send credentials.
 *
 * For more details, see g_unix_connection_send_credentials() which is
 * the synchronous version of this call.
 *
 * When the operation is finished, @callback will be called. You can then call
 * g_unix_connection_send_credentials_finish() to get the result of the operation.
 *
 * Since: 2.32
 **/
void
g_unix_connection_send_credentials_async (GUnixConnection      *connection,
                                          GCancellable         *cancellable,
                                          GAsyncReadyCallback   callback,
                                          gpointer              user_data)
{
  GTask *task;

  task = g_task_new (connection, cancellable, callback, user_data);

  g_task_run_in_thread (task, send_credentials_async_thread);
}

/**
 * g_unix_connection_send_credentials_finish:
 * @connection: A #GUnixConnection.
 * @result: a #GAsyncResult.
 * @error: a #GError, or %NULL
 *
 * Finishes an asynchronous send credentials operation started with
 * g_unix_connection_send_credentials_async().
 *
 * Returns: %TRUE if the operation was successful, otherwise %FALSE.
 *
 * Since: 2.32
 **/
gboolean
g_unix_connection_send_credentials_finish (GUnixConnection *connection,
                                           GAsyncResult    *result,
                                           GError         **error)
{
  g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);

  return g_task_propagate_boolean (G_TASK (result), error);
}

/**
 * g_unix_connection_receive_credentials:
 * @connection: A #GUnixConnection.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Receives credentials from the sending end of the connection.  The
 * sending end has to call g_unix_connection_send_credentials() (or
 * similar) for this to work.
 *
 * As well as reading the credentials this also reads (and discards) a
 * single byte from the stream, as this is required for credentials
 * passing to work on some implementations.
 *
 * Other ways to exchange credentials with a foreign peer includes the
 * #GUnixCredentialsMessage type and g_socket_get_credentials() function.
 *
 * Returns: (transfer full): Received credentials on success (free with
 * g_object_unref()), %NULL if @error is set.
 *
 * Since: 2.26
 */
GCredentials *
g_unix_connection_receive_credentials (GUnixConnection      *connection,
                                       GCancellable         *cancellable,
                                       GError              **error)
{
  GCredentials *ret;
  GSocketControlMessage **scms;
  gint nscm;
  GSocket *socket;
  gint n;
  gssize num_bytes_read;
#ifdef __linux__
  gboolean turn_off_so_passcreds;
#endif

  g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  ret = NULL;
  scms = NULL;

  g_object_get (connection, "socket", &socket, NULL);

  /* On Linux, we need to turn on SO_PASSCRED if it isn't enabled
   * already. We also need to turn it off when we're done.  See
   * #617483 for more discussion.
   */
#ifdef __linux__
  {
    gint opt_val;

    turn_off_so_passcreds = FALSE;
    opt_val = 0;
    if (!g_socket_get_option (socket,
			      SOL_SOCKET,
			      SO_PASSCRED,
			      &opt_val,
			      NULL))
      {
        g_set_error (error,
                     G_IO_ERROR,
                     g_io_error_from_errno (errno),
                     _("Error checking if SO_PASSCRED is enabled for socket: %s"),
                     strerror (errno));
        goto out;
      }
    if (opt_val == 0)
      {
        if (!g_socket_set_option (socket,
				  SOL_SOCKET,
				  SO_PASSCRED,
				  TRUE,
				  NULL))
          {
            g_set_error (error,
                         G_IO_ERROR,
                         g_io_error_from_errno (errno),
                         _("Error enabling SO_PASSCRED: %s"),
                         strerror (errno));
            goto out;
          }
        turn_off_so_passcreds = TRUE;
      }
  }
#endif

  g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE);
  num_bytes_read = g_socket_receive_message (socket,
                                             NULL, /* GSocketAddress **address */
                                             NULL,
                                             0,
                                             &scms,
                                             &nscm,
                                             NULL,
                                             cancellable,
                                             error);
  if (num_bytes_read != 1)
    {
      /* Handle situation where g_socket_receive_message() returns
       * 0 bytes and not setting @error
       */
      if (num_bytes_read == 0 && error != NULL && *error == NULL)
        {
          g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_FAILED,
                               _("Expecting to read a single byte for receiving credentials but read zero bytes"));
        }
      goto out;
    }

  if (g_unix_credentials_message_is_supported () &&
      /* Fall back on get_credentials if the other side didn't send the credentials */
      nscm > 0)
    {
      if (nscm != 1)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       _("Expecting 1 control message, got %d"),
                       nscm);
          goto out;
        }

      if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
        {
          g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_FAILED,
                               _("Unexpected type of ancillary data"));
          goto out;
        }

      ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
      g_object_ref (ret);
    }
  else
    {
      if (nscm != 0)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       _("Not expecting control message, but got %d"),
                       nscm);
          goto out;
        }
      else
        {
          ret = g_socket_get_credentials (socket, error);
        }
    }

 out:

#ifdef __linux__
  if (turn_off_so_passcreds)
    {
      if (!g_socket_set_option (socket,
				SOL_SOCKET,
				SO_PASSCRED,
				FALSE,
				NULL))
        {
          g_set_error (error,
                       G_IO_ERROR,
                       g_io_error_from_errno (errno),
                       _("Error while disabling SO_PASSCRED: %s"),
                       strerror (errno));
          goto out;
        }
    }
#endif

  if (scms != NULL)
    {
      for (n = 0; n < nscm; n++)
        g_object_unref (scms[n]);
      g_free (scms);
    }
  g_object_unref (socket);
  return ret;
}

static void
receive_credentials_async_thread (GTask         *task,
				  gpointer       source_object,
				  gpointer       task_data,
				  GCancellable  *cancellable)
{
  GCredentials *creds;
  GError *error = NULL;

  creds = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (source_object),
                                                 cancellable,
                                                 &error);
  if (creds)
    g_task_return_pointer (task, creds, g_object_unref);
  else
    g_task_return_error (task, error);
  g_object_unref (task);
}

/**
 * g_unix_connection_receive_credentials_async:
 * @connection: A #GUnixConnection.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Asynchronously receive credentials.
 *
 * For more details, see g_unix_connection_receive_credentials() which is
 * the synchronous version of this call.
 *
 * When the operation is finished, @callback will be called. You can then call
 * g_unix_connection_receive_credentials_finish() to get the result of the operation.
 *
 * Since: 2.32
 **/
void
g_unix_connection_receive_credentials_async (GUnixConnection      *connection,
                                              GCancellable         *cancellable,
                                              GAsyncReadyCallback   callback,
                                              gpointer              user_data)
{
  GTask *task;

  task = g_task_new (connection, cancellable, callback, user_data);

  g_task_run_in_thread (task, receive_credentials_async_thread);
}

/**
 * g_unix_connection_receive_credentials_finish:
 * @connection: A #GUnixConnection.
 * @result: a #GAsyncResult.
 * @error: a #GError, or %NULL
 *
 * Finishes an asynchronous receive credentials operation started with
 * g_unix_connection_receive_credentials_async().
 *
 * Returns: (transfer full): a #GCredentials, or %NULL on error.
 *     Free the returned object with g_object_unref().
 *
 * Since: 2.32
 **/
GCredentials *
g_unix_connection_receive_credentials_finish (GUnixConnection *connection,
                                              GAsyncResult    *result,
                                              GError         **error)
{
  g_return_val_if_fail (g_task_is_valid (result, connection), NULL);

  return g_task_propagate_pointer (G_TASK (result), error);
}
