Exemplo n.º 1
0
static void add_connection(const char *path, DBusMessageIter *properties,
			void *user_data)
{
	struct connection_data *data;
	int err;
	char *ident = get_ident(path);
	connman_bool_t found = FALSE;

	data = g_hash_table_lookup(vpn_connections, ident);
	if (data != NULL) {
		/*
		 * We might have a dummy connection struct here that
		 * was created by configuration_create_reply() so in
		 * that case just continue.
		 */
		if (data->connect_pending == FALSE)
			return;

		found = TRUE;
	} else {
		data = create_connection_data(path);
		if (data == NULL)
			return;
	}

	DBG("data %p path %s", data, path);

	while (dbus_message_iter_get_arg_type(properties) ==
			DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		const char *key;
		char *str;

		dbus_message_iter_recurse(properties, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (g_str_equal(key, "State") == TRUE) {
			dbus_message_iter_get_basic(&value, &str);
			DBG("state %s -> %s", data->state, str);
			data->state = g_strdup(str);
		} else if (g_str_equal(key, "IPv4") == TRUE) {
			extract_ip(&value, AF_INET, data);
		} else if (g_str_equal(key, "IPv6") == TRUE) {
			extract_ip(&value, AF_INET6, data);
		} else if (g_str_equal(key, "Name") == TRUE) {
			dbus_message_iter_get_basic(&value, &str);
			data->name = g_strdup(str);
		} else if (g_str_equal(key, "Type") == TRUE) {
			dbus_message_iter_get_basic(&value, &str);
			data->type = g_strdup(str);
		} else if (g_str_equal(key, "Host") == TRUE) {
			dbus_message_iter_get_basic(&value, &str);
			data->host = g_strdup(str);
		} else if (g_str_equal(key, "Domain") == TRUE) {
			dbus_message_iter_get_basic(&value, &str);
			data->domain = g_strdup(str);
		} else if (g_str_equal(key, "Nameservers") == TRUE) {
			extract_nameservers(&value, data);
		} else if (g_str_equal(key, "Index") == TRUE) {
			dbus_message_iter_get_basic(&value, &data->index);
		} else {
			if (dbus_message_iter_get_arg_type(&value) ==
							DBUS_TYPE_STRING) {
				dbus_message_iter_get_basic(&value, &str);
				g_hash_table_replace(data->setting_strings,
						g_strdup(key), g_strdup(str));
			} else {
				DBG("unknown key %s", key);
			}
		}

		dbus_message_iter_next(properties);
	}

	if (found == FALSE)
		g_hash_table_insert(vpn_connections, g_strdup(data->ident),
									data);

	err = create_provider(data, user_data);
	if (err < 0)
		goto out;

	resolv_host_addr(data);

	if (data->connect_pending == TRUE)
		connect_provider(data, data->cb_data);

	return;

out:
	DBG("removing %s", data->ident);
	g_hash_table_remove(vpn_connections, data->ident);
}
Exemplo n.º 2
0
int connect_session(connection_data *connection, char *server_ip, uint16_t server_port, uint16_t client_port) 
{
  handshake_packet syn_packet, *received_packet = NULL;
  struct sockaddr_in server, client;
  socklen_t client_len;
  int i = 0, return_value = 0;
  char *ptr = NULL;
  char *client_ip = malloc(sizeof(char) * 16);
  uint32_t sock_fd = 0;

  srand(time(NULL));
  net_init();

#ifdef _DEBUG_
  printf("Before creating socket.\n");
#endif

  if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    {
      perror("socket() failed");
      return -1;
    }
#ifdef _DEBUG_
  printf("After creating socket.\n");
  printf("Creating sockaddr_in to find out client ip\n");
#endif

  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr(server_ip);
  server.sin_port = htons(server_port);
#ifdef _DEBUG_
  printf("Using a connected UDP socket to find out client ip\n");
#endif

  if (connect(sock_fd, (struct sockaddr *)&server, sizeof(server)) < 0) 
    {
      perror("connect() failed (in trying to find out client ip)");
      return -1;
    }

  client_len = sizeof(client);
#ifdef _DEBUG_
  printf("Using getsockname() to get local IP the socket bound to\n");
#endif

  if (getsockname(sock_fd, (struct sockaddr *)&client, &client_len) < 0) 
    {
      perror("getsockname() failed when trying to find out client ip");
      return -1;
    }
#ifdef _DEBUG_
  printf("Fetching the IP address from client sockaddr struct\n");
#endif

  if (inet_ntop(AF_INET, &client.sin_addr, client_ip, 16) < 0)
    {
      perror("inet_ntop() failed to get client ip");
      return -1;
    }

  CLOSE(sock_fd);
#ifdef _DEBUG_
  printf("Client ip in buffer: %s\n", client_ip);
  printf("Before creating socket.\n");
#endif

  if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
    {
      perror("socket() failed");
      return -1;
    }
#ifdef _DEBUG_
  printf("After creating socket.\n");
  printf("Preparing SYN packet.\n");
#endif

  syn_packet.proto_id = "herp";
  syn_packet.packet_type = HANDSHAKE;
  syn_packet.client_ip = client_ip;
  syn_packet.client_port = client_port;
  syn_packet.client_id = rand();
  syn_packet.flags = SYN;
  syn_packet.trailer = "derp";

#ifdef _DEBUG_
  printf("Converting to string.\n");
#endif
  ptr = packet_to_string(&syn_packet, HANDSHAKE);
#ifdef _DEBUG_
  printf("Setting up listening socket.\n");
#endif

  connection = create_connection_data(client_ip, client_port, syn_packet.client_id, sock_fd, connection);

#ifdef _DEBUG_
  printf("Binding socket.\n");
#endif

  if (bind(connection->sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
    {
      perror("Bind() failed");
      CLOSE(connection->sock_fd);
      return -1;
    }
#ifdef _DEBUG_
  printf("Creating connection_data.\n");
#endif

  connection = create_connection_data(server_ip, server_port, syn_packet.client_id, connection->sock_fd, connection);
  connection->client_ip = client_ip;
  connection->client_port = client_port;

  for(i = 0; i < 3; i++) 
    {
#ifdef _DEBUG_
      printf("Try %d\n", i+1);
      printf("Struct data: %d %d %d socket: %d client_id: %d\n", connection->destination->sin_family, connection->destination->sin_port, connection->destination->sin_addr.s_addr, connection->sock_fd, connection->client_id);
#endif

      if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
	{
	  perror("sendto() failed");
	  CLOSE(connection->sock_fd);
	  return -1;
	}

#ifdef _DEBUG_
      printf("Entering listening mode.\n");
#endif

      ptr = listen_socket(connection, 5, 0);

#ifdef _DEBUG_
      if (ptr != NULL)
	printf("Received string: %s\n", ptr);
#endif
      if (ptr != NULL) {

	if (atoi(&ptr[5]) == HANDSHAKE) 
	  {
#ifdef _DEBUG_
	    printf("It is a handshake packet outside recv_data!\n");
#endif
	    received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE);
#ifdef _DEBUG_
	    printf("ptr size %d\n", strlen(ptr));
#endif
	    if (!is_packet(received_packet, HANDSHAKE) && !strncmp(connection->client_ip, received_packet->client_ip, strlen(connection->client_ip)) && (received_packet->flags == ACK)) 
	      {
#ifdef _DEBUG_
		printf("ACK packet received: %p.\n", connection);
#endif
		connection->client_id = received_packet->client_id;
		free(client_ip);
		return 0;
	      }
	  } 
	else 
	  {
#ifdef _DEBUG_
	    printf("Is not a packet :(\n");
#endif
	    break;
	  }
      }
    } 

  fprintf(stderr, "No server responded with a ACK, stopping connection attempts...\n");
  free(client_ip);
  return 1;
}
Exemplo n.º 3
0
static int create_configuration(DBusMessage *msg, connection_ready_cb callback)
{
	DBusMessage *new_msg = NULL;
	DBusPendingCall *call;
	DBusMessageIter iter, array, new_iter, new_dict;
	const char *type = NULL, *name = NULL;
	const char *host = NULL, *domain = NULL;
	char *ident, *me = NULL;
	int err = 0;
	dbus_bool_t result;
	struct connection_data *data;
	struct config_create_data *user_data = NULL;
	GSList *networks = NULL;

	/*
	 * We copy the old message data into new message. We cannot
	 * just use the old message as is because the user route
	 * information is not in the same format in vpnd.
	 */
	new_msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
	dbus_message_iter_init_append(new_msg, &new_iter);
	connman_dbus_dict_open(&new_iter, &new_dict);

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_recurse(&iter, &array);

	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		void *item_value;
		const char *key;
		int value_type;

		dbus_message_iter_recurse(&array, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		value_type = dbus_message_iter_get_arg_type(&value);
		item_value = NULL;

		switch (value_type) {
		case DBUS_TYPE_STRING:
			dbus_message_iter_get_basic(&value, &item_value);

			if (g_str_equal(key, "Type") == TRUE) {
				type = (const char *)item_value;
			} else if (g_str_equal(key, "Name") == TRUE) {
				name = (const char *)item_value;
			} else if (g_str_equal(key, "Host") == TRUE) {
				host = (const char *)item_value;
			} else if (g_str_equal(key, "VPN.Domain") == TRUE) {
				domain = (const char *)item_value;
			}

			DBG("%s %s", key, (char *)item_value);

			if (item_value != NULL)
				connman_dbus_dict_append_basic(&new_dict, key,
						value_type, &item_value);
			break;
		case DBUS_TYPE_ARRAY:
			if (g_str_equal(key, "Networks") == TRUE) {
				networks = get_user_networks(&value);
				connman_dbus_dict_append_array(&new_dict,
							"UserRoutes",
							DBUS_TYPE_DICT_ENTRY,
							append_routes,
							networks);
			}
			break;
		}

		dbus_message_iter_next(&array);
	}

	connman_dbus_dict_close(&new_iter, &new_dict);

	DBG("VPN type %s name %s host %s domain %s networks %p",
		type, name, host, domain, networks);

	if (host == NULL || domain == NULL) {
		err = -EINVAL;
		goto done;
	}

	if (type == NULL || name == NULL) {
		err = -EOPNOTSUPP;
		goto done;
	}

	ident = g_strdup_printf("%s_%s", host, domain);
	set_dbus_ident(ident);

	DBG("ident %s", ident);

	data = g_hash_table_lookup(vpn_connections, ident);
	if (data != NULL) {
		if (data->call != NULL || data->cb_data != NULL) {
			DBG("create configuration call already pending");
			err = -EINPROGRESS;
			goto done;
		}
	} else {
		char *path = g_strdup_printf("%s/connection/%s", VPN_PATH,
								ident);
		data = create_connection_data(path);
		g_free(path);

		if (data == NULL) {
			err = -ENOMEM;
			goto done;
		}

		g_hash_table_insert(vpn_connections, g_strdup(ident), data);
	}

	/*
	 * User called net.connman.Manager.ConnectProvider if we are here.
	 * So use the data from original message in the new msg.
	 */
	me = g_strdup(dbus_message_get_destination(msg));

	dbus_message_set_interface(new_msg, VPN_MANAGER_INTERFACE);
	dbus_message_set_path(new_msg, "/");
	dbus_message_set_destination(new_msg, VPN_SERVICE);
	dbus_message_set_sender(new_msg, me);
	dbus_message_set_member(new_msg, "Create");

	user_data = g_try_new0(struct config_create_data, 1);
	if (user_data == NULL) {
		err = -ENOMEM;
		goto done;
	}

	user_data->callback = callback;
	user_data->message = dbus_message_ref(msg);
	user_data->path = NULL;

	DBG("cb %p msg %p", user_data, msg);

	result = dbus_connection_send_with_reply(connection, new_msg,
						&call, DBUS_TIMEOUT);
	if (result == FALSE || call == NULL) {
		err = -EIO;
		goto done;
	}

	dbus_pending_call_set_notify(call, configuration_create_reply,
							user_data, NULL);
	data->call = call;

done:
	if (new_msg != NULL)
		dbus_message_unref(new_msg);

	if (networks != NULL)
		g_slist_free_full(networks, destroy_route);

	g_free(me);
	return err;
}
Exemplo n.º 4
0
int accept_session (connection_data *connection, uint16_t port, int client_id) 
{
  handshake_packet ack_packet, *received_packet = NULL;
  static int first_time = 1;
  static uint16_t sock_fd;
  char *ptr = NULL;

  if (first_time) 
    {
#ifdef _DEBUG_
      printf("Inside a first_time only\n");
#endif
      net_init();
#ifdef _DEBUG_
      printf("Before creating socket.\n");
#endif

      if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) 
	{
	  perror("socket() failed");
	  return -1;
	}
#ifdef _DEBUG_
      printf("After creating socket.\n");
#endif
    }

  connection = create_connection_data("0.0.0.0", port, 0, sock_fd, connection);

  if (first_time) 
    {
#ifdef _DEBUG_
      printf("Setting up listening socket.\n");
      printf("Binding socket.\n");
#endif
      if (bind(sock_fd, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
	{
	  perror("Bind() failed");
	  CLOSE(sock_fd);
	  return -1;
	}
      first_time = 0;
    }

  while(1) 
    {
#ifdef _DEBUG_
      printf("Listening for SYN packet.\n");
      printf("connection->sock_fd: %d\n", connection->sock_fd);
#endif
      ptr = listen_socket(connection, 60, 0);
#ifdef _DEBUG_
      printf("Received string: %s\n", ptr);
#endif
      if (ptr != NULL) {

        if (atoi(&ptr[5]) == HANDSHAKE) 
          {
#ifdef _DEBUG_
            printf("Converting from string to packet.\n");
#endif
            received_packet = (handshake_packet *)string_to_packet(ptr, HANDSHAKE);
#ifdef _DEBUG_
            printf("ptr size %d\n", strlen(ptr));
            printf("It is a handshake packet outside recv_data!\n");
            printf("Content: %s %u %s %u %u %s\n", received_packet->proto_id, received_packet->packet_type, received_packet->client_ip, received_packet->client_port, received_packet->flags, received_packet->trailer);
#endif

            if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == SYN) 
              {
#ifdef _DEBUG_
                printf("SYN Packet received.\n");
#endif
                break;
              }
            else if (!is_packet(received_packet, HANDSHAKE) && received_packet->flags == RST) 
              {
                connection_termination(connection, SERVER);
                return 1;
              }
          }
      }
    }
#ifdef _DEBUG_
  printf("Preparing ACK packet.\n");
#endif

  ack_packet.proto_id = "herp";
  ack_packet.packet_type = HANDSHAKE;
  ack_packet.client_ip = received_packet->client_ip;
  ack_packet.client_port = received_packet->client_port;
  ack_packet.client_id = client_id;
  ack_packet.flags = ACK;
  ack_packet.trailer = "derp";
#ifdef _DEBUG_
  printf("Creating connection_data struct.\n");
#endif

  connection = create_connection_data(received_packet->client_ip, received_packet->client_port, client_id, connection->sock_fd, connection);
#ifdef _DEBUG_
  printf("Converting packet_to_string.\n");
#endif

  ptr = packet_to_string(&ack_packet, HANDSHAKE);

#ifdef _DEBUG_
  printf("Sending ACK packet.\n");
#endif

  if (sendto(connection->sock_fd, ptr, strlen(ptr), 0, (struct sockaddr *)connection->destination, sizeof(struct sockaddr)) < 0) 
    {
      perror("sendto() failed");
      CLOSE(connection->sock_fd);
      return -1;
    }
#ifdef _DEBUG_
  printf("pointer address %p\n", connection);
#endif
  free(received_packet);
  free(ptr);
  return 0;
}