*
* ConnMan VPN daemon
*
- * Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010,2013-2014 BMW Car IT GmbH.
+ * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <connman/vpn-dbus.h>
#include "../vpn-provider.h"
+#include "../vpn-agent.h"
#include "vpn.h"
int type;
} pptp_options[] = {
{ "PPTP.User", "user", NULL, OPT_STRING },
- { "PPTP.EchoFailure", "lcp-echo-failure", "0", OPT_STRING },
- { "PPTP.EchoInterval", "lcp-echo-interval", "0", OPT_STRING },
- { "PPTP.Debug", "debug", NULL, OPT_STRING },
- { "PPTP.RefuseEAP", "refuse-eap", NULL, OPT_BOOL },
- { "PPTP.RefusePAP", "refuse-pap", NULL, OPT_BOOL },
- { "PPTP.RefuseCHAP", "refuse-chap", NULL, OPT_BOOL },
- { "PPTP.RefuseMSCHAP", "refuse-mschap", NULL, OPT_BOOL },
- { "PPTP.RefuseMSCHAP2", "refuse-mschapv2", NULL, OPT_BOOL },
- { "PPTP.NoBSDComp", "nobsdcomp", NULL, OPT_BOOL },
- { "PPTP.NoDeflate", "nodeflate", NULL, OPT_BOOL },
- { "PPTP.RequirMPPE", "require-mppe", NULL, OPT_BOOL },
- { "PPTP.RequirMPPE40", "require-mppe-40", NULL, OPT_BOOL },
- { "PPTP.RequirMPPE128", "require-mppe-128", NULL, OPT_BOOL },
- { "PPTP.RequirMPPEStateful", "mppe-stateful", NULL, OPT_BOOL },
- { "PPTP.NoVJ", "no-vj-comp", NULL, OPT_BOOL },
+ { "PPPD.EchoFailure", "lcp-echo-failure", "0", OPT_STRING },
+ { "PPPD.EchoInterval", "lcp-echo-interval", "0", OPT_STRING },
+ { "PPPD.Debug", "debug", NULL, OPT_STRING },
+ { "PPPD.RefuseEAP", "refuse-eap", NULL, OPT_BOOL },
+ { "PPPD.RefusePAP", "refuse-pap", NULL, OPT_BOOL },
+ { "PPPD.RefuseCHAP", "refuse-chap", NULL, OPT_BOOL },
+ { "PPPD.RefuseMSCHAP", "refuse-mschap", NULL, OPT_BOOL },
+ { "PPPD.RefuseMSCHAP2", "refuse-mschapv2", NULL, OPT_BOOL },
+ { "PPPD.NoBSDComp", "nobsdcomp", NULL, OPT_BOOL },
+ { "PPPD.NoDeflate", "nodeflate", NULL, OPT_BOOL },
+ { "PPPD.RequirMPPE", "require-mppe", NULL, OPT_BOOL },
+ { "PPPD.RequirMPPE40", "require-mppe-40", NULL, OPT_BOOL },
+ { "PPPD.RequirMPPE128", "require-mppe-128", NULL, OPT_BOOL },
+ { "PPPD.RequirMPPEStateful", "mppe-stateful", NULL, OPT_BOOL },
+ { "PPPD.NoVJ", "novj", NULL, OPT_BOOL },
};
static DBusConnection *connection;
struct vpn_provider *provider = user_data;
DBusMessage *reply;
- if (dbus_message_get_no_reply(msg) == TRUE)
+ if (dbus_message_get_no_reply(msg))
return NULL;
user = vpn_provider_get_string(provider, "PPTP.User");
passwd = vpn_provider_get_string(provider, "PPTP.Password");
- if (user == NULL || strlen(user) == 0 ||
- passwd == NULL || strlen(passwd) == 0)
+ if (!user || strlen(user) == 0 ||
+ !passwd || strlen(passwd) == 0)
return NULL;
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
dbus_message_append_args(reply, DBUS_TYPE_STRING, &user,
dbus_message_iter_get_basic(&iter, &reason);
dbus_message_iter_next(&iter);
- if (provider == NULL) {
+ if (!provider) {
connman_error("No provider found");
return VPN_STATE_FAILURE;
}
- if (strcmp(reason, "auth failed") == 0)
+ if (strcmp(reason, "auth failed") == 0) {
+ DBG("authentication failure");
+
+ vpn_provider_set_string(provider, "PPTP.User", NULL);
+ vpn_provider_set_string_hide_value(provider, "PPTP.Password",
+ NULL);
+
return VPN_STATE_AUTH_FAILURE;
+ }
if (strcmp(reason, "connect"))
return VPN_STATE_DISCONNECT;
DBG("%s = %s", key, value);
- if (!strcmp(key, "INTERNAL_IP4_ADDRESS")) {
- vpn_provider_set_string(provider, "Address", value);
+ if (!strcmp(key, "INTERNAL_IP4_ADDRESS"))
addressv4 = g_strdup(value);
- }
- if (!strcmp(key, "INTERNAL_IP4_NETMASK")) {
- vpn_provider_set_string(provider, "Netmask", value);
+ if (!strcmp(key, "INTERNAL_IP4_NETMASK"))
netmask = g_strdup(value);
- }
- if (!strcmp(key, "INTERNAL_IP4_DNS")) {
- vpn_provider_set_string(provider, "DNS", value);
+ if (!strcmp(key, "INTERNAL_IP4_DNS"))
nameservers = g_strdup(value);
- }
if (!strcmp(key, "INTERNAL_IFNAME"))
ifname = g_strdup(value);
return VPN_STATE_FAILURE;
}
- if (addressv4 != NULL)
+ if (addressv4)
ipaddress = connman_ipaddress_alloc(AF_INET);
g_free(ifname);
- if (ipaddress == NULL) {
+ if (!ipaddress) {
connman_error("No IP address for provider");
g_free(addressv4);
g_free(netmask);
}
value = vpn_provider_get_string(provider, "HostIP");
- if (value != NULL) {
+ if (value) {
vpn_provider_set_string(provider, "Gateway", value);
gateway = g_strdup(value);
}
- if (addressv4 != NULL)
+ if (addressv4)
connman_ipaddress_set_ipv4(ipaddress, addressv4, netmask,
gateway);
static int pptp_save(struct vpn_provider *provider, GKeyFile *keyfile)
{
const char *option;
+ bool pptp_option, pppd_option;
int i;
for (i = 0; i < (int)ARRAY_SIZE(pptp_options); i++) {
- if (strncmp(pptp_options[i].cm_opt, "PPTP.", 5) == 0) {
+ pptp_option = pppd_option = false;
+
+ if (strncmp(pptp_options[i].cm_opt, "PPTP.", 5) == 0)
+ pptp_option = true;
+
+ if (strncmp(pptp_options[i].cm_opt, "PPPD.", 5) == 0)
+ pppd_option = true;
+
+ if (pptp_option || pppd_option) {
option = vpn_provider_get_string(provider,
pptp_options[i].cm_opt);
- if (option == NULL)
- continue;
+ if (!option) {
+ /*
+ * Check if the option prefix is PPTP as the
+ * PPPD options were using PPTP prefix earlier.
+ */
+ char *pptp_str;
+
+ if (!pppd_option)
+ continue;
+
+ pptp_str = g_strdup_printf("PPTP.%s",
+ &pptp_options[i].cm_opt[5]);
+ option = vpn_provider_get_string(provider,
+ pptp_str);
+ g_free(pptp_str);
+
+ if (!option)
+ continue;
+ }
g_key_file_set_string(keyfile,
vpn_provider_get_save_group(provider),
static void pptp_write_bool_option(struct connman_task *task,
const char *key, const char *value)
{
- if (key != NULL && value != NULL) {
+ if (key && value) {
if (strcasecmp(value, "yes") == 0 ||
strcasecmp(value, "true") == 0 ||
strcmp(value, "1") == 0)
static void request_input_reply(DBusMessage *reply, void *user_data)
{
struct request_input_reply *pptp_reply = user_data;
+ struct pptp_private_data *data;
const char *error = NULL;
char *username = NULL, *password = NULL;
char *key;
DBusMessageIter iter, dict;
+ int err;
DBG("provider %p", pptp_reply->provider);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ if (!reply)
+ goto done;
+
+ data = pptp_reply->user_data;
+
+ err = vpn_agent_check_and_process_reply_error(reply,
+ pptp_reply->provider, data->task, data->cb,
+ data->user_data);
+ if (err) {
+ /* Ensure cb is called only once */
+ data->cb = NULL;
+ data->user_data = NULL;
error = dbus_message_get_error_name(reply);
goto done;
}
- if (vpn_agent_check_reply_has_dict(reply) == FALSE)
+ if (!vpn_agent_check_reply_has_dict(reply))
goto done;
dbus_message_iter_init(reply, &iter);
const char *error, void *user_data);
static int request_input(struct vpn_provider *provider,
- request_cb_t callback, void *user_data)
+ request_cb_t callback, const char *dbus_sender,
+ void *user_data)
{
DBusMessage *message;
const char *path, *agent_sender, *agent_path;
DBusMessageIter dict;
struct request_input_reply *pptp_reply;
int err;
+ void *agent;
- connman_agent_get_info(&agent_sender, &agent_path);
-
- if (provider == NULL || agent_path == NULL || callback == NULL)
+ agent = connman_agent_get_info(dbus_sender, &agent_sender,
+ &agent_path);
+ if (!provider || !agent || !agent_path || !callback)
return -ESRCH;
message = dbus_message_new_method_call(agent_sender, agent_path,
VPN_AGENT_INTERFACE,
"RequestInput");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
connman_dbus_dict_open(&iter, &dict);
+ if (vpn_provider_get_authentication_errors(provider))
+ vpn_agent_append_auth_failure(&dict, provider, NULL);
+
vpn_agent_append_user_info(&dict, provider, "PPTP.User");
vpn_agent_append_host_and_name(&dict, provider);
connman_dbus_dict_close(&iter, &dict);
pptp_reply = g_try_new0(struct request_input_reply, 1);
- if (pptp_reply == NULL) {
+ if (!pptp_reply) {
dbus_message_unref(message);
return -ENOMEM;
}
err = connman_agent_queue_message(provider, message,
connman_timeout_input_request(),
- request_input_reply, pptp_reply);
+ request_input_reply, pptp_reply, agent);
if (err < 0 && err != -EBUSY) {
DBG("error %d sending agent request", err);
dbus_message_unref(message);
char *str;
int err, i;
- host = vpn_provider_get_string(provider, "Host");
- if (host == NULL) {
- connman_error("Host not set; cannot enable VPN");
- err = -EINVAL;
- goto done;
- }
-
- if (username == NULL || password == NULL) {
+ if (!username || !password) {
DBG("Cannot connect username %s password %p",
username, password);
err = -EINVAL;
goto done;
}
- vpn_provider_set_string(provider, "PPTP.User", username);
- vpn_provider_set_string(provider, "PPTP.Password", password);
-
DBG("username %s password %p", username, password);
+ host = vpn_provider_get_string(provider, "Host");
str = g_strdup_printf("%s %s --nolaunchpppd --loglevel 2",
PPTP, host);
- if (str == NULL) {
+ if (!str) {
connman_error("can not allocate memory");
err = -ENOMEM;
goto done;
connman_task_add_argument(task, "nodetach", NULL);
connman_task_add_argument(task, "lock", NULL);
+ connman_task_add_argument(task, "logfd", "2");
connman_task_add_argument(task, "usepeerdns", NULL);
connman_task_add_argument(task, "noipdefault", NULL);
connman_task_add_argument(task, "noauth", NULL);
for (i = 0; i < (int)ARRAY_SIZE(pptp_options); i++) {
opt_s = vpn_provider_get_string(provider,
pptp_options[i].cm_opt);
- if (opt_s == NULL)
+ if (!opt_s)
opt_s = pptp_options[i].vpnc_default;
- if (opt_s == NULL)
+ if (!opt_s)
continue;
if (pptp_options[i].type == OPT_STRING)
}
done:
- if (cb != NULL)
+ if (cb)
cb(provider, user_data, err);
return err;
{
struct pptp_private_data *data = user_data;
- if (username == NULL || password == NULL)
+ if (!username || !password)
DBG("Requesting username %s or password failed, error %s",
username, error);
- else if (error != NULL)
+ else if (error)
DBG("error %s", error);
+ vpn_provider_set_string(provider, "PPTP.User", username);
+ vpn_provider_set_string_hide_value(provider, "PPTP.Password",
+ password);
+
run_connect(provider, data->task, data->if_name, data->cb,
data->user_data, username, password);
static int pptp_connect(struct vpn_provider *provider,
struct connman_task *task, const char *if_name,
- vpn_provider_connect_cb_t cb, void *user_data)
+ vpn_provider_connect_cb_t cb, const char *dbus_sender,
+ void *user_data)
{
const char *username, *password;
int err;
DBG("user %s password %p", username, password);
- if (username == NULL || password == NULL) {
+ if (!username || !password) {
struct pptp_private_data *data;
data = g_try_new0(struct pptp_private_data, 1);
- if (data == NULL)
+ if (!data)
return -ENOMEM;
data->task = task;
data->cb = cb;
data->user_data = user_data;
- err = request_input(provider, request_input_cb, data);
+ err = request_input(provider, request_input_cb, dbus_sender,
+ data);
if (err != -EINPROGRESS) {
free_private_data(data);
goto done;
username, password);
error:
- if (cb != NULL)
+ if (cb)
cb(provider, user_data, err);
return err;
}
-static int pptp_error_code(int exit_code)
+static int pptp_error_code(struct vpn_provider *provider, int exit_code)
{
switch (exit_code) {
}
}
+static void pptp_disconnect(struct vpn_provider *provider)
+{
+ if (!provider)
+ return;
+
+ vpn_provider_set_string_hide_value(provider, "PPTP.Password", NULL);
+
+ connman_agent_cancel(provider);
+}
+
static struct vpn_driver vpn_driver = {
.flags = VPN_FLAG_NO_TUN,
.notify = pptp_notify,
.connect = pptp_connect,
.error_code = pptp_error_code,
.save = pptp_save,
+ .disconnect = pptp_disconnect,
};
static int pptp_init(void)