diff options
69 files changed, 2513 insertions, 1495 deletions
@@ -80,3 +80,13 @@ Mario Schuknecht <mario.schuknecht@dresearch-fe.de> Slava Monich <slava.monich@jolla.com> Aaron McCarthy <aaron.mccarthy@jolla.com> Saurav Babu <saurav.babu@samsung.com> +David Lechner <david@lechnology.com> +Jason Abele <jason@aether.com> +Erik Larsson <erik@ortogonal.com> +Chris Hiszpanski <chris@kunasystems.com> +Tomáš Čech <sleep_walker@suse.cz> +Philip Withnall <philip@tecnocode.co.uk> +Andreas Oberritter <obi@opendreambox.org> +Arman Uguray <armansito@chromium.org> +Vinicius Costa Gomes <vcgomes@gmail.com> +Marcus Folkesson <marcus.folkesson@gmail.com> @@ -1,3 +1,32 @@ +ver 1.29: + Fix issue with IPv6 autoconfiguration when disabled. + Fix issue with IPv6 temporary route handling. + Fix issue with IPv6 timers for nameservers. + Fix issue with DHPCv6 and route configuration. + Fix issue with DHCPv6 source port and buggy servers. + Fix issue with DHCPv6 rapid commit option length. + Fix issue with DHCPv6 rapid commit error handling. + Fix issue with handling invalid WiFi passphrases. + Fix issue with connecting Ethernet devices. + Add support for Ethernet and VLAN usage. + +ver 1.28: + Fix issue with DHCPv6 re-transmission timer. + Fix issue with DHCP service ID option byte order. + Fix issue with IPv6 connections and SLAAC/DHCPv6. + Fix issue with telephony and IPv6 autoconfiguration. + Fix issue with Bluetooth technology setting changes. + Fix issue with WiFi autoscan interval calculation. + Fix issue with WiFi and missing BSS signal strength. + Add support for IPv4 information for WiFi Display. + +ver 1.27: + Fix issue with memory leak in IP configuration. + Fix issue with providing random numbers for DHCP. + Fix issue with handling IN_MOVED_TO inotify events. + Fix issue with channel selection for WiFi scanning. + Add support for handling Bluetooth GN and PANU roles. + ver 1.26: Fix issue with missing WiFi security provisioning support. Fix issue with immutable setting and provisioned services. diff --git a/Makefile.am b/Makefile.am index a5741701..507736d7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,6 +72,13 @@ endif endif endif +service_files_sources = src/connman.service.in src/net.connman.service.in \ + vpn/connman-vpn.service.in \ + vpn/net.connman.vpn.service.in +service_files = src/connman.service src/net.connman.service \ + vpn/connman-vpn.service \ + vpn/net.connman.vpn.service + plugin_LTLIBRARIES = plugin_objects = @@ -82,6 +89,7 @@ builtin_libadd = builtin_cflags = noinst_PROGRAMS = +bin_PROGRAMS = unit_objects = @@ -106,7 +114,7 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) \ src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \ src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \ src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \ - src/peer_service.c src/machine.c + src/peer_service.c src/machine.c src/util.c src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \ @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ \ @@ -145,13 +153,13 @@ vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \ -Wl,--version-script=$(srcdir)/vpn/vpn.ver endif -BUILT_SOURCES = $(local_headers) src/builtin.h +BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) scripts/connman if VPN BUILT_SOURCES += vpn/builtin.h endif -CLEANFILES = src/connman.conf $(BUILT_SOURCES) +CLEANFILES = src/connman.conf $(BUILT_SOURCES) $(service_files) statedir = $(localstatedir)/run/connman vpn_statedir = $(localstatedir)/run/connman-vpn @@ -212,7 +220,8 @@ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ -I$(builddir)/src EXTRA_DIST = src/genbuiltin src/connman-dbus.conf src/connman-polkit.conf \ - plugins/connman-nmcompat.conf + plugins/connman-nmcompat.conf \ + $(service_files_sources) scripts/connman.in if VPN vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \ @@ -237,9 +246,9 @@ script_LTLIBRARIES = include Makefile.plugins if CLIENT -noinst_PROGRAMS += client/connmanctl +bin_PROGRAMS += client/connmanctl -noinst_MANUAL_PAGES = doc/connmanctl.1 +MANUAL_PAGES += doc/connmanctl.1 client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \ client/services.h client/services.c \ @@ -254,22 +263,14 @@ client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ \ -lreadline -ldl endif -noinst_PROGRAMS += unit/test-pbkdf2-sha1 unit/test-prf-sha1 unit/test-ippool - -unit_test_pbkdf2_sha1_SOURCES = unit/test-pbkdf2-sha1.c \ - src/shared/sha1.h src/shared/sha1.c -unit_test_pbkdf2_sha1_LDADD = @GLIB_LIBS@ - -unit_test_prf_sha1_SOURCES = unit/test-prf-sha1.c \ - src/shared/sha1.h src/shared/sha1.c -unit_test_prf_sha1_LDADD = @GLIB_LIBS@ +noinst_PROGRAMS += unit/test-ippool unit_test_ippool_SOURCES = src/log.c src/dbus.c src/error.c \ src/ippool.c unit/test-ippool.c unit_test_ippool_LDADD = gdbus/libgdbus-internal.la \ @GLIB_LIBS@ @DBUS_LIBS@ -ldl -TESTS = unit/test-pbkdf2-sha1 unit/test-prf-sha1 unit/test-ippool +TESTS = unit/test-ippool if WISPR noinst_PROGRAMS += tools/wispr @@ -367,6 +368,8 @@ endif EXTRA_DIST += $(test_scripts) EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \ + doc/coding-style.txt doc/wifi-p2p-overview.txt \ + doc/vpn-agent-api.txt doc/peer-api.txt \ doc/ipconfig-api.txt doc/plugin-api.txt \ doc/manager-api.txt doc/agent-api.txt \ doc/service-api.txt doc/technology-api.txt \ @@ -374,6 +377,7 @@ EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \ doc/clock-api.txt doc/session-api.txt \ doc/session-overview.txt doc/backtrace.txt \ doc/advanced-configuration.txt \ + doc/vpn-config-format.txt \ doc/vpn-connection-api.txt \ doc/vpn-manager-api.txt doc/vpn-overview.txt \ doc/session-policy-format.txt @@ -402,7 +406,7 @@ DISTCLEANFILES = $(pkgconfig_DATA) MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ - ltmain.sh depcomp compile missing install-sh mkinstalldirs + ltmain.sh depcomp compile missing install-sh mkinstalldirs test-driver src/builtin.h: src/genbuiltin $(builtin_sources) @@ -439,6 +443,17 @@ endif EXTRA_DIST += vpn/connman-task.te +do_subst = $(AM_V_GEN)$(SED) \ + -e 's,[@]prefix[@],$(prefix),g' \ + -e 's,[@]sbindir[@],$(sbindir),g' \ + -e 's,[@]sysconfdir[@],$(sysconfdir),g' + +%.service: %.service.in Makefile + $(do_subst) < $< > $@ + +scripts/connman: scripts/connman.in Makefile + $(do_subst) < $< > $@ + include/connman/version.h: include/version.h $(AM_V_at)$(MKDIR_P) include/connman $(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@ diff --git a/Makefile.in b/Makefile.in index 3fe3485d..c625154c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -59,9 +59,9 @@ host_triplet = @host@ @WISPR_FALSE@am__append_2 = gweb/giognutls.h gweb/gionotls.c @DATAFILES_TRUE@@VPN_TRUE@am__append_3 = vpn/connman-vpn-dbus.conf @DATAFILES_TRUE@@SYSTEMD_TRUE@@VPN_TRUE@am__append_4 = vpn/connman-vpn.service -noinst_PROGRAMS = $(am__EXEEXT_1) unit/test-pbkdf2-sha1$(EXEEXT) \ - unit/test-prf-sha1$(EXEEXT) unit/test-ippool$(EXEEXT) \ - $(am__EXEEXT_2) $(am__EXEEXT_3) +noinst_PROGRAMS = unit/test-ippool$(EXEEXT) $(am__EXEEXT_2) \ + $(am__EXEEXT_3) +bin_PROGRAMS = $(am__EXEEXT_1) sbin_PROGRAMS = src/connmand$(EXEEXT) $(am__EXEEXT_4) @VPN_TRUE@am__append_5 = vpn/connman-vpnd @VPN_TRUE@am__append_6 = vpn/builtin.h @@ -71,13 +71,8 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \ $(srcdir)/Makefile.in $(srcdir)/Makefile.plugins \ $(srcdir)/config.h.in $(srcdir)/connman.pc.in \ $(top_srcdir)/configure $(top_srcdir)/include/version.h.in \ - $(top_srcdir)/scripts/connman.in \ - $(top_srcdir)/src/connman.service.in \ - $(top_srcdir)/src/net.connman.service.in \ - $(top_srcdir)/vpn/connman-vpn.service.in \ - $(top_srcdir)/vpn/net.connman.vpn.service.in AUTHORS COPYING \ - ChangeLog INSTALL NEWS TODO compile config.guess config.sub \ - depcomp install-sh ltmain.sh missing + AUTHORS COPYING ChangeLog INSTALL NEWS TODO compile \ + config.guess config.sub depcomp install-sh ltmain.sh missing @LOOPBACK_TRUE@am__append_7 = loopback @LOOPBACK_TRUE@am__append_8 = plugins/loopback.c @ETHERNET_TRUE@am__append_9 = ethernet @@ -149,10 +144,10 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \ @NEARD_TRUE@am__append_74 = neard @NEARD_TRUE@am__append_75 = plugins/neard.c @CLIENT_TRUE@am__append_76 = client/connmanctl -TESTS = unit/test-pbkdf2-sha1$(EXEEXT) unit/test-prf-sha1$(EXEEXT) \ - unit/test-ippool$(EXEEXT) -@WISPR_TRUE@am__append_77 = tools/wispr -@TOOLS_TRUE@am__append_78 = tools/supplicant-test \ +@CLIENT_TRUE@am__append_77 = doc/connmanctl.1 +TESTS = unit/test-ippool$(EXEEXT) +@WISPR_TRUE@am__append_78 = tools/wispr +@TOOLS_TRUE@am__append_79 = tools/supplicant-test \ @TOOLS_TRUE@ tools/dhcp-test tools/dhcp-server-test \ @TOOLS_TRUE@ tools/addr-test tools/web-test tools/resolv-test \ @TOOLS_TRUE@ tools/dbus-test tools/polkit-test \ @@ -161,8 +156,8 @@ TESTS = unit/test-pbkdf2-sha1$(EXEEXT) unit/test-prf-sha1$(EXEEXT) \ @TOOLS_TRUE@ tools/session-test tools/iptables-unit \ @TOOLS_TRUE@ tools/dnsproxy-test tools/netlink-test -@SELINUX_TRUE@@VPN_TRUE@am__append_79 = connman-task.pp @SELINUX_TRUE@@VPN_TRUE@am__append_80 = connman-task.pp +@SELINUX_TRUE@@VPN_TRUE@am__append_81 = connman-task.pp subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ @@ -173,9 +168,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = include/version.h src/connman.service \ - vpn/connman-vpn.service vpn/net.connman.vpn.service \ - scripts/connman connman.pc src/net.connman.service +CONFIG_CLEAN_FILES = include/version.h connman.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -205,8 +198,9 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(scriptdir)" \ - "$(DESTDIR)$(vpn_plugindir)" "$(DESTDIR)$(sbindir)" \ - "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(testdir)" \ + "$(DESTDIR)$(vpn_plugindir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(scriptdir)" \ + "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ "$(DESTDIR)$(dbusconfdir)" "$(DESTDIR)$(dbusservicedir)" \ "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(policydir)" \ @@ -359,7 +353,8 @@ vpn_plugins_vpnc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @OPENCONNECT_TRUE@am__EXEEXT_5 = scripts/openconnect-script$(EXEEXT) @OPENCONNECT_FALSE@@VPNC_TRUE@am__EXEEXT_6 = scripts/openconnect-script$(EXEEXT) @OPENVPN_TRUE@am__EXEEXT_7 = scripts/openvpn-script$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) $(script_PROGRAMS) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) \ + $(script_PROGRAMS) am__client_connmanctl_SOURCES_DIST = client/dbus_helpers.h \ client/dbus_helpers.c client/services.h client/services.c \ client/commands.h client/commands.c client/input.h \ @@ -409,7 +404,7 @@ am__src_connmand_SOURCES_DIST = gdhcp/gdhcp.h gdhcp/common.h \ src/wpad.c src/wispr.c src/stats.c src/iptables.c \ src/dnsproxy.c src/6to4.c src/ippool.c src/bridge.c src/nat.c \ src/ipaddress.c src/inotify.c src/firewall.c src/ipv6pd.c \ - src/peer.c src/peer_service.c src/machine.c + src/peer.c src/peer_service.c src/machine.c src/util.c am__objects_1 = gdhcp/src_connmand-common.$(OBJEXT) \ gdhcp/src_connmand-client.$(OBJEXT) \ gdhcp/src_connmand-server.$(OBJEXT) \ @@ -500,7 +495,8 @@ am_src_connmand_OBJECTS = $(am__objects_1) $(am__objects_4) \ src/src_connmand-ipv6pd.$(OBJEXT) \ src/src_connmand-peer.$(OBJEXT) \ src/src_connmand-peer_service.$(OBJEXT) \ - src/src_connmand-machine.$(OBJEXT) + src/src_connmand-machine.$(OBJEXT) \ + src/src_connmand-util.$(OBJEXT) src_connmand_OBJECTS = $(am_src_connmand_OBJECTS) am__DEPENDENCIES_1 = src_connmand_DEPENDENCIES = gdbus/libgdbus-internal.la \ @@ -637,14 +633,6 @@ am_unit_test_ippool_OBJECTS = src/log.$(OBJEXT) src/dbus.$(OBJEXT) \ unit/test-ippool.$(OBJEXT) unit_test_ippool_OBJECTS = $(am_unit_test_ippool_OBJECTS) unit_test_ippool_DEPENDENCIES = gdbus/libgdbus-internal.la -am_unit_test_pbkdf2_sha1_OBJECTS = unit/test-pbkdf2-sha1.$(OBJEXT) \ - src/shared/sha1.$(OBJEXT) -unit_test_pbkdf2_sha1_OBJECTS = $(am_unit_test_pbkdf2_sha1_OBJECTS) -unit_test_pbkdf2_sha1_DEPENDENCIES = -am_unit_test_prf_sha1_OBJECTS = unit/test-prf-sha1.$(OBJEXT) \ - src/shared/sha1.$(OBJEXT) -unit_test_prf_sha1_OBJECTS = $(am_unit_test_prf_sha1_OBJECTS) -unit_test_prf_sha1_DEPENDENCIES = am__vpn_connman_vpnd_SOURCES_DIST = vpn/plugins/openconnect.c \ vpn/plugins/openvpn.c vpn/plugins/vpnc.c vpn/plugins/l2tp.c \ vpn/plugins/pptp.c vpn/plugins/vpn.c vpn/plugins/vpn.h \ @@ -773,8 +761,7 @@ SOURCES = $(gdbus_libgdbus_internal_la_SOURCES) \ tools/stats-tool.c $(tools_supplicant_test_SOURCES) \ tools/tap-test.c $(tools_web_test_SOURCES) \ $(tools_wispr_SOURCES) $(tools_wpad_test_SOURCES) \ - $(unit_test_ippool_SOURCES) $(unit_test_pbkdf2_sha1_SOURCES) \ - $(unit_test_prf_sha1_SOURCES) $(vpn_connman_vpnd_SOURCES) + $(unit_test_ippool_SOURCES) $(vpn_connman_vpnd_SOURCES) DIST_SOURCES = $(gdbus_libgdbus_internal_la_SOURCES) \ plugins/hh2serial-gps.c plugins/iospm.c \ plugins/session_policy_local.c plugins/tist.c \ @@ -801,14 +788,14 @@ DIST_SOURCES = $(gdbus_libgdbus_internal_la_SOURCES) \ $(am__tools_web_test_SOURCES_DIST) \ $(am__tools_wispr_SOURCES_DIST) \ $(am__tools_wpad_test_SOURCES_DIST) \ - $(unit_test_ippool_SOURCES) $(unit_test_pbkdf2_sha1_SOURCES) \ - $(unit_test_prf_sha1_SOURCES) \ + $(unit_test_ippool_SOURCES) \ $(am__vpn_connman_vpnd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +man1dir = $(mandir)/man1 man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff @@ -1028,6 +1015,14 @@ shared_sources = src/shared/util.h src/shared/util.c \ @DATAFILES_TRUE@@SYSTEMD_TRUE@systemdunitdir = @SYSTEMD_UNITDIR@ @DATAFILES_TRUE@@SYSTEMD_TRUE@systemdunit_DATA = src/connman.service \ @DATAFILES_TRUE@@SYSTEMD_TRUE@ $(am__append_4) +service_files_sources = src/connman.service.in src/net.connman.service.in \ + vpn/connman-vpn.service.in \ + vpn/net.connman.vpn.service.in + +service_files = src/connman.service src/net.connman.service \ + vpn/connman-vpn.service \ + vpn/net.connman.vpn.service + plugin_LTLIBRARIES = $(am__append_19) $(am__append_59) \ $(am__append_68) $(am__append_72) plugin_objects = $(am__append_20) $(am__append_60) $(am__append_69) \ @@ -1045,7 +1040,7 @@ builtin_sources = $(am__append_8) $(am__append_10) $(am__append_12) \ builtin_libadd = builtin_cflags = unit_objects = -MANUAL_PAGES = doc/connman.8 doc/connman.conf.5 +MANUAL_PAGES = $(am__append_77) doc/connman.8 doc/connman.conf.5 src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) \ $(builtin_sources) $(shared_sources) src/connman.ver \ src/main.c src/connman.h src/log.c \ @@ -1063,7 +1058,7 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) \ src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \ src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \ src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \ - src/peer_service.c src/machine.c + src/peer_service.c src/machine.c src/util.c src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \ @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ \ @@ -1101,8 +1096,10 @@ src_connmand_LDFLAGS = -Wl,--export-dynamic \ @VPN_TRUE@vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \ @VPN_TRUE@ -Wl,--version-script=$(srcdir)/vpn/vpn.ver -BUILT_SOURCES = $(local_headers) src/builtin.h $(am__append_6) -CLEANFILES = src/connman.conf $(BUILT_SOURCES) $(am__append_80) +BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) \ + scripts/connman $(am__append_6) +CLEANFILES = src/connman.conf $(BUILT_SOURCES) $(service_files) \ + $(am__append_81) statedir = $(localstatedir)/run/connman vpn_statedir = $(localstatedir)/run/connman-vpn @VPN_TRUE@vpn_plugindir = $(libdir)/connman/plugins-vpn @@ -1143,17 +1140,21 @@ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ EXTRA_DIST = src/genbuiltin src/connman-dbus.conf \ src/connman-polkit.conf plugins/connman-nmcompat.conf \ - vpn/vpn-dbus.conf vpn/vpn-polkit.conf plugins/polkit.policy \ + $(service_files_sources) scripts/connman.in vpn/vpn-dbus.conf \ + vpn/vpn-polkit.conf plugins/polkit.policy \ vpn/vpn-polkit.policy $(test_scripts) doc/overview-api.txt \ - doc/behavior-api.txt doc/ipconfig-api.txt doc/plugin-api.txt \ + doc/behavior-api.txt doc/coding-style.txt \ + doc/wifi-p2p-overview.txt doc/vpn-agent-api.txt \ + doc/peer-api.txt doc/ipconfig-api.txt doc/plugin-api.txt \ doc/manager-api.txt doc/agent-api.txt doc/service-api.txt \ doc/technology-api.txt doc/counter-api.txt \ doc/config-format.txt doc/clock-api.txt doc/session-api.txt \ doc/session-overview.txt doc/backtrace.txt \ - doc/advanced-configuration.txt doc/vpn-connection-api.txt \ - doc/vpn-manager-api.txt doc/vpn-overview.txt \ - doc/session-policy-format.txt src/main.conf src/eduroam.config \ - $(am__append_79) vpn/connman-task.te + doc/advanced-configuration.txt doc/vpn-config-format.txt \ + doc/vpn-connection-api.txt doc/vpn-manager-api.txt \ + doc/vpn-overview.txt doc/session-policy-format.txt \ + src/main.conf src/eduroam.config $(am__append_80) \ + vpn/connman-task.te @VPN_TRUE@vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \ @VPN_TRUE@ $(builtin_vpn_cflags) \ @VPN_TRUE@ -DCONNMAN_PLUGIN_BUILTIN \ @@ -1241,7 +1242,6 @@ gsupplicant_sources = gsupplicant/gsupplicant.h gsupplicant/dbus.h \ @SESSION_POLICY_LOCAL_BUILTIN_FALSE@@SESSION_POLICY_LOCAL_TRUE@ -DSTORAGEDIR=\""$(storagedir)\"" @SESSION_POLICY_LOCAL_BUILTIN_FALSE@@SESSION_POLICY_LOCAL_TRUE@plugins_session_policy_local_la_LDFLAGS = $(plugin_ldflags) -@CLIENT_TRUE@noinst_MANUAL_PAGES = doc/connmanctl.1 @CLIENT_TRUE@client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \ @CLIENT_TRUE@ client/services.h client/services.c \ @CLIENT_TRUE@ client/commands.h client/commands.c \ @@ -1254,14 +1254,6 @@ gsupplicant_sources = gsupplicant/gsupplicant.h gsupplicant/dbus.h \ @CLIENT_TRUE@client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ \ @CLIENT_TRUE@ -lreadline -ldl -unit_test_pbkdf2_sha1_SOURCES = unit/test-pbkdf2-sha1.c \ - src/shared/sha1.h src/shared/sha1.c - -unit_test_pbkdf2_sha1_LDADD = @GLIB_LIBS@ -unit_test_prf_sha1_SOURCES = unit/test-prf-sha1.c \ - src/shared/sha1.h src/shared/sha1.c - -unit_test_prf_sha1_LDADD = @GLIB_LIBS@ unit_test_ippool_SOURCES = src/log.c src/dbus.c src/error.c \ src/ippool.c unit/test-ippool.c @@ -1345,7 +1337,12 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles \ DISTCLEANFILES = $(pkgconfig_DATA) MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ - ltmain.sh depcomp compile missing install-sh mkinstalldirs + ltmain.sh depcomp compile missing install-sh mkinstalldirs test-driver + +do_subst = $(AM_V_GEN)$(SED) \ + -e 's,[@]prefix[@],$(prefix),g' \ + -e 's,[@]sbindir[@],$(sbindir),g' \ + -e 's,[@]sysconfdir[@],$(sysconfdir),g' all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -1404,18 +1401,8 @@ distclean-hdr: -rm -f config.h stamp-h1 include/version.h: $(top_builddir)/config.status $(top_srcdir)/include/version.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ -src/connman.service: $(top_builddir)/config.status $(top_srcdir)/src/connman.service.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -vpn/connman-vpn.service: $(top_builddir)/config.status $(top_srcdir)/vpn/connman-vpn.service.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -vpn/net.connman.vpn.service: $(top_builddir)/config.status $(top_srcdir)/vpn/net.connman.vpn.service.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -scripts/connman: $(top_builddir)/config.status $(top_srcdir)/scripts/connman.in - cd $(top_builddir) && $(SHELL) ./config.status $@ connman.pc: $(top_builddir)/config.status $(srcdir)/connman.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ -src/net.connman.service: $(top_builddir)/config.status $(top_srcdir)/src/net.connman.service.in - cd $(top_builddir) && $(SHELL) ./config.status $@ clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @@ -1607,6 +1594,52 @@ vpn/plugins/vpn_plugins_vpnc_la-vpnc.lo: vpn/plugins/$(am__dirstamp) \ vpn/plugins/$(DEPDIR)/$(am__dirstamp) vpn/plugins/vpnc.la: $(vpn_plugins_vpnc_la_OBJECTS) $(vpn_plugins_vpnc_la_DEPENDENCIES) $(EXTRA_vpn_plugins_vpnc_la_DEPENDENCIES) vpn/plugins/$(am__dirstamp) $(AM_V_CCLD)$(vpn_plugins_vpnc_la_LINK) $(am_vpn_plugins_vpnc_la_rpath) $(vpn_plugins_vpnc_la_OBJECTS) $(vpn_plugins_vpnc_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ @@ -1932,6 +1965,8 @@ src/src_connmand-peer_service.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/src_connmand-machine.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) +src/src_connmand-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) src/connmand$(EXEEXT): $(src_connmand_OBJECTS) $(src_connmand_DEPENDENCIES) $(EXTRA_src_connmand_DEPENDENCIES) src/$(am__dirstamp) @rm -f src/connmand$(EXEEXT) $(AM_V_CCLD)$(src_connmand_LINK) $(src_connmand_OBJECTS) $(src_connmand_LDADD) $(LIBS) @@ -2087,18 +2122,6 @@ unit/test-ippool.$(OBJEXT): unit/$(am__dirstamp) \ unit/test-ippool$(EXEEXT): $(unit_test_ippool_OBJECTS) $(unit_test_ippool_DEPENDENCIES) $(EXTRA_unit_test_ippool_DEPENDENCIES) unit/$(am__dirstamp) @rm -f unit/test-ippool$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unit_test_ippool_OBJECTS) $(unit_test_ippool_LDADD) $(LIBS) -unit/test-pbkdf2-sha1.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -src/shared/sha1.$(OBJEXT): src/shared/$(am__dirstamp) \ - src/shared/$(DEPDIR)/$(am__dirstamp) -unit/test-pbkdf2-sha1$(EXEEXT): $(unit_test_pbkdf2_sha1_OBJECTS) $(unit_test_pbkdf2_sha1_DEPENDENCIES) $(EXTRA_unit_test_pbkdf2_sha1_DEPENDENCIES) unit/$(am__dirstamp) - @rm -f unit/test-pbkdf2-sha1$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(unit_test_pbkdf2_sha1_OBJECTS) $(unit_test_pbkdf2_sha1_LDADD) $(LIBS) -unit/test-prf-sha1.$(OBJEXT): unit/$(am__dirstamp) \ - unit/$(DEPDIR)/$(am__dirstamp) -unit/test-prf-sha1$(EXEEXT): $(unit_test_prf_sha1_OBJECTS) $(unit_test_prf_sha1_DEPENDENCIES) $(EXTRA_unit_test_prf_sha1_DEPENDENCIES) unit/$(am__dirstamp) - @rm -f unit/test-prf-sha1$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(unit_test_prf_sha1_OBJECTS) $(unit_test_prf_sha1_LDADD) $(LIBS) vpn/plugins/vpn_connman_vpnd-openconnect.$(OBJEXT): \ vpn/plugins/$(am__dirstamp) \ vpn/plugins/$(DEPDIR)/$(am__dirstamp) @@ -2280,7 +2303,6 @@ mostlyclean-compile: -rm -f src/iptables.$(OBJEXT) -rm -f src/log.$(OBJEXT) -rm -f src/shared/netlink.$(OBJEXT) - -rm -f src/shared/sha1.$(OBJEXT) -rm -f src/shared/src_connmand-netlink.$(OBJEXT) -rm -f src/shared/src_connmand-util.$(OBJEXT) -rm -f src/shared/util.$(OBJEXT) @@ -2332,6 +2354,7 @@ mostlyclean-compile: -rm -f src/src_connmand-tethering.$(OBJEXT) -rm -f src/src_connmand-timeserver.$(OBJEXT) -rm -f src/src_connmand-timezone.$(OBJEXT) + -rm -f src/src_connmand-util.$(OBJEXT) -rm -f src/src_connmand-utsname.$(OBJEXT) -rm -f src/src_connmand-wispr.$(OBJEXT) -rm -f src/src_connmand-wpad.$(OBJEXT) @@ -2373,8 +2396,6 @@ mostlyclean-compile: -rm -f tools/wispr.$(OBJEXT) -rm -f tools/wpad-test.$(OBJEXT) -rm -f unit/test-ippool.$(OBJEXT) - -rm -f unit/test-pbkdf2-sha1.$(OBJEXT) - -rm -f unit/test-prf-sha1.$(OBJEXT) -rm -f vpn/plugins/vpn_connman_vpnd-l2tp.$(OBJEXT) -rm -f vpn/plugins/vpn_connman_vpnd-openconnect.$(OBJEXT) -rm -f vpn/plugins/vpn_connman_vpnd-openvpn.$(OBJEXT) @@ -2523,6 +2544,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-tethering.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-timeserver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-timezone.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-utsname.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-wispr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_connmand-wpad.Po@am__quote@ @@ -2541,7 +2563,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vpn_connman_vpnd-storage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vpn_connman_vpnd-task.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/netlink.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/sha1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/src_connmand-netlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/src_connmand-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/util.Po@am__quote@ @@ -2569,8 +2590,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/wispr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/wpad-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-ippool.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-pbkdf2-sha1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-prf-sha1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vpn/$(DEPDIR)/vpn_connman_vpnd-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vpn/$(DEPDIR)/vpn_connman_vpnd-vpn-agent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vpn/$(DEPDIR)/vpn_connman_vpnd-vpn-config.Po@am__quote@ @@ -3823,6 +3842,20 @@ src/src_connmand-machine.obj: src/machine.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_connmand_CFLAGS) $(CFLAGS) -c -o src/src_connmand-machine.obj `if test -f 'src/machine.c'; then $(CYGPATH_W) 'src/machine.c'; else $(CYGPATH_W) '$(srcdir)/src/machine.c'; fi` +src/src_connmand-util.o: src/util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_connmand_CFLAGS) $(CFLAGS) -MT src/src_connmand-util.o -MD -MP -MF src/$(DEPDIR)/src_connmand-util.Tpo -c -o src/src_connmand-util.o `test -f 'src/util.c' || echo '$(srcdir)/'`src/util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/src_connmand-util.Tpo src/$(DEPDIR)/src_connmand-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util.c' object='src/src_connmand-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_connmand_CFLAGS) $(CFLAGS) -c -o src/src_connmand-util.o `test -f 'src/util.c' || echo '$(srcdir)/'`src/util.c + +src/src_connmand-util.obj: src/util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_connmand_CFLAGS) $(CFLAGS) -MT src/src_connmand-util.obj -MD -MP -MF src/$(DEPDIR)/src_connmand-util.Tpo -c -o src/src_connmand-util.obj `if test -f 'src/util.c'; then $(CYGPATH_W) 'src/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/src_connmand-util.Tpo src/$(DEPDIR)/src_connmand-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util.c' object='src/src_connmand-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_connmand_CFLAGS) $(CFLAGS) -c -o src/src_connmand-util.obj `if test -f 'src/util.c'; then $(CYGPATH_W) 'src/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util.c'; fi` + src/tools_iptables_unit-log.o: src/log.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_iptables_unit_CFLAGS) $(CFLAGS) -MT src/tools_iptables_unit-log.o -MD -MP -MF src/$(DEPDIR)/tools_iptables_unit-log.Tpo -c -o src/tools_iptables_unit-log.o `test -f 'src/log.c' || echo '$(srcdir)/'`src/log.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/tools_iptables_unit-log.Tpo src/$(DEPDIR)/tools_iptables_unit-log.Po @@ -4288,6 +4321,49 @@ clean-libtool: distclean-libtool: -rm -f libtool config.lt +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man5: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ @@ -4870,7 +4946,7 @@ check: $(BUILT_SOURCES) all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ $(HEADERS) config.h installdirs: - for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(vpn_plugindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(dbusconfdir)" "$(DESTDIR)$(dbusservicedir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(policydir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(vpn_plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(dbusconfdir)" "$(DESTDIR)$(dbusservicedir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(policydir)" "$(DESTDIR)$(scriptdir)" "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -4936,7 +5012,7 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic clean-libtool clean-local \ +clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ clean-pluginLTLIBRARIES clean-sbinPROGRAMS \ clean-scriptLTLIBRARIES clean-scriptPROGRAMS \ @@ -4973,7 +5049,7 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-binPROGRAMS install-sbinPROGRAMS install-html: install-html-am @@ -4983,7 +5059,7 @@ install-info: install-info-am install-info-am: -install-man: install-man5 install-man8 +install-man: install-man1 install-man5 install-man8 install-pdf: install-pdf-am @@ -5015,22 +5091,22 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dbusconfDATA uninstall-dbusserviceDATA \ - uninstall-includeHEADERS uninstall-man \ - uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA \ - uninstall-pluginLTLIBRARIES uninstall-policyDATA \ - uninstall-sbinPROGRAMS uninstall-scriptDATA \ - uninstall-scriptLTLIBRARIES uninstall-scriptPROGRAMS \ - uninstall-systemdunitDATA uninstall-testSCRIPTS \ - uninstall-vpn_pluginLTLIBRARIES +uninstall-am: uninstall-binPROGRAMS uninstall-dbusconfDATA \ + uninstall-dbusserviceDATA uninstall-includeHEADERS \ + uninstall-man uninstall-nodist_includeHEADERS \ + uninstall-pkgconfigDATA uninstall-pluginLTLIBRARIES \ + uninstall-policyDATA uninstall-sbinPROGRAMS \ + uninstall-scriptDATA uninstall-scriptLTLIBRARIES \ + uninstall-scriptPROGRAMS uninstall-systemdunitDATA \ + uninstall-testSCRIPTS uninstall-vpn_pluginLTLIBRARIES -uninstall-man: uninstall-man5 uninstall-man8 +uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .MAKE: all check check-am install install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ - clean clean-generic clean-libtool clean-local \ - clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + clean clean-binPROGRAMS clean-generic clean-libtool \ + clean-local clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ clean-pluginLTLIBRARIES clean-sbinPROGRAMS \ clean-scriptLTLIBRARIES clean-scriptPROGRAMS \ clean-vpn_pluginLTLIBRARIES ctags dist dist-all dist-bzip2 \ @@ -5039,13 +5115,13 @@ uninstall-man: uninstall-man5 uninstall-man8 distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dbusconfDATA \ - install-dbusserviceDATA install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-man install-man5 install-man8 \ - install-nodist_includeHEADERS install-pdf install-pdf-am \ - install-pkgconfigDATA install-pluginLTLIBRARIES \ + install-binPROGRAMS install-data install-data-am \ + install-dbusconfDATA install-dbusserviceDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-man install-man1 install-man5 \ + install-man8 install-nodist_includeHEADERS install-pdf \ + install-pdf-am install-pkgconfigDATA install-pluginLTLIBRARIES \ install-policyDATA install-ps install-ps-am \ install-sbinPROGRAMS install-scriptDATA \ install-scriptLTLIBRARIES install-scriptPROGRAMS install-strip \ @@ -5054,14 +5130,15 @@ uninstall-man: uninstall-man5 uninstall-man8 installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-dbusconfDATA uninstall-dbusserviceDATA \ - uninstall-includeHEADERS uninstall-man uninstall-man5 \ - uninstall-man8 uninstall-nodist_includeHEADERS \ - uninstall-pkgconfigDATA uninstall-pluginLTLIBRARIES \ - uninstall-policyDATA uninstall-sbinPROGRAMS \ - uninstall-scriptDATA uninstall-scriptLTLIBRARIES \ - uninstall-scriptPROGRAMS uninstall-systemdunitDATA \ - uninstall-testSCRIPTS uninstall-vpn_pluginLTLIBRARIES + uninstall-am uninstall-binPROGRAMS uninstall-dbusconfDATA \ + uninstall-dbusserviceDATA uninstall-includeHEADERS \ + uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 \ + uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA \ + uninstall-pluginLTLIBRARIES uninstall-policyDATA \ + uninstall-sbinPROGRAMS uninstall-scriptDATA \ + uninstall-scriptLTLIBRARIES uninstall-scriptPROGRAMS \ + uninstall-systemdunitDATA uninstall-testSCRIPTS \ + uninstall-vpn_pluginLTLIBRARIES plugins/net.connman.policy: plugins/polkit.policy @@ -5087,6 +5164,12 @@ src/connman.conf: src/connman-dbus.conf src/connman-polkit.conf @SELINUX_TRUE@connman-task.pp: vpn/connman-task.te @SELINUX_TRUE@ make -f /usr/share/selinux/devel/Makefile +%.service: %.service.in Makefile + $(do_subst) < $< > $@ + +scripts/connman: scripts/connman.in Makefile + $(do_subst) < $< > $@ + include/connman/version.h: include/version.h $(AM_V_at)$(MKDIR_P) include/connman $(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@ @@ -312,13 +312,6 @@ CONFIG_BGSCAN_SIMPLE=y This last option will enable the support of background scanning while being connected, which is necessary when roaming on wifi. -and finally: - -CONFIG_AUTOSCAN_EXPONENTIAL=y - -This will enable the exact same function as bgscan but while being -disconnected. - It is recommended to use wpa_supplicant 2.x or later. If wpa_supplicant is configured to D-Bus autostart, then ConnMan will @@ -16,7 +16,6 @@ Core Priority: Low Complexity: C8 - Owner: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> Discuss and implement a basic and safe firewalling strategy into Connman. Provide a D-Bus API for personal firewalling. @@ -61,7 +60,7 @@ Core - Unit tests for DHCP, DNS and HTTP - Priority: Medium + Priority: Low Complexity: C4 Create unit tests for these components starting with DHCP. Use gtest @@ -71,12 +70,46 @@ Core - Support other time sources than NTP - Priority: Medium + Priority: Low Complexity: C2 Support other time sources like cellular, GPS in addition to NTP. +- Get interface names from src/device.c + + Priority: Low + Complexity: C2 + + Instead of using ioctls in connman_inet_ifindex and connman_inet_ifname, + utilize the information already provided by netlink in src/device.c. + + +- Simplify gateway selection code + + Priority: Low + Complexity: C4 + + The service list is always sorted according to preference with the + first service always owning the default route. See if update_order and + find_default_gateway in src/connection.c can be modified to use the + sorted service list instead of walking through the gateway_hash. + + +- Support D-Bus ObjectManager + + Priority: Medium + Complexity: C4 + + Support D-Bus ObjectManager by using functionality already present in + ./gdbus. Method calls and signals are already registered with gdbus, but + properties and replies especially in Agent are still handled with plain + dbus library function calls. + + With this, Manager API is removed, and a WiFi P2P API based on + ObjectManager common to Linux desktops can be implemented. + + WiFi ==== @@ -97,7 +130,6 @@ WiFi Priority: Medium Complexity: C2 - Owner: Samuel Ortiz <sameo@linux.intel.com> This EAP is needed for SIM card based network authentication. ConnMan here plays a minor role: Once wpa_supplicant is set up for @@ -111,17 +143,10 @@ WiFi Complexity: C1 -- WiFi p2p - - Priority: Medium - Complexity: C2 - - - Removing wpa_supplicant 0.7.x legacy support Priority: Low Complexity: C1 - Owner: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> Removing global country property setter in gsupplicant, and removing wifi's technology set_regdom implementation. Removing autoscan fallback. @@ -149,7 +174,7 @@ VPN Priority: Medium Complexity: C4 - Owner: Jukka Rissanen <jukka.rissanen@linux.intel.com> + - L2TP & PPTP compatibility prefix removal @@ -191,7 +216,7 @@ User Interface Priority: Low Complexity: C4 - Owner: Alok Barsode <alok.barsode@linux.intel.com> A GNOME3 shell user interface would make it easier for mainstream distros - users to use ConnMan. + users to use ConnMan. Continue/restart the work at + https://github.com/connectivity/gnome-extension-connman @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for connman 1.26. +# Generated by GNU Autoconf 2.69 for connman 1.29. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='connman' PACKAGE_TARNAME='connman' -PACKAGE_VERSION='1.26' -PACKAGE_STRING='connman 1.26' +PACKAGE_VERSION='1.29' +PACKAGE_STRING='connman 1.29' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -868,7 +868,9 @@ with_openvpn enable_openvpn with_vpnc enable_vpnc +with_l2tp enable_l2tp +with_pptp enable_pptp enable_iospm enable_tist @@ -1455,7 +1457,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures connman 1.26 to adapt to many kinds of systems. +\`configure' configures connman 1.29 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1525,7 +1527,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of connman 1.26:";; + short | recursive ) echo "Configuration of connman 1.29:";; esac cat <<\_ACEOF @@ -1588,6 +1590,8 @@ Optional Packages: specify location of openconnect binary --with-openvpn=PROGRAM specify location of openvpn binary --with-vpnc=PROGRAM specify location of vpnc binary + --with-l2tp=PROGRAM specify location of l2tp binary + --with-pptp=PROGRAM specify location of pptp binary --with-stats-max-file-size=SIZE Maximal size of a statistics round robin file --with-dbusconfdir=PATH path to D-Bus config directory @@ -1687,7 +1691,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -connman configure 1.26 +connman configure 1.29 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2052,7 +2056,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by connman $as_me 1.26, which was +It was created by connman $as_me 1.29, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2868,7 +2872,7 @@ fi # Define the identity of the package. PACKAGE='connman' - VERSION='1.26' + VERSION='1.29' cat >>confdefs.h <<_ACEOF @@ -12139,6 +12143,13 @@ else fi + +# Check whether --with-l2tp was given. +if test "${with_l2tp+set}" = set; then : + withval=$with_l2tp; path_l2tp=${withval} +fi + + # Check whether --enable-l2tp was given. if test "${enable_l2tp+set}" = set; then : enableval=$enable_l2tp; enable_l2tp=${enableval} @@ -12273,6 +12284,13 @@ else fi + +# Check whether --with-pptp was given. +if test "${with_pptp+set}" = set; then : + withval=$with_pptp; path_pptp=${withval} +fi + + # Check whether --enable-pptp was given. if test "${enable_pptp+set}" = set; then : enableval=$enable_pptp; enable_pptp=${enableval} @@ -13429,7 +13447,7 @@ else fi -ac_config_files="$ac_config_files Makefile include/version.h src/connman.service vpn/connman-vpn.service vpn/net.connman.vpn.service scripts/connman connman.pc src/net.connman.service" +ac_config_files="$ac_config_files Makefile include/version.h connman.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -14101,7 +14119,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by connman $as_me 1.26, which was +This file was extended by connman $as_me 1.29, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14167,7 +14185,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -connman config.status 1.26 +connman config.status 1.29 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -14578,12 +14596,7 @@ do "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "include/version.h") CONFIG_FILES="$CONFIG_FILES include/version.h" ;; - "src/connman.service") CONFIG_FILES="$CONFIG_FILES src/connman.service" ;; - "vpn/connman-vpn.service") CONFIG_FILES="$CONFIG_FILES vpn/connman-vpn.service" ;; - "vpn/net.connman.vpn.service") CONFIG_FILES="$CONFIG_FILES vpn/net.connman.vpn.service" ;; - "scripts/connman") CONFIG_FILES="$CONFIG_FILES scripts/connman" ;; "connman.pc") CONFIG_FILES="$CONFIG_FILES connman.pc" ;; - "src/net.connman.service") CONFIG_FILES="$CONFIG_FILES src/net.connman.service" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 6f35c789..e7d31a77 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(connman, 1.26) +AC_INIT(connman, 1.29) AM_INIT_AUTOMAKE([foreign subdir-objects color-tests]) AC_CONFIG_HEADERS([config.h]) @@ -121,6 +121,9 @@ fi AM_CONDITIONAL(VPNC, test "${enable_vpnc}" != "no") AM_CONDITIONAL(VPNC_BUILTIN, test "${enable_vpnc}" = "builtin") +AC_ARG_WITH(l2tp, AC_HELP_STRING([--with-l2tp=PROGRAM], + [specify location of l2tp binary]), [path_l2tp=${withval}]) + AC_ARG_ENABLE(l2tp, AC_HELP_STRING([--enable-l2tp], [enable l2tp support]), [enable_l2tp=${enableval}], [enable_l2tp="no"]) @@ -143,6 +146,9 @@ fi AM_CONDITIONAL(L2TP, test "${enable_l2tp}" != "no") AM_CONDITIONAL(L2TP_BUILTIN, test "${enable_l2tp}" = "builtin") +AC_ARG_WITH(pptp, AC_HELP_STRING([--with-pptp=PROGRAM], + [specify location of pptp binary]), [path_pptp=${withval}]) + AC_ARG_ENABLE(pptp, AC_HELP_STRING([--enable-pptp], [enable pptp support]), [enable_pptp=${enableval}], [enable_pptp="no"]) @@ -384,6 +390,4 @@ AM_CONDITIONAL(VPN, test "${enable_openconnect}" != "no" -o \ "${enable_l2tp}" != "no" -o \ "${enable_pptp}" != "no") -AC_OUTPUT(Makefile include/version.h src/connman.service - vpn/connman-vpn.service vpn/net.connman.vpn.service - scripts/connman connman.pc src/net.connman.service) +AC_OUTPUT(Makefile include/version.h connman.pc) diff --git a/doc/coding-style.txt b/doc/coding-style.txt new file mode 100644 index 00000000..97410ce7 --- /dev/null +++ b/doc/coding-style.txt @@ -0,0 +1,344 @@ +Every project has its coding style, and ConnMan is not an exception. This +document describes the preferred coding style for ConnMan code, in order to keep +some level of consistency among developers so that code can be easily +understood and maintained, and also to help your code survive under +maintainer's fastidious eyes so that you can get a passport for your patch +ASAP. + +First of all, ConnMan coding style must follow every rule for Linux kernel +(http://www.kernel.org/doc/Documentation/CodingStyle). There also exists a tool +named checkpatch.pl to help you check the compliance with it. Just type +"checkpatch.pl --no-tree patch_name" to check your patch. In theory, you need +to clean up all the warnings and errors except this one: "ERROR: Missing +Signed-off-by: line(s)". ConnMan does not used Signed-Off lines, so including +them is actually an error. In certain circumstances one can ignore the 80 +character per line limit. This is generally only allowed if the alternative +would make the code even less readable. + +Besides the kernel coding style above, ConnMan has special flavors for its own. +Some of them are mandatory (marked as 'M'), while some others are optional +(marked as 'O'), but generally preferred. + +M1: Blank line before and after an if/while/do/for statement +============================================================ +There should be a blank line before if statement unless the if is nested and +not preceded by an expression or variable declaration. + +Example: +1) +a = 1; +if (b) { // wrong + +2) +a = 1 + +if (b) { +} +a = 2; // wrong + +3) +if (a) { + if (b) // correct + +4) +b = 2; + +if (a) { // correct + +} + +b = 3; + +The only exception to this rule applies when a variable is being allocated: +array = g_try_new0(int, 20); +if (!array) // Correct + return; + + +M2: Multiple line comment +========================= +If your comments have more then one line, please start it from the second line. + +Example: +/* + * first line comment // correct + * ... + * last line comment + */ + + +M3: Space before and after operator +=================================== +There should be a space before and after each operator. + +Example: +a + b; // correct + + +M4: Wrap long lines +=================== +If your condition in if, while, for statement or a function declaration is too +long to fit in one line, the new line needs to be indented not aligned with the +body. + +Example: +1) +if (call->status == CALL_STATUS_ACTIVE || + call->status == CALL_STATUS_HELD) { // wrong + connman_dbus_dict_append(); + +2) +if (call->status == CALL_STATUS_ACTIVE || + call->status == CALL_STATUS_HELD) { // correct + connman_dbus_dict_append(); + +3) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index) // wrong +{ + int a; + ... +} + +4) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index) // correct +{ + int a; + ... +} + +If the line being wrapped is a function call or function declaration, the +preferred style is to indent at least past the opening parenthesis. Indenting +further is acceptable as well (as long as you don't hit the 80 character +limit). + +If this is not possible due to hitting the 80 character limit, then indenting +as far as possible to the right without hitting the limit is preferred. + +Example: + +1) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index); // worse + +2) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index); + // better + +M5: Git commit message 50/72 formatting +======================================= +The commit message header should be within 50 characters. And if you have +detailed explanatory text, wrap it to 72 character. + + +M6: Space when doing type casting +================================= +There should be a space between new type and variable. + +Example: +1) +a = (int *)b; // wrong +2) +a = (int *) b; // correct + + +M7: Don't initialize variable unnecessarily +=========================================== +When declaring a variable, try not to initialize it unless necessary. + +Example: +int i = 1; // wrong + +for (i = 0; i < 3; i++) { +} + + +M8: Use g_try_malloc instead of g_malloc +======================================== +When g_malloc fails, the whole program would exit. Most of time, this is not +the expected behavior, and you may want to use g_try_malloc instead. + +Example: +additional = g_try_malloc(len - 1); // correct +if (!additional) + return FALSE; + + +M9: Follow the order of include header elements +=============================================== +When writing an include header the various elements should be in the following +order: + - #includes + - forward declarations + - #defines + - enums + - typedefs + - function declarations and inline function definitions + + +M10: Internal headers must not use include guards +================================================= +Any time when creating a new header file with non-public API, that header +must not contain include guards. + + +M11: Naming of enums +==================== + +Enums must have a descriptive name. The enum type should be small caps and +it should not be typedef-ed. Enum contents should be in CAPITAL letters and +prefixed by the enum type name. + +Example: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS, + ANIMAL_TYPE_EIGHT_LEGS, + ANIMAL_TYPE_TWO_LEGS, +}; + +If the enum contents have values (e.g. from specification) the formatting +should be as follows: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS = 4, + ANIMAL_TYPE_EIGHT_LEGS = 8, + ANIMAL_TYPE_TWO_LEGS = 2, +}; + +M12: Enum as switch variable +==================== + +If the variable of a switch is an enum, you must not include a default in +switch body. The reason for this is: If later on you modify the enum by adding +a new type, and forget to change the switch accordingly, the compiler will +complain the new added type hasn't been handled. + +Example: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS = 4, + ANIMAL_TYPE_EIGHT_LEGS = 8, + ANIMAL_TYPE_TWO_LEGS = 2, +}; + +enum animal_type t; + +switch (t) { +case ANIMAL_TYPE_FOUR_LEGS: + ... + break; +case ANIMAL_TYPE_EIGHT_LEGS: + ... + break; +case ANIMAL_TYPE_TWO_LEGS: + ... + break; +default: // wrong + break; +} + +However if the enum comes from an external header file outside ConnMan +we cannot make any assumption of how the enum is defined and this +rule might not apply. + +M13: Check for pointer being NULL +================================= + +When checking if a pointer or a return value is NULL, use the +check with "!" operator. + +Example: +1) +array = g_try_new0(int, 20); +if (!array) // Correct + return; + +2) +if (!g_at_chat_get_slave(chat)) // Correct + return -EINVAL; + +3) +array = g_try_new0(int, 20); +if (array == NULL) // Wrong + return; + + +M14: Always use parenthesis with sizeof +======================================= +The expression argument to the sizeof operator should always be in +parenthesis, too. + +Example: +1) +memset(stuff, 0, sizeof(*stuff)); + +2) +memset(stuff, 0, sizeof *stuff); // Wrong + + +M15: Use void if function has no parameters +=========================================================== +A function with no parameters must use void in the parameter list. + +Example: +1) +void foo(void) +{ +} + +2) +void foo() // Wrong +{ +} + +M16: Don't use hex value with shift operators +============================================== +The expression argument to the shift operators should not be in hex. + +Example: + +1) +1 << y + +2) +0x1 << y // Wrong + +O1: Shorten the name +==================== +Better to use abbreviation, rather than full name, to name a variable, +function, struct, etc. + +Example: +supplementary_service // too long +ss // better + +O2: Try to avoid complex if body +================================ +It's better not to have a complicated statement for if. You may judge its +contrary condition and return | break | continue | goto ASAP. + +Example: +1) +if (a) { // worse + struct voicecall *v; + call = synthesize_outgoing_call(vc, vc->pending); + v = voicecall_create(vc, call); + v->detect_time = time(NULL); + DBG("Registering new call: %d", call->id); + voicecall_dbus_register(v); +} else + return; + +2) +if (!a) + return; + +struct voicecall *v; +call = synthesize_outgoing_call(vc, vc->pending); +v = voicecall_create(vc, call); +v->detect_time = time(NULL); +DBG("Registering new call: %d", call->id); +voicecall_dbus_register(v); diff --git a/doc/connmanctl.1 b/doc/connmanctl.1 new file mode 100644 index 00000000..b71c6e62 --- /dev/null +++ b/doc/connmanctl.1 @@ -0,0 +1,190 @@ +.TH connmanctl 1 07/31/2012 "" "User Commands for Connman CLI" +.SH +NAME +connmanctl \- Connman CLI +.SH +SYNOPSIS +.BR connmanctl " [" +.BR enable " <technology> | " +.BR offlinemode "] [" +.BR disable " <technology> | " +.BR offlinemode "] [" +.BR technologies "] [" +.BR state "] [" +.BR services " [\-\-properties <service>]] [" +.BR scan " <technology>] [" +.BR connect " <service>] [" +.BR config " <service> \-\-<option> ARGS...] [" +.BR help " | \-\-help]" +.PP +.SH +DESCRIPTION +Connmanctl is a Connman command line interface which can be run in two modes: +a plain synchronous command input, and an asynchronous interactive shell. +To run a specific command the user may enter connmanctl <command> [options] +[args], or enter connmanctl; in this case, the program will drop into the +interactive shell. +.PP +Connmantl can handle most simple network connections. It is able to enable/ +disable any technology that exists on the system, display a list of +services available, connect to/disconnect from any unsecured networks, +show properties of the system, the technologies, and any individual +service, and configure all of the properties. It is also able to monitor +changes in the properties of the services, technologies, and the system. +.PP +In the interactive shell, all of the same commands can be used. It +provides quicker usage when needing to use connmanctl more extensively. +.SH +COMMANDS AND OPTIONS +.TP +.BR "help | \-\-help | " "(no arguments)" +Shows the abbreviated help menu in the terminal. +.PP +.TP +.BR enable " <technology>" +Enables the given technology type (e.g. ethernet, wifi, 3g, etc.) +Turns power on to the technology, but doesn't connect unless +there is a service with autoconnect set to True. +.PP +.TP +.BR disable " <technology>" +Disables the given technology type. Turns power off to the +technology and disconnects if it is already connected. +.PP +.TP +.B enable offlinemode +Enables offline mode. Disconnects and powers down all +technologies system-wide, however each technology can be powered +back on individually. +.PP +.TP +.B disable offlinemode +Disables offline mode. Technologies are powered back on according +to their individual policies. +.PP +.TP +.B technologies +Shows a list of all technology types existing on the system and +their properties. See the properties section of the Technology +API for explanations of each property. +.PP +.TP +.B state +Shows the system properties. Includes ths online state of the +system, offline mode, and session mode. +.PP +.TP +.BR scan " <technology>" +Scans for new services on the given technology. +.PP +.TP +.B services +Shows a list of all available service names. This includes the +names of wifi networks, the wired ethernet connection, names of +bluetooth devices, etc. These are the names used when a +<service> command is called for. The service name +(e.g. Joes-wifi), the service path (e.g. +wifi_6834534139723_managed_none), or the full service path (e.g. +/net/connman/Service/wifi_5467631...) are all accepted as valid +input. An asterisk in front of the service indicates that the +service is favorited, and a "C" indicates a service that is +already connected. +.PP +.TP +.BR "services \-\-properties" " <service>" +Shows a list of all properties for that service. See the +properties section of the Service API for explanations of each +property. +.PP +.TP +.BR connect " <service>" +Connects to the given service if it is unsecured. +.PP +.TP +.BR disconnect " <service>" +Disconnects from the given service. +.PP +.TP +.BR config " <service> " \-\-<option> +Configures a writable property of the given service to the +value(s) entered after --<option>. +.PP +.TP +.BR monitor " [\-\-<option>]" +Listens for and displays DBus signals sent by Connman. The option indicates +which signals you want to subscribe to. If no option is entered, it displays +all signals from all interfaces. +.PP +.SS +Config Options: +.PP +.TP +.B \-\-autoconnect=y/n +Sets the autoconnect property of the service. +.PP +.TP +.B \-\-ipv4 +Configures the IPv4 settings for the service. Enter the settings +in the order "Method", "Address", "Netmask", then "Gateway" +after the argument. See the properties section of the Service +API for more information on these settings and the values +accepted for them. It also displays a list of changes to both the +IPv4 settings, and incidental changes to other values related to +it. +.PP +.TP +.B \-\-ipv6 +Configures the IPv6 settings for the service. Enter the settings +in the order "Method", "Address", "PrefixLength", "Gateway", then +"Privacy". See the properties section of the Service API for more +information on these settings and the values accepted for them. +It also displays a list of entered changes to the IPv6 settings, +and incidental changes to other values related to it. +.PP +.TP +.B \-\-nameservers +Adds to the list of manually configured domain name servers. +Enter the name servers after the argument separated by spaces. +.PP +.TP +.B \-\-timeservers +Adds to the list of manually configured time servers. Enter the +time servers after the argument separated by spaces. +.PP +.TP +.B \-\-domains +Adds to the list of manually configured search domains. Enter +the domains after the argument, separated by spaces. +.PP +.TP +.B \-\-proxy +Configures the IPv6 settings for the service. Enter the settings in the +order "Method", "URL". If the Method is set to "direct", no other arguments +are taken. If the Method is set to "auto", the URL is optional. To set the +Servers and Excludes manually, enter "manual" followed by "servers" with a +list of servers separated by spaces. Then, optionally, the word "excludes" +followed by a list of excludes separated by spaces. e.g. "./connmanctl config +joes-wifi \-\-proxy manual servers serv1 serv2 serv3 excludes excl1 excl2" +.PP +.SS +Monitor Options: +.PP +.TP +.B \-\-services +Listens for and displays the PropertyChanged signal from the Service interface. +Also displays the service name (e.g. Joes-wifi) that the property is part of. +More information, including a list of possible properties can be found in the +Service API. +.PP +.TP +.B \-\-tech +Listens for and displays the PropertyChanged signal from the Technology +interface. More information, including a list of possible properties can be +found in the Technology API. +.PP +.TP +.B \-\-manager +Listens for and displays the PropertyChanged, ServicesChanged, TechnologyAdded, +and TechnologyRemoved signals from the Manager interface. More information on +these signals and a list of possible properties can be found in the Manager API. +.PP diff --git a/doc/peer-api.txt b/doc/peer-api.txt new file mode 100644 index 00000000..cc094ff2 --- /dev/null +++ b/doc/peer-api.txt @@ -0,0 +1,102 @@ +Peer hierarchy [EXPERIMENTAL] +============================= + +Service net.connman +Interface net.connman.Peer +Object path [variable prefix]/{peer0,peer1,...} + +Methods dict GetProperties() [deprecated] + + Returns properties for the peer object. See the + properties sections for available properties. + + Usage of this method is highly discouraged. Use + the Manager.GetPeers() method instead. + + Possible Errors: [service].Error.InvalidArguments + + void Connect() [experimental] + + Connect this peer. + + This method call will only return in case of an error + or when the peer is fully connected. So setting a + longer D-Bus timeout might be a really good idea. + + Possible Errors: [service].Error.InvalidArguments + + void Disconnect() [experimental] + + Disconnect this peer. If the peer is not connected, an + error message will be generated. + + Possible Errors: [service].Error.InvalidArguments + +Signals PropertyChanged(string name, variant value) [experimental] + + This signal indicates a changed value of the given + property. + +Properties string State [readonly] [experimental] + + The peer state information. + + Valid state are "idle", "failure", "association", + "configuration", "ready" and "disconnect". + + string Name [readonly] [experimental] + + Name of the peer. + + dict IPv4 [readonly] [experimental] + + string Local [readonly] + + The current peer's local configured IPv4 + address. + + string Remote [readonly] + + The current peer's remote configured IPv4 + address. + + array{dict} Services [readonly] [experimental] + + Array of P2P service specifications consisting of + either UpnpService and UpnpVersion or BonjourQuery + and BonjourResponse, but not a mix of these. The + dict members have the following format: + + String UpnpService [readonly] + + The UPNP service URI. + + int32 UpnpVersion [readonly] + + The UPNP version in use. + + array{byte} BonjourQuery [readonly] + + The bonjour service query data, provided + through a byte array. + + Note: a Peer object will never show this + information. When scanning, a device gets + only the bonjour response data. However, + this information is mandatory when a bonjour + service is given through Manager API + RegisterPeerService and + UnregisterPeerService. + + array{byte} BonjourResponse [readonly] + + The bonjour service response data, provided + through a byte array. + + Note: this will be the only bonjour related + information a Peer object will show. + + array{byte} WiFiDisplayIEs [readonly] + + The TLV formated byte array representing the + WiFi Display Informations Elements. diff --git a/doc/service-api.txt b/doc/service-api.txt index c9dd7e2f..b4f1dca0 100644 --- a/doc/service-api.txt +++ b/doc/service-api.txt @@ -155,7 +155,9 @@ Properties string State [readonly] the "failure" state. Otherwise it might be empty or not present at all. - Current defined error code is "dhcp-failed". + Currently defined error codes are: "out-of-range", + "pin-missing", "dhcp-failed", "connect-failed", + "login-failed", "auth-failed" and "invalid-key". string Name [readonly] diff --git a/doc/vpn-agent-api.txt b/doc/vpn-agent-api.txt new file mode 100644 index 00000000..72bee9db --- /dev/null +++ b/doc/vpn-agent-api.txt @@ -0,0 +1,158 @@ +Agent hierarchy +=============== + +Service unique name +Interface net.connman.vpn.Agent +Object path freely definable + +Methods void Release() + + This method gets called when the service daemon + unregisters the agent. An agent can use it to do + cleanup tasks. There is no need to unregister the + agent, because when this method gets called it has + already been unregistered. + + void ReportError(object service, string error) + + This method gets called when an error has to be + reported to the user. + + A special return value can be used to trigger a + retry of the failed transaction. + + Possible Errors: net.connman.vpn.Agent.Error.Retry + + dict RequestInput(object service, dict fields) + + This method gets called when trying to connect to + a service and some extra input is required. For + example a password or username. + + The return value should be a dictionary where the + keys are the field names and the values are the + actual fields. Alternatively an error indicating that + the request got canceled can be returned. + + Most common return field names are "Username" and of + course "Password". + + The dictionary arguments contains field names with + their input parameters. + + Possible Errors: net.connman.vpn.Agent.Error.Canceled + + void Cancel() + + This method gets called to indicate that the agent + request failed before a reply was returned. + +Fields string Username + + Username for authentication. This field will be + requested when connecting to L2TP and PPTP. + + string Password + + Password for authentication. + + boolean SaveCredentials + + Tells if the user wants the user credentials + be saved by connman-vpnd. + + string Host + + End point of this VPN link i.e., the VPN gateway + we are trying to connect to. + + string Name + + Name of the VPN connection we are trying to connect to. + + string OpenConnect.CACert + + Informational field containing a path name for an + additional Certificate Authority file. + + string OpenConnect.ClientCert + + Informational field containing a pkcs11 URL or a path + name for the client certificate. + + string OpenConnect.Cookie + + Return the OpenConnect cookie value that is used for + authenticating the VPN session. + + string OpenConnect.ServerCert + + Return the OpenConnect server hash used to identify + the final server after possible web authentication + logins, selections and redirections. + + string OpenConnect.VPNHost + + Return the final VPN server to use after possible + web authentication logins, selections and redirections. + +Arguments string Type + + Contains the type of a field. For example "password", + "response", "boolean" or plain "string". + + string Requirement + + Contains the requirement option. Valid values are + "mandatory", "optional", "alternate" or + "informational". + + The "alternate" value specifies that this field can be + returned as an alternative to another one. + + All "mandatory" fields must be returned, while the + "optional" can be returned if available. + + Nothing needs to be returned for "informational", as it + is here only to provide an information so a value is + attached to it. + + array{string} Alternates + + Contains the list of alternate field names this + field can be represented by. + + string Value + + Contains data as a string, relatively to an + "informational" argument. + +Examples Requesting a username and password for L2TP network + + RequestInput("/vpn1", + { "Username" : { "Type" : "string", + "Requirement" : "mandatory" + } } + { "Password" : { "Type" : "password", + "Requirement" : "mandatory" + } } + { "SaveCredentials" : { "Type" : "boolean", + "Requirement" : "optional" + } + } + ==> { "Username" : "foo", "Password" : "secret123", + "SaveCredentials" : true } + + Requesting a OpenConnect cookie + + RequestInput("/vpn2", + { "OpenConnect.Cookie" : { "Type" : "string", + "Requirement" : "mandatory" + } } + { "Host" : { "Type" : "string", + "Requirement" : "informational" + } } + { "Name" : { "Type" : "string", + "Requirement" : "informational" + } } + ==> { "OpenConnect.Cookie" : "0123456@adfsf@asasdf" } diff --git a/doc/vpn-config-format.txt b/doc/vpn-config-format.txt new file mode 100644 index 00000000..23c9c149 --- /dev/null +++ b/doc/vpn-config-format.txt @@ -0,0 +1,235 @@ +Connman configuration file format for VPN +***************************************** + +Connman VPN uses configuration files to provision existing providers. +vpnd will be looking for its configuration files at VPN_STORAGEDIR +which by default points to /var/lib/connman-vpn. Configuration file names +must not include other characters than letters or numbers and must have +a .config suffix. Those configuration files are text files with a simple +key-value pair format organized into sections. Values do not comprise leading +trailing whitespace. We typically have one file per provisioned network. + +If the config file is removed, then vpnd tries to remove the +provisioned service. If an individual service entry inside a config is removed, +then the corresponding provisioned service is removed. If a service +section is changed, then the corresponding service is removed and immediately +re-provisioned. + + +Global section [global] +======================= + +These files can have an optional global section describing the actual file. +The two allowed fields for this section are: +- Name: Name of the network. +- Description: Description of the network. + + +Provider section [provider_*] +============================= + +Each provisioned provider must start with the [provider_*] tag. +Replace * with an identifier unique to the config file. + +Allowed fields: +- Type: Provider type. Value of OpenConnect, OpenVPN, VPNC, L2TP or PPTP + +VPN related parameters (M = mandatory, O = optional): +- Name: A user defined name for the VPN (M) +- Host: VPN server IP address (M) +- Domain: Domain name for the VPN service (M) +- Networks: The networks behind the VPN link can be defined here. This can + be missing if all traffic should go via VPN tunnel. If there are more + than one network, then separate them by comma. Format of the entry + is network/netmask/gateway. The gateway can be left out. (O) + Example: 192.168.100.0/24/10.1.0.1,192.168.200.0/255.255.255.0/10.1.0.2 + For IPv6 addresses only prefix length is accepted like this 2001:db8::1/64 + +OpenConnect VPN supports following options (see openconnect(8) for details): + Option name OpenConnect option Description + OpenConnect.ServerCert --servercert SHA1 certificate fingerprint of the + final VPN server after possible web + authentication login, selection and + redirection (O) + OpenConnect.CACert --cafile File containing other Certificate + Authorities in addition to the ones + in the system trust database (O) + OpenConnect.ClientCert --certificate Client certificate file, if needed + by web authentication (O) + VPN.MTU --mtu Request MTU from server as the MTU + of the tunnel (O) + OpenConnect.Cookie --cookie-on-stdin Cookie received as a result of the + web authentication. As the cookie + lifetime can be very limited, it + does not usually make sense to add + it into the configuration file (O) + OpenConnect.VPNHost The final VPN server to use after + completing the web authentication. + Only usable for extremely simple VPN + configurations and should normally + be set only via the VPN Agent API. +If OpenConnect.Cookie or OpenConnect.ServerCert are missing, the VPN Agent will +be contacted to supply the information. + +OpenVPN VPN supports following options (see openvpn(8) for details): + Option name OpenVPN option Description + OpenVPN.CACert --ca Certificate authority file (M) + OpenVPN.Cert --cert Local peer's signed certificate (M) + OpenVPN.Key --key Local peer's private key (M) + OpenVPN.MTU --mtu MTU of the tunnel (O) + OpenVPN.NSCertType --ns-cert-type Peer certificate type, value of + either server or client (O) + OpenVPN.Proto --proto Use protocol (O) + OpenVPN.Port --port TCP/UDP port number (O) + OpenVPN.AuthUserPass --auth-user-pass Authenticate with server using + username/password (O) + OpenVPN.AskPass --askpass Get certificate password from file (O) + OpenVPN.AuthNoCache --auth-nocache Don't cache --askpass or + --auth-user-pass value (O) + OpenVPN.TLSRemote --tls-remote Accept connections only from a host + with X509 name or common name equal + to name parameter (O) + OpenVPN.TLSAuth sub-option of --tls-remote (O) + OpenVPN.TLSAuthDir sub-option of --tls-remote (O) + OpenVPN.Cipher --cipher Encrypt packets with cipher algorithm + given as parameter (O) + OpenVPN.Auth --auth Authenticate packets with HMAC using + message digest algorithm alg (O) + OpenVPN.CompLZO --comp-lzo Use fast LZO compression. Value can + be "yes", "no", or "adaptive". Default + is adaptive (O) + OpenVPN.RemoteCertTls --remote-cert-tls Require that peer certificate was + signed based on RFC3280 TLS rules. + Value is "client" or "server" (O) + OpenVPN.ConfigFile --config OpenVPN config file that can contain + extra options not supported by OpenVPN + plugin (O) + +VPNC VPN supports following options (see vpnc(8) for details): + Option name VPNC config value Description + VPNC.IPSec.ID IPSec ID your group username (M) + VPNC.IPSec.Secret IPSec secret your group password (cleartext) (O) + VPNC.Xauth.Username Xauth username your username (O) + VPNC.Xauth.Password Xauth password your password (cleartext) (O) + VPNC.IKE.Authmode IKE Authmode IKE Authentication mode (O) + VPNC.IKE.DHGroup IKE DH Group name of the IKE DH Group (O) + VPNC.PFS Perfect Forward Secrecy Diffie-Hellman group to use for PFS (O) + VPNC.Domain Domain Domain name for authentication (O) + VPNC.Vendor Vendor vendor of your IPSec gateway (O) + VPNC.LocalPort Local Port local ISAKMP port number to use + VPNC.CiscoPort Cisco UDP Encapsulation Port Local UDP port number to use (O) + VPNC.AppVersion Application Version Application Version to report (O) + VPNC.NATTMode NAT Traversal Mode Which NAT-Traversal Method to use (O) + VPNC.DPDTimeout DPD idle timeout (our side) Send DPD packet after timeout (O) + VPNC.SingleDES Enable Single DES enables single DES encryption (O) + VPNC.NoEncryption Enable no encryption enables using no encryption for data traffic (O) + +L2TP VPN supports following options (see xl2tpd.conf(5) and pppd(8) for details) + Option name xl2tpd config value Description + L2TP.User - L2TP user name, asked from the user + if not set here (O) + L2TP.Password - L2TP password, asked from the user + if not set here (O) + L2TP.BPS bps Max bandwith to use (O) + L2TP.TXBPS tx bps Max transmit bandwith to use (O) + L2TP.RXBPS rx bps Max receive bandwith to use (O) + L2TP.LengthBit length bit Use length bit (O) + L2TP.Challenge challenge Use challenge authentication (O) + L2TP.DefaultRoute defaultroute Default route (O) + L2TP.FlowBit flow bit Use seq numbers (O) + L2TP.TunnelRWS tunnel rws Window size (O) + L2TP.Exclusive exclusive Use only one control channel (O) + L2TP.Redial redial Redial if disconnected (O) + L2TP.RedialTimeout redial timeout Redial timeout (O) + L2TP.MaxRedials max redials How many times to try redial (O) + L2TP.RequirePAP require pap Need pap (O) + L2TP.RequireCHAP require chap Need chap (O) + L2TP.ReqAuth require authentication Need auth (O) + L2TP.AccessControl access control Accept only these peers (O) + L2TP.AuthFile auth file Authentication file location (O) + L2TP.ListenAddr listen-addr Listen address (O) + L2TP.IPsecSaref ipsec saref Use IPSec SA (O) + L2TP.Port port What UDP port is used (O) + + Option name pppd config value Description + PPPD.EchoFailure lcp-echo-failure Dead peer check count (O) + PPPD.EchoInterval lcp-echo-interval Dead peer check interval (O) + PPPD.Debug debug Debug level (O) + PPPD.RefuseEAP refuse-eap Deny eap auth (O) + PPPD.RefusePAP refuse-pap Deny pap auth (O) + PPPD.RefuseCHAP refuse-chap Deny chap auth (O) + PPPD.RefuseMSCHAP refuse-mschap Deny mschap auth (O) + PPPD.RefuseMSCHAP2 refuse-mschapv2 Deny mschapv2 auth (O) + PPPD.NoBSDComp nobsdcomp Disables BSD compression (O) + PPPD.NoPcomp nopcomp Disable protocol compression (O) + PPPD.UseAccomp accomp Disable address/control compression (O) + PPPD.NoDeflate nodeflate Disable deflate compression (O) + PPPD.ReqMPPE require-mppe Require the use of MPPE (O) + PPPD.ReqMPPE40 require-mppe-40 Require the use of MPPE 40 bit (O) + PPPD.ReqMPPE128 require-mppe-128 Require the use of MPPE 128 bit (O) + PPPD.ReqMPPEStateful mppe-stateful Allow MPPE to use stateful mode (O) + PPPD.NoVJ no-vj-comp No Van Jacobson compression (O) + + +PPTP VPN supports following options (see pptp(8) and pppd(8) for details) + Option name pptp config value Description + PPTP.User - PPTP user name, asked from the user + if not set here (O) + PPTP.Password - PPTP password, asked from the user + if not set here (O) + + Option name pppd config value Description + PPPD.EchoFailure lcp-echo-failure Dead peer check count (O) + PPPD.EchoInterval lcp-echo-interval Dead peer check interval (O) + PPPD.Debug debug Debug level (O) + PPPD.RefuseEAP refuse-eap Deny eap auth (O) + PPPD.RefusePAP refuse-pap Deny pap auth (O) + PPPD.RefuseCHAP refuse-chap Deny chap auth (O) + PPPD.RefuseMSCHAP refuse-mschap Deny mschap auth (O) + PPPD.RefuseMSCHAP2 refuse-mschapv2 Deny mschapv2 auth (O) + PPPD.NoBSDComp nobsdcomp Disables BSD compression (O) + PPPD.NoDeflate nodeflate Disable deflate compression (O) + PPPD.RequirMPPE require-mppe Require the use of MPPE (O) + PPPD.RequirMPPE40 require-mppe-40 Require the use of MPPE 40 bit (O) + PPPD.RequirMPPE128 require-mppe-128 Require the use of MPPE 128 bit (O) + PPPD.RequirMPPEStateful mppe-stateful Allow MPPE to use stateful mode (O) + PPPD.NoVJ no-vj-comp No Van Jacobson compression (O) + + +Example +======= + +This is a configuration file for a VPN providing L2TP, OpenVPN and +OpenConnect services. + + +example@example:[~]$ cat /var/lib/connman/vpn/example.config +[global] +Name = Example +Description = Example VPN configuration + +[provider_l2tp] +Type = L2TP +Name = Connection to corporate network +Host = 1.2.3.4 +Domain = corporate.com +Networks = 10.10.30.0/24 +L2TP.User = username + +[provider_openconnect] +Type = OpenConnect +Name = Connection to corporate network using Cisco VPN +Host = 7.6.5.4 +Domain = corporate.com +Networks = 10.10.20.0/255.255.255.0/10.20.1.5,192.168.99.1/24,2001:db8::1/64 +OpenConnect.ServerCert = 263AFAB4CB2E6621D12E90182008AEF44AEFA031 +OpenConnect.CACert = /etc/certs/certificate.p12 + +[provider_openvpn] +Type = OpenVPN +Name = Connection to corporate network using OpenVPN +Host = 3.2.5.6 +Domain = my.home.network +OpenVPN.CACert = /etc/certs/cacert.pem +OpenVPN.Cert = /etc/certs/cert.pem +OpenVPN.Key = /etc/certs/cert.key diff --git a/doc/wifi-p2p-overview.txt b/doc/wifi-p2p-overview.txt new file mode 100644 index 00000000..73b677c5 --- /dev/null +++ b/doc/wifi-p2p-overview.txt @@ -0,0 +1,54 @@ +WiFi P2P Functionality [experimental] +************************************* + +Note: Nothing about WiFi P2P Services is exposed, this is yet to be specified. + +Summary +======= + +WiFi P2P is supported as follows: +- if hardware and wpa_supplicant supports it, a "p2p" technology will appear + in the technology list +- "p2p" technology, as for "wifi" technology, supports a Scan() method. Such + method will trigger a P2P find process. The results will be available + through the Manager interface, comparable to services being available + through this same interface after a Scan() on "wifi" technology. +- the result of a "p2p" Scan() consists into a list of "peer" objects +- it is then possible to access peer information, connecting and disconnecting + it via the Peer API. + + +API Usage +========= + +The UI willing to access to WiFi P2P technology should proceed this way: +- Request Manager.GetTechnologies() and figure out from the result if "p2p" + technology is provided. What comes next implies this successful case. +- Add a listener to signal Manager.PeersChanged(): this signal will provide + the results of a "p2p" technology Scan(). +- From the "p2p" technology object, request a Technology.Scan() method. This + will run for a while a P2P find process. +- If P2P peers are found, it will be signaled through Manager.PeersChanged(). + Objects are "Peer" objects. UI might use Manager.GetPeers() instead, if + listening to a signal is not the preferred way. +- Once selected the proper Peer object, request a Peer.Connect() method on it + so it will connect to it. Peer.Disconnect() will disconnect. + +Internals +========= + +Through such API, everything is made to hide irrelevant informations for the +applications, which are: + +- Everything related to the P2P group and the Group Owner (GO) +- All low level peer settings +- All Service Request Discovery mechanism + +Hiding this mean ConnMan will handle it properly behind. + +For instance, if you connect to a Peer which happens to be a persistent GO +ConnMan will notice it and store the Group information for a later connection +to speed up such connection. + +For Service Discovery (SD), this will be handled the same way: silently +behind, by ConnMan. diff --git a/gdbus/client.c b/gdbus/client.c index eb68a0f8..48711ae8 100644 --- a/gdbus/client.c +++ b/gdbus/client.c @@ -42,6 +42,7 @@ struct GDBusClient { DBusConnection *dbus_conn; char *service_name; char *base_path; + char *root_path; guint watch; guint added_watch; guint removed_watch; @@ -1107,7 +1108,11 @@ static void get_managed_objects(GDBusClient *client) { DBusMessage *msg; - if (!client->proxy_added && !client->proxy_removed) { + if (!client->connected) + return; + + if ((!client->proxy_added && !client->proxy_removed) || + !client->root_path) { refresh_properties(client); return; } @@ -1115,9 +1120,10 @@ static void get_managed_objects(GDBusClient *client) if (client->get_objects_call != NULL) return; - msg = dbus_message_new_method_call(client->service_name, "/", - DBUS_INTERFACE_DBUS ".ObjectManager", - "GetManagedObjects"); + msg = dbus_message_new_method_call(client->service_name, + client->root_path, + DBUS_INTERFACE_OBJECT_MANAGER, + "GetManagedObjects"); if (msg == NULL) return; @@ -1142,13 +1148,13 @@ static void service_connect(DBusConnection *conn, void *user_data) g_dbus_client_ref(client); + client->connected = TRUE; + if (client->connect_func) client->connect_func(conn, client->connect_data); get_managed_objects(client); - client->connected = TRUE; - g_dbus_client_unref(client); } @@ -1156,13 +1162,13 @@ static void service_disconnect(DBusConnection *conn, void *user_data) { GDBusClient *client = user_data; + client->connected = FALSE; + g_list_free_full(client->proxy_list, proxy_free); client->proxy_list = NULL; - if (client->disconn_func) { + if (client->disconn_func) client->disconn_func(conn, client->disconn_data); - client->connected = FALSE; - } } static DBusHandlerResult message_filter(DBusConnection *connection, @@ -1196,10 +1202,18 @@ static DBusHandlerResult message_filter(DBusConnection *connection, GDBusClient *g_dbus_client_new(DBusConnection *connection, const char *service, const char *path) { + return g_dbus_client_new_full(connection, service, path, "/"); +} + +GDBusClient *g_dbus_client_new_full(DBusConnection *connection, + const char *service, + const char *path, + const char *root_path) +{ GDBusClient *client; unsigned int i; - if (connection == NULL) + if (!connection || !service) return NULL; client = g_try_new0(GDBusClient, 1); @@ -1215,6 +1229,7 @@ GDBusClient *g_dbus_client_new(DBusConnection *connection, client->dbus_conn = dbus_connection_ref(connection); client->service_name = g_strdup(service); client->base_path = g_strdup(path); + client->root_path = g_strdup(root_path); client->connected = FALSE; client->match_rules = g_ptr_array_sized_new(1); @@ -1224,14 +1239,18 @@ GDBusClient *g_dbus_client_new(DBusConnection *connection, service_connect, service_disconnect, client, NULL); + + if (!root_path) + return g_dbus_client_ref(client); + client->added_watch = g_dbus_add_signal_watch(connection, service, - "/", + client->root_path, DBUS_INTERFACE_OBJECT_MANAGER, "InterfacesAdded", interfaces_added, client, NULL); client->removed_watch = g_dbus_add_signal_watch(connection, service, - "/", + client->root_path, DBUS_INTERFACE_OBJECT_MANAGER, "InterfacesRemoved", interfaces_removed, @@ -1305,6 +1324,7 @@ void g_dbus_client_unref(GDBusClient *client) g_free(client->service_name); g_free(client->base_path); + g_free(client->root_path); g_free(client); } @@ -1371,7 +1391,8 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client, client->property_changed = property_changed; client->user_data = user_data; - get_managed_objects(client); + if (proxy_added || proxy_removed || property_changed) + get_managed_objects(client); return TRUE; } diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index 551c306a..d99c2549 100644 --- a/gdbus/gdbus.h +++ b/gdbus/gdbus.h @@ -216,6 +216,7 @@ struct GDBusSecurityTable { .flags = G_DBUS_SIGNAL_FLAG_EXPERIMENTAL void g_dbus_set_flags(int flags); +int g_dbus_get_flags(void); gboolean g_dbus_register_interface(DBusConnection *connection, const char *path, const char *name, @@ -355,6 +356,10 @@ gboolean g_dbus_proxy_set_removed_watch(GDBusProxy *proxy, GDBusClient *g_dbus_client_new(DBusConnection *connection, const char *service, const char *path); +GDBusClient *g_dbus_client_new_full(DBusConnection *connection, + const char *service, + const char *path, + const char *root_path); GDBusClient *g_dbus_client_ref(GDBusClient *client); void g_dbus_client_unref(GDBusClient *client); diff --git a/gdbus/mainloop.c b/gdbus/mainloop.c index 3e88eac8..b90a8447 100644 --- a/gdbus/mainloop.c +++ b/gdbus/mainloop.c @@ -322,6 +322,7 @@ DBusConnection *g_dbus_setup_private(DBusBusType type, const char *name, return NULL; if (setup_bus(conn, name, error) == FALSE) { + dbus_connection_close(conn); dbus_connection_unref(conn); return NULL; } diff --git a/gdbus/object.c b/gdbus/object.c index 4d5a64cb..96db5166 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -1412,7 +1412,10 @@ DBusMessage *g_dbus_create_error_valist(DBusMessage *message, const char *name, { char str[1024]; - vsnprintf(str, sizeof(str), format, args); + if (format) + vsnprintf(str, sizeof(str), format, args); + else + str[0] = '\0'; return dbus_message_new_error(message, name, str); } @@ -1530,11 +1533,8 @@ gboolean g_dbus_send_error_valist(DBusConnection *connection, const char *format, va_list args) { DBusMessage *error; - char str[1024]; - - vsnprintf(str, sizeof(str), format, args); - error = dbus_message_new_error(message, name, str); + error = g_dbus_create_error_valist(message, name, format, args); if (error == NULL) return FALSE; @@ -1816,3 +1816,8 @@ void g_dbus_set_flags(int flags) { global_flags = flags; } + +int g_dbus_get_flags(void) +{ + return global_flags; +} diff --git a/gdbus/watch.c b/gdbus/watch.c index 0d0054c1..b60f650f 100644 --- a/gdbus/watch.c +++ b/gdbus/watch.c @@ -523,9 +523,7 @@ static DBusHandlerResult message_filter(DBusConnection *connection, member = dbus_message_get_member(message); dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID); - /* Sender is always the owner */ - if (sender == NULL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* If sender != NULL it is always the owner */ for (current = listeners; current != NULL; current = current->next) { data = current->data; @@ -533,6 +531,9 @@ static DBusHandlerResult message_filter(DBusConnection *connection, if (connection != data->connection) continue; + if (!sender && data->owner) + continue; + if (data->owner && g_str_equal(sender, data->owner) == FALSE) continue; diff --git a/gdhcp/client.c b/gdhcp/client.c index 66c3a90d..5a4a89c8 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -514,11 +514,13 @@ static int send_release(GDHCPClient *dhcp_client, uint32_t server, uint32_t ciaddr) { struct dhcp_packet packet; + uint64_t rand; debug(dhcp_client, "sending DHCP release request"); init_packet(dhcp_client, &packet, DHCPRELEASE); - packet.xid = rand(); + dhcp_get_random(&rand); + packet.xid = rand; packet.ciaddr = htonl(ciaddr); dhcp_add_option_uint32(&packet, DHCP_SERVER_ID, server); @@ -540,7 +542,7 @@ static gboolean send_probe_packet(gpointer dhcp_data) /* if requested_ip is not valid, pick a new address*/ if (dhcp_client->requested_ip == 0) { debug(dhcp_client, "pick a new random address"); - dhcp_client->requested_ip = ipv4ll_random_ip(0); + dhcp_client->requested_ip = ipv4ll_random_ip(); } debug(dhcp_client, "sending IPV4LL probe request"); @@ -1361,7 +1363,6 @@ static int dhcp_recv_l2_packet(struct dhcp_packet *dhcp_pkt, int fd, static void ipv4ll_start(GDHCPClient *dhcp_client) { guint timeout; - int seed; remove_timeouts(dhcp_client); @@ -1369,9 +1370,7 @@ static void ipv4ll_start(GDHCPClient *dhcp_client) dhcp_client->retry_times = 0; dhcp_client->requested_ip = 0; - /*try to start with a based mac address ip*/ - seed = (dhcp_client->mac_address[4] << 8 | dhcp_client->mac_address[4]); - dhcp_client->requested_ip = ipv4ll_random_ip(seed); + dhcp_client->requested_ip = ipv4ll_random_ip(); /*first wait a random delay to avoid storm of arp request on boot*/ timeout = ipv4ll_random_delay_ms(PROBE_WAIT); @@ -1670,6 +1669,7 @@ static gboolean start_expire(gpointer user_data) static gboolean continue_rebound(gpointer user_data) { GDHCPClient *dhcp_client = user_data; + uint64_t rand; switch_listening_mode(dhcp_client, L2); send_request(dhcp_client); @@ -1680,9 +1680,10 @@ static gboolean continue_rebound(gpointer user_data) /*recalculate remaining rebind time*/ dhcp_client->T2 >>= 1; if (dhcp_client->T2 > 60) { + dhcp_get_random(&rand); dhcp_client->t2_timeout = g_timeout_add_full(G_PRIORITY_HIGH, - dhcp_client->T2 * 1000 + (rand() % 2000) - 1000, + dhcp_client->T2 * 1000 + (rand % 2000) - 1000, continue_rebound, dhcp_client, NULL); @@ -1714,6 +1715,7 @@ static gboolean start_rebound(gpointer user_data) static gboolean continue_renew (gpointer user_data) { GDHCPClient *dhcp_client = user_data; + uint64_t rand; switch_listening_mode(dhcp_client, L3); send_request(dhcp_client); @@ -1724,8 +1726,9 @@ static gboolean continue_renew (gpointer user_data) dhcp_client->T1 >>= 1; if (dhcp_client->T1 > 60) { + dhcp_get_random(&rand); dhcp_client->t1_timeout = g_timeout_add_full(G_PRIORITY_HIGH, - dhcp_client->T1 * 1000 + (rand() % 2000) - 1000, + dhcp_client->T1 * 1000 + (rand % 2000) - 1000, continue_renew, dhcp_client, NULL); @@ -2461,7 +2464,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, rapid_commit = dhcpv6_get_option(packet6, pkt_len, G_DHCPV6_RAPID_COMMIT, &option_len, &count); - if (!rapid_commit || option_len == 0 || + if (!rapid_commit || option_len != 0 || count != 1) /* RFC 3315, 17.1.4 */ return TRUE; @@ -2707,6 +2710,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) { int re; uint32_t addr; + uint64_t rand; if (dhcp_client->type == G_DHCP_IPV6) { if (dhcp_client->information_req_cb) { @@ -2815,7 +2819,8 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) if (re != 0) return re; - dhcp_client->xid = rand(); + dhcp_get_random(&rand); + dhcp_client->xid = rand; dhcp_client->start = time(NULL); } @@ -2984,6 +2989,14 @@ int g_dhcp_client_get_index(GDHCPClient *dhcp_client) return dhcp_client->ifindex; } +char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client) +{ + if (!dhcp_client) + return NULL; + + return get_ip(dhcp_client->server_ip); +} + char *g_dhcp_client_get_address(GDHCPClient *dhcp_client) { return g_strdup(dhcp_client->assigned_ip); diff --git a/gdhcp/common.c b/gdhcp/common.c index 45278a88..f3d4677e 100644 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -35,6 +35,7 @@ #include <netpacket/packet.h> #include <net/ethernet.h> #include <arpa/inet.h> +#include <fcntl.h> #include "gdhcp.h" #include "common.h" @@ -58,6 +59,42 @@ static const DHCPOption client_options[] = { { OPTION_UNKNOWN, 0x00 }, }; +#define URANDOM "/dev/urandom" +static int random_fd = -1; + +int dhcp_get_random(uint64_t *val) +{ + int r; + + if (random_fd < 0) { + random_fd = open(URANDOM, O_RDONLY); + if (random_fd < 0) { + r = -errno; + *val = random(); + + return r; + } + } + + if (read(random_fd, val, sizeof(uint64_t)) < 0) { + r = -errno; + *val = random(); + + return r; + } + + return 0; +} + +void dhcp_cleanup_random(void) +{ + if (random_fd < 0) + return; + + close(random_fd); + random_fd = -1; +} + GDHCPOptionType dhcp_get_code_type(uint8_t code) { int i; @@ -356,12 +393,14 @@ void dhcp_init_header(struct dhcp_packet *packet, char type) void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type) { int id; + uint64_t rand; memset(packet, 0, sizeof(*packet)); packet->message = type; - id = random(); + dhcp_get_random(&rand); + id = rand; packet->transaction_id[0] = (id >> 16) & 0xff; packet->transaction_id[1] = (id >> 8) & 0xff; @@ -434,19 +473,14 @@ uint16_t dhcp_checksum(void *addr, int count) static const struct in6_addr in6addr_all_dhcp_relay_agents_and_servers_mc = IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_MC_INIT; -/* from netinet/in.h */ -struct in6_pktinfo { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ -}; - int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) { struct msghdr m; struct iovec v; struct in6_pktinfo *pktinfo; struct cmsghdr *cmsg; - int fd, ret; + int fd, ret, opt = 1; + struct sockaddr_in6 src; struct sockaddr_in6 dst; void *control_buf; size_t control_buf_len; @@ -455,6 +489,17 @@ int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) if (fd < 0) return -errno; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + memset(&src, 0, sizeof(src)); + src.sin6_family = AF_INET6; + src.sin6_port = htons(DHCPV6_CLIENT_PORT); + + if (bind(fd, (struct sockaddr *) &src, sizeof(src)) <0) { + close(fd); + return -errno; + } + memset(&dst, 0, sizeof(dst)); dst.sin6_family = AF_INET6; dst.sin6_port = htons(DHCPV6_SERVER_PORT); diff --git a/gdhcp/common.h b/gdhcp/common.h index c6927992..75abc183 100644 --- a/gdhcp/common.h +++ b/gdhcp/common.h @@ -170,6 +170,14 @@ static const uint8_t dhcp_option_lengths[] = { [OPTION_U32] = 4, }; +/* already defined within netinet/in.h if using GNU compiler */ +#ifndef __USE_GNU +struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; +#endif + uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code); uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, int code, uint16_t *option_len, int *option_count); diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index f3e47bf6..0ed7fa54 100644 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -150,6 +150,7 @@ GDHCPClientError g_dhcp_client_set_send(GDHCPClient *client, unsigned char option_code, const char *option_value); +char *g_dhcp_client_get_server_address(GDHCPClient *client); char *g_dhcp_client_get_address(GDHCPClient *client); char *g_dhcp_client_get_netmask(GDHCPClient *client); GList *g_dhcp_client_get_option(GDHCPClient *client, @@ -201,6 +202,9 @@ typedef enum { typedef void (*GDHCPSaveLeaseFunc) (unsigned char *mac, unsigned int nip, unsigned int expire); + +typedef void (*GDHCPLeaseAddedCb) (unsigned char *mac, uint32_t ip); + struct _GDHCPServer; typedef struct _GDHCPServer GDHCPServer; @@ -223,6 +227,12 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server, unsigned int lease_time); void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server, GDHCPSaveLeaseFunc func, gpointer user_data); +void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, + GDHCPLeaseAddedCb cb); + +int dhcp_get_random(uint64_t *val); +void dhcp_cleanup_random(void); + #ifdef __cplusplus } #endif diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c index 9bf52b0a..c43971f0 100644 --- a/gdhcp/ipv4ll.c +++ b/gdhcp/ipv4ll.c @@ -34,23 +34,19 @@ #include <glib.h> #include "ipv4ll.h" +#include "common.h" /** * Return a random link local IP (in host byte order) */ -uint32_t ipv4ll_random_ip(int seed) +uint32_t ipv4ll_random_ip(void) { unsigned tmp; + uint64_t rand; - if (seed) - srand(seed); - else { - struct timeval tv; - gettimeofday(&tv, NULL); - srand(tv.tv_usec); - } do { - tmp = rand(); + dhcp_get_random(&rand); + tmp = rand; tmp = tmp & IN_CLASSB_HOST; } while (tmp > (IN_CLASSB_HOST - 0x0200)); return ((LINKLOCAL_ADDR + 0x0100) + tmp); @@ -61,13 +57,10 @@ uint32_t ipv4ll_random_ip(int seed) */ guint ipv4ll_random_delay_ms(guint secs) { - struct timeval tv; - guint tmp; + uint64_t rand; - gettimeofday(&tv, NULL); - srand(tv.tv_usec); - tmp = rand(); - return tmp % (secs * 1000); + dhcp_get_random(&rand); + return rand % (secs * 1000); } int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, diff --git a/gdhcp/ipv4ll.h b/gdhcp/ipv4ll.h index aaac33ed..bee8138a 100644 --- a/gdhcp/ipv4ll.h +++ b/gdhcp/ipv4ll.h @@ -43,7 +43,7 @@ extern "C" { #define RATE_LIMIT_INTERVAL 60 #define DEFEND_INTERVAL 10 -uint32_t ipv4ll_random_ip(int seed); +uint32_t ipv4ll_random_ip(void); guint ipv4ll_random_delay_ms(guint secs); int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, uint32_t target_ip, int ifindex); diff --git a/gdhcp/server.c b/gdhcp/server.c index aa40488c..8574c24c 100644 --- a/gdhcp/server.c +++ b/gdhcp/server.c @@ -56,7 +56,7 @@ struct _GDHCPServer { char *interface; uint32_t start_ip; uint32_t end_ip; - uint32_t server_nip; + uint32_t server_nip; /* our address in network byte order */ uint32_t lease_seconds; int listener_sockfd; guint listener_watch; @@ -65,6 +65,7 @@ struct _GDHCPServer { GHashTable *nip_lease_hash; GHashTable *option_hash; /* Options send to client */ GDHCPSaveLeaseFunc save_lease_func; + GDHCPLeaseAddedCb lease_added_cb; GDHCPDebugFunc debug_func; gpointer debug_data; }; @@ -213,6 +214,9 @@ static struct dhcp_lease *add_lease(GDHCPServer *dhcp_server, uint32_t expire, g_hash_table_insert(dhcp_server->nip_lease_hash, GINT_TO_POINTER((int) lease->lease_nip), lease); + if (dhcp_server->lease_added_cb) + dhcp_server->lease_added_cb(lease->lease_mac, yiaddr); + return lease; } @@ -450,7 +454,7 @@ static void init_packet(GDHCPServer *dhcp_server, struct dhcp_packet *packet, packet->gateway_nip = client_packet->gateway_nip; packet->ciaddr = client_packet->ciaddr; dhcp_add_option_uint32(packet, DHCP_SERVER_ID, - dhcp_server->server_nip); + ntohl(dhcp_server->server_nip)); } static void add_option(gpointer key, gpointer value, gpointer user_data) @@ -664,7 +668,8 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID); if (server_id_option) { - uint32_t server_nid = get_be32(server_id_option); + uint32_t server_nid = + get_unaligned((const uint32_t *) server_id_option); if (server_nid != dhcp_server->server_nip) return TRUE; @@ -814,6 +819,15 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server, dhcp_server->save_lease_func = func; } +void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, + GDHCPLeaseAddedCb cb) +{ + if (!dhcp_server) + return; + + dhcp_server->lease_added_cb = cb; +} + GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server) { if (!dhcp_server) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index e49aaa6a..187dc654 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -225,11 +225,6 @@ int g_supplicant_interface_scan(GSupplicantInterface *interface, GSupplicantInterfaceCallback callback, void *user_data); -int g_supplicant_interface_autoscan(GSupplicantInterface *interface, - const char *autoscan_data, - GSupplicantInterfaceCallback callback, - void *user_data); - int g_supplicant_interface_p2p_find(GSupplicantInterface *interface, GSupplicantInterfaceCallback callback, void *user_data); @@ -326,6 +321,7 @@ GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer); const char *g_supplicant_peer_get_path(GSupplicantPeer *peer); const char *g_supplicant_peer_get_identifier(GSupplicantPeer *peer); const void *g_supplicant_peer_get_device_address(GSupplicantPeer *peer); +const void *g_supplicant_peer_get_iface_address(GSupplicantPeer *peer); const char *g_supplicant_peer_get_name(GSupplicantPeer *peer); const unsigned char *g_supplicant_peer_get_widi_ies(GSupplicantPeer *peer, int *length); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 909a6178..cd91f952 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -44,6 +44,8 @@ #define IEEE80211_CAP_IBSS 0x0002 #define IEEE80211_CAP_PRIVACY 0x0010 +#define BSS_UNKNOWN_STRENGTH -90 + static DBusConnection *connection; static const GSupplicantCallbacks *callbacks_pointer; @@ -1079,6 +1081,14 @@ const void *g_supplicant_peer_get_device_address(GSupplicantPeer *peer) return peer->device_address; } +const void *g_supplicant_peer_get_iface_address(GSupplicantPeer *peer) +{ + if (!peer) + return NULL; + + return peer->iface_address; +} + const char *g_supplicant_peer_get_name(GSupplicantPeer *peer) { if (!peer) @@ -1750,6 +1760,9 @@ static void bss_property(const char *key, DBusMessageIter *iter, dbus_message_iter_get_basic(iter, &signal); bss->signal = signal; + if (!bss->signal) + bss->signal = BSS_UNKNOWN_STRENGTH; + } else if (g_strcmp0(key, "Level") == 0) { dbus_int32_t level = 0; @@ -1814,6 +1827,7 @@ static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter, bss->interface = interface; bss->path = g_strdup(path); + bss->signal = BSS_UNKNOWN_STRENGTH; return bss; } @@ -1900,7 +1914,7 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data) bss = g_hash_table_lookup(network->bss_table, path); if (network->best_bss == bss) { network->best_bss = NULL; - network->signal = 0; + network->signal = BSS_UNKNOWN_STRENGTH; } g_hash_table_remove(bss_mapping, path); @@ -2838,7 +2852,6 @@ static void group_sig_property(const char *key, DBusMessageIter *iter, if (len == ETH_ALEN) memcpy(data->iface_address, dev_addr, len); - } else if (g_strcmp0(key, "role") == 0) { const char *str = NULL; @@ -3079,7 +3092,11 @@ static void signal_group_peer_disconnected(const char *path, DBusMessageIter *it if (!peer_path) return; - elem = g_slist_find_custom(group->members, peer_path, g_str_equal); + for (elem = group->members; elem; elem = elem->next) { + if (!g_strcmp0(elem->data, peer_path)) + break; + } + if (!elem) return; @@ -3432,14 +3449,6 @@ struct interface_scan_data { void *user_data; }; -struct interface_autoscan_data { - GSupplicantInterface *interface; - char *path; - GSupplicantInterfaceCallback callback; - const char *autoscan_params; - void *user_data; -}; - static void interface_create_data_free(struct interface_create_data *data) { g_free(data->ifname); @@ -3956,64 +3965,6 @@ int g_supplicant_interface_scan(GSupplicantInterface *interface, return ret; } -static void interface_autoscan_result(const char *error, - DBusMessageIter *iter, void *user_data) -{ - struct interface_autoscan_data *data = user_data; - int err = 0; - - if (error) { - SUPPLICANT_DBG("error %s", error); - err = -EIO; - } - - g_free(data->path); - - if (data->callback) - data->callback(err, data->interface, data->user_data); - - dbus_free(data); -} - -static void interface_autoscan_params(DBusMessageIter *iter, void *user_data) -{ - struct interface_autoscan_data *data = user_data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, - &data->autoscan_params); -} - -int g_supplicant_interface_autoscan(GSupplicantInterface *interface, - const char *autoscan_data, - GSupplicantInterfaceCallback callback, - void *user_data) -{ - struct interface_autoscan_data *data; - int ret; - - data = dbus_malloc0(sizeof(*data)); - if (!data) - return -ENOMEM; - - data->interface = interface; - data->path = g_strdup(interface->path); - data->callback = callback; - data->autoscan_params = autoscan_data; - data->user_data = user_data; - - ret = supplicant_dbus_method_call(interface->path, - SUPPLICANT_INTERFACE ".Interface", "AutoScan", - interface_autoscan_params, - interface_autoscan_result, data, - interface); - if (ret < 0) { - g_free(data->path); - dbus_free(data); - } - - return ret; -} - static int parse_supplicant_error(DBusMessageIter *iter) { int err = -ECANCELED; @@ -4118,6 +4069,14 @@ error: g_free(data); } +static void add_network_security_none(DBusMessageIter *dict) +{ + const char *auth_alg = "OPEN"; + + supplicant_dbus_dict_append_basic(dict, "auth_alg", + DBUS_TYPE_STRING, &auth_alg); +} + static void add_network_security_wep(DBusMessageIter *dict, GSupplicantSSID *ssid) { @@ -4463,8 +4422,12 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid) char *key_mgmt; switch (ssid->security) { - case G_SUPPLICANT_SECURITY_UNKNOWN: case G_SUPPLICANT_SECURITY_NONE: + key_mgmt = "NONE"; + add_network_security_none(dict); + add_network_security_ciphers(dict, ssid); + break; + case G_SUPPLICANT_SECURITY_UNKNOWN: case G_SUPPLICANT_SECURITY_WEP: key_mgmt = "NONE"; add_network_security_wep(dict, ssid); diff --git a/include/ipconfig.h b/include/ipconfig.h index a86b2955..68ef40b6 100644 --- a/include/ipconfig.h +++ b/include/ipconfig.h @@ -36,9 +36,9 @@ extern "C" { enum connman_ipconfig_type { CONNMAN_IPCONFIG_TYPE_UNKNOWN = 0, - CONNMAN_IPCONFIG_TYPE_ALL = 0, CONNMAN_IPCONFIG_TYPE_IPV4 = 1, CONNMAN_IPCONFIG_TYPE_IPV6 = 2, + CONNMAN_IPCONFIG_TYPE_ALL = 3, }; enum connman_ipconfig_method { diff --git a/include/peer.h b/include/peer.h index 8a690f5f..80663932 100644 --- a/include/peer.h +++ b/include/peer.h @@ -64,6 +64,8 @@ void connman_peer_unref_debug(struct connman_peer *peer, const char *connman_peer_get_identifier(struct connman_peer *peer); void connman_peer_set_name(struct connman_peer *peer, const char *name); +void connman_peer_set_iface_address(struct connman_peer *peer, + const unsigned char *iface_address); void connman_peer_set_device(struct connman_peer *peer, struct connman_device *device); struct connman_device *connman_peer_get_device(struct connman_peer *peer); diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index 82217d03..45cc3194 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -36,7 +36,9 @@ #define BLUEZ_SERVICE "org.bluez" #define BLUEZ_PATH "/org/bluez" +#define BLUETOOTH_PAN_PANU "00001115-0000-1000-8000-00805f9b34fb" #define BLUETOOTH_PAN_NAP "00001116-0000-1000-8000-00805f9b34fb" +#define BLUETOOTH_PAN_GN "00001117-0000-1000-8000-00805f9b34fb" #define BLUETOOTH_ADDR_LEN 6 @@ -50,6 +52,7 @@ struct bluetooth_pan { struct connman_network *network; GDBusProxy *btdevice_proxy; GDBusProxy *btnetwork_proxy; + const char *pan_role; }; static void address2ident(const char *address, char *ident) @@ -85,28 +88,37 @@ static bool proxy_get_bool(GDBusProxy *proxy, const char *property) return value; } -static bool proxy_get_nap(GDBusProxy *proxy) +static const char *proxy_get_role(GDBusProxy *proxy) { - DBusMessageIter iter, value; + DBusMessageIter iter, value; + const char *pref = NULL; if (!proxy) - return false; + return NULL; if (!g_dbus_proxy_get_property(proxy, "UUIDs", &iter)) - return false; + return NULL; dbus_message_iter_recurse(&iter, &value); while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { const char *uuid; - dbus_message_iter_get_basic(&value, &uuid); - if (strcmp(uuid, BLUETOOTH_PAN_NAP) == 0) - return true; + dbus_message_iter_get_basic(&value, &uuid); + /* + * If a device offers more than one role, we prefer NAP, + * then GN, then PANU. + */ + if (!strcmp(uuid, BLUETOOTH_PAN_NAP)) + return "nap"; + if (!strcmp(uuid, BLUETOOTH_PAN_GN)) + pref = "gn"; + if (!strcmp(uuid, BLUETOOTH_PAN_PANU) && !pref) + pref = "panu"; dbus_message_iter_next(&value); } - return false; + return pref; } static int bluetooth_pan_probe(struct connman_network *network) @@ -225,9 +237,11 @@ static void pan_connect_cb(DBusMessage *message, void *user_data) static void pan_connect_append(DBusMessageIter *iter, void *user_data) { - const char *role = BLUETOOTH_PAN_NAP; + const char *path = user_data; + struct bluetooth_pan *pan; - dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &role); + pan = g_hash_table_lookup(networks, path); + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &pan->pan_role); } static int bluetooth_pan_connect(struct connman_network *network) @@ -322,8 +336,10 @@ static void btnetwork_property_change(GDBusProxy *proxy, const char *name, static void pan_create_nap(struct bluetooth_pan *pan) { struct connman_device *device; + const char* role; - if (!proxy_get_nap(pan->btdevice_proxy)) { + role = proxy_get_role(pan->btdevice_proxy); + if (!role) { pan_remove_nap(pan); return; } @@ -366,6 +382,7 @@ static void pan_create_nap(struct bluetooth_pan *pan) connman_network_set_group(pan->network, ident); } + pan->pan_role = role; connman_device_add_network(device, pan->network); if (pan_connect(pan, NULL)) @@ -376,9 +393,10 @@ static void btdevice_property_change(GDBusProxy *proxy, const char *name, DBusMessageIter *iter, void *user_data) { struct bluetooth_pan *pan; - bool pan_nap = false; + const char *old_role = NULL; + const char *new_role; - if (strcmp(name, "UUIDs") != 0) + if (strcmp(name, "UUIDs")) return; pan = g_hash_table_lookup(networks, g_dbus_proxy_get_path(proxy)); @@ -387,12 +405,13 @@ static void btdevice_property_change(GDBusProxy *proxy, const char *name, if (pan->network && connman_network_get_device(pan->network)) - pan_nap = true; + old_role = pan->pan_role; + new_role = proxy_get_role(pan->btdevice_proxy); - DBG("network %p network nap %d proxy nap %d", pan->network, pan_nap, - proxy_get_nap(pan->btdevice_proxy)); + DBG("network %p network role %s proxy role %s", pan->network, old_role, + new_role); - if (proxy_get_nap(pan->btdevice_proxy) == pan_nap) + if (old_role && new_role && !strcmp(old_role, new_role)) return; pan_create_nap(pan); @@ -447,7 +466,7 @@ static void pan_create(GDBusProxy *network_proxy) g_dbus_proxy_set_property_watch(pan->btdevice_proxy, btdevice_property_change, NULL); - DBG("pan %p %s nap %d", pan, path, proxy_get_nap(pan->btdevice_proxy)); + DBG("pan %p %s role %s", pan, path, proxy_get_role(pan->btdevice_proxy)); pan_create_nap(pan); } @@ -756,7 +775,7 @@ static void device_create(GDBusProxy *proxy) powered = proxy_get_bool(proxy, "Powered"); connman_device_set_powered(device, powered); - if (proxy_get_nap(proxy) && !bluetooth_tethering) + if (proxy_get_role(proxy) && !bluetooth_tethering) tethering_create(path, NULL, NULL, false); } @@ -880,7 +899,7 @@ static int bluetooth_tech_set_tethering(struct connman_technology *technology, if (i == 0) return -ENODEV; - return -EINPROGRESS; + return 0; } static struct connman_technology_driver tech_driver = { @@ -957,6 +976,8 @@ static void bluetooth_exit(void) */ device_driver.disable = NULL; + g_dbus_client_unref(client); + connman_network_driver_unregister(&network_driver); g_hash_table_destroy(networks); diff --git a/plugins/ethernet.c b/plugins/ethernet.c index b8e52ce0..d176508d 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -25,6 +25,13 @@ #include <errno.h> #include <net/if.h> +#include <string.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdio.h> + +#include <linux/if_vlan.h> +#include <linux/sockios.h> #ifndef IFF_LOWER_UP #define IFF_LOWER_UP 0x10000 @@ -50,6 +57,32 @@ struct ethernet_data { struct connman_network *network; }; + +static int get_vlan_vid(const char *ifname) +{ + struct vlan_ioctl_args vifr; + int vid; + int sk; + + memset(&vifr, 0, sizeof(vifr)); + + sk = socket(AF_INET, SOCK_STREAM, 0); + if (sk < 0) + return -errno; + + vifr.cmd = GET_VLAN_VID_CMD; + strncpy(vifr.device1, ifname, sizeof(vifr.device1)); + + if(ioctl(sk, SIOCSIFVLAN, &vifr) >= 0) + vid = vifr.u.VID; + else + vid = -errno; + + close(sk); + + return vid; +} + static int eth_network_probe(struct connman_network *network) { DBG("network %p", network); @@ -93,7 +126,8 @@ static void add_network(struct connman_device *device, struct ethernet_data *ethernet) { struct connman_network *network; - int index; + int index, vid; + char *ifname; network = connman_network_create("carrier", CONNMAN_NETWORK_TYPE_ETHERNET); @@ -102,6 +136,10 @@ static void add_network(struct connman_device *device, index = connman_device_get_index(device); connman_network_set_index(network, index); + ifname = connman_inet_ifname(index); + if (!ifname) + return; + vid = get_vlan_vid(ifname); connman_network_set_name(network, "Wired"); @@ -110,15 +148,21 @@ static void add_network(struct connman_device *device, return; } - if (!eth_tethering) + if (!eth_tethering) { + char group[10] = "cable"; /* * Prevent service from starting the reconnect * procedure as we do not want the DHCP client * to run when tethering. */ - connman_network_set_group(network, "cable"); + if (vid >= 0) + snprintf(group, sizeof(group), "%03x_cable", vid); + + connman_network_set_group(network, group); + } ethernet->network = network; + g_free(ifname); } static void remove_network(struct connman_device *device, diff --git a/plugins/ofono.c b/plugins/ofono.c index 7af551ba..5cd83029 100644 --- a/plugins/ofono.c +++ b/plugins/ofono.c @@ -277,13 +277,11 @@ static void set_connected(struct modem_data *modem) if (!service) return; + connman_service_create_ip4config(service, index); + connman_network_set_ipv4_method(modem->network, method); + if (method == CONNMAN_IPCONFIG_METHOD_FIXED || method == CONNMAN_IPCONFIG_METHOD_DHCP) { - connman_service_create_ip4config(service, index); - connman_network_set_index(modem->network, index); - - connman_network_set_ipv4_method(modem->network, method); - setip = true; } @@ -293,11 +291,10 @@ static void set_connected(struct modem_data *modem) } method = modem->context->ipv6_method; - if (method == CONNMAN_IPCONFIG_METHOD_FIXED) { - connman_service_create_ip6config(service, index); - connman_network_set_ipv6_method(modem->network, method); - connman_network_set_ipaddress(modem->network, - modem->context->ipv6_address); + connman_service_create_ip6config(service, index); + connman_network_set_ipv6_method(modem->network, method); + + if (method == CONNMAN_IPCONFIG_METHOD_AUTO) { setip = true; } @@ -317,18 +314,32 @@ static void set_connected(struct modem_data *modem) modem->context->ipv6_nameservers); } - if (setip) + if (setip) { + connman_network_set_index(modem->network, index); connman_network_set_connected(modem->network, true); + } } static void set_disconnected(struct modem_data *modem) { DBG("%s", modem->path); - if (!modem->network) - return; + if (modem->network) + connman_network_set_connected(modem->network, false); - connman_network_set_connected(modem->network, false); + if (modem->context) { + g_free(modem->context->ipv4_nameservers); + modem->context->ipv4_nameservers = NULL; + if (modem->context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF) + modem->context->ipv4_method = + CONNMAN_IPCONFIG_METHOD_UNKNOWN; + + g_free(modem->context->ipv6_nameservers); + modem->context->ipv6_nameservers = NULL; + if (modem->context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF) + modem->context->ipv6_method = + CONNMAN_IPCONFIG_METHOD_UNKNOWN; + } } typedef void (*set_property_cb)(struct modem_data *data, @@ -755,6 +766,10 @@ static void extract_ipv4_settings(DBusMessageIter *array, const char *interface = NULL; int index = -1; + connman_ipaddress_free(context->ipv4_address); + context->ipv4_address = NULL; + context->index = -1; + if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) return; @@ -854,6 +869,10 @@ static void extract_ipv6_settings(DBusMessageIter *array, const char *interface = NULL; int index = -1; + connman_ipaddress_free(context->ipv6_address); + context->ipv6_address = NULL; + context->index = -1; + if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) return; @@ -905,7 +924,7 @@ static void extract_ipv6_settings(DBusMessageIter *array, if (index < 0) goto out; - context->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED; + context->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO; context->ipv6_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6); @@ -1065,12 +1084,53 @@ static void remove_network(struct modem_data *modem) modem->network = NULL; } +static int set_context_ipconfig(struct network_context *context, + const char *protocol) +{ + DBG("context %p protocol %s", context, protocol); + + if (!context || !protocol) + return -EINVAL; + + if (g_str_equal(protocol, "ip")) { + if (context->ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) + context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; + + context->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF; + + connman_ipaddress_free(context->ipv6_address); + context->ipv6_address = NULL; + + } else if (g_str_equal(protocol, "ipv6")) { + if (context->ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) + context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; + + context->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF; + + connman_ipaddress_free(context->ipv4_address); + context->ipv4_address = NULL; + + } else if (g_str_equal(protocol, "dual")) { + if (context->ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) + context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; + + if (context->ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) + context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; + } + + DBG("ipv4 method %d ipv6 method %d", context->ipv4_method, + context->ipv6_method); + + return 0; +} + static int add_cm_context(struct modem_data *modem, const char *context_path, DBusMessageIter *dict) { const char *context_type = NULL; struct network_context *context = NULL; dbus_bool_t active = FALSE; + const char *ip_protocol = NULL; DBG("%s context path %s", modem->path, context_path); @@ -1123,7 +1183,14 @@ static int add_cm_context(struct modem_data *modem, const char *context_path, modem->valid_apn = false; DBG("%s AccessPointName '%s'", modem->path, apn); + } else if (g_str_equal(key, "Protocol") && + dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING ) { + + dbus_message_iter_get_basic(&value, &ip_protocol); + + DBG("%s Protocol %s", modem->path, ip_protocol); } + dbus_message_iter_next(dict); } @@ -1132,6 +1199,9 @@ static int add_cm_context(struct modem_data *modem, const char *context_path, return -EINVAL; } + if (ip_protocol) + set_context_ipconfig(context, ip_protocol); + modem->context = context; modem->active = active; @@ -1246,6 +1316,14 @@ static gboolean context_changed(DBusConnection *conn, remove_network(modem); } + + } else if (g_str_equal(key, "Protocol") && + dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING ) { + const char *ip_protocol; + + dbus_message_iter_get_basic(&value, &ip_protocol); + + set_context_ipconfig(modem->context, ip_protocol); } return TRUE; diff --git a/plugins/polkit.policy b/plugins/polkit.policy index 0c2629a3..0de152ce 100644 --- a/plugins/polkit.policy +++ b/plugins/polkit.policy @@ -13,7 +13,7 @@ <message>Policy prevents modification of settings</message> <defaults> <allow_inactive>no</allow_inactive> - <allow_active>auth_self_keep_session</allow_active> + <allow_active>auth_self_keep</allow_active> </defaults> </action> @@ -22,7 +22,7 @@ <message>Policy prevents modification of secrets</message> <defaults> <allow_inactive>no</allow_inactive> - <allow_active>auth_admin_keep_session</allow_active> + <allow_active>auth_admin_keep</allow_active> </defaults> </action> diff --git a/plugins/wifi.c b/plugins/wifi.c index 5f2ebf1c..42dd4074 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -992,7 +992,7 @@ static int get_hidden_connections(GSupplicantScanParams *scan_data) GKeyFile *keyfile; gchar **services; char *ssid, *name; - int i, freq, ret; + int i, ret; bool value; int num_ssids = 0, add_param_failed = 0; @@ -1022,13 +1022,10 @@ static int get_hidden_connections(GSupplicantScanParams *scan_data) ssid = g_key_file_get_string(keyfile, services[i], "SSID", NULL); - freq = g_key_file_get_integer(keyfile, services[i], - "Frequency", NULL); - name = g_key_file_get_string(keyfile, services[i], "Name", NULL); - ret = add_scan_param(ssid, NULL, 0, freq, scan_data, 0, name); + ret = add_scan_param(ssid, NULL, 0, 0, scan_data, 0, name); if (ret < 0) add_param_failed++; else if (ret > 0) @@ -1311,7 +1308,7 @@ static gboolean autoscan_timeout(gpointer data) } else interval = autoscan->interval * autoscan->base; - if (autoscan->interval >= autoscan->limit) + if (interval > autoscan->limit) interval = autoscan->limit; throw_wifi_scan(wifi->device, scan_callback_hidden); @@ -1340,6 +1337,9 @@ static void start_autoscan(struct connman_device *device) if (wifi->p2p_device) return; + if (wifi->connected) + return; + autoscan = wifi->autoscan; if (!autoscan) return; @@ -1396,22 +1396,8 @@ static void setup_autoscan(struct wifi_data *wifi) start_autoscan(wifi->device); } -static void interface_autoscan_callback(int result, - GSupplicantInterface *interface, - void *user_data) -{ - struct wifi_data *wifi = user_data; - - if (result < 0) { - DBG("Could not enable Autoscan, falling back..."); - setup_autoscan(wifi); - } -} - static void finalize_interface_creation(struct wifi_data *wifi) { - GSupplicantInterface *interface = wifi->interface; - DBG("interface is ready wifi %p tethering %d", wifi, wifi->tethering); if (!wifi->device) { @@ -1427,12 +1413,7 @@ static void finalize_interface_creation(struct wifi_data *wifi) if (wifi->p2p_device) return; - /* Setting up automatic scanning */ - if (g_supplicant_interface_autoscan(interface, AUTOSCAN_DEFAULT, - interface_autoscan_callback, wifi) < 0) { - DBG("Could not enable Autoscan, falling back..."); - setup_autoscan(wifi); - } + setup_autoscan(wifi); } static void interface_create_callback(int result, @@ -1839,6 +1820,9 @@ static int wifi_scan(enum connman_service_type type, return 0; } + } else if (wifi->connected) { + g_supplicant_free_scan_params(scan_params); + return wifi_scan_simple(device); } else { ret = get_latest_connections(driver_max_ssids, scan_params); if (ret <= 0) { @@ -2781,9 +2765,8 @@ static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state) p_state = CONNMAN_PEER_STATE_IDLE; break; case G_SUPPLICANT_PEER_GROUP_JOINED: - if (!g_supplicant_peer_is_in_a_group(peer)) - break; - p_state = CONNMAN_PEER_STATE_READY; + connman_peer_set_iface_address(connman_peer, + g_supplicant_peer_get_iface_address(peer)); break; case G_SUPPLICANT_PEER_GROUP_DISCONNECTED: p_state = CONNMAN_PEER_STATE_IDLE; diff --git a/scripts/connman.in b/scripts/connman.in index ec98f391..1692b950 100644 --- a/scripts/connman.in +++ b/scripts/connman.in @@ -1,6 +1,6 @@ #!/bin/sh -DAEMON=@prefix@/sbin/connmand +DAEMON=@sbindir@/connmand DESC="Connection Manager" . /lib/lsb/init-functions diff --git a/src/agent-connman.c b/src/agent-connman.c index b2049a3d..84404510 100644 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -79,8 +79,10 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) int name_len = 0; DBusMessageIter iter, dict; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -160,7 +162,7 @@ done: values_received, name, name_len, identity, passphrase, wps, wpspin, error, passphrase_reply->user_data); -out: + g_free(passphrase_reply); } @@ -365,8 +367,10 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) char *key; DBusMessageIter iter, dict; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -414,7 +418,7 @@ done: username_password_reply->service, values_received, NULL, 0, username, password, FALSE, NULL, error, username_password_reply->user_data); -out: + g_free(username_password_reply); } @@ -582,6 +586,11 @@ static void request_browser_reply(DBusMessage *reply, void *user_data) bool result = false; const char *error = NULL; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); goto done; @@ -674,8 +683,10 @@ static void request_peer_authorization_reply(DBusMessage *reply, char *wpspin = NULL; char *key; - if (!reply) - goto out; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); @@ -716,7 +727,7 @@ static void request_peer_authorization_reply(DBusMessage *reply, done: auth_reply->peer_callback(auth_reply->peer, choice_done, wpspin, error, auth_reply->user_data); -out: + g_free(auth_reply); } diff --git a/src/agent.c b/src/agent.c index a3400262..bdeb0e71 100644 --- a/src/agent.c +++ b/src/agent.c @@ -502,7 +502,7 @@ void connman_agent_cancel(void *user_context) g_hash_table_iter_init(&iter, agent_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { - GList *list; + GList *list, *next; struct connman_agent *agent = value; /* @@ -512,6 +512,8 @@ void connman_agent_cancel(void *user_context) while (list) { struct connman_agent_request *request = list->data; + next = list->next; + if (request && request->user_context && request->user_context == user_context) { @@ -521,10 +523,11 @@ void connman_agent_cancel(void *user_context) agent_request_free(request); - agent->queue = list->next; - list = g_list_delete_link(list, list); - } else - list = list->next; + agent->queue = g_list_delete_link(agent->queue, + list); + } + + list = next; } /* diff --git a/src/config.c b/src/config.c index 93a788a1..a4c117e1 100644 --- a/src/config.c +++ b/src/config.c @@ -891,7 +891,7 @@ static void config_notify_handler(struct inotify_event *event, return; } - if (event->mask & IN_CREATE) + if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) create_config(ident); if (event->mask & IN_MODIFY) { @@ -1435,12 +1435,14 @@ static void generate_random_string(char *str, int length) { uint8_t val; int i; + uint64_t rand; memset(str, '\0', length); for (i = 0; i < length-1; i++) { do { - val = (uint8_t)(random() % 122); + __connman_util_get_random(&rand); + val = (uint8_t)(rand % 122); if (val < 48) val += 48; } while((val > 57 && val < 65) || (val > 90 && val < 97)); diff --git a/src/connection.c b/src/connection.c index 8fe97258..aa4e1c05 100644 --- a/src/connection.c +++ b/src/connection.c @@ -401,13 +401,9 @@ static struct gateway_data *add_gateway(struct connman_service *service, data->ipv4_gateway = old->ipv4_gateway; old->ipv4_gateway = NULL; } - } else { - /* - * Only take a ref if we are adding new stuff to hash. - */ - connman_service_ref(service); } + connman_service_ref(data->service); g_hash_table_replace(gateway_hash, service, data); return data; @@ -708,6 +704,8 @@ static void remove_gateway(gpointer user_data) g_free(data->ipv6_gateway); } + connman_service_unref(data->service); + g_free(data); } @@ -999,9 +997,7 @@ void __connman_connection_gateway_remove(struct connman_service *service, (data->ipv4_gateway && !data->ipv6_gateway && do_ipv4) || (data->ipv6_gateway && !data->ipv4_gateway - && do_ipv6) - ) { - connman_service_unref(service); + && do_ipv6)) { g_hash_table_remove(gateway_hash, service); } else DBG("Not yet removing gw ipv4 %p/%d ipv6 %p/%d", diff --git a/src/connman.h b/src/connman.h index da012152..cbd88d88 100644 --- a/src/connman.h +++ b/src/connman.h @@ -338,7 +338,7 @@ void __connman_ipconfig_newlink(int index, unsigned short type, unsigned short mtu, struct rtnl_link_stats *stats); void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats); -void __connman_ipconfig_newaddr(int index, int family, const char *label, +int __connman_ipconfig_newaddr(int index, int family, const char *label, unsigned char prefixlen, const char *address); void __connman_ipconfig_deladdr(int index, int family, const char *label, unsigned char prefixlen, const char *address); @@ -451,6 +451,7 @@ typedef void (* dhcpv6_cb) (struct connman_network *network, typedef void (* dhcp_cb) (struct connman_ipconfig *ipconfig, struct connman_network *opt_network, bool success, gpointer data); +char *__connman_dhcp_get_server_address(struct connman_ipconfig *ipconfig); int __connman_dhcp_start(struct connman_ipconfig *ipconfig, struct connman_network *network, dhcp_cb callback, gpointer user_data); @@ -586,9 +587,8 @@ int __connman_network_connect(struct connman_network *network); int __connman_network_disconnect(struct connman_network *network); int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig); -int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig_ipv4, - struct connman_ipconfig *ipconfig_ipv6); +int __connman_network_enable_ipconfig(struct connman_network *network, + struct connman_ipconfig *ipconfig); const char *__connman_network_get_type(struct connman_network *network); const char *__connman_network_get_group(struct connman_network *network); @@ -1034,3 +1034,7 @@ void __connman_nfacct_cleanup(void); int __connman_machine_init(void); void __connman_machine_cleanup(void); + +int __connman_util_get_random(uint64_t *val); +int __connman_util_init(void); +void __connman_util_cleanup(void); diff --git a/src/connman.service.in b/src/connman.service.in index 7b6195e9..ba4dedd7 100644 --- a/src/connman.service.in +++ b/src/connman.service.in @@ -2,13 +2,14 @@ Description=Connection service Requires=dbus.socket After=dbus.socket -Before=remote-fs.target +Before=remote-fs-pre.target +Wants=remote-fs-pre.target [Service] Type=dbus BusName=net.connman Restart=on-failure -ExecStart=@prefix@/sbin/connmand -n +ExecStart=@sbindir@/connmand -n StandardOutput=null [Install] diff --git a/src/counter.c b/src/counter.c index 06e5daff..8ea6205b 100644 --- a/src/counter.c +++ b/src/counter.c @@ -133,8 +133,11 @@ void __connman_counter_send_usage(const char *path, struct connman_counter *counter; counter = g_hash_table_lookup(counter_table, path); - if (!counter) + if (!counter) { + if (message) + dbus_message_unref(message); return; + } dbus_message_set_destination(message, counter->owner); dbus_message_set_path(message, counter->path); @@ -582,6 +582,17 @@ static int dhcp_release(struct connman_dhcp *dhcp) return 0; } +char *__connman_dhcp_get_server_address(struct connman_ipconfig *ipconfig) +{ + struct connman_dhcp *dhcp; + + dhcp = g_hash_table_lookup(ipconfig_table, ipconfig); + if (!dhcp) + return NULL; + + return g_dhcp_client_get_server_address(dhcp->dhcp_client); +} + int __connman_dhcp_start(struct connman_ipconfig *ipconfig, struct connman_network *network, dhcp_cb callback, gpointer user_data) @@ -672,4 +683,6 @@ void __connman_dhcp_cleanup(void) g_hash_table_destroy(ipconfig_table); ipconfig_table = NULL; + + dhcp_cleanup_random(); } diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 5f8029f1..bdb3b987 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -105,25 +105,37 @@ static void clear_timer(struct connman_dhcpv6 *dhcp) } } -static inline float get_random(void) +static inline guint get_random(void) { - return (rand() % 200 - 100) / 1000.0; + uint64_t val; + + __connman_util_get_random(&val); + + /* Make sure the value is always positive so strip MSB */ + return ((uint32_t)val) >> 1; +} + +static guint compute_random(guint val) +{ + return val - val / 10 + + (get_random() % (2 * 1000)) * val / 10 / 1000; } /* Calculate a random delay, RFC 3315 chapter 14 */ /* RT and MRT are milliseconds */ static guint calc_delay(guint RT, guint MRT) { - float delay = get_random(); - float rt = RT * (2 + delay); + if (MRT && (RT > MRT / 2)) + RT = compute_random(MRT); + else + RT += compute_random(RT); - if (rt > MRT) - rt = MRT * (1 + delay); - - if (rt < 0) - rt = MRT; + return RT; +} - return (guint)rt; +static guint initial_rt(guint timeout) +{ + return compute_random(timeout); } static void free_prefix(gpointer data) @@ -1095,7 +1107,7 @@ static void re_cb(enum request_type req_type, GDHCPClient *dhcp_client, if (!option) { switch (req_type) { case REQ_REQUEST: - dhcpv6_request(dhcp, true); + do_resend_request(dhcp); break; case REQ_REBIND: dhcpv6_rebind(dhcp); @@ -1220,7 +1232,7 @@ static gboolean start_rebind(gpointer user_data) if (check_restart(dhcp) < 0) return FALSE; - dhcp->RT = REB_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REB_TIMEOUT); DBG("rebind initial RT timeout %d msec", dhcp->RT); @@ -1387,7 +1399,7 @@ static gboolean start_renew(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = REN_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REN_TIMEOUT); DBG("renew initial RT timeout %d msec", dhcp->RT); @@ -1585,7 +1597,7 @@ static gboolean start_info_req(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = INF_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(INF_TIMEOUT); DBG("info initial RT timeout %d msec", dhcp->RT); @@ -1601,6 +1613,7 @@ int __connman_dhcpv6_start_info(struct connman_network *network, { struct connman_dhcpv6 *dhcp; int delay; + uint64_t rand; DBG(""); @@ -1626,7 +1639,8 @@ int __connman_dhcpv6_start_info(struct connman_network *network, g_hash_table_replace(network_table, network, dhcp); /* Initial timeout, RFC 3315, 18.1.5 */ - delay = rand() % 1000; + __connman_util_get_random(&rand); + delay = rand % 1000; dhcp->timeout = g_timeout_add(delay, start_info_req, dhcp); @@ -1650,7 +1664,7 @@ static void advertise_cb(GDHCPClient *dhcp_client, gpointer user_data) return; } - dhcp->RT = REQ_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REQ_TIMEOUT); DBG("request initial RT timeout %d msec", dhcp->RT); dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request, dhcp); @@ -1668,9 +1682,16 @@ static void solicitation_cb(GDHCPClient *dhcp_client, gpointer user_data) clear_timer(dhcp); - do_dad(dhcp_client, dhcp); - g_dhcpv6_client_clear_retransmit(dhcp_client); + + if (g_dhcpv6_client_get_status(dhcp_client) != 0) { + if (dhcp->callback) + dhcp->callback(dhcp->network, + CONNMAN_DHCPV6_STATUS_FAIL, NULL); + return; + } + + do_dad(dhcp_client, dhcp); } static gboolean timeout_solicitation(gpointer user_data) @@ -1761,7 +1782,7 @@ static gboolean start_solicitation(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = SOL_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(SOL_TIMEOUT); DBG("solicit initial RT timeout %d msec", dhcp->RT); @@ -1778,6 +1799,7 @@ int __connman_dhcpv6_start(struct connman_network *network, struct connman_service *service; struct connman_dhcpv6 *dhcp; int delay; + uint64_t rand; DBG(""); @@ -1807,7 +1829,8 @@ int __connman_dhcpv6_start(struct connman_network *network, g_hash_table_replace(network_table, network, dhcp); /* Initial timeout, RFC 3315, 17.1.2 */ - delay = rand() % 1000; + __connman_util_get_random(&rand); + delay = rand % 1000; /* * Start from scratch. @@ -2171,7 +2194,7 @@ static gboolean start_pd_rebind(gpointer user_data) if (check_pd_restart(dhcp) < 0) return FALSE; - dhcp->RT = REB_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REB_TIMEOUT); DBG("rebind initial RT timeout %d msec", dhcp->RT); @@ -2223,7 +2246,7 @@ static gboolean start_pd_rebind_with_confirm(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = CNF_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(CNF_TIMEOUT); DBG("rebind with confirm initial RT timeout %d msec", dhcp->RT); @@ -2260,7 +2283,7 @@ static gboolean start_pd_renew(gpointer user_data) { struct connman_dhcpv6 *dhcp = user_data; - dhcp->RT = REN_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REN_TIMEOUT); DBG("renew initial RT timeout %d msec", dhcp->RT); @@ -2476,7 +2499,7 @@ static void advertise_pd_cb(GDHCPClient *dhcp_client, gpointer user_data) return; } - dhcp->RT = REQ_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(REQ_TIMEOUT); DBG("request initial RT timeout %d msec", dhcp->RT); dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_request, dhcp); @@ -2531,7 +2554,7 @@ static gboolean start_pd_solicitation(gpointer user_data) struct connman_dhcpv6 *dhcp = user_data; /* Set the retransmission timeout, RFC 3315 chapter 14 */ - dhcp->RT = SOL_TIMEOUT * (1 + get_random()); + dhcp->RT = initial_rt(SOL_TIMEOUT); DBG("solicit initial RT timeout %d msec", dhcp->RT); @@ -2640,8 +2663,6 @@ int __connman_dhcpv6_init(void) { DBG(""); - srand(time(NULL)); - network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, remove_network); diff --git a/src/dnsproxy.c b/src/dnsproxy.c index bdd7fd5c..cf3490c4 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -215,10 +215,15 @@ static GSList *request_list = NULL; static GHashTable *listener_table = NULL; static time_t next_refresh; static GHashTable *partial_tcp_req_table; +static guint cache_timer = 0; static guint16 get_id(void) { - return random(); + uint64_t rand; + + __connman_util_get_random(&rand); + + return rand; } static int protocol_offset(int protocol) @@ -526,6 +531,8 @@ static void destroy_request_data(struct request_data *req) static gboolean request_timeout(gpointer user_data) { struct request_data *req = user_data; + struct sockaddr *sa; + int sk; if (!req) return FALSE; @@ -533,47 +540,38 @@ static gboolean request_timeout(gpointer user_data) DBG("id 0x%04x", req->srcid); request_list = g_slist_remove(request_list, req); - req->numserv--; - if (req->resplen > 0 && req->resp) { - int sk, err; + if (req->protocol == IPPROTO_UDP) { + sk = get_req_udp_socket(req); + sa = &req->sa; + } else if (req->protocol == IPPROTO_TCP) { + sk = req->client_sk; + sa = NULL; + } else + goto out; - if (req->protocol == IPPROTO_UDP) { - sk = get_req_udp_socket(req); - if (sk < 0) - return FALSE; + if (req->resplen > 0 && req->resp) { + /* + * Here we have received at least one reply (probably telling + * "not found" result), so send that back to client instead + * of more fatal server failed error. + */ + if (sk >= 0) + sendto(sk, req->resp, req->resplen, MSG_NOSIGNAL, + sa, req->sa_len); - err = sendto(sk, req->resp, req->resplen, MSG_NOSIGNAL, - &req->sa, req->sa_len); - } else { - sk = req->client_sk; - err = send(sk, req->resp, req->resplen, MSG_NOSIGNAL); - if (err < 0) - close(sk); - } - if (err < 0) - return FALSE; - } else if (req->request && req->numserv == 0) { + } else if (req->request) { + /* + * There was not reply from server at all. + */ struct domain_hdr *hdr; - if (req->protocol == IPPROTO_TCP) { - hdr = (void *) (req->request + 2); - hdr->id = req->srcid; - send_response(req->client_sk, req->request, - req->request_len, NULL, 0, IPPROTO_TCP); - - } else if (req->protocol == IPPROTO_UDP) { - int sk; + hdr = (void *)(req->request + protocol_offset(req->protocol)); + hdr->id = req->srcid; - hdr = (void *) (req->request); - hdr->id = req->srcid; - - sk = get_req_udp_socket(req); - if (sk >= 0) - send_response(sk, req->request, - req->request_len, &req->sa, - req->sa_len, IPPROTO_UDP); - } + if (sk >= 0) + send_response(sk, req->request, req->request_len, + sa, req->sa_len, req->protocol); } /* @@ -586,6 +584,7 @@ static gboolean request_timeout(gpointer user_data) GINT_TO_POINTER(req->client_sk)); } +out: req->timeout = 0; destroy_request_data(req); @@ -764,6 +763,8 @@ static void cache_element_destroy(gpointer value) static gboolean try_remove_cache(gpointer user_data) { + cache_timer = 0; + if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) { DBG("No cache users, removing it."); @@ -2204,8 +2205,8 @@ static void destroy_server(struct server_data *server) * without any good reason. The small delay allows the new RDNSS to * create a new DNS server instance and the refcount does not go to 0. */ - if (cache) - g_timeout_add_seconds(3, try_remove_cache, NULL); + if (cache && !cache_timer) + cache_timer = g_timeout_add_seconds(3, try_remove_cache, NULL); g_free(server); } @@ -3460,6 +3461,9 @@ static bool udp_listener_event(GIOChannel *channel, GIOCondition condition, return true; } + req->name = g_strdup(query); + req->request = g_malloc(len); + memcpy(req->request, buf, len); req->timeout = g_timeout_add_seconds(5, request_timeout, req); request_list = g_slist_append(request_list, req); @@ -3829,8 +3833,6 @@ int __connman_dnsproxy_init(void) DBG(""); - srandom(time(NULL)); - listener_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); @@ -3862,6 +3864,16 @@ void __connman_dnsproxy_cleanup(void) { DBG(""); + if (cache_timer) { + g_source_remove(cache_timer); + cache_timer = 0; + } + + if (cache) { + g_hash_table_destroy(cache); + cache = NULL; + } + connman_notifier_unregister(&dnsproxy_notifier); g_hash_table_foreach(listener_table, remove_listener, NULL); diff --git a/src/inotify.c b/src/inotify.c index 1ab3807c..c251c6ff 100644 --- a/src/inotify.c +++ b/src/inotify.c @@ -35,6 +35,8 @@ #include "connman.h" struct connman_inotify { + unsigned int refcount; + GIOChannel *channel; uint watch; int wd; @@ -42,13 +44,30 @@ struct connman_inotify { GSList *list; }; +static void cleanup_inotify(gpointer user_data); + +static void connman_inotify_ref(struct connman_inotify *i) +{ + __sync_fetch_and_add(&i->refcount, 1); +} + +static void connman_inotify_unref(gpointer data) +{ + struct connman_inotify *i = data; + + if (__sync_fetch_and_sub(&i->refcount, 1) != 1) + return; + + cleanup_inotify(data); +} + static GHashTable *inotify_hash; static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, gpointer user_data) { struct connman_inotify *inotify = user_data; - char buffer[256]; + char buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; char *next_event; gsize bytes_read; GIOStatus status; @@ -60,7 +79,7 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, } status = g_io_channel_read_chars(channel, buffer, - sizeof(buffer) -1, &bytes_read, NULL); + sizeof(buffer), &bytes_read, NULL); switch (status) { case G_IO_STATUS_NORMAL: @@ -75,6 +94,8 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, next_event = buffer; + connman_inotify_ref(inotify); + while (bytes_read > 0) { struct inotify_event *event; gchar *ident; @@ -102,6 +123,8 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, } } + connman_inotify_unref(inotify); + return TRUE; } @@ -179,6 +202,7 @@ int connman_inotify_register(const char *path, inotify_event_cb callback) if (!inotify) return -ENOMEM; + inotify->refcount = 1; inotify->wd = -1; err = create_watch(path, inotify); @@ -225,7 +249,7 @@ int __connman_inotify_init(void) DBG(""); inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, cleanup_inotify); + g_free, connman_inotify_unref); return 0; } diff --git a/src/ipconfig.c b/src/ipconfig.c index ae70745f..f8c148be 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -45,8 +45,6 @@ struct connman_ipconfig { int index; enum connman_ipconfig_type type; - struct connman_ipconfig *origin; - const struct connman_ipconfig_ops *ops; void *ops_data; @@ -135,6 +133,7 @@ const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type) { switch (type) { case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: return "unknown"; case CONNMAN_IPCONFIG_TYPE_IPV4: return "IPv4"; @@ -445,12 +444,9 @@ static void update_stats(struct connman_ipdevice *ipdevice, if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6) return; - if (ipdevice->config_ipv4) - service = __connman_ipconfig_get_data(ipdevice->config_ipv4); - else if (ipdevice->config_ipv6) - service = __connman_ipconfig_get_data(ipdevice->config_ipv6); - else - return; + service = __connman_service_lookup_from_index(ipdevice->index); + + DBG("service %p", service); if (!service) return; @@ -642,7 +638,7 @@ static inline gint check_duplicate_address(gconstpointer a, gconstpointer b) return g_strcmp0(addr1->local, addr2->local); } -void __connman_ipconfig_newaddr(int index, int family, const char *label, +int __connman_ipconfig_newaddr(int index, int family, const char *label, unsigned char prefixlen, const char *address) { struct connman_ipdevice *ipdevice; @@ -655,11 +651,11 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index)); if (!ipdevice) - return; + return -ENXIO; ipaddress = connman_ipaddress_alloc(family); if (!ipaddress) - return; + return -ENOMEM; ipaddress->prefixlen = prefixlen; ipaddress->local = g_strdup(address); @@ -667,7 +663,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, if (g_slist_find_custom(ipdevice->address_list, ipaddress, check_duplicate_address)) { connman_ipaddress_free(ipaddress); - return; + return -EALREADY; } if (family == AF_INET) @@ -675,7 +671,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, else if (family == AF_INET6) type = CONNMAN_IPCONFIG_TYPE_IPV6; else - return; + return -EINVAL; ipdevice->address_list = g_slist_prepend(ipdevice->address_list, ipaddress); @@ -698,7 +694,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, goto out; if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP)) - return; + goto out; for (list = g_list_first(ipconfig_list); list; list = g_list_next(list)) { @@ -719,6 +715,7 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, out: g_free(ifname); + return 0; } void __connman_ipconfig_deladdr(int index, int family, const char *label, @@ -1253,11 +1250,6 @@ void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig, __connman_ipconfig_set_ops(ipconfig, NULL); - if (ipconfig->origin && ipconfig->origin != ipconfig) { - __connman_ipconfig_unref(ipconfig->origin); - ipconfig->origin = NULL; - } - connman_ipaddress_free(ipconfig->system); connman_ipaddress_free(ipconfig->address); g_free(ipconfig->last_dhcp_address); @@ -1302,9 +1294,6 @@ int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig) if (!ipconfig) return -1; - if (ipconfig->origin) - return ipconfig->origin->index; - return ipconfig->index; } @@ -2128,6 +2117,7 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig, type = AF_INET6; break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: type = -1; break; } @@ -2217,6 +2207,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO; break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF; break; } @@ -2256,42 +2247,59 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, g_free(method); g_free(key); - key = g_strdup_printf("%snetmask_prefixlen", prefix); - ipconfig->address->prefixlen = g_key_file_get_integer( + switch (ipconfig->method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + break; + + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + + key = g_strdup_printf("%snetmask_prefixlen", prefix); + ipconfig->address->prefixlen = g_key_file_get_integer( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%slocal_address", prefix); - g_free(ipconfig->address->local); - ipconfig->address->local = g_key_file_get_string( + key = g_strdup_printf("%slocal_address", prefix); + g_free(ipconfig->address->local); + ipconfig->address->local = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%speer_address", prefix); - g_free(ipconfig->address->peer); - ipconfig->address->peer = g_key_file_get_string( + key = g_strdup_printf("%speer_address", prefix); + g_free(ipconfig->address->peer); + ipconfig->address->peer = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%sbroadcast_address", prefix); - g_free(ipconfig->address->broadcast); - ipconfig->address->broadcast = g_key_file_get_string( + key = g_strdup_printf("%sbroadcast_address", prefix); + g_free(ipconfig->address->broadcast); + ipconfig->address->broadcast = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); - key = g_strdup_printf("%sgateway", prefix); - g_free(ipconfig->address->gateway); - ipconfig->address->gateway = g_key_file_get_string( + key = g_strdup_printf("%sgateway", prefix); + g_free(ipconfig->address->gateway); + ipconfig->address->gateway = g_key_file_get_string( keyfile, identifier, key, NULL); - g_free(key); + g_free(key); + break; + + case CONNMAN_IPCONFIG_METHOD_DHCP: + + key = g_strdup_printf("%sDHCP.LastAddress", prefix); + str = g_key_file_get_string(keyfile, identifier, key, NULL); + if (str) { + g_free(ipconfig->last_dhcp_address); + ipconfig->last_dhcp_address = str; + } + g_free(key); + + break; - key = g_strdup_printf("%sDHCP.LastAddress", prefix); - str = g_key_file_get_string(keyfile, identifier, key, NULL); - if (str) { - g_free(ipconfig->last_dhcp_address); - ipconfig->last_dhcp_address = str; + case CONNMAN_IPCONFIG_METHOD_AUTO: + break; } - g_free(key); return 0; } diff --git a/src/ipv6pd.c b/src/ipv6pd.c index 5ecda389..0d221f07 100644 --- a/src/ipv6pd.c +++ b/src/ipv6pd.c @@ -165,8 +165,10 @@ static void cleanup(void) timer_uplink = 0; } - g_hash_table_destroy(timer_hash); - timer_hash = NULL; + if (timer_hash) { + g_hash_table_destroy(timer_hash); + timer_hash = NULL; + } if (prefixes) { g_slist_free_full(prefixes, g_free); @@ -639,6 +639,7 @@ int main(int argc, char *argv[]) else config_init(option_config); + __connman_util_init(); __connman_inotify_init(); __connman_technology_init(); __connman_notifier_init(); @@ -729,6 +730,7 @@ int main(int argc, char *argv[]) __connman_technology_cleanup(); __connman_inotify_cleanup(); + __connman_util_cleanup(); __connman_dbus_cleanup(); __connman_log_cleanup(option_backtrace); @@ -747,6 +749,7 @@ int main(int argc, char *argv[]) g_strfreev(connman_settings.tethering_technologies); g_free(option_debug); + g_free(option_wifi); return 0; } diff --git a/src/net.connman.service.in b/src/net.connman.service.in index e76969bc..f7f6a7c0 100644 --- a/src/net.connman.service.in +++ b/src/net.connman.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=net.connman -Exec=@prefix@/sbin/connmand -n +Exec=@sbindir@/connmand -n User=root SystemdService=connman.service diff --git a/src/network.c b/src/network.c index b388995f..badb7702 100644 --- a/src/network.c +++ b/src/network.c @@ -153,10 +153,6 @@ static void dhcp_success(struct connman_network *network) if (!service) goto err; - connman_network_set_associating(network, false); - - network->connecting = false; - ipconfig_ipv4 = __connman_service_get_ip4config(service); DBG("lease acquired for ipconfig %p", ipconfig_ipv4); @@ -188,9 +184,6 @@ static void dhcp_failure(struct connman_network *network) if (!service) return; - connman_network_set_associating(network, false); - network->connecting = false; - ipconfig_ipv4 = __connman_service_get_ip4config(service); DBG("lease lost for ipconfig %p", ipconfig_ipv4); @@ -206,55 +199,24 @@ static void dhcp_callback(struct connman_ipconfig *ipconfig, struct connman_network *network, bool success, gpointer data) { + network->connecting = false; + if (success) dhcp_success(network); else dhcp_failure(network); } -static int set_connected_fixed(struct connman_network *network) -{ - struct connman_service *service; - struct connman_ipconfig *ipconfig_ipv4; - int err; - - DBG(""); - - service = connman_service_lookup_from_network(network); - - ipconfig_ipv4 = __connman_service_get_ip4config(service); - - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - - network->connecting = false; - - connman_network_set_associating(network, false); - - err = __connman_ipconfig_address_add(ipconfig_ipv4); - if (err < 0) - goto err; - - err = __connman_ipconfig_gateway_add(ipconfig_ipv4); - if (err < 0) - goto err; - - return 0; - -err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - - return err; -} - -static void set_connected_manual(struct connman_network *network) +static int set_connected_manual(struct connman_network *network) { + int err = 0; struct connman_service *service; struct connman_ipconfig *ipconfig; - int err; DBG("network %p", network); + network->connecting = false; + service = connman_service_lookup_from_network(network); ipconfig = __connman_service_get_ip4config(service); @@ -262,8 +224,6 @@ static void set_connected_manual(struct connman_network *network) if (!__connman_ipconfig_get_local(ipconfig)) __connman_service_read_ip4config(service); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - err = __connman_ipconfig_address_add(ipconfig); if (err < 0) goto err; @@ -272,16 +232,8 @@ static void set_connected_manual(struct connman_network *network) if (err < 0) goto err; - network->connecting = false; - - connman_network_set_associating(network, false); - - return; - err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return; + return err; } static int set_connected_dhcp(struct connman_network *network) @@ -292,8 +244,6 @@ static int set_connected_dhcp(struct connman_network *network) DBG("network %p", network); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - service = connman_service_lookup_from_network(network); ipconfig_ipv4 = __connman_service_get_ip4config(service); @@ -342,6 +292,8 @@ static int manual_ipv6_set(struct connman_network *network, connman_device_set_disconnected(network->device, false); + connman_network_set_associating(network, false); + network->connecting = false; return 0; @@ -349,6 +301,8 @@ static int manual_ipv6_set(struct connman_network *network, static void stop_dhcpv6(struct connman_network *network) { + network->connecting = false; + __connman_dhcpv6_stop(network); } @@ -386,8 +340,6 @@ static int dhcpv6_set_addresses(struct connman_network *network) if (!service) goto err; - connman_network_set_associating(network, false); - network->connecting = false; ipconfig_ipv6 = __connman_service_get_ip6config(service); @@ -395,10 +347,6 @@ static int dhcpv6_set_addresses(struct connman_network *network) if (err < 0) goto err; - err = __connman_ipconfig_gateway_add(ipconfig_ipv6); - if (err < 0) - goto err; - return 0; err: @@ -511,6 +459,8 @@ static void check_dhcpv6(struct nd_router_advert *reply, if (service) { connman_service_create_ip6config(service, network->index); + connman_network_set_associating(network, false); + __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION, CONNMAN_IPCONFIG_TYPE_IPV6); @@ -519,10 +469,16 @@ static void check_dhcpv6(struct nd_router_advert *reply, /* * We do stateful/stateless DHCPv6 if router advertisement says so. */ - if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) + if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) { __connman_dhcpv6_start(network, prefixes, dhcpv6_callback); - else if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) - __connman_dhcpv6_start_info(network, dhcpv6_info_callback); + } else { + if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) + __connman_dhcpv6_start_info(network, + dhcpv6_info_callback); + + g_slist_free_full(prefixes, g_free); + network->connecting = false; + } connman_network_unref(network); } @@ -602,8 +558,6 @@ static void autoconf_ipv6_set(struct connman_network *network) connman_device_set_disconnected(network->device, false); - network->connecting = false; - service = connman_service_lookup_from_network(network); if (!service) return; @@ -612,6 +566,8 @@ static void autoconf_ipv6_set(struct connman_network *network) if (!ipconfig) return; + __connman_ipconfig_enable_ipv6(ipconfig); + __connman_ipconfig_address_remove(ipconfig); index = __connman_ipconfig_get_index(ipconfig); @@ -626,13 +582,13 @@ static void autoconf_ipv6_set(struct connman_network *network) static void set_connected(struct connman_network *network) { struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; - enum connman_ipconfig_method ipv4_method, ipv6_method; struct connman_service *service; - int ret; if (network->connected) return; + connman_network_set_associating(network, false); + network->connected = true; service = connman_service_lookup_from_network(network); @@ -643,56 +599,8 @@ static void set_connected(struct connman_network *network) DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4, ipconfig_ipv6); - ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); - ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); - - DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method); - - switch (ipv6_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - break; - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: - autoconf_ipv6_set(network); - break; - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - break; - } - - switch (ipv4_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_AUTO: - return; - case CONNMAN_IPCONFIG_METHOD_FIXED: - if (set_connected_fixed(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - return; - case CONNMAN_IPCONFIG_METHOD_MANUAL: - set_connected_manual(network); - return; - case CONNMAN_IPCONFIG_METHOD_DHCP: - if (set_connected_dhcp(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - } - - network->connecting = false; - - connman_network_set_associating(network, false); + __connman_network_enable_ipconfig(network, ipconfig_ipv4); + __connman_network_enable_ipconfig(network, ipconfig_ipv6); } static void set_disconnected(struct connman_network *network) @@ -1139,14 +1047,21 @@ void connman_network_set_index(struct connman_network *network, int index) goto done; ipconfig = __connman_service_get_ip4config(service); - if (!ipconfig) - goto done; + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); + + DBG("index %d service %p ip4config %p", network->index, + service, ipconfig); + } + + ipconfig = __connman_service_get_ip6config(service); + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); - /* If index changed, the index of ipconfig must be reset. */ - __connman_ipconfig_set_index(ipconfig, index); + DBG("index %d service %p ip6config %p", network->index, + service, ipconfig); + } - DBG("index %d service %p ip4config %p", network->index, - service, ipconfig); done: network->index = index; } @@ -1594,26 +1509,6 @@ int __connman_network_disconnect(struct connman_network *network) return err; } -static int manual_ipv4_set(struct connman_network *network, - struct connman_ipconfig *ipconfig) -{ - struct connman_service *service; - int err; - - service = connman_service_lookup_from_network(network); - if (!service) - return -EINVAL; - - err = __connman_ipconfig_address_add(ipconfig); - if (err < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return err; - } - - return __connman_ipconfig_gateway_add(ipconfig); -} - int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { @@ -1658,58 +1553,88 @@ int __connman_network_clear_ipconfig(struct connman_network *network, return 0; } -int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig_ipv4, - struct connman_ipconfig *ipconfig_ipv6) +int __connman_network_enable_ipconfig(struct connman_network *network, + struct connman_ipconfig *ipconfig) { + int r = 0; + enum connman_ipconfig_type type; enum connman_ipconfig_method method; - int ret; - if (!network) + if (!network || !ipconfig) return -EINVAL; - if (ipconfig_ipv6) { - method = __connman_ipconfig_get_method(ipconfig_ipv6); + type = __connman_ipconfig_get_config_type(ipconfig); + + switch (type) { + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: + return -ENOSYS; + + case CONNMAN_IPCONFIG_TYPE_IPV6: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv6 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + break; + case CONNMAN_IPCONFIG_METHOD_OFF: + __connman_ipconfig_disable_ipv6(ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_AUTO: autoconf_ipv6_set(network); break; + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return ret; - } + r = manual_ipv6_set(network, ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + r = -ENOSYS; break; } - } - if (ipconfig_ipv4) { - method = __connman_ipconfig_get_method(ipconfig_ipv4); + break; + + case CONNMAN_IPCONFIG_TYPE_IPV4: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv4 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: + break; + case CONNMAN_IPCONFIG_METHOD_AUTO: - return -EINVAL; + r = -ENOSYS; + break; + + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - return manual_ipv4_set(network, ipconfig_ipv4); + r = set_connected_manual(network); + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: - return __connman_dhcp_start(ipconfig_ipv4, - network, dhcp_callback, NULL); + r = set_connected_dhcp(network); + break; } + + break; } - return 0; + if (r < 0) + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + + return r; } int connman_network_set_ipaddress(struct connman_network *network, @@ -208,6 +208,8 @@ static void send_packet(int fd, const char *server, uint32_t timeout) static gboolean next_poll(gpointer user_data) { + poll_id = 0; + if (!timeserver || transmit_fd == 0) return FALSE; @@ -27,6 +27,7 @@ #include <ctype.h> #include <gdbus.h> #include <gdhcp/gdhcp.h> +#include <netinet/if_ether.h> #include <connman/agent.h> @@ -54,6 +55,7 @@ struct connman_peer { int refcount; struct connman_device *device; struct connman_device *sub_device; + unsigned char *iface_address[ETH_ALEN]; char *identifier; char *name; char *path; @@ -64,9 +66,12 @@ struct connman_peer { bool connection_master; struct connman_ippool *ip_pool; GDHCPServer *dhcp_server; + uint32_t lease_ip; GSList *services; }; +static void settings_changed(struct connman_peer *peer); + static void stop_dhcp_server(struct connman_peer *peer) { DBG(""); @@ -79,6 +84,7 @@ static void stop_dhcp_server(struct connman_peer *peer) if (peer->ip_pool) __connman_ippool_unref(peer->ip_pool); peer->ip_pool = NULL; + peer->lease_ip = 0; } static void dhcp_server_debug(const char *str, void *data) @@ -86,6 +92,24 @@ static void dhcp_server_debug(const char *str, void *data) connman_info("%s: %s\n", (const char *) data, str); } +static void lease_added(unsigned char *mac, uint32_t ip) +{ + GList *list, *start; + + start = list = g_hash_table_get_values(peers_table); + for (; list; list = list->next) { + struct connman_peer *temp = list->data; + + if (!memcmp(temp->iface_address, mac, ETH_ALEN)) { + temp->lease_ip = ip; + settings_changed(temp); + break; + } + } + + g_list_free(start); +} + static gboolean dhcp_server_started(gpointer data) { struct connman_peer *peer = data; @@ -146,6 +170,8 @@ static int start_dhcp_server(struct connman_peer *peer) g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_DNS_SERVER, NULL); g_dhcp_server_set_ip_range(peer->dhcp_server, start_ip, end_ip); + g_dhcp_server_set_lease_added_cb(peer->dhcp_server, lease_added); + err = g_dhcp_server_start(peer->dhcp_server); if (err < 0) goto error; @@ -253,39 +279,43 @@ static bool allow_property_changed(struct connman_peer *peer) return true; } -static void append_dhcp_server_ipv4(DBusMessageIter *iter, void *user_data) +static void append_ipv4(DBusMessageIter *iter, void *user_data) { struct connman_peer *peer = user_data; - const char *str = "dhcp"; - const char *gateway; - const char *subnet; + char trans[INET_ADDRSTRLEN+1] = {}; + const char *local = ""; + const char *remote = ""; + char *dhcp = NULL; - if (!peer->ip_pool) + if (!is_connected(peer)) return; - gateway = __connman_ippool_get_gateway(peer->ip_pool); - subnet = __connman_ippool_get_subnet_mask(peer->ip_pool); + if (peer->connection_master) { + struct in_addr addr; - connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str); - connman_dbus_dict_append_basic(iter, "Address", - DBUS_TYPE_STRING, &gateway); - connman_dbus_dict_append_basic(iter, "Netmask", - DBUS_TYPE_STRING, &subnet); - connman_dbus_dict_append_basic(iter, "Gateway", - DBUS_TYPE_STRING, &gateway); -} + addr.s_addr = peer->lease_ip; + inet_ntop(AF_INET, &addr, trans, INET_ADDRSTRLEN); -static void append_ipv4(DBusMessageIter *iter, void *user_data) -{ - struct connman_peer *peer = user_data; + local = __connman_ippool_get_gateway(peer->ip_pool); + remote = trans; + } else if (peer->ipconfig) { + local = __connman_ipconfig_get_local(peer->ipconfig); - if (!is_connected(peer)) - return; + remote = __connman_ipconfig_get_gateway(peer->ipconfig); + if (!remote) { + remote = dhcp = __connman_dhcp_get_server_address( + peer->ipconfig); + if (!dhcp) + remote = ""; + } + } - if (peer->connection_master) - append_dhcp_server_ipv4(iter, peer); - else if (peer->ipconfig) - __connman_ipconfig_append_ipv4(peer->ipconfig, iter); + connman_dbus_dict_append_basic(iter, "Local", + DBUS_TYPE_STRING, &local); + connman_dbus_dict_append_basic(iter, "Remote", + DBUS_TYPE_STRING, &remote); + if (dhcp) + g_free(dhcp); } static void append_peer_service(DBusMessageIter *iter, @@ -725,6 +755,13 @@ void connman_peer_set_name(struct connman_peer *peer, const char *name) peer->name = g_strdup(name); } +void connman_peer_set_iface_address(struct connman_peer *peer, + const unsigned char *iface_address) +{ + memset(peer->iface_address, 0, ETH_ALEN); + memcpy(peer->iface_address, iface_address, ETH_ALEN); +} + void connman_peer_set_device(struct connman_peer *peer, struct connman_device *device) { @@ -885,6 +922,10 @@ int connman_peer_set_state(struct connman_peer *peer, peer->state = new_state; state_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY || + peer->state == CONNMAN_PEER_STATE_DISCONNECT) + settings_changed(peer); + return 0; } @@ -976,7 +1017,8 @@ static void peer_ip_bound(struct connman_ipconfig *ipconfig, DBG("%s ip bound", ifname); - settings_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY) + settings_changed(peer); connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY); } @@ -987,7 +1029,8 @@ static void peer_ip_release(struct connman_ipconfig *ipconfig, DBG("%s ip release", ifname); - settings_changed(peer); + if (peer->state == CONNMAN_PEER_STATE_READY) + settings_changed(peer); } static const struct connman_ipconfig_ops peer_ip_ops = { @@ -1151,6 +1194,10 @@ void __connman_peer_cleanup(void) { DBG(""); + g_hash_table_destroy(peers_notify->remove); + g_hash_table_destroy(peers_notify->add); + g_free(peers_notify); + g_hash_table_destroy(peers_table); peers_table = NULL; dbus_connection_unref(connection); diff --git a/src/proxy.c b/src/proxy.c index 0d1a25ab..f331de92 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -44,6 +44,9 @@ struct proxy_lookup { static void remove_lookup(struct proxy_lookup *lookup) { + if (lookup->watch > 0) + g_source_remove(lookup->watch); + lookup_list = g_slist_remove(lookup_list, lookup); connman_service_unref(lookup->service); @@ -150,11 +153,6 @@ void connman_proxy_lookup_cancel(unsigned int token) } if (lookup) { - if (lookup->watch > 0) { - g_source_remove(lookup->watch); - lookup->watch = 0; - } - if (lookup->proxy && lookup->proxy->cancel_lookup) lookup->proxy->cancel_lookup(lookup->service, diff --git a/src/resolver.c b/src/resolver.c index 01e7c0e0..652f4fd9 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -608,14 +608,6 @@ int __connman_resolver_redo_servers(int index) */ __connman_dnsproxy_remove(entry->index, entry->domain, entry->server); - /* - * Remove also the resolver timer for the old server entry. - * A new timer will be set for the new server entry - * when the next Router Advertisement message arrives - * with RDNSS/DNSSL settings. - */ - g_source_remove(entry->timeout); - entry->timeout = 0; __connman_dnsproxy_append(entry->index, entry->domain, entry->server); diff --git a/src/rfkill.c b/src/rfkill.c index 960cfea7..2bfb0928 100644 --- a/src/rfkill.c +++ b/src/rfkill.c @@ -153,14 +153,14 @@ static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; } -static GIOChannel *channel = NULL; +static guint watch = 0; int __connman_rfkill_block(enum connman_service_type type, bool block) { uint8_t rfkill_type; struct rfkill_event event; ssize_t len; - int fd, err; + int fd, err = 0; DBG("type %d block %d", type, block); @@ -170,7 +170,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) fd = open("/dev/rfkill", O_RDWR | O_CLOEXEC); if (fd < 0) - return fd; + return -errno; memset(&event, 0, sizeof(event)); event.op = RFKILL_OP_CHANGE_ALL; @@ -179,10 +179,9 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) len = write(fd, &event, sizeof(event)); if (len < 0) { + err = -errno; connman_error("Failed to change RFKILL state"); - err = len; - } else - err = 0; + } close(fd); @@ -191,6 +190,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) int __connman_rfkill_init(void) { + GIOChannel *channel; GIOFlags flags; int fd; @@ -215,21 +215,21 @@ int __connman_rfkill_init(void) /* Process current RFKILL events sent on device open */ while (rfkill_process(channel) == G_IO_STATUS_NORMAL); - g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, - rfkill_event, NULL); + watch = g_io_add_watch(channel, + G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + rfkill_event, NULL); + + g_io_channel_unref(channel); - return 0; + return watch ? 0 : -EIO; } void __connman_rfkill_cleanup(void) { DBG(""); - if (!channel) - return; - - g_io_channel_shutdown(channel, TRUE, NULL); - g_io_channel_unref(channel); - - channel = NULL; + if (watch) { + g_source_remove(watch); + watch = 0; + } } @@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface) } else if (strcmp(line + 8, "gadget") == 0) { interface->service_type = CONNMAN_SERVICE_TYPE_GADGET; interface->device_type = CONNMAN_DEVICE_TYPE_GADGET; + } else if (strcmp(line + 8, "vlan") == 0) { + interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET; + interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET; } else { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; @@ -612,17 +615,18 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen, if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN)) return; - __connman_ipconfig_newaddr(index, family, label, - prefixlen, ip_string); - - if (family == AF_INET6) { - /* - * Re-create RDNSS configured servers if there are any - * for this interface. This is done because we might - * have now properly configured interface with proper - * autoconfigured address. - */ - __connman_resolver_redo_servers(index); + if (__connman_ipconfig_newaddr(index, family, label, + prefixlen, ip_string) >= 0) { + if (family == AF_INET6) { + /* + * Re-create RDNSS configured servers if there + * are any for this interface. This is done + * because we might have now properly + * configured interface with proper + * autoconfigured address. + */ + __connman_resolver_redo_servers(index); + } } } @@ -1083,6 +1087,8 @@ static void rtnl_route(struct nlmsghdr *hdr) static bool is_route_rtmsg(struct rtmsg *msg) { + if (msg->rtm_flags & RTM_F_CLONED) + return false; if (msg->rtm_table != RT_TABLE_MAIN) return false; @@ -1291,6 +1297,7 @@ static const char *type2string(uint16_t type) } static GIOChannel *channel = NULL; +static guint channel_watch = 0; struct rtnl_request { struct nlmsghdr hdr; @@ -1621,8 +1628,9 @@ int __connman_rtnl_init(void) g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, FALSE); - g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, - netlink_event, NULL); + channel_watch = g_io_add_watch(channel, + G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + netlink_event, NULL); return 0; } @@ -1672,6 +1680,11 @@ void __connman_rtnl_cleanup(void) g_slist_free(request_list); request_list = NULL; + if (channel_watch) { + g_source_remove(channel_watch); + channel_watch = 0; + } + g_io_channel_shutdown(channel, TRUE, NULL); g_io_channel_unref(channel); diff --git a/src/service.c b/src/service.c index 87a2f2cd..29a632e1 100644 --- a/src/service.c +++ b/src/service.c @@ -1227,14 +1227,18 @@ static void add_nameserver_route(int family, int index, char *nameserver, static void nameserver_add_routes(int index, char **nameservers, const char *gw) { - int i, family; + int i, ns_family, gw_family; + + gw_family = connman_inet_check_ipaddress(gw); + if (gw_family < 0) + return; for (i = 0; nameservers[i]; i++) { - family = connman_inet_check_ipaddress(nameservers[i]); - if (family < 0) + ns_family = connman_inet_check_ipaddress(nameservers[i]); + if (ns_family < 0 || ns_family != gw_family) continue; - add_nameserver_route(family, index, nameservers[i], gw); + add_nameserver_route(ns_family, index, nameservers[i], gw); } } @@ -2870,7 +2874,6 @@ int __connman_service_set_passphrase(struct connman_service *service, if (service->network) connman_network_set_string(service->network, "WiFi.Passphrase", service->passphrase); - service_save(service); return 0; } @@ -2883,16 +2886,6 @@ const char *__connman_service_get_passphrase(struct connman_service *service) return service->passphrase; } -static void clear_passphrase(struct connman_service *service) -{ - g_free(service->passphrase); - service->passphrase = NULL; - - if (service->network) - connman_network_set_string(service->network, "WiFi.Passphrase", - service->passphrase); -} - static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -3413,10 +3406,13 @@ static DBusMessage *set_property(DBusConnection *conn, if (err < 0) { if (is_connected_state(service, state) || - is_connecting_state(service, state)) - __connman_network_set_ipconfig(service->network, - service->ipconfig_ipv4, - service->ipconfig_ipv6); + is_connecting_state(service, state)) { + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv4); + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv6); + } + return __connman_error_failed(msg, -err); } @@ -3425,10 +3421,12 @@ static DBusMessage *set_property(DBusConnection *conn, else ipv6_configuration_changed(service); - if (is_connecting(service) || is_connected(service)) - __connman_network_set_ipconfig(service->network, - service->ipconfig_ipv4, - service->ipconfig_ipv6); + if (is_connecting(service) || is_connected(service)) { + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv4); + __connman_network_enable_ipconfig(service->network, + service->ipconfig_ipv6); + } service_save(service); } else @@ -3450,14 +3448,14 @@ static void set_error(struct connman_service *service, if (!service->path) return; + if (!allow_property_changed(service)) + return; + str = error2string(service->error); if (!str) str = ""; - if (!allow_property_changed(service)) - return; - connman_dbus_property_changed_basic(service->path, CONNMAN_SERVICE_INTERFACE, "Error", DBUS_TYPE_STRING, &str); @@ -4807,6 +4805,11 @@ bool __connman_service_is_connected_state(struct connman_service *service, return is_connected_state(service, service->state_ipv4); case CONNMAN_IPCONFIG_TYPE_IPV6: return is_connected_state(service, service->state_ipv6); + case CONNMAN_IPCONFIG_TYPE_ALL: + return is_connected_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4) && + is_connected_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); } return false; @@ -5299,6 +5302,8 @@ static int service_indicate_state(struct connman_service *service) break; case CONNMAN_SERVICE_STATE_READY: + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + if (service->new_service && __connman_stats_service_register(service) == 0) { /* @@ -5365,6 +5370,7 @@ static int service_indicate_state(struct connman_service *service) break; case CONNMAN_SERVICE_STATE_DISCONNECT: + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); reply_pending(service, ECONNABORTED); @@ -5409,9 +5415,6 @@ static int service_indicate_state(struct connman_service *service) break; } - if (new_state != CONNMAN_SERVICE_STATE_FAILURE) - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); - service_list_sort(); __connman_connection_update_gateway(); @@ -5439,17 +5442,10 @@ int __connman_service_indicate_error(struct connman_service *service, if (!service) return -EINVAL; - set_error(service, error); - - /* - * Supplicant does not always return invalid key error for - * WPA-EAP so clear the credentials always. - */ - if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY || - service->security == CONNMAN_SERVICE_SECURITY_8021X) - clear_passphrase(service); + if (service->state == CONNMAN_SERVICE_STATE_FAILURE) + return -EALREADY; - __connman_service_set_agent_identity(service, NULL); + set_error(service, error); __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_FAILURE, @@ -5653,7 +5649,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, enum connman_ipconfig_type type) { struct connman_ipconfig *ipconfig = NULL; - enum connman_service_state *old_state; + enum connman_service_state old_state; enum connman_ipconfig_method method; if (!service) @@ -5661,16 +5657,17 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, switch (type) { case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: return -EINVAL; case CONNMAN_IPCONFIG_TYPE_IPV4: - old_state = &service->state_ipv4; + old_state = service->state_ipv4; ipconfig = service->ipconfig_ipv4; break; case CONNMAN_IPCONFIG_TYPE_IPV6: - old_state = &service->state_ipv6; + old_state = service->state_ipv6; ipconfig = service->ipconfig_ipv6; break; @@ -5680,12 +5677,12 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, return -EINVAL; /* Any change? */ - if (*old_state == new_state) + if (old_state == new_state) return -EALREADY; DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)", service, service ? service->identifier : NULL, - *old_state, state2string(*old_state), + old_state, state2string(old_state), new_state, state2string(new_state), type, __connman_ipconfig_type2string(type)); @@ -5732,14 +5729,17 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, break; case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + case CONNMAN_IPCONFIG_METHOD_DHCP: + case CONNMAN_IPCONFIG_METHOD_AUTO: break; } - *old_state = new_state; + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + service->state_ipv4 = new_state; + else + service->state_ipv6 = new_state; update_nameservers(service); @@ -5839,6 +5839,9 @@ static int service_connect(struct connman_service *service) case CONNMAN_SERVICE_SECURITY_PSK: case CONNMAN_SERVICE_SECURITY_WPA: case CONNMAN_SERVICE_SECURITY_RSN: + if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) + return -ENOKEY; + if (!service->passphrase) { if (!service->network) return -EOPNOTSUPP; @@ -5865,9 +5868,10 @@ static int service_connect(struct connman_service *service) * missing. Agent provided credentials can be used as * fallback if needed. */ - if ((!service->identity && + if (((!service->identity && !service->agent_identity) || - !service->passphrase) + !service->passphrase) || + service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) return -ENOKEY; break; @@ -5962,16 +5966,15 @@ int __connman_service_connect(struct connman_service *service, err = service_connect(service); service->connect_reason = reason; - if (err >= 0) { - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + + if (err >= 0) return 0; - } if (err == -EINPROGRESS) { if (service->timeout == 0) service->timeout = g_timeout_add_seconds( CONNECT_TIMEOUT, connect_timeout, service); - set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + return -EINPROGRESS; } @@ -6729,8 +6732,32 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne if (service->favorite) { device = connman_network_get_device(service->network); - if (device && !connman_device_get_scanning(device)) - __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); + if (device && !connman_device_get_scanning(device)) { + + switch (service->type) { + case CONNMAN_SERVICE_TYPE_UNKNOWN: + case CONNMAN_SERVICE_TYPE_SYSTEM: + case CONNMAN_SERVICE_TYPE_P2P: + break; + + case CONNMAN_SERVICE_TYPE_GADGET: + case CONNMAN_SERVICE_TYPE_ETHERNET: + if (service->autoconnect) { + __connman_service_connect(service, + CONNMAN_SERVICE_CONNECT_REASON_AUTO); + break; + } + + /* fall through */ + case CONNMAN_SERVICE_TYPE_BLUETOOTH: + case CONNMAN_SERVICE_TYPE_GPS: + case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_WIFI: + case CONNMAN_SERVICE_TYPE_CELLULAR: + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); + break; + } + } } __connman_notifier_service_add(service, service->name); diff --git a/src/shared/sha1.c b/src/shared/sha1.c deleted file mode 100644 index e67b020d..00000000 --- a/src/shared/sha1.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * - * This library 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.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> - -#include "src/shared/sha1.h" - -#define SHA1_MAC_LEN 20 - -static void __hmac_sha1(GChecksum *checksum, const void *key, size_t key_len, - const void *data, size_t data_len, void *output) -{ - unsigned char ipad[64]; - unsigned char opad[64]; - unsigned char digest[SHA1_MAC_LEN]; - size_t length; - int i; - - /* if key is longer than 64 bytes reset it to key=SHA1(key) */ - if (key_len > 64) { - g_checksum_update(checksum, key, key_len); - length = sizeof(digest); - g_checksum_get_digest(checksum, digest, &length); - - g_checksum_reset(checksum); - - key = digest; - key_len = SHA1_MAC_LEN; - } - - /* start out by storing key in pads */ - memset(ipad, 0, sizeof(ipad)); - memset(opad, 0, sizeof(opad)); - memcpy(ipad, key, key_len); - memcpy(opad, key, key_len); - - /* XOR key with ipad and opad values */ - for (i = 0; i < 64; i++) { - ipad[i] ^= 0x36; - opad[i] ^= 0x5c; - } - - /* perform inner SHA1 */ - g_checksum_update(checksum, ipad, sizeof(ipad)); - g_checksum_update(checksum, data, data_len); - length = sizeof(digest); - g_checksum_get_digest(checksum, digest, &length); - - g_checksum_reset(checksum); - - /* perform outer SHA1 */ - g_checksum_update(checksum, opad, sizeof(opad)); - g_checksum_update(checksum, digest, length); - length = sizeof(digest); - g_checksum_get_digest(checksum, output, &length); - - g_checksum_reset(checksum); -} - -int hmac_sha1(const void *key, size_t key_len, - const void *data, size_t data_len, void *output, size_t size) -{ - GChecksum *checksum; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - __hmac_sha1(checksum, key, key_len, data, data_len, output); - - g_checksum_free(checksum); - - return 0; -} - -static void F(GChecksum *checksum, const char *password, size_t password_len, - const char *salt, size_t salt_len, - unsigned int iterations, unsigned int count, - unsigned char *digest) -{ - unsigned char tmp1[SHA1_MAC_LEN]; - unsigned char tmp2[SHA1_MAC_LEN]; - unsigned char buf[36]; - unsigned int i, j; - - memcpy(buf, salt, salt_len); - buf[salt_len + 0] = (count >> 24) & 0xff; - buf[salt_len + 1] = (count >> 16) & 0xff; - buf[salt_len + 2] = (count >> 8) & 0xff; - buf[salt_len + 3] = count & 0xff; - - __hmac_sha1(checksum, password, password_len, - buf, salt_len + 4, tmp1); - memcpy(digest, tmp1, SHA1_MAC_LEN); - - for (i = 1; i < iterations; i++) { - __hmac_sha1(checksum, password, password_len, - tmp1, SHA1_MAC_LEN, tmp2); - memcpy(tmp1, tmp2, SHA1_MAC_LEN); - - for (j = 0; j < SHA1_MAC_LEN; j++) - digest[j] ^= tmp2[j]; - } -} - -int pbkdf2_sha1(const void *password, size_t password_len, - const void *salt, size_t salt_len, - unsigned int iterations, void *output, size_t size) -{ - GChecksum *checksum; - unsigned char *ptr = output; - unsigned char digest[SHA1_MAC_LEN]; - unsigned int i; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - for (i = 1; size > 0; i++) { - size_t len; - - F(checksum, password, password_len, salt, salt_len, - iterations, i, digest); - - len = size > SHA1_MAC_LEN ? SHA1_MAC_LEN : size; - memcpy(ptr, digest, len); - - ptr += len; - size -= len; - } - - g_checksum_free(checksum); - - return 0; -} - -int prf_sha1(const void *key, size_t key_len, - const void *prefix, size_t prefix_len, - const void *data, size_t data_len, void *output, size_t size) -{ - GChecksum *checksum; - unsigned char input[1024]; - size_t input_len; - unsigned int i, offset = 0; - - checksum = g_checksum_new(G_CHECKSUM_SHA1); - - memcpy(input, prefix, prefix_len); - input[prefix_len] = 0; - - memcpy(input + prefix_len + 1, data, data_len); - input[prefix_len + 1 + data_len] = 0; - - input_len = prefix_len + 1 + data_len + 1; - - for (i = 0; i < (size + 19) / 20; i++) { - __hmac_sha1(checksum, key, key_len, input, input_len, - output + offset); - - offset += 20; - input[input_len - 1]++; - } - - g_checksum_free(checksum); - - return 0; -} diff --git a/src/shared/sha1.h b/src/shared/sha1.h deleted file mode 100644 index 0c0c6d19..00000000 --- a/src/shared/sha1.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * - * This library 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.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -int hmac_sha1(const void *key, size_t key_len, - const void *data, size_t data_len, void *output, size_t size); - -int pbkdf2_sha1(const void *password, size_t password_len, - const void *salt, size_t salt_len, - unsigned int iterations, void *output, size_t size); - -int prf_sha1(const void *key, size_t key_len, - const void *prefix, size_t prefix_len, - const void *data, size_t data_len, void *output, size_t size); diff --git a/src/technology.c b/src/technology.c index d80d9e6d..55303a0c 100644 --- a/src/technology.c +++ b/src/technology.c @@ -84,6 +84,9 @@ struct connman_technology { static GSList *driver_list = NULL; +static int technology_enabled(struct connman_technology *technology); +static int technology_disabled(struct connman_technology *technology); + static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_technology_driver *driver1 = a; @@ -615,19 +618,27 @@ static gboolean technology_pending_reply(gpointer user_data) static int technology_affect_devices(struct connman_technology *technology, bool enable_device) { + int err = 0, err_dev; GSList *list; - int err = -ENXIO; - if (technology->type == CONNMAN_SERVICE_TYPE_P2P) + if (technology->type == CONNMAN_SERVICE_TYPE_P2P) { + if (enable_device) + __connman_technology_enabled(technology->type); + else + __connman_technology_disabled(technology->type); return 0; + } for (list = technology->device_list; list; list = list->next) { struct connman_device *device = list->data; if (enable_device) - err = __connman_device_enable(device); + err_dev = __connman_device_enable(device); else - err = __connman_device_disable(device); + err_dev = __connman_device_disable(device); + + if (err_dev < 0 && err_dev != -EALREADY) + err = err_dev; } return err; @@ -1186,13 +1197,6 @@ static struct connman_technology *technology_get(enum connman_service_type type) technology->type = type; technology->path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str); - if (type == CONNMAN_SERVICE_TYPE_P2P) { - struct connman_technology *wifi; - - wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI); - if (wifi) - technology->enabled = wifi->enabled; - } technology_load(technology); technology_list = g_slist_prepend(technology_list, technology); @@ -1211,7 +1215,20 @@ static struct connman_technology *technology_get(enum connman_service_type type) return NULL; } - DBG("technology %p", technology); + if (type == CONNMAN_SERVICE_TYPE_P2P) { + struct connman_technology *wifi; + bool enable; + + enable = technology->enable_persistent; + + wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI); + if (enable && wifi) + enable = wifi->enabled; + + technology_affect_devices(technology, enable); + } + + DBG("technology %p %s", technology, get_name(technology->type)); return technology; } @@ -1797,6 +1814,12 @@ void __connman_technology_cleanup(void) { DBG(""); + while (technology_list) { + struct connman_technology *technology = technology_list->data; + technology_list = g_slist_remove(technology_list, technology); + technology_put(technology); + } + g_hash_table_destroy(rfkill_list); dbus_connection_unref(connection); diff --git a/src/util.c b/src/util.c new file mode 100644 index 00000000..da32cc55 --- /dev/null +++ b/src/util.c @@ -0,0 +1,88 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2014 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <inttypes.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include "connman.h" + +#define URANDOM "/dev/urandom" + +int f = -1; + +int __connman_util_get_random(uint64_t *val) +{ + int r = 0; + + if (!val) + return -EINVAL; + + if (read(f, val, sizeof(uint64_t)) < 0) { + r = -errno; + connman_warn_once("Could not read from "URANDOM); + *val = random(); + } + + return r; +} + +int __connman_util_init(void) +{ + int r = 0; + + if (f > 0) + return 0; + + f = open(URANDOM, O_RDONLY); + if (f < 0) { + r = -errno; + connman_warn("Could not open "URANDOM); + srandom(time(NULL)); + } else { + uint64_t val; + + r = __connman_util_get_random(&val); + if (r < 0) + srandom(time(NULL)); + else + srandom(val); + } + + return r; +} + +void __connman_util_cleanup(void) +{ + if (f > 0) + close(f); + + f = -1; +} diff --git a/src/wispr.c b/src/wispr.c index c4fcd60b..ef4bdaba 100644 --- a/src/wispr.c +++ b/src/wispr.c @@ -143,6 +143,7 @@ static void free_wispr_routes(struct connman_wispr_portal_context *wp_context) route->address); break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: break; } @@ -487,6 +488,7 @@ static bool wispr_route_request(const char *address, int ai_family, gateway); break; case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: break; } diff --git a/unit/test-pbkdf2-sha1.c b/unit/test-pbkdf2-sha1.c deleted file mode 100644 index 71e1d4e2..00000000 --- a/unit/test-pbkdf2-sha1.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2007-2012 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include <glib.h> - -#include "src/shared/sha1.h" - -struct pbkdf2_data { - const char *password; - unsigned int password_len; - const char *salt; - unsigned int salt_len; - unsigned int count; - unsigned int key_len; - const char *key; -}; - -static void pbkdf2_test(gconstpointer data) -{ - const struct pbkdf2_data *test = data; - unsigned int password_len; - unsigned int salt_len; - unsigned int key_len; - unsigned char output[25]; - char key[50]; - unsigned int i; - int result; - - password_len = test->password_len ? : strlen(test->password); - salt_len = test->salt_len ? : strlen(test->salt); - - key_len = test->key_len ? : (strlen(test->key) / 2); - - if (g_test_verbose()) { - g_print("Password = \"%s\" (%d octects)\n", - test->password, password_len); - g_print("Salt = \"%s\" (%d octects)\n", - test->salt, salt_len); - g_print("Count = %d\n", test->count); - g_print("Key = %s (%d octects)\n", test->key, key_len); - } - - result = pbkdf2_sha1(test->password, password_len, - test->salt, salt_len, - test->count, output, key_len); - - g_assert(result == 0); - - for (i = 0; i < key_len; i++) - sprintf(key + (i * 2), "%02x", output[i]); - - if (g_test_verbose()) - g_print("Result = %s\n", key); - - g_assert(strcmp(test->key, key) == 0); -} - -static const struct pbkdf2_data pbkdf2_test_vector_1 = { - .password = "password", - .salt = "salt", - .count = 1, - .key = "0c60c80f961f0e71f3a9b524af6012062fe037a6", - .key_len = 20, -}; - -static const struct pbkdf2_data pbkdf2_test_vector_2 = { - .password = "password", - .salt = "salt", - .count = 2, - .key = "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", - .key_len = 20, -}; - -static const struct pbkdf2_data pbkdf2_test_vector_3 = { - .password = "password", - .salt = "salt", - .count = 4096, - .key = "4b007901b765489abead49d926f721d065a429c1", - .key_len = 20, -}; - -static const struct pbkdf2_data pbkdf2_test_vector_4 = { - .password = "password", - .salt = "salt", - .count = 16777216, - .key = "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", - .key_len = 20, -}; - -static const struct pbkdf2_data pbkdf2_test_vector_5 = { - .password = "passwordPASSWORDpassword", - .salt = "saltSALTsaltSALTsaltSALTsaltSALTsalt", - .count = 4096, - .key = "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", - .key_len = 25, -}; - -static const struct pbkdf2_data pbkdf2_test_vector_6 = { - .password = "pass\0word", - .password_len = 9, - .salt = "sa\0lt", - .salt_len = 5, - .count = 4096, - .key = "56fa6aa75548099dcc37d7f03425e0c3", - .key_len = 16, -}; - -static const struct pbkdf2_data athena_test_vector_1 = { - .password = "password", - .salt = "ATHENA.MIT.EDUraeburn", - .count = 1, - .key = "cdedb5281bb2f801565a1122b2563515", -}; - -static const struct pbkdf2_data athena_test_vector_2 = { - .password = "password", - .salt = "ATHENA.MIT.EDUraeburn", - .count = 2, - .key = "01dbee7f4a9e243e988b62c73cda935d", -}; - -static const struct pbkdf2_data athena_test_vector_3 = { - .password = "password", - .salt = "ATHENA.MIT.EDUraeburn", - .count = 1200, - .key = "5c08eb61fdf71e4e4ec3cf6ba1f5512b", -}; - -static const struct pbkdf2_data athena_test_vector_4 = { - .password = "password", - .salt = "\x12\x34\x56\x78\x78\x56\x34\x12", - .count = 5, - .key = "d1daa78615f287e6a1c8b120d7062a49", -}; - -static const struct pbkdf2_data athena_test_vector_5 = { - .password = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - .salt = "pass phrase equals block size", - .count = 1200, - .key = "139c30c0966bc32ba55fdbf212530ac9", -}; - -static const struct pbkdf2_data athena_test_vector_6 = { - .password = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - .salt = "pass phrase exceeds block size", - .count = 1200, - .key = "9ccad6d468770cd51b10e6a68721be61", -}; - -static const struct pbkdf2_data athena_test_vector_7 = { - .password = "\xf0\x9d\x84\x9e", /* g-clef (0xf09d849e) */ - .salt = "EXAMPLE.COMpianist", - .count = 50, - .key = "6b9cf26d45455a43a5b8bb276a403b39", -}; - -struct psk_data { - const char *passphrase; - const unsigned char *ssid; - size_t ssid_len; - const char *network; - const char *psk; -}; - -static void psk_test(gconstpointer data) -{ - const struct psk_data *test = data; - unsigned char ssid[32]; - size_t ssid_len; - unsigned char output[32]; - char psk[65]; - unsigned int i; - int result; - - if (!test->network) { - memcpy(ssid, test->ssid, test->ssid_len); - ssid_len = test->ssid_len; - } else { - ssid_len = strlen(test->network); - memcpy(ssid, test->network, ssid_len); - } - - if (g_test_verbose()) { - g_print("Passphrase = \"%s\"\n", test->passphrase); - g_print("SSID = {"); - for (i = 0; i < ssid_len; i++) - g_print("%s'%c'", i == 0 ? " " : ", ", - ssid[i]); - g_print(" }\n"); - g_print("SSID Length = %zd\n", ssid_len); - g_print("PSK = %s\n", test->psk); - } - - result = pbkdf2_sha1(test->passphrase, strlen(test->passphrase), - ssid, ssid_len, 4096, - output, sizeof(output)); - - g_assert(result == 0); - - for (i = 0; i < sizeof(output); i++) - sprintf(psk + (i * 2), "%02x", output[i]); - - if (g_test_verbose()) - g_print("Result = %s\n", psk); - - g_assert(strcmp(test->psk, psk) == 0); -} - -static const unsigned char psk_test_case_1_ssid[] = { 'I', 'E', 'E', 'E' }; - -static const struct psk_data psk_test_case_1 = { - .passphrase = "password", - .ssid = psk_test_case_1_ssid, - .ssid_len = sizeof(psk_test_case_1_ssid), - .psk = "f42c6fc52df0ebef9ebb4b90b38a5f90" - "2e83fe1b135a70e23aed762e9710a12e", -}; - -static const unsigned char psk_test_case_2_ssid[] = { 'T', 'h', 'i', 's', - 'I', 's', 'A', 'S', 'S', 'I', 'D' }; - -static const struct psk_data psk_test_case_2 = { - .passphrase = "ThisIsAPassword", - .ssid = psk_test_case_2_ssid, - .ssid_len = sizeof(psk_test_case_2_ssid), - .psk = "0dc0d6eb90555ed6419756b9a15ec3e3" - "209b63df707dd508d14581f8982721af", -}; - -static const unsigned char psk_test_case_3_ssid[] = { - 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', - 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', - 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', - 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z' }; - -static const struct psk_data psk_test_case_3 = { - .passphrase = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - .ssid = psk_test_case_3_ssid, - .ssid_len = sizeof(psk_test_case_3_ssid), - .psk = "becb93866bb8c3832cb777c2f559807c" - "8c59afcb6eae734885001300a981cc62", -}; - -int main(int argc, char *argv[]) -{ - g_test_init(&argc, &argv, NULL); - - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 1", - &pbkdf2_test_vector_1, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 2", - &pbkdf2_test_vector_2, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 3", - &pbkdf2_test_vector_3, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 4", - &pbkdf2_test_vector_4, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 5", - &pbkdf2_test_vector_5, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/PBKDF2 Test vector 6", - &pbkdf2_test_vector_6, pbkdf2_test); - - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 1", - &athena_test_vector_1, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 2", - &athena_test_vector_2, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 3", - &athena_test_vector_3, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 4", - &athena_test_vector_4, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 5", - &athena_test_vector_5, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 6", - &athena_test_vector_6, pbkdf2_test); - g_test_add_data_func("/pbkdf2-sha1/ATHENA Test vector 7", - &athena_test_vector_7, pbkdf2_test); - - g_test_add_data_func("/pbkdf2-sha1/PSK Test case 1", - &psk_test_case_1, psk_test); - g_test_add_data_func("/pbkdf2-sha1/PSK Test case 2", - &psk_test_case_2, psk_test); - g_test_add_data_func("/pbkdf2-sha1/PSK Test case 3", - &psk_test_case_3, psk_test); - - return g_test_run(); -} diff --git a/unit/test-prf-sha1.c b/unit/test-prf-sha1.c deleted file mode 100644 index c6a3787d..00000000 --- a/unit/test-prf-sha1.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2007-2012 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include <glib.h> - -#include "src/shared/sha1.h" - -struct prf_data { - const char *key; - unsigned int key_len; - const char *prefix; - unsigned int prefix_len; - const char *data; - unsigned int data_len; - const char *prf; -}; - -static void prf_test(gconstpointer data) -{ - const struct prf_data *test = data; - unsigned int prf_len; - unsigned char output[512]; - char prf[128]; - unsigned int i; - int result; - - prf_len = strlen(test->prf) / 2; - - if (g_test_verbose()) - g_print("PRF = %s (%d octects)\n", test->prf, prf_len); - - result = prf_sha1(test->key, test->key_len, test->prefix, - test->prefix_len, test->data, test->data_len, - output, prf_len); - - g_assert(result == 0); - - for (i = 0; i < prf_len; i++) - sprintf(prf + (i * 2), "%02x", output[i]); - - if (g_test_verbose()) - g_print("Result = %s\n", prf); - - g_assert(strcmp(test->prf, prf) == 0); -} - -static const struct prf_data test_case_1 = { - .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" - "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - .key_len = 20, - .prefix = "prefix", - .prefix_len = 6, - .data = "Hi There", - .data_len = 8, - .prf = "bcd4c650b30b9684951829e0d75f9d54" - "b862175ed9f00606e17d8da35402ffee" - "75df78c3d31e0f889f012120c0862beb" - "67753e7439ae242edb8373698356cf5a", -}; - -static const struct prf_data test_case_2 = { - .key = "Jefe", - .key_len = 4, - .prefix = "prefix", - .prefix_len = 6, - .data = "what do ya want for nothing?", - .data_len = 28, - .prf = "51f4de5b33f249adf81aeb713a3c20f4" - "fe631446fabdfa58244759ae58ef9009" - "a99abf4eac2ca5fa87e692c440eb4002" - "3e7babb206d61de7b92f41529092b8fc", -}; - -static const struct prf_data test_case_3 = { - .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", - .key_len = 20, - .prefix = "prefix", - .prefix_len = 6, - .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" - "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" - "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" - "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" - "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", - .data_len = 50, - .prf = "e1ac546ec4cb636f9976487be5c86be1" - "7a0252ca5d8d8df12cfb0473525249ce" - "9dd8d177ead710bc9b590547239107ae" - "f7b4abd43d87f0a68f1cbd9e2b6f7607", -}; - -int main(int argc, char *argv[]) -{ - g_test_init(&argc, &argv, NULL); - - g_test_add_data_func("/prf-sha1/Test case 1", - &test_case_1, prf_test); - g_test_add_data_func("/prf-sha1/Test case 2", - &test_case_2, prf_test); - g_test_add_data_func("/prf-sha1/Test case 3", - &test_case_3, prf_test); - - return g_test_run(); -} diff --git a/vpn/connman-vpn.service.in b/vpn/connman-vpn.service.in index 3778d51c..de65a70d 100644 --- a/vpn/connman-vpn.service.in +++ b/vpn/connman-vpn.service.in @@ -6,7 +6,7 @@ After=dbus.socket [Service] Type=dbus BusName=net.connman.vpn -ExecStart=@prefix@/sbin/connman-vpnd -n +ExecStart=@sbindir@/connman-vpnd -n StandardOutput=null [Install] diff --git a/vpn/net.connman.vpn.service.in b/vpn/net.connman.vpn.service.in index fc9e9bf3..e473ea9e 100644 --- a/vpn/net.connman.vpn.service.in +++ b/vpn/net.connman.vpn.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=net.connman.vpn -Exec=@prefix@/sbin/connman-vpnd -n +Exec=@sbindir@/connman-vpnd -n User=root SystemdService=connman-vpn.service |