diff options
Diffstat (limited to 'src/settings')
223 files changed, 55382 insertions, 0 deletions
diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am new file mode 100644 index 00000000..55b5b7ef --- /dev/null +++ b/src/settings/Makefile.am @@ -0,0 +1,89 @@ +SUBDIRS=plugins . tests + +INCLUDES = -I${top_srcdir} \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src \ + -I${top_builddir}/marshallers + +noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la + +libtest_settings_utils_la_SOURCES = \ + nm-settings-utils.c \ + nm-settings-utils.h + +libtest_settings_utils_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) + +libtest_settings_utils_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +BUILT_SOURCES = \ + nm-settings-glue.h \ + nm-settings-connection-glue.h \ + nm-agent-manager-glue.h + +libsettings_la_SOURCES = \ + nm-settings.c \ + nm-settings.h \ + nm-inotify-helper.c \ + nm-inotify-helper.h \ + nm-polkit-helpers.h \ + nm-settings-error.c \ + nm-settings-error.h \ + nm-system-config-interface.c \ + nm-system-config-interface.h \ + nm-settings-connection.c \ + nm-settings-connection.h \ + nm-default-wired-connection.c \ + nm-default-wired-connection.h \ + nm-agent-manager.c \ + nm-agent-manager.h \ + nm-secret-agent.c \ + nm-secret-agent.h \ + nm-settings-utils.h \ + nm-settings-utils.c + +libsettings_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DBINDIR=\"$(bindir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ + -DPLUGINDIR=\"$(pkglibdir)\" + +libsettings_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(POLKIT_LIBS) + +libsettings_la_LDFLAGS = -rdynamic + +nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< + +nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $< + +nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $< + +CLEANFILES = \ + $(BUILT_SOURCES) + diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in new file mode 100644 index 00000000..81970334 --- /dev/null +++ b/src/settings/Makefile.in @@ -0,0 +1,945 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsettings_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libsettings_la_OBJECTS = libsettings_la-nm-settings.lo \ + libsettings_la-nm-inotify-helper.lo \ + libsettings_la-nm-settings-error.lo \ + libsettings_la-nm-system-config-interface.lo \ + libsettings_la-nm-settings-connection.lo \ + libsettings_la-nm-default-wired-connection.lo \ + libsettings_la-nm-agent-manager.lo \ + libsettings_la-nm-secret-agent.lo \ + libsettings_la-nm-settings-utils.lo +libsettings_la_OBJECTS = $(am_libsettings_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libsettings_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libsettings_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +libtest_settings_utils_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libtest_settings_utils_la_OBJECTS = \ + libtest_settings_utils_la-nm-settings-utils.lo +libtest_settings_utils_la_OBJECTS = \ + $(am_libtest_settings_utils_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libsettings_la_SOURCES) \ + $(libtest_settings_utils_la_SOURCES) +DIST_SOURCES = $(libsettings_la_SOURCES) \ + $(libtest_settings_utils_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = plugins . tests +INCLUDES = -I${top_srcdir} \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src \ + -I${top_builddir}/marshallers + +noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la +libtest_settings_utils_la_SOURCES = \ + nm-settings-utils.c \ + nm-settings-utils.h + +libtest_settings_utils_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) + +libtest_settings_utils_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +BUILT_SOURCES = \ + nm-settings-glue.h \ + nm-settings-connection-glue.h \ + nm-agent-manager-glue.h + +libsettings_la_SOURCES = \ + nm-settings.c \ + nm-settings.h \ + nm-inotify-helper.c \ + nm-inotify-helper.h \ + nm-polkit-helpers.h \ + nm-settings-error.c \ + nm-settings-error.h \ + nm-system-config-interface.c \ + nm-system-config-interface.h \ + nm-settings-connection.c \ + nm-settings-connection.h \ + nm-default-wired-connection.c \ + nm-default-wired-connection.h \ + nm-agent-manager.c \ + nm-agent-manager.h \ + nm-secret-agent.c \ + nm-secret-agent.h \ + nm-settings-utils.h \ + nm-settings-utils.c + +libsettings_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DBINDIR=\"$(bindir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ + -DPLUGINDIR=\"$(pkglibdir)\" + +libsettings_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(POLKIT_LIBS) + +libsettings_la_LDFLAGS = -rdynamic +CLEANFILES = \ + $(BUILT_SOURCES) + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsettings.la: $(libsettings_la_OBJECTS) $(libsettings_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsettings_la_LINK) $(libsettings_la_OBJECTS) $(libsettings_la_LIBADD) $(LIBS) +libtest-settings-utils.la: $(libtest_settings_utils_la_OBJECTS) $(libtest_settings_utils_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libtest_settings_utils_la_OBJECTS) $(libtest_settings_utils_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-agent-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-default-wired-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-inotify-helper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-secret-agent.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-system-config-interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libsettings_la-nm-settings.lo: nm-settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings.Tpo -c -o libsettings_la-nm-settings.lo `test -f 'nm-settings.c' || echo '$(srcdir)/'`nm-settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings.Tpo $(DEPDIR)/libsettings_la-nm-settings.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings.c' object='libsettings_la-nm-settings.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings.lo `test -f 'nm-settings.c' || echo '$(srcdir)/'`nm-settings.c + +libsettings_la-nm-inotify-helper.lo: nm-inotify-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-inotify-helper.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-inotify-helper.Tpo -c -o libsettings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-inotify-helper.Tpo $(DEPDIR)/libsettings_la-nm-inotify-helper.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-inotify-helper.c' object='libsettings_la-nm-inotify-helper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c + +libsettings_la-nm-settings-error.lo: nm-settings-error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-error.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-error.Tpo -c -o libsettings_la-nm-settings-error.lo `test -f 'nm-settings-error.c' || echo '$(srcdir)/'`nm-settings-error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-error.Tpo $(DEPDIR)/libsettings_la-nm-settings-error.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-error.c' object='libsettings_la-nm-settings-error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-error.lo `test -f 'nm-settings-error.c' || echo '$(srcdir)/'`nm-settings-error.c + +libsettings_la-nm-system-config-interface.lo: nm-system-config-interface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-system-config-interface.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-system-config-interface.Tpo -c -o libsettings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-system-config-interface.Tpo $(DEPDIR)/libsettings_la-nm-system-config-interface.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-system-config-interface.c' object='libsettings_la-nm-system-config-interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c + +libsettings_la-nm-settings-connection.lo: nm-settings-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-connection.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-connection.Tpo -c -o libsettings_la-nm-settings-connection.lo `test -f 'nm-settings-connection.c' || echo '$(srcdir)/'`nm-settings-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-connection.Tpo $(DEPDIR)/libsettings_la-nm-settings-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-connection.c' object='libsettings_la-nm-settings-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-connection.lo `test -f 'nm-settings-connection.c' || echo '$(srcdir)/'`nm-settings-connection.c + +libsettings_la-nm-default-wired-connection.lo: nm-default-wired-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-default-wired-connection.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-default-wired-connection.Tpo -c -o libsettings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-default-wired-connection.Tpo $(DEPDIR)/libsettings_la-nm-default-wired-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-default-wired-connection.c' object='libsettings_la-nm-default-wired-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c + +libsettings_la-nm-agent-manager.lo: nm-agent-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-agent-manager.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-agent-manager.Tpo -c -o libsettings_la-nm-agent-manager.lo `test -f 'nm-agent-manager.c' || echo '$(srcdir)/'`nm-agent-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-agent-manager.Tpo $(DEPDIR)/libsettings_la-nm-agent-manager.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-agent-manager.c' object='libsettings_la-nm-agent-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-agent-manager.lo `test -f 'nm-agent-manager.c' || echo '$(srcdir)/'`nm-agent-manager.c + +libsettings_la-nm-secret-agent.lo: nm-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-secret-agent.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-secret-agent.Tpo -c -o libsettings_la-nm-secret-agent.lo `test -f 'nm-secret-agent.c' || echo '$(srcdir)/'`nm-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-secret-agent.Tpo $(DEPDIR)/libsettings_la-nm-secret-agent.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-secret-agent.c' object='libsettings_la-nm-secret-agent.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-secret-agent.lo `test -f 'nm-secret-agent.c' || echo '$(srcdir)/'`nm-secret-agent.c + +libsettings_la-nm-settings-utils.lo: nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-utils.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-utils.Tpo -c -o libsettings_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-utils.Tpo $(DEPDIR)/libsettings_la-nm-settings-utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-utils.c' object='libsettings_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c + +libtest_settings_utils_la-nm-settings-utils.lo: nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_settings_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtest_settings_utils_la-nm-settings-utils.lo -MD -MP -MF $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Tpo -c -o libtest_settings_utils_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Tpo $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-utils.c' object='libtest_settings_utils_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_settings_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtest_settings_utils_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< + +nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $< + +nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c new file mode 100644 index 00000000..dbc29cae --- /dev/null +++ b/src/settings/nm-agent-manager.c @@ -0,0 +1,1390 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <string.h> +#include <ctype.h> +#include <pwd.h> + +#include <glib.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "NetworkManager.h" +#include "nm-logging.h" +#include "nm-agent-manager.h" +#include "nm-secret-agent.h" +#include "nm-manager-auth.h" +#include "nm-dbus-glib-types.h" +#include "nm-polkit-helpers.h" +#include "nm-manager-auth.h" +#include "nm-setting-vpn.h" +#include "nm-setting-connection.h" + +G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) + +#define NM_AGENT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_AGENT_MANAGER, \ + NMAgentManagerPrivate)) + +typedef struct { + gboolean disposed; + + NMDBusManager *dbus_mgr; + NMSessionMonitor *session_monitor; + PolkitAuthority *authority; + + /* Hashed by owner name, not identifier, since two agents in different + * sessions can use the same identifier. + */ + GHashTable *agents; + + GHashTable *requests; +} NMAgentManagerPrivate; + +typedef struct _Request Request; + +static void request_add_agent (Request *req, + NMSecretAgent *agent, + NMSessionMonitor *session_monitor); + +static void request_remove_agent (Request *req, NMSecretAgent *agent); + +static void impl_agent_manager_register (NMAgentManager *self, + const char *identifier, + DBusGMethodInvocation *context); + +static void impl_agent_manager_unregister (NMAgentManager *self, + DBusGMethodInvocation *context); + +#include "nm-agent-manager-glue.h" + +/********************************************************************/ + +#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ()) +#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) + +typedef enum { + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS +} NMAgentManagerError; + +static GQuark +nm_agent_manager_error_quark (void) +{ + static GQuark ret = 0; + + if (G_UNLIKELY (ret == 0)) + ret = g_quark_from_static_string ("nm-agent-manager-error"); + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +static GType +nm_agent_manager_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unable to determine caller's sender or UID */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "SenderUnknown"), + /* Permission for some operation was denied */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"), + /* The caller's session could not be determined */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "SessionNotFound"), + /* The identifier was invalid */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "InvalidIdentifier"), + /* Request was not from a registered agent */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"), + /* Some internal error occurred */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"), + /* No secrets were available */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NoSecrets"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMAgentManagerError", values); + } + return etype; +} + +/*************************************************************/ + +static gboolean +remove_agent (NMAgentManager *self, const char *owner) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + NMSecretAgent *agent; + GHashTableIter iter; + gpointer data; + + g_return_val_if_fail (owner != NULL, FALSE); + + /* Make sure this agent has already registered */ + agent = g_hash_table_lookup (priv->agents, owner); + if (!agent) + return FALSE; + + nm_log_dbg (LOGD_AGENTS, "(%s) agent unregistered", + nm_secret_agent_get_description (agent)); + + /* Remove this agent to any in-progress secrets requests */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_remove_agent ((Request *) data, agent); + + /* And dispose of the agent */ + g_hash_table_remove (priv->agents, owner); + return TRUE; +} + +/*************************************************************/ + +static gboolean +validate_identifier (const char *identifier, GError **error) +{ + const char *p = identifier; + size_t id_len; + + if (!identifier) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "No identifier was given"); + return FALSE; + } + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen (identifier); + if (id_len < 3 || id_len > 255) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier length not between 3 and 255 characters (inclusive)"); + return FALSE; + } + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier must not start or end with '.'"); + return FALSE; + } + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) { + g_set_error (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains invalid character '%c'", *p); + return FALSE; + } + + if ((*p == '.') && (*(p + 1) == '.')) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains two '.' characters in sequence"); + return FALSE; + } + p++; + } + + return TRUE; +} + +static void +impl_agent_manager_register (NMAgentManager *self, + const char *identifier, + DBusGMethodInvocation *context) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + char *error_desc = NULL, *sender = NULL; + gulong sender_uid = G_MAXULONG; + GError *error = NULL, *local = NULL; + NMSecretAgent *agent; + GHashTableIter iter; + gpointer data; + + if (!nm_auth_get_caller_uid (context, + priv->dbus_mgr, + &sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + error_desc); + g_free (error_desc); + goto done; + } + + if (!nm_session_monitor_uid_has_session (priv->session_monitor, + sender_uid, + NULL, + &local)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, + local && local->message ? local->message : "Session not found"); + goto done; + } + + sender = dbus_g_method_get_sender (context); + if (!sender) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + "Failed to get D-Bus request sender"); + goto done; + } + + /* Validate the identifier */ + if (!validate_identifier (identifier, &error)) + goto done; + + /* Success, add the new agent */ + agent = nm_secret_agent_new (priv->dbus_mgr, sender, identifier, sender_uid); + if (!agent) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, + "Failed to initialize the agent"); + goto done; + } + + g_hash_table_insert (priv->agents, g_strdup (sender), agent); + nm_log_dbg (LOGD_AGENTS, "(%s) agent registered", + nm_secret_agent_get_description (agent)); + dbus_g_method_return (context); + + /* Add this agent to any in-progress secrets requests */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_add_agent ((Request *) data, agent, priv->session_monitor); + +done: + if (error) + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_clear_error (&local); + g_free (sender); +} + +static void +impl_agent_manager_unregister (NMAgentManager *self, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + char *sender = NULL; + + sender = dbus_g_method_get_sender (context); + if (!sender) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + "Failed to get D-Bus request sender"); + goto done; + } + + /* Found the agent, unregister and remove it */ + if (!remove_agent (self, sender)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + "Caller is not registered as an Agent"); + goto done; + } + + dbus_g_method_return (context); + +done: + if (error) + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_free (sender); +} + +/*************************************************************/ + +typedef void (*RequestCompleteFunc) (Request *req, + GHashTable *secrets, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + GError *error, + gpointer user_data); +typedef void (*RequestNextFunc) (Request *req); +typedef void (*RequestCancelFunc) (Request *req); + +struct _Request { + guint32 reqid; + PolkitAuthority *authority; + NMAuthChain *chain; + + NMConnection *connection; + gboolean filter_by_uid; + gulong uid_filter; + char *setting_name; + NMSettingsGetSecretsFlags flags; + char *hint; + + /* Current agent being asked for secrets */ + NMSecretAgent *current; + gconstpointer current_call_id; + gboolean current_has_modify; + + /* Stores the sorted list of NMSecretAgents which will be asked for secrets */ + GSList *pending; + + /* Stores the list of NMSecretAgent hashes that we've already + * asked for secrets, so that we don't ask the same agent twice + * if it quits and re-registers during this secrets request. + */ + GSList *asked; + + guint32 idle_id; + + GHashTable *existing_secrets; + + NMAgentSecretsResultFunc callback; + gpointer callback_data; + gpointer other_data2; + gpointer other_data3; + + RequestCancelFunc cancel_callback; + RequestNextFunc next_callback; + RequestCompleteFunc complete_callback; + gpointer complete_callback_data; +}; + +static guint32 next_req_id = 1; + +static Request * +request_new_get (NMConnection *connection, + PolkitAuthority *authority, + gboolean filter_by_uid, + gulong uid_filter, + GHashTable *existing_secrets, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data, + RequestNextFunc next_callback, + RequestCancelFunc cancel_callback) +{ + Request *req; + + req = g_malloc0 (sizeof (Request)); + req->reqid = next_req_id++; + req->connection = g_object_ref (connection); + req->authority = g_object_ref (authority); + req->filter_by_uid = filter_by_uid; + req->uid_filter = uid_filter; + if (existing_secrets) + req->existing_secrets = g_hash_table_ref (existing_secrets); + req->setting_name = g_strdup (setting_name); + req->flags = flags; + req->hint = g_strdup (hint); + req->callback = callback; + req->callback_data = callback_data; + req->other_data2 = other_data2; + req->other_data3 = other_data3; + req->complete_callback = complete_callback; + req->complete_callback_data = complete_callback_data; + req->next_callback = next_callback; + req->cancel_callback = cancel_callback; + + return req; +} + +static Request * +request_new_other (NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data, + RequestNextFunc next_callback) +{ + Request *req; + + req = g_malloc0 (sizeof (Request)); + req->reqid = next_req_id++; + req->connection = g_object_ref (connection); + req->filter_by_uid = filter_by_uid; + req->uid_filter = uid_filter; + req->complete_callback = complete_callback; + req->complete_callback_data = complete_callback_data; + req->next_callback = next_callback; + + return req; +} + +static void +request_free (Request *req) +{ + if (req->idle_id) + g_source_remove (req->idle_id); + + if (req->cancel_callback) + req->cancel_callback (req); + + g_slist_free (req->pending); + g_slist_free (req->asked); + g_object_unref (req->connection); + g_free (req->setting_name); + g_free (req->hint); + if (req->existing_secrets) + g_hash_table_unref (req->existing_secrets); + if (req->chain) + nm_auth_chain_unref (req->chain); + if (req->authority) + g_object_unref (req->authority); + memset (req, 0, sizeof (Request)); + g_free (req); +} + +static void +req_complete_success (Request *req, + GHashTable *secrets, + const char *agent_dbus_owner, + const char *agent_uname, + gboolean agent_has_modify) +{ + req->complete_callback (req, + secrets, + agent_dbus_owner, + agent_uname, + agent_has_modify, + NULL, + req->complete_callback_data); +} + +static void +req_complete_error (Request *req, GError *error) +{ + req->complete_callback (req, NULL, NULL, NULL, FALSE, error, req->complete_callback_data); +} + +static gint +agent_compare_func (NMSecretAgent *a, NMSecretAgent *b, gpointer user_data) +{ + NMSessionMonitor *session_monitor = NM_SESSION_MONITOR (user_data); + gboolean a_active, b_active; + + if (a && !b) + return -1; + else if (a == b) + return 0; + else if (!a && b) + return 1; + + /* Prefer agents in active sessions */ + a_active = nm_session_monitor_uid_active (session_monitor, + nm_secret_agent_get_owner_uid (a), + NULL); + b_active = nm_session_monitor_uid_active (session_monitor, + nm_secret_agent_get_owner_uid (b), + NULL); + if (a_active && !b_active) + return -1; + else if (a_active == b_active) + return 0; + else if (!a_active && b_active) + return 1; + + return 0; +} + +static void +request_add_agent (Request *req, + NMSecretAgent *agent, + NMSessionMonitor *session_monitor) +{ + uid_t agent_uid; + + g_return_if_fail (req != NULL); + g_return_if_fail (agent != NULL); + + if (g_slist_find (req->asked, GUINT_TO_POINTER (nm_secret_agent_get_hash (agent)))) + return; + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). + */ + agent_uid = nm_secret_agent_get_owner_uid (agent); + if (0 != agent_uid) { + if (!nm_auth_uid_in_acl (req->connection, session_monitor, agent_uid, NULL)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s (not in ACL)", + nm_secret_agent_get_description (agent), + req, req->setting_name); + /* Connection not visible to this agent's user */ + return; + } + /* Caller is allowed to manipulate this connection */ + } + + /* If the request should filter agents by UID, do that now */ + if (req->filter_by_uid && (agent_uid != req->uid_filter)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s " + "(uid %d not required %ld)", + nm_secret_agent_get_description (agent), + req, req->setting_name, agent_uid, req->uid_filter); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent allowed for secrets request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Add this agent to the list, preferring active sessions */ + req->pending = g_slist_insert_sorted_with_data (req->pending, + agent, + (GCompareDataFunc) agent_compare_func, + session_monitor); +} + +static void +request_add_agents (NMAgentManager *self, Request *req) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; + + g_hash_table_iter_init (&iter, priv->agents); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_add_agent (req, NM_SECRET_AGENT (data), priv->session_monitor); +} + +static void +request_remove_agent (Request *req, NMSecretAgent *agent) +{ + gboolean try_next = FALSE; + const char *detail = ""; + + g_return_if_fail (req != NULL); + g_return_if_fail (agent != NULL); + + /* If this agent is being asked right now, cancel the request */ + if (agent == req->current) { + req->cancel_callback (req); + req->current_has_modify = FALSE; + req->current = NULL; + req->current_call_id = NULL; + try_next = TRUE; + detail = " current"; + } + + nm_log_dbg (LOGD_AGENTS, "(%s)%s agent removed from secrets request %p/%s", + nm_secret_agent_get_description (agent), + detail, req, req->setting_name); + + req->pending = g_slist_remove (req->pending, agent); + + if (try_next) { + /* If the agent serving the in-progress secrets request went away then + * we need to send the request to the next agent. + */ + req->next_callback (req); + } +} + +static gboolean +next_generic (Request *req, const char *detail) +{ + GError *error = NULL; + gboolean success = FALSE; + + if (req->pending == NULL) { + /* No more secret agents are available to fulfill this secrets request */ + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS, + "No agents were available for this request."); + req_complete_error (req, error); + g_error_free (error); + } else { + /* Send a secrets request to the next agent */ + req->current_has_modify = FALSE; + req->current = req->pending->data; + req->pending = g_slist_remove (req->pending, req->current); + + nm_log_dbg (LOGD_AGENTS, "(%s) agent %s secrets for request %p/%s", + nm_secret_agent_get_description (req->current), + detail, req, req->setting_name); + success = TRUE; + } + + return success; +} + +static gboolean +start_generic (gpointer user_data) +{ + Request *req = user_data; + + req->idle_id = 0; + req->next_callback (req); + return FALSE; +} + + +/*************************************************************/ + +static void +get_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + GHashTable *setting_secrets; + const char *agent_dbus_owner; + gboolean agent_has_modify; + struct passwd *pw; + char *agent_uname = NULL; + + g_return_if_fail (call_id == req->current_call_id); + + agent_has_modify = req->current_has_modify; + req->current_has_modify = FALSE; + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + /* Ensure the setting we wanted secrets for got returned and has something in it */ + setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + if (!setting_secrets || !g_hash_table_size (setting_secrets)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Get the agent's username */ + pw = getpwuid (nm_secret_agent_get_owner_uid (agent)); + if (pw && strlen (pw->pw_name)) { + /* Needs to be UTF-8 valid since it may be pushed through D-Bus */ + if (g_utf8_validate (pw->pw_name, -1, NULL)) + agent_uname = g_strdup (pw->pw_name); + } + + agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); + req_complete_success (req, secrets, agent_dbus_owner, agent_uname, agent_has_modify); + g_free (agent_uname); +} + +static void +set_secrets_not_required (NMConnection *connection, GHashTable *hash) +{ + GHashTableIter iter, setting_iter; + const char *setting_name = NULL; + GHashTable *setting_hash = NULL; + + /* Iterate through the settings hashes */ + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_hash)) { + const char *key_name = NULL; + NMSetting *setting; + GValue *val; + + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (setting) { + /* Now through each secret in the setting and mark it as not required */ + g_hash_table_iter_init (&setting_iter, setting_hash); + while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, (gpointer *) &val)) { + /* For each secret, set the flag that it's not required; VPN + * secrets need slightly different treatment here since the + * "secrets" property is actually a hash table of secrets. + */ + if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 + && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0 + && G_VALUE_HOLDS (val, DBUS_TYPE_G_MAP_OF_STRING)) { + GHashTableIter vpn_secret_iter; + const char *secret_name; + + g_hash_table_iter_init (&vpn_secret_iter, g_value_get_boxed (val)); + while (g_hash_table_iter_next (&vpn_secret_iter, (gpointer *) &secret_name, NULL)) + nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + } else + nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + } + } + } +} + +static void +get_agent_request_secrets (Request *req, gboolean include_system_secrets) +{ + NMConnection *tmp; + + tmp = nm_connection_duplicate (req->connection); + nm_connection_clear_secrets (tmp); + if (include_system_secrets) { + if (req->existing_secrets) + nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL); + } else { + /* Update secret flags in the temporary connection to indicate that + * the system secrets we're not sending to the agent aren't required, + * so the agent can properly validate UI controls and such. + */ + if (req->existing_secrets) + set_secrets_not_required (tmp, req->existing_secrets); + } + + req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), + tmp, + req->setting_name, + req->hint, + req->flags, + get_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current_has_modify = FALSE; + req->current = NULL; + req->next_callback (req); + } + + g_object_unref (tmp); +} + +static void +get_agent_modify_auth_cb (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + Request *req = user_data; + NMAuthCallResult result; + const char *perm; + + req->chain = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check error: (%d) %s", + req, req->setting_name, + error->code, error->message ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + } else { + /* If the agent obtained the 'modify' permission, we send all system secrets + * to it. If it didn't, we still ask it for secrets, but we don't send + * any system secrets. + */ + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); + if (result == NM_AUTH_CALL_RESULT_YES) + req->current_has_modify = TRUE; + + nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check result %d", + req, req->setting_name, result); + + get_agent_request_secrets (req, req->current_has_modify); + } + nm_auth_chain_unref (chain); +} + +static void +check_system_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + gboolean *has_system = user_data; + + if (!(flags & NM_SETTING_PARAM_SECRET)) + return; + + /* Clear out system-owned or always-ask secrets */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + /* VPNs are special; need to handle each secret separately */ + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + *has_system = TRUE; + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + *has_system = TRUE; + } +} + +static gboolean +has_system_secrets (NMConnection *connection) +{ + gboolean has_system = FALSE; + + nm_connection_for_each_setting_value (connection, check_system_secrets_cb, &has_system); + return has_system; +} + +static void +get_next_cb (Request *req) +{ + NMSettingConnection *s_con; + const char *agent_dbus_owner, *perm; + + if (!next_generic (req, "getting")) + return; + + agent_dbus_owner = nm_secret_agent_get_dbus_owner (NM_SECRET_AGENT (req->current)); + + /* If the request flags allow user interaction, and there are existing + * system secrets (or blank secrets that are supposed to be system-owned), + * check whether the agent has the 'modify' permission before sending those + * secrets to the agent. We shouldn't leak system-owned secrets to + * unprivileged users. + */ + if ( (req->flags != NM_SETTINGS_GET_SECRETS_FLAG_NONE) + && (req->existing_secrets || has_system_secrets (req->connection))) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", + req, req->setting_name, agent_dbus_owner); + + req->chain = nm_auth_chain_new_dbus_sender (req->authority, + agent_dbus_owner, + get_agent_modify_auth_cb, + req); + g_assert (req->chain); + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + nm_auth_chain_set_data (req->chain, "perm", (gpointer) perm, NULL); + + nm_auth_chain_add_call (req->chain, perm, TRUE); + } else { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", + req, req->setting_name, agent_dbus_owner); + + get_agent_request_secrets (req, FALSE); + } +} + +static gboolean +get_start (gpointer user_data) +{ + Request *req = user_data; + GHashTable *setting_secrets = NULL; + + req->idle_id = 0; + + /* Check if there are any existing secrets */ + if (req->existing_secrets) + setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); + + if (setting_secrets && g_hash_table_size (setting_secrets)) { + NMConnection *tmp; + GError *error = NULL; + gboolean request_new = (req->flags & NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW); + + /* The connection already had secrets; check if any more are required. + * If no more are required, we're done. If secrets are still needed, + * ask a secret agent for more. This allows admins to provide generic + * secrets but allow additional user-specific ones as well. + */ + tmp = nm_connection_duplicate (req->connection); + g_assert (tmp); + + if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { + req_complete_error (req, error); + g_clear_error (&error); + } else { + /* Do we have everything we need? */ + /* FIXME: handle second check for VPN connections */ + if ((nm_connection_need_secrets (tmp, NULL) == NULL) && (request_new == FALSE)) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient", + req, req->setting_name); + + /* Got everything, we're done */ + req_complete_success (req, req->existing_secrets, NULL, NULL, FALSE); + } else { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", + req, req->setting_name); + + /* We don't, so ask some agents for additional secrets */ + req->next_callback (req); + } + } + g_object_unref (tmp); + } else { + /* Couldn't get secrets from system settings, so now we ask the + * agents for secrets. Let the Agent Manager handle which agents + * we'll ask and in which order. + */ + req->next_callback (req); + } + + return FALSE; +} + +static void +get_complete_cb (Request *req, + GHashTable *secrets, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + /* Send secrets back to the requesting object */ + req->callback (self, + req->reqid, + agent_dbus_owner, + agent_username, + agent_has_modify, + req->setting_name, + req->flags, + error ? NULL : secrets, + error, + req->callback_data, + req->other_data2, + req->other_data3); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); +} + +static void +get_cancel_cb (Request *req) +{ + if (req->current && req->current_call_id) + nm_secret_agent_cancel_secrets (req->current, req->current_call_id); +} + +guint32 +nm_agent_manager_get_secrets (NMAgentManager *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, + GHashTable *existing_secrets, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); + g_return_val_if_fail (callback != NULL, 0); + + nm_log_dbg (LOGD_SETTINGS, + "Secrets requested for connection %s (%s)", + nm_connection_get_path (connection), + setting_name); + + /* NOTE: a few things in the Request handling depend on existing_secrets + * being NULL if there aren't any system-owned secrets for this connection. + * This in turn depends on nm_connection_to_hash() and nm_setting_to_hash() + * both returning NULL if they didn't hash anything. + */ + + req = request_new_get (connection, + priv->authority, + filter_by_uid, + uid_filter, + existing_secrets, + setting_name, + flags, + hint, + callback, + callback_data, + other_data2, + other_data3, + get_complete_cb, + self, + get_next_cb, + get_cancel_cb); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (get_start, req); + + return req->reqid; +} + +void +nm_agent_manager_cancel_secrets (NMAgentManager *self, + guint32 request_id) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (request_id > 0); + + g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests, + GUINT_TO_POINTER (request_id)); +} + +/*************************************************************/ + +static void +save_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + const char *agent_dbus_owner; + + g_return_if_fail (call_id == req->current_call_id); + + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed save secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent saved secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); + req_complete_success (req, NULL, NULL, agent_dbus_owner, FALSE); +} + +static void +save_next_cb (Request *req) +{ + if (!next_generic (req, "saving")) + return; + + req->current_call_id = nm_secret_agent_save_secrets (NM_SECRET_AGENT (req->current), + req->connection, + save_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + req->next_callback (req); + } +} + +static void +save_complete_cb (Request *req, + GHashTable *secrets, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); +} + +guint32 +nm_agent_manager_save_secrets (NMAgentManager *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); + + nm_log_dbg (LOGD_SETTINGS, + "Saving secrets for connection %s", + nm_connection_get_path (connection)); + + req = request_new_other (connection, + filter_by_uid, + uid_filter, + save_complete_cb, + self, + save_next_cb); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (start_generic, req); + + return req->reqid; +} + +/*************************************************************/ + +static void +delete_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + + g_return_if_fail (call_id == req->current_call_id); + + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed delete secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + } else { + nm_log_dbg (LOGD_AGENTS, "(%s) agent deleted secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + } + + /* Tell the next agent to delete secrets */ + req->next_callback (req); +} + +static void +delete_next_cb (Request *req) +{ + if (!next_generic (req, "deleting")) + return; + + req->current_call_id = nm_secret_agent_delete_secrets (NM_SECRET_AGENT (req->current), + req->connection, + delete_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + req->next_callback (req); + } +} + +static void +delete_complete_cb (Request *req, + GHashTable *secrets, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); +} + +guint32 +nm_agent_manager_delete_secrets (NMAgentManager *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); + + nm_log_dbg (LOGD_SETTINGS, + "Deleting secrets for connection %s", + nm_connection_get_path (connection)); + + req = request_new_other (connection, + filter_by_uid, + uid_filter, + delete_complete_cb, + self, + delete_next_cb); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (start_generic, req); + + return req->reqid; +} + +/*************************************************************/ + +static void +name_owner_changed_cb (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + if (old_owner) { + /* The agent quit, so remove it and let interested clients know */ + remove_agent (NM_AGENT_MANAGER (user_data), old_owner); + } +} + +/*************************************************************/ + +NMAgentManager * +nm_agent_manager_get (void) +{ + static NMAgentManager *singleton = NULL; + NMAgentManagerPrivate *priv; + DBusGConnection *connection; + + if (singleton) + return g_object_ref (singleton); + + singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); + g_assert (singleton); + + priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton); + priv->session_monitor = nm_session_monitor_get (); + priv->dbus_mgr = nm_dbus_manager_get (); + + connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + dbus_g_connection_register_g_object (connection, + NM_DBUS_PATH_AGENT_MANAGER, + G_OBJECT (singleton)); + + g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed_cb), + singleton); + + return singleton; +} + +static void +nm_agent_manager_init (NMAgentManager *self) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GError *error = NULL; + + priv->authority = polkit_authority_get_sync (NULL, &error); + if (!priv->authority) { + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->requests = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) request_free); +} + +static void +dispose (GObject *object) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); + + if (!priv->disposed) { + priv->disposed = TRUE; + + g_hash_table_destroy (priv->agents); + g_hash_table_destroy (priv->requests); + + g_object_unref (priv->session_monitor); + g_object_unref (priv->dbus_mgr); + g_object_unref (priv->authority); + } + + G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); +} + +static void +nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); + + g_type_class_add_private (agent_manager_class, sizeof (NMAgentManagerPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (agent_manager_class), + &dbus_glib_nm_agent_manager_object_info); + + dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR, + NM_DBUS_INTERFACE_AGENT_MANAGER, + NM_TYPE_AGENT_MANAGER_ERROR); +} diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h new file mode 100644 index 00000000..788a9175 --- /dev/null +++ b/src/settings/nm-agent-manager.h @@ -0,0 +1,88 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#ifndef NM_AGENT_MANAGER_H +#define NM_AGENT_MANAGER_H + +#include <glib.h> +#include <glib-object.h> +#include <nm-connection.h> +#include "nm-settings-flags.h" + +#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) +#define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) +#define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) +#define NM_IS_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) +#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) +#define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) + +typedef struct { + GObject parent; +} NMAgentManager; + +typedef struct { + GObjectClass parent; +} NMAgentManagerClass; + +GType nm_agent_manager_get_type (void); + +NMAgentManager *nm_agent_manager_get (void); + +/* If no agent fulfilled the secrets request, agent_dbus_owner will be NULL */ +typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, + guint32 call_id, + const char *agent_dbus_owner, + const char *agent_uname, + gboolean agent_has_modify, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + GHashTable *secrets, + GError *error, + gpointer user_data, + gpointer other_data2, + gpointer other_data3); + +guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid, + GHashTable *existing_secrets, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3); + +void nm_agent_manager_cancel_secrets (NMAgentManager *manager, + guint32 request_id); + +guint32 nm_agent_manager_save_secrets (NMAgentManager *manager, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter); + +guint32 nm_agent_manager_delete_secrets (NMAgentManager *manager, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter); + +#endif /* NM_AGENT_MANAGER_H */ diff --git a/src/settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c new file mode 100644 index 00000000..035d851c --- /dev/null +++ b/src/settings/nm-default-wired-connection.c @@ -0,0 +1,205 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2009 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <netinet/ether.h> + +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-utils.h> + +#include "nm-dbus-glib-types.h" +#include "nm-marshal.h" +#include "nm-default-wired-connection.h" + +G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) + +typedef struct { + gboolean disposed; + NMDevice *device; + GByteArray *mac; +} NMDefaultWiredConnectionPrivate; + +enum { + PROP_0, + PROP_MAC, + PROP_DEVICE, + PROP_READ_ONLY, + LAST_PROP +}; + +enum { + TRY_UPDATE, + DELETED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/****************************************************************/ + +NMDevice * +nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired) +{ + g_return_val_if_fail (NM_IS_DEFAULT_WIRED_CONNECTION (wired), NULL); + + return NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (wired)->device; +} + +static void +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); + + /* Keep the object alive over try-update since it might get removed + * from the settings service there, but we still need it for the callback. + */ + g_object_ref (connection); + g_signal_emit (self, signals[TRY_UPDATE], 0); + callback (connection, NULL, user_data); + g_object_unref (connection); +} + +static void +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); + NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (connection); + + g_signal_emit (self, signals[DELETED], 0, priv->mac); + NM_SETTINGS_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->delete (connection, + callback, + user_data); +} + +/****************************************************************/ + +NMDefaultWiredConnection * +nm_default_wired_connection_new (const GByteArray *mac, + NMDevice *device, + const char *defname, + gboolean read_only) +{ + NMDefaultWiredConnection *self; + NMDefaultWiredConnectionPrivate *priv; + NMSetting *setting; + char *uuid; + + g_return_val_if_fail (mac != NULL, NULL); + g_return_val_if_fail (mac->len == ETH_ALEN, NULL); + g_return_val_if_fail (device != NULL, NULL); + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail (defname != NULL, NULL); + + self = (NMDefaultWiredConnection *) g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, NULL); + if (self) { + priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (self); + priv->device = device; + priv->mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (priv->mac, mac->data, mac->len); + + setting = nm_setting_connection_new (); + + uuid = nm_utils_uuid_generate (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, defname, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_READ_ONLY, read_only, + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), + NULL); + g_free (uuid); + + nm_connection_add_setting (NM_CONNECTION (self), setting); + + /* Lock the connection to the specific device */ + setting = nm_setting_wired_new (); + g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL); + nm_connection_add_setting (NM_CONNECTION (self), setting); + } + + return self; +} + +static void +nm_default_wired_connection_init (NMDefaultWiredConnection *self) +{ +} + +static void +dispose (GObject *object) +{ + NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); + + if (priv->disposed == FALSE) { + priv->disposed = TRUE; + g_object_unref (priv->device); + g_byte_array_free (priv->mac, TRUE); + } + + G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->dispose (object); +} + +static void +nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + settings_class->commit_changes = commit_changes; + settings_class->delete = do_delete; + + /* Signals */ + signals[TRY_UPDATE] = + g_signal_new ("try-update", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /* The 'deleted' signal is used to signal intentional deletions (like + * updating or user-requested deletion) rather than using the + * superclass' 'removed' signal, since that signal doesn't have the + * semantics we want; it gets emitted as a side-effect of various operations + * and is meant more for D-Bus clients instead of in-service uses. + */ + signals[DELETED] = + g_signal_new ("deleted", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} diff --git a/src/settings/nm-default-wired-connection.h b/src/settings/nm-default-wired-connection.h new file mode 100644 index 00000000..cf62d522 --- /dev/null +++ b/src/settings/nm-default-wired-connection.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2009 - 2011 Red Hat, Inc. + */ + +#ifndef NM_DEFAULT_WIRED_CONNECTION_H +#define NM_DEFAULT_WIRED_CONNECTION_H + +#include "nm-settings-connection.h" +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEFAULT_WIRED_CONNECTION (nm_default_wired_connection_get_type ()) +#define NM_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnection)) +#define NM_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) +#define NM_IS_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) +#define NM_IS_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) +#define NM_DEFAULT_WIRED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) + +typedef struct { + NMSettingsConnection parent; +} NMDefaultWiredConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMDefaultWiredConnectionClass; + +GType nm_default_wired_connection_get_type (void); + +NMDefaultWiredConnection *nm_default_wired_connection_new (const GByteArray *mac, + NMDevice *device, + const char *defname, + gboolean read_only); + +NMDevice *nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired); + +G_END_DECLS + +#endif /* NM_DEFAULT_WIRED_CONNECTION_H */ diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c new file mode 100644 index 00000000..f44fee82 --- /dev/null +++ b/src/settings/nm-inotify-helper.c @@ -0,0 +1,212 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include <unistd.h> +#include <string.h> +#include <sys/inotify.h> +#include <glib.h> + +#include "nm-marshal.h" +#include "nm-inotify-helper.h" +#include "nm-logging.h" + +G_DEFINE_TYPE (NMInotifyHelper, nm_inotify_helper, G_TYPE_OBJECT) + +#define NM_INOTIFY_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperPrivate)) + +typedef struct { + int ifd; + + GHashTable *wd_refs; +} NMInotifyHelperPrivate; + +/* Signals */ +enum { + EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +int +nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + int wd; + guint32 refcount; + + g_return_val_if_fail (priv->ifd >= 0, -1); + + /* We only care about modifications since we're just trying to get change + * notifications on hardlinks. + */ + + wd = inotify_add_watch (priv->ifd, path, IN_CLOSE_WRITE); + if (wd < 0) + return -1; + + refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); + refcount++; + g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); + + return wd; +} + +void +nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + guint32 refcount; + + g_return_if_fail (priv->ifd >= 0); + + refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); + if (!refcount) + return; + + refcount--; + if (!refcount) { + g_hash_table_remove (priv->wd_refs, GINT_TO_POINTER (wd)); + inotify_rm_watch (priv->ifd, wd); + } else + g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); +} + +static gboolean +inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_data) +{ + NMInotifyHelper *self = NM_INOTIFY_HELPER (user_data); + struct inotify_event evt; + + /* read the notifications from the watch descriptor */ + while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) { + gchar filename[PATH_MAX + 1]; + + filename[0] = '\0'; + if (evt.len > 0) { + g_io_channel_read_chars (channel, + filename, + evt.len > PATH_MAX ? PATH_MAX : evt.len, + NULL, NULL); + } + + if (!(evt.mask & IN_IGNORED)) + g_signal_emit (self, signals[EVENT], 0, &evt, &filename[0]); + } + + return TRUE; +} + +static gboolean +init_inotify (NMInotifyHelper *self) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + GIOChannel *channel; + guint source_id; + + priv->ifd = inotify_init (); + if (priv->ifd == -1) { + nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify"); + return FALSE; + } + + /* Watch the inotify descriptor for file/directory change events */ + channel = g_io_channel_unix_new (priv->ifd); + if (!channel) { + nm_log_warn (LOGD_SETTINGS, "couldn't create new GIOChannel"); + close (priv->ifd); + priv->ifd = -1; + return FALSE; + } + + g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_encoding (channel, NULL, NULL); + + source_id = g_io_add_watch (channel, + G_IO_IN | G_IO_ERR, + (GIOFunc) inotify_event_handler, + (gpointer) self); + g_io_channel_unref (channel); + return TRUE; +} + +NMInotifyHelper * +nm_inotify_helper_get (void) +{ + static NMInotifyHelper *singleton = NULL; + + if (!singleton) { + singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); + if (!singleton) + return NULL; + + if (!init_inotify (singleton)) { + g_object_unref (singleton); + return NULL; + } + } else + g_object_ref (singleton); + + g_assert (singleton); + return singleton; +} + +static void +nm_inotify_helper_init (NMInotifyHelper *self) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + + priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +static void +finalize (GObject *object) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object); + + if (priv->ifd >= 0) + close (priv->ifd); + + g_hash_table_destroy (priv->wd_refs); + + G_OBJECT_CLASS (nm_inotify_helper_parent_class)->finalize (object); +} + +static void +nm_inotify_helper_class_init (NMInotifyHelperClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + + /* Signals */ + signals[EVENT] = + g_signal_new ("event", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMInotifyHelperClass, event), + NULL, NULL, + _nm_marshal_VOID__POINTER_STRING, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING); +} + diff --git a/src/settings/nm-inotify-helper.h b/src/settings/nm-inotify-helper.h new file mode 100644 index 00000000..10d43ac9 --- /dev/null +++ b/src/settings/nm-inotify-helper.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef __INOTIFY_HELPER_H__ +#define __INOTIFY_HELPER_H__ + +#include <glib.h> +#include <glib-object.h> +#include <sys/inotify.h> + +#define NM_TYPE_INOTIFY_HELPER (nm_inotify_helper_get_type ()) +#define NM_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelper)) +#define NM_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) +#define NM_IS_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) +#define NM_IS_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) +#define NM_INOTIFY_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) + +typedef struct { + GObject parent; +} NMInotifyHelper; + +typedef struct { + GObjectClass parent; + + /* signals */ + void (* event) (NMInotifyHelper *helper, struct inotify_event *evt, const char *filename); +} NMInotifyHelperClass; + +GType nm_inotify_helper_get_type (void); + +NMInotifyHelper * nm_inotify_helper_get (void); + +int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path); + +void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd); + +#endif /* __INOTIFY_HELPER_H__ */ diff --git a/src/settings/nm-polkit-helpers.h b/src/settings/nm-polkit-helpers.h new file mode 100644 index 00000000..d812e944 --- /dev/null +++ b/src/settings/nm-polkit-helpers.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 - 2010 Red Hat, Inc. + */ + +#ifndef NM_POLKIT_HELPERS_H +#define NM_POLKIT_HELPERS_H + +#include <polkit/polkit.h> + +/* Fix for polkit 0.97 and later */ +#if !HAVE_POLKIT_AUTHORITY_GET_SYNC +static inline PolkitAuthority * +polkit_authority_get_sync (GCancellable *cancellable, GError **error) +{ + PolkitAuthority *authority; + + authority = polkit_authority_get (); + if (!authority) + g_set_error (error, 0, 0, "failed to get the PolicyKit authority"); + return authority; +} +#endif + +#endif /* NM_POLKIT_HELPERS_H */ diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c new file mode 100644 index 00000000..2b1156cb --- /dev/null +++ b/src/settings/nm-secret-agent.c @@ -0,0 +1,398 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#include <config.h> + +#include <glib.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "NetworkManager.h" +#include "nm-secret-agent.h" +#include "nm-dbus-glib-types.h" + +G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) + +#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SECRET_AGENT, \ + NMSecretAgentPrivate)) + +typedef struct { + gboolean disposed; + + char *description; + char *owner; + char *identifier; + uid_t owner_uid; + guint32 hash; + + NMDBusManager *dbus_mgr; + DBusGProxy *proxy; + + GHashTable *requests; +} NMSecretAgentPrivate; + +/*************************************************************/ + +typedef struct { + NMSecretAgent *agent; + DBusGProxyCall *call; + char *path; + char *setting_name; + NMSecretAgentCallback callback; + gpointer callback_data; +} Request; + +static Request * +request_new (NMSecretAgent *agent, + const char *path, + const char *setting_name, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + Request *r; + + r = g_slice_new0 (Request); + r->agent = agent; + r->path = g_strdup (path); + r->setting_name = g_strdup (setting_name); + r->callback = callback; + r->callback_data = callback_data; + return r; +} + +static void +request_free (Request *r) +{ + g_free (r->path); + g_free (r->setting_name); + g_slice_free (Request, r); +} + +/*************************************************************/ + +const char * +nm_secret_agent_get_description (NMSecretAgent *agent) +{ + NMSecretAgentPrivate *priv; + + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE (agent); + if (!priv->description) { + priv->description = g_strdup_printf ("%s/%s/%u", + priv->owner, + priv->identifier, + priv->owner_uid); + } + + return priv->description; +} + +const char * +nm_secret_agent_get_dbus_owner (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner; +} + +const char * +nm_secret_agent_get_identifier (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->identifier; +} + +uid_t +nm_secret_agent_get_owner_uid (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, G_MAXUINT); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXUINT); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner_uid; +} + +guint32 +nm_secret_agent_get_hash (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, 0); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), 0); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->hash; +} + +/*************************************************************/ + +static void +get_callback (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) +{ + Request *r = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); + GError *error = NULL; + GHashTable *secrets = NULL; + + g_return_if_fail (call == r->call); + + dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, + G_TYPE_INVALID); + r->callback (r->agent, r->call, secrets, error, r->callback_data); + if (secrets) + g_hash_table_unref (secrets); + g_clear_error (&error); + g_hash_table_remove (priv->requests, call); +} + +gconstpointer +nm_secret_agent_get_secrets (NMSecretAgent *self, + NMConnection *connection, + const char *setting_name, + const char *hint, + NMSettingsGetSecretsFlags flags, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + NMSecretAgentPrivate *priv; + GHashTable *hash; + const char *hints[2] = { hint, NULL }; + Request *r; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (setting_name != NULL, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); + r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "GetSecrets", + get_callback, + r, + NULL, + 120000, /* 120 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), + G_TYPE_STRING, setting_name, + G_TYPE_STRV, hints, + G_TYPE_UINT, flags, + G_TYPE_INVALID); + g_hash_table_insert (priv->requests, r->call, r); + + g_hash_table_destroy (hash); + return r->call; +} + +void +nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call) +{ + NMSecretAgentPrivate *priv; + Request *r; + + g_return_if_fail (self != NULL); + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + r = g_hash_table_lookup (priv->requests, call); + g_return_if_fail (r != NULL); + + dbus_g_proxy_cancel_call (NM_SECRET_AGENT_GET_PRIVATE (self)->proxy, (gpointer) call); + + dbus_g_proxy_call_no_reply (priv->proxy, + "CancelGetSecrets", + G_TYPE_STRING, r->path, + G_TYPE_STRING, r->setting_name, + G_TYPE_INVALID); + g_hash_table_remove (priv->requests, call); +} + +/*************************************************************/ + +static void +agent_save_delete_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) +{ + Request *r = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); + GError *error = NULL; + + g_return_if_fail (call == r->call); + + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + r->callback (r->agent, r->call, NULL, error, r->callback_data); + g_clear_error (&error); + g_hash_table_remove (priv->requests, call); +} + +static gpointer +agent_new_save_delete (NMSecretAgent *self, + NMConnection *connection, + NMSettingHashFlags hash_flags, + const char *method, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GHashTable *hash; + Request *r; + const char *cpath = nm_connection_get_path (connection); + + hash = nm_connection_to_hash (connection, hash_flags); + + r = request_new (self, cpath, NULL, callback, callback_data); + r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + method, + agent_save_delete_cb, + r, + NULL, + 10000, /* 10 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, cpath, + G_TYPE_INVALID); + g_hash_table_insert (priv->requests, r->call, r); + + g_hash_table_destroy (hash); + return r->call; +} + +gconstpointer +nm_secret_agent_save_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + + /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ + return agent_new_save_delete (self, + connection, + NM_SETTING_HASH_FLAG_ALL, + "SaveSecrets", + callback, + callback_data); +} + +gconstpointer +nm_secret_agent_delete_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + + /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ + return agent_new_save_delete (self, + connection, + NM_SETTING_HASH_FLAG_NO_SECRETS, + "DeleteSecrets", + callback, + callback_data); +} + +/*************************************************************/ + +NMSecretAgent * +nm_secret_agent_new (NMDBusManager *dbus_mgr, + const char *owner, + const char *identifier, + uid_t owner_uid) +{ + NMSecretAgent *self; + NMSecretAgentPrivate *priv; + DBusGConnection *bus; + char *hash_str; + + g_return_val_if_fail (owner != NULL, NULL); + g_return_val_if_fail (identifier != NULL, NULL); + + self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); + if (self) { + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->owner = g_strdup (owner); + priv->identifier = g_strdup (identifier); + priv->owner_uid = owner_uid; + + hash_str = g_strdup_printf ("%08u%s", owner_uid, identifier); + priv->hash = g_str_hash (hash_str); + g_free (hash_str); + + priv->dbus_mgr = g_object_ref (dbus_mgr); + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (bus, + owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT); + g_assert (priv->proxy); + } + + return self; +} + +static void +nm_secret_agent_init (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->requests = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) request_free); +} + +static void +dispose (GObject *object) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); + + if (!priv->disposed) { + priv->disposed = TRUE; + + g_free (priv->description); + g_free (priv->owner); + g_free (priv->identifier); + + g_hash_table_destroy (priv->requests); + g_object_unref (priv->proxy); + g_object_unref (priv->dbus_mgr); + } + + G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); +} + +static void +nm_secret_agent_class_init (NMSecretAgentClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMSecretAgentPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; +} + diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h new file mode 100644 index 00000000..597940b4 --- /dev/null +++ b/src/settings/nm-secret-agent.h @@ -0,0 +1,92 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#ifndef NM_SECRET_AGENT_H +#define NM_SECRET_AGENT_H + +#include <glib.h> +#include <glib-object.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <nm-connection.h> +#include "nm-dbus-manager.h" +#include "nm-settings-flags.h" + +#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) +#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) +#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) +#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) + +typedef struct { + GObject parent; +} NMSecretAgent; + +typedef struct { + GObjectClass parent; +} NMSecretAgentClass; + +GType nm_secret_agent_get_type (void); + +NMSecretAgent *nm_secret_agent_new (NMDBusManager *dbus_mgr, + const char *owner, + const char *identifier, + uid_t owner_uid); + +const char *nm_secret_agent_get_description (NMSecretAgent *agent); + +const char *nm_secret_agent_get_dbus_owner (NMSecretAgent *agent); + +const char *nm_secret_agent_get_identifier (NMSecretAgent *agent); + +uid_t nm_secret_agent_get_owner_uid (NMSecretAgent *agent); + +guint32 nm_secret_agent_get_hash (NMSecretAgent *agent); + +typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent, + gconstpointer call, + GHashTable *new_secrets, /* NULL for save & delete */ + GError *error, + gpointer user_data); + +gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, + NMConnection *connection, + const char *setting_name, + const char *hint, + NMSettingsGetSecretsFlags flags, + NMSecretAgentCallback callback, + gpointer callback_data); + +void nm_secret_agent_cancel_secrets (NMSecretAgent *agent, + gconstpointer call_id); + +gconstpointer nm_secret_agent_save_secrets (NMSecretAgent *agent, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data); + +gconstpointer nm_secret_agent_delete_secrets (NMSecretAgent *agent, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data); + +#endif /* NM_SECRET_AGENT_H */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c new file mode 100644 index 00000000..22aef716 --- /dev/null +++ b/src/settings/nm-settings-connection.c @@ -0,0 +1,1510 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> + +#include <NetworkManager.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <nm-setting-connection.h> +#include <nm-setting-vpn.h> +#include <nm-utils.h> + +#include "nm-settings-connection.h" +#include "nm-session-monitor.h" +#include "nm-dbus-manager.h" +#include "nm-settings-error.h" +#include "nm-dbus-glib-types.h" +#include "nm-polkit-helpers.h" +#include "nm-logging.h" +#include "nm-manager-auth.h" +#include "nm-marshal.h" +#include "nm-agent-manager.h" + +#define SETTINGS_TIMESTAMPS_FILE LOCALSTATEDIR"/lib/NetworkManager/timestamps" + +static void impl_settings_connection_get_settings (NMSettingsConnection *connection, + DBusGMethodInvocation *context); + +static void impl_settings_connection_update (NMSettingsConnection *connection, + GHashTable *new_settings, + DBusGMethodInvocation *context); + +static void impl_settings_connection_delete (NMSettingsConnection *connection, + DBusGMethodInvocation *context); + +static void impl_settings_connection_get_secrets (NMSettingsConnection *connection, + const gchar *setting_name, + DBusGMethodInvocation *context); + +#include "nm-settings-connection-glue.h" + +G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_CONNECTION) + +#define NM_SETTINGS_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SETTINGS_CONNECTION, \ + NMSettingsConnectionPrivate)) + +enum { + PROP_0 = 0, + PROP_VISIBLE, +}; + +enum { + UPDATED, + REMOVED, + UNREGISTER, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef struct { + gboolean disposed; + + NMDBusManager *dbus_mgr; + NMAgentManager *agent_mgr; + + PolkitAuthority *authority; + GSList *pending_auths; /* List of pending authentication requests */ + NMConnection *secrets; + gboolean visible; /* Is this connection is visible by some session? */ + + GSList *reqs; /* in-progress secrets requests */ + + NMSessionMonitor *session_monitor; + guint session_changed_id; + + guint64 timestamp; /* Up-to-date timestamp of connection use */ +} NMSettingsConnectionPrivate; + +/**************************************************************/ + +static void +set_visible (NMSettingsConnection *self, gboolean new_visible) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if (new_visible == priv->visible) + return; + priv->visible = new_visible; + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_VISIBLE); +} + +gboolean +nm_settings_connection_is_visible (NMSettingsConnection *self) +{ + g_return_val_if_fail (NM_SETTINGS_CONNECTION (self), FALSE); + + return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible; +} + +void +nm_settings_connection_recheck_visibility (NMSettingsConnection *self) +{ + NMSettingsConnectionPrivate *priv; + NMSettingConnection *s_con; + guint32 num, i; + + g_return_if_fail (NM_SETTINGS_CONNECTION (self)); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + /* Check every user in the ACL for a session */ + num = nm_setting_connection_get_num_permissions (s_con); + if (num == 0) { + /* Visible to all */ + set_visible (self, TRUE); + return; + } + + for (i = 0; i < num; i++) { + const char *puser; + + if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) { + if (nm_session_monitor_user_has_session (priv->session_monitor, puser, NULL, NULL)) { + set_visible (self, TRUE); + return; + } + } + } + + set_visible (self, FALSE); +} + +static void +session_changed_cb (NMSessionMonitor *self, gpointer user_data) +{ + nm_settings_connection_recheck_visibility (NM_SETTINGS_CONNECTION (user_data)); +} + +/**************************************************************/ + +static void +only_system_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* VPNs are special; need to handle each secret separately */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } + } +} + +static void +update_secrets_cache (NMSettingsConnection *self) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if (priv->secrets) + g_object_unref (priv->secrets); + priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + + /* Clear out non-system-owned and not-saved secrets */ + nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL); +} + +/* Update the settings of this connection to match that of 'new', taking care to + * make a private copy of secrets. */ +gboolean +nm_settings_connection_replace_settings (NMSettingsConnection *self, + NMConnection *new, + GError **error) +{ + NMSettingsConnectionPrivate *priv; + GHashTable *new_settings; + gboolean success = FALSE; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail (new != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (new), FALSE); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL); + g_assert (new_settings); + if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) { + /* Copy the connection to keep its secrets around even if NM + * calls nm_connection_clear_secrets(). + */ + update_secrets_cache (self); + + nm_settings_connection_recheck_visibility (self); + success = TRUE; + } + g_hash_table_destroy (new_settings); + return success; +} + +static void +ignore_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ +} + +/* Replaces the settings in this connection with those in 'new'. If any changes + * are made, commits them to permanent storage and to any other subsystems + * watching this connection. Before returning, 'callback' is run with the given + * 'user_data' along with any errors encountered. + */ +void +nm_settings_connection_replace_and_commit (NMSettingsConnection *self, + NMConnection *new, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + GError *error = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + g_return_if_fail (new != NULL); + g_return_if_fail (NM_IS_CONNECTION (new)); + + if (!callback) + callback = ignore_cb; + + /* Do nothing if there's nothing to update */ + if (nm_connection_compare (NM_CONNECTION (self), + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_EXACT)) { + callback (self, NULL, user_data); + return; + } + + if (nm_settings_connection_replace_settings (self, new, &error)) { + nm_settings_connection_commit_changes (self, callback, user_data); + } else { + callback (self, error, user_data); + g_clear_error (&error); + } +} + +void +nm_settings_connection_commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes) { + NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes (connection, + callback, + user_data); + } else { + GError *error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__); + callback (connection, error, user_data); + g_error_free (error); + } +} + +void +nm_settings_connection_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete) { + NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete (connection, + callback, + user_data); + } else { + GError *error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); + callback (connection, error, user_data); + g_error_free (error); + } +} + +static void +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + g_object_ref (connection); + g_signal_emit (connection, signals[UPDATED], 0); + callback (connection, NULL, user_data); + g_object_unref (connection); +} + +static void +remove_timestamp_from_db (NMSettingsConnection *connection) +{ + GKeyFile *timestamps_file; + + timestamps_file = g_key_file_new (); + if (g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL)) { + const char *connection_uuid; + char *data; + gsize len; + GError *error = NULL; + + connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); + + g_key_file_remove_key (timestamps_file, "timestamps", connection_uuid, NULL); + data = g_key_file_to_data (timestamps_file, &len, &error); + if (data) { + g_file_set_contents (SETTINGS_TIMESTAMPS_FILE, data, len, &error); + g_free (data); + } + if (error) { + nm_log_warn (LOGD_SETTINGS, "error writing timestamps file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message); + g_error_free (error); + } + } + g_key_file_free (timestamps_file); +} + +static void +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + NMConnection *for_agents; + + g_object_ref (connection); + set_visible (connection, FALSE); + + /* Tell agents to remove secrets for this connection */ + for_agents = nm_connection_duplicate (NM_CONNECTION (connection)); + nm_connection_clear_secrets (for_agents); + nm_agent_manager_delete_secrets (priv->agent_mgr, for_agents, FALSE, 0); + + /* Remove timestamp from timestamps database file */ + remove_timestamp_from_db (connection); + + /* Signal the connection is removed and deleted */ + g_signal_emit (connection, signals[REMOVED], 0); + callback (connection, NULL, user_data); + g_object_unref (connection); +} + +/**************************************************************/ + +static gboolean +supports_secrets (NMSettingsConnection *connection, const char *setting_name) +{ + /* All secrets supported */ + return TRUE; +} + +/* Return TRUE to continue, FALSE to stop */ +typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data); + +static gboolean +clear_nonagent_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + if (flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_hash_table_iter_remove (iter); + return TRUE; +} + +static gboolean +clear_unsaved_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + g_hash_table_iter_remove (iter); + return TRUE; +} + +static gboolean +has_system_owned_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + gboolean *has_system_owned = user_data; + + if (!(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) { + *has_system_owned = TRUE; + return FALSE; + } + return TRUE; +} + +static void +for_each_secret (NMConnection *connection, + GHashTable *secrets, + ForEachSecretFunc callback, + gpointer callback_data) +{ + GHashTableIter iter; + const char *setting_name; + GHashTable *setting_hash; + + /* Walk through the list of setting hashes */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_hash)) { + GHashTableIter setting_iter; + const char *secret_name; + + /* Walk through the list of keys in each setting hash */ + g_hash_table_iter_init (&setting_iter, setting_hash); + while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) { + NMSetting *setting; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Get the actual NMSetting from the connection so we can get secret flags */ + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (setting && nm_setting_get_secret_flags (setting, secret_name, &flags, NULL)) { + if (callback (&setting_iter, flags, callback_data) == FALSE) + return; + } + } + } +} + +static void +new_secrets_commit_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ + if (error) { + nm_log_warn (LOGD_SETTINGS, "Error saving new secrets to backing storage: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); + } +} + +static void +agent_secrets_done_cb (NMAgentManager *manager, + guint32 call_id, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + GHashTable *secrets, + GError *error, + gpointer user_data, + gpointer other_data2, + gpointer other_data3) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionSecretsFunc callback = other_data2; + gpointer callback_data = other_data3; + GError *local = NULL; + GHashTable *hash; + gboolean agent_had_system = FALSE; + + if (error) { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request error: (%d) %s", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + error->code, + error->message ? error->message : "(unknown)"); + + callback (self, call_id, NULL, setting_name, error, callback_data); + return; + } + + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { + local = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + callback (self, call_id, NULL, setting_name, local, callback_data); + g_clear_error (&local); + return; + } + + g_assert (secrets); + if (agent_dbus_owner) { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets returned from agent %s", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + agent_dbus_owner); + + /* If the agent returned any system-owned secrets (initial connect and no + * secrets given when the connection was created, or something like that) + * make sure the agent's UID has the 'modify' permission before we use or + * save those system-owned secrets. If not, discard them and use the + * existing secrets, or fail the connection. + */ + for_each_secret (NM_CONNECTION (self), secrets, has_system_owned_secrets, &agent_had_system); + if (agent_had_system) { + if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE) { + /* No user interaction was allowed when requesting secrets; the + * agent is being bad. Remove system-owned secrets. + */ + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) interaction forbidden but agent %s returned system secrets", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + agent_dbus_owner); + + for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); + } else if (agent_has_modify == FALSE) { + /* Agent didn't successfully authenticate; clear system-owned secrets + * from the secrets the agent returned. + */ + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate but provided system secrets", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id); + + for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); + } + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) existing secrets returned", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id); + } + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id); + + /* If no user interaction was allowed, make sure that no "unsaved" secrets + * came back. Unsaved secrets by definition require user interaction. + */ + if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE) + for_each_secret (NM_CONNECTION (self), secrets, clear_unsaved_secrets, NULL); + + /* Update the connection with our existing secrets from backing storage */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + /* Update the connection with the agent's secrets; by this point if any + * system-owned secrets exist in 'secrets' the agent that provided them + * will have been authenticated, so those secrets can replace the existing + * system secrets. + */ + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + /* Now that all secrets are updated, copy and cache new secrets, + * then save them to backing storage. + */ + update_secrets_cache (self); + + /* Only save secrets to backing storage if the agent returned any + * new system secrets. If it didn't, then the secrets are agent- + * owned and there's no point to writing out the connection when + * nothing has changed, since agent-owned secrets don't get saved here. + */ + if (agent_had_system) { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id); + + nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL); + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) new agent secrets processed", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id); + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); + } + + callback (self, call_id, agent_username, setting_name, local, callback_data); + g_clear_error (&local); + if (hash) + g_hash_table_destroy (hash); +} + +/** + * nm_settings_connection_get_secrets: + * @connection: the #NMSettingsConnection + * @filter_by_uid: if TRUE, only request secrets from agents registered by the + * same UID as @uid. + * @uid: when @filter_by_uid is TRUE, only request secrets from agents belonging + * to this UID + * @setting_name: the setting to return secrets for + * @flags: flags to modify the secrets request + * @hint: the name of a key in @setting_name for which a secret may be required + * @callback: the function to call with returned secrets + * @callback_data: user data to pass to @callback + * + * Retrieves secrets from persistent storage and queries any secret agents for + * additional secrets. + * + * Returns: a call ID which may be used to cancel the ongoing secrets request + **/ +guint32 +nm_settings_connection_get_secrets (NMSettingsConnection *self, + gboolean filter_by_uid, + gulong uid, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, + GError **error) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GHashTable *existing_secrets; + guint32 call_id = 0; + + /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() + * will clear secrets on this object's settings. priv->secrets should be + * a complete copy of this object and kept in sync by + * nm_settings_connection_replace_settings(). + */ + if (!priv->secrets) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "%s.%d - Internal error; secrets cache invalid.", + __FILE__, __LINE__); + return 0; + } + + /* Make sure the request actually requests something we can return */ + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + return 0; + } + + existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + NM_CONNECTION (self), + filter_by_uid, + uid, + existing_secrets, + setting_name, + flags, + hint, + agent_secrets_done_cb, + self, + callback, + callback_data); + if (existing_secrets) + g_hash_table_unref (existing_secrets); + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets requested flags 0x%X hint '%s'", + nm_connection_get_uuid (NM_CONNECTION (self)), + setting_name, + call_id, + flags, + hint); + + return call_id; +} + +void +nm_settings_connection_cancel_secrets (NMSettingsConnection *self, + guint32 call_id) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + nm_log_dbg (LOGD_SETTINGS, "(%s:%u) secrets canceled", + nm_connection_get_uuid (NM_CONNECTION (self)), + call_id); + + priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); +} + +/**** User authorization **************************************/ + +typedef void (*AuthCallback) (NMSettingsConnection *connection, + DBusGMethodInvocation *context, + gulong sender_uid, + GError *error, + gpointer data); + +static void +pk_auth_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + NMAuthCallResult result; + const char *perm; + AuthCallback callback; + gpointer callback_data; + gulong sender_uid; + + priv->pending_auths = g_slist_remove (priv->pending_auths, chain); + + /* If our NMSettingsConnection is already gone, do nothing */ + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + } else { + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); + + /* Caller didn't successfully authenticate */ + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); + } + } + + callback = nm_auth_chain_get_data (chain, "callback"); + callback_data = nm_auth_chain_get_data (chain, "callback-data"); + sender_uid = nm_auth_chain_get_data_ulong (chain, "sender-uid"); + callback (self, context, sender_uid, error, callback_data); + + g_clear_error (&error); + nm_auth_chain_unref (chain); +} + +static gboolean +check_user_in_acl (NMConnection *connection, + DBusGMethodInvocation *context, + NMDBusManager *dbus_mgr, + NMSessionMonitor *session_monitor, + gulong *out_sender_uid, + GError **error) +{ + gulong sender_uid = G_MAXULONG; + char *error_desc = NULL; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (session_monitor != NULL, FALSE); + + /* Get the caller's UID */ + if (!nm_auth_get_caller_uid (context, dbus_mgr, &sender_uid, &error_desc)) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + return FALSE; + } + + /* Make sure the UID can view this connection */ + if (0 != sender_uid) { + if (!nm_auth_uid_in_acl (connection, session_monitor, sender_uid, &error_desc)) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + return FALSE; + } + } + + if (out_sender_uid) + *out_sender_uid = sender_uid; + return TRUE; +} + +static void +auth_start (NMSettingsConnection *self, + DBusGMethodInvocation *context, + const char *check_permission, + AuthCallback callback, + gpointer callback_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMAuthChain *chain; + gulong sender_uid = G_MAXULONG; + GError *error = NULL; + + if (!check_user_in_acl (NM_CONNECTION (self), + context, + priv->dbus_mgr, + priv->session_monitor, + &sender_uid, + &error)) { + callback (self, context, G_MAXULONG, error, callback_data); + g_clear_error (&error); + return; + } + + if (check_permission) { + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); + g_assert (chain); + nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + nm_auth_chain_set_data_ulong (chain, "sender-uid", sender_uid); + + nm_auth_chain_add_call (chain, check_permission, TRUE); + priv->pending_auths = g_slist_append (priv->pending_auths, chain); + } else { + /* Don't need polkit auth, automatic success */ + callback (self, context, sender_uid, NULL, callback_data); + } +} + +/**** DBus method handlers ************************************/ + +static gboolean +check_writable (NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (!s_con) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Connection did not have required 'connection' setting"); + return FALSE; + } + + /* If the connection is read-only, that has to be changed at the source of + * the problem (ex a system settings plugin that can't write connections out) + * instead of over D-Bus. + */ + if (nm_setting_connection_get_read_only (s_con)) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, + "Connection is read-only"); + return FALSE; + } + + return TRUE; +} + +static void +get_settings_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + gulong sender_uid, + GError *error, + gpointer data) +{ + if (error) + dbus_g_method_return_error (context, error); + else { + GHashTable *settings; + NMConnection *dupl_con; + NMSettingConnection *s_con; + guint64 timestamp; + + dupl_con = nm_connection_duplicate (NM_CONNECTION (self)); + g_assert (dupl_con); + + /* Timestamp is not updated in connection's 'timestamp' property, + * because it would force updating the connection and in turn + * writing to /etc periodically, which we want to avoid. Rather real + * timestamps are kept track of in a private variable. So, substitute + * timestamp property with the real one here before returning the settings. + */ + timestamp = nm_settings_connection_get_timestamp (self); + if (timestamp) { + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (dupl_con), NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL); + } + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + settings = nm_connection_to_hash (NM_CONNECTION (dupl_con), NM_SETTING_HASH_FLAG_NO_SECRETS); + g_assert (settings); + dbus_g_method_return (context, settings); + g_hash_table_destroy (settings); + g_object_unref (dupl_con); + } +} + +static void +impl_settings_connection_get_settings (NMSettingsConnection *self, + DBusGMethodInvocation *context) +{ + auth_start (self, context, NULL, get_settings_auth_cb, NULL); +} + +static void +con_update_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + +static void +only_agent_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Clear out system-owned or always-ask secrets */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + /* VPNs are special; need to handle each secret separately */ + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } + } +} + +static void +update_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + gulong sender_uid, + GError *error, + gpointer data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMConnection *new_settings = data; + NMConnection *for_agent; + + if (error) + dbus_g_method_return_error (context, error); + else { + /* Update and commit our settings. */ + nm_settings_connection_replace_and_commit (self, + new_settings, + con_update_cb, + context); + + /* Dupe the connection and clear out non-agent-owned secrets so we can + * send the agent-owned ones to agents to be saved. Only send them to + * agents of the same UID as the Update() request sender. + */ + for_agent = nm_connection_duplicate (NM_CONNECTION (self)); + nm_connection_for_each_setting_value (for_agent, only_agent_secrets_cb, NULL); + nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, sender_uid); + g_object_unref (for_agent); + } + + g_object_unref (new_settings); +} + +static const char * +get_modify_permission_update (NMConnection *old, NMConnection *new) +{ + NMSettingConnection *s_con; + guint32 orig_num = 0, new_num = 0; + + s_con = (NMSettingConnection *) nm_connection_get_setting (old, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + orig_num = nm_setting_connection_get_num_permissions (s_con); + + s_con = (NMSettingConnection *) nm_connection_get_setting (new, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + new_num = nm_setting_connection_get_num_permissions (s_con); + + /* If the caller is the only user in either connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. + */ + if (orig_num == 1 && new_num == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + + /* If the update request affects more than just the caller (ie if the old + * settings were system-wide, or the new ones are), require 'modify.system'. + */ + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; +} + +static void +impl_settings_connection_update (NMSettingsConnection *self, + GHashTable *new_settings, + DBusGMethodInvocation *context) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMConnection *tmp; + GError *error = NULL; + + /* If the connection is read-only, that has to be changed at the source of + * the problem (ex a system settings plugin that can't write connections out) + * instead of over D-Bus. + */ + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Check if the settings are valid first */ + tmp = nm_connection_new_from_hash (new_settings, &error); + if (!tmp) { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* And that the new connection settings will be visible to the user + * that's sending the update request. You can't make a connection + * invisible to yourself. + */ + if (!check_user_in_acl (tmp, + context, + priv->dbus_mgr, + priv->session_monitor, + NULL, + &error)) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_object_unref (tmp); + return; + } + + auth_start (self, + context, + get_modify_permission_update (NM_CONNECTION (self), tmp), + update_auth_cb, + tmp); +} + +static void +con_delete_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + +static void +delete_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + gulong sender_uid, + GError *error, + gpointer data) +{ + if (error) { + dbus_g_method_return_error (context, error); + return; + } + + nm_settings_connection_delete (self, con_delete_cb, context); +} + +static const char * +get_modify_permission_basic (NMSettingsConnection *connection) +{ + NMSettingConnection *s_con; + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; +} + +static void +impl_settings_connection_delete (NMSettingsConnection *self, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + auth_start (self, context, get_modify_permission_basic (self), delete_auth_cb, NULL); +} + +/**************************************************************/ + +static void +dbus_get_agent_secrets_cb (NMSettingsConnection *self, + guint32 call_id, + const char *agent_username, + const char *setting_name, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + DBusGMethodInvocation *context = user_data; + GHashTable *hash; + + priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); + + if (error) + dbus_g_method_return_error (context, error); + else { + /* The connection's secrets will have been updated by the agent manager, + * so we want to refresh the secrets cache. Note that we will never save + * new secrets to backing storage here because D-Bus initated requests will + * never ask for completely new secrets from agents. Thus system-owned + * secrets should not have changed from backing storage. We also don't + * send agent-owned secrets back out to be saved since we assume the agent + * that provided the secrets saved them itself. + */ + update_secrets_cache (self); + + hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS); + dbus_g_method_return (context, hash); + g_hash_table_destroy (hash); + } +} + +static void +dbus_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + gulong sender_uid, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + char *setting_name = user_data; + guint32 call_id = 0; + GError *local = NULL; + + if (!error) { + call_id = nm_settings_connection_get_secrets (self, + TRUE, + sender_uid, + setting_name, + NM_SETTINGS_GET_SECRETS_FLAG_NONE, + NULL, + dbus_get_agent_secrets_cb, + context, + &local); + if (call_id > 0) { + /* track the request and wait for the callback */ + priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); + } + } + + if (error || local) { + dbus_g_method_return_error (context, error ? error : local); + g_clear_error (&local); + } + + g_free (setting_name); +} + +static void +impl_settings_connection_get_secrets (NMSettingsConnection *self, + const gchar *setting_name, + DBusGMethodInvocation *context) +{ + auth_start (self, + context, + get_modify_permission_basic (self), + dbus_secrets_auth_cb, + g_strdup (setting_name)); +} + +/**************************************************************/ + +void +nm_settings_connection_signal_remove (NMSettingsConnection *self) +{ + /* Emit removed first */ + g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED); + + /* And unregistered last to ensure the removed signal goes out before + * we take the connection off the bus. + */ + g_signal_emit_by_name (self, "unregister"); +} + +/** + * nm_settings_connection_get_timestamp: + * @connection: the #NMSettingsConnection + * + * Returns current connection's timestamp. + * + * Returns: timestamp of the last connection use (0 when it's not used) + **/ +guint64 +nm_settings_connection_get_timestamp (NMSettingsConnection *connection) +{ + g_return_val_if_fail (NM_SETTINGS_CONNECTION (connection), 0); + + return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->timestamp; +} + +/** + * nm_settings_connection_update_timestamp: + * @connection: the #NMSettingsConnection + * @timestamp: timestamp to set into the connection and to store into + * the timestamps database + * + * Updates the connection and timestamps database with the provided timestamp. + **/ +void +nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + const char *connection_uuid; + GKeyFile *timestamps_file; + char *data, *tmp; + gsize len; + GError *error = NULL; + + /* Update timestamp in private storage */ + priv->timestamp = timestamp; + + /* Save timestamp to timestamps database file */ + timestamps_file = g_key_file_new (); + if (!g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, &error)) { + if (!(error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT)) + nm_log_warn (LOGD_SETTINGS, "error parsing timestamps file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message); + g_clear_error (&error); + } + + connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); + tmp = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp); + g_key_file_set_value (timestamps_file, "timestamps", connection_uuid, tmp); + g_free (tmp); + + data = g_key_file_to_data (timestamps_file, &len, &error); + if (data) { + g_file_set_contents (SETTINGS_TIMESTAMPS_FILE, data, len, &error); + g_free (data); + } + if (error) { + nm_log_warn (LOGD_SETTINGS, "error saving timestamp to file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message); + g_error_free (error); + } + g_key_file_free (timestamps_file); +} + +/** + * nm_settings_connection_read_and_fill_timestamp: + * @connection: the #NMSettingsConnection + * + * Retrieves timestamp of the connection's last usage from database file and + * stores it into the connection private data. + **/ +void +nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + const char *connection_uuid; + guint64 timestamp = 0; + GKeyFile *timestamps_file; + GError *err = NULL; + char *tmp_str; + + /* Get timestamp from database file */ + timestamps_file = g_key_file_new (); + g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL); + connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); + tmp_str = g_key_file_get_value (timestamps_file, "timestamps", connection_uuid, &err); + if (tmp_str) { + timestamp = g_ascii_strtoull (tmp_str, NULL, 10); + g_free (tmp_str); + } + + /* Update connection's timestamp */ + if (!err) + priv->timestamp = timestamp; + else { + nm_log_dbg (LOGD_SETTINGS, "failed to read connection timestamp for '%s': (%d) %s", + connection_uuid, err->code, err->message); + g_clear_error (&err); + } + g_key_file_free (timestamps_file); +} + +/**************************************************************/ + +static void +nm_settings_connection_init (NMSettingsConnection *self) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + static guint32 dbus_counter = 0; + char *dbus_path; + GError *error = NULL; + + priv->dbus_mgr = nm_dbus_manager_get (); + + priv->authority = polkit_authority_get_sync (NULL, &error); + if (!priv->authority) { + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++); + nm_connection_set_path (NM_CONNECTION (self), dbus_path); + g_free (dbus_path); + priv->visible = FALSE; + + priv->session_monitor = nm_session_monitor_get (); + priv->session_changed_id = g_signal_connect (priv->session_monitor, + NM_SESSION_MONITOR_CHANGED, + G_CALLBACK (session_changed_cb), + self); + + priv->agent_mgr = nm_agent_manager_get (); +} + +static void +dispose (GObject *object) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GSList *iter; + + if (priv->disposed) + goto out; + priv->disposed = TRUE; + + if (priv->secrets) + g_object_unref (priv->secrets); + + /* Cancel PolicyKit requests */ + for (iter = priv->pending_auths; iter; iter = g_slist_next (iter)) + nm_auth_chain_unref ((NMAuthChain *) iter->data); + g_slist_free (priv->pending_auths); + priv->pending_auths = NULL; + + /* Cancel in-progress secrets requests */ + for (iter = priv->reqs; iter; iter = g_slist_next (iter)) + nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data)); + g_slist_free (priv->reqs); + + set_visible (self, FALSE); + + g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); + g_object_unref (priv->dbus_mgr); + g_object_unref (priv->authority); + +out: + G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_VISIBLE: + g_value_set_boolean (value, NM_SETTINGS_CONNECTION_GET_PRIVATE (object)->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static void +nm_settings_connection_class_init (NMSettingsConnectionClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (NMSettingsConnectionPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + class->commit_changes = commit_changes; + class->delete = do_delete; + class->supports_secrets = supports_secrets; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_VISIBLE, + g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE, + "Visible", + "Visible", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + signals[UPDATED] = + g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[REMOVED] = + g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /* Not exported */ + signals[UNREGISTER] = + g_signal_new ("unregister", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), + &dbus_glib_nm_settings_connection_object_info); +} diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h new file mode 100644 index 00000000..116bfdcc --- /dev/null +++ b/src/settings/nm-settings-connection.h @@ -0,0 +1,129 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTINGS_CONNECTION_H +#define NM_SETTINGS_CONNECTION_H + +#include <nm-connection.h> +#include "nm-settings-flags.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) +#define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection)) +#define NM_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) +#define NM_IS_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) + +#define NM_SETTINGS_CONNECTION_UPDATED "updated" +#define NM_SETTINGS_CONNECTION_REMOVED "removed" +#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" +#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" + +#define NM_SETTINGS_CONNECTION_VISIBLE "visible" + +typedef struct _NMSettingsConnection NMSettingsConnection; + +typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; + +typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection, + GError *error, + gpointer user_data); + +struct _NMSettingsConnection { + NMConnection parent; +}; + +struct _NMSettingsConnectionClass { + NMConnectionClass parent; + + /* virtual methods */ + void (*commit_changes) (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + + void (*delete) (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data); + + gboolean (*supports_secrets) (NMSettingsConnection *connection, + const char *setting_name); +}; + +GType nm_settings_connection_get_type (void); + +void nm_settings_connection_commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + +gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self, + NMConnection *new_settings, + GError **error); + +void nm_settings_connection_replace_and_commit (NMSettingsConnection *self, + NMConnection *new_settings, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + +void nm_settings_connection_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data); + +typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connection, + guint32 call_id, + const char *agent_username, + const char *setting_name, + GError *error, + gpointer user_data); + +guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection, + gboolean filter_by_uid, + gulong uid, + const char *setting_name, + NMSettingsGetSecretsFlags flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, + GError **error); + +void nm_settings_connection_cancel_secrets (NMSettingsConnection *connection, + guint32 call_id); + +gboolean nm_settings_connection_is_visible (NMSettingsConnection *self); + +void nm_settings_connection_recheck_visibility (NMSettingsConnection *self); + +void nm_settings_connection_signal_remove (NMSettingsConnection *self); + +guint64 nm_settings_connection_get_timestamp (NMSettingsConnection *connection); + +void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp); + +void nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection); + +G_END_DECLS + +#endif /* NM_SETTINGS_CONNECTION_H */ diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c new file mode 100644 index 00000000..7e24fb71 --- /dev/null +++ b/src/settings/nm-settings-error.c @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include "nm-settings-error.h" + +GQuark +nm_settings_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) + ret = g_quark_from_static_string ("nm-settings-error"); + + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_settings_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + ENUM_ENTRY (NM_SETTINGS_ERROR_GENERAL, "GeneralError"), + + /* The connection was invalid. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"), + /* The connection is read-only; modifications are not allowed. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), + /* A bug in the settings service caused the error. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"), + /* Retrieval or request of secrets failed. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), + /* The request for secrets was canceled. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), + /* The request could not be completed because permission was denied. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), + /* The requested setting does not existing in this connection. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), + /* The caller does not have permission to perform this operation */ + ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + /* No plugin supports adding new connections */ + ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), + /* The plugin providing this connection does not support updating it */ + ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), + /* The plugin providing this connection does not support deleting it */ + ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), + /* Failed to add the connection */ + ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), + /* No plugin supports modifying the system hostname */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), + /* Saving the system hostname failed */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), + /* A connection with this UUID already exists */ + ENUM_ENTRY (NM_SETTINGS_ERROR_UUID_EXISTS, "UuidExists"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMSettingsError", values); + } + + return etype; +} diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h new file mode 100644 index 00000000..b782a779 --- /dev/null +++ b/src/settings/nm-settings-error.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTINGS_ERROR_H +#define NM_SETTINGS_ERROR_H + +#include <glib.h> +#include <glib-object.h> + +enum { + NM_SETTINGS_ERROR_GENERAL = 0, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, + NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SETTINGS_ERROR_INVALID_SETTING, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, + NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, + NM_SETTINGS_ERROR_ADD_FAILED, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + NM_SETTINGS_ERROR_UUID_EXISTS, +}; + +#define NM_SETTINGS_ERROR (nm_settings_error_quark ()) +GQuark nm_settings_error_quark (void); + +#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) +GType nm_settings_error_get_type (void); + +#endif /* NM_SETTINGS_ERROR_H */ diff --git a/src/settings/nm-settings-utils.c b/src/settings/nm-settings-utils.c new file mode 100644 index 00000000..d0e21fbd --- /dev/null +++ b/src/settings/nm-settings-utils.c @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#include <string.h> +#include <glib.h> +#include <glib/gi18n.h> + +#include <nm-connection.h> +#include "nm-settings-utils.h" + +char * +nm_settings_utils_get_default_wired_name (GHashTable *connections) +{ + GHashTableIter iter; + NMConnection *connection = NULL; + GSList *names = NULL, *niter; + char *cname = NULL; + int i = 0; + + /* Build up a list of all existing connection names for dupe checking */ + g_hash_table_iter_init (&iter, connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { + const char *id; + + id = nm_connection_get_id (connection); + g_assert (id); + names = g_slist_append (names, (gpointer) id); + } + + /* Find the next available unique connection name */ + while (!cname && (i++ < 10000)) { + char *temp; + gboolean found = FALSE; + + temp = g_strdup_printf (_("Wired connection %d"), i); + for (niter = names; niter; niter = g_slist_next (niter)) { + if (g_strcmp0 (niter->data, temp) == 0) { + found = TRUE; + g_free (temp); + break; + } + } + + if (found == FALSE) + cname = temp; + } + g_slist_free (names); + + return cname; +} + diff --git a/src/settings/nm-settings-utils.h b/src/settings/nm-settings-utils.h new file mode 100644 index 00000000..f669d2b1 --- /dev/null +++ b/src/settings/nm-settings-utils.h @@ -0,0 +1,26 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTINGS_UTILS_H +#define NM_SETTINGS_UTILS_H + +#include <glib.h> + +char *nm_settings_utils_get_default_wired_name (GHashTable *connections); + +#endif /* NM_SETTINGS_UTILS_H */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c new file mode 100644 index 00000000..f6dbf5e3 --- /dev/null +++ b/src/settings/nm-settings.c @@ -0,0 +1,1663 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Søren Sandmann <sandmann@daimi.au.dk> + * Dan Williams <dcbw@redhat.com> + * Tambet Ingo <tambet@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2011 Red Hat, Inc. + * (C) Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include <unistd.h> +#include <string.h> +#include <gmodule.h> +#include <net/ethernet.h> +#include <netinet/ether.h> +#include <pwd.h> +#include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <NetworkManager.h> +#include <nm-connection.h> +#include <nm-setting-8021x.h> +#include <nm-setting-bluetooth.h> +#include <nm-setting-cdma.h> +#include <nm-setting-connection.h> +#include <nm-setting-gsm.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-olpc-mesh.h> +#include <nm-setting-ppp.h> +#include <nm-setting-pppoe.h> +#include <nm-setting-serial.h> +#include <nm-setting-vpn.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> + +#include "../nm-device-ethernet.h" +#include "nm-dbus-glib-types.h" +#include "nm-settings.h" +#include "nm-settings-connection.h" +#include "nm-polkit-helpers.h" +#include "nm-settings-error.h" +#include "nm-default-wired-connection.h" +#include "nm-logging.h" +#include "nm-dbus-manager.h" +#include "nm-manager-auth.h" +#include "nm-session-monitor.h" +#include "plugins/keyfile/plugin.h" +#include "nm-agent-manager.h" +#include "nm-settings-utils.h" + +#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" + +/* LINKER CRACKROCK */ +#define EXPORT(sym) void * __export_##sym = &sym; + +#include "nm-inotify-helper.h" +EXPORT(nm_inotify_helper_get_type) +EXPORT(nm_inotify_helper_get) +EXPORT(nm_inotify_helper_add_watch) +EXPORT(nm_inotify_helper_remove_watch) + +EXPORT(nm_settings_connection_get_type) +EXPORT(nm_settings_connection_replace_settings) +EXPORT(nm_settings_connection_replace_and_commit) +/* END LINKER CRACKROCK */ + +static void claim_connection (NMSettings *self, + NMSettingsConnection *connection, + gboolean do_export); + +static gboolean impl_settings_list_connections (NMSettings *self, + GPtrArray **connections, + GError **error); + +static void impl_settings_add_connection (NMSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context); + +static void impl_settings_save_hostname (NMSettings *self, + const char *hostname, + DBusGMethodInvocation *context); + +#include "nm-settings-glue.h" + +static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); + +typedef struct { + NMDBusManager *dbus_mgr; + DBusGConnection *bus; + + NMAgentManager *agent_mgr; + + PolkitAuthority *authority; + guint auth_changed_id; + char *config_file; + + NMSessionMonitor *session_monitor; + GSList *auths; + + GSList *plugins; + gboolean connections_loaded; + GHashTable *connections; + GSList *unmanaged_specs; +} NMSettingsPrivate; + +G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT) + +#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate)) + +enum { + PROPERTIES_CHANGED, + CONNECTION_ADDED, + CONNECTION_UPDATED, + CONNECTION_REMOVED, + CONNECTION_VISIBILITY_CHANGED, + CONNECTIONS_LOADED, + + NEW_CONNECTION, /* exported, not used internally */ + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_UNMANAGED_SPECS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + + LAST_PROP +}; + +static void +load_connections (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + if (priv->connections_loaded) + return; + + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + GSList *plugin_connections; + GSList *elt; + + plugin_connections = nm_system_config_interface_get_connections (plugin); + + // FIXME: ensure connections from plugins loaded with a lower priority + // get rejected when they conflict with connections from a higher + // priority plugin. + + for (elt = plugin_connections; elt; elt = g_slist_next (elt)) + claim_connection (self, NM_SETTINGS_CONNECTION (elt->data), TRUE); + + g_slist_free (plugin_connections); + } + + priv->connections_loaded = TRUE; + + /* FIXME: Bad hack */ + unmanaged_specs_changed (NULL, self); + + g_signal_emit (self, signals[CONNECTIONS_LOADED], 0); +} + +void +nm_settings_for_each_connection (NMSettings *self, + NMSettingsForEachFunc for_each_func, + gpointer user_data) +{ + NMSettingsPrivate *priv; + GHashTableIter iter; + gpointer data; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail (for_each_func != NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); + + load_connections (self); + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) + for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); +} + +static gboolean +impl_settings_list_connections (NMSettings *self, + GPtrArray **connections, + GError **error) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer key; + + load_connections (self); + + *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, &key, NULL)) + g_ptr_array_add (*connections, g_strdup ((const char *) key)); + return TRUE; +} + +static int +connection_sort (gconstpointer pa, gconstpointer pb) +{ + NMConnection *a = NM_CONNECTION (pa); + NMSettingConnection *con_a; + NMConnection *b = NM_CONNECTION (pb); + NMSettingConnection *con_b; + guint64 ts_a, ts_b; + + con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); + g_assert (con_a); + con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (con_b); + + if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { + if (nm_setting_connection_get_autoconnect (con_a)) + return -1; + return 1; + } + + ts_a = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pa)); + ts_b = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pb)); + if (ts_a > ts_b) + return -1; + else if (ts_a == ts_b) + return 0; + return 1; +} + +/* Returns a list of NMSettingsConnections. Caller must free the list with + * g_slist_free(). + */ +GSList * +nm_settings_get_connections (NMSettings *self) +{ + GHashTableIter iter; + gpointer data = NULL; + GSList *list = NULL; + + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + + g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) + list = g_slist_insert_sorted (list, data, connection_sort); + return list; +} + +NMSettingsConnection * +nm_settings_get_connection_by_path (NMSettings *self, const char *path) +{ + NMSettingsPrivate *priv; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + g_return_val_if_fail (path != NULL, NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); + + load_connections (self); + + return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path); +} + +static void +clear_unmanaged_specs (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + + g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL); + g_slist_free (priv->unmanaged_specs); + priv->unmanaged_specs = NULL; +} + +static char* +uscore_to_wincaps (const char *uscore) +{ + const char *p; + GString *str; + gboolean last_was_uscore; + + last_was_uscore = TRUE; + + str = g_string_new (NULL); + p = uscore; + while (p && *p) { + if (*p == '-' || *p == '_') + last_was_uscore = TRUE; + else { + if (last_was_uscore) { + g_string_append_c (str, g_ascii_toupper (*p)); + last_was_uscore = FALSE; + } else + g_string_append_c (str, *p); + } + ++p; + } + + return g_string_free (str, FALSE); +} + +static void +notify (GObject *object, GParamSpec *pspec) +{ + GValue *value; + GHashTable *hash; + + value = g_slice_new0 (GValue); + hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); + + g_value_init (value, pspec->value_type); + g_object_get_property (object, pspec->name, value); + g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value); + g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash); + g_hash_table_destroy (hash); + g_value_unset (value); + g_slice_free (GValue, value); +} + +const GSList * +nm_settings_get_unmanaged_specs (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + + load_connections (self); + return priv->unmanaged_specs; +} + +static NMSystemConfigInterface * +get_plugin (NMSettings *self, guint32 capability) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + g_return_val_if_fail (self != NULL, NULL); + + /* Do any of the plugins support setting the hostname? */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & capability) + return NM_SYSTEM_CONFIG_INTERFACE (iter->data); + } + + return NULL; +} + +/* Returns an allocated string which the caller owns and must eventually free */ +char * +nm_settings_get_hostname (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + char *hostname = NULL; + + /* Hostname returned is the hostname returned from the first plugin + * that provides one. + */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL); + if (hostname && strlen (hostname)) + return hostname; + g_free (hostname); + } + } + + return NULL; +} + +static void +plugin_connection_added (NMSystemConfigInterface *config, + NMSettingsConnection *connection, + gpointer user_data) +{ + claim_connection (NM_SETTINGS (user_data), connection, TRUE); +} + +static gboolean +find_unmanaged_device (NMSettings *self, const char *needle) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) { + if (!strcmp ((const char *) iter->data, needle)) + return TRUE; + } + return FALSE; +} + +static void +unmanaged_specs_changed (NMSystemConfigInterface *config, + gpointer user_data) +{ + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + clear_unmanaged_specs (self); + + /* Ask all the plugins for their unmanaged specs */ + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + GSList *specs, *specs_iter; + + specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data)); + for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) { + if (!find_unmanaged_device (self, (const char *) specs_iter->data)) { + priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data); + } else + g_free (specs_iter->data); + } + + g_slist_free (specs); + } + + g_object_notify (G_OBJECT (self), NM_SETTINGS_UNMANAGED_SPECS); +} + +static void +hostname_changed (NMSystemConfigInterface *config, + GParamSpec *pspec, + gpointer user_data) +{ + g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME); +} + +static void +add_plugin (NMSettings *self, NMSystemConfigInterface *plugin) +{ + NMSettingsPrivate *priv; + char *pname = NULL; + char *pinfo = NULL; + + g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin)); + + priv = NM_SETTINGS_GET_PRIVATE (self); + + priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); + + g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, + G_CALLBACK (plugin_connection_added), self); + g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self); + + nm_system_config_interface_init (plugin, NULL); + + g_object_get (G_OBJECT (plugin), + NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname, + NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo, + NULL); + + g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED, + G_CALLBACK (unmanaged_specs_changed), self); + + nm_log_info (LOGD_SETTINGS, "Loaded plugin %s: %s", pname, pinfo); + g_free (pname); + g_free (pinfo); +} + +static GObject * +find_plugin (GSList *list, const char *pname) +{ + GSList *iter; + GObject *obj = NULL; + + g_return_val_if_fail (pname != NULL, NULL); + + for (iter = list; iter && !obj; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + char *list_pname = NULL; + + g_object_get (G_OBJECT (plugin), + NM_SYSTEM_CONFIG_INTERFACE_NAME, + &list_pname, + NULL); + if (list_pname && !strcmp (pname, list_pname)) + obj = G_OBJECT (plugin); + + g_free (list_pname); + } + + return obj; +} + +static gboolean +load_plugins (NMSettings *self, const char *plugins, GError **error) +{ + GSList *list = NULL; + char **plist; + char **iter; + gboolean success = TRUE; + + plist = g_strsplit (plugins, ",", 0); + if (!plist) + return FALSE; + + for (iter = plist; *iter; iter++) { + GModule *plugin; + char *full_name, *path; + const char *pname = g_strstrip (*iter); + GObject *obj; + GObject * (*factory_func) (void); + + /* keyfile plugin built in now */ + if (!strcmp (pname, "keyfile")) + continue; + + /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */ + if (!strcmp (pname, "ifcfg-fedora")) + pname = "ifcfg-rh"; + + obj = find_plugin (list, pname); + if (obj) + continue; + + full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); + path = g_module_build_path (PLUGINDIR, full_name); + + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + if (!plugin) { + g_set_error (error, 0, 0, + "Could not load plugin '%s': %s", + pname, g_module_error ()); + g_free (full_name); + g_free (path); + success = FALSE; + break; + } + + g_free (full_name); + g_free (path); + + if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) { + g_set_error (error, 0, 0, + "Could not find plugin '%s' factory function.", + pname); + success = FALSE; + break; + } + + obj = (*factory_func) (); + if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) { + g_set_error (error, 0, 0, + "Plugin '%s' returned invalid system config object.", + pname); + success = FALSE; + break; + } + + g_module_make_resident (plugin); + g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin); + add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj)); + list = g_slist_append (list, obj); + } + + g_strfreev (plist); + + g_slist_foreach (list, (GFunc) g_object_unref, NULL); + g_slist_free (list); + + return success; +} + +#define REMOVED_ID_TAG "removed-id-tag" +#define UPDATED_ID_TAG "updated-id-tag" +#define VISIBLE_ID_TAG "visible-id-tag" +#define UNREG_ID_TAG "unreg-id-tag" + +static void +connection_removed (NMSettingsConnection *obj, gpointer user_data) +{ + GObject *connection = G_OBJECT (obj); + guint id; + g_object_ref (connection); + + /* Disconnect signal handlers, as plugins might still keep references + * to the connection (and thus the signal handlers would still be live) + * even after NMSettings has dropped all its references. + */ + + id = GPOINTER_TO_UINT (g_object_get_data (connection, REMOVED_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, UPDATED_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, VISIBLE_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + /* Forget about the connection internall */ + g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection))); + + /* Re-emit for listeners like NMPolicy */ + g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection); + + g_object_unref (connection); +} + +static void +connection_unregister (NMSettingsConnection *obj, gpointer user_data) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data); + GObject *connection = G_OBJECT (obj); + guint id; + + /* Make sure it's unregistered from the bus now that's removed */ + dbus_g_connection_unregister_g_object (priv->bus, connection); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, UNREG_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); +} + +static void +connection_updated (NMSettingsConnection *connection, gpointer user_data) +{ + /* Re-emit for listeners like NMPolicy */ + g_signal_emit (NM_SETTINGS (user_data), + signals[CONNECTION_UPDATED], + 0, + connection); +} + +static void +connection_visibility_changed (NMSettingsConnection *connection, + GParamSpec *pspec, + gpointer user_data) +{ + /* Re-emit for listeners like NMPolicy */ + g_signal_emit (NM_SETTINGS (user_data), + signals[CONNECTION_VISIBILITY_CHANGED], + 0, + connection); +} + +static void +claim_connection (NMSettings *self, + NMSettingsConnection *connection, + gboolean do_export) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + static guint32 ec_counter = 0; + GError *error = NULL; + GHashTableIter iter; + gpointer data; + char *path; + guint id; + + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + /* prevent duplicates */ + if (data == connection) + return; + } + + if (!nm_connection_verify (NM_CONNECTION (connection), &error)) { + nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: '%s' / '%s' invalid: %d", + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); + return; + } + + /* Read timestamp from look-aside file and put it into the connection's data */ + nm_settings_connection_read_and_fill_timestamp (connection); + + /* Ensure it's initial visibility is up-to-date */ + nm_settings_connection_recheck_visibility (connection); + + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed), + self); + g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id)); + + id = g_signal_connect (connection, "unregister", + G_CALLBACK (connection_unregister), + self); + g_object_set_data (G_OBJECT (connection), UNREG_ID_TAG, GUINT_TO_POINTER (id)); + + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED, + G_CALLBACK (connection_updated), + self); + g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id)); + + id = g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE, + G_CALLBACK (connection_visibility_changed), + self); + g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id)); + + /* Export the connection over D-Bus */ + g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); + nm_connection_set_path (NM_CONNECTION (connection), path); + dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); + g_free (path); + + g_hash_table_insert (priv->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), + g_object_ref (connection)); + + /* Only emit the individual connection-added signal after connections + * have been initially loaded. While getting the first list of connections + * we suppress it, then send the connections-loaded signal after we're all + * done to minimize processing. + */ + if (priv->connections_loaded) { + /* Internal added signal */ + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); + + /* Exported D-Bus signal */ + g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); + } +} + +// TODO it seems that this is only ever used to remove a +// NMDefaultWiredConnection, and it probably needs to stay that way. So this +// *needs* a better name! +static void +remove_default_wired_connection (NMSettings *self, + NMSettingsConnection *connection, + gboolean do_signal) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + const char *path = nm_connection_get_path (NM_CONNECTION (connection)); + + if (g_hash_table_lookup (priv->connections, path)) { + g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_CONNECTION_REMOVED); + g_hash_table_remove (priv->connections, path); + } +} + +static NMSettingsConnection * +add_new_connection (NMSettings *self, + NMConnection *connection, + GError **error) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + NMSettingsConnection *added = NULL; + GHashTableIter citer; + NMConnection *candidate = NULL; + + /* Make sure a connection with this UUID doesn't already exist */ + g_hash_table_iter_init (&citer, priv->connections); + while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) { + if (g_strcmp0 (nm_connection_get_uuid (connection), + nm_connection_get_uuid (candidate)) == 0) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_UUID_EXISTS, + "A connection with this UUID already exists."); + return NULL; + } + } + + /* 1) plugin writes the NMConnection to disk + * 2) plugin creates a new NMSettingsConnection subclass with the settings + * from the NMConnection and returns it to the settings service + * 3) settings service exports the new NMSettingsConnection subclass + * 4) plugin notices that something on the filesystem has changed + * 5) plugin reads the changes and ignores them because they will + * contain the same data as the connection it already knows about + */ + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + GError *add_error = NULL; + + g_clear_error (error); + added = nm_system_config_interface_add_connection (plugin, connection, &add_error); + if (added) { + claim_connection (self, added, TRUE); + return added; + } + g_propagate_error (error, add_error); + } + return NULL; +} + +static void +pk_add_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMAuthCallResult result; + GError *error = NULL, *add_error = NULL; + NMConnection *connection; + NMSettingsConnection *added = NULL; + NMSettingsAddCallback callback; + gpointer callback_data; + const char *perm; + + priv->auths = g_slist_remove (priv->auths, chain); + + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + goto done; + } + + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); + + /* Caller didn't successfully authenticate */ + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); + goto done; + } + + connection = nm_auth_chain_get_data (chain, "connection"); + g_assert (connection); + added = add_new_connection (self, connection, &add_error); + if (!added) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_ADD_FAILED, + "Saving connection failed: (%d) %s", + add_error ? add_error->code : -1, + (add_error && add_error->message) ? add_error->message : "(unknown)"); + g_error_free (add_error); + } + +done: + callback = nm_auth_chain_get_data (chain, "callback"); + callback_data = nm_auth_chain_get_data (chain, "callback-data"); + + callback (self, added, error, context, callback_data); + + g_clear_error (&error); + nm_auth_chain_unref (chain); +} + +static void +add_cb (NMSettings *self, + NMSettingsConnection *connection, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection))); +} + +void +nm_settings_add_connection (NMSettings *self, + NMConnection *connection, + DBusGMethodInvocation *context, + NMSettingsAddCallback callback, + gpointer user_data) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingConnection *s_con; + NMAuthChain *chain; + GError *error = NULL, *tmp_error = NULL; + gulong caller_uid = G_MAXULONG; + char *error_desc = NULL; + const char *perm; + + /* Connection must be valid, of course */ + if (!nm_connection_verify (connection, &tmp_error)) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + tmp_error ? tmp_error->message : "(unknown)"); + g_error_free (tmp_error); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Do any of the plugins support adding? */ + if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + "None of the registered plugins support add."); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Get the caller's UID */ + if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Unable to determine UID of request: %s.", + error_desc ? error_desc : "(unknown)"); + g_free (error_desc); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). + */ + if (0 != caller_uid) { + if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + error_desc); + g_free (error_desc); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Caller is allowed to add this connection */ + } + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + + /* Otherwise validate the user request */ + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self); + g_assert (chain); + priv->auths = g_slist_append (priv->auths, chain); + nm_auth_chain_add_call (chain, perm, TRUE); + nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL); + nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); +} + +static void +impl_settings_add_connection (NMSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context) +{ + NMConnection *connection; + GError *error = NULL; + + connection = nm_connection_new_from_hash (settings, &error); + if (connection) { + nm_settings_add_connection (self, connection, context, add_cb, NULL); + g_object_unref (connection); + } else { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +static void +pk_hostname_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMAuthCallResult result; + gboolean success = FALSE; + GError *error = NULL; + GSList *iter; + const char *hostname; + + priv->auths = g_slist_remove (priv->auths, chain); + + /* If our NMSettingsConnection is already gone, do nothing */ + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + goto done; + } + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); + + /* Caller didn't successfully authenticate */ + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); + goto done; + } + + /* Set the hostname in all plugins */ + hostname = nm_auth_chain_get_data (chain, "hostname"); + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { + g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL); + success = TRUE; + } + } + + if (!success) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + "Saving the hostname failed."); + } + +done: + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); + + g_clear_error (&error); + nm_auth_chain_unref (chain); +} + +static void +impl_settings_save_hostname (NMSettings *self, + const char *hostname, + DBusGMethodInvocation *context) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMAuthChain *chain; + GError *error = NULL; + + /* Do any of the plugins support setting the hostname? */ + if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + "None of the registered plugins support setting the hostname."); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Otherwise validate the user request */ + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self); + g_assert (chain); + priv->auths = g_slist_append (priv->auths, chain); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); + nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); +} + +static gboolean +have_connection_for_device (NMSettings *self, GByteArray *mac) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + const GByteArray *setting_mac; + gboolean ret = FALSE; + + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + /* Find a wired connection locked to the given MAC address, if any */ + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *connection = NM_CONNECTION (data); + const char *connection_type; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + connection_type = nm_setting_connection_get_connection_type (s_con); + + if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME) + && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) + continue; + + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + + /* No wired setting; therefore the PPPoE connection applies to any device */ + if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) { + ret = TRUE; + break; + } + + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (setting_mac) { + /* A connection mac-locked to this device */ + if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) { + ret = TRUE; + break; + } + } else { + /* A connection that applies to any wired device */ + ret = TRUE; + break; + } + } + + return ret; +} + +/* Search through the list of blacklisted MAC addresses in the config file. */ +static gboolean +is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GKeyFile *config; + char **list, **iter; + gboolean found = FALSE; + + g_return_val_if_fail (mac != NULL, FALSE); + + if (!priv->config_file) + return FALSE; + + config = g_key_file_new (); + if (!config) { + nm_log_warn (LOGD_SETTINGS, "not enough memory to load config file."); + return FALSE; + } + + g_key_file_set_list_separator (config, ','); + if (!g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_NONE, NULL)) + goto out; + + list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); + for (iter = list; iter && *iter; iter++) { + struct ether_addr *candidate; + + if (strcmp(g_strstrip(*iter), "*") == 0) { + found = TRUE; + break; + } + + candidate = ether_aton (*iter); + if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { + found = TRUE; + break; + } + } + + if (list) + g_strfreev (list); + +out: + g_key_file_free (config); + return found; +} + +#define DEFAULT_WIRED_TAG "default-wired" + +static void +default_wired_deleted (NMDefaultWiredConnection *wired, + const GByteArray *mac, + NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingConnection *s_con; + char *tmp; + GKeyFile *config; + char **list, **iter, **updated; + gboolean found = FALSE; + gsize len = 0, i; + char *data; + + /* If there was no config file specified, there's nothing to do */ + if (!priv->config_file) + goto cleanup; + + /* When the default wired connection is removed (either deleted or saved + * to a new persistent connection by a plugin), write the MAC address of + * the wired device to the config file and don't create a new default wired + * connection for that device again. + */ + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired), + NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + /* Ignore removals of read-only connections, since they couldn't have + * been removed by the user. + */ + if (nm_setting_connection_get_read_only (s_con)) + goto cleanup; + + config = g_key_file_new (); + if (!config) + goto cleanup; + + g_key_file_set_list_separator (config, ','); + g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL); + + list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); + for (iter = list; iter && *iter; iter++) { + struct ether_addr *candidate; + + if (strcmp(g_strstrip(*iter), "*") == 0) { + found = TRUE; + break; + } + + candidate = ether_aton (*iter); + if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { + found = TRUE; + break; + } + } + + /* Add this device's MAC to the list */ + if (!found) { + tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], mac->data[5]); + + /* New list; size + 1 for the new element, + 1 again for ending NULL */ + updated = g_malloc0 (sizeof (char*) * (len + 2)); + + /* Copy original list and add new MAC */ + for (i = 0; list && list[i]; i++) + updated[i] = list[i]; + updated[i++] = tmp; + updated[i] = NULL; + + g_key_file_set_string_list (config, + "main", CONFIG_KEY_NO_AUTO_DEFAULT, + (const char **) updated, + len + 2); + /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */ + g_free (updated); + g_free (tmp); + + data = g_key_file_to_data (config, &len, NULL); + if (data) { + g_file_set_contents (priv->config_file, data, len, NULL); + g_free (data); + } + } + + if (list) + g_strfreev (list); + g_key_file_free (config); + +cleanup: + g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), + DEFAULT_WIRED_TAG, + NULL); +} + +static void +delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) +{ +} + +static gboolean +default_wired_try_update (NMDefaultWiredConnection *wired, + NMSettings *self) +{ + GError *error = NULL; + const char *id; + NMSettingsConnection *added; + + /* Try to move this default wired conneciton to a plugin so that it has + * persistent storage. + */ + + id = nm_connection_get_id (NM_CONNECTION (wired)); + g_assert (id); + + remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE); + added = add_new_connection (self, NM_CONNECTION (wired), &error); + if (added) { + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (wired), delete_cb, NULL); + + g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), + DEFAULT_WIRED_TAG, + NULL); + nm_log_info (LOGD_SETTINGS, "Saved default wired connection '%s' to persistent storage", id); + return FALSE; + } + + nm_log_warn (LOGD_SETTINGS, "couldn't save default wired connection '%s': %d / %s", + id, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + + /* If there was an error, don't destroy the default wired connection, + * but add it back to the system settings service. Connection is already + * exported on the bus, don't export it again, thus do_export == FALSE. + */ + claim_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE); + return TRUE; +} + +void +nm_settings_device_added (NMSettings *self, NMDevice *device) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GByteArray *mac = NULL; + struct ether_addr tmp; + NMDefaultWiredConnection *wired; + gboolean read_only = TRUE; + const char *id; + char *defname; + + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + return; + + /* If the device isn't managed or it already has a default wired connection, + * ignore it. + */ + if ( !nm_device_get_managed (device) + || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG)) + return; + + nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp); + + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN); + + if ( have_connection_for_device (self, mac) + || is_mac_auto_wired_blacklisted (self, mac)) + goto ignore; + + if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) + read_only = FALSE; + + defname = nm_settings_utils_get_default_wired_name (priv->connections); + wired = nm_default_wired_connection_new (mac, device, defname, read_only); + g_free (defname); + if (!wired) + goto ignore; + + id = nm_connection_get_id (NM_CONNECTION (wired)); + g_assert (id); + + nm_log_info (LOGD_SETTINGS, "Added default wired connection '%s' for %s", + id, nm_device_get_udi (device)); + + g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self); + g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self); + claim_connection (self, NM_SETTINGS_CONNECTION (wired), TRUE); + g_object_unref (wired); + + g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired); + +ignore: + g_byte_array_free (mac, TRUE); +} + +void +nm_settings_device_removed (NMSettings *self, NMDevice *device) +{ + NMDefaultWiredConnection *connection; + + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + return; + + connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); + if (connection) + remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (connection), TRUE); +} + +/***************************************************************/ + +NMSettings * +nm_settings_new (const char *config_file, + const char *plugins, + GError **error) +{ + NMSettings *self; + NMSettingsPrivate *priv; + GObject *keyfile_plugin; + + self = g_object_new (NM_TYPE_SETTINGS, NULL); + if (!self) + return NULL; + + priv = NM_SETTINGS_GET_PRIVATE (self); + + priv->config_file = g_strdup (config_file); + priv->dbus_mgr = nm_dbus_manager_get (); + priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + + if (plugins) { + /* Load the plugins; fail if a plugin is not found. */ + if (!load_plugins (self, plugins, error)) { + g_object_unref (self); + return NULL; + } + } + + /* Add the keyfile plugin last */ + keyfile_plugin = nm_settings_keyfile_plugin_new (); + g_assert (keyfile_plugin); + add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin)); + + unmanaged_specs_changed (NULL, self); + + dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); + return self; +} + +static void +nm_settings_init (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GError *error = NULL; + + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + + priv->authority = polkit_authority_get_sync (NULL, &error); + if (!priv->authority) { + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + priv->session_monitor = nm_session_monitor_get (); + + /* Hold a reference to the agent manager so it stays alive; the only + * other holders are NMSettingsConnection objects which are often + * transient, and we don't want the agent manager to get destroyed and + * recreated often. + */ + priv->agent_mgr = nm_agent_manager_get (); +} + +static void +dispose (GObject *object) +{ + NMSettings *self = NM_SETTINGS (object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + if (priv->auth_changed_id) { + g_signal_handler_disconnect (priv->authority, priv->auth_changed_id); + priv->auth_changed_id = 0; + } + + for (iter = priv->auths; iter; iter = g_slist_next (iter)) + nm_auth_chain_unref ((NMAuthChain *) iter->data); + g_slist_free (priv->auths); + + g_object_unref (priv->dbus_mgr); + + g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); + + G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMSettings *self = NM_SETTINGS (object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + + g_hash_table_destroy (priv->connections); + + clear_unmanaged_specs (self); + + g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); + g_slist_free (priv->plugins); + + g_free (priv->config_file); + + G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettings *self = NM_SETTINGS (object); + const GSList *specs, *iter; + GSList *copy = NULL; + + switch (prop_id) { + case PROP_UNMANAGED_SPECS: + specs = nm_settings_get_unmanaged_specs (self); + for (iter = specs; iter; iter = g_slist_next (iter)) + copy = g_slist_append (copy, g_strdup (iter->data)); + g_value_take_boxed (value, copy); + break; + case PROP_HOSTNAME: + g_value_take_string (value, nm_settings_get_hostname (self)); + + /* Don't ever pass NULL through D-Bus */ + if (!g_value_get_string (value)) + g_value_set_static_string (value, ""); + break; + case PROP_CAN_MODIFY: + g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_settings_class_init (NMSettingsClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (NMSettingsPrivate)); + + /* virtual methods */ + object_class->notify = notify; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /* properties */ + + g_object_class_install_property + (object_class, PROP_UNMANAGED_SPECS, + g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, + "Unamanged device specs", + "Unmanaged device specs", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_SETTINGS_HOSTNAME, + "Hostname", + "Persistent hostname", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, + "CanModify", + "Can modify anything (hostname, connections, etc)", + FALSE, + G_PARAM_READABLE)); + + /* signals */ + signals[PROPERTIES_CHANGED] = + g_signal_new ("properties-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, properties_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); + signals[CONNECTION_ADDED] = + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, connection_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_UPDATED] = + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, connection_updated), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_REMOVED] = + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, connection_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_VISIBILITY_CHANGED] = + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTIONS_LOADED] = + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsClass, connections_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[NEW_CONNECTION] = + g_signal_new ("new-connection", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + dbus_g_error_domain_register (NM_SETTINGS_ERROR, + NM_DBUS_IFACE_SETTINGS, + NM_TYPE_SETTINGS_ERROR); + + /* And register all the settings errors with D-Bus */ + dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR); + dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR); + dbus_g_error_domain_register (NM_SETTING_BLUETOOTH_ERROR, NULL, NM_TYPE_SETTING_BLUETOOTH_ERROR); + dbus_g_error_domain_register (NM_SETTING_CDMA_ERROR, NULL, NM_TYPE_SETTING_CDMA_ERROR); + dbus_g_error_domain_register (NM_SETTING_CONNECTION_ERROR, NULL, NM_TYPE_SETTING_CONNECTION_ERROR); + dbus_g_error_domain_register (NM_SETTING_GSM_ERROR, NULL, NM_TYPE_SETTING_GSM_ERROR); + dbus_g_error_domain_register (NM_SETTING_IP4_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP4_CONFIG_ERROR); + dbus_g_error_domain_register (NM_SETTING_IP6_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP6_CONFIG_ERROR); + dbus_g_error_domain_register (NM_SETTING_OLPC_MESH_ERROR, NULL, NM_TYPE_SETTING_OLPC_MESH_ERROR); + dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR); + dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR); + dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR); + dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR); + dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR); + dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR); + dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR); + dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR); + + dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info); + +} + diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h new file mode 100644 index 00000000..a5cb4d7c --- /dev/null +++ b/src/settings/nm-settings.h @@ -0,0 +1,115 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Søren Sandmann <sandmann@daimi.au.dk> + * Dan Williams <dcbw@redhat.com> + * Tambet Ingo <tambet@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_SETTINGS_H__ +#define __NM_SETTINGS_H__ + +#include <nm-connection.h> + +#include "nm-settings-connection.h" +#include "nm-system-config-interface.h" +#include "nm-device.h" + +#define NM_TYPE_SETTINGS (nm_settings_get_type ()) +#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings)) +#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass)) +#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS)) +#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS)) +#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass)) + +#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" +#define NM_SETTINGS_HOSTNAME "hostname" +#define NM_SETTINGS_CAN_MODIFY "can-modify" + +#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added" +#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated" +#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed" +#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" +#define NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED "connections-loaded" + +typedef struct { + GObject parent_instance; +} NMSettings; + +typedef struct { + GObjectClass parent_class; + + /* Signals */ + void (*properties_changed) (NMSettings *self, GHashTable *properties); + + void (*connection_added) (NMSettings *self, NMSettingsConnection *connection); + + void (*connection_updated) (NMSettings *self, NMSettingsConnection *connection); + + void (*connection_removed) (NMSettings *self, NMSettingsConnection *connection); + + void (*connection_visibility_changed) (NMSettings *self, NMSettingsConnection *connection); + + void (*connections_loaded) (NMSettings *self); +} NMSettingsClass; + +GType nm_settings_get_type (void); + +NMSettings *nm_settings_new (const char *config_file, + const char *plugins, + GError **error); + +typedef void (*NMSettingsForEachFunc) (NMSettings *settings, + NMSettingsConnection *connection, + gpointer user_data); + +void nm_settings_for_each_connection (NMSettings *settings, + NMSettingsForEachFunc for_each_func, + gpointer user_data); + +typedef void (*NMSettingsAddCallback) (NMSettings *settings, + NMSettingsConnection *connection, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data); + +void nm_settings_add_connection (NMSettings *self, + NMConnection *connection, + DBusGMethodInvocation *context, + NMSettingsAddCallback callback, + gpointer user_data); + +/* Returns a list of NMSettingsConnections. Caller must free the list with + * g_slist_free(). + */ +GSList *nm_settings_get_connections (NMSettings *settings); + +NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings, + const char *path); + +const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); + +char *nm_settings_get_hostname (NMSettings *self); + +void nm_settings_device_added (NMSettings *self, NMDevice *device); + +void nm_settings_device_removed (NMSettings *self, NMDevice *device); + +#endif /* __NM_SETTINGS_H__ */ diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c new file mode 100644 index 00000000..45aa6305 --- /dev/null +++ b/src/settings/nm-system-config-interface.c @@ -0,0 +1,162 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "nm-system-config-interface.h" + +static void +interface_init (gpointer g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (initialized) + return; + + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_NAME, + "Name", + "Plugin name", + NULL, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_INFO, + "Info", + "Plugin information", + NULL, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, + "Capabilities", + "Plugin capabilties", + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + ( NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS + | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME), + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, + "Hostname", + "Configured hostname", + NULL, + G_PARAM_READWRITE)); + + /* Signals */ + g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSystemConfigInterface, connection_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + NM_TYPE_SETTINGS_CONNECTION); + + g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_specs_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + initialized = TRUE; +} + + +GType +nm_system_config_interface_get_type (void) +{ + static GType system_config_interface_type = 0; + + if (!system_config_interface_type) { + const GTypeInfo system_config_interface_info = { + sizeof (NMSystemConfigInterface), /* class_size */ + interface_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + system_config_interface_type = g_type_register_static (G_TYPE_INTERFACE, + "NMSystemConfigInterface", + &system_config_interface_info, + 0); + + g_type_interface_add_prerequisite (system_config_interface_type, G_TYPE_OBJECT); + } + + return system_config_interface_type; +} + +void +nm_system_config_interface_init (NMSystemConfigInterface *config, + gpointer unused) +{ + g_return_if_fail (config != NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init) + NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config); +} + +GSList * +nm_system_config_interface_get_connections (NMSystemConfigInterface *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections) + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections (config); + return NULL; +} + +GSList * +nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs) + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs (config); + return NULL; +} + +NMSettingsConnection * +nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (config != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection) + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error); + + return NULL; +} diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h new file mode 100644 index 00000000..96a64061 --- /dev/null +++ b/src/settings/nm-system-config-interface.h @@ -0,0 +1,146 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef NM_SYSTEM_CONFIG_INTERFACE_H +#define NM_SYSTEM_CONFIG_INTERFACE_H + +#include <glib.h> +#include <glib-object.h> +#include <nm-connection.h> +#include <nm-settings-connection.h> + +G_BEGIN_DECLS + +#define PLUGIN_PRINT(pname, fmt, args...) \ + { g_message (" " pname ": " fmt, ##args); } + +#define PLUGIN_WARN(pname, fmt, args...) \ + { g_warning (" " pname ": " fmt, ##args); } + + +/* Plugin's factory function that returns a GObject that implements + * NMSystemConfigInterface. + */ +GObject * nm_system_config_factory (void); + +#define NM_TYPE_SYSTEM_CONFIG_INTERFACE (nm_system_config_interface_get_type ()) +#define NM_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) +#define NM_IS_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE)) +#define NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) + + +#define NM_SYSTEM_CONFIG_INTERFACE_NAME "name" +#define NM_SYSTEM_CONFIG_INTERFACE_INFO "info" +#define NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES "capabilities" +#define NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME "hostname" + +#define NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed" +#define NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED "connection-added" + +typedef enum { + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE = 0x00000000, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS = 0x00000001, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME = 0x00000002 + + /* When adding more capabilities, be sure to update the "Capabilities" + * property max value in nm-system-config-interface.c. + */ +} NMSystemConfigInterfaceCapabilities; + +typedef enum { + NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST = 0x1000, + + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME = NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, +} NMSystemConfigInterfaceProp; + + +typedef struct _NMSystemConfigInterface NMSystemConfigInterface; + +struct _NMSystemConfigInterface { + GTypeInterface g_iface; + + /* Called when the plugin is loaded to initialize it */ + void (*init) (NMSystemConfigInterface *config); + + /* Returns a GSList of NMSettingsConnection objects that represent + * connections the plugin knows about. The returned list is freed by the + * system settings service. + */ + GSList * (*get_connections) (NMSystemConfigInterface *config); + + /* + * Return a string list of specifications of devices which NetworkManager + * should not manage. Returned list will be freed by the system settings + * service, and each element must be allocated using g_malloc() or its + * variants (g_strdup, g_strdup_printf, etc). + * + * Each string in the list must follow the format <method>:<data>, where + * the method and data are one of the following: + * + * Method: mac Data: device MAC address formatted with leading zeros and + * lowercase letters, like 00:0a:0b:0c:0d:0e + * + * Method: s390-subchannels Data: string of 2 or 3 s390 subchannels + * separated by commas (,) that identify the + * device, like "0.0.09a0,0.0.09a1,0.0.09a2". + * The string may contain only the following + * characters: [a-fA-F0-9,.] + */ + GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); + + /* + * Save the given connection to backing storage, and return a new + * NMSettingsConnection subclass that contains the same settings as the + * original connection. + */ + NMSettingsConnection * (*add_connection) (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); + + /* Signals */ + + /* Emitted when a new connection has been found by the plugin */ + void (*connection_added) (NMSystemConfigInterface *config, + NMSettingsConnection *connection); + + /* Emitted when the list of unmanaged device specifications changes */ + void (*unmanaged_specs_changed) (NMSystemConfigInterface *config); +}; + +GType nm_system_config_interface_get_type (void); + +void nm_system_config_interface_init (NMSystemConfigInterface *config, + gpointer unused); + +GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config); + +GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config); + +NMSettingsConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); + +G_END_DECLS + +#endif /* NM_SYSTEM_CONFIG_INTERFACE_H */ diff --git a/src/settings/plugins/Makefile.am b/src/settings/plugins/Makefile.am new file mode 100644 index 00000000..5df57d5e --- /dev/null +++ b/src/settings/plugins/Makefile.am @@ -0,0 +1,21 @@ +SUBDIRS=keyfile + +if TARGET_REDHAT +SUBDIRS+=ifcfg-rh +endif + +if TARGET_SUSE +SUBDIRS+=ifcfg-suse +endif + +if TARGET_MANDRIVA +SUBDIRS+=ifcfg-rh +endif + +if TARGET_DEBIAN +SUBDIRS+=ifupdown +endif + +if TARGET_GENTOO +SUBDIRS+=ifnet +endif diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in new file mode 100644 index 00000000..d0ade2a1 --- /dev/null +++ b/src/settings/plugins/Makefile.in @@ -0,0 +1,660 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@TARGET_REDHAT_TRUE@am__append_1 = ifcfg-rh +@TARGET_SUSE_TRUE@am__append_2 = ifcfg-suse +@TARGET_MANDRIVA_TRUE@am__append_3 = ifcfg-rh +@TARGET_DEBIAN_TRUE@am__append_4 = ifupdown +@TARGET_GENTOO_TRUE@am__append_5 = ifnet +subdir = src/settings/plugins +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = keyfile ifcfg-rh ifcfg-suse ifupdown ifnet +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = keyfile $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifcfg-rh/Makefile.am b/src/settings/plugins/ifcfg-rh/Makefile.am new file mode 100644 index 00000000..9874d352 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/Makefile.am @@ -0,0 +1,76 @@ +SUBDIRS=. tests + +nm-ifcfg-rh-glue.h: nm-ifcfg-rh.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_ifcfg_rh --mode=glib-server --output=$@ $< + +BUILT_SOURCES = \ + nm-ifcfg-rh-glue.h + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-rh.la + +noinst_LTLIBRARIES = libifcfg-rh-io.la + +libifcfg_rh_io_la_SOURCES = \ + shvar.c \ + shvar.h \ + reader.c \ + reader.h \ + writer.c \ + writer.h \ + errors.c \ + common.h \ + utils.c \ + utils.h + +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/marshallers + +libifcfg_rh_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(NSS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +libifcfg_rh_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(NSS_LIBS) + +libnm_settings_plugin_ifcfg_rh_la_SOURCES = \ + plugin.c \ + plugin.h \ + nm-ifcfg-connection.c \ + nm-ifcfg-connection.h + +libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + libifcfg-rh-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GIO_LIBS) + +dbusservicedir = $(DBUS_SYS_DIR) +dbusservice_DATA = nm-ifcfg-rh.conf + +EXTRA_DIST = \ + $(dbusservice_DATA) \ + nm-ifcfg-rh.xml + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in new file mode 100644 index 00000000..dac8fc9e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -0,0 +1,978 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ifcfg-rh +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkglibdir)" \ + "$(DESTDIR)$(dbusservicedir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libifcfg_rh_io_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libifcfg_rh_io_la_OBJECTS = libifcfg_rh_io_la-shvar.lo \ + libifcfg_rh_io_la-reader.lo libifcfg_rh_io_la-writer.lo \ + libifcfg_rh_io_la-errors.lo libifcfg_rh_io_la-utils.lo +libifcfg_rh_io_la_OBJECTS = $(am_libifcfg_rh_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + libifcfg-rh-io.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \ + libnm_settings_plugin_ifcfg_rh_la-plugin.lo \ + libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo +libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \ + $(am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS) +libnm_settings_plugin_ifcfg_rh_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_ifcfg_rh_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libifcfg_rh_io_la_SOURCES) \ + $(libnm_settings_plugin_ifcfg_rh_la_SOURCES) +DIST_SOURCES = $(libifcfg_rh_io_la_SOURCES) \ + $(libnm_settings_plugin_ifcfg_rh_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +DATA = $(dbusservice_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests +BUILT_SOURCES = \ + nm-ifcfg-rh-glue.h + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-rh.la +noinst_LTLIBRARIES = libifcfg-rh-io.la +libifcfg_rh_io_la_SOURCES = \ + shvar.c \ + shvar.h \ + reader.c \ + reader.h \ + writer.c \ + writer.h \ + errors.c \ + common.h \ + utils.c \ + utils.h + +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/marshallers + +libifcfg_rh_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(NSS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +libifcfg_rh_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(NSS_LIBS) + +libnm_settings_plugin_ifcfg_rh_la_SOURCES = \ + plugin.c \ + plugin.h \ + nm-ifcfg-connection.c \ + nm-ifcfg-connection.h + +libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + libifcfg-rh-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GIO_LIBS) + +dbusservicedir = $(DBUS_SYS_DIR) +dbusservice_DATA = nm-ifcfg-rh.conf +EXTRA_DIST = \ + $(dbusservice_DATA) \ + nm-ifcfg-rh.xml + +CLEANFILES = $(BUILT_SOURCES) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libifcfg-rh-io.la: $(libifcfg_rh_io_la_OBJECTS) $(libifcfg_rh_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libifcfg_rh_io_la_OBJECTS) $(libifcfg_rh_io_la_LIBADD) $(LIBS) +libnm-settings-plugin-ifcfg-rh.la: $(libnm_settings_plugin_ifcfg_rh_la_OBJECTS) $(libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_ifcfg_rh_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifcfg_rh_la_OBJECTS) $(libnm_settings_plugin_ifcfg_rh_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-errors.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-reader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-shvar.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-writer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libifcfg_rh_io_la-shvar.lo: shvar.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-shvar.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-shvar.Tpo -c -o libifcfg_rh_io_la-shvar.lo `test -f 'shvar.c' || echo '$(srcdir)/'`shvar.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-shvar.Tpo $(DEPDIR)/libifcfg_rh_io_la-shvar.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='shvar.c' object='libifcfg_rh_io_la-shvar.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-shvar.lo `test -f 'shvar.c' || echo '$(srcdir)/'`shvar.c + +libifcfg_rh_io_la-reader.lo: reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-reader.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-reader.Tpo -c -o libifcfg_rh_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-reader.Tpo $(DEPDIR)/libifcfg_rh_io_la-reader.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reader.c' object='libifcfg_rh_io_la-reader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c + +libifcfg_rh_io_la-writer.lo: writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-writer.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-writer.Tpo -c -o libifcfg_rh_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-writer.Tpo $(DEPDIR)/libifcfg_rh_io_la-writer.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writer.c' object='libifcfg_rh_io_la-writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c + +libifcfg_rh_io_la-errors.lo: errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-errors.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-errors.Tpo -c -o libifcfg_rh_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-errors.Tpo $(DEPDIR)/libifcfg_rh_io_la-errors.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libifcfg_rh_io_la-errors.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c + +libifcfg_rh_io_la-utils.lo: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-utils.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-utils.Tpo -c -o libifcfg_rh_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-utils.Tpo $(DEPDIR)/libifcfg_rh_io_la-utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libifcfg_rh_io_la-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c + +libnm_settings_plugin_ifcfg_rh_la-plugin.lo: plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_rh_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Tpo -c -o libnm_settings_plugin_ifcfg_rh_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifcfg_rh_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_rh_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c + +libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo: nm-ifcfg-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Tpo -c -o libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo `test -f 'nm-ifcfg-connection.c' || echo '$(srcdir)/'`nm-ifcfg-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifcfg-connection.c' object='libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo `test -f 'nm-ifcfg-connection.c' || echo '$(srcdir)/'`nm-ifcfg-connection.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dbusserviceDATA: $(dbusservice_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbusservicedir)" || $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)" + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \ + done + +uninstall-dbusserviceDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(dbusservicedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(dbusservicedir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(dbusservicedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pkglibLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dbusserviceDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-dbusserviceDATA uninstall-pkglibLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dbusserviceDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkglibLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-dbusserviceDATA uninstall-pkglibLTLIBRARIES + + +nm-ifcfg-rh-glue.h: nm-ifcfg-rh.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_ifcfg_rh --mode=glib-server --output=$@ $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h new file mode 100644 index 00000000..74a77c4c --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include <glib.h> + +#define IFCFG_TAG "ifcfg-" +#define KEYS_TAG "keys-" +#define ROUTE_TAG "route-" +#define ROUTE6_TAG "route6-" + +#define BAK_TAG ".bak" +#define TILDE_TAG "~" +#define ORIG_TAG ".orig" +#define REJ_TAG ".rej" +#define RPMNEW_TAG ".rpmnew" +#define AUGNEW_TAG ".augnew" +#define AUGTMP_TAG ".augtmp" + +#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts" + +#define IFCFG_PLUGIN_NAME "ifcfg-rh" +#define IFCFG_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." + +#define TYPE_ETHERNET "Ethernet" +#define TYPE_WIRELESS "Wireless" +#define TYPE_BRIDGE "Bridge" + +#define SECRET_FLAG_AGENT "user" +#define SECRET_FLAG_NOT_SAVED "ask" +#define SECRET_FLAG_NOT_REQUIRED "unused" + +#define IFCFG_PLUGIN_ERROR (ifcfg_plugin_error_quark ()) +GQuark ifcfg_plugin_error_quark (void); + + +#endif /* __COMMON_H__ */ + diff --git a/src/settings/plugins/ifcfg-rh/errors.c b/src/settings/plugins/ifcfg-rh/errors.c new file mode 100644 index 00000000..25039104 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/errors.c @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2009 Red Hat, Inc. + */ + +#include <glib.h> +#include "common.h" + +GQuark +ifcfg_plugin_error_quark (void) +{ + static GQuark error_quark = 0; + + if (G_UNLIKELY (error_quark == 0)) + error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark"); + + return error_quark; +} + + diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c new file mode 100644 index 00000000..433f933b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -0,0 +1,346 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2010 Red Hat, Inc. + */ + +#include <string.h> +#include <net/ethernet.h> +#include <netinet/ether.h> + +#include <glib/gstdio.h> + +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-gsm.h> +#include <nm-setting-cdma.h> +#include <nm-setting-pppoe.h> +#include <nm-setting-wireless-security.h> +#include <nm-setting-8021x.h> + +#include "common.h" +#include "nm-ifcfg-connection.h" +#include "reader.h" +#include "writer.h" +#include "nm-inotify-helper.h" + +G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate)) + +typedef struct { + gulong ih_event_id; + + char *path; + int file_wd; + + char *keyfile; + int keyfile_wd; + + char *routefile; + int routefile_wd; + + char *route6file; + int route6file_wd; + + char *unmanaged; +} NMIfcfgConnectionPrivate; + +enum { + PROP_0, + PROP_UNMANAGED, + LAST_PROP +}; + +/* Signals */ +enum { + IFCFG_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +files_changed_cb (NMInotifyHelper *ih, + struct inotify_event *evt, + const char *path, + gpointer user_data) +{ + NMIfcfgConnection *self = NM_IFCFG_CONNECTION (user_data); + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); + + if ( (evt->wd != priv->file_wd) + && (evt->wd != priv->keyfile_wd) + && (evt->wd != priv->routefile_wd) + && (evt->wd != priv->route6file_wd)) + return; + + /* push the event up to the plugin */ + g_signal_emit (self, signals[IFCFG_CHANGED], 0); +} + +NMIfcfgConnection * +nm_ifcfg_connection_new (const char *full_path, + NMConnection *source, + GError **error, + gboolean *ignore_error) +{ + GObject *object; + NMIfcfgConnectionPrivate *priv; + NMConnection *tmp; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + NMInotifyHelper *ih; + + g_return_val_if_fail (full_path != NULL, NULL); + + /* If we're given a connection already, prefer that instead of re-reading */ + if (source) + tmp = g_object_ref (source); + else { + tmp = connection_from_file (full_path, NULL, NULL, NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + error, + ignore_error); + if (!tmp) + return NULL; + } + + object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, + NM_IFCFG_CONNECTION_UNMANAGED, unmanaged, + NULL); + if (!object) + goto out; + + /* Update our settings with what was read from the file */ + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) { + g_object_unref (object); + object = NULL; + goto out; + } + + priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); + priv->path = g_strdup (full_path); + + ih = nm_inotify_helper_get (); + priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object); + + priv->file_wd = nm_inotify_helper_add_watch (ih, full_path); + + priv->keyfile = keyfile; + priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile); + + priv->routefile = routefile; + priv->routefile_wd = nm_inotify_helper_add_watch (ih, routefile); + + priv->route6file = route6file; + priv->route6file_wd = nm_inotify_helper_add_watch (ih, route6file); + +out: + g_object_unref (tmp); + return (NMIfcfgConnection *) object; +} + +const char * +nm_ifcfg_connection_get_path (NMIfcfgConnection *self) +{ + g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); + + return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path; +} + +const char * +nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self) +{ + g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); + + return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged; +} + +static void +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); + GError *error = NULL; + NMConnection *reread; + char *unmanaged = NULL, *keyfile = NULL, *routefile = NULL, *route6file = NULL; + + /* To ensure we don't rewrite files that are only changed from other + * processes on-disk, read the existing connection back in and only rewrite + * it if it's really changed. + */ + reread = connection_from_file (priv->path, NULL, NULL, NULL, + &unmanaged, &keyfile, &routefile, &route6file, + NULL, NULL); + g_free (unmanaged); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + + if (reread && nm_connection_compare (NM_CONNECTION (connection), + reread, + NM_SETTING_COMPARE_FLAG_EXACT)) + goto out; + + if (!writer_update_connection (NM_CONNECTION (connection), + IFCFG_DIR, + priv->path, + priv->keyfile, + &error)) { + callback (connection, error, user_data); + g_error_free (error); + return; + } + +out: + if (reread) + g_object_unref (reread); + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data); +} + +static void +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); + + g_unlink (priv->path); + if (priv->keyfile) + g_unlink (priv->keyfile); + if (priv->routefile) + g_unlink (priv->routefile); + + if (priv->route6file) + g_unlink (priv->route6file); + + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data); +} + +/* GObject */ + +static void +nm_ifcfg_connection_init (NMIfcfgConnection *connection) +{ +} + +static void +finalize (GObject *object) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); + NMInotifyHelper *ih; + + nm_connection_clear_secrets (NM_CONNECTION (object)); + + ih = nm_inotify_helper_get (); + + if (priv->ih_event_id) + g_signal_handler_disconnect (ih, priv->ih_event_id); + + g_free (priv->path); + if (priv->file_wd >= 0) + nm_inotify_helper_remove_watch (ih, priv->file_wd); + + g_free (priv->keyfile); + if (priv->keyfile_wd >= 0) + nm_inotify_helper_remove_watch (ih, priv->keyfile_wd); + + g_free (priv->routefile); + if (priv->routefile_wd >= 0) + nm_inotify_helper_remove_watch (ih, priv->routefile_wd); + + g_free (priv->route6file); + if (priv->route6file_wd >= 0) + nm_inotify_helper_remove_watch (ih, priv->route6file_wd); + + G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_UNMANAGED: + priv->unmanaged = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_UNMANAGED: + g_value_set_string (value, priv->unmanaged); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifcfg_connection_class); + + g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate)); + + /* Virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + settings_class->delete = do_delete; + settings_class->commit_changes = commit_changes; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_UNMANAGED, + g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED, + "Unmanaged", + "Unmanaged", + NULL, + G_PARAM_READWRITE)); + + signals[IFCFG_CHANGED] = + g_signal_new ("ifcfg-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h new file mode 100644 index 00000000..731aa598 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#ifndef NM_IFCFG_CONNECTION_H +#define NM_IFCFG_CONNECTION_H + +G_BEGIN_DECLS + +#include <NetworkManager.h> +#include <nm-settings-connection.h> + +#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) +#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection)) +#define NM_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass)) +#define NM_IS_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION)) +#define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION)) +#define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass)) + +#define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged" + +typedef struct { + NMSettingsConnection parent; +} NMIfcfgConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMIfcfgConnectionClass; + +GType nm_ifcfg_connection_get_type (void); + +NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename, + NMConnection *source, + GError **error, + gboolean *ignore_error); + +const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self); + +const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self); + +gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self, + GHashTable *new_settings, + GError **error); + +G_END_DECLS + +#endif /* NM_IFCFG_CONNECTION_H */ diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf new file mode 100644 index 00000000..cade31dd --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf @@ -0,0 +1,18 @@ +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <policy user="root"> + <allow own="com.redhat.ifcfgrh1"/> + <allow send_destination="com.redhat.ifcfgrh1"/> + </policy> + <policy at_console="true"> + <deny own="com.redhat.ifcfgrh1"/> + <allow send_destination="com.redhat.ifcfgrh1"/> + </policy> + <policy context="default"> + <deny own="com.redhat.ifcfgrh1"/> + <allow send_destination="com.redhat.ifcfgrh1"/> + </policy> +</busconfig> + diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml new file mode 100644 index 00000000..52793452 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> + <interface name="com.redhat.ifcfgrh1"> + <tp:docstring> + Utility methods for handling NM integration with standard Red Hat ifcfg files. + </tp:docstring> + + <method name="GetIfcfgDetails"> + <tp:docstring> + Given an ifcfg file, return various internal information about it. + </tp:docstring> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_ifcfgrh_get_ifcfg_details"/> + <arg name="ifcfg" type="s" direction="in"> + <tp:docstring> + The full path to an ifcfg file. + </tp:docstring> + </arg> + <arg name="uuid" type="s" direction="out"> + <tp:docstring> + The UUID of the NM connection backed by this ifcfg file. If the ifcfg file does not contain a UUID tag, this UUID is generated by NM, otherwise the UUID from the ifcfg file is used. + </tp:docstring> + </arg> + <arg name="path" type="o" direction="out"> + <tp:docstring> + The object path of the NM connected backed by this ifcfg file. + </tp:docstring> + </arg> + </method> + </interface> +</node> diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c new file mode 100644 index 00000000..ae40b90a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -0,0 +1,800 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Dan Williams <dcbw@redhat.com> + * Søren Sandmann <sandmann@daimi.au.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <net/ethernet.h> +#include <netinet/ether.h> + +#include <gmodule.h> +#include <glib-object.h> +#include <glib/gi18n.h> +#include <gio/gio.h> + +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <nm-setting-connection.h> + +#include "common.h" +#include "nm-dbus-glib-types.h" +#include "plugin.h" +#include "nm-system-config-interface.h" +#include "nm-settings-error.h" + +#include "nm-ifcfg-connection.h" +#include "nm-inotify-helper.h" +#include "shvar.h" +#include "writer.h" +#include "utils.h" + +#define DBUS_SERVICE_NAME "com.redhat.ifcfgrh1" +#define DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1" + +static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, + const char *in_ifcfg, + const char **out_uuid, + const char **out_path, + GError **error); + +#include "nm-ifcfg-rh-glue.h" + +static void connection_new_or_changed (SCPluginIfcfg *plugin, + const char *path, + NMIfcfgConnection *existing); + +static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); + +G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) + +#define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate)) + + +typedef struct { + GHashTable *connections; + + gulong ih_event_id; + int sc_network_wd; + char *hostname; + + GFileMonitor *monitor; + guint monitor_id; + + DBusGConnection *bus; +} SCPluginIfcfgPrivate; + + +static void +connection_unmanaged_changed (NMIfcfgConnection *connection, + GParamSpec *pspec, + gpointer user_data) +{ + g_signal_emit_by_name (SC_PLUGIN_IFCFG (user_data), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); +} + +static void +connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); + const char *path; + + path = nm_ifcfg_connection_get_path (connection); + g_return_if_fail (path != NULL); + + connection_new_or_changed (plugin, path, connection); +} + +static NMIfcfgConnection * +_internal_new_connection (SCPluginIfcfg *self, + const char *path, + NMConnection *source, + GError **error) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); + NMIfcfgConnection *connection; + const char *cid; + GError *local = NULL; + gboolean ignore_error = FALSE; + + if (!source) { + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", path); + } + + connection = nm_ifcfg_connection_new (path, source, &local, &ignore_error); + if (!connection) { + if (!ignore_error) { + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " error: %s", + (local && local->message) ? local->message : "(unknown)"); + } + g_propagate_error (error, local); + return NULL; + } + + cid = nm_connection_get_id (NM_CONNECTION (connection)); + g_assert (cid); + + g_hash_table_insert (priv->connections, + (gpointer) nm_ifcfg_connection_get_path (connection), + connection); + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); + + if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " + "device due to NM_CONTROLLED/BRIDGE/VLAN.", cid); + } else { + /* Wait for the connection to become unmanaged once it knows the + * hardware IDs of its device, if/when the device gets plugged in. + */ + g_signal_connect (G_OBJECT (connection), "notify::" NM_IFCFG_CONNECTION_UNMANAGED, + G_CALLBACK (connection_unmanaged_changed), self); + } + + /* watch changes of ifcfg hardlinks */ + g_signal_connect (G_OBJECT (connection), "ifcfg-changed", + G_CALLBACK (connection_ifcfg_changed), self); + + return connection; +} + +static void +read_connections (SCPluginIfcfg *plugin) +{ + GDir *dir; + GError *err = NULL; + + dir = g_dir_open (IFCFG_DIR, 0, &err); + if (dir) { + const char *item; + + while ((item = g_dir_read_name (dir))) { + char *full_path; + + if (utils_should_ignore_file (item, TRUE)) + continue; + + full_path = g_build_filename (IFCFG_DIR, item, NULL); + if (utils_get_ifcfg_name (full_path, TRUE)) + _internal_new_connection (plugin, full_path, NULL, NULL); + g_free (full_path); + } + + g_dir_close (dir); + } else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Can not read directory '%s': %s", IFCFG_DIR, err->message); + g_error_free (err); + } +} + +/* Monitoring */ + +/* Callback for nm_settings_connection_replace_and_commit. Report any errors + * encountered when commiting connection settings updates. */ +static void +commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) +{ + if (error) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", + (error && error->message) ? error->message : "(unknown)"); + } +} + +static void +remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); + gboolean managed = FALSE; + const char *path; + + g_return_if_fail (self != NULL); + g_return_if_fail (connection != NULL); + + managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection); + path = nm_ifcfg_connection_get_path (connection); + + g_object_ref (connection); + g_hash_table_remove (priv->connections, path); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); + g_object_unref (connection); + + /* Emit unmanaged changes _after_ removing the connection */ + if (managed == FALSE) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); +} + +static void +connection_new_or_changed (SCPluginIfcfg *self, + const char *path, + NMIfcfgConnection *existing) +{ + NMIfcfgConnection *new; + GError *error = NULL; + gboolean ignore_error = FALSE; + const char *new_unmanaged = NULL, *old_unmanaged = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (path != NULL); + + if (!existing) { + /* Completely new connection */ + new = _internal_new_connection (self, path, NULL, NULL); + if (new) { + if (nm_ifcfg_connection_get_unmanaged_spec (new)) { + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } else { + /* Only managed connections are announced to the settings service */ + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); + } + } + return; + } + + new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, NULL, &error, &ignore_error); + if (!new) { + /* errors reading connection; remove it */ + if (!ignore_error) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s", + (error && error->message) ? error->message : "(unknown)"); + } + g_clear_error (&error); + + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", path); + remove_connection (self, existing); + return; + } + + /* Successfully read connection changes */ + + /* When the connections are the same, nothing is done */ + if (nm_connection_compare (NM_CONNECTION (existing), + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_EXACT)) { + g_object_unref (new); + return; + } + + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path); + + old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing)); + new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new)); + + if (new_unmanaged) { + if (!old_unmanaged) { + /* Unexport the connection by telling the settings service it's + * been removed, and notify the settings service by signalling that + * unmanaged specs have changed. + */ + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (existing)); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } + } else { + if (old_unmanaged) { /* now managed */ + const char *cid; + + cid = nm_connection_get_id (NM_CONNECTION (new)); + g_assert (cid); + + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its " + "device because NM_CONTROLLED was true.", cid); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing); + } + + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (existing), + NM_CONNECTION (new), + commit_cb, NULL); + + /* Update unmanaged status */ + g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } + g_object_unref (new); +} + +static void +dir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + char *path, *name; + NMIfcfgConnection *connection; + + path = g_file_get_path (file); + if (utils_should_ignore_file (path, FALSE)) { + g_free (path); + return; + } + + /* Given any ifcfg, keys, or routes file, get the ifcfg file path */ + name = utils_get_ifcfg_path (path); + g_free (path); + if (name) { + connection = g_hash_table_lookup (priv->connections, name); + switch (event_type) { + case G_FILE_MONITOR_EVENT_DELETED: + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name); + if (connection) + remove_connection (plugin, connection); + break; + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + /* Update or new */ + connection_new_or_changed (plugin, name, connection); + break; + default: + break; + } + g_free (name); + } +} + +static void +setup_ifcfg_monitoring (SCPluginIfcfg *plugin) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + GFile *file; + GFileMonitor *monitor; + + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + + file = g_file_new_for_path (IFCFG_DIR "/"); + monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); + + if (monitor) { + priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), plugin); + priv->monitor = monitor; + } +} + +static GSList * +get_connections (NMSystemConfigInterface *config) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + GSList *list = NULL; + GHashTableIter iter; + gpointer value; + + if (!priv->connections) { + setup_ifcfg_monitoring (plugin); + read_connections (plugin); + } + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value); + + if (!nm_ifcfg_connection_get_unmanaged_spec (exported)) + list = g_slist_prepend (list, value); + } + + return list; +} + +static void +check_unmanaged (gpointer key, gpointer data, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data); + const char *unmanaged_spec; + GSList *iter; + + unmanaged_spec = nm_ifcfg_connection_get_unmanaged_spec (connection); + if (!unmanaged_spec) + return; + + /* Just return if the unmanaged spec is already in the list */ + for (iter = *list; iter; iter = g_slist_next (iter)) { + if (!strcmp ((char *) iter->data, unmanaged_spec)) + return; + } + + *list = g_slist_prepend (*list, g_strdup (unmanaged_spec)); +} + +static GSList * +get_unmanaged_specs (NMSystemConfigInterface *config) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config); + GSList *list = NULL; + + if (!priv->connections) { + setup_ifcfg_monitoring (plugin); + read_connections (plugin); + } + + g_hash_table_foreach (priv->connections, check_unmanaged, &list); + return list; +} + +static NMSettingsConnection * +add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error) +{ + SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); + NMIfcfgConnection *added = NULL; + char *path = NULL; + + /* Write it out first, then add the connection to our internal list */ + if (writer_new_connection (connection, IFCFG_DIR, &path, error)) { + added = _internal_new_connection (self, path, connection, error); + g_free (path); + } + return (NMSettingsConnection *) added; +} + +#define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network" + +static char * +plugin_get_hostname (SCPluginIfcfg *plugin) +{ + shvarFile *network; + char *hostname; + gboolean ignore_localhost; + + network = svNewFile (SC_NETWORK_FILE); + if (!network) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Could not get hostname: failed to read " SC_NETWORK_FILE); + return NULL; + } + + hostname = svGetValue (network, "HOSTNAME", FALSE); + ignore_localhost = svTrueValue (network, "NM_IGNORE_HOSTNAME_LOCALHOST", FALSE); + if (ignore_localhost) { + /* Ignore a hostname of 'localhost' or 'localhost.localdomain' to preserve + * 'network' service behavior. + */ + if (hostname && (!strcmp (hostname, "localhost") || !strcmp (hostname, "localhost.localdomain"))) { + g_free (hostname); + hostname = NULL; + } + } + + svCloseFile (network); + return hostname; +} + +static gboolean +plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + shvarFile *network; + + network = svCreateFile (SC_NETWORK_FILE); + if (!network) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Could not save hostname: failed to create/open " SC_NETWORK_FILE); + return FALSE; + } + + svSetValue (network, "HOSTNAME", hostname, FALSE); + svWriteFile (network, 0644); + svCloseFile (network); + + g_free (priv->hostname); + priv->hostname = g_strdup (hostname); + return TRUE; +} + +static void +sc_network_changed_cb (NMInotifyHelper *ih, + struct inotify_event *evt, + const char *path, + gpointer user_data) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + char *new_hostname; + + if (evt->wd != priv->sc_network_wd) + return; + + new_hostname = plugin_get_hostname (plugin); + if ( (new_hostname && !priv->hostname) + || (!new_hostname && priv->hostname) + || (priv->hostname && new_hostname && strcmp (priv->hostname, new_hostname))) { + g_free (priv->hostname); + priv->hostname = new_hostname; + g_object_notify (G_OBJECT (plugin), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); + } else + g_free (new_hostname); +} + +static gboolean +impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, + const char *in_ifcfg, + const char **out_uuid, + const char **out_path, + GError **error) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + NMIfcfgConnection *connection; + NMSettingConnection *s_con; + const char *uuid; + const char *path; + + if (!g_path_is_absolute (in_ifcfg)) { + g_set_error (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg path '%s' is not absolute", in_ifcfg); + return FALSE; + } + + connection = g_hash_table_lookup (priv->connections, in_ifcfg); + if (!connection || nm_ifcfg_connection_get_unmanaged_spec (connection)) { + g_set_error (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg file '%s' unknown", in_ifcfg); + return FALSE; + } + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + if (!s_con) { + g_set_error (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + "unable to retrieve the connection setting"); + return FALSE; + } + + uuid = nm_setting_connection_get_uuid (s_con); + if (!uuid) { + g_set_error (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + "unable to get the UUID"); + return FALSE; + } + + path = nm_connection_get_path (NM_CONNECTION (connection)); + if (!path) { + g_set_error (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + "unable to get the connection D-Bus path"); + return FALSE; + } + + *out_uuid = g_strdup (uuid); + *out_path = g_strdup (path); + + return TRUE; +} + +static void +init (NMSystemConfigInterface *config) +{ +} + +static void +sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + NMInotifyHelper *ih; + GError *error = NULL; + gboolean success = FALSE; + + ih = nm_inotify_helper_get (); + priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (sc_network_changed_cb), plugin); + priv->sc_network_wd = nm_inotify_helper_add_watch (ih, SC_NETWORK_FILE); + + priv->hostname = plugin_get_hostname (plugin); + + priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (!priv->bus) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't connect to D-Bus: %s", + error->message); + g_clear_error (&error); + } else { + DBusConnection *tmp; + DBusGProxy *proxy; + int result; + + tmp = dbus_g_connection_get_connection (priv->bus); + dbus_connection_set_exit_on_disconnect (tmp, FALSE); + + proxy = dbus_g_proxy_new_for_name (priv->bus, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + if (!dbus_g_proxy_call (proxy, "RequestName", &error, + G_TYPE_STRING, DBUS_SERVICE_NAME, + G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID)) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't acquire D-Bus service: %s", + error->message); + g_clear_error (&error); + } else if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't acquire ifcfgrh1 D-Bus service (already taken)"); + } else + success = TRUE; + } + + if (!success) { + dbus_g_connection_unref (priv->bus); + priv->bus = NULL; + } +} + +static void +dispose (GObject *object) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (object); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + NMInotifyHelper *ih; + + if (priv->bus) { + dbus_g_connection_unref (priv->bus); + priv->bus = NULL; + } + + ih = nm_inotify_helper_get (); + + g_signal_handler_disconnect (ih, priv->ih_event_id); + + if (priv->sc_network_wd >= 0) + nm_inotify_helper_remove_watch (ih, priv->sc_network_wd); + + g_free (priv->hostname); + + if (priv->connections) + g_hash_table_destroy (priv->connections); + + if (priv->monitor) { + if (priv->monitor_id) + g_signal_handler_disconnect (priv->monitor, priv->monitor_id); + + g_file_monitor_cancel (priv->monitor); + g_object_unref (priv->monitor); + } + + G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object); + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, IFCFG_PLUGIN_NAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, IFCFG_PLUGIN_INFO); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + g_value_set_string (value, priv->hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + const char *hostname; + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + hostname = g_value_get_string (value); + if (hostname && strlen (hostname) < 1) + hostname = NULL; + plugin_set_hostname (SC_PLUGIN_IFCFG (object), hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate)); + + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class), + &dbus_glib_nm_ifcfg_rh_object_info); +} + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class) +{ + /* interface implementation */ + system_config_interface_class->get_connections = get_connections; + system_config_interface_class->add_connection = add_connection; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; + system_config_interface_class->init = init; +} + +G_MODULE_EXPORT GObject * +nm_system_config_factory (void) +{ + static SCPluginIfcfg *singleton = NULL; + SCPluginIfcfgPrivate *priv; + + if (!singleton) { + singleton = SC_PLUGIN_IFCFG (g_object_new (SC_TYPE_PLUGIN_IFCFG, NULL)); + if (singleton) { + priv = SC_PLUGIN_IFCFG_GET_PRIVATE (singleton); + if (priv->bus) + dbus_g_connection_register_g_object (priv->bus, + DBUS_OBJECT_PATH, + G_OBJECT (singleton)); + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Acquired D-Bus service %s", DBUS_SERVICE_NAME); + } + } else + g_object_ref (singleton); + + return G_OBJECT (singleton); +} diff --git a/src/settings/plugins/ifcfg-rh/plugin.h b/src/settings/plugins/ifcfg-rh/plugin.h new file mode 100644 index 00000000..d820a26e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/plugin.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Dan Williams <dcbw@redhat.com> + * Søren Sandmann <sandmann@daimi.au.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2008 Red Hat, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <glib-object.h> + +#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ()) +#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg)) +#define SC_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass)) +#define SC_IS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG)) +#define SC_IS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG)) +#define SC_PLUGIN_IFCFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass)) + +typedef struct _SCPluginIfcfg SCPluginIfcfg; +typedef struct _SCPluginIfcfgClass SCPluginIfcfgClass; + +struct _SCPluginIfcfg { + GObject parent; +}; + +struct _SCPluginIfcfgClass { + GObjectClass parent; +}; + +GType sc_plugin_ifcfg_get_type (void); + +#endif /* _PLUGIN_H_ */ + diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c new file mode 100644 index 00000000..c366dd40 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -0,0 +1,3466 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <sys/wait.h> +#include <ctype.h> +#include <sys/inotify.h> +#include <errno.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <netinet/ether.h> + +#ifndef __user +#define __user +#endif +#include <linux/types.h> +#include <wireless.h> +#undef __user + +#include <glib.h> +#include <glib/gi18n.h> +#include <nm-connection.h> +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-8021x.h> +#include <nm-utils.h> + +#include "common.h" +#include "shvar.h" +#include "utils.h" + +#include "reader.h" + +#define PLUGIN_PRINT(pname, fmt, args...) \ + { g_message (" " pname ": " fmt, ##args); } + +#define PLUGIN_WARN(pname, fmt, args...) \ + { g_warning (" " pname ": " fmt, ##args); } + +static gboolean +get_int (const char *str, int *value) +{ + char *e; + + errno = 0; + *value = strtol (str, &e, 0); + if (errno || *e != '\0') + return FALSE; + + return TRUE; +} + +static NMSetting * +make_connection_setting (const char *file, + shvarFile *ifcfg, + const char *type, + const char *suggested) +{ + NMSettingConnection *s_con; + const char *ifcfg_name = NULL; + char *new_id = NULL, *uuid = NULL, *value; + char *ifcfg_id; + + ifcfg_name = utils_get_ifcfg_name (file, TRUE); + if (!ifcfg_name) + return NULL; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Try the ifcfg file's internally defined name if available */ + ifcfg_id = svGetValue (ifcfg, "NAME", FALSE); + if (ifcfg_id && strlen (ifcfg_id)) + g_object_set (s_con, NM_SETTING_CONNECTION_ID, ifcfg_id, NULL); + + if (!nm_setting_connection_get_id (s_con)) { + if (suggested) { + /* For cosmetic reasons, if the suggested name is the same as + * the ifcfg files name, don't use it. Mainly for wifi so that + * the SSID is shown in the connection ID instead of just "wlan0". + */ + if (strcmp (ifcfg_name, suggested)) { + new_id = g_strdup_printf ("%s %s (%s)", reader_get_prefix (), suggested, ifcfg_name); + g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); + } + } + + /* Use the ifcfg file's name as a last resort */ + if (!nm_setting_connection_get_id (s_con)) { + new_id = g_strdup_printf ("%s %s", reader_get_prefix (), ifcfg_name); + g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); + } + } + + g_free (new_id); + g_free (ifcfg_id); + + /* Try for a UUID key before falling back to hashing the file name */ + uuid = svGetValue (ifcfg, "UUID", FALSE); + if (!uuid || !strlen (uuid)) { + g_free (uuid); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + } + g_object_set (s_con, + NM_SETTING_CONNECTION_TYPE, type, + NM_SETTING_CONNECTION_UUID, uuid, + NULL); + g_free (uuid); + + /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */ + g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, + svTrueValue (ifcfg, "ONBOOT", TRUE), + NULL); + + value = svGetValue (ifcfg, "USERS", FALSE); + if (value) { + char **items, **iter; + + items = g_strsplit_set (value, " ", -1); + for (iter = items; iter && *iter; iter++) { + if (strlen (*iter)) { + if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid USERS item '%s'", *iter); + } + } + g_free (value); + } + + return NM_SETTING (s_con); +} + +static gboolean +read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error) +{ + char *value = NULL; + struct ether_addr *mac; + + g_return_val_if_fail (ifcfg != NULL, FALSE); + g_return_val_if_fail (array != NULL, FALSE); + g_return_val_if_fail (*array == NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + value = svGetValue (ifcfg, key, FALSE); + if (!value || !strlen (value)) { + g_free (value); + return TRUE; + } + + mac = ether_aton (value); + if (!mac) { + g_free (value); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "%s: the MAC address '%s' was invalid.", key, value); + return FALSE; + } + + g_free (value); + *array = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); + return TRUE; +} + +static void +iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED) +{ + /* We are in the child process here; set a different process group to + * ensure signal isolation between child and parent. + */ + pid_t pid = getpid (); + setpgid (pid, pid); +} + +static char * +match_iscsiadm_tag (const char *line, const char *tag, gboolean *skip) +{ + char *p; + + if (g_ascii_strncasecmp (line, tag, strlen (tag))) + return NULL; + + p = strchr (line, '='); + if (!p) { + g_warning ("%s: malformed iscsiadm record: no = in '%s'.", + __func__, line); + *skip = TRUE; + return NULL; + } + + p++; /* advance past = */ + return g_strstrip (p); +} + +#define ISCSI_HWADDR_TAG "iface.hwaddress" +#define ISCSI_BOOTPROTO_TAG "iface.bootproto" +#define ISCSI_IPADDR_TAG "iface.ipaddress" +#define ISCSI_SUBNET_TAG "iface.subnet_mask" +#define ISCSI_GATEWAY_TAG "iface.gateway" +#define ISCSI_DNS1_TAG "iface.primary_dns" +#define ISCSI_DNS2_TAG "iface.secondary_dns" + +static gboolean +fill_ip4_setting_from_ibft (shvarFile *ifcfg, + NMSettingIP4Config *s_ip4, + const char *iscsiadm_path, + GError **error) +{ + const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL }; + const char *envp[1] = { NULL }; + gboolean success = FALSE, in_record = FALSE, hwaddr_matched = FALSE, skip = FALSE; + char *out = NULL, *err = NULL; + gint status = 0; + GByteArray *ifcfg_mac = NULL; + char **lines = NULL, **iter; + const char *method = NULL; + struct in_addr ipaddr; + struct in_addr gateway; + struct in_addr dns1; + struct in_addr dns2; + guint32 prefix = 0; + + g_return_val_if_fail (s_ip4 != NULL, FALSE); + g_return_val_if_fail (iscsiadm_path != NULL, FALSE); + + if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0, + iscsiadm_child_setup, NULL, &out, &err, &status, error)) + return FALSE; + + if (!WIFEXITED (status)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "%s exited abnormally.", iscsiadm_path); + goto done; + } + + if (WEXITSTATUS (status) != 0) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "%s exited with error %d. Message: '%s'", + iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)"); + goto done; + } + + if (!read_mac_address (ifcfg, "HWADDR", &ifcfg_mac, error)) + goto done; + /* Ensure we got a MAC */ + if (!ifcfg_mac) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing device MAC address (no HWADDR tag present)."); + goto done; + } + + memset (&ipaddr, 0, sizeof (ipaddr)); + memset (&gateway, 0, sizeof (gateway)); + memset (&dns1, 0, sizeof (dns1)); + memset (&dns2, 0, sizeof (dns2)); + + /* Success, lets parse the output */ + lines = g_strsplit_set (out, "\n\r", -1); + for (iter = lines; iter && *iter; iter++) { + char *p; + + if (!g_ascii_strcasecmp (*iter, "# BEGIN RECORD")) { + if (in_record) { + g_warning ("%s: malformed iscsiadm record: already parsing record.", __func__); + skip = TRUE; + } + } else if (!g_ascii_strcasecmp (*iter, "# END RECORD")) { + if (!skip && hwaddr_matched) { + /* Record is good; fill IP4 config with its info */ + if (!method) { + g_warning ("%s: malformed iscsiadm record: missing BOOTPROTO.", __func__); + return FALSE; + } + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL); + + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + NMIP4Address *addr; + + if (!ipaddr.s_addr || !prefix) { + g_warning ("%s: malformed iscsiadm record: BOOTPROTO=static " + "but missing IP address or prefix.", __func__); + return FALSE; + } + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ipaddr.s_addr); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gateway.s_addr); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + if (dns1.s_addr) + nm_setting_ip4_config_add_dns (s_ip4, dns1.s_addr); + if (dns2.s_addr) + nm_setting_ip4_config_add_dns (s_ip4, dns2.s_addr); + + // FIXME: DNS search domains? + } + return TRUE; + } + skip = FALSE; + hwaddr_matched = FALSE; + memset (&ipaddr, 0, sizeof (ipaddr)); + memset (&gateway, 0, sizeof (gateway)); + memset (&dns1, 0, sizeof (dns1)); + memset (&dns2, 0, sizeof (dns2)); + prefix = 0; + method = NULL; + } + + if (skip) + continue; + + /* HWADDR */ + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_HWADDR_TAG, &skip))) { + struct ether_addr *ibft_mac; + + ibft_mac = ether_aton (p); + if (!ibft_mac) { + g_warning ("%s: malformed iscsiadm record: invalid hwaddress.", __func__); + skip = TRUE; + continue; + } + + if (memcmp (ifcfg_mac->data, (guint8 *) ibft_mac->ether_addr_octet, ETH_ALEN)) { + /* This record isn't for the current device, ignore it */ + skip = TRUE; + continue; + } + + /* Success, this record is for this device */ + hwaddr_matched = TRUE; + } + + /* BOOTPROTO */ + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_BOOTPROTO_TAG, &skip))) { + if (!g_ascii_strcasecmp (p, "dhcp")) + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + else if (!g_ascii_strcasecmp (p, "static")) + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + else { + g_warning ("%s: malformed iscsiadm record: unknown BOOTPROTO '%s'.", + __func__, p); + skip = TRUE; + continue; + } + } + + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_IPADDR_TAG, &skip))) { + if (inet_pton (AF_INET, p, &ipaddr) < 1) { + g_warning ("%s: malformed iscsiadm record: invalid IP address '%s'.", + __func__, p); + skip = TRUE; + continue; + } + } + + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_SUBNET_TAG, &skip))) { + struct in_addr mask; + + if (inet_pton (AF_INET, p, &mask) < 1) { + g_warning ("%s: malformed iscsiadm record: invalid subnet mask '%s'.", + __func__, p); + skip = TRUE; + continue; + } + + prefix = nm_utils_ip4_netmask_to_prefix (mask.s_addr); + } + + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_GATEWAY_TAG, &skip))) { + if (inet_pton (AF_INET, p, &gateway) < 1) { + g_warning ("%s: malformed iscsiadm record: invalid IP gateway '%s'.", + __func__, p); + skip = TRUE; + continue; + } + } + + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS1_TAG, &skip))) { + if (inet_pton (AF_INET, p, &dns1) < 1) { + g_warning ("%s: malformed iscsiadm record: invalid DNS1 address '%s'.", + __func__, p); + skip = TRUE; + continue; + } + } + + if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS2_TAG, &skip))) { + if (inet_pton (AF_INET, p, &dns2) < 1) { + g_warning ("%s: malformed iscsiadm record: invalid DNS2 address '%s'.", + __func__, p); + skip = TRUE; + continue; + } + } + } + + success = TRUE; + +done: + if (ifcfg_mac) + g_byte_array_free (ifcfg_mac, TRUE); + g_strfreev (lines); + g_free (out); + g_free (err); + return success; +} + +static gboolean +read_ip4_address (shvarFile *ifcfg, + const char *tag, + guint32 *out_addr, + GError **error) +{ + char *value = NULL; + struct in_addr ip4_addr; + gboolean success = FALSE; + + g_return_val_if_fail (ifcfg != NULL, FALSE); + g_return_val_if_fail (tag != NULL, FALSE); + g_return_val_if_fail (out_addr != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + *out_addr = 0; + + value = svGetValue (ifcfg, tag, FALSE); + if (!value) + return TRUE; + + if (inet_pton (AF_INET, value, &ip4_addr) > 0) { + *out_addr = ip4_addr.s_addr; + success = TRUE; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid %s IP4 address '%s'", tag, value); + } + g_free (value); + return success; +} + +static gboolean +parse_ip6_address (const char *value, + struct in6_addr *out_addr, + GError **error) +{ + struct in6_addr ip6_addr; + gboolean success = FALSE; + + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (out_addr != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + *out_addr = in6addr_any; + + if (inet_pton (AF_INET6, value, &ip6_addr) > 0) { + *out_addr = ip6_addr; + success = TRUE; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 address '%s'", value); + } + return success; +} + +static NMIP4Address * +read_full_ip4_address (shvarFile *ifcfg, + const char *network_file, + guint32 which, + GError **error) +{ + NMIP4Address *addr; + char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag; + guint32 tmp; + gboolean success = FALSE; + shvarFile *network_ifcfg; + char *value; + + g_return_val_if_fail (which > 0, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + g_return_val_if_fail (network_file != NULL, NULL); + + addr = nm_ip4_address_new (); + if (which == 1) { + ip_tag = g_strdup ("IPADDR"); + prefix_tag = g_strdup ("PREFIX"); + netmask_tag = g_strdup ("NETMASK"); + gw_tag = g_strdup ("GATEWAY"); + } else { + ip_tag = g_strdup_printf ("IPADDR%u", which); + prefix_tag = g_strdup_printf ("PREFIX%u", which); + netmask_tag = g_strdup_printf ("NETMASK%u", which); + gw_tag = g_strdup_printf ("GATEWAY%u", which); + } + + /* IP address */ + if (!read_ip4_address (ifcfg, ip_tag, &tmp, error)) + goto error; + if (!tmp) { + nm_ip4_address_unref (addr); + addr = NULL; + success = TRUE; /* done */ + goto error; + } + nm_ip4_address_set_address (addr, tmp); + + /* Gateway */ + if (!read_ip4_address (ifcfg, gw_tag, &tmp, error)) + goto error; + if (tmp) + nm_ip4_address_set_gateway (addr, tmp); + else { + gboolean read_success; + + /* If no gateway in the ifcfg, try /etc/sysconfig/network instead */ + network_ifcfg = svNewFile (network_file); + if (network_ifcfg) { + read_success = read_ip4_address (network_ifcfg, "GATEWAY", &tmp, error); + svCloseFile (network_ifcfg); + if (!read_success) + goto error; + nm_ip4_address_set_gateway (addr, tmp); + } + } + + /* Prefix */ + value = svGetValue (ifcfg, prefix_tag, FALSE); + if (value) { + long int prefix; + + errno = 0; + prefix = strtol (value, NULL, 10); + if (errno || prefix <= 0 || prefix > 32) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 prefix '%s'", value); + g_free (value); + goto error; + } + nm_ip4_address_set_prefix (addr, (guint32) prefix); + g_free (value); + } + + /* Fall back to NETMASK if no PREFIX was specified */ + if (!nm_ip4_address_get_prefix (addr)) { + if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error)) + goto error; + nm_ip4_address_set_prefix (addr, nm_utils_ip4_netmask_to_prefix (tmp)); + } + + /* Try to autodetermine the prefix for the address' class */ + if (!nm_ip4_address_get_prefix (addr)) { + guint32 prefix = 0; + + prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); + nm_ip4_address_set_prefix (addr, prefix); + + value = svGetValue (ifcfg, ip_tag, FALSE); + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing %s, assuming %s/%u", + prefix_tag, value, prefix); + g_free (value); + } + + /* Validate the prefix */ + if (nm_ip4_address_get_prefix (addr) > 32) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing or invalid IP4 prefix '%d'", + nm_ip4_address_get_prefix (addr)); + goto error; + } + + success = TRUE; + +error: + if (!success) { + nm_ip4_address_unref (addr); + addr = NULL; + } + + g_free (ip_tag); + g_free (prefix_tag); + g_free (netmask_tag); + g_free (gw_tag); + return addr; +} + +static NMIP4Route * +read_one_ip4_route (shvarFile *ifcfg, + const char *network_file, + guint32 which, + GError **error) +{ + NMIP4Route *route; + char *ip_tag, *netmask_tag, *gw_tag, *metric_tag, *value; + guint32 tmp; + gboolean success = FALSE; + + g_return_val_if_fail (ifcfg != NULL, NULL); + g_return_val_if_fail (network_file != NULL, NULL); + g_return_val_if_fail (which >= 0, NULL); + + route = nm_ip4_route_new (); + + ip_tag = g_strdup_printf ("ADDRESS%u", which); + netmask_tag = g_strdup_printf ("NETMASK%u", which); + gw_tag = g_strdup_printf ("GATEWAY%u", which); + metric_tag = g_strdup_printf ("METRIC%u", which); + + /* Destination */ + if (!read_ip4_address (ifcfg, ip_tag, &tmp, error)) + goto out; + if (!tmp) { + /* Check whether IP is missing or 0.0.0.0 */ + char *val; + val = svGetValue (ifcfg, ip_tag, FALSE); + if (!val) { + nm_ip4_route_unref (route); + route = NULL; + success = TRUE; /* done */ + goto out; + } + g_free (val); + } + nm_ip4_route_set_dest (route, tmp); + + /* Next hop */ + if (!read_ip4_address (ifcfg, gw_tag, &tmp, error)) + goto out; + /* No need to check tmp, because we don't make distinction between missing GATEWAY IP and 0.0.0.0 */ + nm_ip4_route_set_next_hop (route, tmp); + + /* Prefix */ + if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error)) + goto out; + nm_ip4_route_set_prefix (route, nm_utils_ip4_netmask_to_prefix (tmp)); + + /* Validate the prefix */ + if ( !nm_ip4_route_get_prefix (route) + || nm_ip4_route_get_prefix (route) > 32) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing or invalid IP4 prefix '%d'", + nm_ip4_route_get_prefix (route)); + goto out; + } + + /* Metric */ + value = svGetValue (ifcfg, metric_tag, FALSE); + if (value) { + long int metric; + + errno = 0; + metric = strtol (value, NULL, 10); + if (errno || metric < 0) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 route metric '%s'", value); + g_free (value); + goto out; + } + nm_ip4_route_set_metric (route, (guint32) metric); + g_free (value); + } + + success = TRUE; + +out: + if (!success) { + nm_ip4_route_unref (route); + route = NULL; + } + + g_free (ip_tag); + g_free (netmask_tag); + g_free (gw_tag); + g_free (metric_tag); + return route; +} + +static gboolean +read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error) +{ + char *contents = NULL; + gsize len = 0; + char **lines = NULL, **iter; + GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; + GMatchInfo *match_info; + NMIP4Route *route; + struct in_addr ip4_addr; + char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; + long int prefix_int, metric_int; + gboolean success = FALSE; + + const char *pattern_empty = "^\\s*(\\#.*)?$"; + const char *pattern_to1 = "^\\s*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */ + "(?:/(\\d{1,2}))?"; /* optional prefix */ + const char *pattern_to2 = "to\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */ + "(?:/(\\d{1,2}))?"; /* optional prefix */ + const char *pattern_via = "via\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"; /* IP of gateway */ + const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */ + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (s_ip4 != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + /* Read the route file */ + if (!g_file_get_contents (filename, &contents, &len, NULL)) + return FALSE; + + if (len == 0) { + g_free (contents); + return FALSE; + } + + /* Create regexes for pieces to be matched */ + regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL); + regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL); + regex_via = g_regex_new (pattern_via, 0, 0, NULL); + regex_metric = g_regex_new (pattern_metric, 0, 0, NULL); + + /* New NMIP4Route structure */ + route = nm_ip4_route_new (); + + /* Iterate through file lines */ + lines = g_strsplit_set (contents, "\n\r", -1); + for (iter = lines; iter && *iter; iter++) { + + /* Skip empty lines */ + if (g_regex_match_simple (pattern_empty, *iter, 0, 0)) + continue; + + /* Destination */ + g_regex_match (regex_to1, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_regex_match (regex_to2, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IP4 route destination address in record: '%s'", *iter); + goto error; + } + } + dest = g_match_info_fetch (match_info, 1); + g_match_info_free (match_info); + if (!strcmp (dest, "default")) + strcpy (dest, "0.0.0.0"); + if (inet_pton (AF_INET, dest, &ip4_addr) != 1) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 route destination address '%s'", dest); + g_free (dest); + goto error; + } + nm_ip4_route_set_dest (route, ip4_addr.s_addr); + g_free (dest); + + /* Prefix - is optional; 32 if missing */ + prefix = g_match_info_fetch (match_info, 2); + prefix_int = 32; + if (prefix) { + errno = 0; + prefix_int = strtol (prefix, NULL, 10); + if (errno || prefix_int < 0 || prefix_int > 32) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 route destination prefix '%s'", prefix); + g_free (prefix); + goto error; + } + } + + nm_ip4_route_set_prefix (route, (guint32) prefix_int); + g_free (prefix); + + /* Next hop */ + g_regex_match (regex_via, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IP4 route gateway address in record: '%s'", *iter); + goto error; + } + next_hop = g_match_info_fetch (match_info, 1); + g_match_info_free (match_info); + if (inet_pton (AF_INET, next_hop, &ip4_addr) != 1) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 route gateway address '%s'", next_hop); + g_free (next_hop); + goto error; + } + nm_ip4_route_set_next_hop (route, ip4_addr.s_addr); + g_free (next_hop); + + /* Metric */ + g_regex_match (regex_metric, *iter, 0, &match_info); + metric_int = 0; + if (g_match_info_matches (match_info)) { + metric = g_match_info_fetch (match_info, 1); + errno = 0; + metric_int = strtol (metric, NULL, 10); + if (errno || metric_int < 0) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP4 route metric '%s'", metric); + g_free (metric); + goto error; + } + g_free (metric); + } + + nm_ip4_route_set_metric (route, (guint32) metric_int); + g_match_info_free (match_info); + + if (!nm_setting_ip4_config_add_route (s_ip4, route)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 route"); + + } + + success = TRUE; + +error: + g_free (contents); + g_strfreev (lines); + nm_ip4_route_unref (route); + g_regex_unref (regex_to1); + g_regex_unref (regex_to2); + g_regex_unref (regex_via); + g_regex_unref (regex_metric); + + return success; +} + +static NMIP6Address * +parse_full_ip6_address (shvarFile *ifcfg, + const char *network_file, + const char *addr_str, + int i, + GError **error) +{ + NMIP6Address *addr = NULL; + char **list; + char *ip_val, *prefix_val; + shvarFile *network_ifcfg; + char *value = NULL; + struct in6_addr tmp = IN6ADDR_ANY_INIT; + gboolean success = FALSE; + + g_return_val_if_fail (addr_str != NULL, NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (*error == NULL, NULL); + + /* Split the adddress and prefix */ + list = g_strsplit_set (addr_str, "/", 2); + if (g_strv_length (list) < 1) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 address '%s'", addr_str); + goto error; + } + + ip_val = list[0]; + prefix_val = list[1]; + + addr = nm_ip6_address_new (); + /* IP address */ + if (ip_val) { + if (!parse_ip6_address (ip_val, &tmp, error)) + goto error; + } + nm_ip6_address_set_address (addr, &tmp); + + /* Prefix */ + if (prefix_val) { + long int prefix; + + errno = 0; + prefix = strtol (prefix_val, NULL, 10); + if (errno || prefix <= 0 || prefix > 128) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 prefix '%s'", prefix_val); + goto error; + } + nm_ip6_address_set_prefix (addr, (guint32) prefix); + } else { + /* Missing prefix is treated as prefix of 64 */ + nm_ip6_address_set_prefix (addr, 64); + } + + /* Gateway */ + tmp = in6addr_any; + value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE); + if (i != 0) { + /* We don't support gateways for IPV6ADDR_SECONDARIES yet */ + g_free (value); + value = NULL; + } + if (!value) { + /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */ + network_ifcfg = svNewFile (network_file); + if (network_ifcfg) { + value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE); + svCloseFile (network_ifcfg); + } + } + if (value) { + char *ptr; + + if ((ptr = strchr (value, '%')) != NULL) + *ptr = '\0'; /* remove %interface prefix if present */ + if (!parse_ip6_address (value, &tmp, error)) + goto error; + nm_ip6_address_set_gateway (addr, &tmp); + } + + success = TRUE; + +error: + if (!success) { + nm_ip6_address_unref (addr); + addr = NULL; + } + + g_strfreev (list); + g_free (value); + return addr; +} + +/* IPv6 address is very complex to describe completely by a regular expression, + * so don't try to, rather use looser syntax to comprise all possibilities + * NOTE: The regexes below don't describe all variants allowed by 'ip route add', + * namely destination IP without 'to' keyword is recognized just at line start. + */ +#define IPV6_ADDR_REGEX "[0-9A-Fa-f:.]+" + +static gboolean +read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error) +{ + char *contents = NULL; + gsize len = 0; + char **lines = NULL, **iter; + GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; + GMatchInfo *match_info; + NMIP6Route *route; + struct in6_addr ip6_addr; + char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; + long int prefix_int, metric_int; + gboolean success = FALSE; + + const char *pattern_empty = "^\\s*(\\#.*)?$"; + const char *pattern_to1 = "^\\s*(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */ + "(?:/(\\d{1,2}))?"; /* optional prefix */ + const char *pattern_to2 = "to\\s+(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */ + "(?:/(\\d{1,2}))?"; /* optional prefix */ + const char *pattern_via = "via\\s+(" IPV6_ADDR_REGEX ")"; /* IPv6 of gateway */ + const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */ + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (s_ip6 != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + /* Read the route file */ + if (!g_file_get_contents (filename, &contents, &len, NULL)) + return FALSE; + + if (len == 0) { + g_free (contents); + return FALSE; + } + + /* Create regexes for pieces to be matched */ + regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL); + regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL); + regex_via = g_regex_new (pattern_via, 0, 0, NULL); + regex_metric = g_regex_new (pattern_metric, 0, 0, NULL); + + /* New NMIP6Route structure */ + route = nm_ip6_route_new (); + + /* Iterate through file lines */ + lines = g_strsplit_set (contents, "\n\r", -1); + for (iter = lines; iter && *iter; iter++) { + + /* Skip empty lines */ + if (g_regex_match_simple (pattern_empty, *iter, 0, 0)) + continue; + + /* Destination */ + g_regex_match (regex_to1, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_regex_match (regex_to2, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IP6 route destination address in record: '%s'", *iter); + goto error; + } + } + dest = g_match_info_fetch (match_info, 1); + g_match_info_free (match_info); + if (!strcmp (dest, "default")) + strcpy (dest, "::"); + if (inet_pton (AF_INET6, dest, &ip6_addr) != 1) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 route destination address '%s'", dest); + g_free (dest); + goto error; + } + nm_ip6_route_set_dest (route, &ip6_addr); + g_free (dest); + + /* Prefix - is optional; 128 if missing */ + prefix = g_match_info_fetch (match_info, 2); + prefix_int = 128; + if (prefix) { + errno = 0; + prefix_int = strtol (prefix, NULL, 10); + if (errno || prefix_int < 0 || prefix_int > 128) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 route destination prefix '%s'", prefix); + g_free (prefix); + goto error; + } + } + + nm_ip6_route_set_prefix (route, (guint32) prefix_int); + g_free (prefix); + + /* Next hop */ + g_regex_match (regex_via, *iter, 0, &match_info); + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IP6 route gateway address in record: '%s'", *iter); + goto error; + } + next_hop = g_match_info_fetch (match_info, 1); + g_match_info_free (match_info); + if (inet_pton (AF_INET6, next_hop, &ip6_addr) != 1) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 route gateway address '%s'", next_hop); + g_free (next_hop); + goto error; + } + nm_ip6_route_set_next_hop (route, &ip6_addr); + g_free (next_hop); + + /* Metric */ + g_regex_match (regex_metric, *iter, 0, &match_info); + metric_int = 0; + if (g_match_info_matches (match_info)) { + metric = g_match_info_fetch (match_info, 1); + errno = 0; + metric_int = strtol (metric, NULL, 10); + if (errno || metric_int < 0 || metric_int > G_MAXUINT32) { + g_match_info_free (match_info); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid IP6 route metric '%s'", metric); + g_free (metric); + goto error; + } + g_free (metric); + } + + nm_ip6_route_set_metric (route, (guint32) metric_int); + g_match_info_free (match_info); + + if (!nm_setting_ip6_config_add_route (s_ip6, route)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 route"); + } + + success = TRUE; + +error: + g_free (contents); + g_strfreev (lines); + nm_ip6_route_unref (route); + g_regex_unref (regex_to1); + g_regex_unref (regex_to2); + g_regex_unref (regex_via); + g_regex_unref (regex_metric); + + return success; +} + + +static NMSetting * +make_ip4_setting (shvarFile *ifcfg, + const char *network_file, + const char *iscsiadm_path, + gboolean valid_ip6_config, + GError **error) +{ + NMSettingIP4Config *s_ip4 = NULL; + char *value = NULL; + char *route_path = NULL; + char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + guint32 i; + shvarFile *network_ifcfg; + shvarFile *route_ifcfg; + gboolean never_default = FALSE, tmp_success; + + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + if (!s_ip4) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not allocate IP4 setting"); + return NULL; + } + + /* First check if DEFROUTE is set for this device; DEFROUTE has the + * opposite meaning from never-default. The default if DEFROUTE is not + * specified is DEFROUTE=yes which means that this connection can be used + * as a default route + */ + never_default = !svTrueValue (ifcfg, "DEFROUTE", TRUE); + + /* Then check if GATEWAYDEV; it's global and overrides DEFROUTE */ + network_ifcfg = svNewFile (network_file); + if (network_ifcfg) { + char *gatewaydev; + + /* Get the connection ifcfg device name and the global gateway device */ + value = svGetValue (ifcfg, "DEVICE", FALSE); + gatewaydev = svGetValue (network_ifcfg, "GATEWAYDEV", FALSE); + + /* If there was a global gateway device specified, then only connections + * for that device can be the default connection. + */ + if (gatewaydev && value) + never_default = !!strcmp (value, gatewaydev); + + g_free (gatewaydev); + g_free (value); + svCloseFile (network_ifcfg); + } + + value = svGetValue (ifcfg, "BOOTPROTO", FALSE); + if (value) { + if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")) + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + else if (!g_ascii_strcasecmp (value, "ibft")) { + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL); + /* iSCSI Boot Firmware Table: need to read values from the iSCSI + * firmware for this device and create the IP4 setting using those. + */ + if (fill_ip4_setting_from_ibft (ifcfg, s_ip4, iscsiadm_path, error)) + return NM_SETTING (s_ip4); + g_object_unref (s_ip4); + return NULL; + } else if (!g_ascii_strcasecmp (value, "autoip")) { + g_free (value); + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, + NULL); + return NM_SETTING (s_ip4); + } else if (!g_ascii_strcasecmp (value, "shared")) { + g_free (value); + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, + NULL); + return NM_SETTING (s_ip4); + } else if (!g_ascii_strcasecmp (value, "none") || !g_ascii_strcasecmp (value, "static")) { + /* Static IP */ + } else if (strlen (value)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown BOOTPROTO '%s'", value); + g_free (value); + goto done; + } + g_free (value); + } else { + char *tmp_ip4, *tmp_prefix, *tmp_netmask; + + /* If there is no BOOTPROTO, no IPADDR, no PREFIX, no NETMASK, but + * valid IPv6 configuration, assume that IPv4 is disabled. Otherwise, + * if there is no IPv6 configuration, assume DHCP is to be used. + * Happens with minimal ifcfg files like the following that anaconda + * sometimes used to write out: + * + * DEVICE=eth0 + * HWADDR=11:22:33:44:55:66 + * + */ + tmp_ip4 = svGetValue (ifcfg, "IPADDR", FALSE); + tmp_prefix = svGetValue (ifcfg, "PREFIX", FALSE); + tmp_netmask = svGetValue (ifcfg, "NETMASK", FALSE); + if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) { + if (valid_ip6_config) { + /* Nope, no IPv4 */ + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + return NM_SETTING (s_ip4); + } + + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + } + g_free (tmp_ip4); + g_free (tmp_prefix); + g_free (tmp_netmask); + } + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, method, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE), + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", TRUE), + NULL); + + /* Handle manual settings */ + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + NMIP4Address *addr; + + for (i = 1; i < 256; i++) { + addr = read_full_ip4_address (ifcfg, network_file, i, error); + if (error && *error) + goto done; + if (!addr) + break; + + if (!nm_setting_ip4_config_add_address (s_ip4, addr)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 address"); + nm_ip4_address_unref (addr); + } + } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE); + if (value && strlen (value)) + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, value, NULL); + g_free (value); + + value = svGetValue (ifcfg, "DHCP_CLIENT_ID", FALSE); + if (value && strlen (value)) + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, value, NULL); + g_free (value); + } + + /* DNS servers + * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) + */ + for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) { + char *tag; + guint32 dns; + struct in6_addr ip6_dns; + GError *tmp_err = NULL; + + tag = g_strdup_printf ("DNS%u", i); + tmp_success = read_ip4_address (ifcfg, tag, &dns, error); + if (!tmp_success) { + /* if it's IPv6, don't exit */ + dns = 0; + value = svGetValue (ifcfg, tag, FALSE); + if (value) { + tmp_success = parse_ip6_address (value, &ip6_dns, &tmp_err); + g_clear_error (&tmp_err); + g_free (value); + } + if (!tmp_success) { + g_free (tag); + goto done; + } + g_clear_error (error); + } + + if (dns && !nm_setting_ip4_config_add_dns (s_ip4, dns)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS server %s", tag); + g_free (tag); + } + + /* DNS searches */ + value = svGetValue (ifcfg, "DOMAIN", FALSE); + if (value) { + char **searches = NULL; + + searches = g_strsplit (value, " ", 0); + if (searches) { + char **item; + for (item = searches; *item; item++) { + if (strlen (*item)) { + if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS domain '%s'", *item); + } + } + g_strfreev (searches); + } + g_free (value); + } + + /* Static routes - route-<name> file */ + route_path = utils_get_route_path (ifcfg->fileName); + if (!route_path) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not get route file path for '%s'", ifcfg->fileName); + goto done; + } + + /* First test new/legacy syntax */ + if (utils_has_route_file_new_syntax (route_path)) { + /* Parse route file in new syntax */ + g_free (route_path); + route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE); + if (route_ifcfg) { + NMIP4Route *route; + for (i = 0; i < 256; i++) { + route = read_one_ip4_route (route_ifcfg, network_file, i, error); + if (error && *error) { + svCloseFile (route_ifcfg); + goto done; + } + if (!route) + break; + + if (!nm_setting_ip4_config_add_route (s_ip4, route)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 route"); + nm_ip4_route_unref (route); + } + svCloseFile (route_ifcfg); + } + } else { + read_route_file_legacy (route_path, s_ip4, error); + g_free (route_path); + if (error && *error) + goto done; + } + + /* Legacy value NM used for a while but is incorrect (rh #459370) */ + if (!nm_setting_ip4_config_get_num_dns_searches (s_ip4)) { + value = svGetValue (ifcfg, "SEARCH", FALSE); + if (value) { + char **searches = NULL; + + searches = g_strsplit (value, " ", 0); + if (searches) { + char **item; + for (item = searches; *item; item++) { + if (strlen (*item)) { + if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS search '%s'", *item); + } + } + g_strfreev (searches); + } + g_free (value); + } + } + + return NM_SETTING (s_ip4); + +done: + g_object_unref (s_ip4); + return NULL; +} + +static NMSetting * +make_ip6_setting (shvarFile *ifcfg, + const char *network_file, + const char *iscsiadm_path, + GError **error) +{ + NMSettingIP6Config *s_ip6 = NULL; + char *value = NULL; + char *str_value; + char *route6_path = NULL; + gboolean bool_value, ipv6forwarding, ipv6_autoconf, dhcp6 = FALSE; + char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + guint32 i; + shvarFile *network_ifcfg; + gboolean never_default = FALSE, tmp_success; + + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + if (!s_ip6) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not allocate IP6 setting"); + return NULL; + } + + /* Is IPV6 enabled? Set method to "ignored", when not enabled */ + str_value = svGetValue (ifcfg, "IPV6INIT", FALSE); + bool_value = svTrueValue (ifcfg, "IPV6INIT", FALSE); + if (!str_value) { + network_ifcfg = svNewFile (network_file); + if (network_ifcfg) { + bool_value = svTrueValue (network_ifcfg, "IPV6INIT", FALSE); + svCloseFile (network_ifcfg); + } + } + g_free (str_value); + + if (!bool_value) { + /* IPv6 is disabled */ + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + return NM_SETTING (s_ip6); + } + + /* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the + * opposite meaning from never-default. The default if IPV6_DEFROUTE is not + * specified is IPV6_DEFROUTE=yes which means that this connection can be used + * as a default route + */ + never_default = !svTrueValue (ifcfg, "IPV6_DEFROUTE", TRUE); + + /* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified; + * they are global and override IPV6_DEFROUTE + * When both are set, the device specified in IPV6_DEFAULTGW takes preference. + */ + network_ifcfg = svNewFile (network_file); + if (network_ifcfg) { + char *ipv6_defaultgw, *ipv6_defaultdev; + char *default_dev = NULL; + + /* Get the connection ifcfg device name and the global default route device */ + value = svGetValue (ifcfg, "DEVICE", FALSE); + ipv6_defaultgw = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE); + ipv6_defaultdev = svGetValue (network_ifcfg, "IPV6_DEFAULTDEV", FALSE); + + if (ipv6_defaultgw) { + default_dev = strchr (ipv6_defaultgw, '%'); + if (default_dev) + default_dev++; + } + if (!default_dev) + default_dev = ipv6_defaultdev; + + /* If there was a global default route device specified, then only connections + * for that device can be the default connection. + */ + if (default_dev && value) + never_default = !!strcmp (value, default_dev); + + g_free (ipv6_defaultgw); + g_free (ipv6_defaultdev); + g_free (value); + svCloseFile (network_ifcfg); + } + + /* Find out method property */ + ipv6forwarding = svTrueValue (ifcfg, "IPV6FORWARDING", FALSE); + ipv6_autoconf = svTrueValue (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding); + dhcp6 = svTrueValue (ifcfg, "DHCPV6C", FALSE); + + if (ipv6_autoconf) + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + else if (dhcp6) + method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; + else { + /* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */ + str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE); + if (!str_value) + str_value = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE); + + if (!str_value) + method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + g_free (str_value); + } + /* TODO - handle other methods */ + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, method, + NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE), + NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NULL); + + if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + NMIP6Address *addr; + char *val; + char *ipv6addr, *ipv6addr_secondaries; + char **list = NULL, **iter; + + ipv6addr = svGetValue (ifcfg, "IPV6ADDR", FALSE); + ipv6addr_secondaries = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE); + + val = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL, + ipv6addr ? ipv6addr : "", + ipv6addr_secondaries ? ipv6addr_secondaries : "", + NULL); + g_free (ipv6addr); + g_free (ipv6addr_secondaries); + + list = g_strsplit_set (val, " ", 0); + g_free (val); + for (iter = list, i = 0; iter && *iter; iter++, i++) { + addr = parse_full_ip6_address (ifcfg, network_file, *iter, i, error); + if (!addr) { + g_strfreev (list); + goto error; + } + + if (!nm_setting_ip6_config_add_address (s_ip6, addr)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 address"); + nm_ip6_address_unref (addr); + } + g_strfreev (list); + } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + /* TODO - autoconf or DHCPv6 stuff goes here */ + } + + /* DNS servers + * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) + */ + for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) { + char *tag; + struct in6_addr ip6_dns; + + ip6_dns = in6addr_any; + tag = g_strdup_printf ("DNS%u", i); + value = svGetValue (ifcfg, tag, FALSE); + if (value) + tmp_success = parse_ip6_address (value, &ip6_dns, error); + + if (!tmp_success) { + struct in_addr ip4_addr; + if (inet_pton (AF_INET, value, &ip4_addr) != 1) { + g_free (tag); + g_free (value); + goto error; + } + /* ignore error - it is IPv4 address */ + tmp_success = TRUE; + g_clear_error (error); + } + + if (!IN6_IS_ADDR_UNSPECIFIED (&ip6_dns) && !nm_setting_ip6_config_add_dns (s_ip6, &ip6_dns)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS server %s", tag); + g_free (tag); + g_free (value); + } + + /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */ + + /* Read static routes from route6-<interface> file */ + route6_path = utils_get_route6_path (ifcfg->fileName); + if (!route6_path) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not get route6 file path for '%s'", ifcfg->fileName); + goto error; + } + + read_route6_file (route6_path, s_ip6, error); + g_free (route6_path); + if (error && *error) + goto error; + + return NM_SETTING (s_ip6); + +error: + g_object_unref (s_ip6); + return NULL; +} + +static gboolean +add_one_wep_key (shvarFile *ifcfg, + const char *shvar_key, + guint8 key_idx, + gboolean passphrase, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + char *key = NULL; + char *value = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (ifcfg != NULL, FALSE); + g_return_val_if_fail (shvar_key != NULL, FALSE); + g_return_val_if_fail (key_idx <= 3, FALSE); + g_return_val_if_fail (s_wsec != NULL, FALSE); + + value = svGetValue (ifcfg, shvar_key, FALSE); + if (!value || !strlen (value)) { + g_free (value); + return TRUE; + } + + /* Validate keys */ + if (passphrase) { + if (strlen (value) && strlen (value) < 64) { + key = g_strdup (value); + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_PASSPHRASE, + NULL); + } + } else { + if (strlen (value) == 10 || strlen (value) == 26) { + /* Hexadecimal WEP key */ + char *p = value; + + while (*p) { + if (!g_ascii_isxdigit (*p)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid hexadecimal WEP key."); + goto out; + } + p++; + } + key = g_strdup (value); + } else if ( !strncmp (value, "s:", 2) + && (strlen (value) == 7 || strlen (value) == 15)) { + /* ASCII key */ + char *p = value + 2; + + while (*p) { + if (!isascii ((int) (*p))) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid ASCII WEP key."); + goto out; + } + p++; + } + + /* Remove 's:' prefix. + * Don't convert to hex string. wpa_supplicant takes 'wep_key0' option over D-Bus as byte array + * and converts it to hex string itself. Even though we convert hex string keys into a bin string + * before passing to wpa_supplicant, this prevents two unnecessary conversions. And mainly, + * ASCII WEP key doesn't change to HEX WEP key in UI, which could confuse users. + */ + key = g_strdup (value + 2); + } + } + + if (key) { + nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key); + success = TRUE; + } else + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid WEP key length."); + +out: + g_free (value); + return success; +} + +static gboolean +read_wep_keys (shvarFile *ifcfg, + guint8 def_idx, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + /* Try hex/ascii keys first */ + if (!add_one_wep_key (ifcfg, "KEY1", 0, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY2", 1, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY3", 2, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY4", 3, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY", def_idx, FALSE, s_wsec, error)) + return FALSE; + + /* And then passphrases */ + if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE1", 0, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE2", 1, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE3", 2, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE4", 3, TRUE, s_wsec, error)) + return FALSE; + + return TRUE; +} + +static NMSettingSecretFlags +read_secret_flags (shvarFile *ifcfg, const char *flags_key) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + char *val; + + g_return_val_if_fail (flags_key != NULL, NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (flags_key[0] != '\0', NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (g_str_has_suffix (flags_key, "_FLAGS"), NM_SETTING_SECRET_FLAG_NONE); + + val = svGetValue (ifcfg, flags_key, FALSE); + if (val) { + if (strstr (val, SECRET_FLAG_AGENT)) + flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + if (strstr (val, SECRET_FLAG_NOT_SAVED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; + if (strstr (val, SECRET_FLAG_NOT_REQUIRED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; + + g_free (val); + } + return flags; +} + +static NMSetting * +make_wep_setting (shvarFile *ifcfg, + const char *file, + GError **error) +{ + NMSettingWirelessSecurity *s_wsec; + char *value; + shvarFile *keys_ifcfg = NULL; + int default_key_idx = 0; + gboolean has_default_key = FALSE, success; + NMSettingSecretFlags key_flags; + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); + + value = svGetValue (ifcfg, "DEFAULTKEY", FALSE); + if (value) { + success = get_int (value, &default_key_idx); + if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) { + has_default_key = TRUE; + default_key_idx--; /* convert to [0...3] */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL); + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid default WEP key '%s'", value); + g_free (value); + goto error; + } + g_free (value); + } + + /* Read WEP key flags */ + key_flags = read_secret_flags (ifcfg, "WEP_KEY_FLAGS"); + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL); + + /* Read keys in the ifcfg file if they are system-owned */ + if (key_flags == NM_SETTING_SECRET_FLAG_NONE) { + if (!read_wep_keys (ifcfg, default_key_idx, s_wsec, error)) + goto error; + + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + if (keys_ifcfg) { + if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wsec, error)) { + svCloseFile (keys_ifcfg); + goto error; + } + svCloseFile (keys_ifcfg); + g_assert (error == NULL || *error == NULL); + } + } + + value = svGetValue (ifcfg, "SECURITYMODE", FALSE); + if (value) { + char *lcase; + + lcase = g_ascii_strdown (value, -1); + g_free (value); + + if (!strcmp (lcase, "open")) { + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); + } else if (!strcmp (lcase, "restricted")) { + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL); + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid WEP authentication algorithm '%s'", + lcase); + g_free (lcase); + goto error; + } + g_free (lcase); + } + + /* If no WEP keys were given, and the keys are not agent-owned, and no + * default WEP key index was given, then the connection is unencrypted. + */ + if ( !nm_setting_wireless_security_get_wep_key (s_wsec, 0) + && !nm_setting_wireless_security_get_wep_key (s_wsec, 1) + && !nm_setting_wireless_security_get_wep_key (s_wsec, 2) + && !nm_setting_wireless_security_get_wep_key (s_wsec, 3) + && (has_default_key == FALSE) + && (key_flags == NM_SETTING_SECRET_FLAG_NONE)) { + const char *auth_alg; + + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + if (auth_alg && !strcmp (auth_alg, "shared")) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "WEP Shared Key authentication is invalid for " + "unencrypted connections."); + goto error; + } + + /* Unencrypted */ + g_object_unref (s_wsec); + s_wsec = NULL; + } + + return (NMSetting *) s_wsec; + +error: + if (s_wsec) + g_object_unref (s_wsec); + return NULL; +} + +static gboolean +fill_wpa_ciphers (shvarFile *ifcfg, + NMSettingWirelessSecurity *wsec, + gboolean group, + gboolean adhoc) +{ + char *value = NULL, *p; + char **list = NULL, **iter; + int i = 0; + + p = value = svGetValue (ifcfg, group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", TRUE); + if (!value) + return TRUE; + + /* Strip quotes */ + if (p[0] == '"') + p++; + if (p[strlen (p) - 1] == '"') + p[strlen (p) - 1] = '\0'; + + list = g_strsplit_set (p, " ", 0); + for (iter = list; iter && *iter; iter++, i++) { + /* Ad-Hoc configurations cannot have pairwise ciphers, and can only + * have one group cipher. Ignore any additional group ciphers and + * any pairwise ciphers specified. + */ + if (adhoc) { + if (group && (i > 0)) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)", + *iter); + continue; + } else if (!group) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)", + *iter); + continue; + } + } + + if (!strcmp (*iter, "CCMP")) { + if (group) + nm_setting_wireless_security_add_group (wsec, "ccmp"); + else + nm_setting_wireless_security_add_pairwise (wsec, "ccmp"); + } else if (!strcmp (*iter, "TKIP")) { + if (group) + nm_setting_wireless_security_add_group (wsec, "tkip"); + else + nm_setting_wireless_security_add_pairwise (wsec, "tkip"); + } else if (group && !strcmp (*iter, "WEP104")) + nm_setting_wireless_security_add_group (wsec, "wep104"); + else if (group && !strcmp (*iter, "WEP40")) + nm_setting_wireless_security_add_group (wsec, "wep40"); + else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring invalid %s cipher '%s'", + group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", + *iter); + } + } + + if (list) + g_strfreev (list); + g_free (value); + return TRUE; +} + +#define WPA_PMK_LEN 32 + +static char * +parse_wpa_psk (shvarFile *ifcfg, + const char *file, + const GByteArray *ssid, + GError **error) +{ + shvarFile *keys_ifcfg; + char *psk = NULL, *p, *hashed = NULL; + gboolean quoted = FALSE; + + /* Passphrase must be between 10 and 66 characters in length because WPA + * hex keys are exactly 64 characters (no quoting), and WPA passphrases + * are between 8 and 63 characters (inclusive), plus optional quoting if + * the passphrase contains spaces. + */ + + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + if (keys_ifcfg) { + psk = svGetValue (keys_ifcfg, "WPA_PSK", TRUE); + svCloseFile (keys_ifcfg); + } + + /* Fall back to the original ifcfg */ + if (!psk) + psk = svGetValue (ifcfg, "WPA_PSK", TRUE); + + if (!psk) + return NULL; + + p = psk; + + if (p[0] == '"' && psk[strlen (psk) - 1] == '"') + quoted = TRUE; + + if (!quoted && (strlen (psk) == 64)) { + /* Verify the hex PSK; 64 digits */ + while (*p) { + if (!isxdigit (*p++)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid WPA_PSK (contains non-hexadecimal characters)"); + goto out; + } + } + hashed = g_strdup (psk); + } else { + /* Prior to 4f6eef9e77265484555663cf666cde4fa8323469 and + * 28e2e446868b94b92edc4a82aa0bf1e3eda8ec54 the writer may not have + * properly quoted passphrases, so just handle anything that's unquoted + * and between 8 and 63 characters as a passphrase. + */ + + if (quoted) { + /* Get rid of the quotes */ + p++; + p[strlen (p) - 1] = '\0'; + } + + /* Length check */ + if (strlen (p) < 8 || strlen (p) > 63) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid WPA_PSK (passphrases must be between " + "8 and 63 characters long (inclusive))"); + goto out; + } + + hashed = g_strdup (p); + } + + if (!hashed) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); + goto out; + } + +out: + g_free (psk); + return hashed; +} + +static gboolean +eap_simple_reader (const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + NMSettingSecretFlags flags; + char *value; + + value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); + if (!value) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + g_free (value); + + flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL); + + /* Only read the password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); + if (!value && keys) { + /* Try the lookaside keys file */ + value = svGetValue (keys, "IEEE_8021X_PASSWORD", FALSE); + } + + if (!value) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", + eap_method); + return FALSE; + } + + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + g_free (value); + } + + return TRUE; +} + +static char * +get_cert_file (const char *ifcfg_path, const char *cert_path) +{ + const char *base = cert_path; + char *p, *ret, *dirname; + + g_return_val_if_fail (ifcfg_path != NULL, NULL); + g_return_val_if_fail (cert_path != NULL, NULL); + + if (cert_path[0] == '/') + return g_strdup (cert_path); + + p = strrchr (cert_path, '/'); + if (p) + base = p + 1; + + dirname = g_path_get_dirname (ifcfg_path); + ret = g_build_path ("/", dirname, base, NULL); + g_free (dirname); + return ret; +} + +static gboolean +eap_tls_reader (const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + char *value; + char *ca_cert = NULL; + char *real_path = NULL; + char *client_cert = NULL; + char *privkey = NULL; + char *privkey_password = NULL; + gboolean success = FALSE; + NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char *ca_cert_key = phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT"; + const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD"; + const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; + const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; + const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS": "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS"; + const char *pk_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS; + NMSettingSecretFlags flags; + + value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); + if (!value) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + g_free (value); + + ca_cert = svGetValue (ifcfg, ca_cert_key, FALSE); + if (ca_cert) { + real_path = get_cert_file (ifcfg->fileName, ca_cert); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + real_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + real_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } + g_free (real_path); + real_path = NULL; + } else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing %s for EAP" + " method '%s'; this is insecure!", + ca_cert_key, + eap_method); + } + + /* Read and set private key password flags */ + flags = read_secret_flags (ifcfg, pk_pw_flags_key); + g_object_set (s_8021x, pk_pw_flags_prop, flags, NULL); + + /* Read the private key password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Private key password */ + privkey_password = svGetValue (ifcfg, pk_pw_key, FALSE); + if (!privkey_password && keys) { + /* Try the lookaside keys file */ + privkey_password = svGetValue (keys, pk_pw_key, FALSE); + } + + if (!privkey_password) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing %s for EAP method '%s'.", + pk_pw_key, + eap_method); + goto done; + } + } + + /* The private key itself */ + privkey = svGetValue (ifcfg, pk_key, FALSE); + if (!privkey) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing %s for EAP method '%s'.", + pk_key, + eap_method); + goto done; + } + + real_path = get_cert_file (ifcfg->fileName, privkey); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, + real_path, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_private_key (s_8021x, + real_path, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, + error)) + goto done; + } + g_free (real_path); + real_path = NULL; + + /* Only set the client certificate if the private key is not PKCS#12 format, + * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, + * then nm_setting_802_1x_set_private_key() already set the client certificate + * to the same value as the private key. + */ + if ( privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY + || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { + client_cert = svGetValue (ifcfg, cli_cert_key, FALSE); + if (!client_cert) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing %s for EAP method '%s'.", + cli_cert_key, + eap_method); + goto done; + } + + real_path = get_cert_file (ifcfg->fileName, client_cert); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, + real_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_client_cert (s_8021x, + real_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } + g_free (real_path); + real_path = NULL; + } + + success = TRUE; + +done: + g_free (real_path); + g_free (ca_cert); + g_free (client_cert); + g_free (privkey); + g_free (privkey_password); + return success; +} + +static gboolean +eap_peap_reader (const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + char *ca_cert = NULL; + char *real_cert_path = NULL; + char *inner_auth = NULL; + char *peapver = NULL; + char *lower; + char **list = NULL, **iter; + gboolean success = FALSE; + + ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE); + if (ca_cert) { + real_cert_path = get_cert_file (ifcfg->fileName, ca_cert); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + real_cert_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing " + "IEEE_8021X_CA_CERT for EAP method '%s'; this is" + " insecure!", + eap_method); + } + + peapver = svGetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", FALSE); + if (peapver) { + if (!strcmp (peapver, "0")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL); + else if (!strcmp (peapver, "1")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); + else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown IEEE_8021X_PEAP_VERSION value '%s'", + peapver); + goto done; + } + } + + if (svTrueValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", FALSE)) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", NULL); + + inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); + if (!inner_auth) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + + /* Handle options for the inner auth method */ + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + if (!strlen (*iter)) + continue; + + if ( !strcmp (*iter, "MSCHAPV2") + || !strcmp (*iter, "MD5") + || !strcmp (*iter, "GTC")) { + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + } else if (!strcmp (*iter, "TLS")) { + if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + + lower = g_ascii_strdown (*iter, -1); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL); + g_free (lower); + break; + } + + if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "No valid IEEE_8021X_INNER_AUTH_METHODS found."); + goto done; + } + + success = TRUE; + +done: + if (list) + g_strfreev (list); + g_free (inner_auth); + g_free (peapver); + g_free (real_cert_path); + g_free (ca_cert); + return success; +} + +static gboolean +eap_ttls_reader (const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + gboolean success = FALSE; + char *anon_ident = NULL; + char *ca_cert = NULL; + char *real_cert_path = NULL; + char *inner_auth = NULL; + char *tmp; + char **list = NULL, **iter; + + ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE); + if (ca_cert) { + real_cert_path = get_cert_file (ifcfg->fileName, ca_cert); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + real_cert_path, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing " + "IEEE_8021X_CA_CERT for EAP method '%s'; this is" + " insecure!", + eap_method); + } + + anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE); + if (anon_ident && strlen (anon_ident)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL); + + tmp = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); + if (!tmp) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + + inner_auth = g_ascii_strdown (tmp, -1); + g_free (tmp); + + /* Handle options for the inner auth method */ + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + if (!strlen (*iter)) + continue; + + if ( !strcmp (*iter, "mschapv2") + || !strcmp (*iter, "mschap") + || !strcmp (*iter, "pap") + || !strcmp (*iter, "chap")) { + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL); + } else if (!strcmp (*iter, "eap-tls")) { + if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL); + } else if (!strcmp (*iter, "eap-mschapv2") || !strcmp (*iter, "eap-md5")) { + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + strlen ("eap-")), NULL); + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + break; + } + + success = TRUE; + +done: + if (list) + g_strfreev (list); + g_free (inner_auth); + g_free (real_cert_path); + g_free (ca_cert); + g_free (anon_ident); + return success; +} + +typedef struct { + const char *method; + gboolean (*reader)(const char *eap_method, + shvarFile *ifcfg, + shvarFile *keys, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + gboolean wifi_phase2_only; +} EAPReader; + +static EAPReader eap_readers[] = { + { "md5", eap_simple_reader, TRUE }, + { "pap", eap_simple_reader, TRUE }, + { "chap", eap_simple_reader, TRUE }, + { "mschap", eap_simple_reader, TRUE }, + { "mschapv2", eap_simple_reader, TRUE }, + { "leap", eap_simple_reader, FALSE }, + { "tls", eap_tls_reader, FALSE }, + { "peap", eap_peap_reader, FALSE }, + { "ttls", eap_ttls_reader, FALSE }, + { NULL, NULL } +}; + +static NMSetting8021x * +fill_8021x (shvarFile *ifcfg, + const char *file, + const char *key_mgmt, + gboolean wifi, + GError **error) +{ + NMSetting8021x *s_8021x; + shvarFile *keys = NULL; + char *value; + char **list, **iter; + + value = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE); + if (!value) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing IEEE_8021X_EAP_METHODS for key management '%s'", + key_mgmt); + return NULL; + } + + list = g_strsplit (value, " ", 0); + g_free (value); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + + /* Read in the lookaside keys file, if present */ + keys = utils_get_keys_ifcfg (file, FALSE); + + /* Validate and handle each EAP method */ + for (iter = list; iter && *iter; iter++) { + EAPReader *eap = &eap_readers[0]; + gboolean found = FALSE; + char *lower = NULL; + + lower = g_ascii_strdown (*iter, -1); + while (eap->method && !found) { + if (strcmp (eap->method, lower)) + goto next; + + /* Some EAP methods don't provide keying material, thus they + * cannot be used with WiFi unless they are an inner method + * used with TTLS or PEAP or whatever. + */ + if (wifi && eap->wifi_phase2_only) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignored invalid " + "IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.", + lower); + goto next; + } + + /* Parse EAP method specific options */ + if (!(*eap->reader)(lower, ifcfg, keys, s_8021x, FALSE, error)) { + g_free (lower); + goto error; + } + nm_setting_802_1x_add_eap_method (s_8021x, lower); + found = TRUE; + + next: + eap++; + } + + if (!found) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignored unknown" + "IEEE_8021X_EAP_METHOD '%s'.", + lower); + } + g_free (lower); + } + g_strfreev (list); + + if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "No valid EAP methods found in IEEE_8021X_EAP_METHODS."); + goto error; + } + + if (keys) + svCloseFile (keys); + return s_8021x; + +error: + if (keys) + svCloseFile (keys); + g_object_unref (s_8021x); + return NULL; +} + +static NMSetting * +make_wpa_setting (shvarFile *ifcfg, + const char *file, + const GByteArray *ssid, + gboolean adhoc, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSettingWirelessSecurity *wsec; + char *value, *psk, *lower; + gboolean wpa_psk = FALSE, wpa_eap = FALSE, ieee8021x = FALSE; + + wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + value = svGetValue (ifcfg, "KEY_MGMT", FALSE); + wpa_psk = !g_strcmp0 (value, "WPA-PSK"); + wpa_eap = !g_strcmp0 (value, "WPA-EAP"); + ieee8021x = !g_strcmp0 (value, "IEEE8021X"); + if (!wpa_psk && !wpa_eap && !ieee8021x) + goto error; /* Not WPA or Dynamic WEP */ + + /* Pairwise and Group ciphers (only relevant for WPA/RSN) */ + if (wpa_psk || wpa_eap) { + fill_wpa_ciphers (ifcfg, wsec, FALSE, adhoc); + fill_wpa_ciphers (ifcfg, wsec, TRUE, adhoc); + } + + /* WPA and/or RSN */ + if (adhoc) { + /* Ad-Hoc mode only supports WPA proto for now */ + nm_setting_wireless_security_add_proto (wsec, "wpa"); + } else { + char *allow_wpa, *allow_rsn; + + allow_wpa = svGetValue (ifcfg, "WPA_ALLOW_WPA", FALSE); + allow_rsn = svGetValue (ifcfg, "WPA_ALLOW_WPA2", FALSE); + + if (allow_wpa && svTrueValue (ifcfg, "WPA_ALLOW_WPA", TRUE)) + nm_setting_wireless_security_add_proto (wsec, "wpa"); + if (allow_rsn && svTrueValue (ifcfg, "WPA_ALLOW_WPA2", TRUE)) + nm_setting_wireless_security_add_proto (wsec, "rsn"); + + /* If neither WPA_ALLOW_WPA or WPA_ALLOW_WPA2 were present, default + * to both WPA and RSN allowed. + */ + if (!allow_wpa && !allow_rsn && !ieee8021x) { + nm_setting_wireless_security_add_proto (wsec, "wpa"); + nm_setting_wireless_security_add_proto (wsec, "rsn"); + } + + g_free (allow_wpa); + g_free (allow_rsn); + } + + if (!strcmp (value, "WPA-PSK")) { + NMSettingSecretFlags psk_flags; + + psk_flags = read_secret_flags (ifcfg, "WPA_PSK_FLAGS"); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL); + + /* Read PSK if it's system-owned */ + if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) { + psk = parse_wpa_psk (ifcfg, file, ssid, error); + if (psk) { + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); + g_free (psk); + } + } + + if (adhoc) + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); + else + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL); + } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { + /* Adhoc mode is mutually exclusive with any 802.1x-based authentication */ + if (adhoc) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", value); + goto error; + } + + *s_8021x = fill_8021x (ifcfg, file, value, TRUE, error); + if (!*s_8021x) + goto error; + + lower = g_ascii_strdown (value, -1); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL); + g_free (lower); + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown wireless KEY_MGMT type '%s'", value); + goto error; + } + + g_free (value); + return (NMSetting *) wsec; + +error: + g_free (value); + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static NMSetting * +make_leap_setting (shvarFile *ifcfg, + const char *file, + GError **error) +{ + NMSettingWirelessSecurity *wsec; + shvarFile *keys_ifcfg; + char *value; + NMSettingSecretFlags flags; + + wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + value = svGetValue (ifcfg, "KEY_MGMT", FALSE); + if (!value || strcmp (value, "IEEE8021X")) + goto error; /* Not LEAP */ + + g_free (value); + value = svGetValue (ifcfg, "SECURITYMODE", FALSE); + if (!value || strcasecmp (value, "leap")) + goto error; /* Not LEAP */ + + g_free (value); + + flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL); + + /* Read LEAP password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE); + if (!value) { + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + if (keys_ifcfg) { + value = svGetValue (keys_ifcfg, "IEEE_8021X_PASSWORD", FALSE); + svCloseFile (keys_ifcfg); + } + } + if (value && strlen (value)) + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); + if (!value || !strlen (value)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing LEAP identity"); + goto error; + } + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, NULL); + g_free (value); + + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NULL); + + return (NMSetting *) wsec; + +error: + g_free (value); + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static NMSetting * +make_wireless_security_setting (shvarFile *ifcfg, + const char *file, + const GByteArray *ssid, + gboolean adhoc, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSetting *wsec; + + if (!adhoc) { + wsec = make_leap_setting (ifcfg, file, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + } + + wsec = make_wpa_setting (ifcfg, file, ssid, adhoc, s_8021x, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + + wsec = make_wep_setting (ifcfg, file, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + + return NULL; /* unencrypted */ +} + +static NMSetting * +make_wireless_setting (shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMSettingWireless *s_wireless; + GByteArray *array = NULL; + char *value; + + s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + + if (read_mac_address (ifcfg, "HWADDR", &array, error)) { + if (array) { + g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL); + + /* A connection can only be unmanaged if we know the MAC address */ + if (!nm_controlled) { + *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x", + array->data[0], array->data[1], array->data[2], + array->data[3], array->data[4], array->data[5]); + } + + g_byte_array_free (array, TRUE); + } else if (!nm_controlled) { + /* If NM_CONTROLLED=no but there wasn't a MAC address, notify + * the user that the device cannot be unmanaged. + */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed"); + } + } else { + g_object_unref (s_wireless); + return NULL; + } + + array = NULL; + if (read_mac_address (ifcfg, "MACADDR", &array, error)) { + if (array) { + g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL); + g_byte_array_free (array, TRUE); + } + } + + value = svGetValue (ifcfg, "ESSID", TRUE); + if (value) { + gsize ssid_len = 0, value_len = strlen (value); + char *p = value, *tmp; + char buf[33]; + + ssid_len = value_len; + if ( (value_len >= 2) + && (value[0] == '"') + && (value[value_len - 1] == '"')) { + /* Strip the quotes and unescape */ + p = value + 1; + value[value_len - 1] = '\0'; + svUnescape (p); + ssid_len = strlen (p); + } else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) { + /* Hex representation */ + if (value_len % 2) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", + value); + g_free (value); + goto error; + } + + p = value + 2; + while (*p) { + if (!isxdigit (*p)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)", + value, *p); + g_free (value); + goto error; + } + p++; + } + + tmp = utils_hexstr2bin (value + 2, value_len - 2); + ssid_len = (value_len - 2) / 2; + memcpy (buf, tmp, ssid_len); + p = &buf[0]; + } + + if (ssid_len > 32 || ssid_len == 0) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", + value, ssid_len); + g_free (value); + goto error; + } + + array = g_byte_array_sized_new (ssid_len); + g_byte_array_append (array, (const guint8 *) p, ssid_len); + g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, array, NULL); + g_byte_array_free (array, TRUE); + g_free (value); + } else { + /* Only fail on lack of SSID if device is managed */ + if (nm_controlled) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing SSID"); + goto error; + } + } + + if (!nm_controlled) + goto done; + + value = svGetValue (ifcfg, "MODE", FALSE); + if (value) { + char *lcase; + const char *mode = NULL; + + lcase = g_ascii_strdown (value, -1); + g_free (value); + + if (!strcmp (lcase, "ad-hoc")) { + mode = "adhoc"; + } else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) { + mode = "infrastructure"; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid mode '%s' (not 'Ad-Hoc', 'Managed', or 'Auto')", + lcase); + g_free (lcase); + goto error; + } + g_free (lcase); + + g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL); + } + + value = svGetValue (ifcfg, "BSSID", FALSE); + if (value) { + struct ether_addr *eth; + GByteArray *bssid; + + eth = ether_aton (value); + if (!eth) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid BSSID '%s'", value); + goto error; + } + + bssid = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); + g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL); + g_byte_array_free (bssid, TRUE); + } + + value = svGetValue (ifcfg, "CHANNEL", FALSE); + if (value) { + long int chan; + + errno = 0; + chan = strtol (value, NULL, 10); + if (errno || chan <= 0 || chan > 196) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid wireless channel '%s'", value); + g_free (value); + goto error; + } + g_object_set (s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL); + if (chan > 14) + g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL); + else + g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL); + } + + value = svGetValue (ifcfg, "MTU", FALSE); + if (value) { + long int mtu; + + errno = 0; + mtu = strtol (value, NULL, 10); + if (errno || mtu < 0 || mtu > 50000) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid wireless MTU '%s'", value); + g_free (value); + goto error; + } + g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL); + } + +done: + return NM_SETTING (s_wireless); + +error: + if (s_wireless) + g_object_unref (s_wireless); + return NULL; +} + +static NMConnection * +wireless_connection_from_ifcfg (const char *file, + shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMConnection *connection = NULL; + NMSetting *con_setting = NULL; + NMSetting *wireless_setting = NULL; + NMSetting8021x *s_8021x = NULL; + const GByteArray *ssid; + NMSetting *security_setting = NULL; + char *printable_ssid = NULL; + const char *mode; + gboolean adhoc = FALSE; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (*error == NULL, NULL); + + connection = nm_connection_new (); + if (!connection) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to allocate new connection for %s.", file); + return NULL; + } + + /* Wireless */ + wireless_setting = make_wireless_setting (ifcfg, nm_controlled, unmanaged, error); + if (!wireless_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, wireless_setting); + + ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting)); + if (ssid) + printable_ssid = nm_utils_ssid_to_utf8 (ssid); + else + printable_ssid = g_strdup_printf ("unmanaged"); + + if (nm_controlled) { + mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); + if (mode && !strcmp (mode, "adhoc")) + adhoc = TRUE; + + /* Wireless security */ + security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, error); + if (*error) { + g_object_unref (connection); + return NULL; + } + if (security_setting) { + nm_connection_add_setting (connection, security_setting); + if (s_8021x) + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SEC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL); + } + } + + /* Connection */ + con_setting = make_connection_setting (file, ifcfg, + NM_SETTING_WIRELESS_SETTING_NAME, + printable_ssid); + g_free (printable_ssid); + if (!con_setting) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to create connection setting."); + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, con_setting); + + /* Don't verify if unmanaged since we may not have an SSID or whatever */ + if (nm_controlled) { + if (!nm_connection_verify (connection, error)) { + g_object_unref (connection); + return NULL; + } + } + + return connection; +} + +static NMSetting * +make_wired_setting (shvarFile *ifcfg, + const char *file, + gboolean nm_controlled, + char **unmanaged, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSettingWired *s_wired; + char *value = NULL; + int mtu; + GByteArray *mac = NULL; + char *nettype; + + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + + value = svGetValue (ifcfg, "MTU", FALSE); + if (value) { + if (get_int (value, &mtu)) { + if (mtu >= 0 && mtu < 65536) + g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL); + } else { + /* Shouldn't be fatal... */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid MTU '%s'", value); + } + g_free (value); + } + + if (read_mac_address (ifcfg, "HWADDR", &mac, error)) { + if (mac) { + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + + /* A connection can only be unmanaged if we know the MAC address */ + if (!nm_controlled) { + *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], mac->data[5]); + } + + g_byte_array_free (mac, TRUE); + } + } else { + g_object_unref (s_wired); + return NULL; + } + + value = svGetValue (ifcfg, "SUBCHANNELS", FALSE); + if (value) { + const char *p = value; + gboolean success = TRUE; + char **chans = NULL; + + /* basic sanity checks */ + while (*p) { + if (!isxdigit (*p) && (*p != ',') && (*p != '.')) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s'", value); + success = FALSE; + break; + } + p++; + } + + if (success) { + guint32 num_chans; + + chans = g_strsplit_set (value, ",", 0); + num_chans = g_strv_length (chans); + if (num_chans < 2 || num_chans > 3) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s' (%d channels, 2 or 3 expected)", + value, g_strv_length (chans)); + } else { + GPtrArray *array = g_ptr_array_sized_new (num_chans); + + g_ptr_array_add (array, chans[0]); + g_ptr_array_add (array, chans[1]); + if (num_chans == 3) + g_ptr_array_add (array, chans[2]); + + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, array, NULL); + g_ptr_array_free (array, TRUE); + + /* set the unmanaged spec too */ + if (!nm_controlled && !*unmanaged) + *unmanaged = g_strdup_printf ("s390-subchannels:%s", value); + } + g_strfreev (chans); + } + g_free (value); + } + + value = svGetValue (ifcfg, "PORTNAME", FALSE); + if (value && strlen (value)) { + nm_setting_wired_add_s390_option (s_wired, "portname", value); + } + g_free (value); + + nettype = svGetValue (ifcfg, "NETTYPE", FALSE); + if (nettype && strlen (nettype)) { + if (!strcmp (nettype, "qeth") || !strcmp (nettype, "lcs") || !strcmp (nettype, "ctc")) + g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, nettype, NULL); + else + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unknown s390 NETTYPE '%s'", nettype); + } + + value = svGetValue (ifcfg, "OPTIONS", FALSE); + if (value && strlen (value)) { + char **options, **iter; + + iter = options = g_strsplit_set (value, " ", 0); + while (iter && *iter) { + char *equals = strchr (*iter, '='); + gboolean valid = FALSE; + + if (equals) { + *equals = '\0'; + valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1); + } + if (!valid) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 OPTION '%s'", *iter); + iter++; + } + g_strfreev (options); + } + g_free (value); + + g_free (nettype); + + if (!nm_controlled && !*unmanaged) { + /* If NM_CONTROLLED=no but there wasn't a MAC address or z/VM + * subchannels, notify the user that the device cannot be unmanaged. + */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR or SUBCHANNELS was missing; device will be managed"); + } + + mac = NULL; + if (read_mac_address (ifcfg, "MACADDR", &mac, error)) { + if (mac) { + g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + } + } + + value = svGetValue (ifcfg, "KEY_MGMT", FALSE); + if (value) { + if (!strcmp (value, "IEEE8021X")) { + *s_8021x = fill_8021x (ifcfg, file, value, FALSE, error); + if (!*s_8021x) + goto error; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Unknown wired KEY_MGMT type '%s'", value); + goto error; + } + g_free (value); + } + + return (NMSetting *) s_wired; + +error: + g_free (value); + g_object_unref (s_wired); + return NULL; +} + +static NMConnection * +wired_connection_from_ifcfg (const char *file, + shvarFile *ifcfg, + gboolean nm_controlled, + char **unmanaged, + GError **error) +{ + NMConnection *connection = NULL; + NMSetting *con_setting = NULL; + NMSetting *wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (ifcfg != NULL, NULL); + + connection = nm_connection_new (); + if (!connection) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to allocate new connection for %s.", file); + return NULL; + } + + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL); + if (!con_setting) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to create connection setting."); + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, con_setting); + + wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error); + if (!wired_setting) { + g_object_unref (connection); + return NULL; + } + nm_connection_add_setting (connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + if (!nm_connection_verify (connection, error)) { + g_object_unref (connection); + return NULL; + } + + return connection; +} + +static gboolean +is_wireless_device (const char *iface) +{ + int fd; + struct iw_range range; + struct iwreq wrq; + gboolean is_wireless = FALSE; + + g_return_val_if_fail (iface != NULL, FALSE); + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (!fd) + return FALSE; + + memset (&wrq, 0, sizeof (struct iwreq)); + memset (&range, 0, sizeof (struct iw_range)); + strncpy (wrq.ifr_name, iface, IFNAMSIZ); + wrq.u.data.pointer = (caddr_t) ⦥ + wrq.u.data.length = sizeof (struct iw_range); + + if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0) + is_wireless = TRUE; + else { + if (errno == EOPNOTSUPP) + is_wireless = FALSE; + else { + /* Sigh... some wired devices (kvm/qemu) return EINVAL when the + * device is down even though it's not a wireless device. So try + * IWNAME as a fallback. + */ + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, iface, IFNAMSIZ); + if (ioctl (fd, SIOCGIWNAME, &wrq) == 0) + is_wireless = TRUE; + } + } + + close (fd); + return is_wireless; +} + +enum { + IGNORE_REASON_NONE = 0x00, + IGNORE_REASON_BRIDGE = 0x01, + IGNORE_REASON_VLAN = 0x02, +}; + +NMConnection * +connection_from_file (const char *filename, + const char *network_file, /* for unit tests only */ + const char *test_type, /* for unit tests only */ + const char *iscsiadm_path, /* for unit tests only */ + char **unmanaged, + char **keyfile, + char **routefile, + char **route6file, + GError **out_error, + gboolean *ignore_error) +{ + NMConnection *connection = NULL; + shvarFile *parsed; + char *type, *nmc = NULL, *bootproto, *tmp; + NMSetting *s_ip4, *s_ip6; + const char *ifcfg_name = NULL; + gboolean nm_controlled = TRUE; + gboolean ip6_used = FALSE; + GError *error = NULL; + guint32 ignore_reason = IGNORE_REASON_NONE; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (unmanaged != NULL, NULL); + g_return_val_if_fail (*unmanaged == NULL, NULL); + g_return_val_if_fail (keyfile != NULL, NULL); + g_return_val_if_fail (*keyfile == NULL, NULL); + g_return_val_if_fail (routefile != NULL, NULL); + g_return_val_if_fail (*routefile == NULL, NULL); + g_return_val_if_fail (route6file != NULL, NULL); + g_return_val_if_fail (*route6file == NULL, NULL); + + /* Non-NULL only for unit tests; normally use /etc/sysconfig/network */ + if (!network_file) + network_file = SYSCONFDIR "/sysconfig/network"; + + if (!iscsiadm_path) + iscsiadm_path = SBINDIR "/iscsiadm"; + + ifcfg_name = utils_get_ifcfg_name (filename, TRUE); + if (!ifcfg_name) { + g_set_error (out_error, IFCFG_PLUGIN_ERROR, 0, + "Ignoring connection '%s' because it's not an ifcfg file.", filename); + return NULL; + } + + parsed = svNewFile (filename); + if (!parsed) { + g_set_error (out_error, IFCFG_PLUGIN_ERROR, 0, + "Couldn't parse file '%s'", filename); + return NULL; + } + + type = svGetValue (parsed, "TYPE", FALSE); + if (!type) { + char *device; + + /* If no type, if the device has wireless extensions, it's wifi, + * otherwise it's ethernet. + */ + device = svGetValue (parsed, "DEVICE", FALSE); + if (!device) { + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "File '%s' had neither TYPE nor DEVICE keys.", filename); + goto done; + } + + if (!strcmp (device, "lo")) { + if (ignore_error) + *ignore_error = TRUE; + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "Ignoring loopback device config."); + g_free (device); + goto done; + } + + if (!test_type) { + /* Test wireless extensions */ + if (is_wireless_device (device)) + type = g_strdup (TYPE_WIRELESS); + else + type = g_strdup (TYPE_ETHERNET); + } else { + /* For the unit tests, there won't necessarily be any + * adapters of the connection's type in the system so the + * type can't be tested with ioctls. + */ + type = g_strdup (test_type); + } + + g_free (device); + } + + nmc = svGetValue (parsed, "NM_CONTROLLED", FALSE); + if (nmc) { + char *lower; + + lower = g_ascii_strdown (nmc, -1); + g_free (nmc); + + if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false")) + nm_controlled = FALSE; + g_free (lower); + } + + /* Ignore BRIDGE= and VLAN= connections for now too (rh #619863) */ + tmp = svGetValue (parsed, "BRIDGE", FALSE); + if (tmp) { + g_free (tmp); + nm_controlled = FALSE; + ignore_reason = IGNORE_REASON_BRIDGE; + } + + if (nm_controlled) { + tmp = svGetValue (parsed, "VLAN", FALSE); + if (tmp) { + g_free (tmp); + nm_controlled = FALSE; + ignore_reason = IGNORE_REASON_VLAN; + } + } + + /* Construct the connection */ + if (!strcasecmp (type, TYPE_ETHERNET)) + connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); + else if (!strcasecmp (type, TYPE_WIRELESS)) + connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error); + else if (!strcasecmp (type, TYPE_BRIDGE)) { + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "Bridge connections are not yet supported"); + } else { + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "Unknown connection type '%s'", type); + } + + if (nm_controlled) { + g_free (*unmanaged); + *unmanaged = NULL; + } + + g_free (type); + + /* Don't bother reading the connection fully if it's unmanaged or ignored */ + if (!connection || *unmanaged || ignore_reason) { + if (connection && !*unmanaged) { + /* However,BRIDGE and VLAN connections that don't have HWADDR won't + * be unmanaged because the unmanaged state is keyed off HWADDR. + * They willl still be tagged 'ignore' from code that checks BRIDGE + * and VLAN above. Since they aren't marked unmanaged, kill them + * completely. + */ + if (ignore_reason) { + g_object_unref (connection); + connection = NULL; + g_set_error (&error, IFCFG_PLUGIN_ERROR, 0, + "%s connections are not yet supported", + ignore_reason == IGNORE_REASON_BRIDGE ? "Bridge" : "VLAN"); + } + } + goto done; + } + + s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, &error); + if (error) { + g_object_unref (connection); + connection = NULL; + goto done; + } else if (s_ip6) { + const char *method; + + nm_connection_add_setting (connection, s_ip6); + method = nm_setting_ip6_config_get_method (NM_SETTING_IP6_CONFIG (s_ip6)); + if (method && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) + ip6_used = TRUE; + } + + s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, ip6_used, &error); + if (error) { + g_object_unref (connection); + connection = NULL; + goto done; + } else if (s_ip4) + nm_connection_add_setting (connection, s_ip4); + + /* iSCSI / ibft connections are read-only since their settings are + * stored in NVRAM and can only be changed in BIOS. + */ + bootproto = svGetValue (parsed, "BOOTPROTO", FALSE); + if ( bootproto + && connection + && !g_ascii_strcasecmp (bootproto, "ibft")) { + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL); + } + + if (!nm_connection_verify (connection, &error)) { + g_object_unref (connection); + connection = NULL; + } + + *keyfile = utils_get_keys_path (filename); + *routefile = utils_get_route_path (filename); + *route6file = utils_get_route6_path (filename); + +done: + svCloseFile (parsed); + if (error && out_error) + *out_error = error; + else + g_clear_error (&error); + return connection; +} + +const char * +reader_get_prefix (void) +{ + return _("System"); +} + diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h new file mode 100644 index 00000000..2a031977 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/reader.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Red Hat, Inc. + */ + +#ifndef __READER_H__ +#define __READER_H__ + +#include <glib.h> +#include <nm-connection.h> + +#include "shvar.h" + +NMConnection *connection_from_file (const char *filename, + const char *network_file, /* for unit tests only */ + const char *test_type, /* for unit tests only */ + const char *iscsiadm_path, /* for unit tests only */ + char **unmanaged, + char **keyfile, + char **routefile, + char **route6file, + GError **error, + gboolean *ignore_error); + +const char *reader_get_prefix (void); + +#endif /* __READER_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c new file mode 100644 index 00000000..0481e1f6 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -0,0 +1,396 @@ +/* + * shvar.c + * + * Implementation of non-destructively reading/writing files containing + * only shell variable declarations and full-line comments. + * + * Includes explicit inheritance mechanism intended for use with + * Red Hat Linux ifcfg-* files. There is no protection against + * inheritance loops; they will generally cause stack overflows. + * Furthermore, they are only intended for one level of inheritance; + * the value setting algorithm assumes this. + * + * Copyright 1999,2000 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "shvar.h" + +/* Open the file <name>, returning a shvarFile on success and NULL on failure. + Add a wrinkle to let the caller specify whether or not to create the file + (actually, return a structure anyway) if it doesn't exist. */ +static shvarFile * +svOpenFile(const char *name, gboolean create) +{ + shvarFile *s = NULL; + int closefd = 0; + + s = g_malloc0(sizeof(shvarFile)); + + s->fd = -1; + if (create) + s->fd = open(name, O_RDWR); /* NOT O_CREAT */ + + if (!create || s->fd == -1) { + /* try read-only */ + s->fd = open(name, O_RDONLY); /* NOT O_CREAT */ + if (s->fd != -1) closefd = 1; + } + s->fileName = g_strdup(name); + + if (s->fd != -1) { + struct stat buf; + char *p, *q; + + if (fstat(s->fd, &buf) < 0) goto bail; + s->arena = g_malloc0(buf.st_size + 1); + + if (read(s->fd, s->arena, buf.st_size) < 0) goto bail; + + /* we'd use g_strsplit() here, but we want a list, not an array */ + for(p = s->arena; (q = strchr(p, '\n')) != NULL; p = q + 1) { + s->lineList = g_list_append(s->lineList, g_strndup(p, q - p)); + } + + /* closefd is set if we opened the file read-only, so go ahead and + close it, because we can't write to it anyway */ + if (closefd) { + close(s->fd); + s->fd = -1; + } + + return s; + } + + if (create) { + return s; + } + +bail: + if (s->fd != -1) close(s->fd); + g_free (s->arena); + g_free (s->fileName); + g_free (s); + return NULL; +} + +/* Open the file <name>, return shvarFile on success, NULL on failure */ +shvarFile * +svNewFile(const char *name) +{ + return svOpenFile(name, FALSE); +} + +/* Create a new file structure, returning actual data if the file exists, + * and a suitable starting point if it doesn't. */ +shvarFile * +svCreateFile(const char *name) +{ + return svOpenFile(name, TRUE); +} + +/* remove escaped characters in place */ +void +svUnescape(char *s) { + int len, i; + + len = strlen(s); + if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) { + i = len - 2; + if (i == 0) + s[0] = '\0'; + else { + memmove(s, s+1, i); + s[i+1] = '\0'; + len = i; + } + } + for (i = 0; i < len; i++) { + if (s[i] == '\\') { + memmove(s+i, s+i+1, len-(i+1)); + len--; + } + s[len] = '\0'; + } +} + + +/* create a new string with all necessary characters escaped. + * caller must free returned string + */ +static const char escapees[] = "\"'\\$~`"; /* must be escaped */ +static const char spaces[] = " \t|&;()<>"; /* only require "" */ +char * +svEscape(const char *s) { + char *new; + int i, j, mangle = 0, space = 0; + int newlen, slen; + static int esclen, splen; + + if (!esclen) esclen = strlen(escapees); + if (!splen) splen = strlen(spaces); + slen = strlen(s); + + for (i = 0; i < slen; i++) { + if (strchr(escapees, s[i])) mangle++; + if (strchr(spaces, s[i])) space++; + } + if (!mangle && !space) return strdup(s); + + newlen = slen + mangle + 3; /* 3 is extra ""\0 */ + new = g_malloc0(newlen); + if (!new) return NULL; + + j = 0; + new[j++] = '"'; + for (i = 0; i < slen; i++) { + if (strchr(escapees, s[i])) { + new[j++] = '\\'; + } + new[j++] = s[i]; + } + new[j++] = '"'; + g_assert(j == slen + mangle + 2); /* j is the index of the '\0' */ + + return new; +} + +/* Get the value associated with the key, and leave the current pointer + * pointing at the line containing the value. The char* returned MUST + * be freed by the caller. + */ +char * +svGetValue(shvarFile *s, const char *key, gboolean verbatim) +{ + char *value = NULL; + char *line; + char *keyString; + int len; + + g_assert(s); + g_assert(key); + + keyString = g_malloc0(strlen(key) + 2); + strcpy(keyString, key); + keyString[strlen(key)] = '='; + len = strlen(keyString); + + for (s->current = s->lineList; s->current; s->current = s->current->next) { + line = s->current->data; + if (!strncmp(keyString, line, len)) { + value = g_strdup(line + len); + if (!verbatim) + svUnescape(value); + break; + } + } + g_free(keyString); + + if (value) { + if (value[0]) { + return value; + } else { + g_free(value); + return NULL; + } + } + if (s->parent) value = svGetValue(s->parent, key, verbatim); + return value; +} + +/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true") + * return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false") + * return <default> otherwise + */ +int +svTrueValue(shvarFile *s, const char *key, int def) +{ + char *tmp; + int returnValue = def; + + tmp = svGetValue(s, key, FALSE); + if (!tmp) return returnValue; + + if ( (!strcasecmp("yes", tmp)) || + (!strcasecmp("true", tmp)) || + (!strcasecmp("t", tmp)) || + (!strcasecmp("y", tmp)) ) returnValue = 1; + else + if ( (!strcasecmp("no", tmp)) || + (!strcasecmp("false", tmp)) || + (!strcasecmp("f", tmp)) || + (!strcasecmp("n", tmp)) ) returnValue = 0; + + g_free (tmp); + return returnValue; +} + + +/* Set the variable <key> equal to the value <value>. + * If <key> does not exist, and the <current> pointer is set, append + * the key=value pair after that line. Otherwise, prepend the pair + * to the top of the file. Here's the algorithm, as the C code + * seems to be rather dense: + * + * if (value == NULL), then: + * if val2 (parent): change line to key= or append line key= + * if val1 (this) : delete line + * else noop + * else use this table: + * val2 + * NULL value other + * v NULL append line noop append line + * a + * l value noop noop noop + * 1 + * other change line delete line change line + * + * No changes are ever made to the parent config file, only to the + * specific file passed on the command line. + * + */ +void +svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim) +{ + char *newval = NULL, *val1 = NULL, *val2 = NULL; + char *keyValue; + + g_assert(s); + g_assert(key); + /* value may be NULL */ + + if (value) + newval = verbatim ? g_strdup(value) : svEscape(value); + keyValue = g_strdup_printf("%s=%s", key, newval ? newval : ""); + + val1 = svGetValue(s, key, FALSE); + if (val1 && newval && !strcmp(val1, newval)) goto bail; + if (s->parent) val2 = svGetValue(s->parent, key, FALSE); + + if (!newval || !newval[0]) { + /* delete value somehow */ + if (val2) { + /* change/append line to get key= */ + if (s->current) s->current->data = keyValue; + else s->lineList = g_list_append(s->lineList, keyValue); + s->modified = 1; + } else if (val1) { + /* delete line */ + s->lineList = g_list_remove_link(s->lineList, s->current); + g_list_free_1(s->current); + s->modified = 1; + goto bail; /* do not need keyValue */ + } + goto end; + } + + if (!val1) { + if (val2 && !strcmp(val2, newval)) goto end; + /* append line */ + s->lineList = g_list_append(s->lineList, keyValue); + s->modified = 1; + goto end; + } + + /* deal with a whole line of noops */ + if (val1 && !strcmp(val1, newval)) goto end; + + /* At this point, val1 && val1 != value */ + if (val2 && !strcmp(val2, newval)) { + /* delete line */ + s->lineList = g_list_remove_link(s->lineList, s->current); + g_list_free_1(s->current); + s->modified = 1; + goto bail; /* do not need keyValue */ + } else { + /* change line */ + if (s->current) s->current->data = keyValue; + else s->lineList = g_list_append(s->lineList, keyValue); + s->modified = 1; + } + +end: + if (newval) free(newval); + if (val1) free(val1); + if (val2) free(val2); + return; + +bail: + if (keyValue) free (keyValue); + goto end; +} + +/* Write the current contents iff modified. Returns -1 on error + * and 0 on success. Do not write if no values have been modified. + * The mode argument is only used if creating the file, not if + * re-writing an existing file, and is passed unchanged to the + * open() syscall. + */ +int +svWriteFile(shvarFile *s, int mode) +{ + FILE *f; + int tmpfd; + + if (s->modified) { + if (s->fd == -1) + s->fd = open(s->fileName, O_WRONLY|O_CREAT, mode); + if (s->fd == -1) + return -1; + if (ftruncate(s->fd, 0) < 0) + return -1; + + tmpfd = dup(s->fd); + f = fdopen(tmpfd, "w"); + fseek(f, 0, SEEK_SET); + for (s->current = s->lineList; s->current; s->current = s->current->next) { + char *line = s->current->data; + fprintf(f, "%s\n", line); + } + fclose(f); + } + + return 0; +} + + +/* Close the file descriptor (if open) and delete the shvarFile. + * Returns -1 on error and 0 on success. + */ +int +svCloseFile(shvarFile *s) +{ + + g_assert(s); + + if (s->fd != -1) close(s->fd); + + g_free(s->arena); + g_free(s->fileName); + g_list_foreach (s->lineList, (GFunc) g_free, NULL); + g_list_free(s->lineList); /* implicitly frees s->current */ + g_free(s); + return 0; +} diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h new file mode 100644 index 00000000..4b650d2a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -0,0 +1,110 @@ +/* + * shvar.h + * + * Interface for non-destructively reading/writing files containing + * only shell variable declarations and full-line comments. + * + * Includes explicit inheritance mechanism intended for use with + * Red Hat Linux ifcfg-* files. There is no protection against + * inheritance loops; they will generally cause stack overflows. + * Furthermore, they are only intended for one level of inheritance; + * the value setting algorithm assumes this. + * + * Copyright 1999 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _SHVAR_H +#define _SHVAR_H + +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _shvarFile shvarFile; +struct _shvarFile { + char *fileName; /* read-only */ + int fd; /* read-only */ + char *arena; /* ignore */ + GList *lineList; /* read-only */ + GList *current; /* set implicitly or explicitly, + points to element of lineList */ + shvarFile *parent; /* set explicitly */ + int modified; /* ignore */ +}; + + +/* Create the file <name>, return shvarFile on success, NULL on failure */ +shvarFile * +svCreateFile(const char *name); + +/* Open the file <name>, return shvarFile on success, NULL on failure */ +shvarFile * +svNewFile(const char *name); + +/* Get the value associated with the key, and leave the current pointer + * pointing at the line containing the value. The char* returned MUST + * be freed by the caller. + */ +char * +svGetValue(shvarFile *s, const char *key, gboolean verbatim); + +/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true") + * return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false") + * return <def> otherwise + */ +int +svTrueValue(shvarFile *s, const char *key, int def); + +/* Set the variable <key> equal to the value <value>. + * If <key> does not exist, and the <current> pointer is set, append + * the key=value pair after that line. Otherwise, prepend the pair + * to the top of the file. + */ +void +svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim); + + +/* Write the current contents iff modified. Returns -1 on error + * and 0 on success. Do not write if no values have been modified. + * The mode argument is only used if creating the file, not if + * re-writing an existing file, and is passed unchanged to the + * open() syscall. + */ +int +svWriteFile(shvarFile *s, int mode); + +/* Close the file descriptor (if open) and delete the shvarFile. + * Returns -1 on error and 0 on success. + */ +int +svCloseFile(shvarFile *s); + +/* Return a new escaped string */ +char * +svEscape(const char *s); + +/* Unescape a string in-place */ +void +svUnescape(char *s); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ! _SHVAR_H */ diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am new file mode 100644 index 00000000..1b76a474 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am @@ -0,0 +1,53 @@ +SUBDIRS=network-scripts + +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +noinst_PROGRAMS = test-ifcfg-rh test-ifcfg-rh-utils + +test_ifcfg_rh_SOURCES = \ + test-ifcfg-rh.c + +test_ifcfg_rh_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \ + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" + +test_ifcfg_rh_LDADD = \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifcfg-rh-io.la \ + $(DBUS_LIBS) + +test_ifcfg_rh_utils_SOURCES = \ + test-ifcfg-rh-utils.c + +test_ifcfg_rh_utils_CPPFLAGS = \ + $(GLIB_CFLAGS) + +test_ifcfg_rh_utils_LDADD = \ + $(builddir)/../libifcfg-rh-io.la + +if WITH_TESTS + +check-local: test-ifcfg-rh + $(abs_builddir)/test-ifcfg-rh-utils + $(abs_builddir)/test-ifcfg-rh + +endif + +EXTRA_DIST = \ + iscsiadm-test-dhcp \ + iscsiadm-test-static \ + iscsiadm-test-bad-ipaddr \ + iscsiadm-test-bad-gateway \ + iscsiadm-test-bad-dns1 \ + iscsiadm-test-bad-dns2 \ + iscsiadm-test-bad-entry \ + iscsiadm-test-bad-record + + diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in new file mode 100644 index 00000000..171cd5e5 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -0,0 +1,826 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-ifcfg-rh$(EXEEXT) test-ifcfg-rh-utils$(EXEEXT) +subdir = src/settings/plugins/ifcfg-rh/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_ifcfg_rh_OBJECTS = test_ifcfg_rh-test-ifcfg-rh.$(OBJEXT) +test_ifcfg_rh_OBJECTS = $(am_test_ifcfg_rh_OBJECTS) +am__DEPENDENCIES_1 = +test_ifcfg_rh_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifcfg-rh-io.la $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am_test_ifcfg_rh_utils_OBJECTS = \ + test_ifcfg_rh_utils-test-ifcfg-rh-utils.$(OBJEXT) +test_ifcfg_rh_utils_OBJECTS = $(am_test_ifcfg_rh_utils_OBJECTS) +test_ifcfg_rh_utils_DEPENDENCIES = $(builddir)/../libifcfg-rh-io.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(test_ifcfg_rh_SOURCES) $(test_ifcfg_rh_utils_SOURCES) +DIST_SOURCES = $(test_ifcfg_rh_SOURCES) $(test_ifcfg_rh_utils_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = network-scripts +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +test_ifcfg_rh_SOURCES = \ + test-ifcfg-rh.c + +test_ifcfg_rh_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \ + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" + +test_ifcfg_rh_LDADD = \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifcfg-rh-io.la \ + $(DBUS_LIBS) + +test_ifcfg_rh_utils_SOURCES = \ + test-ifcfg-rh-utils.c + +test_ifcfg_rh_utils_CPPFLAGS = \ + $(GLIB_CFLAGS) + +test_ifcfg_rh_utils_LDADD = \ + $(builddir)/../libifcfg-rh-io.la + +EXTRA_DIST = \ + iscsiadm-test-dhcp \ + iscsiadm-test-static \ + iscsiadm-test-bad-ipaddr \ + iscsiadm-test-bad-gateway \ + iscsiadm-test-bad-dns1 \ + iscsiadm-test-bad-dns2 \ + iscsiadm-test-bad-entry \ + iscsiadm-test-bad-record + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_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 +test-ifcfg-rh$(EXEEXT): $(test_ifcfg_rh_OBJECTS) $(test_ifcfg_rh_DEPENDENCIES) + @rm -f test-ifcfg-rh$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ifcfg_rh_OBJECTS) $(test_ifcfg_rh_LDADD) $(LIBS) +test-ifcfg-rh-utils$(EXEEXT): $(test_ifcfg_rh_utils_OBJECTS) $(test_ifcfg_rh_utils_DEPENDENCIES) + @rm -f test-ifcfg-rh-utils$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ifcfg_rh_utils_OBJECTS) $(test_ifcfg_rh_utils_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_ifcfg_rh-test-ifcfg-rh.o: test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh-test-ifcfg-rh.o -MD -MP -MF $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o test_ifcfg_rh-test-ifcfg-rh.o `test -f 'test-ifcfg-rh.c' || echo '$(srcdir)/'`test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh.c' object='test_ifcfg_rh-test-ifcfg-rh.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh-test-ifcfg-rh.o `test -f 'test-ifcfg-rh.c' || echo '$(srcdir)/'`test-ifcfg-rh.c + +test_ifcfg_rh-test-ifcfg-rh.obj: test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh-test-ifcfg-rh.obj -MD -MP -MF $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'test-ifcfg-rh.c'; then $(CYGPATH_W) 'test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh.c' object='test_ifcfg_rh-test-ifcfg-rh.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'test-ifcfg-rh.c'; then $(CYGPATH_W) 'test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh.c'; fi` + +test_ifcfg_rh_utils-test-ifcfg-rh-utils.o: test-ifcfg-rh-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh_utils-test-ifcfg-rh-utils.o -MD -MP -MF $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.o `test -f 'test-ifcfg-rh-utils.c' || echo '$(srcdir)/'`test-ifcfg-rh-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh-utils.c' object='test_ifcfg_rh_utils-test-ifcfg-rh-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.o `test -f 'test-ifcfg-rh-utils.c' || echo '$(srcdir)/'`test-ifcfg-rh-utils.c + +test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj: test-ifcfg-rh-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj -MD -MP -MF $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj `if test -f 'test-ifcfg-rh-utils.c'; then $(CYGPATH_W) 'test-ifcfg-rh-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh-utils.c' object='test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj `if test -f 'test-ifcfg-rh-utils.c'; then $(CYGPATH_W) 'test-ifcfg-rh-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh-utils.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +@WITH_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am check-local clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags ctags-recursive \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am + + +@WITH_TESTS_TRUE@check-local: test-ifcfg-rh +@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifcfg-rh-utils +@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifcfg-rh + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 new file mode 100755 index 00000000..4a6a9382 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10000.500.250.1 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 new file mode 100755 index 00000000..9bd5839b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = blah.foo.bar.baz +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry new file mode 100755 index 00000000..eba0ec67 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry @@ -0,0 +1,35 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f1 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth1 +node.name = iqn.1.2008-11.com.blahblah:iscsi1 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway new file mode 100755 index 00000000..b3dc7447 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = aa.bb.cc.dd +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr new file mode 100755 index 00000000..92f44777 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = bb.cc.dd.ee +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record new file mode 100755 index 00000000..a2d215fe --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record @@ -0,0 +1,18 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp new file mode 100755 index 00000000..6de0637c --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp @@ -0,0 +1,33 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f1 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth1 +node.name = iqn.1.2008-11.com.blahblah:iscsi1 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static new file mode 100755 index 00000000..99a6e7c1 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static @@ -0,0 +1,35 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f1 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan = 0 +iface.net_ifacename = eth1 +node.name = iqn.1.2008-11.com.blahblah:iscsi1 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am new file mode 100644 index 00000000..22d1b4a7 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -0,0 +1,90 @@ +EXTRA_DIST = \ + ifcfg-test-minimal \ + ifcfg-test-nm-controlled \ + ifcfg-test-wired-static \ + ifcfg-test-wired-static-bootproto \ + ifcfg-test-wired-dhcp \ + ifcfg-test-wired-dhcp6-only \ + ifcfg-test-wired-global-gateway \ + network-test-wired-global-gateway \ + ifcfg-test-wired-never-default \ + network-test-wired-never-default \ + ifcfg-test-wired-defroute-no \ + ifcfg-test-wired-defroute-no-gatewaydev-yes \ + network-test-wired-defroute-no-gatewaydev-yes \ + ifcfg-test-wired-8021x-peap-mschapv2 \ + keys-test-wired-8021x-peap-mschapv2 \ + ifcfg-test-wired-8021x-tls-agent \ + ifcfg-test-wired-8021x-tls-always \ + ifcfg-test-onboot-no \ + ifcfg-test-wifi-open \ + ifcfg-test-wifi-open-auto \ + ifcfg-test-wifi-open-ssid-quoted \ + ifcfg-test-wifi-open-ssid-long-quoted \ + ifcfg-test-wifi-open-ssid-hex \ + ifcfg-test-wifi-open-ssid-long-hex \ + ifcfg-test-wifi-open-ssid-bad-hex \ + ifcfg-test-wifi-wep \ + keys-test-wifi-wep \ + ifcfg-test-wifi-wep-adhoc \ + keys-test-wifi-wep-adhoc \ + ifcfg-test-wifi-wep-eap-ttls-chap \ + keys-test-wifi-wep-eap-ttls-chap \ + ifcfg-test-wifi-leap \ + keys-test-wifi-leap \ + ifcfg-test-wifi-leap-agent \ + ifcfg-test-wifi-leap-always-ask \ + ifcfg-test-wifi-wpa-psk \ + keys-test-wifi-wpa-psk \ + ifcfg-test-wifi-wpa-psk-unquoted \ + keys-test-wifi-wpa-psk-unquoted \ + ifcfg-test-wifi-wpa-psk-unquoted2 \ + keys-test-wifi-wpa-psk-unquoted2 \ + ifcfg-test-wifi-wpa-psk-adhoc \ + keys-test-wifi-wpa-psk-adhoc \ + ifcfg-test-wifi-wpa-psk-hex \ + keys-test-wifi-wpa-psk-hex \ + ifcfg-test-wifi-wpa-eap-tls \ + keys-test-wifi-wpa-eap-tls \ + ifcfg-test-wifi-wpa-eap-ttls-tls \ + keys-test-wifi-wpa-eap-ttls-tls \ + test_ca_cert.pem \ + test1_key_and_cert.pem \ + ifcfg-test-ibft-dhcp \ + ifcfg-test-ibft-static \ + ifcfg-test-static-routes-legacy \ + route-test-static-routes-legacy \ + ifcfg-test-wired-static-routes \ + route-test-wired-static-routes \ + ifcfg-test-wired-static-routes-legacy \ + route-test-wired-static-routes-legacy \ + ifcfg-test-wired-ipv6-manual \ + route6-test-wired-ipv6-manual \ + ifcfg-test-wired-static-no-prefix-8 \ + ifcfg-test-wired-static-no-prefix-16 \ + ifcfg-test-wired-static-no-prefix-24 \ + ifcfg-test-wired-ipv6-only \ + ifcfg-test-wifi-wep-passphrase \ + keys-test-wifi-wep-passphrase \ + ifcfg-test-wifi-wep-40-ascii \ + keys-test-wifi-wep-40-ascii \ + ifcfg-test-wifi-wep-104-ascii \ + keys-test-wifi-wep-104-ascii \ + ifcfg-test-wired-qeth-static \ + ifcfg-test-bridge-main \ + ifcfg-test-bridge-component \ + ifcfg-test-vlan-interface \ + ifcfg-test-wifi-wep-no-keys \ + ifcfg-test-permissions \ + ifcfg-test-wifi-wep-agent-keys \ + ifcfg-test-wifi-dynamic-wep-leap \ + keys-test-wifi-dynamic-wep-leap + +check-local: + @for f in $(EXTRA_DIST); do \ + chmod 0600 $(abs_srcdir)/$$f; \ + done + +# Make the special temp dir for some written connections + mkdir -p $(abs_builddir)/tmp + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in new file mode 100644 index 00000000..4f95948f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -0,0 +1,543 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ifcfg-rh/tests/network-scripts +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + ifcfg-test-minimal \ + ifcfg-test-nm-controlled \ + ifcfg-test-wired-static \ + ifcfg-test-wired-static-bootproto \ + ifcfg-test-wired-dhcp \ + ifcfg-test-wired-dhcp6-only \ + ifcfg-test-wired-global-gateway \ + network-test-wired-global-gateway \ + ifcfg-test-wired-never-default \ + network-test-wired-never-default \ + ifcfg-test-wired-defroute-no \ + ifcfg-test-wired-defroute-no-gatewaydev-yes \ + network-test-wired-defroute-no-gatewaydev-yes \ + ifcfg-test-wired-8021x-peap-mschapv2 \ + keys-test-wired-8021x-peap-mschapv2 \ + ifcfg-test-wired-8021x-tls-agent \ + ifcfg-test-wired-8021x-tls-always \ + ifcfg-test-onboot-no \ + ifcfg-test-wifi-open \ + ifcfg-test-wifi-open-auto \ + ifcfg-test-wifi-open-ssid-quoted \ + ifcfg-test-wifi-open-ssid-long-quoted \ + ifcfg-test-wifi-open-ssid-hex \ + ifcfg-test-wifi-open-ssid-long-hex \ + ifcfg-test-wifi-open-ssid-bad-hex \ + ifcfg-test-wifi-wep \ + keys-test-wifi-wep \ + ifcfg-test-wifi-wep-adhoc \ + keys-test-wifi-wep-adhoc \ + ifcfg-test-wifi-wep-eap-ttls-chap \ + keys-test-wifi-wep-eap-ttls-chap \ + ifcfg-test-wifi-leap \ + keys-test-wifi-leap \ + ifcfg-test-wifi-leap-agent \ + ifcfg-test-wifi-leap-always-ask \ + ifcfg-test-wifi-wpa-psk \ + keys-test-wifi-wpa-psk \ + ifcfg-test-wifi-wpa-psk-unquoted \ + keys-test-wifi-wpa-psk-unquoted \ + ifcfg-test-wifi-wpa-psk-unquoted2 \ + keys-test-wifi-wpa-psk-unquoted2 \ + ifcfg-test-wifi-wpa-psk-adhoc \ + keys-test-wifi-wpa-psk-adhoc \ + ifcfg-test-wifi-wpa-psk-hex \ + keys-test-wifi-wpa-psk-hex \ + ifcfg-test-wifi-wpa-eap-tls \ + keys-test-wifi-wpa-eap-tls \ + ifcfg-test-wifi-wpa-eap-ttls-tls \ + keys-test-wifi-wpa-eap-ttls-tls \ + test_ca_cert.pem \ + test1_key_and_cert.pem \ + ifcfg-test-ibft-dhcp \ + ifcfg-test-ibft-static \ + ifcfg-test-static-routes-legacy \ + route-test-static-routes-legacy \ + ifcfg-test-wired-static-routes \ + route-test-wired-static-routes \ + ifcfg-test-wired-static-routes-legacy \ + route-test-wired-static-routes-legacy \ + ifcfg-test-wired-ipv6-manual \ + route6-test-wired-ipv6-manual \ + ifcfg-test-wired-static-no-prefix-8 \ + ifcfg-test-wired-static-no-prefix-16 \ + ifcfg-test-wired-static-no-prefix-24 \ + ifcfg-test-wired-ipv6-only \ + ifcfg-test-wifi-wep-passphrase \ + keys-test-wifi-wep-passphrase \ + ifcfg-test-wifi-wep-40-ascii \ + keys-test-wifi-wep-40-ascii \ + ifcfg-test-wifi-wep-104-ascii \ + keys-test-wifi-wep-104-ascii \ + ifcfg-test-wired-qeth-static \ + ifcfg-test-bridge-main \ + ifcfg-test-bridge-component \ + ifcfg-test-vlan-interface \ + ifcfg-test-wifi-wep-no-keys \ + ifcfg-test-permissions \ + ifcfg-test-wifi-wep-agent-keys \ + ifcfg-test-wifi-dynamic-wep-leap \ + keys-test-wifi-dynamic-wep-leap + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-am check-local clean clean-generic \ + clean-libtool distclean distclean-generic distclean-libtool \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am + + +check-local: + @for f in $(EXTRA_DIST); do \ + chmod 0600 $(abs_srcdir)/$$f; \ + done + +# Make the special temp dir for some written connections + mkdir -p $(abs_builddir)/tmp + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component new file mode 100644 index 00000000..f586637e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component @@ -0,0 +1,5 @@ +DEVICE=eth0 +HWADDR=00:22:15:59:62:97 +ONBOOT=no +BRIDGE=br0 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main new file mode 100644 index 00000000..c5caf3fc --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main @@ -0,0 +1,7 @@ +DEVICE=br0 +ONBOOT=no +TYPE=Bridge +BOOTPROTO=dhcp +STP=on +DELAY=0 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp new file mode 100644 index 00000000..abfcd6e4 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp @@ -0,0 +1,4 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +DEVICE=eth0 +HWADDR=00:33:21:98:b9:f1 +BOOTPROTO=ibft diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static new file mode 100644 index 00000000..99b02e42 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static @@ -0,0 +1,4 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +DEVICE=eth0 +HWADDR=00:33:21:98:b9:f0 +BOOTPROTO=ibft diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal new file mode 100644 index 00000000..63bcc840 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal @@ -0,0 +1,4 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +DEVICE=eth0 +HWADDR=00:16:41:11:22:33 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled new file mode 100644 index 00000000..a38f1f5f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled @@ -0,0 +1,9 @@ +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:f8:9f +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=no + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no new file mode 100644 index 00000000..b9491711 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no @@ -0,0 +1,5 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +ONBOOT=no + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions new file mode 100644 index 00000000..5b413aa9 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions @@ -0,0 +1,8 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERS="dcbw ssmith johnny5" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy new file mode 100644 index 00000000..2173729d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy @@ -0,0 +1,12 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +DEVICE=eth0 +HWADDR=00:16:41:11:22:33 +NAME="test-static-routes-legacy" +TYPE=Ethernet +BOOTPROTO=dhcp +DEFROUTE=yes +UUID=ba60d05a-7898-820d-c2db-427a88f8f2a5 +ONBOOT=yes +IPV6INIT=no +PEERDNS=yes +PEERROUTES=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface new file mode 100644 index 00000000..6c841855 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface @@ -0,0 +1,7 @@ +DEVICE=eth1.43 +VLAN=yes +ONBOOT=yes +BOOTPROTO=none +IPADDR=192.168.43.149 +NETMASK=255.255.255.0 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap new file mode 100644 index 00000000..d9c95cc2 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap @@ -0,0 +1,17 @@ +ESSID="sdasdsdg" +MODE=Managed +KEY_MGMT=IEEE8021X +CIPHER_GROUP="WEP40 WEP104" +TYPE=Wireless +IEEE_8021X_EAP_METHODS=LEAP +IEEE_8021X_IDENTITY="bill smith" +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=yes +IPV6INIT=no +NAME="Test Dynamic WEP LEAP" +UUID=aca7a23c-d934-49a3-8bfb-ad66f846c57b +ONBOOT=yes +USERS=dcbw diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap new file mode 100644 index 00000000..50f4fd31 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap @@ -0,0 +1,17 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +KEY_MGMT=IEEE8021X +SECURITYMODE=LEAP +IEEE_8021X_IDENTITY="Bill Smith" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent new file mode 100644 index 00000000..991ba67a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent @@ -0,0 +1,17 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +KEY_MGMT=IEEE8021X +SECURITYMODE=LEAP +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_PASSWORD_FLAGS=user diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask new file mode 100644 index 00000000..5bb02b5c --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask @@ -0,0 +1,17 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +KEY_MGMT=IEEE8021X +SECURITYMODE=LEAP +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_PASSWORD_FLAGS="user ask" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open new file mode 100644 index 00000000..d4bb8f75 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto new file mode 100644 index 00000000..42ee200a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Auto +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex new file mode 100644 index 00000000..32d63342 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=0x626cxx +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex new file mode 100644 index 00000000..dcb46da7 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=0x626c6168626c6168 +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex new file mode 100644 index 00000000..37bb085b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=0x626c6168626c6168626c6168626c6168626c6168626c6168626c6168626c6168AA +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted new file mode 100644 index 00000000..0b46acd6 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID="foo\"bar\\foo\"bar\\foo\"bar\\foo\"bar\\1" +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted new file mode 100644 index 00000000..08496bb5 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID="foo\"bar\\" +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep new file mode 100644 index 00000000..e1ce20d6 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep @@ -0,0 +1,14 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +SECURITYMODE=restricted diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii new file mode 100644 index 00000000..250efa13 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii @@ -0,0 +1,14 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +SECURITYMODE=open diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii new file mode 100644 index 00000000..250efa13 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii @@ -0,0 +1,14 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +SECURITYMODE=open diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc new file mode 100644 index 00000000..9d0bacfc --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc @@ -0,0 +1,15 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=11 +MODE=Ad-Hoc +RATE=auto +ONBOOT=no +USERCTL=yes +PEERDNS=no +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys new file mode 100644 index 00000000..2bc16b6e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys @@ -0,0 +1,18 @@ +ESSID="foobar" +MODE=Managed +TYPE=Wireless +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=yes +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd +ONBOOT=yes +HWADDR=00:16:BB:AA:CC:DD +WEP_KEY_FLAGS=user +PEERDNS=yes +PEERROUTES=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap new file mode 100644 index 00000000..bdea6aa3 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap @@ -0,0 +1,20 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +BOOTPROTO=dhcp +ONBOOT=yes +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=yes +PEERDNS=yes +ESSID=blahblah +MODE=Managed +RATE=auto +KEY_MGMT=IEEE8021X +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY="David Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_INNER_AUTH_METHODS=CHAP + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys new file mode 100644 index 00000000..cb4da43f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys @@ -0,0 +1,18 @@ +ESSID="foobar" +MODE=Managed +TYPE=Wireless +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=yes +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd +ONBOOT=yes +HWADDR=00:16:BB:AA:CC:DD +DEFAULTKEY=1 +PEERDNS=yes +PEERROUTES=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase new file mode 100644 index 00000000..250efa13 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase @@ -0,0 +1,14 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +SECURITYMODE=open diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls new file mode 100644 index 00000000..92aaeeab --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls @@ -0,0 +1,25 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +BOOTPROTO=dhcp +ONBOOT=yes +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=yes +PEERDNS=yes +ESSID=blahblah +MODE=Managed +RATE=auto +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-EAP +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes +IEEE_8021X_EAP_METHODS=TLS +IEEE_8021X_IDENTITY="Bill Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem +IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls new file mode 100644 index 00000000..42ed1d68 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls @@ -0,0 +1,28 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +BOOTPROTO=dhcp +ONBOOT=yes +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=yes +PEERDNS=yes +ESSID=blahblah +MODE=Managed +RATE=auto +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-EAP +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY="Chuck Shumer" +IEEE_8021X_ANON_IDENTITY="anonymous" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_INNER_AUTH_METHODS=EAP-TLS +IEEE_8021X_INNER_CA_CERT=test_ca_cert.pem +IEEE_8021X_INNER_CLIENT_CERT=test1_key_and_cert.pem +IEEE_8021X_INNER_PRIVATE_KEY=test1_key_and_cert.pem + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk new file mode 100644 index 00000000..2119ba8e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk @@ -0,0 +1,19 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-PSK +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc new file mode 100644 index 00000000..aa00925e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc @@ -0,0 +1,16 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Ad-Hoc +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_GROUP=CCMP +KEY_MGMT=WPA-PSK + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex new file mode 100644 index 00000000..2119ba8e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex @@ -0,0 +1,19 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-PSK +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted new file mode 100644 index 00000000..2119ba8e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted @@ -0,0 +1,19 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-PSK +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2 new file mode 100644 index 00000000..2119ba8e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2 @@ -0,0 +1,19 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=1 +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no +CIPHER_PAIRWISE="TKIP CCMP" +CIPHER_GROUP="TKIP CCMP WEP40 WEP104" +KEY_MGMT=WPA-PSK +WPA_ALLOW_WPA=yes +WPA_ALLOW_WPA2=yes + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 new file mode 100644 index 00000000..6d68eca1 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +NM_CONTROLLED=yes +KEY_MGMT=IEEE8021X +IEEE_8021X_EAP_METHODS=PEAP +IEEE_8021X_IDENTITY="David Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_PEAP_VERSION=1 +IEEE_8021X_PEAP_FORCE_NEW_LABEL=yes +IEEE_8021X_INNER_AUTH_METHODS=MSCHAPV2 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent new file mode 100644 index 00000000..052ab425 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +NM_CONTROLLED=yes +KEY_MGMT=IEEE8021X +IEEE_8021X_EAP_METHODS=TLS +IEEE_8021X_IDENTITY="David Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem +IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem +IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS=user diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always new file mode 100644 index 00000000..5deee066 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +NM_CONTROLLED=yes +KEY_MGMT=IEEE8021X +IEEE_8021X_EAP_METHODS=TLS +IEEE_8021X_IDENTITY="David Smith" +IEEE_8021X_CA_CERT=test_ca_cert.pem +IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem +IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem +IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS="user ask" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no new file mode 100644 index 00000000..fe8b15b2 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth4 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +NM_CONTROLLED=yes +PEERDNS=yes +DEFROUTE=no + +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=no + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes new file mode 100644 index 00000000..3cf4323d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +NM_CONTROLLED=yes +PEERDNS=yes +DEFROUTE=no + +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=no + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp new file mode 100644 index 00000000..727d2ceb --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=yes +PEERDNS=no +DHCP_HOSTNAME=foobar +DNS1=4.2.2.1 +DNS2=4.2.2.2 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only new file mode 100644 index 00000000..de03e044 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only @@ -0,0 +1,11 @@ +DEVICE="eth0" +ONBOOT=no +TYPE=Ethernet +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV6INIT=yes +IPV6_AUTOCONF=no +DHCPV6C=yes +HWADDR=00:13:20:F5:F5:E4 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway new file mode 100644 index 00000000..98d91053 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +PREFIX=24 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual new file mode 100644 index 00000000..45db0e4c --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual @@ -0,0 +1,19 @@ +# Intel Corporation 82567LM Gigabit Network Connection +TYPE=Ethernet +DEVICE=eth2 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +NM_CONTROLLED=yes +PEERDNS=yes +DNS1=10.2.0.4 +DNS2=10.2.0.5 +DNS3=1:2:3:4::a +DNS4=1:2:3:4::b +DOMAIN="lorem.com ipsum.org dolor.edu" +IPV6INIT=yes +IPV6_AUTOCONF=no +IPV6ADDR="1001:abba::1234/56" +IPV6ADDR_SECONDARIES="2001:abba::2234/64 3001:abba::3234/96" +IPV6_FAILURE_FATAL=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only new file mode 100644 index 00000000..59ec32e5 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only @@ -0,0 +1,14 @@ +# Intel Corporation 82567LM Gigabit Network Connection +TYPE=Ethernet +DEVICE=eth2 +HWADDR=00:11:22:33:44:ee +ONBOOT=yes +USERCTL=yes +NM_CONTROLLED=yes +PEERDNS=yes +DNS1=1:2:3:4::a +DOMAIN="lorem.com ipsum.org dolor.edu" +IPV6INIT=yes +IPV6_AUTOCONF=no +IPV6ADDR="1001:abba::1234/56" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default new file mode 100644 index 00000000..12d5b5e6 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default @@ -0,0 +1,11 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth4 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERCTL=yes +NM_CONTROLLED=yes +PEERDNS=yes +IPV6INIT=yes +IPV6_AUTOCONF=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static new file mode 100644 index 00000000..4719de21 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static @@ -0,0 +1,13 @@ +# IBM QETH +DEVICE=eth1 +BOOTPROTO=static +IPADDR=192.168.70.87 +NETMASK=255.255.255.0 +ONBOOT=yes +NETTYPE=qeth +SUBCHANNELS=0.0.0600,0.0.0601,0.0.0602 +TYPE=Ethernet +PORTNAME=OSAPORT +OPTIONS='layer2=1 portno=0' +MACADDR=02:00:00:23:65:1a + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static new file mode 100644 index 00000000..c8315f45 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static @@ -0,0 +1,20 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +NETMASK=255.255.255.0 +GATEWAY=192.168.1.1 +IPV6INIT=yes +IPV6_AUTOCONF=no +IPV6ADDR=dead:beaf::1 +IPV6ADDR_SECONDARIES="dead:beaf::2/56" +DNS3=1:2:3:4::a +DNS4=1:2:3:4::b diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto new file mode 100644 index 00000000..ee821503 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=static +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +NETMASK=255.255.255.0 +GATEWAY=192.168.1.1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16 new file mode 100644 index 00000000..07999038 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16 @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=172.16.3.4 +GATEWAY=172.16.3.1 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24 new file mode 100644 index 00000000..688143cd --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24 @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +GATEWAY=192.168.1.1 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8 new file mode 100644 index 00000000..0433c62a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8 @@ -0,0 +1,14 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=10.11.12.13 +GATEWAY=10.0.0.1 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes new file mode 100644 index 00000000..7faf49bd --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +NETMASK=255.255.255.0 +GATEWAY=192.168.1.1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy new file mode 100644 index 00000000..7faf49bd --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy @@ -0,0 +1,15 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=none +ONBOOT=yes +USERCTL=yes +IPV6INIT=no +MTU=1492 +NM_CONTROLLED=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +NETMASK=255.255.255.0 +GATEWAY=192.168.1.1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap new file mode 100644 index 00000000..6936f2e0 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap @@ -0,0 +1,2 @@ +IEEE_8021X_PASSWORD="foobar baz" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap new file mode 100644 index 00000000..fe78177e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap @@ -0,0 +1 @@ +IEEE_8021X_PASSWORD="foobarblah" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep new file mode 100644 index 00000000..0bd766c2 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep @@ -0,0 +1 @@ +KEY=0123456789abcdef0123456789 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii new file mode 100644 index 00000000..f5d532b2 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii @@ -0,0 +1 @@ +KEY1=s:LoremIpsumSit diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii new file mode 100644 index 00000000..b0d14708 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii @@ -0,0 +1 @@ +KEY1=s:Lorem diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc new file mode 100644 index 00000000..0bd766c2 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc @@ -0,0 +1 @@ +KEY=0123456789abcdef0123456789 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap new file mode 100644 index 00000000..6936f2e0 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap @@ -0,0 +1,2 @@ +IEEE_8021X_PASSWORD="foobar baz" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase new file mode 100644 index 00000000..d45c0ea8 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase @@ -0,0 +1 @@ +KEY_PASSPHRASE1="foobar222blahblah" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls new file mode 100644 index 00000000..0c3bc1e1 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls @@ -0,0 +1,2 @@ +IEEE_8021X_PRIVATE_KEY_PASSWORD="test1" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls new file mode 100644 index 00000000..b6256b95 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls @@ -0,0 +1,2 @@ +IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD="test1" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk new file mode 100644 index 00000000..d7813b2f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk @@ -0,0 +1,2 @@ +WPA_PSK="I wonder what the king is doing tonight?" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc new file mode 100644 index 00000000..d7813b2f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc @@ -0,0 +1,2 @@ +WPA_PSK="I wonder what the king is doing tonight?" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex new file mode 100644 index 00000000..d0576a8d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex @@ -0,0 +1,2 @@ +WPA_PSK=1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted new file mode 100644 index 00000000..9a47196a --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted @@ -0,0 +1,2 @@ +WPA_PSK=54336845e2f3f321c4c7 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2 new file mode 100644 index 00000000..347bb85e --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2 @@ -0,0 +1,2 @@ +WPA_PSK="a5d4d45e78e1455d8e6124e81ea137f9a5d4d45e78e1455d8e6124e81ea137f9" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2 new file mode 100644 index 00000000..6936f2e0 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2 @@ -0,0 +1,2 @@ +IEEE_8021X_PASSWORD="foobar baz" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes new file mode 100644 index 00000000..0d6a302f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes @@ -0,0 +1,2 @@ +GATEWAYDEV=eth0 +IPV6_DEFAULTDEV=eth0 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway new file mode 100644 index 00000000..7987d105 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway @@ -0,0 +1 @@ +GATEWAY=192.168.1.2 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default new file mode 100644 index 00000000..9a292679 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default @@ -0,0 +1,4 @@ +GATEWAYDEV=eth0 +# when devices in IPV6_DEFAULTDEV and IPV6_DEFAULTGW don't match the one in IPV6_DEFAULTGW is prefered +IPV6_DEFAULTDEV=eth4 +IPV6_DEFAULTGW=2001::1234%eth0 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy new file mode 100644 index 00000000..3db42ab5 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy @@ -0,0 +1,3 @@ +1.2.3.0/24 via 222.173.190.239 metric 0 +3.2.1.0/24 via 202.254.171.190 metric 77 +7.7.7.7/32 via 10.0.2.2 metric 11 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes new file mode 100644 index 00000000..ee2a32d8 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes @@ -0,0 +1,8 @@ +ADDRESS0=11.22.33.0 +NETMASK0=255.255.255.0 +GATEWAY0=192.168.1.5 + +ADDRESS1=44.55.66.77 +NETMASK1=255.255.255.255 +GATEWAY1=192.168.1.7 +METRIC1=3 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy new file mode 100644 index 00000000..cb7d42bd --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy @@ -0,0 +1,7 @@ +# Test route file in legacy format; i.e. lines passed as argumet to "ip route add" + + +21.31.41.0/24 via 9.9.9.9 metric 1 + via 8.8.8.8 to 32.42.52.62 + 43.53.0.0/16 metric 3 via 7.7.7.7 dev eth2 + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual new file mode 100644 index 00000000..ae4e47ae --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual @@ -0,0 +1 @@ +9876::1234/96 via 9876::7777 metric 2 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem new file mode 100644 index 00000000..dec9aa1b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem @@ -0,0 +1,118 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4DE0615F23D82107 + +QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz +L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7 +zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU +h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW +ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv +QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na +eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo +cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m +RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8 +xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr +T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI +ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo +RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ +EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt +lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5 +r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4 +aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W +GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e +DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE +lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO +8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3 +VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt +G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ +tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW +QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1 +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com + Validity + Not Before: Mar 10 15:13:16 2009 GMT + Not After : Mar 8 15:13:16 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a: + 82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48: + ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49: + c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8: + 03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14: + ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9: + c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c: + 60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d: + 44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b: + f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d: + c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75: + d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2: + 06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38: + ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba: + ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36: + 2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11: + a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f: + a3:43 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C + X509v3 Authority Key Identifier: + keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10 + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com + serial:EB:E7:64:FB:79:F7:22:19 + + Signature Algorithm: md5WithRSAEncryption + 7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82: + f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89: + b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b: + 12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76: + 1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48: + 32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02: + 85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1: + fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c: + cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43: + 8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71: + 1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19: + 07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69: + 7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62: + 8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7: + 3b:65:fe:f9 +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx +HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN +MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl +MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG +A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR +XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA +vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9 +jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF +TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX +gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj +ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy +YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww +gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ +BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx +FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD +VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3 +IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/ +DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2 +8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr +vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD +T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa +PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk= +-----END CERTIFICATE----- diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem new file mode 100644 index 00000000..ef1be20d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE +AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx +NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ +QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55 +IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3 +DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU +xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc +Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3 +FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4 +HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm +J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P +T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF +ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL +EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl +c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc +JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT +p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t +qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn +B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp +3nniskIjbH0xjgZf/nVMyLnjxg== +-----END CERTIFICATE----- diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c new file mode 100644 index 00000000..a6c54fd3 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c @@ -0,0 +1,164 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2009 Red Hat, Inc. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> + +#include "nm-test-helpers.h" + +#include "common.h" +#include "utils.h" + + +static void +test_get_ifcfg_name (const char *desc, + const char *path, + gboolean only_ifcfg, + const char *expected) +{ + const char *result; + + result = utils_get_ifcfg_name (path, only_ifcfg); + if (expected == NULL) { + ASSERT (result == NULL, desc, "unexpected valid ifcfg name '%s'", result); + } else { + ASSERT (result != NULL, desc, "failed to create ifcfg name for '%s'", path); + + ASSERT (strcmp (result, expected) == 0, + desc, "unexpected ifcfg name '%s' created for '%s'", result, path); + } +} + +static void +test_get_ifcfg_path (const char *desc, + const char *path, + const char *expected) +{ + const char *result; + + result = utils_get_ifcfg_path (path); + if (expected == NULL) { + ASSERT (result == NULL, desc, "unexpected valid ifcfg name '%s'", result); + } else { + ASSERT (result != NULL, desc, "failed to create ifcfg name for '%s'", path); + + ASSERT (strcmp (result, expected) == 0, + desc, "unexpected ifcfg name '%s' created for '%s'", result, path); + } +} + +static void +test_get_keys_path (const char *desc, + const char *path, + const char *expected) +{ + const char *result; + + result = utils_get_keys_path (path); + if (expected == NULL) { + ASSERT (result == NULL, desc, "unexpected valid extra path '%s'", result); + } else { + ASSERT (result != NULL, desc, "failed to create extra path for '%s'", path); + + ASSERT (strcmp (result, expected) == 0, + desc, "unexpected extra path '%s' created for '%s'", result, path); + } +} + +static void +test_get_route_path (const char *desc, + const char *path, + const char *expected) +{ + const char *result; + + result = utils_get_route_path (path); + if (expected == NULL) { + ASSERT (result == NULL, desc, "unexpected valid extra path '%s'", result); + } else { + ASSERT (result != NULL, desc, "failed to create extra path for '%s'", path); + + ASSERT (strcmp (result, expected) == 0, + desc, "unexpected extra path '%s' created for '%s'", result, path); + } +} + +static void +test_ignored (const char *desc, const char *path, gboolean expected_ignored) +{ + gboolean result; + + result = utils_should_ignore_file (path, FALSE); + ASSERT (result == expected_ignored, desc, "unexpected ignore result for path '%s'", path); +} + +int main (int argc, char **argv) +{ + char *base; + + /* The tests */ + test_get_ifcfg_name ("get-ifcfg-name-bad", "/foo/bar/adfasdfadf", FALSE, NULL); + test_get_ifcfg_name ("get-ifcfg-name-good", "/foo/bar/ifcfg-FooBar", FALSE, "FooBar"); + test_get_ifcfg_name ("get-ifcfg-name-keys", "/foo/bar/keys-BlahLbah", FALSE, "BlahLbah"); + test_get_ifcfg_name ("get-ifcfg-name-route", "/foo/bar/route-Lalalala", FALSE, "Lalalala"); + test_get_ifcfg_name ("get-ifcfg-name-only-ifcfg-route", "/foo/bar/route-Lalalala", TRUE, NULL); + test_get_ifcfg_name ("get-ifcfg-name-only-ifcfg-keys", "/foo/bar/keys-Lalalala", TRUE, NULL); + test_get_ifcfg_name ("get-ifcfg-name-no-path-ifcfg", "ifcfg-Lalalala", FALSE, "Lalalala"); + test_get_ifcfg_name ("get-ifcfg-name-no-path-keys", "keys-Lalalala", FALSE, "Lalalala"); + test_get_ifcfg_name ("get-ifcfg-name-no-path-route", "route-Lalalala", FALSE, "Lalalala"); + + test_get_ifcfg_name ("get-ifcfg-name-bad2-ifcfg", "/foo/bar/asdfasifcfg-Foobar", FALSE, NULL); + test_get_ifcfg_name ("get-ifcfg-name-bad2-keys", "/foo/bar/asdfaskeys-Foobar", FALSE, NULL); + test_get_ifcfg_name ("get-ifcfg-name-bad2-route", "/foo/bar/asdfasroute-Foobar", FALSE, NULL); + + test_get_ifcfg_path ("ifcfg-path-bad", "/foo/bar/adfasdfasdf", NULL); + test_get_ifcfg_path ("ifcfg-path-from-keys-no-path", "keys-BlahBlah", "ifcfg-BlahBlah"); + test_get_ifcfg_path ("ifcfg-path-from-keys", "/foo/bar/keys-BlahBlah", "/foo/bar/ifcfg-BlahBlah"); + test_get_ifcfg_path ("ifcfg-path-from-route", "/foo/bar/route-BlahBlah", "/foo/bar/ifcfg-BlahBlah"); + + test_get_keys_path ("keys-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); + test_get_keys_path ("keys-path-from-ifcfg-no-path", "ifcfg-FooBar", "keys-FooBar"); + test_get_keys_path ("keys-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/keys-FooBar"); + test_get_keys_path ("keys-path-from-route", "/foo/bar/route-FooBar", "/foo/bar/keys-FooBar"); + + test_get_route_path ("route-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); + test_get_route_path ("route-path-from-ifcfg-no-path", "ifcfg-FooBar", "route-FooBar"); + test_get_route_path ("route-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/route-FooBar"); + test_get_route_path ("route-path-from-keys", "/foo/bar/keys-FooBar", "/foo/bar/route-FooBar"); + + test_ignored ("ignored-ifcfg", "ifcfg-FooBar", FALSE); + test_ignored ("ignored-keys", "keys-FooBar", FALSE); + test_ignored ("ignored-route", "route-FooBar", FALSE); + test_ignored ("ignored-bak", "ifcfg-FooBar" BAK_TAG, TRUE); + test_ignored ("ignored-tilde", "ifcfg-FooBar" TILDE_TAG, TRUE); + test_ignored ("ignored-orig", "ifcfg-FooBar" ORIG_TAG, TRUE); + test_ignored ("ignored-rej", "ifcfg-FooBar" REJ_TAG, TRUE); + test_ignored ("ignored-rpmnew", "ifcfg-FooBar" RPMNEW_TAG, TRUE); + test_ignored ("ignored-augnew", "ifcfg-FooBar" AUGNEW_TAG, TRUE); + test_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c new file mode 100644 index 00000000..ebe9e47f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -0,0 +1,10849 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <netinet/ether.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <nm-utils.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-8021x.h> +#include <nm-setting-pppoe.h> +#include <nm-setting-ppp.h> +#include <nm-setting-vpn.h> +#include <nm-setting-gsm.h> +#include <nm-setting-cdma.h> +#include <nm-setting-serial.h> + +#include "nm-test-helpers.h" + +#include "common.h" +#include "reader.h" +#include "writer.h" +#include "utils.h" + +#if 0 +static void +connection_diff (NMConnection *a, NMConnection *b) +{ + GHashTable *hash; + GHashTableIter iter, siter; + const char *setting_name, *key; + GHashTable *setting_hash = NULL; + + if (!nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &hash)) { + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + g_hash_table_iter_init (&siter, setting_hash); + while (g_hash_table_iter_next (&siter, (gpointer) &key, NULL)) + g_message (":: %s :: %s", setting_name,key); + } + g_hash_table_destroy (hash); + } +} +#endif + +typedef enum { + CK_CA_CERT = 0, + CK_CLIENT_CERT = 1, + CK_PRIV_KEY = 2 +} CertKeyType; + +static gboolean +verify_cert_or_key (CertKeyType ck_type, + NMSetting8021x *s_compare, + const char *file, + const char *privkey_password, + const char *ifcfg, + const char *test_name, + const char *setting_key) +{ + NMSetting8021x *s_8021x; + GError *error = NULL; + gboolean success = FALSE; + const char *expected = NULL, *setting = NULL; + gboolean phase2 = FALSE; + NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + + if (strstr (setting_key, "phase2")) + phase2 = TRUE; + + /* CA Cert */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, + test_name, "failed to verify %s: could not create temp 802.1x setting", + ifcfg); + + if (ck_type == CK_CA_CERT) { + if (phase2) + success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + else + success = nm_setting_802_1x_set_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + } else if (ck_type == CK_CLIENT_CERT) { + if (phase2) + success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + else + success = nm_setting_802_1x_set_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + } else if (ck_type == CK_PRIV_KEY) { + if (phase2) + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + else + success = nm_setting_802_1x_set_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); + } + ASSERT (success == TRUE, + test_name, "failed to verify %s: could not load item for %s / %s: %s", + ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key, error->message); + + if (ck_type == CK_CA_CERT) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021x); + else + scheme = nm_setting_802_1x_get_ca_cert_scheme (s_8021x); + } else if (ck_type == CK_CLIENT_CERT) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021x); + else + scheme = nm_setting_802_1x_get_client_cert_scheme (s_8021x); + } else if (ck_type == CK_PRIV_KEY) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x); + else + scheme = nm_setting_802_1x_get_private_key_scheme (s_8021x); + } + ASSERT (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + test_name, "failed to verify %s: unexpected cert/key scheme for %s / %s", + ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key); + + if (ck_type == CK_CA_CERT) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_ca_cert_path (s_8021x); + else + expected = nm_setting_802_1x_get_ca_cert_path (s_8021x); + } else if (ck_type == CK_CLIENT_CERT) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_client_cert_path (s_8021x); + else + expected = nm_setting_802_1x_get_client_cert_path (s_8021x); + } else if (ck_type == CK_PRIV_KEY) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_private_key_path (s_8021x); + else + expected = nm_setting_802_1x_get_private_key_path (s_8021x); + } + ASSERT (expected != NULL, + test_name, "failed to verify %s: failed to get read item for %s / %s", + ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key); + + if (ck_type == CK_CA_CERT) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_ca_cert_path (s_compare); + else + setting = nm_setting_802_1x_get_ca_cert_path (s_compare); + } else if (ck_type == CK_CLIENT_CERT) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_client_cert_path (s_compare); + else + setting = nm_setting_802_1x_get_client_cert_path (s_compare); + } else if (ck_type == CK_PRIV_KEY) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_private_key_path (s_compare); + else + setting = nm_setting_802_1x_get_private_key_path (s_compare); + } + ASSERT (setting != NULL, + test_name, "failed to verify %s: missing %s / %s key", + ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key); + + ASSERT (strlen (setting) == strlen (expected), + test_name, "failed to verify %s: unexpected %s / %s certificate length", + test_name, NM_SETTING_802_1X_SETTING_NAME, setting_key); + + ASSERT (strcmp (setting, expected) == 0, + test_name, "failed to verify %s: %s / %s key certificate mismatch", + ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key); + + g_object_unref (s_8021x); + return TRUE; +} + + +#define TEST_IFCFG_MINIMAL TEST_IFCFG_DIR"/network-scripts/ifcfg-test-minimal" + +static void +test_read_minimal (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; + const char *expected_id = "System test-minimal"; + guint64 expected_timestamp = 0; + + connection = connection_from_file (TEST_IFCFG_MINIMAL, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "minimal-wired-read", "failed to read %s: %s", TEST_IFCFG_MINIMAL, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "minimal-wired-verify", "failed to verify %s: %s", TEST_IFCFG_MINIMAL, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "minimal-wired-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_MINIMAL, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "minimal-wired-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_MINIMAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "minimal-wired-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "minimal-wired-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "minimal-wired-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "minimal-wired-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_MINIMAL, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "minimal-wired-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_MINIMAL, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_MINIMAL, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + ASSERT (nm_setting_wired_get_mtu (s_wired) == 0, + "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MTU); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "minimal-wired-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_MINIMAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "minimal-wired-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, + "minimal-wired-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_MINIMAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + + g_object_unref (connection); +} + +#define TEST_IFCFG_UNMANAGED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-nm-controlled" + +static void +test_read_unmanaged (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0xf8, 0x9f }; + const char *expected_id = "System test-nm-controlled"; + guint64 expected_timestamp = 0; + + connection = connection_from_file (TEST_IFCFG_UNMANAGED, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "unmanaged-read", "failed to read %s: %s", TEST_IFCFG_UNMANAGED, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "unmanaged-verify", "failed to verify %s: %s", TEST_IFCFG_UNMANAGED, error->message); + + ASSERT (unmanaged != NULL, + "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED); + + ASSERT (strcmp (unmanaged, "mac:00:11:22:33:f8:9f") == 0, + "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "unmanaged-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_UNMANAGED, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "unmanaged-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_UNMANAGED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "unmanaged-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_UNMANAGED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "unmanaged-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_UNMANAGED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + /* Since the unmanaged connections are not completely read, defaults will + * be used for many settings. + */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "unmanaged-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_UNMANAGED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "unmanaged-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_UNMANAGED, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "unmanaged-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_UNMANAGED, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "unmanaged-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_UNMANAGED, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "unmanaged-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_UNMANAGED, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 == NULL, + "unmanaged-verify-ip4", "failed to verify %s: unexpected %s setting", + TEST_IFCFG_UNMANAGED, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + g_object_unref (connection); +} + +static void +test_read_wired_static (const char *file, const char *expected_id) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = FALSE; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; + const char *tmp; + const char *expected_dns1 = "4.2.2.1"; + const char *expected_dns2 = "4.2.2.2"; + struct in_addr addr; + struct in6_addr addr6; + const char *expected_address1 = "192.168.1.5"; + const char *expected_address1_gw = "192.168.1.1"; + const char *expected6_address1 = "dead:beaf::1"; + const char *expected6_address2 = "dead:beaf::2"; + const char *expected6_dns1 = "1:2:3:4::a"; + const char *expected6_dns2 = "1:2:3:4::b"; + NMIP4Address *ip4_addr; + NMIP6Address *ip6_addr; + + connection = connection_from_file (file, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-static-read", "failed to read %s: %s", file, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-static-verify", "failed to verify %s: %s", file, error->message); + + ASSERT (unmanaged == FALSE, + "wired-static-verify", "failed to verify %s: unexpected unmanaged value", file); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-static-verify-connection", "failed to verify %s: missing %s setting", + file, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-static-verify-connection", "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-static-verify-connection", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == 0, + "wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-static-verify-wired", "failed to verify %s: missing %s setting", + file, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "wired-static-verify-wired", "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + file, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + ASSERT (nm_setting_wired_get_mtu (s_wired) == 1492, + "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MTU); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-static-verify-ip4", "failed to verify %s: missing %s setting", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* Implicit may-fail */ + ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == FALSE, + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_MAY_FAIL); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + "wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + "wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* Address #1 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + "wired-static-verify-ip4", "failed to verify %s: missing IP4 address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24, + "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, + "wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, + "wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, + "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + if (!strcmp (expected_id, "System test-wired-static")) { + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-static-verify-ip6", "failed to verify %s: missing %s setting", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + /* Implicit may-fail */ + ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE, + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_MAY_FAIL); + + /* DNS Addresses */ + ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected6_dns1, &addr6) > 0, + "wired-static-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1", + file); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6), + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected6_dns2, &addr6) > 0, + "wired-static-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #2", + file); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6), + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value #2", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 2, + "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* Address #1 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + "wired-static-verify-ip6", "failed to verify %s: missing IP6 address #1", + file); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64, + "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix", + file); + + ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0, + "wired-static-verify-ip6", "failed to verify %s: couldn't convert IP address #1", + file); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6), + "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #1", + file); + + /* Address #2 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); + ASSERT (ip6_addr, + "wired-static-verify-ip6", "failed to verify %s: missing IP6 address #2", + file); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 56, + "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #2 prefix", + file); + + ASSERT (inet_pton (AF_INET6, expected6_address2, &addr6) > 0, + "wired-static-verify-ip6", "failed to verify %s: couldn't convert IP address #2", + file); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6), + "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #2", + file); + } + + g_object_unref (connection); +} + +#define TEST_IFCFG_STATIC_NO_PREFIX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-no-prefix" + +static void +test_read_wired_static_no_prefix (guint32 expected_prefix) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + char *unmanaged = FALSE; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + NMIP4Address *ip4_addr; + char *file, *expected_id; + const char *tmp; + + file = g_strdup_printf (TEST_IFCFG_STATIC_NO_PREFIX "-%u", expected_prefix); + ASSERT (file != NULL, + "wired-static-no-prefix-read", "failed to create path to file"); + + expected_id = g_strdup_printf ("System test-wired-static-no-prefix-%u", expected_prefix); + ASSERT (expected_id != NULL, + "wired-static-no-prefix-read", "failed to expected connection ID"); + + connection = connection_from_file (file, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-static-no-prefix-read", "failed to read %s: %s", file, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-static-no-prefix-verify", "failed to verify %s: %s", file, error->message); + + ASSERT (unmanaged == FALSE, + "wired-static-no-prefix-verify", "failed to verify %s: unexpected unmanaged value", file); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s setting", + file, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s / %s key", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-static-no-prefix-verify-connection", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + g_free (expected_id); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing %s setting", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* Address #1 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing IP4 address #1", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, + "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", + file, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + g_free (file); + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_DHCP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp" + +static void +test_read_wired_dhcp (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; + const char *tmp; + const char *expected_id = "System test-wired-dhcp"; + const char *expected_dns1 = "4.2.2.1"; + const char *expected_dns2 = "4.2.2.2"; + struct in_addr addr; + const char *expected_dhcp_hostname = "foobar"; + + connection = connection_from_file (TEST_IFCFG_WIRED_DHCP, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-dhcp-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP, error->message); + + ASSERT (unmanaged == FALSE, + "wired-dhcp-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-dhcp-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-dhcp-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == 0, + "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-dhcp-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "wired-dhcp-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-dhcp-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + tmp = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); + ASSERT (tmp != NULL, + "wired-dhcp-verify-ip4", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME); + ASSERT (strcmp (tmp, expected_dhcp_hostname) == 0, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME); + + ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway" +#define TEST_NETWORK_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway" + +static void +test_read_wired_global_gateway (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-global-gateway"; + struct in_addr addr; + const char *expected_address1 = "192.168.1.5"; + const char *expected_address1_gw = "192.168.1.2"; + NMIP4Address *ip4_addr; + + connection = connection_from_file (TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + TEST_NETWORK_WIRED_GLOBAL_GATEWAY, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-global-gateway-read", "failed to read %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-global-gateway-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message); + + ASSERT (unmanaged == FALSE, + "wired-global-gateway-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_GLOBAL_GATEWAY); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-global-gateway-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-global-gateway-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* Address #1 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + "wired-global-gateway-verify-ip4", "failed to verify %s: missing IP4 address #1", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24, + "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, + "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, + "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, + "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway", + TEST_IFCFG_WIRED_GLOBAL_GATEWAY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default" +#define TEST_NETWORK_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default" + +static void +test_read_wired_never_default (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-never-default"; + + connection = connection_from_file (TEST_IFCFG_WIRED_NEVER_DEFAULT, + TEST_NETWORK_WIRED_NEVER_DEFAULT, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-never-default-read", "failed to read %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-never-default-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message); + + ASSERT (unmanaged == FALSE, + "wired-never-default-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_NEVER_DEFAULT); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-never-default-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-never-default-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-never-default-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-never-default-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-never-default-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE, + "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 0, + "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-never-default-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0, + "wired-never-default-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE, + "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_NEVER_DEFAULT, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_DEFROUTE_NO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no" + +static void +test_read_wired_defroute_no (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-defroute-no"; + + connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-defroute-no-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-defroute-no-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message); + + ASSERT (unmanaged == FALSE, + "wired-defroute-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DEFROUTE_NO); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-defroute-no-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-defroute-no-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-defroute-no-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-defroute-no-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-defroute-no-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE, + "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-defroute-no-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0, + "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE, + "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes" +#define TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES TEST_IFCFG_DIR"/network-scripts/network-test-wired-defroute-no-gatewaydev-yes" + +static void +test_read_wired_defroute_no_gatewaydev_yes (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-defroute-no-gatewaydev-yes"; + + connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-defroute-no-gatewaydev-yes-read", + "failed to read %s: %s", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-defroute-no-gatewaydev-yes-verify", + "failed to verify %s: %s", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + error->message); + + ASSERT (unmanaged == FALSE, + "wired-defroute-no-gatewaydev-yes-verify", + "failed to verify %s: unexpected unmanaged value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-defroute-no-gatewaydev-yes-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, + "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE, + "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_STATIC_ROUTES TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes" + +static void +test_read_wired_static_routes (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + NMIP4Route *ip4_route; + struct in_addr addr; + const char *expected_id = "System test-wired-static-routes"; + const char *expected_dst1 = "11.22.33.0"; + const char *expected_dst2 = "44.55.66.77"; + const char *expected_gw1 = "192.168.1.5"; + const char *expected_gw2 = "192.168.1.7"; + + connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + + ASSERT (connection != NULL, + "wired-static-routes-read", + "failed to read %s: %s", + TEST_IFCFG_WIRED_STATIC_ROUTES, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-static-routes-verify", "failed to verify %s: %s", + TEST_IFCFG_WIRED_STATIC_ROUTES, error->message); + + ASSERT (unmanaged == NULL, + "wired-static-routes-verify", + "failed to verify %s: unexpected unmanaged value", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-static-routes-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-static-routes-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-static-routes-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-static-routes-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-static-routes-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* Routes */ + ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 2, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0); + ASSERT (ip4_route, + "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #1", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0, + "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1", + TEST_IFCFG_WIRED_STATIC_ROUTES); + ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0, + "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1", + TEST_IFCFG_WIRED_STATIC_ROUTES); + ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1); + ASSERT (ip4_route, + "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #2", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0, + "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2", + TEST_IFCFG_WIRED_STATIC_ROUTES); + ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0, + "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2", + TEST_IFCFG_WIRED_STATIC_ROUTES); + ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_STATIC_ROUTES, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + ASSERT (nm_ip4_route_get_metric (ip4_route) == 3, + "wired-static-routes-verify-ip4", "failed to verify %s: unexpected route metric #2", + TEST_IFCFG_WIRED_STATIC_ROUTES); + + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes-legacy" + +static void +test_read_wired_static_routes_legacy (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + NMIP4Route *ip4_route; + struct in_addr addr; + const char *expected_id = "System test-wired-static-routes-legacy"; + const char *expected_dst1 = "21.31.41.0"; + const char *expected_dst2 = "32.42.52.62"; + const char *expected_dst3 = "43.53.0.0"; + const char *expected_gw1 = "9.9.9.9"; + const char *expected_gw2 = "8.8.8.8"; + const char *expected_gw3 = "7.7.7.7"; + + connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + + ASSERT (connection != NULL, + "wired-static-routes-legacy-read", + "failed to read %s: %s", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-static-routes-legacy-verify", "failed to verify %s: %s", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, error->message); + + ASSERT (unmanaged == NULL, + "wired-static-routes-legacy-verify", + "failed to verify %s: unexpected unmanaged value", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-static-routes-legacy-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* Routes */ + ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 3, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + /* Route #1 */ + ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0); + ASSERT (ip4_route, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #1", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_metric (ip4_route) == 1, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 metric", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + /* Route #2 */ + ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1); + ASSERT (ip4_route, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #2", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_metric (ip4_route) == 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 metric", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + /* Route #3 */ + ip4_route = nm_setting_ip4_config_get_route (s_ip4, 2); + ASSERT (ip4_route, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #3", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_dst3, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #3", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_prefix (ip4_route) == 16, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 prefix", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + ASSERT (inet_pton (AF_INET, expected_gw3, &addr) > 0, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #3", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES); + + ASSERT (nm_ip4_route_get_metric (ip4_route) == 3, + "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 metric", + TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_IPV6_MANUAL TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-manual" + +static void +test_read_wired_ipv6_manual (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-ipv6-manual"; + const char *expected_address1 = "1001:abba::1234"; + const char *expected_address2 = "2001:abba::2234"; + const char *expected_address3 = "3001:abba::3234"; + guint32 expected_prefix1 = 56; + guint32 expected_prefix2 = 64; + guint32 expected_prefix3 = 96; + const char *expected_route1_dest = "9876::1234"; + guint32 expected_route1_prefix = 96; + const char *expected_route1_nexthop = "9876::7777"; + guint32 expected_route1_metric = 2; + const char *expected_dns1 = "1:2:3:4::a"; + const char *expected_dns2 = "1:2:3:4::b"; + NMIP6Address *ip6_addr; + NMIP6Route *ip6_route; + struct in6_addr addr; + + connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_MANUAL, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-ipv6-manual-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_MANUAL, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-ipv6-manual-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_MANUAL, error->message); + + ASSERT (unmanaged == FALSE, + "wired-ipv6-manual-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-ipv6-manual-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-ipv6-manual-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* DNS search domains */ + ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 3, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0); + ASSERT (tmp != NULL, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + ASSERT (strcmp (tmp, "lorem.com") == 0, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1); + ASSERT (tmp != NULL, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + ASSERT (strcmp (tmp, "ipsum.org") == 0, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 2); + ASSERT (tmp != NULL, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + ASSERT (strcmp (tmp, "dolor.edu") == 0, + "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS_SEARCH); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + + ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_MAY_FAIL); + + /* IP addresses */ + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 3, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* Address #1 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* Address #2 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); + ASSERT (ip6_addr, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #2", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix2, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2 prefix", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_address2, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #2", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* Address #3 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 2); + ASSERT (ip6_addr, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #3", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix3, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3 prefix", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_address3, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #3", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* Routes */ + ASSERT (nm_setting_ip6_config_get_num_routes (s_ip6) == 1, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + /* Route #1 */ + ip6_route = nm_setting_ip6_config_get_route (s_ip6, 0); + ASSERT (ip6_route, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 route #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_route1_dest, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP route dest #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_dest (ip6_route), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route dest #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_route_get_prefix (ip6_route) == expected_route1_prefix, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route #1 prefix", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_route1_nexthop, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP route next_hop #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_next_hop (ip6_route), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route next hop #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_route_get_metric (ip6_route) == expected_route1_metric, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route #1 metric", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* DNS Addresses */ + ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr), + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + /* DNS domains - none as domains are stuffed to 'ipv4' setting */ + ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0, + "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_IPV6_ONLY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-only" + +static void +test_read_wired_ipv6_only (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-ipv6-only"; + const char *expected_address1 = "1001:abba::1234"; + guint32 expected_prefix1 = 56; + const char *expected_dns1 = "1:2:3:4::a"; + NMIP6Address *ip6_addr; + struct in6_addr addr; + const char *method; + + connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-ipv6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-ipv6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message); + + ASSERT (unmanaged == FALSE, + "wired-ipv6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-ipv6-only-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-ipv6-only-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + method = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, + "wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-ipv6-only-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + /* IP addresses */ + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1, + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* Address #1 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + "wired-ipv6-only-verify-ip6", "failed to verify %s: missing IP6 address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1, + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0, + "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert IP address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + + /* DNS Addresses */ + ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 1, + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, + "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_IFCFG_WIRED_IPV6_MANUAL); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr), + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + /* DNS domains - none as domains are stuffed to 'ipv4' setting */ + ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0, + "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_IPV6_MANUAL, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_DHCP6_ONLY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp6-only" + +static void +test_read_wired_dhcp6_only (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-dhcp6-only"; + const char *method; + + connection = connection_from_file (TEST_IFCFG_WIRED_DHCP6_ONLY, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-dhcp6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-dhcp6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message); + + ASSERT (unmanaged == FALSE, + "wired-dhcp6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP6_ONLY); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-dhcp6-only-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-dhcp6-only-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-dhcp6-only-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + method = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, + "wired-dhcp6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "wired-dhcp6-only-verify-ip6", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0, + "wired-dhcp6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_DHCP6_ONLY, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); +} + +#define TEST_IFCFG_ONBOOT_NO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-onboot-no" + +static void +test_read_onboot_no (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_ONBOOT_NO, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "onboot-no-read", "failed to read %s: %s", TEST_IFCFG_ONBOOT_NO, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "onboot-no-verify", "failed to verify %s: %s", TEST_IFCFG_ONBOOT_NO, error->message); + + ASSERT (unmanaged == FALSE, + "onboot-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_ONBOOT_NO); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "onboot-no-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_ONBOOT_NO, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE, + "onboot-no-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_ONBOOT_NO, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2" +#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" + +static void +test_read_wired_8021x_peap_mschapv2 (void) +{ + NMConnection *connection; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSetting8021x *s_8021x; + NMSetting8021x *tmp_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_identity = "David Smith"; + const char *expected_password = "foobar baz"; + gboolean success = FALSE; + const char *expected_ca_cert_path; + const char *read_ca_cert_path; + + connection = connection_from_file (TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-8021x-peap-mschapv2-read", "failed to read %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-8021x-peap-mschapv2-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message); + + ASSERT (unmanaged == FALSE, + "wired-8021x-peap-mschapv2-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-8021x-peap-mschapv2-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== 802.1x SETTING ===== */ + s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + ASSERT (s_8021x != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME); + + /* EAP methods */ + ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + ASSERT (tmp != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + ASSERT (strcmp (tmp, "peap") == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + + /* Identity */ + tmp = nm_setting_802_1x_get_identity (s_8021x); + ASSERT (tmp != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + ASSERT (strcmp (tmp, expected_identity) == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + + /* Password */ + tmp = nm_setting_802_1x_get_password (s_8021x); + ASSERT (tmp != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD); + ASSERT (strcmp (tmp, expected_password) == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD); + + /* PEAP version */ + tmp = nm_setting_802_1x_get_phase1_peapver (s_8021x); + ASSERT (tmp != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPVER); + ASSERT (strcmp (tmp, "1") == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPVER); + + /* PEAP Label */ + tmp = nm_setting_802_1x_get_phase1_peaplabel (s_8021x); + ASSERT (tmp != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPLABEL); + ASSERT (strcmp (tmp, "1") == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPLABEL); + + /* CA Cert */ + tmp_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (tmp_8021x != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: could not create temp 802.1x setting", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME); + + success = nm_setting_802_1x_set_ca_cert (tmp_8021x, + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: could not load CA certificate", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + expected_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (tmp_8021x); + ASSERT (expected_ca_cert_path != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: failed to get CA certificate", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + + read_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (s_8021x); + ASSERT (read_ca_cert_path != NULL, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + + ASSERT (strcmp (read_ca_cert_path, expected_ca_cert_path) == 0, + "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s certificate path", + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + + g_object_unref (tmp_8021x); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_8021X_TLS_AGENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-tls-agent" +#define TEST_IFCFG_WIRED_8021X_TLS_ALWAYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-tls-always" + +static void +test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags expected_flags) +{ + NMConnection *connection; + NMSettingWired *s_wired; + NMSetting8021x *s_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *expected_identity = "David Smith"; + gboolean success = FALSE; + char *dirname, *tmp; + + connection = connection_from_file (ifcfg, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* ===== WIRED SETTING ===== */ + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + g_assert (s_wired); + + /* ===== 802.1x SETTING ===== */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x); + g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); + g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls"); + g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, expected_identity); + g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, expected_flags); + + dirname = g_path_get_dirname (ifcfg); + tmp = g_build_path ("/", dirname, "test_ca_cert.pem", NULL); + g_assert_cmpstr (nm_setting_802_1x_get_ca_cert_path (s_8021x), ==, tmp); + g_free (tmp); + + tmp = g_build_path ("/", dirname, "test1_key_and_cert.pem", NULL); + g_assert_cmpstr (nm_setting_802_1x_get_client_cert_path (s_8021x), ==, tmp); + g_assert_cmpstr (nm_setting_802_1x_get_private_key_path (s_8021x), ==, tmp); + g_free (tmp); + + g_free (dirname); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_OPEN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open" + +static void +test_read_wifi_open (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; + const char *expected_id = "System blahblah (test-wifi-open)"; + guint64 expected_timestamp = 0; + const char *expected_ssid = "blahblah"; + const char *expected_mode = "infrastructure"; + const guint32 expected_channel = 1; + + connection = connection_from_file (TEST_IFCFG_WIFI_OPEN, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-open-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-open-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-open-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-open-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-open-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "wifi-open-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "wifi-open-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-open-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (array != NULL, + "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + + ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0, + "wifi-open-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MTU); + + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + ASSERT (nm_setting_wireless_get_security (s_wireless) == NULL, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel, + "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-open-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-open-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_OPEN_AUTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-auto" + +static void +test_read_wifi_open_auto (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System blahblah (test-wifi-open-auto)"; + const char *expected_mode = "infrastructure"; + + connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_AUTO, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-open-auto-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_AUTO, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-open-auto-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_AUTO, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-open-auto-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-open-auto-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-open-auto-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_WIRELESS_SETTING_NAME); + + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-open-auto-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_AUTO, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_OPEN_SSID_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-hex" + +static void +test_read_wifi_open_ssid_hex (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + const char *expected_id = "System blahblah (test-wifi-open-ssid-hex)"; + const char *expected_ssid = "blahblah"; + + connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-open-ssid-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_HEX, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-open-ssid-hex-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_HEX, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-open-ssid-hex-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_SSID_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + g_object_unref (connection); +} + +static void +test_read_wifi_open_ssid_bad (const char *file, const char *test) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (file, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection == NULL, test, "unexpected success reading %s", file); + g_clear_error (&error); +} + +#define TEST_IFCFG_WIFI_OPEN_SSID_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-quoted" + +static void +test_read_wifi_open_ssid_quoted (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + const char *expected_id = "System foo\"bar\\ (test-wifi-open-ssid-quoted)"; + const char *expected_ssid = "foo\"bar\\"; + + connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-open-ssid-quoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-open-ssid-quoted-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep" + +static void +test_read_wifi_wep (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; + const char *expected_id = "System blahblah (test-wifi-wep)"; + guint64 expected_timestamp = 0; + const char *expected_ssid = "blahblah"; + const char *expected_mode = "infrastructure"; + const guint32 expected_channel = 1; + const char *expected_wep_key0 = "0123456789abcdef0123456789"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wep-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wep-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "wifi-wep-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "wifi-wep-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (array != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + + /* MTU */ + ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0, + "wifi-wep-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MTU); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + /* BSSID */ + ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + + /* Mode */ + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + /* Channel */ + ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP, + key_type); + + /* WEP key index 0 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT (strcmp (tmp, expected_wep_key0) == 0, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + /* WEP key index 1 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1); + ASSERT (tmp == NULL, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + + /* WEP key index 2 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2); + ASSERT (tmp == NULL, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + + /* WEP key index 3 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3); + ASSERT (tmp == NULL, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + + /* WEP Authentication mode */ + tmp = nm_setting_wireless_security_get_auth_alg (s_wsec); + ASSERT (tmp != NULL, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + ASSERT (strcmp (tmp, "shared") == 0, + "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wep-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wep-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-adhoc" + +static void +test_read_wifi_wep_adhoc (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + const char *expected_id = "System blahblah (test-wifi-wep-adhoc)"; + const char *expected_ssid = "blahblah"; + const char *expected_mode = "adhoc"; + const char *expected_wep_key0 = "0123456789abcdef0123456789"; + struct in_addr addr; + const char *expected_dns1 = "4.2.2.1"; + const char *expected_dns2 = "4.2.2.2"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_ADHOC, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_ADHOC, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-adhoc-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_ADHOC, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wep-adhoc-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE, + "wifi-wep-adhoc-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + /* BSSID */ + ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + + /* Mode */ + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + /* Channel */ + ASSERT (nm_setting_wireless_get_channel (s_wireless) == 11, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key index 0 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT (strcmp (tmp, expected_wep_key0) == 0, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + /* WEP key index 1 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1); + ASSERT (tmp == NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + + /* WEP key index 2 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2); + ASSERT (tmp == NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + + /* WEP key index 3 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3); + ASSERT (tmp == NULL, + "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + + /* WEP Authentication mode */ + tmp = nm_setting_wireless_security_get_auth_alg (s_wsec); + ASSERT (tmp == NULL, + "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* Ignore auto DNS */ + ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_WIFI_WEP_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_PASSPHRASE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-passphrase" + +static void +test_read_wifi_wep_passphrase (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_wep_key0 = "foobar222blahblah"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-passphrase-read", "failed to read %s: %s", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-passphrase-verify", "failed to verify %s: %s", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-passphrase-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_PASSPHRASE, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + key_type); + + /* WEP key index 0 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT (strcmp (tmp, expected_wep_key0) == 0, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + /* WEP key index 1 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1); + ASSERT (tmp == NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + + /* WEP key index 2 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2); + ASSERT (tmp == NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + + /* WEP key index 3 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3); + ASSERT (tmp == NULL, + "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_40_ASCII TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-40-ascii" + +static void +test_read_wifi_wep_40_ascii (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_wep_key0 = "Lorem"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_40_ASCII, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-40-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_40_ASCII, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-40-ascii-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_40_ASCII, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-40-ascii-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP_40_ASCII, + key_type); + + /* WEP key index 0 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT (strcmp (tmp, expected_wep_key0) == 0, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + /* WEP key index 1 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1); + ASSERT (tmp == NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + + /* WEP key index 2 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2); + ASSERT (tmp == NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + + /* WEP key index 3 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3); + ASSERT (tmp == NULL, + "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_40_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_104_ASCII TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-104-ascii" + +static void +test_read_wifi_wep_104_ascii (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_wep_key0 = "LoremIpsumSit"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_104_ASCII, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-104-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_104_ASCII, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-104-ascii-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_104_ASCII, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-104-ascii-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP_104_ASCII, + key_type); + + /* WEP key index 0 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT (strcmp (tmp, expected_wep_key0) == 0, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + /* WEP key index 1 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1); + ASSERT (tmp == NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + + /* WEP key index 2 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2); + ASSERT (tmp == NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + + /* WEP key index 3 */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3); + ASSERT (tmp == NULL, + "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WEP_104_ASCII, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_LEAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap" + +static void +test_read_wifi_leap (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System blahblah (test-wifi-leap)"; + const char *expected_identity = "Bill Smith"; + const char *expected_password = "foobarblah"; + + connection = connection_from_file (TEST_IFCFG_WIFI_LEAP, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-leap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_LEAP, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-leap-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_LEAP, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-leap-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-leap-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-leap-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP Authentication mode */ + tmp = nm_setting_wireless_security_get_auth_alg (s_wsec); + ASSERT (tmp != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + ASSERT (strcmp (tmp, "leap") == 0, + "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + + /* LEAP Username */ + tmp = nm_setting_wireless_security_get_leap_username (s_wsec); + ASSERT (tmp != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT (strcmp (tmp, expected_identity) == 0, + "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* LEAP Password */ + tmp = nm_setting_wireless_security_get_leap_password (s_wsec); + ASSERT (tmp != NULL, + "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + ASSERT (strcmp (tmp, expected_password) == 0, + "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_LEAP, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_LEAP_AGENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-agent" +#define TEST_IFCFG_WIFI_LEAP_ALWAYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-always-ask" + +static void +test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expected_flags) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *expected_identity = "Bill Smith"; + gboolean success; + + connection = connection_from_file (file, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* ===== WIRELESS SETTING ===== */ + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wifi); + + g_assert (g_strcmp0 (nm_setting_wireless_get_security (s_wifi), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); + + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + + g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0); + g_assert (g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap") == 0); + g_assert (g_strcmp0 (nm_setting_wireless_security_get_leap_username (s_wsec), expected_identity) == 0); + /* password blank as it's not system-owned */ + g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == expected_flags); + g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_PSK TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk" + +static void +test_read_wifi_wpa_psk (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; + const char *expected_id = "System blahblah (test-wifi-wpa-psk)"; + guint64 expected_timestamp = 0; + const char *expected_ssid = "blahblah"; + const char *expected_mode = "infrastructure"; + const guint32 expected_channel = 1; + const char *expected_key_mgmt = "wpa-psk"; + const char *expected_psk = "I wonder what the king is doing tonight?"; + guint32 n, i; + gboolean found_pair_tkip = FALSE; + gboolean found_pair_ccmp = FALSE; + gboolean found_group_tkip = FALSE; + gboolean found_group_ccmp = FALSE; + gboolean found_group_wep40 = FALSE; + gboolean found_group_wep104 = FALSE; + gboolean found_proto_wpa = FALSE; + gboolean found_proto_rsn = FALSE; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-psk-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-psk-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (array != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + + /* MTU */ + ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0, + "wifi-wpa-psk-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MTU); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + /* BSSID */ + ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + + /* Mode */ + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + /* Channel */ + ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (strcmp (tmp, expected_key_mgmt) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* PSK */ + tmp = nm_setting_wireless_security_get_psk (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (strcmp (tmp, expected_psk) == 0, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + + /* WEP Authentication mode */ + tmp = nm_setting_wireless_security_get_auth_alg (s_wsec); + ASSERT (tmp == NULL, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + + /* Pairwise ciphers */ + n = nm_setting_wireless_security_get_num_pairwise (s_wsec); + ASSERT (n == 2, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + for (i = 0; i < n; i++) { + tmp = nm_setting_wireless_security_get_pairwise (s_wsec, i); + ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise cipher", + TEST_IFCFG_WIFI_WPA_PSK); + if (strcmp (tmp, "tkip") == 0) + found_pair_tkip = TRUE; + else if (strcmp (tmp, "ccmp") == 0) + found_pair_ccmp = TRUE; + } + ASSERT (found_pair_tkip, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise TKIP cipher", + TEST_IFCFG_WIFI_WPA_PSK); + ASSERT (found_pair_ccmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise CCMP cipher", + TEST_IFCFG_WIFI_WPA_PSK); + + /* Group ciphers */ + n = nm_setting_wireless_security_get_num_groups (s_wsec); + ASSERT (n == 4, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + for (i = 0; i < n; i++) { + tmp = nm_setting_wireless_security_get_group (s_wsec, i); + ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group cipher", + TEST_IFCFG_WIFI_WPA_PSK); + if (strcmp (tmp, "tkip") == 0) + found_group_tkip = TRUE; + else if (strcmp (tmp, "ccmp") == 0) + found_group_ccmp = TRUE; + else if (strcmp (tmp, "wep40") == 0) + found_group_wep40 = TRUE; + else if (strcmp (tmp, "wep104") == 0) + found_group_wep104 = TRUE; + } + ASSERT (found_group_tkip, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group TKIP cipher", + TEST_IFCFG_WIFI_WPA_PSK); + ASSERT (found_group_ccmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group CCMP cipher", + TEST_IFCFG_WIFI_WPA_PSK); + ASSERT (found_group_wep40, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group WEP-40 cipher", + TEST_IFCFG_WIFI_WPA_PSK); + ASSERT (found_group_wep104, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group WEP-104 cipher", + TEST_IFCFG_WIFI_WPA_PSK); + + /* Protocols */ + n = nm_setting_wireless_security_get_num_protos (s_wsec); + ASSERT (n == 2, + "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + for (i = 0; i < n; i++) { + tmp = nm_setting_wireless_security_get_proto (s_wsec, i); + ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protocol", + TEST_IFCFG_WIFI_WPA_PSK); + if (strcmp (tmp, "wpa") == 0) + found_proto_wpa = TRUE; + else if (strcmp (tmp, "rsn") == 0) + found_proto_rsn = TRUE; + } + ASSERT (found_proto_wpa, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protoocl WPA", + TEST_IFCFG_WIFI_WPA_PSK); + ASSERT (found_proto_rsn, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protocol RSN", + TEST_IFCFG_WIFI_WPA_PSK); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wpa-psk-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wpa-psk-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted" + +static void +test_read_wifi_wpa_psk_unquoted (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System blahblah (test-wifi-wpa-psk-unquoted)"; + const char *expected_psk = "54336845e2f3f321c4c7"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-psk-unquoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-psk-unquoted-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* PSK */ + tmp = nm_setting_wireless_security_get_psk (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (strcmp (tmp, expected_psk) == 0, + "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2" + +static void +test_read_wifi_wpa_psk_unquoted2 (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + /* Ensure a quoted 64-character WPA passphrase will fail since passphrases + * must be between 8 and 63 ASCII characters inclusive per the WPA spec. + */ + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection == NULL, + "wifi-wpa-psk-unquoted-read", "unexpected success reading %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2); + g_clear_error (&error); +} + +#define TEST_IFCFG_WIFI_WPA_PSK_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc" + +static void +test_read_wifi_wpa_psk_adhoc (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System blahblah (test-wifi-wpa-psk-adhoc)"; + const char *expected_mode = "adhoc"; + const char *expected_key_mgmt = "wpa-none"; + const char *expected_psk = "I wonder what the king is doing tonight?"; + const char *expected_group = "ccmp"; + const char *expected_proto = "wpa"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-psk-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-psk-adhoc-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Mode */ + tmp = nm_setting_wireless_get_mode (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + ASSERT (strcmp (tmp, expected_mode) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (strcmp (tmp, expected_key_mgmt) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* PSK */ + tmp = nm_setting_wireless_security_get_psk (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (strcmp (tmp, expected_psk) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + + /* Pairwise cipher: unused in adhoc mode */ + ASSERT (nm_setting_wireless_security_get_num_pairwise (s_wsec) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + + /* Group cipher */ + ASSERT (nm_setting_wireless_security_get_num_groups (s_wsec) == 1, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + + tmp = nm_setting_wireless_security_get_group (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing group cipher", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC); + ASSERT (strcmp (tmp, expected_group) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + + /* Protocols */ + ASSERT (nm_setting_wireless_security_get_num_protos (s_wsec) == 1, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + tmp = nm_setting_wireless_security_get_proto (s_wsec, 0); + ASSERT (tmp != NULL, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing proto", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC); + ASSERT (strcmp (tmp, expected_proto) == 0, + "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_ADHOC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_PSK_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-hex" + +static void +test_read_wifi_wpa_psk_hex (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + const char *expected_id = "System blahblah (test-wifi-wpa-psk-hex)"; + const char *expected_ssid = "blahblah"; + const char *expected_key_mgmt = "wpa-psk"; + const char *expected_psk = "1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_HEX, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-psk-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_HEX, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-psk-hex-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_HEX, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (array->len == strlen (expected_ssid), + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (strcmp (tmp, expected_key_mgmt) == 0, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* PSK */ + tmp = nm_setting_wireless_security_get_psk (s_wsec); + ASSERT (tmp != NULL, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (strcmp (tmp, expected_psk) == 0, + "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK_HEX, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_EAP_TLS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-eap-tls" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" + +static void +test_read_wifi_wpa_eap_tls (void) +{ + NMConnection *connection; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + NMSetting8021x *s_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp, *password; + const char *expected_identity = "Bill Smith"; + const char *expected_privkey_password = "test1"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TLS, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-eap-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-eap-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message); + + ASSERT (unmanaged == FALSE, + "wifi-wpa-eap-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TLS); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-eap-tls-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== 802.1x SETTING ===== */ + s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + ASSERT (s_8021x != NULL, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME); + + /* EAP methods */ + ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + ASSERT (tmp != NULL, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + ASSERT (strcmp (tmp, "tls") == 0, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + + /* Identity */ + tmp = nm_setting_802_1x_get_identity (s_8021x); + ASSERT (tmp != NULL, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + ASSERT (strcmp (tmp, expected_identity) == 0, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + + /* CA Cert */ + verify_cert_or_key (CK_CA_CERT, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NULL, + TEST_IFCFG_WIFI_WPA_EAP_TLS, + "wifi-wpa-eap-tls-verify-8021x", + NM_SETTING_802_1X_CA_CERT); + + /* Client Cert */ + verify_cert_or_key (CK_CLIENT_CERT, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NULL, + TEST_IFCFG_WIFI_WPA_EAP_TLS, + "wifi-wpa-eap-tls-verify-8021x", + NM_SETTING_802_1X_CLIENT_CERT); + + /* Private Key Password */ + password = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (password != NULL, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + ASSERT (strcmp (password, expected_privkey_password) == 0, + "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + /* Private key */ + verify_cert_or_key (CK_PRIV_KEY, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + expected_privkey_password, + TEST_IFCFG_WIFI_WPA_EAP_TLS, + "wifi-wpa-eap-tls-verify-8021x", + NM_SETTING_802_1X_PRIVATE_KEY); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls" +#define TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" +/* Also use TLS defines from the previous test */ + +static void +test_read_wifi_wpa_eap_ttls_tls (void) +{ + NMConnection *connection; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + NMSetting8021x *s_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp, *password; + const char *expected_identity = "Chuck Shumer"; + const char *expected_privkey_password = "test1"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wpa-eap-ttls-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message); + + ASSERT (unmanaged == FALSE, + "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wpa-eap-ttls-tls-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== 802.1x SETTING ===== */ + s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + ASSERT (s_8021x != NULL, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME); + + /* EAP methods */ + ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + ASSERT (tmp != NULL, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + ASSERT (strcmp (tmp, "ttls") == 0, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + + /* CA Cert */ + verify_cert_or_key (CK_CA_CERT, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS_CA_CERT, + NULL, + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + "wifi-wpa-eap-ttls-tls-verify-8021x", + NM_SETTING_802_1X_CA_CERT); + + /* Inner auth method */ + tmp = nm_setting_802_1x_get_phase2_autheap (s_8021x); + ASSERT (tmp != NULL, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + ASSERT (strcmp (tmp, "tls") == 0, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + + /* Inner CA Cert */ + verify_cert_or_key (CK_CA_CERT, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NULL, + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + "wifi-wpa-eap-ttls-tls-verify-8021x", + NM_SETTING_802_1X_PHASE2_CA_CERT); + + /* Inner Client Cert */ + verify_cert_or_key (CK_CLIENT_CERT, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NULL, + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + "wifi-wpa-eap-ttls-tls-verify-8021x", + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + + /* Inner Private Key Password */ + password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (password != NULL, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + ASSERT (strcmp (password, expected_privkey_password) == 0, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + /* Inner private key */ + verify_cert_or_key (CK_PRIV_KEY, + s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + expected_privkey_password, + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + "wifi-wpa-eap-ttls-tls-verify-8021x", + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + + /* Identity */ + tmp = nm_setting_802_1x_get_identity (s_8021x); + ASSERT (tmp != NULL, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + ASSERT (strcmp (tmp, expected_identity) == 0, + "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-dynamic-wep-leap" + +static void +test_read_wifi_dynamic_wep_leap (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE, success; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* ===== WIRELESS SETTING ===== */ + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wifi); + + g_assert_cmpstr (nm_setting_wireless_get_security (s_wifi), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* ===== WiFi SECURITY SETTING ===== */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + + /* Key management */ + g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "ieee8021x"); + + /* Auth alg should be NULL (open) for dynamic WEP with LEAP as the EAP method; + * only "old-school" LEAP uses 'leap' for the auth alg. + */ + g_assert_cmpstr (nm_setting_wireless_security_get_auth_alg (s_wsec), ==, NULL); + + /* Expect no old-school LEAP username/password, that'll be in the 802.1x setting */ + g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, NULL); + g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, NULL); + + /* ===== 802.1x SETTING ===== */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x); + + /* EAP method should be "leap" */ + g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); + g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "leap"); + + /* username & password */ + g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "bill smith"); + g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz"); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap" +#define TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" + +static void +test_read_wifi_wep_eap_ttls_chap (void) +{ + NMConnection *connection; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSetting8021x *s_8021x; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_password = "foobar baz"; + const char *expected_identity = "David Smith"; + const char *expected_key_mgmt = "ieee8021x"; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-eap-ttls-chap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message); + + ASSERT (unmanaged == FALSE, + "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-eap-ttls-chap-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* ===== 802.1x SETTING ===== */ + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME); + + /* Key management */ + tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec); + ASSERT (tmp != NULL, + "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (strcmp (tmp, expected_key_mgmt) == 0, + "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WPA_PSK, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* ===== 802.1x SETTING ===== */ + s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); + ASSERT (s_8021x != NULL, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME); + + /* EAP methods */ + ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + ASSERT (tmp != NULL, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + ASSERT (strcmp (tmp, "ttls") == 0, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_EAP); + + /* CA Cert */ + verify_cert_or_key (CK_CA_CERT, + s_8021x, + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP_CA_CERT, + NULL, + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + "wifi-wep-eap-ttls-chap-verify-8021x", + NM_SETTING_802_1X_CA_CERT); + + /* Inner auth method */ + tmp = nm_setting_802_1x_get_phase2_auth (s_8021x); + ASSERT (tmp != NULL, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s eap method", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTH); + ASSERT (strcmp (tmp, "chap") == 0, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTH); + + /* Password */ + tmp = nm_setting_802_1x_get_identity (s_8021x); + ASSERT (tmp != NULL, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + ASSERT (strcmp (tmp, expected_identity) == 0, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + + /* Password */ + tmp = nm_setting_802_1x_get_password (s_8021x); + ASSERT (tmp != NULL, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD); + ASSERT (strcmp (tmp, expected_password) == 0, + "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PASSWORD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIRED_QETH_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-qeth-static" + +static void +test_read_wired_qeth_static (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-qeth-static"; + const GByteArray *array; + const char *expected_channel0 = "0.0.0600"; + const char *expected_channel1 = "0.0.0601"; + const char *expected_channel2 = "0.0.0602"; + const GPtrArray *subchannels; + + connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-qeth-static-read", "failed to read %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-qeth-static-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message); + + ASSERT (unmanaged == FALSE, + "wired-qeth-static-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_QETH_STATIC); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-qeth-static-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-qeth-static-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array == NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + /* Subchannels */ + subchannels = nm_setting_wired_get_s390_subchannels (s_wired); + ASSERT (subchannels != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_SUBCHANNELS); + ASSERT (subchannels->len == 3, + "wired-qeth-static-verify-wired", "failed to verify %s: invalid %s / %s key (not 3 elements)", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_SUBCHANNELS); + + tmp = (const char *) g_ptr_array_index (subchannels, 0); + ASSERT (strcmp (tmp, expected_channel0) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #0", + TEST_IFCFG_WIRED_QETH_STATIC); + + tmp = (const char *) g_ptr_array_index (subchannels, 1); + ASSERT (strcmp (tmp, expected_channel1) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #1", + TEST_IFCFG_WIRED_QETH_STATIC); + + tmp = (const char *) g_ptr_array_index (subchannels, 2); + ASSERT (strcmp (tmp, expected_channel2) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #2", + TEST_IFCFG_WIRED_QETH_STATIC); + + /* Nettype */ + tmp = nm_setting_wired_get_s390_nettype (s_wired); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_NETTYPE); + ASSERT (strcmp (tmp, "qeth") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_NETTYPE); + + /* port name */ + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portname'", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "OSAPORT") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portname' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* port number */ + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portno"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portno'", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "0") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portno' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* layer */ + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "layer2"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'layer2'", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "1") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'layer2' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-qeth-static-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-qeth-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_NO_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-no-keys" + +static void +test_read_wifi_wep_no_keys (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System foobar (test-wifi-wep-no-keys)"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_NO_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-no-keys-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-no-keys-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + key_type); + + /* WEP key index 0; we don't expect it to be filled */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp == NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_object_unref (connection); +} + +#define TEST_IFCFG_PERMISSIONS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-permissions" + +static void +test_read_permissions (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE, success; + GError *error = NULL; + guint32 num; + const char *tmp; + + connection = connection_from_file (TEST_IFCFG_PERMISSIONS, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "permissions-read", "failed to read %s: %s", TEST_IFCFG_PERMISSIONS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "permissions-verify", "failed to verify %s: %s", TEST_IFCFG_PERMISSIONS, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "permissions-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_PERMISSIONS, + NM_SETTING_CONNECTION_SETTING_NAME); + + num = nm_setting_connection_get_num_permissions (s_con); + ASSERT (num == 3, + "permissions-verify-permissions", "unexpected number of permissions (%d, expected 3)", + num); + + /* verify each permission */ + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 0, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #1"); + ASSERT (strcmp (tmp, "dcbw") == 0, + "permissions-verify-permissions", "unexpected permission #1"); + + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 1, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #2"); + ASSERT (strcmp (tmp, "ssmith") == 0, + "permissions-verify-permissions", "unexpected permission #2"); + + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 2, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #3"); + ASSERT (strcmp (tmp, "johnny5") == 0, + "permissions-verify-permissions", "unexpected permission #3"); + + g_object_unref (connection); +} + +#define TEST_IFCFG_WIFI_WEP_AGENT_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-agent-keys" + +static void +test_read_wifi_wep_agent_keys (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + NMWepKeyType key_type; + gboolean success; + NMSettingSecretFlags flags; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_AGENT_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert (connection != NULL); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Ensure the connection is still marked for wifi security even though + * we don't have any WEP keys because they are agent owned. + */ + + /* ===== WIRELESS SETTING ===== */ + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wifi); + tmp = nm_setting_wireless_get_security (s_wifi); + g_assert (g_strcmp0 (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); + + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + + g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0); + g_assert (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0); + + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + + /* We don't expect WEP key0 to be filled */ + g_assert (nm_setting_wireless_security_get_wep_key (s_wsec, 0) == NULL); + + flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec); + g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED); + + g_object_unref (connection); +} + +static void +test_write_wired_static (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4, *reread_s_ip4; + NMSettingIP6Config *s_ip6, *reread_s_ip6; + static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; + GByteArray *mac; + guint32 mtu = 1492; + char *uuid; + const guint32 ip1 = htonl (0x01010103); + const guint32 ip2 = htonl (0x01010105); + const guint32 gw = htonl (0x01010101); + const guint32 dns1 = htonl (0x04020201); + const guint32 dns2 = htonl (0x04020202); + const guint32 prefix = 24; + const char *dns_search1 = "foobar.com"; + const char *dns_search2 = "lab.foobar.com"; + const char *dns_search3 = "foobar6.com"; + const char *dns_search4 = "lab6.foobar.com"; + struct in6_addr ip6, ip6_1, ip6_2; + struct in6_addr route1_dest, route2_dest, route1_nexthop, route2_nexthop; + struct in6_addr dns6_1, dns6_2; + const guint32 route1_prefix = 64, route2_prefix = 0; + const guint32 route1_metric = 99, route2_metric = 1; + NMIP4Address *addr; + NMIP6Address *addr6; + NMIP6Route *route6; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6); + inet_pton (AF_INET6, "2003:1234:abcd::2", &ip6_1); + inet_pton (AF_INET6, "3003:1234:abcd::3", &ip6_2); + inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc::", &route1_dest); + inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", &route1_nexthop); + inet_pton (AF_INET6, "::", &route2_dest); + inet_pton (AF_INET6, "2222:aaaa::9999", &route2_nexthop); + inet_pton (AF_INET6, "fade:0102:0103::face", &dns6_1); + inet_pton (AF_INET6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed", &dns6_2); + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-static-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-static-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired Static", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-static-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, mac, + NM_SETTING_WIRED_MTU, mtu, + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-static-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NULL); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip2); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + nm_setting_ip4_config_add_dns (s_ip4, dns1); + nm_setting_ip4_config_add_dns (s_ip4, dns2); + + nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1); + nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-static-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + + /* Add addresses */ + addr6 = nm_ip6_address_new (); + nm_ip6_address_set_address (addr6, &ip6); + nm_ip6_address_set_prefix (addr6, 11); + nm_setting_ip6_config_add_address (s_ip6, addr6); + nm_ip6_address_unref (addr6); + + addr6 = nm_ip6_address_new (); + nm_ip6_address_set_address (addr6, &ip6_1); + nm_ip6_address_set_prefix (addr6, 22); + nm_setting_ip6_config_add_address (s_ip6, addr6); + nm_ip6_address_unref (addr6); + + addr6 = nm_ip6_address_new (); + nm_ip6_address_set_address (addr6, &ip6_2); + nm_ip6_address_set_prefix (addr6, 33); + nm_setting_ip6_config_add_address (s_ip6, addr6); + nm_ip6_address_unref (addr6); + + /* Add routes */ + route6 = nm_ip6_route_new (); + nm_ip6_route_set_dest (route6, &route1_dest); + nm_ip6_route_set_prefix (route6, route1_prefix); + nm_ip6_route_set_next_hop (route6, &route1_nexthop); + nm_ip6_route_set_metric (route6, route1_metric); + nm_setting_ip6_config_add_route (s_ip6, route6); + nm_ip6_route_unref (route6); + + route6 = nm_ip6_route_new (); + nm_ip6_route_set_dest (route6, &route2_dest); + nm_ip6_route_set_prefix (route6, route2_prefix); + nm_ip6_route_set_next_hop (route6, &route2_nexthop); + nm_ip6_route_set_metric (route6, route2_metric); + nm_setting_ip6_config_add_route (s_ip6, route6); + nm_ip6_route_unref (route6); + + /* DNS servers */ + nm_setting_ip6_config_add_dns (s_ip6, &dns6_1); + nm_setting_ip6_config_add_dns (s_ip6, &dns6_2); + + /* DNS domains */ + nm_setting_ip6_config_add_dns_search (s_ip6, dns_search3); + nm_setting_ip6_config_add_dns_search (s_ip6, dns_search4); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-static-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-static-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-static-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-static-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wired-static-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + /* FIXME: currently DNS domains from IPv6 setting are stored in 'DOMAIN' key in ifcfg-file + * However after re-reading they are dropped into IPv4 setting. + * So, in order to comparison succeeded, move DNS domains back to IPv6 setting. + */ + reread_s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG)); + reread_s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP6_CONFIG)); + nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 2)); + nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 3)); + nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 3); + nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 2); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-static-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wired_dhcp (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-dhcp-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33", + NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, "awesome-hostname", + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, TRUE, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, TRUE, + NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-dhcp-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-dhcp-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-dhcp-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-dhcp-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wired-dhcp-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-dhcp-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wired_static_ip6_only (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; + GByteArray *mac; + char *uuid; + struct in6_addr ip6; + struct in6_addr dns6; + NMIP6Address *addr6; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6); + inet_pton (AF_INET6, "fade:0102:0103::face", &dns6); + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-static-ip6-only-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-static-ip6-only-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired Static IP6 Only", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-static-ip6-only-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-static-ip6-only-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-static-ip6-only-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL); + + /* Add addresses */ + addr6 = nm_ip6_address_new (); + nm_ip6_address_set_address (addr6, &ip6); + nm_ip6_address_set_prefix (addr6, 11); + nm_setting_ip6_config_add_address (s_ip6, addr6); + nm_ip6_address_unref (addr6); + + /* DNS server */ + nm_setting_ip6_config_add_dns (s_ip6, &dns6); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-static-ip6-only-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-static-ip6-only-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-static-ip6-only-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-static-ip6-only-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wired-static-ip6-only-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-static-ip6-only-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + + +#define TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-static-routes-legacy" + +static void +test_read_write_static_routes_legacy (void) +{ + NMConnection *connection, *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *testfile = NULL; + char *keyfile = NULL; + char *keyfile2 = NULL; + char *routefile = NULL; + char *routefile2 = NULL; + char *route6file = NULL; + char *route6file2 = NULL; + gboolean ignore_error = FALSE; + gboolean success; + GError *error = NULL; + const char *tmp; + + connection = connection_from_file (TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "read-write-static-routes-legacy-read", "failed to read %s: %s", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "read-write-static-routes-legacy-verify", "failed to verify %s: %s", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "read_write-static-routes-legacy-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "read-write-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, + "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + + /* Save the ifcfg; use a special different scratch dir to ensure that + * we can clean up after the written connection in both the original + * source tree and for 'make distcheck'. + */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/tmp", + &testfile, + &error); + ASSERT (success == TRUE, + "read-write-static-routes-legacy-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "read-write-static-routes-legacy-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile2, + &routefile2, + &route6file2, + &error, + &ignore_error); + unlink (testfile); + unlink (routefile2); + unlink (route6file2); + + ASSERT (reread != NULL, + "read-write-static-routes-legacy-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (routefile2 != NULL, + "read-write-static-routes-legacy-reread", "expected routefile for '%s'", testfile); + + ASSERT (nm_connection_verify (reread, &error), + "read-write-static-routes-legacy-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "read-write-static-routes-legacy-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_free (keyfile); + g_free (keyfile2); + g_free (routefile); + g_free (routefile2); + g_free (route6file); + g_free (route6file2); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wired_static_routes (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; + GByteArray *mac; + guint32 mtu = 1492; + char *uuid; + const guint32 ip1 = htonl (0x01010103); + const guint32 ip2 = htonl (0x01010105); + const guint32 gw = htonl (0x01010101); + const guint32 dns1 = htonl (0x04020201); + const guint32 dns2 = htonl (0x04020202); + const guint32 route_dst1 = htonl (0x01020300); + const guint32 route_dst2= htonl (0x03020100); + const guint32 route_gw1 = htonl (0xdeadbeef); + const guint32 route_gw2 = htonl (0xcafeabbe); + const guint32 prefix = 24; + const char *dns_search1 = "foobar.com"; + const char *dns_search2 = "lab.foobar.com"; + NMIP4Address *addr; + NMIP4Route *route; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-static-routes-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-static-routes-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired Static Routes", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-static-routes-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + mac = g_byte_array_sized_new (sizeof (tmpmac)); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, mac, + NM_SETTING_WIRED_MTU, mtu, + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-static-routes-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip2); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + /* Write out routes */ + route = nm_ip4_route_new (); + nm_ip4_route_set_dest (route, route_dst1); + nm_ip4_route_set_prefix (route, prefix); + nm_ip4_route_set_next_hop (route, route_gw1); + nm_setting_ip4_config_add_route (s_ip4, route); + nm_ip4_route_unref (route); + + route = nm_ip4_route_new (); + nm_ip4_route_set_dest (route, route_dst2); + nm_ip4_route_set_prefix (route, prefix); + nm_ip4_route_set_next_hop (route, route_gw2); + nm_ip4_route_set_metric (route, 77); + nm_setting_ip4_config_add_route (s_ip4, route); + nm_ip4_route_unref (route); + + nm_setting_ip4_config_add_dns (s_ip4, dns1); + nm_setting_ip4_config_add_dns (s_ip4, dns2); + + nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1); + nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-static-routes-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-static-routes-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-static-routes-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-static-routes-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (routefile != NULL, + "wired-static-routes-write-reread", "expected routefile for '%s'", testfile); + unlink (routefile); + + ASSERT (nm_connection_verify (reread, &error), + "wired-static-routes-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-static-routes-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wired_dhcp_8021x_peap_mschapv2 (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSetting8021x *s_8021x; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP 802.1x PEAP MSCHAPv2", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting", + NM_SETTING_802_1X_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, + NM_SETTING_802_1X_IDENTITY, "Bob Saget", + NM_SETTING_802_1X_PASSWORD, "Kids, it was back in October 2008...", + NM_SETTING_802_1X_PHASE1_PEAPVER, "1", + NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wired-dhcp-8021x-peap-mschapv2write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-dhcp-8021x-peap-mschapv2write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-dhcp-8021x-peap-mschapv2write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-dhcp-8021x-peap-mschapv2write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-dhcp-8021x-peap-mschapv2write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (keyfile != NULL, + "wired-dhcp-8021x-peap-mschapv2write-reread", "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (nm_connection_verify (reread, &error), + "wired-dhcp-8021x-peap-mschapv2write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-dhcp-8021x-peap-mschapv2write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +#if 0 +static GByteArray * +file_to_byte_array (const char *filename) +{ + char *contents; + GByteArray *array = NULL; + gsize length = 0; + + if (g_file_get_contents (filename, &contents, &length, NULL)) { + array = g_byte_array_sized_new (length); + if (array) { + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + } + g_free (contents); + } + return array; +} +#endif + +#define TEST_IFCFG_WIRED_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem" +#define TEST_IFCFG_WIRED_TLS_CLIENT_CERT TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" +#define TEST_IFCFG_WIRED_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem" + +static void +test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, + NMSettingSecretFlags flags) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSetting8021x *s_8021x; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char *pw; + char *tmp; + + connection = nm_connection_new (); + g_assert (connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired 802.1x TLS Blobs", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + g_assert (s_wired); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + g_assert (s_8021x); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + + /* CA cert */ + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIRED_TLS_CA_CERT, + scheme, + &format, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Client cert */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_IFCFG_WIRED_TLS_CLIENT_CERT, + scheme, + &format, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Private key */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_IFCFG_WIRED_TLS_PRIVATE_KEY, + "test1", + scheme, + &format, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY); + + /* Set secret flags */ + g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, flags, NULL); + + /* Verify finished connection */ + success = nm_connection_verify (connection, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify connection: %s", error->message); + } + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to write connection: %s", error->message); + } + g_assert (success); + g_assert (testfile != NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + g_assert (keyfile != NULL); + unlink (keyfile); + + g_assert (reread != NULL); + + success = nm_connection_verify (reread, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify %s: %s", testfile, error->message); + } + g_assert (success); + + /* Ensure the reread connection's certificates and private key are paths; no + * matter what scheme was used in the original connection they will be read + * back in as paths. + */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x); + g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpint (nm_setting_802_1x_get_private_key_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); + + g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, flags); + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Ensure the private key password is still set */ + g_assert (pw != NULL); + g_assert_cmpstr (pw, ==, "test1"); + } else { + /* If the secret isn't owned by system settings, make sure its no longer there */ + g_assert (pw == NULL); + } + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* Do a direct compare if using the path scheme since then the + * certificate and key properties should be the same. If using blob + * scheme the original connection cert/key properties will be blobs + * but the re-read connection is always path scheme, so we wouldn't + * expect it to compare successfully. + */ + if (flags != NM_SETTING_SECRET_FLAG_NONE) { + /* Clear original connection's private key password because flags + * say it's not system-owned, and therefore it should not show up + * in the re-read connection. + */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); + } + + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + } + + /* Clean up created certs and keys */ + tmp = utils_cert_path (testfile, "ca-cert.der"); + unlink (tmp); + g_free (tmp); + + tmp = utils_cert_path (testfile, "client-cert.der"); + unlink (tmp); + g_free (tmp); + + tmp = utils_cert_path (testfile, "private-key.pem"); + unlink (tmp); + g_free (tmp); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_open (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + GByteArray *bssid; + const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + guint32 channel = 9, mtu = 1345; + GByteArray *mac; + const unsigned char mac_data[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + shvarFile *ifcfg; + char *tmp; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-open-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-open-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi Open", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-open-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + bssid = g_byte_array_sized_new (sizeof (bssid_data)); + g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + mac = g_byte_array_sized_new (sizeof (mac_data)); + g_byte_array_append (mac, mac_data, sizeof (mac_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_MAC_ADDRESS, mac, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_BAND, "bg", + NM_SETTING_WIRELESS_CHANNEL, channel, + NM_SETTING_WIRELESS_MTU, mtu, + NULL); + + g_byte_array_free (ssid, TRUE); + g_byte_array_free (bssid, TRUE); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-open-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-open-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-open-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-open-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-open-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + + /* Now make sure that the ESSID item isn't double-quoted (rh #606518) */ + ifcfg = svNewFile (testfile); + ASSERT (ifcfg != NULL, + "wifi-open-write-reread", "failed to load %s as shvarfile", testfile); + + tmp = svGetValue (ifcfg, "ESSID", TRUE); + ASSERT (tmp != NULL, + "wifi-open-write-reread", "failed to read ESSID key from %s", testfile); + + ASSERT (strncmp (tmp, "\"\"", 2) != 0, + "wifi-open-write-reread", "unexpected ESSID double-quote in %s", testfile); + + svCloseFile (ifcfg); + + unlink (testfile); + + ASSERT (reread != NULL, + "wifi-open-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-open-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-open-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_open_hex_ssid (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd }; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-open-hex-ssid-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-open-hex-ssid-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi Open Hex SSID", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-open-hex-ssid-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + + g_byte_array_free (ssid, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-open-hex-ssid-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-open-hex-ssid-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-open-hex-ssid-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-open-hex-ssid-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-open-hex-ssid-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wifi-open-hex-ssid-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-open-hex-ssid-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-open-hex-ssid-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + struct stat statbuf; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wep-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wep-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wep-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wep-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789"); + nm_setting_wireless_security_set_wep_key (s_wsec, 1, "11111111111111111111111111"); + nm_setting_wireless_security_set_wep_key (s_wsec, 2, "aaaaaaaaaaaaaaaaaaaaaaaaaa"); + nm_setting_wireless_security_set_wep_key (s_wsec, 3, "BBBBBBBBBBBBBBBBBBBBBBBBBB"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wep-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wep-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wep-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wep-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wep-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wep-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-wep-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-wep-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-wep-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wep-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wep-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wep-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep_adhoc (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + struct stat statbuf; + NMIP4Address *addr; + const guint32 ip1 = htonl (0x01010103); + const guint32 gw = htonl (0x01010101); + const guint32 dns1 = htonl (0x04020201); + const guint32 prefix = 24; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wep-adhoc-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP AdHoc", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "adhoc", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + + /* IP Address */ + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + nm_setting_ip4_config_add_dns (s_ip4, dns1); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wep-adhoc-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wep-adhoc-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wep-adhoc-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wep-adhoc-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-wep-adhoc-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wep-adhoc-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wep-adhoc-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wep-adhoc-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep_passphrase (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + struct stat statbuf; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wep-passphrase-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wep-passphrase-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Passphrase", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wep-passphrase-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wep-passphrase-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_PASSPHRASE, + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wep-passphrase-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wep-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wep-passphrase-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wep-passphrase-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wep-passphrase-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wep-passphrase-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-wep-passphrase-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wep-passphrase-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wep-passphrase-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wep-passphrase-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep_40_ascii (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah40"; + struct stat statbuf; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 40 ASCII", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "lorem"); + nm_setting_wireless_security_set_wep_key (s_wsec, 1, "ipsum"); + nm_setting_wireless_security_set_wep_key (s_wsec, 2, "dolor"); + nm_setting_wireless_security_set_wep_key (s_wsec, 3, "donec"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wep-40-ascii-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wep-40-ascii-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wep-40-ascii-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wep-40-ascii-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wep-40-ascii-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-wep-40-ascii-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wep-40-ascii-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wep-40-ascii-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wep-40-ascii-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep_104_ascii (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah104"; + struct stat statbuf; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 104 ASCII", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "LoremIpsumSit"); + nm_setting_wireless_security_set_wep_key (s_wsec, 1, "AlfaBetaGamma"); + nm_setting_wireless_security_set_wep_key (s_wsec, 2, "WEP-104 ASCII"); + nm_setting_wireless_security_set_wep_key (s_wsec, 3, "thisismyascii"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wep-104-ascii-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wep-104-ascii-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wep-104-ascii-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wep-104-ascii-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wep-104-ascii-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-wep-104-ascii-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wep-104-ascii-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wep-104-ascii-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wep-104-ascii-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_leap (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + struct stat statbuf; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-leap-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-leap-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-leap-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-leap-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22", + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-leap-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-leap-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-leap-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-leap-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-leap-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-leap-write-reread", "expected keyfile for '%s'", testfile); + + ASSERT (stat (keyfile, &statbuf) == 0, + "wifi-leap-write-reread", "couldn't stat() '%s'", keyfile); + ASSERT (S_ISREG (statbuf.st_mode), + "wifi-leap-write-reread", "keyfile '%s' wasn't a normal file", keyfile); + ASSERT ((statbuf.st_mode & 0077) == 0, + "wifi-leap-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile); + + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-leap-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-leap-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-leap-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP Secret Flags", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + g_assert_no_error (error); + + /* No key should be written out since the secret is not system owned */ + g_assert (keyfile); + g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE); + + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + /* Remove the LEAP password from the original connection since it wont' be + * in the reread connection, as the password is not system owned. + */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, NULL, NULL); + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wpa_psk (const char *name, + const char *test_name, + gboolean wep_group, + gboolean wpa, + gboolean wpa2, + const char *psk) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid, *tmp; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + + g_return_if_fail (psk != NULL); + + connection = nm_connection_new (); + ASSERT (connection != NULL, + test_name, "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + test_name, "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, name, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + test_name, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + test_name, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, psk, + NULL); + + if (wep_group) { + nm_setting_wireless_security_add_group (s_wsec, "wep40"); + nm_setting_wireless_security_add_group (s_wsec, "wep104"); + } + if (wpa) { + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + } + if (wpa2) { + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + } + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + test_name, "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + test_name, "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + test_name, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + test_name, "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + test_name, "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + tmp = g_strdup_printf ("%s-reread", test_name); + ASSERT (keyfile != NULL, + tmp, "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (reread != NULL, + tmp, "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + tmp, "failed to verify %s: %s", testfile, error->message); + g_free (tmp); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + test_name, "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wpa_psk_adhoc (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const unsigned char ssid_data[] = "blahblah"; + NMIP4Address *addr; + const guint32 ip1 = htonl (0x01010103); + const guint32 gw = htonl (0x01010101); + const guint32 dns1 = htonl (0x04020201); + const guint32 prefix = 24; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA PSK", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "adhoc", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL, 11, + NM_SETTING_WIRELESS_BAND, "bg", + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", + NM_SETTING_WIRELESS_SECURITY_PSK, "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0", + NULL); + + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + + /* IP Address */ + addr = nm_ip4_address_new (); + nm_ip4_address_set_address (addr, ip1); + nm_ip4_address_set_prefix (addr, prefix); + nm_ip4_address_set_gateway (addr, gw); + nm_setting_ip4_config_add_address (s_ip4, addr); + nm_ip4_address_unref (addr); + + nm_setting_ip4_config_add_dns (s_ip4, dns1); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wpa-psk-adhoc-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wpa-psk-adhoc-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wpa-psk-adhoc-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wpa-psk-adhoc-write-reread", "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wpa-psk-adhoc-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wpa-psk-adhoc-write-reread", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wpa-psk-adhoc-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wpa_eap_tls (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const char *ssid_data = "blahblah"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TLS", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (ssid_data)); + g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_802_1X_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-tls-write", "failed to set CA certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message); + + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-tls-write", "failed to set client certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, error->message); + + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + "test1", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-tls-write", "failed to set private key '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wpa-eap-tls-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wpa-eap-tls-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-tls-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wpa-eap-tls-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (keyfile != NULL, + "wifi-wpa-eap-tls-write-reread", "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (reread != NULL, + "wifi-wpa-eap-tls-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wpa-eap-tls-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wpa-eap-tls-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wpa_eap_ttls_tls (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const char *ssid_data = "blahblah"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (TLS)", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (ssid_data)); + g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_802_1X_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + + g_object_set (s_8021x, + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22", + NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", + NULL); + + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to set CA certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message); + + /* Phase 2 TLS stuff */ + + /* phase2 CA cert */ + success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to set inner CA certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message); + + /* phase2 client cert */ + success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to set inner client certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, error->message); + + /* phase2 private key */ + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + "test1", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to set private key '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-tls-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wpa-eap-ttls-tls-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wifi-wpa-eap-ttls-tls-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (keyfile != NULL, + "wifi-wpa-eap-ttls-tls-write-reread", "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wpa-eap-ttls-tls-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wpa-eap-ttls-tls-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wpa_eap_ttls_mschapv2 (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const char *ssid_data = "blahblah"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (MSCHAPv2)", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (ssid_data)); + g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_802_1X_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + + g_object_set (s_8021x, + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", + NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22", + NM_SETTING_802_1X_PHASE2_AUTHEAP, "mschapv2", + NULL); + + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to set CA certificate '%s': %s", + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message); + + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wifi-wpa-eap-ttls-mschapv2-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wifi-wpa-eap-ttls-mschapv2-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wifi-wpa-eap-ttls-mschapv2-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (keyfile != NULL, + "wifi-wpa-eap-ttls-mschapv2-write-reread", "expected keyfile for '%s'", testfile); + unlink (keyfile); + + ASSERT (nm_connection_verify (reread, &error), + "wifi-wpa-eap-ttls-mschapv2-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wifi-wpa-eap-ttls-mschapv2-write", "written and re-read connection weren't the same."); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_dynamic_wep_leap (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GByteArray *ssid; + const char *ssid_data = "blahblah"; + shvarFile *ifcfg; + char *tmp; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (ssid_data)); + g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + g_assert (s_8021x); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + nm_setting_802_1x_add_eap_method (s_8021x, "leap"); + + g_object_set (s_8021x, + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (reread); + g_assert (keyfile); + unlink (keyfile); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + /* Check and make sure that an "old-school" LEAP (Network EAP) connection + * did not get written. Check first that the auth alg is not set to "LEAP" + * and next that the only IEEE 802.1x EAP method is "LEAP". + */ + ifcfg = svNewFile (testfile); + g_assert (ifcfg); + tmp = svGetValue (ifcfg, "SECURITYMODE", FALSE); + g_assert_cmpstr (tmp, ==, NULL); + g_free (tmp); + + tmp = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE); + g_assert_cmpstr (tmp, ==, "LEAP"); + + svCloseFile (ifcfg); + unlink (testfile); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +#define TEST_IFCFG_IBFT_DHCP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-dhcp" + +static void +test_read_ibft_dhcp (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf1 }; + const char *expected_id = "System test-ibft-dhcp"; + guint64 expected_timestamp = 0; + + connection = connection_from_file (TEST_IFCFG_IBFT_DHCP, + NULL, + TYPE_ETHERNET, + TEST_IFCFG_DIR "/iscsiadm-test-dhcp", + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "ibft-dhcp-read", "failed to read %s: %s", TEST_IFCFG_IBFT_DHCP, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "ibft-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_DHCP, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "ibft-dhcp-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "ibft-dhcp-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* Read-only */ + ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE, + "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_READ_ONLY); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "ibft-dhcp-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "ibft-dhcp-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + ASSERT (nm_setting_wired_get_mtu (s_wired) == 0, + "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MTU); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "ibft-dhcp-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "ibft-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_DHCP, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +#define TEST_IFCFG_IBFT_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-static" + +static void +test_read_ibft_static (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf0 }; + const char *expected_id = "System test-ibft-static"; + guint64 expected_timestamp = 0; + const char *expected_dns1 = "10.16.255.2"; + const char *expected_dns2 = "10.16.255.3"; + struct in_addr addr; + const char *expected_address1 = "192.168.32.72"; + const char *expected_address1_gw = "192.168.35.254"; + NMIP4Address *ip4_addr; + + connection = connection_from_file (TEST_IFCFG_IBFT_STATIC, + NULL, + TYPE_ETHERNET, + TEST_IFCFG_DIR "/iscsiadm-test-static", + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "ibft-static-read", "failed to read %s: %s", TEST_IFCFG_IBFT_STATIC, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "ibft-static-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_STATIC, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "ibft-static-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "ibft-static-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "ibft-static-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* Timestamp */ + ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, + "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* Read-only */ + ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE, + "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_READ_ONLY); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "ibft-static-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "ibft-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + ASSERT (nm_setting_wired_get_mtu (s_wired) == 0, + "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MTU); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "ibft-static-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* Address #1 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + "ibft-static-verify-ip4", "failed to verify %s: missing IP4 address #1", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 22, + "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, + "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, + "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, + "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway", + TEST_IFCFG_IBFT_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + g_object_unref (connection); +} + +static void +test_read_ibft_malformed (const char *name, const char *iscsiadm_path) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); + + connection = connection_from_file (TEST_IFCFG_IBFT_STATIC, + NULL, + TYPE_ETHERNET, + iscsiadm_path, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection == NULL, + name, "unexpectedly able to read %s", TEST_IFCFG_IBFT_STATIC); +} + +static void +test_write_wired_qeth_dhcp (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + GPtrArray *subchans; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-qeth-dhcp-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired qeth Static", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + subchans = g_ptr_array_sized_new (3); + g_ptr_array_add (subchans, "0.0.600"); + g_ptr_array_add (subchans, "0.0.601"); + g_ptr_array_add (subchans, "0.0.602"); + g_object_set (s_wired, + NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, + NM_SETTING_WIRED_S390_NETTYPE, "qeth", + NULL); + g_ptr_array_free (subchans, TRUE); + + nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR"); + nm_setting_wired_add_s390_option (s_wired, "portno", "1"); + nm_setting_wired_add_s390_option (s_wired, "layer2", "0"); + nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + /* Verify */ + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-qeth-dhcp-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-qeth-dhcp-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-qeth-dhcp-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-qeth-dhcp-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wired-qeth-dhcp-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-qeth-dhcp-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_permissions (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "permissions-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Permissions", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + nm_setting_connection_add_permission (s_con, "user", "blahblah", NULL); + nm_setting_connection_add_permission (s_con, "user", "foobar", NULL); + nm_setting_connection_add_permission (s_con, "user", "asdfasdf", NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + /* Verify */ + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "permissions-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "permissions-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "permissions-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "permissions-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "permissions-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "permissions-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wifi_wep_agent_keys (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + const char *str_ssid = "foobarbaz"; + GByteArray *ssid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + g_assert (connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Agent Owned", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (strlen (str_ssid)); + g_byte_array_append (ssid, (guint8 *) str_ssid, strlen (str_ssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_byte_array_free (ssid, TRUE); + + /* Wifi security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + + /* Verify */ + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile != NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + /* Remove the WEP key from the original, because it should not have been + * written out to disk as it was agent-owned. The new connection should + * not have any WEP keys set. + */ + nm_setting_wireless_security_set_wep_key (s_wsec, 0, NULL); + + /* Compare original and reread */ + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_write_wired_pppoe (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingPPPOE *s_pppoe; + NMSettingPPP *s_ppp; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-pppoe-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-pppoe-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired PPPoE", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-pppoe-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-pppoe-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* PPPoE setting */ + s_pppoe = (NMSettingPPPOE *) nm_setting_pppoe_new (); + ASSERT (s_pppoe != NULL, + "wired-pppoe-write", "failed to allocate new %s setting", + NM_SETTING_PPPOE_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); + + g_object_set (G_OBJECT (s_pppoe), + NM_SETTING_PPPOE_SERVICE, "stupid-service", + NM_SETTING_PPPOE_USERNAME, "Bill Smith", + NM_SETTING_PPPOE_PASSWORD, "test1", + NULL); + + /* PPP setting */ + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + ASSERT (s_ppp != NULL, + "wired-pppoe-write", "failed to allocate new %s setting", + NM_SETTING_PPP_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-pppoe-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == FALSE, + "wired-pppoe-write", "unexpected success writing connection to disk"); + + g_object_unref (connection); +} + +static void +test_write_vpn (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingVPN *s_vpn; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "vpn-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "vpn-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write VPN", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME, + NULL); + g_free (uuid); + + /* VPN setting */ + s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-write", "failed to allocate new %s setting", + NM_SETTING_VPN_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + g_object_set (s_vpn, + NM_SETTING_VPN_SERVICE_TYPE, "awesomevpn", + NM_SETTING_VPN_USER_NAME, "Bill Smith", + NULL); + + nm_setting_vpn_add_data_item (s_vpn, "server", "vpn.somewhere.com"); + nm_setting_vpn_add_secret (s_vpn, "password", "sup3rs3cr3t"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "vpn-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "vpn-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == FALSE, + "vpn-write", "unexpected success writing connection to disk"); + + g_object_unref (connection); +} + +static void +test_write_mobile_broadband (gboolean gsm) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingGsm *s_gsm; + NMSettingCdma *s_cdma; + NMSettingPPP *s_ppp; + NMSettingSerial *s_serial; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "mobile-broadband-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, gsm ? "Test Write GSM" : "Test Write CDMA", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, gsm ? NM_SETTING_GSM_SETTING_NAME : NM_SETTING_CDMA_SETTING_NAME, + NULL); + g_free (uuid); + + if (gsm) { + /* GSM setting */ + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + ASSERT (s_gsm != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_GSM_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); + } else { + /* CDMA setting */ + s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); + ASSERT (s_cdma != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_CDMA_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_cdma)); + + g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL); + } + + /* Serial setting */ + s_serial = (NMSettingSerial *) nm_setting_serial_new (); + ASSERT (s_serial != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_SERIAL_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_serial)); + + g_object_set (s_serial, + NM_SETTING_SERIAL_BAUD, 115200, + NM_SETTING_SERIAL_BITS, 8, + NM_SETTING_SERIAL_PARITY, 'n', + NM_SETTING_SERIAL_STOPBITS, 1, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* PPP setting */ + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + ASSERT (s_ppp != NULL, + "mobile-broadband-write", "failed to allocate new %s setting", + NM_SETTING_PPP_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "mobile-broadband-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == FALSE, + "mobile-broadband-write", "unexpected success writing connection to disk"); + + g_object_unref (connection); +} + +#define TEST_IFCFG_BRIDGE_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-main" + +static void +test_read_bridge_main (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_BRIDGE_MAIN, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection == NULL, + "bridge-main-read", "unexpected success reading %s", TEST_IFCFG_BRIDGE_MAIN); +} + +#define TEST_IFCFG_BRIDGE_COMPONENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-component" + +static void +test_read_bridge_component (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_BRIDGE_COMPONENT, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "bridge-component-read", "unexpected failure reading %s", TEST_IFCFG_BRIDGE_COMPONENT); + + ASSERT (unmanaged != NULL, + "bridge-component-read", "missing unmanaged spec from %s", TEST_IFCFG_BRIDGE_COMPONENT); + + ASSERT (g_strcmp0 (unmanaged, "mac:00:22:15:59:62:97") == 0, + "bridge-component-read", "unexpected unmanaged spec from %s", TEST_IFCFG_BRIDGE_COMPONENT); + + g_object_unref (connection); + g_free (unmanaged); +} + +#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-interface" + +static void +test_read_vlan_interface (void) +{ + NMConnection *connection; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection == NULL, + "vlan-interface-read", "unexpected success reading %s", TEST_IFCFG_VLAN_INTERFACE); +} + +#define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex" +#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted" +#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-hex" + + +#define TEST_IFCFG_WIRED_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static" +#define TEST_IFCFG_WIRED_STATIC_BOOTPROTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-bootproto" + +#define DEFAULT_HEX_PSK "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0" + +int main (int argc, char **argv) +{ + GError *error = NULL; + char *base; + + g_type_init (); + + if (!nm_utils_init (&error)) + FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + + /* The tests */ + test_read_unmanaged (); + test_read_minimal (); + test_read_wired_static (TEST_IFCFG_WIRED_STATIC, "System test-wired-static"); + test_read_wired_static (TEST_IFCFG_WIRED_STATIC_BOOTPROTO, "System test-wired-static-bootproto"); + test_read_wired_static_no_prefix (8); + test_read_wired_static_no_prefix (16); + test_read_wired_static_no_prefix (24); + test_read_wired_dhcp (); + test_read_wired_global_gateway (); + test_read_wired_never_default (); + test_read_wired_defroute_no (); + test_read_wired_defroute_no_gatewaydev_yes (); + test_read_wired_static_routes (); + test_read_wired_static_routes_legacy (); + test_read_wired_ipv6_manual (); + test_read_wired_ipv6_only (); + test_read_wired_dhcp6_only (); + test_read_onboot_no (); + test_read_wired_8021x_peap_mschapv2 (); + test_read_wired_8021x_tls_secret_flags (TEST_IFCFG_WIRED_8021X_TLS_AGENT, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_read_wired_8021x_tls_secret_flags (TEST_IFCFG_WIRED_8021X_TLS_ALWAYS, + NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_read_wifi_open (); + test_read_wifi_open_auto (); + test_read_wifi_open_ssid_hex (); + test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX, "wifi-open-ssid-bad-hex-read"); + test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX, "wifi-open-ssid-long-hex-read"); + test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED, "wifi-open-ssid-long-quoted-read"); + test_read_wifi_open_ssid_quoted (); + test_read_wifi_wep (); + test_read_wifi_wep_adhoc (); + test_read_wifi_wep_passphrase (); + test_read_wifi_wep_40_ascii (); + test_read_wifi_wep_104_ascii (); + test_read_wifi_leap (); + test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_AGENT, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_ALWAYS, + NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_read_wifi_wpa_psk (); + test_read_wifi_wpa_psk_unquoted (); + test_read_wifi_wpa_psk_unquoted2 (); + test_read_wifi_wpa_psk_adhoc (); + test_read_wifi_wpa_psk_hex (); + test_read_wifi_dynamic_wep_leap (); + test_read_wifi_wpa_eap_tls (); + test_read_wifi_wpa_eap_ttls_tls (); + test_read_wifi_wep_eap_ttls_chap (); + test_read_wired_qeth_static (); + test_read_wifi_wep_no_keys (); + test_read_permissions (); + test_read_wifi_wep_agent_keys (); + + test_write_wired_static (); + test_write_wired_static_ip6_only (); + test_write_wired_static_routes (); + test_read_write_static_routes_legacy (); + test_write_wired_dhcp (); + test_write_wired_dhcp_8021x_peap_mschapv2 (); + test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_SECRET_FLAG_NONE); + test_write_wifi_open (); + test_write_wifi_open_hex_ssid (); + test_write_wifi_wep (); + test_write_wifi_wep_adhoc (); + test_write_wifi_wep_passphrase (); + test_write_wifi_wep_40_ascii (); + test_write_wifi_wep_104_ascii (); + test_write_wifi_leap (); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); + test_write_wifi_wpa_psk ("Test Write Wifi WPA PSK", + "wifi-wpa-psk-write", + FALSE, + TRUE, + FALSE, + DEFAULT_HEX_PSK); + test_write_wifi_wpa_psk ("Test Write Wifi WPA2 PSK", + "wifi-wpa2-psk-write", + FALSE, + FALSE, + TRUE, + DEFAULT_HEX_PSK); + test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK", + "wifi-wpa-wpa2-psk-write", + FALSE, + TRUE, + TRUE, + DEFAULT_HEX_PSK); + test_write_wifi_wpa_psk ("Test Write Wifi WEP WPA WPA2 PSK", + "wifi-wep-wpa-wpa2-psk-write", + TRUE, + TRUE, + TRUE, + DEFAULT_HEX_PSK); + test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK Passphrase", + "wifi-wpa-wpa2-psk-passphrase-write", + FALSE, + TRUE, + TRUE, + "really insecure passphrase04!"); + test_write_wifi_wpa_psk_adhoc (); + test_write_wifi_wpa_eap_tls (); + test_write_wifi_wpa_eap_ttls_tls (); + test_write_wifi_wpa_eap_ttls_mschapv2 (); + test_write_wifi_dynamic_wep_leap (); + test_write_wired_qeth_dhcp (); + test_write_permissions (); + test_write_wifi_wep_agent_keys (); + + /* iSCSI / ibft */ + test_read_ibft_dhcp (); + test_read_ibft_static (); + test_read_ibft_malformed ("ibft-bad-record-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-record"); + test_read_ibft_malformed ("ibft-bad-entry-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-entry"); + test_read_ibft_malformed ("ibft-bad-ipaddr-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-ipaddr"); + test_read_ibft_malformed ("ibft-bad-gateway-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-gateway"); + test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1"); + test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2"); + + /* Stuff we expect to fail for now */ + test_write_wired_pppoe (); + test_write_vpn (); + test_write_mobile_broadband (TRUE); + test_write_mobile_broadband (FALSE); + test_read_bridge_main (); + test_read_bridge_component (); + test_read_vlan_interface (); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c new file mode 100644 index 00000000..92a0b802 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -0,0 +1,362 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + */ + +#include <glib.h> +#include <stdlib.h> +#include <string.h> +#include "utils.h" +#include "shvar.h" + +/* + * utils_bin2hexstr + * + * Convert a byte-array into a hexadecimal string. + * + * Code originally by Alex Larsson <alexl@redhat.com> and + * copyright Red Hat, Inc. under terms of the LGPL. + * + */ +char * +utils_bin2hexstr (const char *bytes, int len, int final_len) +{ + static char hex_digits[] = "0123456789abcdef"; + char *result; + int i; + gsize buflen = (len * 2) + 1; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */ + if (final_len > -1) + g_return_val_if_fail (final_len < buflen, NULL); + + result = g_malloc0 (buflen); + for (i = 0; i < len; i++) + { + result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf]; + result[2*i+1] = hex_digits[bytes[i] & 0xf]; + } + /* Cut converted key off at the correct length for this cipher type */ + if (final_len > -1) + result[final_len] = '\0'; + else + result[buflen - 1] = '\0'; + + return result; +} + +/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */ + +static int hex2num (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex2byte (const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +char * +utils_hexstr2bin (const char *hex, size_t len) +{ + size_t i; + int a; + const char * ipos = hex; + char * buf = NULL; + char * opos; + + /* Length must be a multiple of 2 */ + if ((len % 2) != 0) + return NULL; + + opos = buf = g_malloc0 ((len / 2) + 1); + for (i = 0; i < len; i += 2) { + a = hex2byte (ipos); + if (a < 0) { + g_free (buf); + return NULL; + } + *opos++ = a; + ipos += 2; + } + return buf; +} + +/* End from hostap */ + +/* + * Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when + * installing packages. + * + * Implementation taken from upstart. + */ +static gboolean +check_rpm_temp_suffix (const char *path) +{ + const char *ptr; + + g_return_val_if_fail (path != NULL, FALSE); + + /* Matches *;[a-fA-F0-9]{8}; used by rpm */ + ptr = strrchr (path, ';'); + if (ptr && (strspn (ptr + 1, "abcdefABCDEF0123456789") == 8) + && (! ptr[9])) + return TRUE; + return FALSE; +} + +static gboolean +check_suffix (const char *base, const char *tag) +{ + int len, tag_len; + + g_return_val_if_fail (base != NULL, TRUE); + g_return_val_if_fail (tag != NULL, TRUE); + + len = strlen (base); + tag_len = strlen (tag); + if ((len > tag_len) && !strcasecmp (base + len - tag_len, tag)) + return TRUE; + return FALSE; +} + +gboolean +utils_should_ignore_file (const char *filename, gboolean only_ifcfg) +{ + char *base; + gboolean ignore = TRUE; + gboolean is_ifcfg = FALSE; + gboolean is_other = FALSE; + + g_return_val_if_fail (filename != NULL, TRUE); + + base = g_path_get_basename (filename); + g_return_val_if_fail (base != NULL, TRUE); + + /* Only handle ifcfg, keys, and routes files */ + if (!strncmp (base, IFCFG_TAG, strlen (IFCFG_TAG))) + is_ifcfg = TRUE; + + if (only_ifcfg == FALSE) { + if ( !strncmp (base, KEYS_TAG, strlen (KEYS_TAG)) + || !strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG)) + || !strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG))) + is_other = TRUE; + } + + /* But not those that have certain suffixes */ + if ( (is_ifcfg || is_other) + && !check_suffix (base, BAK_TAG) + && !check_suffix (base, TILDE_TAG) + && !check_suffix (base, ORIG_TAG) + && !check_suffix (base, REJ_TAG) + && !check_suffix (base, RPMNEW_TAG) + && !check_suffix (base, AUGNEW_TAG) + && !check_suffix (base, AUGTMP_TAG) + && !check_rpm_temp_suffix (base)) + ignore = FALSE; + + g_free (base); + return ignore; +} + +char * +utils_cert_path (const char *parent, const char *suffix) +{ + const char *name; + char *dir, *path; + + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (suffix != NULL, NULL); + + name = utils_get_ifcfg_name (parent, FALSE); + dir = g_path_get_dirname (parent); + path = g_strdup_printf ("%s/%s-%s", dir, name, suffix); + g_free (dir); + return path; +} + +const char * +utils_get_ifcfg_name (const char *file, gboolean only_ifcfg) +{ + const char *name = NULL, *start = NULL; + char *base; + + g_return_val_if_fail (file != NULL, NULL); + + base = g_path_get_basename (file); + if (!base) + return NULL; + + /* Find the point in 'file' where 'base' starts. We use 'file' since it's + * const and thus will survive after we free 'base'. + */ + start = file + strlen (file) - strlen (base); + g_assert (strcmp (start, base) == 0); + g_free (base); + + if (!strncmp (start, IFCFG_TAG, strlen (IFCFG_TAG))) + name = start + strlen (IFCFG_TAG); + else if (only_ifcfg == FALSE) { + if (!strncmp (start, KEYS_TAG, strlen (KEYS_TAG))) + name = start + strlen (KEYS_TAG); + else if (!strncmp (start, ROUTE_TAG, strlen (ROUTE_TAG))) + name = start + strlen (ROUTE_TAG); + else if (!strncmp (start, ROUTE6_TAG, strlen (ROUTE6_TAG))) + name = start + strlen (ROUTE6_TAG); + } + + return name; +} + +/* Used to get any ifcfg/extra file path from any other ifcfg/extra path + * in the form <tag><name>. + */ +static char * +utils_get_extra_path (const char *parent, const char *tag) +{ + char *item_path = NULL, *dirname; + const char *name; + + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (tag != NULL, NULL); + + dirname = g_path_get_dirname (parent); + if (!dirname) + return NULL; + + name = utils_get_ifcfg_name (parent, FALSE); + if (name) { + if (!strcmp (dirname, ".")) + item_path = g_strdup_printf ("%s%s", tag, name); + else + item_path = g_strdup_printf ("%s/%s%s", dirname, tag, name); + } + g_free (dirname); + + return item_path; +} + +char * +utils_get_ifcfg_path (const char *parent) +{ + return utils_get_extra_path (parent, IFCFG_TAG); +} + +char * +utils_get_keys_path (const char *parent) +{ + return utils_get_extra_path (parent, KEYS_TAG); +} + +char * +utils_get_route_path (const char *parent) +{ + return utils_get_extra_path (parent, ROUTE_TAG); +} + +char * +utils_get_route6_path (const char *parent) +{ + return utils_get_extra_path (parent, ROUTE6_TAG); +} + +shvarFile * +utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create) +{ + shvarFile *ifcfg = NULL; + char *path; + + path = utils_get_extra_path (parent, tag); + if (!path) + return NULL; + + if (should_create && !g_file_test (path, G_FILE_TEST_EXISTS)) + ifcfg = svCreateFile (path); + + if (!ifcfg) + ifcfg = svNewFile (path); + + g_free (path); + return ifcfg; +} + +shvarFile * +utils_get_keys_ifcfg (const char *parent, gboolean should_create) +{ + return utils_get_extra_ifcfg (parent, KEYS_TAG, should_create); +} + +shvarFile * +utils_get_route_ifcfg (const char *parent, gboolean should_create) +{ + return utils_get_extra_ifcfg (parent, ROUTE_TAG, should_create); +} + +shvarFile * +utils_get_route6_ifcfg (const char *parent, gboolean should_create) +{ + return utils_get_extra_ifcfg (parent, ROUTE6_TAG, should_create); +} + +/* Finds out if route file has new or older format + * Returns TRUE - new syntax (ADDRESS<n>=a.b.c.d ...), error opening file or empty + * FALSE - older syntax, i.e. argument to 'ip route add' (1.2.3.0/24 via 11.22.33.44) + */ +gboolean +utils_has_route_file_new_syntax (const char *filename) +{ + char *contents = NULL; + gsize len = 0; + gboolean ret = FALSE; + const char *pattern = "^[[:space:]]*ADDRESS[0-9]+="; + + g_return_val_if_fail (filename != NULL, TRUE); + + if (!g_file_get_contents (filename, &contents, &len, NULL)) + return TRUE; + + if (len <= 0) { + ret = TRUE; + goto gone; + } + + if (g_regex_match_simple (pattern, contents, G_REGEX_MULTILINE, 0)) + ret = TRUE; + +gone: + g_free (contents); + return ret; +} + diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h new file mode 100644 index 00000000..d5e3a133 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/utils.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2009 Red Hat, Inc. + */ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include <glib.h> +#include "shvar.h" +#include "common.h" + +char *utils_bin2hexstr (const char *bytes, int len, int final_len); + +char *utils_hexstr2bin (const char *hex, size_t len); + +char *utils_cert_path (const char *parent, const char *suffix); + +const char *utils_get_ifcfg_name (const char *file, gboolean only_ifcfg); + +gboolean utils_should_ignore_file (const char *filename, gboolean only_ifcfg); + +char *utils_get_ifcfg_path (const char *parent); +char *utils_get_keys_path (const char *parent); +char *utils_get_route_path (const char *parent); +char *utils_get_route6_path (const char *parent); + +shvarFile *utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create); +shvarFile *utils_get_keys_ifcfg (const char *parent, gboolean should_create); +shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create); +shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create); + +gboolean utils_has_route_file_new_syntax (const char *filename); + +#endif /* _UTILS_H_ */ + diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c new file mode 100644 index 00000000..6924262f --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -0,0 +1,1746 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2009 - 2011 Red Hat, Inc. + */ + +#include <ctype.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> + +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-8021x.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-pppoe.h> +#include <nm-utils.h> + +#include "common.h" +#include "shvar.h" +#include "reader.h" +#include "writer.h" +#include "utils.h" +#include "crypto.h" + +#define PLUGIN_WARN(pname, fmt, args...) \ + { g_warning (" " pname ": " fmt, ##args); } + +static void +save_secret_flags (shvarFile *ifcfg, + const char *key, + NMSettingSecretFlags flags) +{ + GString *str; + + g_return_if_fail (ifcfg != NULL); + g_return_if_fail (key != NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + svSetValue (ifcfg, key, NULL, FALSE); + return; + } + + /* Convert flags bitfield into string representation */ + str = g_string_sized_new (20); + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_string_append (str, SECRET_FLAG_AGENT); + + if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, SECRET_FLAG_NOT_SAVED); + } + + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, SECRET_FLAG_NOT_REQUIRED); + } + + svSetValue (ifcfg, key, str->len ? str->str : NULL, FALSE); + g_string_free (str, TRUE); +} + +static void +set_secret (shvarFile *ifcfg, + const char *key, + const char *value, + const char *flags_key, + NMSettingSecretFlags flags, + gboolean verbatim) +{ + shvarFile *keyfile; + + /* Clear the secret from the ifcfg and the associated "keys" file */ + svSetValue (ifcfg, key, NULL, FALSE); + + /* Save secret flags */ + save_secret_flags (ifcfg, flags_key, flags); + + keyfile = utils_get_keys_ifcfg (ifcfg->fileName, TRUE); + if (!keyfile) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not create key file for '%s'", + ifcfg->fileName); + goto error; + } + + /* Clear the secret from the associated "keys" file */ + svSetValue (keyfile, key, NULL, FALSE); + + /* Only write the secret if it's system owned and supposed to be saved */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) + svSetValue (keyfile, key, value, verbatim); + + if (svWriteFile (keyfile, 0600)) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not update key file '%s'", + keyfile->fileName); + svCloseFile (keyfile); + goto error; + } + svCloseFile (keyfile); + return; + +error: + /* Try setting the secret in the actual ifcfg */ + svSetValue (ifcfg, key, value, FALSE); +} + +static gboolean +write_secret_file (const char *path, + const char *data, + gsize len, + GError **error) +{ + char *tmppath; + int fd = -1, written; + gboolean success = FALSE; + + tmppath = g_malloc0 (strlen (path) + 10); + if (!tmppath) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not allocate memory for temporary file for '%s'", + path); + return FALSE; + } + + memcpy (tmppath, path, strlen (path)); + strcat (tmppath, ".XXXXXX"); + + errno = 0; + fd = mkstemp (tmppath); + if (fd < 0) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not create temporary file for '%s': %d", + path, errno); + goto out; + } + + /* Only readable by root */ + errno = 0; + if (fchmod (fd, S_IRUSR | S_IWUSR)) { + close (fd); + unlink (tmppath); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not set permissions for temporary file '%s': %d", + path, errno); + goto out; + } + + errno = 0; + written = write (fd, data, len); + if (written != len) { + close (fd); + unlink (tmppath); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not write temporary file for '%s': %d", + path, errno); + goto out; + } + close (fd); + + /* Try to rename */ + errno = 0; + if (rename (tmppath, path)) { + unlink (tmppath); + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not rename temporary file to '%s': %d", + path, errno); + goto out; + } + success = TRUE; + +out: + g_free (tmppath); + return success; +} + +typedef struct ObjectType { + const char *setting_key; + NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting); + const char * (*path_func) (NMSetting8021x *setting); + const GByteArray * (*blob_func) (NMSetting8021x *setting); + const char *ifcfg_key; + const char *suffix; +} ObjectType; + +static const ObjectType ca_type = { + NM_SETTING_802_1X_CA_CERT, + nm_setting_802_1x_get_ca_cert_scheme, + nm_setting_802_1x_get_ca_cert_path, + nm_setting_802_1x_get_ca_cert_blob, + "IEEE_8021X_CA_CERT", + "ca-cert.der" +}; + +static const ObjectType phase2_ca_type = { + NM_SETTING_802_1X_PHASE2_CA_CERT, + nm_setting_802_1x_get_phase2_ca_cert_scheme, + nm_setting_802_1x_get_phase2_ca_cert_path, + nm_setting_802_1x_get_phase2_ca_cert_blob, + "IEEE_8021X_INNER_CA_CERT", + "inner-ca-cert.der" +}; + +static const ObjectType client_type = { + NM_SETTING_802_1X_CLIENT_CERT, + nm_setting_802_1x_get_client_cert_scheme, + nm_setting_802_1x_get_client_cert_path, + nm_setting_802_1x_get_client_cert_blob, + "IEEE_8021X_CLIENT_CERT", + "client-cert.der" +}; + +static const ObjectType phase2_client_type = { + NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + nm_setting_802_1x_get_phase2_client_cert_scheme, + nm_setting_802_1x_get_phase2_client_cert_path, + nm_setting_802_1x_get_phase2_client_cert_blob, + "IEEE_8021X_INNER_CLIENT_CERT", + "inner-client-cert.der" +}; + +static const ObjectType pk_type = { + NM_SETTING_802_1X_PRIVATE_KEY, + nm_setting_802_1x_get_private_key_scheme, + nm_setting_802_1x_get_private_key_path, + nm_setting_802_1x_get_private_key_blob, + "IEEE_8021X_PRIVATE_KEY", + "private-key.pem" +}; + +static const ObjectType phase2_pk_type = { + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + nm_setting_802_1x_get_phase2_private_key_scheme, + nm_setting_802_1x_get_phase2_private_key_path, + nm_setting_802_1x_get_phase2_private_key_blob, + "IEEE_8021X_INNER_PRIVATE_KEY", + "inner-private-key.pem" +}; + +static const ObjectType p12_type = { + NM_SETTING_802_1X_PRIVATE_KEY, + nm_setting_802_1x_get_private_key_scheme, + nm_setting_802_1x_get_private_key_path, + nm_setting_802_1x_get_private_key_blob, + "IEEE_8021X_PRIVATE_KEY", + "private-key.p12" +}; + +static const ObjectType phase2_p12_type = { + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + nm_setting_802_1x_get_phase2_private_key_scheme, + nm_setting_802_1x_get_phase2_private_key_path, + nm_setting_802_1x_get_phase2_private_key_blob, + "IEEE_8021X_INNER_PRIVATE_KEY", + "inner-private-key.p12" +}; + +static gboolean +write_object (NMSetting8021x *s_8021x, + shvarFile *ifcfg, + const ObjectType *objtype, + GError **error) +{ + NMSetting8021xCKScheme scheme; + const char *path = NULL; + const GByteArray *blob = NULL; + + g_return_val_if_fail (ifcfg != NULL, FALSE); + g_return_val_if_fail (objtype != NULL, FALSE); + + scheme = (*(objtype->scheme_func))(s_8021x); + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + blob = (*(objtype->blob_func))(s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = (*(objtype->path_func))(s_8021x); + break; + default: + break; + } + + /* If certificate/private key wasn't sent, the connection may no longer be + * 802.1x and thus we clear out the paths and certs. + */ + if (!path && !blob) { + char *standard_file; + int ignored; + + /* Since no cert/private key is now being used, delete any standard file + * that was created for this connection, but leave other files alone. + * Thus, for example, + * /etc/sysconfig/network-scripts/ca-cert-Test_Write_Wifi_WPA_EAP-TLS.der + * will be deleted, but /etc/pki/tls/cert.pem will not. + */ + standard_file = utils_cert_path (ifcfg->fileName, objtype->suffix); + if (g_file_test (standard_file, G_FILE_TEST_EXISTS)) + ignored = unlink (standard_file); + g_free (standard_file); + + svSetValue (ifcfg, objtype->ifcfg_key, NULL, FALSE); + return TRUE; + } + + /* If the object path was specified, prefer that over any raw cert data that + * may have been sent. + */ + if (path) { + svSetValue (ifcfg, objtype->ifcfg_key, path, FALSE); + return TRUE; + } + + /* If it's raw certificate data, write the data out to the standard file */ + if (blob) { + gboolean success; + char *new_file; + GError *write_error = NULL; + + new_file = utils_cert_path (ifcfg->fileName, objtype->suffix); + if (!new_file) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not create file path for %s / %s", + NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key); + return FALSE; + } + + /* Write the raw certificate data out to the standard file so that we + * can use paths from now on instead of pushing around the certificate + * data itself. + */ + success = write_secret_file (new_file, (const char *) blob->data, blob->len, &write_error); + if (success) { + svSetValue (ifcfg, objtype->ifcfg_key, new_file, FALSE); + return TRUE; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not write certificate/key for %s / %s: %s", + NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key, + (write_error && write_error->message) ? write_error->message : "(unknown)"); + g_clear_error (&write_error); + } + g_free (new_file); + } + + return FALSE; +} + +static gboolean +write_8021x_certs (NMSetting8021x *s_8021x, + gboolean phase2, + shvarFile *ifcfg, + GError **error) +{ + const char *password = NULL; + gboolean success = FALSE, is_pkcs12 = FALSE; + const ObjectType *otype = NULL; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + /* CA certificate */ + if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_ca_type : &ca_type, error)) + return FALSE; + + /* Private key */ + if (phase2) { + otype = &phase2_pk_type; + if (nm_setting_802_1x_get_phase2_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + otype = &phase2_p12_type; + is_pkcs12 = TRUE; + } + password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + flags = nm_setting_802_1x_get_phase2_private_key_password_flags (s_8021x); + } else { + otype = &pk_type; + if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + otype = &p12_type; + is_pkcs12 = TRUE; + } + password = nm_setting_802_1x_get_private_key_password (s_8021x); + flags = nm_setting_802_1x_get_private_key_password_flags (s_8021x); + } + + /* Save the private key */ + if (!write_object (s_8021x, ifcfg, otype, error)) + goto out; + + /* Private key password */ + if (phase2) { + set_secret (ifcfg, + "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", + password, + "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", + flags, + FALSE); + } else { + set_secret (ifcfg, + "IEEE_8021X_PRIVATE_KEY_PASSWORD", + password, + "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", + flags, + FALSE); + } + + /* Client certificate */ + if (is_pkcs12) { + /* Don't need a client certificate with PKCS#12 since the file is both + * the client certificate and the private key in one file. + */ + svSetValue (ifcfg, + phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT", + NULL, FALSE); + } else { + /* Save the client certificate */ + if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_client_type : &client_type, error)) + goto out; + } + + success = TRUE; + +out: + return success; +} + +static gboolean +write_8021x_setting (NMConnection *connection, + shvarFile *ifcfg, + gboolean wired, + GError **error) +{ + NMSetting8021x *s_8021x; + const char *value; + char *tmp = NULL; + gboolean success = FALSE; + GString *phase2_auth; + + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + if (!s_8021x) { + /* If wired, clear KEY_MGMT */ + if (wired) + svSetValue (ifcfg, "KEY_MGMT", NULL, FALSE); + return TRUE; + } + + /* If wired, write KEY_MGMT */ + if (wired) + svSetValue (ifcfg, "KEY_MGMT", "IEEE8021X", FALSE); + + /* EAP method */ + if (nm_setting_802_1x_get_num_eap_methods (s_8021x)) { + value = nm_setting_802_1x_get_eap_method (s_8021x, 0); + if (value) + tmp = g_ascii_strup (value, -1); + } + svSetValue (ifcfg, "IEEE_8021X_EAP_METHODS", tmp ? tmp : NULL, FALSE); + g_free (tmp); + + svSetValue (ifcfg, "IEEE_8021X_IDENTITY", + nm_setting_802_1x_get_identity (s_8021x), + FALSE); + + svSetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", + nm_setting_802_1x_get_anonymous_identity (s_8021x), + FALSE); + + set_secret (ifcfg, + "IEEE_8021X_PASSWORD", + nm_setting_802_1x_get_password (s_8021x), + "IEEE_8021X_PASSWORD_FLAGS", + nm_setting_802_1x_get_password_flags (s_8021x), + FALSE); + + /* PEAP version */ + value = nm_setting_802_1x_get_phase1_peapver (s_8021x); + svSetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", NULL, FALSE); + if (value && (!strcmp (value, "0") || !strcmp (value, "1"))) + svSetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", value, FALSE); + + /* Force new PEAP label */ + value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x); + svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", NULL, FALSE); + if (value && !strcmp (value, "1")) + svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", "yes", FALSE); + + /* Phase2 auth methods */ + svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", NULL, FALSE); + phase2_auth = g_string_new (NULL); + + value = nm_setting_802_1x_get_phase2_auth (s_8021x); + if (value) { + tmp = g_ascii_strup (value, -1); + g_string_append (phase2_auth, tmp); + g_free (tmp); + } + + value = nm_setting_802_1x_get_phase2_autheap (s_8021x); + if (value) { + if (phase2_auth->len) + g_string_append_c (phase2_auth, ' '); + + tmp = g_ascii_strup (value, -1); + g_string_append_printf (phase2_auth, "EAP-%s", tmp); + g_free (tmp); + } + + svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", + phase2_auth->len ? phase2_auth->str : NULL, + FALSE); + + g_string_free (phase2_auth, TRUE); + + success = write_8021x_certs (s_8021x, FALSE, ifcfg, error); + if (success) { + /* phase2/inner certs */ + success = write_8021x_certs (s_8021x, TRUE, ifcfg, error); + } + + return success; +} + +static gboolean +write_wireless_security_setting (NMConnection *connection, + shvarFile *ifcfg, + gboolean adhoc, + gboolean *no_8021x, + GError **error) +{ + NMSettingWirelessSecurity *s_wsec; + const char *key_mgmt, *auth_alg, *key, *proto, *cipher, *psk; + gboolean wep = FALSE, wpa = FALSE, dynamic_wep = FALSE; + char *tmp; + guint32 i, num; + GString *str; + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + g_assert (key_mgmt); + + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + + svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE); + + if (!strcmp (key_mgmt, "none")) { + wep = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) { + svSetValue (ifcfg, "KEY_MGMT", "WPA-PSK", FALSE); + wpa = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "ieee8021x")) { + svSetValue (ifcfg, "KEY_MGMT", "IEEE8021X", FALSE); + dynamic_wep = TRUE; + } else if (!strcmp (key_mgmt, "wpa-eap")) { + svSetValue (ifcfg, "KEY_MGMT", "WPA-EAP", FALSE); + wpa = TRUE; + } + + svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE); + if (auth_alg) { + if (!strcmp (auth_alg, "shared")) + svSetValue (ifcfg, "SECURITYMODE", "restricted", FALSE); + else if (!strcmp (auth_alg, "open")) + svSetValue (ifcfg, "SECURITYMODE", "open", FALSE); + else if (!strcmp (auth_alg, "leap")) { + svSetValue (ifcfg, "SECURITYMODE", "leap", FALSE); + svSetValue (ifcfg, "IEEE_8021X_IDENTITY", + nm_setting_wireless_security_get_leap_username (s_wsec), + FALSE); + set_secret (ifcfg, + "IEEE_8021X_PASSWORD", + nm_setting_wireless_security_get_leap_password (s_wsec), + "IEEE_8021X_PASSWORD_FLAGS", + nm_setting_wireless_security_get_leap_password_flags (s_wsec), + FALSE); + *no_8021x = TRUE; + } + } + + /* WEP keys */ + + /* Clear any default key */ + set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); + + /* Clear existing keys */ + for (i = 0; i < 4; i++) { + tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); + set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); + g_free (tmp); + + tmp = g_strdup_printf ("KEY%d", i + 1); + set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE); + g_free (tmp); + } + + /* And write the new ones out */ + if (wep) { + /* Default WEP TX key index */ + tmp = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) + 1); + svSetValue (ifcfg, "DEFAULTKEY", tmp, FALSE); + g_free (tmp); + + for (i = 0; i < 4; i++) { + NMWepKeyType key_type; + + key = nm_setting_wireless_security_get_wep_key (s_wsec, i); + if (key) { + char *ascii_key = NULL; + + /* Passphrase needs a different ifcfg key since with WEP, there + * are some passphrases that are indistinguishable from WEP hex + * keys. + */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + if (key_type == NM_WEP_KEY_TYPE_PASSPHRASE) + tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); + else { + tmp = g_strdup_printf ("KEY%d", i + 1); + + /* Add 's:' prefix for ASCII keys */ + if (strlen (key) == 5 || strlen (key) == 13) { + ascii_key = g_strdup_printf ("s:%s", key); + key = ascii_key; + } + } + + set_secret (ifcfg, + tmp, + key, + "WEP_KEY_FLAGS", + nm_setting_wireless_security_get_wep_key_flags (s_wsec), + FALSE); + g_free (tmp); + g_free (ascii_key); + } + } + } + + /* WPA protos */ + svSetValue (ifcfg, "WPA_ALLOW_WPA", NULL, FALSE); + svSetValue (ifcfg, "WPA_ALLOW_WPA2", NULL, FALSE); + num = nm_setting_wireless_security_get_num_protos (s_wsec); + for (i = 0; i < num; i++) { + proto = nm_setting_wireless_security_get_proto (s_wsec, i); + if (proto && !strcmp (proto, "wpa")) + svSetValue (ifcfg, "WPA_ALLOW_WPA", "yes", FALSE); + else if (proto && !strcmp (proto, "rsn")) + svSetValue (ifcfg, "WPA_ALLOW_WPA2", "yes", FALSE); + } + + /* WPA Pairwise ciphers */ + svSetValue (ifcfg, "CIPHER_PAIRWISE", NULL, FALSE); + str = g_string_new (NULL); + num = nm_setting_wireless_security_get_num_pairwise (s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (str, ' '); + cipher = nm_setting_wireless_security_get_pairwise (s_wsec, i); + + /* Don't write out WEP40 or WEP104 if for some reason they are set; they + * are not valid pairwise ciphers. + */ + if (strcmp (cipher, "wep40") && strcmp (cipher, "wep104")) { + tmp = g_ascii_strup (cipher, -1); + g_string_append (str, tmp); + g_free (tmp); + } + } + if (strlen (str->str) && (dynamic_wep == FALSE)) + svSetValue (ifcfg, "CIPHER_PAIRWISE", str->str, FALSE); + g_string_free (str, TRUE); + + /* WPA Group ciphers */ + svSetValue (ifcfg, "CIPHER_GROUP", NULL, FALSE); + str = g_string_new (NULL); + num = nm_setting_wireless_security_get_num_groups (s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (str, ' '); + cipher = nm_setting_wireless_security_get_group (s_wsec, i); + tmp = g_ascii_strup (cipher, -1); + g_string_append (str, tmp); + g_free (tmp); + } + if (strlen (str->str) && (dynamic_wep == FALSE)) + svSetValue (ifcfg, "CIPHER_GROUP", str->str, FALSE); + g_string_free (str, TRUE); + + /* WPA Passphrase */ + if (wpa) { + GString *quoted = NULL; + + psk = nm_setting_wireless_security_get_psk (s_wsec); + if (psk && (strlen (psk) != 64)) { + /* Quote the PSK since it's a passphrase */ + quoted = g_string_sized_new (strlen (psk) + 2); /* 2 for quotes */ + g_string_append_c (quoted, '"'); + g_string_append (quoted, psk); + g_string_append_c (quoted, '"'); + } + set_secret (ifcfg, + "WPA_PSK", + quoted ? quoted->str : psk, + "WPA_PSK_FLAGS", + nm_setting_wireless_security_get_psk_flags (s_wsec), + TRUE); + if (quoted) + g_string_free (quoted, TRUE); + } else { + set_secret (ifcfg, + "WPA_PSK", + NULL, + "WPA_PSK_FLAGS", + NM_SETTING_SECRET_FLAG_NONE, + FALSE); + } + + return TRUE; +} + +static gboolean +write_wireless_setting (NMConnection *connection, + shvarFile *ifcfg, + gboolean *no_8021x, + GError **error) +{ + NMSettingWireless *s_wireless; + char *tmp, *tmp2; + const GByteArray *ssid, *device_mac, *cloned_mac, *bssid; + const char *mode; + char buf[33]; + guint32 mtu, chan, i; + gboolean adhoc = FALSE, hex_ssid = FALSE; + + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (!s_wireless) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + svSetValue (ifcfg, "HWADDR", NULL, FALSE); + device_mac = nm_setting_wireless_get_mac_address (s_wireless); + if (device_mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + device_mac->data[0], device_mac->data[1], device_mac->data[2], + device_mac->data[3], device_mac->data[4], device_mac->data[5]); + svSetValue (ifcfg, "HWADDR", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "MACADDR", NULL, FALSE); + cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); + if (cloned_mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2], + cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]); + svSetValue (ifcfg, "MACADDR", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "MTU", NULL, FALSE); + mtu = nm_setting_wireless_get_mtu (s_wireless); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + svSetValue (ifcfg, "MTU", tmp, FALSE); + g_free (tmp); + } + + ssid = nm_setting_wireless_get_ssid (s_wireless); + if (!ssid) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + if (!ssid->len || ssid->len > 32) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + /* If the SSID contains any non-printable characters, we need to use the + * hex notation of the SSID instead. + */ + for (i = 0; i < ssid->len; i++) { + if (!isprint (ssid->data[i])) { + hex_ssid = TRUE; + break; + } + } + + if (hex_ssid) { + GString *str; + + /* Hex SSIDs don't get quoted */ + str = g_string_sized_new (ssid->len * 2 + 3); + g_string_append (str, "0x"); + for (i = 0; i < ssid->len; i++) + g_string_append_printf (str, "%02X", ssid->data[i]); + svSetValue (ifcfg, "ESSID", str->str, TRUE); + g_string_free (str, TRUE); + } else { + /* Printable SSIDs always get quoted */ + memset (buf, 0, sizeof (buf)); + memcpy (buf, ssid->data, ssid->len); + tmp = svEscape (buf); + + /* svEscape will usually quote the string, but just for consistency, + * if svEscape doesn't quote the ESSID, we quote it ourselves. + */ + if (tmp[0] != '"' && tmp[strlen (tmp) - 1] != '"') { + tmp2 = g_strdup_printf ("\"%s\"", tmp); + svSetValue (ifcfg, "ESSID", tmp2, TRUE); + g_free (tmp2); + } else + svSetValue (ifcfg, "ESSID", tmp, TRUE); + g_free (tmp); + } + + mode = nm_setting_wireless_get_mode (s_wireless); + if (!mode || !strcmp (mode, "infrastructure")) { + svSetValue (ifcfg, "MODE", "Managed", FALSE); + } else if (!strcmp (mode, "adhoc")) { + svSetValue (ifcfg, "MODE", "Ad-Hoc", FALSE); + adhoc = TRUE; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Invalid mode '%s' in '%s' setting", + mode, NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + svSetValue (ifcfg, "CHANNEL", NULL, FALSE); + chan = nm_setting_wireless_get_channel (s_wireless); + if (chan) { + tmp = g_strdup_printf ("%u", chan); + svSetValue (ifcfg, "CHANNEL", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "BSSID", NULL, FALSE); + bssid = nm_setting_wireless_get_bssid (s_wireless); + if (bssid) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + bssid->data[0], bssid->data[1], bssid->data[2], + bssid->data[3], bssid->data[4], bssid->data[5]); + svSetValue (ifcfg, "BSSID", tmp, FALSE); + g_free (tmp); + } + + /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security; + * otherwise there's no way to detect WEP vs. open when WEP keys aren't + * saved. + */ + svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE); + svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE); + + if (nm_setting_wireless_get_security (s_wireless)) { + if (!write_wireless_security_setting (connection, ifcfg, adhoc, no_8021x, error)) + return FALSE; + } + + svSetValue (ifcfg, "TYPE", TYPE_WIRELESS, FALSE); + + return TRUE; +} + +static gboolean +write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingWired *s_wired; + const GByteArray *device_mac, *cloned_mac; + char *tmp; + const char *nettype, *portname, *s390_key, *s390_val; + guint32 mtu, num_opts, i; + const GPtrArray *s390_subchannels; + GString *str; + + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + if (!s_wired) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME); + return FALSE; + } + + svSetValue (ifcfg, "HWADDR", NULL, FALSE); + device_mac = nm_setting_wired_get_mac_address (s_wired); + if (device_mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + device_mac->data[0], device_mac->data[1], device_mac->data[2], + device_mac->data[3], device_mac->data[4], device_mac->data[5]); + svSetValue (ifcfg, "HWADDR", tmp, FALSE); + g_free (tmp); + } + + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (cloned_mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2], + cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]); + svSetValue (ifcfg, "MACADDR", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "MTU", NULL, FALSE); + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + svSetValue (ifcfg, "MTU", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "SUBCHANNELS", NULL, FALSE); + s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); + if (s390_subchannels) { + tmp = NULL; + if (s390_subchannels->len == 2) { + tmp = g_strdup_printf ("%s,%s", + (const char *) g_ptr_array_index (s390_subchannels, 0), + (const char *) g_ptr_array_index (s390_subchannels, 1)); + } else if (s390_subchannels->len == 3) { + tmp = g_strdup_printf ("%s,%s,%s", + (const char *) g_ptr_array_index (s390_subchannels, 0), + (const char *) g_ptr_array_index (s390_subchannels, 1), + (const char *) g_ptr_array_index (s390_subchannels, 2)); + } + svSetValue (ifcfg, "SUBCHANNELS", tmp, FALSE); + g_free (tmp); + } + + svSetValue (ifcfg, "NETTYPE", NULL, FALSE); + nettype = nm_setting_wired_get_s390_nettype (s_wired); + if (nettype) + svSetValue (ifcfg, "NETTYPE", nettype, FALSE); + + svSetValue (ifcfg, "PORTNAME", NULL, FALSE); + portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); + if (portname) + svSetValue (ifcfg, "PORTNAME", portname, FALSE); + + svSetValue (ifcfg, "OPTIONS", NULL, FALSE); + num_opts = nm_setting_wired_get_num_s390_options (s_wired); + if (s390_subchannels && num_opts) { + str = g_string_sized_new (30); + for (i = 0; i < num_opts; i++) { + nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); + + /* portname is handled separately */ + if (!strcmp (s390_key, "portname")) + continue; + + if (str->len) + g_string_append_c (str, ' '); + g_string_append_printf (str, "%s=%s", s390_key, s390_val); + } + if (str->len) + svSetValue (ifcfg, "OPTIONS", str->str, FALSE); + g_string_free (str, TRUE); + } + + svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE); + + return TRUE; +} + +static void +write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) +{ + guint32 n, i; + GString *str; + + svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); + svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); + svSetValue (ifcfg, "ONBOOT", + nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no", + FALSE); + + /* Permissions */ + svSetValue (ifcfg, "USERS", NULL, FALSE); + n = nm_setting_connection_get_num_permissions (s_con); + if (n > 0) { + str = g_string_sized_new (n * 20); + + for (i = 0; i < n; i++) { + const char *puser = NULL; + + /* Items separated by space for consistency with eg + * IPV6ADDR_SECONDARIES and DOMAIN. + */ + if (str->len) + g_string_append_c (str, ' '); + + if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) + g_string_append (str, puser); + } + svSetValue (ifcfg, "USERS", str->str, FALSE); + g_string_free (str, TRUE); + } +} + +static gboolean +write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error) +{ + char dest[INET_ADDRSTRLEN]; + char next_hop[INET_ADDRSTRLEN]; + char **route_items; + char *route_contents; + NMIP4Route *route; + guint32 ip, prefix, metric; + guint32 i, num; + gboolean success = FALSE; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (s_ip4 != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + num = nm_setting_ip4_config_get_num_routes (s_ip4); + if (num == 0) { + unlink (filename); + return TRUE; + } + + route_items = g_malloc0 (sizeof (char*) * (num + 1)); + for (i = 0; i < num; i++) { + route = nm_setting_ip4_config_get_route (s_ip4, i); + + memset (dest, 0, sizeof (dest)); + ip = nm_ip4_route_get_dest (route); + inet_ntop (AF_INET, (const void *) &ip, &dest[0], sizeof (dest)); + + prefix = nm_ip4_route_get_prefix (route); + + memset (next_hop, 0, sizeof (next_hop)); + ip = nm_ip4_route_get_next_hop (route); + inet_ntop (AF_INET, (const void *) &ip, &next_hop[0], sizeof (next_hop)); + + metric = nm_ip4_route_get_metric (route); + + route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric); + } + route_items[num] = NULL; + route_contents = g_strjoinv (NULL, route_items); + g_strfreev (route_items); + + if (!g_file_set_contents (filename, route_contents, -1, NULL)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Writing route file '%s' failed", filename); + goto error; + } + + success = TRUE; + +error: + g_free (route_contents); + + return success; +} + +static gboolean +write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingIP4Config *s_ip4; + const char *value; + char *addr_key, *prefix_key, *netmask_key, *gw_key, *metric_key, *tmp; + char *route_path = NULL; + guint32 i, num; + GString *searches; + gboolean success = FALSE; + gboolean fake_ip4 = FALSE; + const char *method = NULL; + + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + if (s_ip4) + method = nm_setting_ip4_config_get_method (s_ip4); + + /* Missing IP4 setting is assumed to be DHCP */ + if (!method) + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + int result; + + /* IPv4 disabled, clear IPv4 related parameters */ + svSetValue (ifcfg, "BOOTPROTO", NULL, FALSE); + for (i = 0; i < 254; i++) { + if (i == 0) { + addr_key = g_strdup ("IPADDR"); + prefix_key = g_strdup ("PREFIX"); + gw_key = g_strdup ("GATEWAY"); + } else { + addr_key = g_strdup_printf ("IPADDR%d", i + 1); + prefix_key = g_strdup_printf ("PREFIX%d", i + 1); + gw_key = g_strdup_printf ("GATEWAY%d", i + 1); + } + + svSetValue (ifcfg, addr_key, NULL, FALSE); + svSetValue (ifcfg, prefix_key, NULL, FALSE); + svSetValue (ifcfg, gw_key, NULL, FALSE); + } + + route_path = utils_get_route_path (ifcfg->fileName); + result = unlink (route_path); + g_free (route_path); + return TRUE; + } + + /* Temporarily create fake IP4 setting if missing; method set to DHCP above */ + if (!s_ip4) { + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + fake_ip4 = TRUE; + } + + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + svSetValue (ifcfg, "BOOTPROTO", "dhcp", FALSE); + else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + svSetValue (ifcfg, "BOOTPROTO", "none", FALSE); + else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + svSetValue (ifcfg, "BOOTPROTO", "autoip", FALSE); + else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + svSetValue (ifcfg, "BOOTPROTO", "shared", FALSE); + + num = nm_setting_ip4_config_get_num_addresses (s_ip4); + for (i = 0; i < 254; i++) { + char buf[INET_ADDRSTRLEN + 1]; + NMIP4Address *addr; + guint32 ip; + + if (i == 0) { + addr_key = g_strdup ("IPADDR"); + prefix_key = g_strdup ("PREFIX"); + gw_key = g_strdup ("GATEWAY"); + } else { + addr_key = g_strdup_printf ("IPADDR%d", i + 1); + prefix_key = g_strdup_printf ("PREFIX%d", i + 1); + gw_key = g_strdup_printf ("GATEWAY%d", i + 1); + } + + if (i >= num) { + svSetValue (ifcfg, addr_key, NULL, FALSE); + svSetValue (ifcfg, prefix_key, NULL, FALSE); + svSetValue (ifcfg, gw_key, NULL, FALSE); + } else { + addr = nm_setting_ip4_config_get_address (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_address_get_address (addr); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (ifcfg, addr_key, &buf[0], FALSE); + + tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr)); + svSetValue (ifcfg, prefix_key, tmp, FALSE); + g_free (tmp); + + if (nm_ip4_address_get_gateway (addr)) { + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_address_get_gateway (addr); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (ifcfg, gw_key, &buf[0], FALSE); + } else + svSetValue (ifcfg, gw_key, NULL, FALSE); + } + + g_free (addr_key); + g_free (prefix_key); + g_free (gw_key); + } + + num = nm_setting_ip4_config_get_num_dns (s_ip4); + for (i = 0; i < 254; i++) { + char buf[INET_ADDRSTRLEN + 1]; + guint32 ip; + + addr_key = g_strdup_printf ("DNS%d", i + 1); + + if (i >= num) + svSetValue (ifcfg, addr_key, NULL, FALSE); + else { + ip = nm_setting_ip4_config_get_dns (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (ifcfg, addr_key, &buf[0], FALSE); + } + g_free (addr_key); + } + + num = nm_setting_ip4_config_get_num_dns_searches (s_ip4); + if (num > 0) { + searches = g_string_new (NULL); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (searches, ' '); + g_string_append (searches, nm_setting_ip4_config_get_dns_search (s_ip4, i)); + } + svSetValue (ifcfg, "DOMAIN", searches->str, FALSE); + g_string_free (searches, TRUE); + } else + svSetValue (ifcfg, "DOMAIN", NULL, FALSE); + + /* DEFROUTE; remember that it has the opposite meaning from never-default */ + svSetValue (ifcfg, "DEFROUTE", + nm_setting_ip4_config_get_never_default (s_ip4) ? "no" : "yes", + FALSE); + + svSetValue (ifcfg, "PEERDNS", NULL, FALSE); + svSetValue (ifcfg, "PEERROUTES", NULL, FALSE); + svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE); + svSetValue (ifcfg, "DHCP_CLIENT_ID", NULL, FALSE); + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + svSetValue (ifcfg, "PEERDNS", + nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) ? "no" : "yes", + FALSE); + + svSetValue (ifcfg, "PEERROUTES", + nm_setting_ip4_config_get_ignore_auto_routes (s_ip4) ? "no" : "yes", + FALSE); + + value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); + if (value) + svSetValue (ifcfg, "DHCP_HOSTNAME", value, FALSE); + + value = nm_setting_ip4_config_get_dhcp_client_id (s_ip4); + if (value) + svSetValue (ifcfg, "DHCP_CLIENT_ID", value, FALSE); + } + + svSetValue (ifcfg, "IPV4_FAILURE_FATAL", + nm_setting_ip4_config_get_may_fail (s_ip4) ? "no" : "yes", + FALSE); + + /* Static routes - route-<name> file */ + route_path = utils_get_route_path (ifcfg->fileName); + if (!route_path) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not get route file path for '%s'", ifcfg->fileName); + goto out; + } + + if (utils_has_route_file_new_syntax (route_path)) { + shvarFile *routefile; + + g_free (route_path); + routefile = utils_get_route_ifcfg (ifcfg->fileName, TRUE); + if (!routefile) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not create route file '%s'", routefile->fileName); + goto out; + } + + num = nm_setting_ip4_config_get_num_routes (s_ip4); + for (i = 0; i < 256; i++) { + char buf[INET_ADDRSTRLEN]; + NMIP4Route *route; + guint32 ip, metric; + + addr_key = g_strdup_printf ("ADDRESS%d", i); + netmask_key = g_strdup_printf ("NETMASK%d", i); + gw_key = g_strdup_printf ("GATEWAY%d", i); + metric_key = g_strdup_printf ("METRIC%d", i); + + if (i >= num) { + svSetValue (routefile, addr_key, NULL, FALSE); + svSetValue (routefile, netmask_key, NULL, FALSE); + svSetValue (routefile, gw_key, NULL, FALSE); + svSetValue (routefile, metric_key, NULL, FALSE); + } else { + route = nm_setting_ip4_config_get_route (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_route_get_dest (route); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (routefile, addr_key, &buf[0], FALSE); + + memset (buf, 0, sizeof (buf)); + ip = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route)); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (routefile, netmask_key, &buf[0], FALSE); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_route_get_next_hop (route); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + svSetValue (routefile, gw_key, &buf[0], FALSE); + + memset (buf, 0, sizeof (buf)); + metric = nm_ip4_route_get_metric (route); + if (metric == 0) + svSetValue (routefile, metric_key, NULL, FALSE); + else { + tmp = g_strdup_printf ("%u", metric); + svSetValue (routefile, metric_key, tmp, FALSE); + g_free (tmp); + } + } + + g_free (addr_key); + g_free (netmask_key); + g_free (gw_key); + g_free (metric_key); + } + if (svWriteFile (routefile, 0644)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not update route file '%s'", routefile->fileName); + svCloseFile (routefile); + goto out; + } + svCloseFile (routefile); + } else { + write_route_file_legacy (route_path, s_ip4, error); + g_free (route_path); + if (error && *error) + goto out; + } + + success = TRUE; + +out: + if (fake_ip4) + g_object_unref (s_ip4); + + return success; +} + +static gboolean +write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error) +{ + char dest[INET6_ADDRSTRLEN]; + char next_hop[INET6_ADDRSTRLEN]; + char **route_items; + char *route_contents; + NMIP6Route *route; + const struct in6_addr *ip; + guint32 prefix, metric; + guint32 i, num; + gboolean success = FALSE; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (s_ip6 != NULL, FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + + num = nm_setting_ip6_config_get_num_routes (s_ip6); + if (num == 0) { + unlink (filename); + return TRUE; + } + + route_items = g_malloc0 (sizeof (char*) * (num + 1)); + for (i = 0; i < num; i++) { + route = nm_setting_ip6_config_get_route (s_ip6, i); + + memset (dest, 0, sizeof (dest)); + ip = nm_ip6_route_get_dest (route); + inet_ntop (AF_INET6, (const void *) ip, &dest[0], sizeof (dest)); + + prefix = nm_ip6_route_get_prefix (route); + + memset (next_hop, 0, sizeof (next_hop)); + ip = nm_ip6_route_get_next_hop (route); + inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], sizeof (next_hop)); + + metric = nm_ip6_route_get_metric (route); + + route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric); + } + route_items[num] = NULL; + route_contents = g_strjoinv (NULL, route_items); + g_strfreev (route_items); + + if (!g_file_set_contents (filename, route_contents, -1, NULL)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Writing route6 file '%s' failed", filename); + goto error; + } + + success = TRUE; + +error: + g_free (route_contents); + return success; +} + +static gboolean +write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingIP6Config *s_ip6; + NMSettingIP4Config *s_ip4; + const char *value; + char *addr_key, *prefix; + guint32 i, num, num4; + GString *searches; + char buf[INET6_ADDRSTRLEN]; + NMIP6Address *addr; + const struct in6_addr *ip; + GString *ip_str1, *ip_str2, *ip_ptr; + char *route6_path; + + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (!s_ip6) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME); + return FALSE; + } + + value = nm_setting_ip6_config_get_method (s_ip6); + g_assert (value); + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + svSetValue (ifcfg, "IPV6INIT", "no", FALSE); + svSetValue (ifcfg, "DHCPV6C", NULL, FALSE); + return TRUE; + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); + svSetValue (ifcfg, "IPV6_AUTOCONF", "yes", FALSE); + svSetValue (ifcfg, "DHCPV6C", NULL, FALSE); + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); + svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); + svSetValue (ifcfg, "DHCPV6C", "yes", FALSE); + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); + svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); + svSetValue (ifcfg, "DHCPV6C", NULL, FALSE); + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { + svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); + svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); + svSetValue (ifcfg, "DHCPV6C", NULL, FALSE); + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); + svSetValue (ifcfg, "DHCPV6C", NULL, FALSE); + /* TODO */ + } + + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + /* Write out IP addresses */ + num = nm_setting_ip6_config_get_num_addresses (s_ip6); + + ip_str1 = g_string_new (NULL); + ip_str2 = g_string_new (NULL); + for (i = 0; i < num; i++) { + if (i == 0) + ip_ptr = ip_str1; + else + ip_ptr = ip_str2; + + addr = nm_setting_ip6_config_get_address (s_ip6, i); + ip = nm_ip6_address_get_address (addr); + prefix = g_strdup_printf ("%u", nm_ip6_address_get_prefix (addr)); + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf)); + if (i > 1) + g_string_append_c (ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */ + g_string_append (ip_ptr, buf); + g_string_append_c (ip_ptr, '/'); + g_string_append (ip_ptr, prefix); + g_free (prefix); + + /* We only support gateway for the first IP address for now */ + if (i == 0) { + ip = nm_ip6_address_get_gateway (addr); + inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf)); + svSetValue (ifcfg, "IPV6_DEFAULTGW", buf, FALSE); + } + } + + svSetValue (ifcfg, "IPV6ADDR", ip_str1->str, FALSE); + svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str, FALSE); + g_string_free (ip_str1, TRUE); + g_string_free (ip_str2, TRUE); + } else { + svSetValue (ifcfg, "IPV6ADDR", NULL, FALSE); + svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", NULL, FALSE); + svSetValue (ifcfg, "IPV6_DEFAULTGW", NULL, FALSE); + } + + /* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */ + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */ + num = nm_setting_ip6_config_get_num_dns (s_ip6); + for (i = 0; i < 254; i++) { + addr_key = g_strdup_printf ("DNS%d", i + num4 + 1); + + if (i >= num) + svSetValue (ifcfg, addr_key, NULL, FALSE); + else { + ip = nm_setting_ip6_config_get_dns (s_ip6, i); + + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf)); + svSetValue (ifcfg, addr_key, buf, FALSE); + } + g_free (addr_key); + } + + /* Write out DNS domains - 'DOMAIN' key is shared for both IPv4 and IPv6 domains */ + num = nm_setting_ip6_config_get_num_dns_searches (s_ip6); + if (num > 0) { + char *ip4_domains; + ip4_domains = svGetValue (ifcfg, "DOMAIN", FALSE); + searches = g_string_new (ip4_domains); + for (i = 0; i < num; i++) { + if (searches->len > 0) + g_string_append_c (searches, ' '); + g_string_append (searches, nm_setting_ip6_config_get_dns_search (s_ip6, i)); + } + svSetValue (ifcfg, "DOMAIN", searches->str, FALSE); + g_string_free (searches, TRUE); + g_free (ip4_domains); + } + + /* handle IPV6_DEFROUTE */ + /* IPV6_DEFROUTE has the opposite meaning from 'never-default' */ + if (nm_setting_ip6_config_get_never_default(s_ip6)) + svSetValue (ifcfg, "IPV6_DEFROUTE", "no", FALSE); + else + svSetValue (ifcfg, "IPV6_DEFROUTE", "yes", FALSE); + + svSetValue (ifcfg, "IPV6_PEERDNS", NULL, FALSE); + svSetValue (ifcfg, "IPV6_PEERROUTES", NULL, FALSE); + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + svSetValue (ifcfg, "IPV6_PEERDNS", + nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? "no" : "yes", + FALSE); + + svSetValue (ifcfg, "IPV6_PEERROUTES", + nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? "no" : "yes", + FALSE); + } + + svSetValue (ifcfg, "IPV6_FAILURE_FATAL", + nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes", + FALSE); + + /* Static routes go to route6-<dev> file */ + route6_path = utils_get_route6_path (ifcfg->fileName); + if (!route6_path) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Could not get route6 file path for '%s'", ifcfg->fileName); + goto error; + } + write_route6_file (route6_path, s_ip6, error); + g_free (route6_path); + if (error && *error) + goto error; + + return TRUE; + +error: + return FALSE; +} + +static char * +escape_id (const char *id) +{ + char *escaped = g_strdup (id); + char *p = escaped; + + /* Escape random stuff */ + while (*p) { + if (*p == ' ') + *p = '_'; + else if (*p == '/') + *p = '-'; + else if (*p == '\\') + *p = '-'; + p++; + } + + return escaped; +} + +static gboolean +write_connection (NMConnection *connection, + const char *ifcfg_dir, + const char *filename, + const char *keyfile, + char **out_filename, + GError **error) +{ + NMSettingConnection *s_con; + NMSettingIP6Config *s_ip6; + gboolean success = FALSE; + shvarFile *ifcfg = NULL; + char *ifcfg_name = NULL; + const char *type; + gboolean no_8021x = FALSE; + gboolean wired = FALSE; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + if (!s_con) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing '%s' setting", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + if (filename) { + /* For existing connections, 'filename' should be full path to ifcfg file */ + ifcfg = svNewFile (filename); + ifcfg_name = g_strdup (filename); + } else { + char *escaped; + + escaped = escape_id (nm_setting_connection_get_id (s_con)); + ifcfg_name = g_strdup_printf ("%s/ifcfg-%s", ifcfg_dir, escaped); + + /* If a file with this path already exists then we need another name. + * Multiple connections can have the same ID (ie if two connections with + * the same ID are visible to different users) but of course can't have + * the same path. + */ + if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS)) { + guint32 idx = 0; + + g_free (ifcfg_name); + while (idx++ < 500) { + ifcfg_name = g_strdup_printf ("%s/ifcfg-%s %u", ifcfg_dir, escaped, idx); + if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS) == FALSE) + break; + g_free (ifcfg_name); + ifcfg_name = NULL; + } + } + g_free (escaped); + + if (ifcfg_name == NULL) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to find usable ifcfg file name"); + return FALSE; + } + + ifcfg = svCreateFile (ifcfg_name); + } + + if (!ifcfg) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to open/create ifcfg file '%s'", ifcfg_name); + goto out; + } + + type = nm_setting_connection_get_connection_type (s_con); + if (!type) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Missing connection type!"); + goto out; + } + + if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { + // FIXME: can't write PPPoE at this time + if (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Can't write connection type '%s'", + NM_SETTING_PPPOE_SETTING_NAME); + goto out; + } + + if (!write_wired_setting (connection, ifcfg, error)) + goto out; + wired = TRUE; + } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + if (!write_wireless_setting (connection, ifcfg, &no_8021x, error)) + goto out; + } else { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Can't write connection type '%s'", type); + goto out; + } + + if (!no_8021x) { + if (!write_8021x_setting (connection, ifcfg, wired, error)) + goto out; + } + + if (!write_ip4_setting (connection, ifcfg, error)) + goto out; + + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (s_ip6) { + if (!write_ip6_setting (connection, ifcfg, error)) + goto out; + } + + write_connection_setting (s_con, ifcfg); + + if (svWriteFile (ifcfg, 0644)) { + g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + "Can't write connection '%s'", ifcfg->fileName); + goto out; + } + + /* Only return the filename if this was a newly written ifcfg */ + if (out_filename && !filename) + *out_filename = g_strdup (ifcfg_name); + + success = TRUE; + +out: + if (ifcfg) + svCloseFile (ifcfg); + g_free (ifcfg_name); + return success; +} + +gboolean +writer_new_connection (NMConnection *connection, + const char *ifcfg_dir, + char **out_filename, + GError **error) +{ + return write_connection (connection, ifcfg_dir, NULL, NULL, out_filename, error); +} + +gboolean +writer_update_connection (NMConnection *connection, + const char *ifcfg_dir, + const char *filename, + const char *keyfile, + GError **error) +{ + return write_connection (connection, ifcfg_dir, filename, keyfile, NULL, error); +} + diff --git a/src/settings/plugins/ifcfg-rh/writer.h b/src/settings/plugins/ifcfg-rh/writer.h new file mode 100644 index 00000000..edeac0cc --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/writer.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2009 Red Hat, Inc. + */ + +#ifndef _WRITER_H_ +#define _WRITER_H_ + +#include <sys/types.h> +#include <glib.h> +#include <nm-connection.h> + +gboolean writer_new_connection (NMConnection *connection, + const char *ifcfg_dir, + char **out_filename, + GError **error); + +gboolean writer_update_connection (NMConnection *connection, + const char *ifcfg_dir, + const char *filename, + const char *keyfile, + GError **error); + +#endif /* _WRITER_H_ */ diff --git a/src/settings/plugins/ifcfg-suse/Makefile.am b/src/settings/plugins/ifcfg-suse/Makefile.am new file mode 100644 index 00000000..3db8ed31 --- /dev/null +++ b/src/settings/plugins/ifcfg-suse/Makefile.am @@ -0,0 +1,26 @@ + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la + +libnm_settings_plugin_ifcfg_suse_la_SOURCES = \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -I${top_srcdir}/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifcfg_suse_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GIO_LIBS) + diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in new file mode 100644 index 00000000..2a8a1639 --- /dev/null +++ b/src/settings/plugins/ifcfg-suse/Makefile.in @@ -0,0 +1,672 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ifcfg-suse +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libnm_settings_plugin_ifcfg_suse_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS = \ + libnm_settings_plugin_ifcfg_suse_la-plugin.lo +libnm_settings_plugin_ifcfg_suse_la_OBJECTS = \ + $(am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnm_settings_plugin_ifcfg_suse_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_ifcfg_suse_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libnm_settings_plugin_ifcfg_suse_la_SOURCES) +DIST_SOURCES = $(libnm_settings_plugin_ifcfg_suse_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la +libnm_settings_plugin_ifcfg_suse_la_SOURCES = \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -I${top_srcdir}/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifcfg_suse_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GIO_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libnm-settings-plugin-ifcfg-suse.la: $(libnm_settings_plugin_ifcfg_suse_la_OBJECTS) $(libnm_settings_plugin_ifcfg_suse_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_ifcfg_suse_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifcfg_suse_la_OBJECTS) $(libnm_settings_plugin_ifcfg_suse_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libnm_settings_plugin_ifcfg_suse_la-plugin.lo: plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_suse_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Tpo -c -o libnm_settings_plugin_ifcfg_suse_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifcfg_suse_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_suse_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkglibLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifcfg-suse/plugin.c b/src/settings/plugins/ifcfg-suse/plugin.c new file mode 100644 index 00000000..78db56e5 --- /dev/null +++ b/src/settings/plugins/ifcfg-suse/plugin.c @@ -0,0 +1,322 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service + * + * Søren Sandmann <sandmann@daimi.au.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2008 Novell, Inc. + */ + +#include <config.h> +#include <string.h> + +#include <gmodule.h> +#include <glib-object.h> +#include <gio/gio.h> + +#include "plugin.h" +#include "nm-system-config-interface.h" + +#define IFCFG_PLUGIN_NAME "ifcfg-suse" +#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list." +#define IFCFG_DIR SYSCONFDIR "/sysconfig/network" +#define CONF_DHCP IFCFG_DIR "/dhcp" +#define HOSTNAME_FILE "/etc/HOSTNAME" + +static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); + +G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) + +#define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate)) + + +#define IFCFG_FILE_PATH_TAG "ifcfg-file-path" + +typedef struct { + GFileMonitor *hostname_monitor; + GFileMonitor *dhcp_monitor; + char *hostname; +} SCPluginIfcfgPrivate; + +GQuark +ifcfg_plugin_error_quark (void) +{ + static GQuark error_quark = 0; + + if (G_UNLIKELY (error_quark == 0)) + error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark"); + + return error_quark; +} + +typedef void (*FileChangedFn) (gpointer user_data); + +typedef struct { + FileChangedFn callback; + gpointer user_data; +} FileMonitorInfo; + +static void +file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + FileMonitorInfo *info; + + switch (event_type) { + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + case G_FILE_MONITOR_EVENT_DELETED: + info = (FileMonitorInfo *) user_data; + info->callback (info->user_data); + break; + default: + break; + } +} + +static GFileMonitor * +monitor_file_changes (const char *filename, + FileChangedFn callback, + gpointer user_data) +{ + GFile *file; + GFileMonitor *monitor; + FileMonitorInfo *info; + + file = g_file_new_for_path (filename); + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); + + if (monitor) { + info = g_new0 (FileMonitorInfo, 1); + info->callback = callback; + info->user_data = user_data; + g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, info); + g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), info); + } + + return monitor; +} + +static gboolean +hostname_is_dynamic (void) +{ + GIOChannel *channel; + const char *pattern = "DHCLIENT_SET_HOSTNAME="; + char *str = NULL; + int pattern_len; + gboolean dynamic = FALSE; + + channel = g_io_channel_new_file (CONF_DHCP, "r", NULL); + if (!channel) + return dynamic; + + pattern_len = strlen (pattern); + + while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) { + if (!strncmp (str, pattern, pattern_len)) { + if (!strncmp (str + pattern_len, "\"yes\"", 5)) + dynamic = TRUE; + break; + } + g_free (str); + } + + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + + return dynamic; +} + +static char * +hostname_read () +{ + GIOChannel *channel; + char *hostname = NULL; + + channel = g_io_channel_new_file (HOSTNAME_FILE, "r", NULL); + if (channel) { + g_io_channel_read_line (channel, &hostname, NULL, NULL, NULL); + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + + if (hostname) + hostname = g_strchomp (hostname); + } + + return hostname; +} + +static void +hostname_changed (gpointer data) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (data); + + g_free (priv->hostname); + if (hostname_is_dynamic ()) + priv->hostname = NULL; + else + priv->hostname = hostname_read (); + + g_object_notify (G_OBJECT (data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + GIOChannel *channel; + + channel = g_io_channel_new_file (HOSTNAME_FILE, "w", NULL); + if (channel) { + g_io_channel_write_chars (channel, hostname, -1, NULL, NULL); + g_io_channel_write_chars (channel, "\n", -1, NULL, NULL); + g_io_channel_shutdown (channel, TRUE, NULL); + g_io_channel_unref (channel); + } + + g_free (priv->hostname); + priv->hostname = g_strdup (hostname); +} + +static void +init (NMSystemConfigInterface *config) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config); + + priv->hostname_monitor = monitor_file_changes (HOSTNAME_FILE, hostname_changed, config); + priv->dhcp_monitor = monitor_file_changes (CONF_DHCP, hostname_changed, config); + + if (!hostname_is_dynamic ()) + priv->hostname = hostname_read (); +} + +static void +sc_plugin_ifcfg_init (SCPluginIfcfg *self) +{ +} + +static void +dispose (GObject *object) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object); + + if (priv->dhcp_monitor) + g_object_unref (priv->dhcp_monitor); + + if (priv->hostname_monitor) + g_object_unref (priv->hostname_monitor); + + g_free (priv->hostname); + + G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, IFCFG_PLUGIN_NAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, IFCFG_PLUGIN_INFO); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + g_value_set_string (value, SC_PLUGIN_IFCFG_GET_PRIVATE (object)->hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + const char *hostname; + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + hostname = g_value_get_string (value); + if (hostname && strlen (hostname) < 1) + hostname = NULL; + plugin_set_hostname (SC_PLUGIN_IFCFG (object), hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class) +{ + /* interface implementation */ + system_config_interface_class->init = init; +} + +G_MODULE_EXPORT GObject * +nm_system_config_factory (void) +{ + static SCPluginIfcfg *singleton = NULL; + + if (!singleton) + singleton = SC_PLUGIN_IFCFG (g_object_new (SC_TYPE_PLUGIN_IFCFG, NULL)); + else + g_object_ref (singleton); + + return G_OBJECT (singleton); +} diff --git a/src/settings/plugins/ifcfg-suse/plugin.h b/src/settings/plugins/ifcfg-suse/plugin.h new file mode 100644 index 00000000..97840595 --- /dev/null +++ b/src/settings/plugins/ifcfg-suse/plugin.h @@ -0,0 +1,52 @@ +/* NetworkManager system settings service + * + * Søren Sandmann <sandmann@daimi.au.dk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 Red Hat, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <glib-object.h> + +#define PLUGIN_NAME "ifcfg-suse" + +#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ()) +#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg)) +#define SC_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass)) +#define SC_IS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG)) +#define SC_IS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG)) +#define SC_PLUGIN_IFCFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass)) + +typedef struct _SCPluginIfcfg SCPluginIfcfg; +typedef struct _SCPluginIfcfgClass SCPluginIfcfgClass; + +struct _SCPluginIfcfg { + GObject parent; +}; + +struct _SCPluginIfcfgClass { + GObjectClass parent; +}; + +GType sc_plugin_ifcfg_get_type (void); + +GQuark ifcfg_plugin_error_quark (void); + +#endif /* _PLUGIN_H_ */ + diff --git a/src/settings/plugins/ifnet/Makefile.am b/src/settings/plugins/ifnet/Makefile.am new file mode 100644 index 00000000..9bf8a79a --- /dev/null +++ b/src/settings/plugins/ifnet/Makefile.am @@ -0,0 +1,57 @@ +SUBDIRS = . tests +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la + +noinst_LTLIBRARIES = lib-ifnet-io.la + +libnm_settings_plugin_ifnet_la_SOURCES = \ + nm-ifnet-connection.c \ + nm-ifnet-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifnet_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version + +libnm_settings_plugin_ifnet_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + lib-ifnet-io.la\ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GUDEV_LIBS) \ + $(GIO_LIBS) + +lib_ifnet_io_la_SOURCES = \ + net_parser.c\ + net_parser.h\ + connection_parser.c \ + connection_parser.h \ + net_utils.h\ + net_utils.c\ + wpa_parser.h\ + wpa_parser.c + +lib_ifnet_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +lib_ifnet_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS)\ + $(GIO_LIBS) diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in new file mode 100644 index 00000000..793258f7 --- /dev/null +++ b/src/settings/plugins/ifnet/Makefile.in @@ -0,0 +1,922 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ifnet +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +lib_ifnet_io_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_lib_ifnet_io_la_OBJECTS = lib_ifnet_io_la-net_parser.lo \ + lib_ifnet_io_la-connection_parser.lo \ + lib_ifnet_io_la-net_utils.lo lib_ifnet_io_la-wpa_parser.lo +lib_ifnet_io_la_OBJECTS = $(am_lib_ifnet_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnm_settings_plugin_ifnet_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la lib-ifnet-io.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libnm_settings_plugin_ifnet_la_OBJECTS = \ + libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo \ + libnm_settings_plugin_ifnet_la-plugin.lo +libnm_settings_plugin_ifnet_la_OBJECTS = \ + $(am_libnm_settings_plugin_ifnet_la_OBJECTS) +libnm_settings_plugin_ifnet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_ifnet_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(lib_ifnet_io_la_SOURCES) \ + $(libnm_settings_plugin_ifnet_la_SOURCES) +DIST_SOURCES = $(lib_ifnet_io_la_SOURCES) \ + $(libnm_settings_plugin_ifnet_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la +noinst_LTLIBRARIES = lib-ifnet-io.la +libnm_settings_plugin_ifnet_la_SOURCES = \ + nm-ifnet-connection.c \ + nm-ifnet-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifnet_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifnet_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + lib-ifnet-io.la\ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GUDEV_LIBS) \ + $(GIO_LIBS) + +lib_ifnet_io_la_SOURCES = \ + net_parser.c\ + net_parser.h\ + connection_parser.c \ + connection_parser.h \ + net_utils.h\ + net_utils.c\ + wpa_parser.h\ + wpa_parser.c + +lib_ifnet_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +lib_ifnet_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS)\ + $(GIO_LIBS) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +lib-ifnet-io.la: $(lib_ifnet_io_la_OBJECTS) $(lib_ifnet_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lib_ifnet_io_la_OBJECTS) $(lib_ifnet_io_la_LIBADD) $(LIBS) +libnm-settings-plugin-ifnet.la: $(libnm_settings_plugin_ifnet_la_OBJECTS) $(libnm_settings_plugin_ifnet_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_ifnet_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifnet_la_OBJECTS) $(libnm_settings_plugin_ifnet_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-connection_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-net_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-net_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-wpa_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +lib_ifnet_io_la-net_parser.lo: net_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-net_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-net_parser.Tpo -c -o lib_ifnet_io_la-net_parser.lo `test -f 'net_parser.c' || echo '$(srcdir)/'`net_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-net_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-net_parser.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='net_parser.c' object='lib_ifnet_io_la-net_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-net_parser.lo `test -f 'net_parser.c' || echo '$(srcdir)/'`net_parser.c + +lib_ifnet_io_la-connection_parser.lo: connection_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-connection_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-connection_parser.Tpo -c -o lib_ifnet_io_la-connection_parser.lo `test -f 'connection_parser.c' || echo '$(srcdir)/'`connection_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-connection_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-connection_parser.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='connection_parser.c' object='lib_ifnet_io_la-connection_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-connection_parser.lo `test -f 'connection_parser.c' || echo '$(srcdir)/'`connection_parser.c + +lib_ifnet_io_la-net_utils.lo: net_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-net_utils.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-net_utils.Tpo -c -o lib_ifnet_io_la-net_utils.lo `test -f 'net_utils.c' || echo '$(srcdir)/'`net_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-net_utils.Tpo $(DEPDIR)/lib_ifnet_io_la-net_utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='net_utils.c' object='lib_ifnet_io_la-net_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-net_utils.lo `test -f 'net_utils.c' || echo '$(srcdir)/'`net_utils.c + +lib_ifnet_io_la-wpa_parser.lo: wpa_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-wpa_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Tpo -c -o lib_ifnet_io_la-wpa_parser.lo `test -f 'wpa_parser.c' || echo '$(srcdir)/'`wpa_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wpa_parser.c' object='lib_ifnet_io_la-wpa_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-wpa_parser.lo `test -f 'wpa_parser.c' || echo '$(srcdir)/'`wpa_parser.c + +libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo: nm-ifnet-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Tpo -c -o libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo `test -f 'nm-ifnet-connection.c' || echo '$(srcdir)/'`nm-ifnet-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifnet-connection.c' object='libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo `test -f 'nm-ifnet-connection.c' || echo '$(srcdir)/'`nm-ifnet-connection.c + +libnm_settings_plugin_ifnet_la-plugin.lo: plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifnet_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Tpo -c -o libnm_settings_plugin_ifnet_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifnet_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifnet_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pkglibLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkglibLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-pkglibLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c new file mode 100644 index 00000000..982f94f9 --- /dev/null +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -0,0 +1,3069 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "config.h" + +#include <string.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <netinet/ether.h> +#include <errno.h> +#include <ctype.h> +#include <glib/gi18n.h> + +#include <nm-setting-connection.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-ppp.h> +#include <nm-setting-pppoe.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-8021x.h> +#include <nm-system-config-interface.h> +#include <nm-utils.h> + +#include "net_utils.h" +#include "wpa_parser.h" +#include "connection_parser.h" +#include "nm-ifnet-connection.h" + +static const char * +get_prefix (void) +{ + return _("System"); +} + +static void +update_connection_id (NMConnection *connection, const char *conn_name) +{ + gchar *idstr = NULL; + gchar *uuid_base = NULL; + gchar *uuid = NULL; + int name_len; + NMSettingConnection *setting; + + name_len = strlen (conn_name); + if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { + gchar * conn_name_printable = utils_hexstr2bin (conn_name + 2, name_len - 2); + idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name_printable); + g_free (conn_name_printable); + } else + idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name); + uuid_base = idstr; + uuid = nm_utils_uuid_generate_from_string (uuid_base); + setting = + (NMSettingConnection *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_CONNECTION); + g_object_set (setting, NM_SETTING_CONNECTION_ID, idstr, + NM_SETTING_CONNECTION_UUID, uuid, NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "update_connection_setting_from_config_block: name:%s, id:%s, uuid: %s", + conn_name, idstr, uuid); + + g_free (uuid); + g_free (idstr); +} + +static gboolean eap_simple_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + +static gboolean eap_tls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + +static gboolean eap_peap_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + +static gboolean eap_ttls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + +typedef struct { + const char *method; + gboolean (*reader) (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + gboolean wifi_phase2_only; +} EAPReader; + +static EAPReader eap_readers[] = { + {"md5", eap_simple_reader, TRUE}, + {"pap", eap_simple_reader, TRUE}, + {"chap", eap_simple_reader, TRUE}, + {"mschap", eap_simple_reader, TRUE}, + {"mschapv2", eap_simple_reader, TRUE}, + {"leap", eap_simple_reader, TRUE}, + {"tls", eap_tls_reader, FALSE}, + {"peap", eap_peap_reader, FALSE}, + {"ttls", eap_ttls_reader, FALSE}, + {NULL, NULL} +}; + +/* reading identity and password */ +static gboolean +eap_simple_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + const char *value; + + /* identity */ + value = wpa_get_value (ssid, "identity"); + if (!value) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + + /* password */ + value = wpa_get_value (ssid, "password"); + if (!value) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", + eap_method); + return FALSE; + } + + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + + return TRUE; +} + +static gboolean +eap_tls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + const char *value; + const char *ca_cert = NULL; + const char *client_cert = NULL; + const char *privkey = NULL; + const char *privkey_password = NULL; + gboolean success = FALSE; + NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + + /* identity */ + value = wpa_get_value (ssid, "identity"); + if (!value) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + + /* ca cert */ + ca_cert = wpa_get_value (ssid, phase2 ? "ca_cert2" : "ca_cert"); + if (ca_cert) { + if (phase2) { + if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } + } else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: missing %s for EAP" + " method '%s'; this is insecure!", + phase2 ? "IEEE_8021X_INNER_CA_CERT" : + "IEEE_8021X_CA_CERT", eap_method); + } + + /* Private key password */ + privkey_password = wpa_get_value (ssid, + phase2 ? "private_key_passwd2" : + "private_key_passwd"); + + if (!privkey_password) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : + "IEEE_8021X_PRIVATE_KEY_PASSWORD", eap_method); + goto done; + } + + /* The private key itself */ + privkey = wpa_get_value (ssid, phase2 ? "private_key2" : "private_key"); + if (!privkey) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : + "IEEE_8021X_PRIVATE_KEY", eap_method); + goto done; + } + + if (phase2) { + if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, + privkey, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_private_key (s_8021x, + privkey, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, error)) + goto done; + } + + /* Only set the client certificate if the private key is not PKCS#12 format, + * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, + * then nm_setting_802_1x_set_private_key() already set the client certificate + * to the same value as the private key. + */ + if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY + || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { + client_cert = wpa_get_value (ssid, + phase2 ? "client_cert2" : + "client_cert"); + if (!client_cert) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : + "IEEE_8021X_CLIENT_CERT", eap_method); + goto done; + } + + if (phase2) { + if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, + client_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_client_cert (s_8021x, + client_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } + } + + success = TRUE; + +done: + return success; +} + +static gboolean +eap_peap_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + const char *ca_cert = NULL; + const char *inner_auth = NULL; + const char *peapver = NULL; + char **list = NULL, **iter, *lower; + gboolean success = FALSE; + + ca_cert = wpa_get_value (ssid, "ca_cert"); + if (ca_cert) { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: missing " + "IEEE_8021X_CA_CERT for EAP method '%s'; this is" + " insecure!", eap_method); + } + + peapver = wpa_get_value (ssid, "phase1"); + /* peap version, default is automatic */ + if (peapver && strstr (peapver, "peapver")) { + if (strstr (peapver, "peapver=0")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, + "0", NULL); + else if (strstr (peapver, "peapver=1")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, + "1", NULL); + else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown IEEE_8021X_PEAP_VERSION value '%s'", + peapver); + goto done; + } + } + + /* peaplabel */ + if (peapver && strstr (peapver, "peaplabel=1")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", + NULL); + + inner_auth = wpa_get_value (ssid, "phase2"); + if (!inner_auth) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + /* Handle options for the inner auth method */ + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + gchar *pos = NULL; + + if (!strlen (*iter)) + continue; + + if (!(pos = strstr (*iter, "MSCHAPV2")) + || !(pos = strstr (*iter, "MD5")) + || !(pos = strstr (*iter, "GTC"))) { + if (!eap_simple_reader + (pos, ssid, s_8021x, TRUE, error)) + goto done; + } else if (!(pos = strstr (*iter, "TLS"))) { + if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error)) + goto done; + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + + pos = strchr (*iter, '='); + pos++; + lower = g_ascii_strdown (pos, -1); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, + NULL); + g_free (lower); + break; + } + + if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "No valid IEEE_8021X_INNER_AUTH_METHODS found."); + goto done; + } + + success = TRUE; + +done: + if (list) + g_strfreev (list); + return success; +} + +static gboolean +eap_ttls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) +{ + gboolean success = FALSE; + const char *anon_ident = NULL; + const char *ca_cert = NULL; + const char *tmp; + char **list = NULL, **iter, *inner_auth = NULL; + + /* ca cert */ + ca_cert = wpa_get_value (ssid, "ca_cert"); + if (ca_cert) { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: missing " + "IEEE_8021X_CA_CERT for EAP method '%s'; this is" + " insecure!", eap_method); + } + + /* anonymous indentity for tls */ + anon_ident = wpa_get_value (ssid, "anonymous_identity"); + if (anon_ident && strlen (anon_ident)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + anon_ident, NULL); + + tmp = wpa_get_value (ssid, "phase2"); + if (!tmp) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + + /* Handle options for the inner auth method */ + inner_auth = g_ascii_strdown (tmp, -1); + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + gchar *pos = NULL; + + if (!strlen (*iter)) + continue; + if ((pos = strstr (*iter, "mschapv2")) != NULL + || (pos = strstr (*iter, "mschap")) != NULL + || (pos = strstr (*iter, "pap")) != NULL + || (pos = strstr (*iter, "chap")) != NULL) { + if (!eap_simple_reader + (pos, ssid, s_8021x, TRUE, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, + pos, NULL); + } else if ((pos = strstr (*iter, "tls")) != NULL) { + if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, + "tls", NULL); + } else if ((pos = strstr (*iter, "mschapv2")) != NULL + || (pos = strstr (*iter, "md5")) != NULL) { + if (!eap_simple_reader + (pos, ssid, s_8021x, TRUE, error)) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "SIMPLE ERROR"); + goto done; + } + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, + pos, NULL); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + break; + } + + success = TRUE; +done: + if (list) + g_strfreev (list); + g_free (inner_auth); + return success; +} + +/* type is already decided by net_parser, this function is just used to + * doing tansformation*/ +static const gchar * +guess_connection_type (const char *conn_name) +{ + const gchar *type = ifnet_get_data (conn_name, "type"); + const gchar *ret_type = NULL; + + if (!g_strcmp0 (type, "ppp")) + ret_type = NM_SETTING_PPPOE_SETTING_NAME; + + if (!g_strcmp0 (type, "wireless")) + ret_type = NM_SETTING_WIRELESS_SETTING_NAME; + + if (!ret_type) + ret_type = NM_SETTING_WIRED_SETTING_NAME; + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "guessed connection type (%s) = %s", conn_name, ret_type); + return ret_type; +} + +/* Reading mac address for setting connection option. + * Unmanaged device mac address is required by NetworkManager*/ +static gboolean +read_mac_address (const char *conn_name, GByteArray **array, GError **error) +{ + const char *value = ifnet_get_data (conn_name, "mac"); + struct ether_addr *mac; + + if (!value || !strlen (value)) + return TRUE; + + mac = ether_aton (value); + if (!mac) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "The MAC address '%s' was invalid.", value); + return FALSE; + } + + *array = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); + return TRUE; +} + +static void +make_wired_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + GByteArray *mac = NULL; + NMSettingWired *s_wired = NULL; + const char *value = NULL; + + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + + /* mtu_xxx */ + value = ifnet_get_data (conn_name, "mtu"); + if (value) { + long int mtu; + + errno = 0; + mtu = strtol (value, NULL, 10); + if (errno || mtu < 0 || mtu > 65535) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: invalid MTU '%s' for %s", + value, conn_name); + } else + g_object_set (s_wired, NM_SETTING_WIRED_MTU, + (guint32) mtu, NULL); + } + + if (read_mac_address (conn_name, &mac, error)) { + if (mac) { + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, + mac, NULL); + g_byte_array_free (mac, TRUE); + } + } else { + g_object_unref (s_wired); + s_wired = NULL; + } + if (s_wired) + nm_connection_add_setting (connection, NM_SETTING (s_wired)); +} + +/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, + * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/ +static void +make_ip4_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + + NMSettingIP4Config *ip4_setting = + NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + const char *value, *method; + gboolean is_static_block = is_static_ip4 (conn_name); + ip_block *iblock = NULL; + + /* set dhcp options (dhcp_xxx) */ + value = ifnet_get_data (conn_name, "dhcp"); + g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, value + && strstr (value, "nodns") ? TRUE : FALSE, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, value + && strstr (value, "nogateway") ? TRUE : FALSE, NULL); + + if (!is_static_block) { + method = ifnet_get_data (conn_name, "config"); + if (!method){ + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown config for %s", conn_name); + g_object_unref (ip4_setting); + return; + } + if (!strcmp (method, "dhcp")) + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + else if (!strcmp (method, "autoip")){ + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); + return; + } else if (!strcmp (method, "shared")){ + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); + return; + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown config for %s", conn_name); + g_object_unref (ip4_setting); + return; + } + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Using %s method for %s", + method, conn_name); + }else { + iblock = convert_ip4_config_block (conn_name); + if (!iblock) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Ifnet plugin: can't aquire ip configuration for %s", + conn_name); + g_object_unref (ip4_setting); + return; + } + /************** add all ip settings to the connection**********/ + while (iblock) { + ip_block *current_iblock; + NMIP4Address *ip4_addr = nm_ip4_address_new (); + + nm_ip4_address_set_address (ip4_addr, iblock->ip); + nm_ip4_address_set_prefix (ip4_addr, + nm_utils_ip4_netmask_to_prefix + (iblock->netmask)); + /* currently all the IPs has the same gateway */ + nm_ip4_address_set_gateway (ip4_addr, iblock->gateway); + if (iblock->gateway) + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, NULL); + if (!nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignoring duplicate IP4 address"); + nm_ip4_address_unref (ip4_addr); + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + + } + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), + NULL); + } + + /* add dhcp hostname and client id */ + if (!is_static_block && !strcmp (method, "dhcp")) { + gchar *dhcp_hostname, *client_id; + + get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); + if (dhcp_hostname) { + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, + dhcp_hostname, NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "DHCP hostname: %s", + dhcp_hostname); + g_free (dhcp_hostname); + } + if (client_id) { + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, + client_id, NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "DHCP client id: %s", + client_id); + g_free (client_id); + } + } + + /* add all IPv4 dns servers, IPv6 servers will be ignored */ + set_ip4_dns_servers (ip4_setting, conn_name); + + /* DNS searches */ + value = ifnet_get_data (conn_name, "dns_search"); + if (value) { + char *stripped = g_strdup (value); + char **searches = NULL; + + strip_string (stripped, '"'); + + searches = g_strsplit (stripped, " ", 0); + if (searches) { + char **item; + + for (item = searches; *item; item++) { + if (strlen (*item)) { + if (!nm_setting_ip4_config_add_dns_search (ip4_setting, *item)) + PLUGIN_WARN + (IFNET_PLUGIN_NAME, + " warning: duplicate DNS domain '%s'", + *item); + } + } + g_strfreev (searches); + } + } + + /* static routes */ + iblock = convert_ip4_routes_block (conn_name); + while (iblock) { + ip_block *current_iblock = iblock; + const char *metric_str; + char *stripped; + long int metric; + NMIP4Route *route = nm_ip4_route_new (); + + nm_ip4_route_set_dest (route, iblock->ip); + nm_ip4_route_set_next_hop (route, iblock->gateway); + nm_ip4_route_set_prefix (route, + nm_utils_ip4_netmask_to_prefix + (iblock->netmask)); + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { + metric = strtol (metric_str, NULL, 10); + nm_ip4_route_set_metric (route, (guint32) metric); + } else { + metric_str = ifnet_get_global_data ("metric"); + if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); + metric = strtol (metric_str, NULL, 10); + nm_ip4_route_set_metric (route, + (guint32) metric); + g_free (stripped); + } + } + + if (!nm_setting_ip4_config_add_route (ip4_setting, route)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "warning: duplicate IP4 route"); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "new IP4 route:%d\n", iblock->ip); + + nm_ip4_route_unref (route); + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + } + + /* Finally add setting to connection */ + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); +} + +static void +make_ip6_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingIP6Config *s_ip6 = NULL; + gboolean is_static_block = is_static_ip6 (conn_name); + + // used to disable IPv6 + gboolean ipv6_enabled = FALSE; + gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + const char *value; + ip6_block *iblock; + gboolean never_default = !has_default_ip6_route (conn_name); + + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + if (!s_ip6) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Could not allocate IP6 setting"); + return; + } + + value = ifnet_get_data (conn_name, "enable_ipv6"); + if (value && is_true (value)) + ipv6_enabled = TRUE; + + //FIXME Handle other methods that NM supports in future + // Currently only Manual and DHCP are supported + if (!ipv6_enabled) { + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + goto done; + } else if (!is_static_block) { + // config_eth* contains "dhcp6" + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + never_default = FALSE; + } + // else if (!has_ip6_address(conn_name)) + // doesn't have "dhcp6" && doesn't have any ipv6 address + // method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + else + // doesn't have "dhcp6" && has at least one ipv6 address + method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "IPv6 for %s enabled, using %s", + conn_name, method); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, method, + NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, FALSE, + NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, FALSE, + NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, NULL); + + /* Make manual settings */ + if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + ip6_block *current_iblock; + + iblock = convert_ip6_config_block (conn_name); + if (!iblock) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Ifnet plugin: can't aquire ip6 configuration for %s", + conn_name); + goto error; + } + /* add all IPv6 addresses */ + while (iblock) { + NMIP6Address *ip6_addr = nm_ip6_address_new (); + + nm_ip6_address_set_address (ip6_addr, iblock->ip); + nm_ip6_address_set_prefix (ip6_addr, iblock->prefix); + if (nm_setting_ip6_config_add_address (s_ip6, ip6_addr)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "ipv6 addresses count: %d", + nm_setting_ip6_config_get_num_addresses + (s_ip6)); + } else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignoring duplicate IP4 address"); + } + nm_ip6_address_unref (ip6_addr); + current_iblock = iblock; + iblock = iblock->next; + destroy_ip6_block (current_iblock); + } + + } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + /* - autoconf or DHCPv6 stuff goes here */ + } + // DNS Servers, set NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS TRUE here + set_ip6_dns_servers (s_ip6, conn_name); + + /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */ + + // Add routes + iblock = convert_ip6_routes_block (conn_name); + if (iblock) + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, NULL); + /* Add all IPv6 routes */ + while (iblock) { + ip6_block *current_iblock = iblock; + const char *metric_str; + char *stripped; + long int metric = 1; + NMIP6Route *route = nm_ip6_route_new (); + + nm_ip6_route_set_dest (route, iblock->ip); + nm_ip6_route_set_next_hop (route, iblock->next_hop); + nm_ip6_route_set_prefix (route, iblock->prefix); + /* metric is not per routes configuration right now + * global metric is also supported (metric="x") */ + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { + metric = strtol (metric_str, NULL, 10); + nm_ip6_route_set_metric (route, (guint32) metric); + } else { + metric_str = ifnet_get_global_data ("metric"); + if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); + metric = strtol (metric_str, NULL, 10); + nm_ip6_route_set_metric (route, + (guint32) metric); + g_free (stripped); + } else + nm_ip6_route_set_metric (route, (guint32) 1); + } + + if (!nm_setting_ip6_config_add_route (s_ip6, route)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: duplicate IP6 route"); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, " info: new IP6 route"); + nm_ip6_route_unref (route); + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip6_block (current_iblock); + } + +done: + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + return; + +error: + g_object_unref (s_ip6); + PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: Ignore IPv6 for %s", + conn_name); + return; +} + +static NMSetting * +make_wireless_connection_setting (const char *conn_name, + NMSetting8021x **s_8021x, + GError **error) +{ + GByteArray *array, *mac = NULL; + NMSettingWireless *wireless_setting = NULL; + gboolean adhoc = FALSE; + const char *value; + const char *type; + + /* PPP over WIFI is not supported yet */ + g_return_val_if_fail (conn_name != NULL + && strcmp (ifnet_get_data (conn_name, "type"), + "ppp") != 0, NULL); + type = ifnet_get_data (conn_name, "type"); + if (strcmp (type, "ppp") == 0) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "PPP over WIFI is not supported yet"); + return NULL; + } + + wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + if (read_mac_address (conn_name, &mac, error)) { + if (mac) { + g_object_set (wireless_setting, + NM_SETTING_WIRELESS_MAC_ADDRESS, mac, + NULL); + g_byte_array_free (mac, TRUE); + + } + } else { + g_object_unref (wireless_setting); + return NULL; + } + + /* handle ssid (hex and ascii) */ + if (conn_name) { + gsize ssid_len = 0, value_len = strlen (conn_name); + const char *p; + char *tmp, *converted = NULL; + + ssid_len = value_len; + if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { + /* Hex representation */ + if (value_len % 2) { + g_set_error (error, ifnet_plugin_error_quark (), + 0, + "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", + conn_name); + goto error; + } + // ignore "0x" + p = conn_name + 2; + if (!is_hex (p)) { + g_set_error (error, + ifnet_plugin_error_quark (), + 0, + "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)", + conn_name, *p); + goto error; + + } + tmp = utils_hexstr2bin (p, value_len - 2); + ssid_len = (value_len - 2) / 2; + converted = g_malloc0 (ssid_len + 1); + memcpy (converted, tmp, ssid_len); + g_free (tmp); + } + + if (ssid_len > 32 || ssid_len == 0) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", + conn_name, ssid_len); + goto error; + } + array = g_byte_array_sized_new (ssid_len); + g_byte_array_append (array, (const guint8 *) (converted ? converted : conn_name), ssid_len); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, array, NULL); + g_byte_array_free (array, TRUE); + g_free (converted); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing SSID"); + goto error; + } + + /* mode=0: infrastructure + * mode=1: adhoc */ + value = wpa_get_value (conn_name, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + if (exist_ssid (conn_name)) { + const char *mode = adhoc ? "adhoc" : "infrastructure"; + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, mode, + NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Using mode: %s", mode); + } + + /* BSSID setting */ + value = wpa_get_value (conn_name, "bssid"); + if (value) { + struct ether_addr *eth; + GByteArray *bssid; + + eth = ether_aton (value); + if (!eth) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid BSSID '%s'", value); + goto error; + } + + bssid = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, + bssid, NULL); + g_byte_array_free (bssid, TRUE); + + } + + /* mtu_ssid="xx" */ + value = ifnet_get_data (conn_name, "mtu"); + if (value) { + long int mtu; + + errno = 0; + mtu = strtol (value, NULL, 10); + if (errno || mtu < 0 || mtu > 50000) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: invalid MTU '%s' for %s", + value, conn_name); + } else + g_object_set (wireless_setting, NM_SETTING_WIRELESS_MTU, + (guint32) mtu, NULL); + + } + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "wireless_setting added for %s", + conn_name); + return NM_SETTING (wireless_setting); +error: + if (wireless_setting) + g_object_unref (wireless_setting); + return NULL; + +} + +static NMSettingWirelessSecurity * +make_leap_setting (const char *ssid, GError **error) +{ + NMSettingWirelessSecurity *wsec; + const char *value; + + wsec = + NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + value = wpa_get_value (ssid, "key_mgmt"); + if (!value || strcmp (value, "IEEE8021X")) + goto error; /* Not LEAP */ + + value = wpa_get_value (ssid, "eap"); + if (!value || strcasecmp (value, "LEAP")) + goto error; /* Not LEAP */ + + value = wpa_get_value (ssid, "password"); + if (value && strlen (value)) + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + value, NULL); + + value = wpa_get_value (ssid, "identity"); + if (!value || !strlen (value)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing LEAP identity"); + goto error; + } + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, + NULL); + + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL); + + return wsec; +error: + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static gboolean +add_one_wep_key (const char *ssid, + const char *key, + int key_idx, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + const char *value; + char *converted = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (ssid != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (key_idx >= 0 && key_idx <= 3, FALSE); + g_return_val_if_fail (s_wsec != NULL, FALSE); + + value = wpa_get_value (ssid, key); + if (!value) + return TRUE; + + /* Validate keys */ + if (strlen (value) == 10 || strlen (value) == 26) { + /* Hexadecimal WEP key */ + if (!is_hex (value)) { + g_set_error (error, ifnet_plugin_error_quark (), + 0, "Invalid hexadecimal WEP key."); + goto out; + } + converted = g_strdup (value); + } else if (value[0] == '"' + && (strlen (value) == 7 || strlen (value) == 15)) { + /* ASCII passphrase */ + char *tmp = g_strdup (value); + char *p = strip_string (tmp, '"'); + + if (!is_ascii (p)) { + g_set_error (error, ifnet_plugin_error_quark (), + 0, "Invalid ASCII WEP passphrase."); + g_free (tmp); + goto out; + + } + + converted = utils_bin2hexstr (tmp, strlen (tmp), strlen (tmp) * 2); + g_free (tmp); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid WEP key length. Key: %s", value); + goto out; + } + + if (converted) { + nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, converted); + g_free (converted); + success = TRUE; + } + +out: + return success; +} + +static gboolean +add_wep_keys (const char *ssid, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + if (!add_one_wep_key (ssid, "wep_key0", 0, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key1", 1, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key2", 2, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key3", 3, s_wsec, error)) + return FALSE; + return TRUE; + +} + +static NMSettingWirelessSecurity * +make_wep_setting (const char *ssid, GError **error) +{ + const char *auth_alg, *value; + int default_key_idx = 0; + NMSettingWirelessSecurity *s_wireless_sec; + + s_wireless_sec = + NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "none", NULL); + + /* default key index */ + value = wpa_get_value (ssid, "wep_tx_keyidx"); + if (value) { + default_key_idx = atoi (value); + if (default_key_idx >= 0 && default_key_idx <= 3) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + default_key_idx, NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "Default key index: %d", default_key_idx); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid default WEP key '%s'", value); + goto error; + } + } + + if (!add_wep_keys (ssid, s_wireless_sec, error)) + goto error; + + /* If there's a default key, ensure that key exists */ + if ((default_key_idx == 1) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Default WEP key index was 2, but no valid KEY2 exists."); + goto error; + } else if ((default_key_idx == 2) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, + 2)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Default WEP key index was 3, but no valid KEY3 exists."); + goto error; + } else if ((default_key_idx == 3) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, + 3)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Default WEP key index was 4, but no valid KEY4 exists."); + goto error; + } + + /* authentication algorithms */ + auth_alg = wpa_get_value (ssid, "auth_alg"); + if (auth_alg) { + if (strcmp (auth_alg, "OPEN") == 0) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "WEP: Use open system authentication"); + } else if (strcmp (auth_alg, "SHARED") == 0) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "shared", NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "WEP: Use shared system authentication"); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid WEP authentication algorithm '%s'", + auth_alg); + goto error; + } + + } + + if (!nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3) + && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) { + if (auth_alg && !strcmp (auth_alg, "shared")) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "WEP Shared Key authentication is invalid for " + "unencrypted connections."); + goto error; + } + /* Unencrypted */ + g_object_unref (s_wireless_sec); + s_wireless_sec = NULL; + } + return s_wireless_sec; + +error: + if (s_wireless_sec) + g_object_unref (s_wireless_sec); + return NULL; +} + +static char * +parse_wpa_psk (const char *psk, GError **error) +{ + char *hashed = NULL; + gboolean quoted = FALSE; + + if (!psk) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing WPA_PSK for WPA-PSK key management"); + return NULL; + } + + /* Passphrase must be between 10 and 66 characters in length becuase WPA + * hex keys are exactly 64 characters (no quoting), and WPA passphrases + * are between 8 and 63 characters (inclusive), plus optional quoting if + * the passphrase contains spaces. + */ + + if (psk[0] == '"' && psk[strlen (psk) - 1] == '"') + quoted = TRUE; + if (!quoted && (strlen (psk) == 64)) { + /* Verify the hex PSK; 64 digits */ + if (!is_hex (psk)) { + g_set_error (error, ifnet_plugin_error_quark (), + 0, + "Invalid WPA_PSK (contains non-hexadecimal characters)"); + goto out; + } + hashed = g_strdup (psk); + } else { + char *stripped = g_strdup (psk); + + strip_string (stripped, '"'); + + /* Length check */ + if (strlen (stripped) < 8 || strlen (stripped) > 63) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid WPA_PSK (passphrases must be between " + "8 and 63 characters long (inclusive))"); + g_free (stripped); + goto out; + } + + hashed = g_strdup (stripped); + g_free (stripped); + } + + if (!hashed) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); + goto out; + } + +out: + return hashed; +} + +static gboolean +fill_wpa_ciphers (const char *ssid, + NMSettingWirelessSecurity *wsec, + gboolean group, + gboolean adhoc) +{ + const char *value; + char **list = NULL, **iter; + int i = 0; + + value = wpa_get_value (ssid, group ? "group" : "pairwise"); + if (!value) + return TRUE; + + list = g_strsplit_set (value, " ", 0); + for (iter = list; iter && *iter; iter++, i++) { + /* Ad-Hoc configurations cannot have pairwise ciphers, and can only + * have one group cipher. Ignore any additional group ciphers and + * any pairwise ciphers specified. + */ + if (adhoc) { + if (group && (i > 0)) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)", + *iter); + continue; + } else if (!group) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)", + *iter); + continue; + } + } + + if (!strcmp (*iter, "CCMP")) { + if (group) + nm_setting_wireless_security_add_group (wsec, + "ccmp"); + else + nm_setting_wireless_security_add_pairwise (wsec, + "ccmp"); + } else if (!strcmp (*iter, "TKIP")) { + if (group) + nm_setting_wireless_security_add_group (wsec, + "tkip"); + else + nm_setting_wireless_security_add_pairwise (wsec, + "tkip"); + } else if (group && !strcmp (*iter, "WEP104")) + nm_setting_wireless_security_add_group (wsec, "wep104"); + else if (group && !strcmp (*iter, "WEP40")) + nm_setting_wireless_security_add_group (wsec, "wep40"); + else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: ignoring invalid %s cipher '%s'", + group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", + *iter); + } + } + + if (list) + g_strfreev (list); + return TRUE; +} + +static NMSetting8021x * +fill_8021x (const char *ssid, + const char *key_mgmt, + gboolean wifi, + GError **error) +{ + NMSetting8021x *s_8021x; + const char *value; + char **list, **iter; + + value = wpa_get_value (ssid, "eap"); + if (!value) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing IEEE_8021X_EAP_METHODS for key management '%s'", + key_mgmt); + return NULL; + } + + list = g_strsplit (value, " ", 0); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + /* Validate and handle each EAP method */ + for (iter = list; iter && *iter; iter++) { + EAPReader *eap = &eap_readers[0]; + gboolean found = FALSE; + char *lower = NULL; + + lower = g_ascii_strdown (*iter, -1); + while (eap->method && !found) { + if (strcmp (eap->method, lower)) + goto next; + + /* Some EAP methods don't provide keying material, thus they + * cannot be used with WiFi unless they are an inner method + * used with TTLS or PEAP or whatever. + */ + if (wifi && eap->wifi_phase2_only) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: ignored invalid " + "IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.", + lower); + goto next; + } + + /* Parse EAP method specific options */ + if (!(*eap->reader) + (lower, ssid, s_8021x, FALSE, error)) { + g_free (lower); + goto error; + } + nm_setting_802_1x_add_eap_method (s_8021x, lower); + found = TRUE; + + next: + eap++; + } + + if (!found) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: ignored unknown" + "IEEE_8021X_EAP_METHOD '%s'.", lower); + } + g_free (lower); + } + g_strfreev (list); + + if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "No valid EAP methods found in IEEE_8021X_EAP_METHODS."); + goto error; + } + + return s_8021x; + +error: + g_object_unref (s_8021x); + return NULL; +} + +static NMSettingWirelessSecurity * +make_wpa_setting (const char *ssid, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSettingWirelessSecurity *wsec; + const char *value; + char *lower; + gboolean adhoc = FALSE; + + if (!exist_ssid (ssid)) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "No security info found for ssid: %s", ssid); + return NULL; + } + + wsec = + NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + /* mode=1: adhoc + * mode=0: infrastructure */ + value = wpa_get_value (ssid, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + value = wpa_get_value (ssid, "key_mgmt"); + /* Not WPA or Dynamic WEP */ + if (!value) + goto error; + if (strcmp (value, "WPA-PSK") && strcmp (value, "WPA-EAP")) + goto error; + /* Pairwise and Group ciphers */ + fill_wpa_ciphers (ssid, wsec, FALSE, adhoc); + fill_wpa_ciphers (ssid, wsec, TRUE, adhoc); + + /* WPA and/or RSN */ + if (adhoc) { + /* Ad-Hoc mode only supports WPA proto for now */ + nm_setting_wireless_security_add_proto (wsec, "wpa"); + } else { + nm_setting_wireless_security_add_proto (wsec, "wpa"); + nm_setting_wireless_security_add_proto (wsec, "rsn"); + + } + + if (!strcmp (value, "WPA-PSK")) { + char *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error); + + if (!psk) + goto error; + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, + NULL); + g_free (psk); + + if (adhoc) + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-none", NULL); + else + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", NULL); + } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { + if (adhoc) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", + value); + goto error; + } + *s_8021x = fill_8021x (ssid, value, TRUE, error); + if (!*s_8021x) + goto error; + + lower = g_ascii_strdown (value, -1); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + lower, NULL); + g_free (lower); + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Unknown wireless KEY_MGMT type '%s'", value); + goto error; + } + return wsec; +error: + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static NMSettingWirelessSecurity * +make_wireless_security_setting (const char *conn_name, + NMSetting8021x **s_8021x, + GError ** error) +{ + NMSettingWirelessSecurity *wsec = NULL; + const char *ssid; + gboolean adhoc = FALSE; + const char *value; + + g_return_val_if_fail (conn_name != NULL + && strcmp (ifnet_get_data (conn_name, "type"), + "ppp") != 0, NULL); + if (!wpa_get_value (conn_name, "ssid")) + return NULL; + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "updating wireless security settings (%s).", conn_name); + + ssid = conn_name; + value = wpa_get_value (ssid, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + if (!adhoc) { + wsec = make_leap_setting (ssid, error); + if (error && *error) + goto error; + } + if (!wsec) { + wsec = make_wpa_setting (ssid, s_8021x, error); + if (error && *error) + goto error; + } + if (!wsec) { + wsec = make_wep_setting (ssid, error); + if (error && *error) + goto error; + } + + if (!wsec) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Can't handle security information for ssid: %s", + conn_name); + } + + return wsec; +error: + return NULL; +} + +/* Currently only support username and password */ +static void +make_pppoe_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingPPPOE *s_pppoe; + NMSettingPPP *s_ppp; + const char *value; + + s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ()); + + /* username */ + value = ifnet_get_data (conn_name, "username"); + if (!value) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "ppp requires at lease a username"); + return; + } + g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, value, NULL); + + /* password */ + value = ifnet_get_data (conn_name, "password"); + if (!value) { + value = ""; + } + + g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, value, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); + + /* PPP setting */ + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); +} + +NMConnection * +ifnet_update_connection_from_config_block (const char *conn_name, GError **error) +{ + const gchar *type = NULL; + NMConnection *connection = NULL; + NMSettingConnection *setting = NULL; + NMSetting8021x *s_8021x = NULL; + NMSettingWirelessSecurity *wsec = NULL; + gboolean auto_conn = TRUE; + const char *value = NULL; + gboolean success = FALSE; + + connection = nm_connection_new (); + if (!connection) + return NULL; + setting = + (NMSettingConnection *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_CONNECTION); + if (!setting) { + setting = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + g_assert (setting); + nm_connection_add_setting (connection, NM_SETTING (setting)); + } + + type = guess_connection_type (conn_name); + value = ifnet_get_data (conn_name, "auto"); + if (value && !strcmp (value, "false")) + auto_conn = FALSE; + update_connection_id (connection, conn_name); + g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type, + NM_SETTING_CONNECTION_READ_ONLY, FALSE, + NM_SETTING_CONNECTION_AUTOCONNECT, auto_conn, NULL); + + if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type) + || !strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) { + /* wired setting */ + make_wired_connection_setting (connection, conn_name, error); + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto error; + } + /* pppoe setting */ + if (!strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) + make_pppoe_connection_setting (connection, conn_name, + error); + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto error; + } + } else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { + /* wireless setting */ + NMSetting *wireless_setting; + + wireless_setting = make_wireless_connection_setting (conn_name, &s_8021x, error); + if (!wireless_setting) + goto error; + nm_connection_add_setting (connection, wireless_setting); + + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto error; + } + + /* wireless security setting */ + wsec = make_wireless_security_setting (conn_name, &s_8021x, error); + if (wsec) { + nm_connection_add_setting (connection, + NM_SETTING (wsec)); + if (s_8021x) + nm_connection_add_setting (connection, + NM_SETTING + (s_8021x)); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SEC, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + } + + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto error; + } + + } else + goto error; + + /* IPv4 setting */ + make_ip4_setting (connection, conn_name, error); + if (error && *error) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + + /* IPv6 setting */ + make_ip6_setting (connection, conn_name, error); + if (error && *error) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + + success = nm_connection_verify (connection, error); + if (error && *error) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, success); + if (!success) + goto error; + return connection; + +error: + g_object_unref (setting); + g_object_unref (connection); + return NULL; +} + +typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x * setting); +typedef const char *(*PathFunc) (NMSetting8021x * setting); +typedef const GByteArray *(*BlobFunc) (NMSetting8021x * setting); + +typedef struct ObjectType { + const char *setting_key; + SchemeFunc scheme_func; + PathFunc path_func; + BlobFunc blob_func; + const char *conn_name_key; + const char *suffix; +} ObjectType; + +static const ObjectType ca_type = { + NM_SETTING_802_1X_CA_CERT, + nm_setting_802_1x_get_ca_cert_scheme, + nm_setting_802_1x_get_ca_cert_path, + nm_setting_802_1x_get_ca_cert_blob, + "ca_cert", + "ca-cert.der" +}; + +static const ObjectType phase2_ca_type = { + NM_SETTING_802_1X_PHASE2_CA_CERT, + nm_setting_802_1x_get_phase2_ca_cert_scheme, + nm_setting_802_1x_get_phase2_ca_cert_path, + nm_setting_802_1x_get_phase2_ca_cert_blob, + "ca_cert2", + "inner-ca-cert.der" +}; + +static const ObjectType client_type = { + NM_SETTING_802_1X_CLIENT_CERT, + nm_setting_802_1x_get_client_cert_scheme, + nm_setting_802_1x_get_client_cert_path, + nm_setting_802_1x_get_client_cert_blob, + "client_cert", + "client-cert.der" +}; + +static const ObjectType phase2_client_type = { + NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + nm_setting_802_1x_get_phase2_client_cert_scheme, + nm_setting_802_1x_get_phase2_client_cert_path, + nm_setting_802_1x_get_phase2_client_cert_blob, + "client_cert2", + "inner-client-cert.der" +}; + +static const ObjectType pk_type = { + NM_SETTING_802_1X_PRIVATE_KEY, + nm_setting_802_1x_get_private_key_scheme, + nm_setting_802_1x_get_private_key_path, + nm_setting_802_1x_get_private_key_blob, + "private_key", + "private-key.pem" +}; + +static const ObjectType phase2_pk_type = { + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + nm_setting_802_1x_get_phase2_private_key_scheme, + nm_setting_802_1x_get_phase2_private_key_path, + nm_setting_802_1x_get_phase2_private_key_blob, + "private_key2", + "inner-private-key.pem" +}; + +static const ObjectType p12_type = { + NM_SETTING_802_1X_PRIVATE_KEY, + nm_setting_802_1x_get_private_key_scheme, + nm_setting_802_1x_get_private_key_path, + nm_setting_802_1x_get_private_key_blob, + "private_key", + "private-key.p12" +}; + +static const ObjectType phase2_p12_type = { + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + nm_setting_802_1x_get_phase2_private_key_scheme, + nm_setting_802_1x_get_phase2_private_key_path, + nm_setting_802_1x_get_phase2_private_key_blob, + "private_key2", + "inner-private-key.p12" +}; + +static gboolean +write_object (NMSetting8021x *s_8021x, + const char *conn_name, + const GByteArray *override_data, + const ObjectType *objtype, + GError **error) +{ + NMSetting8021xCKScheme scheme; + const char *path = NULL; + const GByteArray *blob = NULL; + + g_return_val_if_fail (conn_name != NULL, FALSE); + g_return_val_if_fail (objtype != NULL, FALSE); + if (override_data) + /* if given explicit data to save, always use that instead of asking + * the setting what to do. + */ + blob = override_data; + else { + scheme = (*(objtype->scheme_func)) (s_8021x); + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + blob = (*(objtype->blob_func)) (s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = (*(objtype->path_func)) (s_8021x); + break; + default: + break; + } + } + + /* If the object path was specified, prefer that over any raw cert data that + * may have been sent. + */ + if (path) { + wpa_set_data (conn_name, (gchar *) objtype->conn_name_key, + (gchar *) path); + return TRUE; + } + + /* does not support writing encryption data now */ + if (blob) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + " warning: Currently we do not support certs writing."); + } + + return TRUE; +} + +static gboolean +write_8021x_certs (NMSetting8021x *s_8021x, + gboolean phase2, + const char *conn_name, + GError **error) +{ + char *password = NULL; + const ObjectType *otype = NULL; + gboolean is_pkcs12 = FALSE, success = FALSE; + const GByteArray *blob = NULL; + GByteArray *enc_key = NULL; + gchar *generated_pw = NULL; + + /* CA certificate */ + if (phase2) + otype = &phase2_ca_type; + else + otype = &ca_type; + + if (!write_object (s_8021x, conn_name, NULL, otype, error)) + return FALSE; + + /* Private key */ + if (phase2) { + if (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x) != + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (nm_setting_802_1x_get_phase2_private_key_format + (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + is_pkcs12 = TRUE; + } + password = (char *) + nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + } else { + if (nm_setting_802_1x_get_private_key_scheme (s_8021x) != + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (nm_setting_802_1x_get_private_key_format (s_8021x) + == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + is_pkcs12 = TRUE; + } + password = (char *) + nm_setting_802_1x_get_private_key_password (s_8021x); + } + + if (is_pkcs12) + otype = phase2 ? &phase2_p12_type : &p12_type; + else + otype = phase2 ? &phase2_pk_type : &pk_type; + + if ((*(otype->scheme_func)) (s_8021x) == + NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = (*(otype->blob_func)) (s_8021x); + + /* Only do the private key re-encrypt dance if we got the raw key data, which + * by definition will be unencrypted. If we're given a direct path to the + * private key file, it'll be encrypted, so we don't need to re-encrypt. + */ + if (blob && !is_pkcs12) { + /* Encrypt the unencrypted private key with the fake password */ + enc_key = + nm_utils_rsa_key_encrypt (blob, password, &generated_pw, + error); + if (!enc_key) + goto out; + + if (generated_pw) + password = generated_pw; + } + + /* Save the private key */ + if (!write_object + (s_8021x, conn_name, enc_key ? enc_key : blob, otype, error)) + goto out; + + if (phase2) + wpa_set_data (conn_name, "private_key_passwd2", password); + else + wpa_set_data (conn_name, "private_key_passwd", password); + + /* Client certificate */ + if (is_pkcs12) { + wpa_set_data (conn_name, + phase2 ? "client_cert2" : "client_cert", NULL); + } else { + if (phase2) + otype = &phase2_client_type; + else + otype = &client_type; + + /* Save the client certificate */ + if (!write_object (s_8021x, conn_name, NULL, otype, error)) + goto out; + } + + success = TRUE; +out: + if (generated_pw) { + memset (generated_pw, 0, strlen (generated_pw)); + g_free (generated_pw); + } + if (enc_key) { + memset (enc_key->data, 0, enc_key->len); + g_byte_array_free (enc_key, TRUE); + } + return success; +} + +static gboolean +write_8021x_setting (NMConnection *connection, + const char *conn_name, + gboolean wired, + GError **error) +{ + NMSetting8021x *s_8021x; + const char *value; + char *tmp = NULL; + gboolean success = FALSE; + GString *phase2_auth; + GString *phase1; + + s_8021x = + (NMSetting8021x *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_802_1X); + + if (!s_8021x) { + return TRUE; + } + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding 8021x setting for %s", + conn_name); + + /* If wired, write KEY_MGMT */ + if (wired) + wpa_set_data (conn_name, "key_mgmt", "IEEE8021X"); + + /* EAP method */ + if (nm_setting_802_1x_get_num_eap_methods (s_8021x)) { + value = nm_setting_802_1x_get_eap_method (s_8021x, 0); + if (value) + tmp = g_ascii_strup (value, -1); + } + wpa_set_data (conn_name, "eap", tmp ? tmp : NULL); + g_free (tmp); + + wpa_set_data (conn_name, "identity", + (gchar *) nm_setting_802_1x_get_identity (s_8021x)); + + wpa_set_data (conn_name, "anonymous_identity", (gchar *) + nm_setting_802_1x_get_anonymous_identity (s_8021x)); + + wpa_set_data (conn_name, "password", + (gchar *) nm_setting_802_1x_get_password (s_8021x)); + + phase1 = g_string_new (NULL); + + /* PEAP version */ + wpa_set_data (conn_name, "phase1", NULL); + value = nm_setting_802_1x_get_phase1_peapver (s_8021x); + if (value && (!strcmp (value, "0") || !strcmp (value, "1"))) + g_string_append_printf (phase1, "peapver=%s ", value); + + /* PEAP label */ + value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x); + if (value && !strcmp (value, "1")) + g_string_append_printf (phase1, "peaplabel=%s ", value); + if (phase1->len) { + tmp = g_strstrip (g_strdup (phase1->str)); + wpa_set_data (conn_name, "phase1", tmp); + g_free (tmp); + } + + /* Phase2 auth methods */ + wpa_set_data (conn_name, "phase2", NULL); + phase2_auth = g_string_new (NULL); + + value = nm_setting_802_1x_get_phase2_auth (s_8021x); + if (value) { + tmp = g_ascii_strup (value, -1); + g_string_append_printf (phase2_auth, "auth=%s ", tmp); + g_free (tmp); + } + + /* Phase2 auth heap */ + value = nm_setting_802_1x_get_phase2_autheap (s_8021x); + if (value) { + tmp = g_ascii_strup (value, -1); + g_string_append_printf (phase2_auth, "autheap=%s ", tmp); + g_free (tmp); + } + tmp = g_strstrip (g_strdup (phase2_auth->str)); + wpa_set_data (conn_name, "phase2", phase2_auth->len ? tmp : NULL); + g_free (tmp); + + g_string_free (phase2_auth, TRUE); + g_string_free (phase1, TRUE); + + success = write_8021x_certs (s_8021x, FALSE, conn_name, error); + if (success) { + /* phase2/inner certs */ + success = write_8021x_certs (s_8021x, TRUE, conn_name, error); + } + + return success; +} + +static gboolean +write_wireless_security_setting (NMConnection * connection, + gchar * conn_name, + gboolean adhoc, + gboolean * no_8021x, GError ** error) +{ + NMSettingWirelessSecurity *s_wsec; + const char *key_mgmt, *auth_alg, *key, *cipher, *psk; + gboolean wep = FALSE, wpa = FALSE; + char *tmp; + guint32 i, num; + GString *str; + + s_wsec = + (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + g_assert (key_mgmt); + + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + + if (!strcmp (key_mgmt, "none")) { + wpa_set_data (conn_name, "key_mgmt", "NONE"); + wep = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "wpa-none") + || !strcmp (key_mgmt, "wpa-psk")) { + wpa_set_data (conn_name, "key_mgmt", "WPA-PSK"); + wpa = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "ieee8021x")) { + wpa_set_data (conn_name, "key_mgmt", "IEEE8021X"); + } else if (!strcmp (key_mgmt, "wpa-eap")) { + wpa_set_data (conn_name, "key_mgmt", "WPA-EAP"); + wpa = TRUE; + } else + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Unknown key_mgmt: %s", key_mgmt); + + if (auth_alg) { + if (!strcmp (auth_alg, "shared")) + wpa_set_data (conn_name, "auth_alg", "SHARED"); + else if (!strcmp (auth_alg, "open")) + wpa_set_data (conn_name, "auth_alg", "OPEN"); + else if (!strcmp (auth_alg, "leap")) { + wpa_set_data (conn_name, "auth_alg", "LEAP"); + wpa_set_data (conn_name, "eap", "LEAP"); + wpa_set_data (conn_name, "identity", (gchar *) + nm_setting_wireless_security_get_leap_username + (s_wsec)); + wpa_set_data (conn_name, "password", (gchar *) + nm_setting_wireless_security_get_leap_password + (s_wsec)); + *no_8021x = TRUE; + } + } else + wpa_set_data (conn_name, "auth_alg", NULL); + + /* Default WEP TX key index */ + wpa_set_data (conn_name, "wep_tx_keyidx", NULL); + if (wep) { + tmp = + g_strdup_printf ("%d", + nm_setting_wireless_security_get_wep_tx_keyidx + (s_wsec)); + wpa_set_data (conn_name, "wep_tx_keyidx", tmp); + g_free (tmp); + } + + /* WEP keys */ + for (i = 0; i < 4; i++) { + int length; + + key = nm_setting_wireless_security_get_wep_key (s_wsec, i); + if (!key) + continue; + tmp = g_strdup_printf ("wep_key%d", i); + length = strlen (key); + if (length == 10 || length == 26 || length == 58) + wpa_set_data (conn_name, tmp, (gchar *) key); + else { + gchar *tmp_key = g_strdup_printf ("\"%s\"", key); + + wpa_set_data (conn_name, tmp, tmp_key); + g_free (tmp_key); + } + g_free (tmp); + } + + /* WPA Pairwise ciphers */ + wpa_set_data (conn_name, "pairwise", NULL); + str = g_string_new (NULL); + num = nm_setting_wireless_security_get_num_pairwise (s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (str, ' '); + cipher = nm_setting_wireless_security_get_pairwise (s_wsec, i); + tmp = g_ascii_strup (cipher, -1); + g_string_append (str, tmp); + g_free (tmp); + } + if (strlen (str->str)) + wpa_set_data (conn_name, "pairwise", str->str); + g_string_free (str, TRUE); + + /* WPA Group ciphers */ + wpa_set_data (conn_name, "group", NULL); + str = g_string_new (NULL); + num = nm_setting_wireless_security_get_num_groups (s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (str, ' '); + cipher = nm_setting_wireless_security_get_group (s_wsec, i); + tmp = g_ascii_strup (cipher, -1); + g_string_append (str, tmp); + g_free (tmp); + } + if (strlen (str->str)) + wpa_set_data (conn_name, "group", str->str); + g_string_free (str, TRUE); + + /* WPA Passphrase */ + if (wpa) { + GString *quoted = NULL; + + psk = nm_setting_wireless_security_get_psk (s_wsec); + if (psk && (strlen (psk) != 64)) { + quoted = g_string_sized_new (strlen (psk) + 2); + g_string_append_c (quoted, '"'); + g_string_append (quoted, psk); + g_string_append_c (quoted, '"'); + } + /* psk will be lost here if we don't check it for NULL */ + if (psk) + wpa_set_data (conn_name, "psk", + quoted ? quoted->str : (gchar *) psk); + if (quoted) + g_string_free (quoted, TRUE); + } else + wpa_set_data (conn_name, "psk", NULL); + + return TRUE; +} + +/* remove old ssid and add new one*/ +static void +update_wireless_ssid (NMConnection *connection, + const char *conn_name, + const char *ssid, + gboolean hex) +{ + if(strcmp (conn_name, ssid)){ + ifnet_delete_network (conn_name); + wpa_delete_security (conn_name); + } + + ifnet_add_network (ssid, "wireless"); + wpa_add_security (ssid); +} + +static gboolean +write_wireless_setting (NMConnection *connection, + const char *conn_name, + gboolean *no_8021x, + const char **out_new_name, + GError **error) +{ + NMSettingWireless *s_wireless; + const GByteArray *ssid, *mac, *bssid; + const char *mode; + char buf[33]; + guint32 mtu, i; + gboolean adhoc = FALSE, hex_ssid = FALSE; + gchar *ssid_str, *tmp; + + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (!s_wireless) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + ssid = nm_setting_wireless_get_ssid (s_wireless); + if (!ssid) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing SSID in '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + if (!ssid->len || ssid->len > 32) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Invalid SSID in '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + /* If the SSID contains any non-alnum characters, we need to use + * the hex notation of the SSID instead. (Because openrc doesn't + * support these characters, see bug #356337) + */ + for (i = 0; i < ssid->len; i++) { + if (!isalnum (ssid->data[i])) { + hex_ssid = TRUE; + break; + } + } + + if (hex_ssid) { + GString *str; + + /* Hex SSIDs don't get quoted */ + str = g_string_sized_new (ssid->len * 2 + 3); + g_string_append (str, "0x"); + for (i = 0; i < ssid->len; i++) + g_string_append_printf (str, "%02X", ssid->data[i]); + update_wireless_ssid (connection, conn_name, str->str, hex_ssid); + ssid_str = g_string_free (str, FALSE); + } else { + /* Printable SSIDs get quoted */ + memset (buf, 0, sizeof (buf)); + memcpy (buf, ssid->data, ssid->len); + g_strstrip (buf); + update_wireless_ssid (connection, conn_name, buf, hex_ssid); + ssid_str = g_strdup (buf); + } + + ifnet_set_data (ssid_str, "mac", NULL); + mac = nm_setting_wireless_get_mac_address (s_wireless); + if (mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], + mac->data[5]); + ifnet_set_data (ssid_str, "mac", tmp); + g_free (tmp); + } + + ifnet_set_data (ssid_str, "mtu", NULL); + mtu = nm_setting_wireless_get_mtu (s_wireless); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + ifnet_set_data (ssid_str, "mtu", tmp); + g_free (tmp); + } + + ifnet_set_data (ssid_str, "mode", NULL); + mode = nm_setting_wireless_get_mode (s_wireless); + if (!mode || !strcmp (mode, "infrastructure")) { + wpa_set_data (ssid_str, "mode", "0"); + } else if (!strcmp (mode, "adhoc")) { + wpa_set_data (ssid_str, "mode", "1"); + adhoc = TRUE; + } else { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Invalid mode '%s' in '%s' setting", + mode, NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + wpa_set_data (ssid_str, "bssid", NULL); + bssid = nm_setting_wireless_get_bssid (s_wireless); + if (bssid) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + bssid->data[0], bssid->data[1], + bssid->data[2], bssid->data[3], + bssid->data[4], bssid->data[5]); + wpa_set_data (ssid_str, "bssid", tmp); + g_free (tmp); + } + + if (nm_setting_wireless_get_security (s_wireless)) { + if (!write_wireless_security_setting + (connection, ssid_str, adhoc, no_8021x, error)) + return FALSE; + } else + wpa_delete_security (ssid_str); + + if (out_new_name) + *out_new_name = ifnet_get_data (ssid_str, "name"); + g_free (ssid_str); + return TRUE; +} + +static gboolean +write_wired_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingWired *s_wired; + const GByteArray *mac; + char *tmp; + guint32 mtu; + + s_wired = + (NMSettingWired *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRED); + if (!s_wired) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_WIRED_SETTING_NAME); + return FALSE; + } + + ifnet_set_data (conn_name, "mac", NULL); + mac = nm_setting_wired_get_mac_address (s_wired); + if (mac) { + tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], + mac->data[5]); + ifnet_set_data (conn_name, "mac", tmp); + g_free (tmp); + } + + ifnet_set_data (conn_name, "mtu", NULL); + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + ifnet_set_data (conn_name, "mtu", tmp); + g_free (tmp); + } + //FIXME may add connection type in future + //ifnet_set_data (conn_name, "TYPE", TYPE_ETHERNET); + + return TRUE; +} + +static void +write_connection_setting (NMSettingConnection *s_con, const char *conn_name) +{ + ifnet_set_data (conn_name, "auto", + nm_setting_connection_get_autoconnect (s_con) ? "true" : + "false"); +} + +static gboolean +write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) +{ + NMSettingIP4Config *s_ip4; + const char *value; + char *tmp; + guint32 i, num; + GString *searches; + GString *ips; + GString *routes; + GString *dns; + gboolean has_def_route = FALSE; + gboolean success = FALSE; + + s_ip4 = + (NMSettingIP4Config *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_IP4_CONFIG); + if (!s_ip4) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + return FALSE; + } + routes = g_string_new (NULL); + + value = nm_setting_ip4_config_get_method (s_ip4); + g_assert (value); + if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + + num = nm_setting_ip4_config_get_num_addresses (s_ip4); + ips = g_string_new (NULL); + /* IPv4 addresses */ + for (i = 0; i < num; i++) { + char buf[INET_ADDRSTRLEN + 1]; + NMIP4Address *addr; + guint32 ip; + + addr = nm_setting_ip4_config_get_address (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_address_get_address (addr); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], + sizeof (buf)); + g_string_append_printf (ips, "\"%s", &buf[0]); + + tmp = + g_strdup_printf ("%u", + nm_ip4_address_get_prefix (addr)); + g_string_append_printf (ips, "/%s\" ", tmp); + g_free (tmp); + + /* only the first gateway will be written */ + if (!has_def_route && nm_ip4_address_get_gateway (addr)) { + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_address_get_gateway (addr); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], + sizeof (buf)); + g_string_append_printf (routes, + "\"default via %s\" ", + &buf[0]); + has_def_route = TRUE; + } + } + ifnet_set_data (conn_name, "config", ips->str); + g_string_free (ips, TRUE); + } else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + ifnet_set_data (conn_name, "config", "shared"); + else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + ifnet_set_data (conn_name, "config", "autoip"); + else + ifnet_set_data (conn_name, "config", "dhcp"); + + /* DNS Servers */ + num = nm_setting_ip4_config_get_num_dns (s_ip4); + if (num > 0) { + dns = g_string_new (NULL); + for (i = 0; i < num; i++) { + char buf[INET_ADDRSTRLEN + 1]; + guint32 ip; + + ip = nm_setting_ip4_config_get_dns (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], + sizeof (buf)); + g_string_append_printf (dns, " %s", buf); + } + ifnet_set_data (conn_name, "dns_servers", dns->str); + g_string_free (dns, TRUE); + } else + ifnet_set_data (conn_name, "dns_servers", NULL); + + /* DNS Searches */ + num = nm_setting_ip4_config_get_num_dns_searches (s_ip4); + if (num > 0) { + searches = g_string_new (NULL); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c (searches, ' '); + g_string_append (searches, + nm_setting_ip4_config_get_dns_search + (s_ip4, i)); + } + ifnet_set_data (conn_name, "dns_search", searches->str); + g_string_free (searches, TRUE); + } else + ifnet_set_data (conn_name, "dns_search", NULL); + /* FIXME Will be implemented when configuration supports it + if (!strcmp(value, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + value = nm_setting_ip4_config_get_dhcp_hostname(s_ip4); + if (value) + ifnet_set_data(conn_name, "DHCP_HOSTNAME", value, + FALSE); + + value = nm_setting_ip4_config_get_dhcp_client_id(s_ip4); + if (value) + ifnet_set_data(conn_name, "DHCP_CLIENT_ID", value, + FALSE); + } + */ + + /* Static routes */ + num = nm_setting_ip4_config_get_num_routes (s_ip4); + if (num > 0) { + for (i = 0; i < num; i++) { + char buf[INET_ADDRSTRLEN + 1]; + NMIP4Route *route; + guint32 ip; + + route = nm_setting_ip4_config_get_route (s_ip4, i); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_route_get_dest (route); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], + sizeof (buf)); + g_string_append_printf (routes, "\"%s", buf); + + tmp = + g_strdup_printf ("%u", + nm_ip4_route_get_prefix (route)); + g_string_append_printf (routes, "/%s via ", tmp); + g_free (tmp); + + memset (buf, 0, sizeof (buf)); + ip = nm_ip4_route_get_next_hop (route); + inet_ntop (AF_INET, (const void *) &ip, &buf[0], + sizeof (buf)); + g_string_append_printf (routes, "%s\" ", buf); + } + } + if (routes->len > 0) + ifnet_set_data (conn_name, "routes", routes->str); + else + ifnet_set_data (conn_name, "routes", NULL); + g_string_free (routes, TRUE); + + success = TRUE; + + return success; +} + +static gboolean +write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **error) +{ + char dest[INET6_ADDRSTRLEN + 1]; + char next_hop[INET6_ADDRSTRLEN + 1]; + NMIP6Route *route; + const struct in6_addr *ip; + guint32 prefix; + guint32 i, num; + GString *routes_string; + const char *old_routes; + + g_return_val_if_fail (s_ip6 != NULL, FALSE); + num = nm_setting_ip6_config_get_num_routes (s_ip6); + if (num == 0) { + return TRUE; + } + + old_routes = ifnet_get_data (conn_name, "routes"); + routes_string = g_string_new (old_routes); + if (old_routes) + g_string_append (routes_string, "\" "); + for (i = 0; i < num; i++) { + route = nm_setting_ip6_config_get_route (s_ip6, i); + + memset (dest, 0, sizeof (dest)); + ip = nm_ip6_route_get_dest (route); + inet_ntop (AF_INET6, (const void *) ip, &dest[0], + sizeof (dest)); + + prefix = nm_ip6_route_get_prefix (route); + + memset (next_hop, 0, sizeof (next_hop)); + ip = nm_ip6_route_get_next_hop (route); + inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], + sizeof (next_hop)); + + g_string_append_printf (routes_string, "\"%s/%u via %s\" ", + dest, prefix, next_hop); + } + if (num > 0) + ifnet_set_data (conn_name, "routes", routes_string->str); + g_string_free (routes_string, TRUE); + + return TRUE; +} + +static gboolean +write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) +{ + NMSettingIP6Config *s_ip6; + const char *value; + char *prefix; + guint32 i, num; + GString *searches; + char buf[INET6_ADDRSTRLEN + 1]; + NMIP6Address *addr; + const struct in6_addr *ip; + + s_ip6 = + (NMSettingIP6Config *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_IP6_CONFIG); + if (!s_ip6) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + return FALSE; + } + + value = nm_setting_ip6_config_get_method (s_ip6); + g_assert (value); + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + ifnet_set_data (conn_name, "enable_ipv6", "false"); + return TRUE; + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + /* nothing to do now */ + } else { + // if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + const char *config = ifnet_get_data (conn_name, "config"); + gchar *tmp; + + if (!config) + tmp = g_strdup_printf ("dhcp6"); + else + tmp = g_strdup_printf ("%s\" \"dhcp6\"", config); + ifnet_set_data (conn_name, "config", tmp); + g_free (tmp); + } + /* else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + } */ + + /* Remember to set IPv6 enabled */ + ifnet_set_data (conn_name, "enable_ipv6", "true"); + + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + const char *config = ifnet_get_data (conn_name, "config"); + gchar *tmp; + GString *ip_str; + + if (!config) + config = ""; + num = nm_setting_ip6_config_get_num_addresses (s_ip6); + + /* IPv6 addresses */ + ip_str = g_string_new (NULL); + for (i = 0; i < num; i++) { + addr = nm_setting_ip6_config_get_address (s_ip6, i); + ip = nm_ip6_address_get_address (addr); + prefix = + g_strdup_printf ("%u", + nm_ip6_address_get_prefix (addr)); + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET6, (const void *) ip, buf, + sizeof (buf)); + g_string_append_printf (ip_str, "\"%s/", buf); + g_string_append_printf (ip_str, "%s\" ", prefix); + g_free (prefix); + } + tmp = g_strdup_printf ("%s\" %s", config, ip_str->str); + ifnet_set_data (conn_name, "config", tmp); + g_free (tmp); + g_string_free (ip_str, TRUE); + } + + /* DNS Servers */ + num = nm_setting_ip6_config_get_num_dns (s_ip6); + if (num > 0) { + const char *dns_servers = ifnet_get_data (conn_name, "dns_servers"); + gchar *tmp; + GString *dns_string = g_string_new (NULL); + + if (!dns_servers) + dns_servers = ""; + for (i = 0; i < num; i++) { + ip = nm_setting_ip6_config_get_dns (s_ip6, i); + + memset (buf, 0, sizeof (buf)); + inet_ntop (AF_INET6, (const void *) ip, buf, + sizeof (buf)); + if (!strstr (dns_servers, buf)) + g_string_append_printf (dns_string, "%s ", buf); + } + tmp = g_strdup_printf ("%s %s", dns_servers, dns_string->str); + ifnet_set_data (conn_name, "dns_servers", tmp); + g_free (tmp); + g_string_free (dns_string, TRUE); + + } else + /* DNS Searches */ + num = nm_setting_ip6_config_get_num_dns_searches (s_ip6); + if (num > 0) { + const char *ip4_domains; + + ip4_domains = ifnet_get_data (conn_name, "dns_search"); + if (!ip4_domains) + ip4_domains = ""; + searches = g_string_new (ip4_domains); + for (i = 0; i < num; i++) { + const gchar *search = NULL; + + search = + nm_setting_ip6_config_get_dns_search (s_ip6, i); + if (search && !strstr (searches->str, search)) { + if (searches->len > 0) + g_string_append_c (searches, ' '); + g_string_append (searches, search); + } + } + ifnet_set_data (conn_name, "dns_search", searches->str); + g_string_free (searches, TRUE); + } + + write_route6_file (s_ip6, conn_name, error); + if (error && *error) + return FALSE; + return TRUE; +} + +static gboolean +write_pppoe_setting (const char *conn_name, NMSettingPPPOE * s_pppoe) +{ + const gchar *value; + + value = nm_setting_pppoe_get_username (s_pppoe); + if (!value) { + return FALSE; + } + ifnet_set_data (conn_name, "username", (gchar *) value); + + value = nm_setting_pppoe_get_password (s_pppoe); + /* password could be NULL here */ + if (value) { + ifnet_set_data (conn_name, "password", (gchar *) value); + } + return TRUE; +} + +gboolean +ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + GError **error) +{ + NMSettingConnection *s_con; + NMSettingIP6Config *s_ip6; + gboolean success = FALSE; + const char *type; + gboolean no_8021x = FALSE; + gboolean wired = FALSE, pppoe = TRUE; + const char *new_name = NULL; + + s_con = + NM_SETTING_CONNECTION (nm_connection_get_setting + (connection, NM_TYPE_SETTING_CONNECTION)); + if (!s_con) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing '%s' setting", + NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + + type = nm_setting_connection_get_connection_type (s_con); + if (!type) { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Missing connection type!"); + goto out; + } + + if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { + /* Writing wired setting */ + if (!write_wired_setting (connection, conn_name, error)) + goto out; + wired = TRUE; + no_8021x = TRUE; + } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + /* Writing wireless setting */ + if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error)) + goto out; + } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { + NMSettingPPPOE *s_pppoe; + + /* Writing pppoe setting */ + s_pppoe = NM_SETTING_PPPOE (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)); + if (!write_pppoe_setting (conn_name, s_pppoe)) + goto out; + pppoe = TRUE; + wired = TRUE; + no_8021x = TRUE; + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Can't write connection type '%s'", type); + goto out; + } + + /* connection name may have been updated; use it when writing out + * the rest of the settings. + */ + if (new_name) + conn_name = new_name; + + //FIXME wired connection doesn't support 8021x now + if (!no_8021x) { + if (!write_8021x_setting (connection, conn_name, wired, error)) + goto out; + } + + /* IPv4 Setting */ + if (!write_ip4_setting (connection, conn_name, error)) + goto out; + + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (s_ip6) { + /* IPv6 Setting */ + if (!write_ip6_setting (connection, conn_name, error)) + goto out; + } + + /* Connection Setting */ + write_connection_setting (s_con, conn_name); + + /* connection id will be displayed in nm-applet */ + update_connection_id (connection, conn_name); + + success = ifnet_flush_to_file (config_file); + if (success) + wpa_flush_to_file (wpa_file); + + if (out_new_name) + *out_new_name = g_strdup (conn_name); + +out: + return success; +} + +gboolean +ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file) +{ + gboolean result = FALSE; + + ifnet_delete_network (conn_name); + result = ifnet_flush_to_file (config_file); + if (result) { + /* connection may not have security information + * so simply ignore the return value*/ + wpa_delete_security (conn_name); + wpa_flush_to_file (wpa_file); + } + + return result; +} + +/* get the available wired name(eth*). */ +static gchar * +get_wired_name () +{ + int i = 0; + + for (; i < 256; i++) { + gchar *conn_name = g_strdup_printf ("eth%d", i); + + if (!ifnet_has_network (conn_name)) { + return conn_name; + } else + g_free (conn_name); + } + return NULL; +} + +/* get the available pppoe name(ppp*). */ +static gchar * +get_ppp_name () +{ + int i = 0; + + for (; i < 256; i++) { + gchar *conn_name = g_strdup_printf ("ppp%d", i); + + if (!ifnet_has_network (conn_name)) { + return conn_name; + } else + g_free (conn_name); + } + return NULL; +} + +/* get wireless ssid */ +static gchar * +get_wireless_name (NMConnection * connection) +{ + NMSettingWireless *s_wireless; + const GByteArray *ssid; + gboolean hex_ssid = FALSE; + gchar *result = NULL; + char buf[33]; + int i = 0; + + s_wireless = + (NMSettingWireless *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_WIRELESS); + if (!s_wireless) + return NULL; + + ssid = nm_setting_wireless_get_ssid (s_wireless); + if (!ssid->len || ssid->len > 32) { + return NULL; + } + + for (i = 0; i < ssid->len; i++) { + if (!isprint (ssid->data[i])) { + hex_ssid = TRUE; + break; + } + } + + if (hex_ssid) { + GString *str; + + str = g_string_sized_new (ssid->len * 2 + 3); + g_string_append (str, "0x"); + for (i = 0; i < ssid->len; i++) + g_string_append_printf (str, "%02X", ssid->data[i]); + result = g_strdup (str->str); + g_string_free (str, TRUE); + } else { + memset (buf, 0, sizeof (buf)); + memcpy (buf, ssid->data, ssid->len); + result = g_strdup_printf ("%s", buf); + g_strstrip (result); + } + + return result; +} + +char * +ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + GError **error) +{ + NMSettingConnection *s_con; + gboolean success = FALSE; + const char *type; + gchar *new_type, *new_name = NULL; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + type = nm_setting_connection_get_connection_type (s_con); + g_assert (type); + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding %s connection", type); + + /* get name and type + * Wireless type: wireless + * Wired type: wired + * PPPoE type: ppp*/ + if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { + new_name = get_wired_name (); + if (!new_name) + goto out; + new_type = "wired"; + } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + new_name = get_wireless_name (connection); + new_type = "wireless"; + } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { + new_name = get_ppp_name (); + if (!new_name) + goto out; + new_type = "ppp"; + } else { + g_set_error (error, ifnet_plugin_error_quark (), 0, + "Can't write connection type '%s'", type); + goto out; + } + + if (ifnet_add_network (new_name, new_type)) { + success = ifnet_update_parsers_by_connection (connection, + new_name, + config_file, + wpa_file, + NULL, + error); + } + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Added new connection: %s, result: %s", + new_name, success ? "success" : "fail"); + +out: + if (!success) + g_free (new_name); + return success ? new_name : NULL; +} diff --git a/src/settings/plugins/ifnet/connection_parser.h b/src/settings/plugins/ifnet/connection_parser.h new file mode 100644 index 00000000..b617b605 --- /dev/null +++ b/src/settings/plugins/ifnet/connection_parser.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _CONNECTION_PARSER_H +#define _CONNECTION_PARSER_H +#include <nm-connection.h> +#include "net_parser.h" + +NMConnection *ifnet_update_connection_from_config_block (const char *conn_name, + GError **error); + +/* nm_conn_name is used to update nm_ifnet_connection's priv data */ +gboolean ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + GError **error); + +gboolean ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file); + +char * ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + GError ** error); +#endif diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c new file mode 100644 index 00000000..a48103db --- /dev/null +++ b/src/settings/plugins/ifnet/net_parser.c @@ -0,0 +1,639 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <string.h> +#include <nm-system-config-interface.h> +#include <stdio.h> +#include "net_parser.h" +#include "net_utils.h" + +/* Save all the connection information */ +static GHashTable *conn_table; + +/* Save global settings which are used for writing*/ +static GHashTable *global_settings_table; + +/* Save functions */ +static GList *functions_list; + +/* Used to decide whether to write changes to file*/ +static gboolean net_parser_data_changed = FALSE; + +static GHashTable * +add_new_connection_config (const gchar * type, const gchar * name) +{ + GHashTable *new_conn; + gchar *new_name; + + if (!name) + return NULL; + + /* Return existing connection */ + if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL) + return new_conn; + new_conn = g_hash_table_new (g_str_hash, g_str_equal); + new_name = g_strdup (name); + g_hash_table_insert (new_conn, g_strdup ("name"), new_name); + g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type)); + g_hash_table_insert (conn_table, new_name, new_conn); + return new_conn; +} + +gboolean +ifnet_add_network (const char *name, const char *type) +{ + if (ifnet_has_network (name)) + return TRUE; + if (add_new_connection_config (type, name)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding network for %s", name); + net_parser_data_changed = TRUE; + return TRUE; + } + return FALSE; +} + +gboolean +ifnet_has_network (const char *conn_name) +{ + return g_hash_table_lookup (conn_table, conn_name) != NULL; +} + +static GHashTable * +get_connection_config (const char *name) +{ + return g_hash_table_lookup (conn_table, name); +} + +/* Ignored name won't be treated as wireless ssid */ +static gchar *ignore_name[] = { + "vlan", "bond", "atm", "ath", "ippp", "vpn", "tap", "tun", "1", + "br", "nas", "6to4", "timeout", "kvm", "force", NULL +}; + +static gboolean +ignore_connection_name (const char *name) +{ + gboolean result = FALSE; + guint i = 0; + + /* check ignore_name list */ + while (ignore_name[i] != NULL) { + if (g_ascii_strncasecmp + (name, ignore_name[i], strlen (ignore_name[i])) == 0) { + return TRUE; + } + i++; + } + /* Ignore mac address based configuration */ + if (strlen (name) == 12 && is_hex (name)) + result = TRUE; + return result; + +} + +static gboolean +is_global_setting (char *key) +{ + static gchar *global_settings[] = { "wpa_supplicant_", NULL }; + int i; + + for (i = 0; global_settings[i] != NULL; i++) { + if (strstr (key, global_settings[i])) + return 1; + } + return 0; +} + +/* Parse a complete line */ +/* Connection type is determined here */ +static void +init_block_by_line (gchar * buf) +{ + gchar **key_value; + gchar *pos; + gchar *data; + gchar *tmp; + GHashTable *conn; + + key_value = g_strsplit (buf, "=", 2); + if (g_strv_length (key_value) != 2) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle this line: %s\n", + buf); + g_strfreev (key_value); + return; + } + pos = g_strrstr (key_value[0], "_"); + if (pos == NULL || is_global_setting (key_value[0])) { + /* global data */ + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "global:%s-%s\n", key_value[0], + key_value[1]); + g_hash_table_insert (global_settings_table, + g_strdup (key_value[0]), + g_strdup (key_value[1])); + g_strfreev (key_value); + return; + } + *pos++ = '\0'; + if ((conn = get_connection_config (pos)) == NULL) { + if (g_ascii_strncasecmp (pos, "eth", 3) == 0 + && strlen (pos) == 4) + /* wired connection */ + conn = add_new_connection_config ("wired", pos); + else if (g_ascii_strncasecmp (pos, "ppp", 3) == 0 + && strlen (pos) == 4) + /* pppoe connection */ + conn = add_new_connection_config ("ppp", pos); + else if (ignore_connection_name (pos)) { + /* ignored connection */ + conn = add_new_connection_config ("ignore", pos); + } else + /* wireless connection */ + conn = add_new_connection_config ("wireless", pos); + } + data = g_strdup (key_value[1]); + tmp = strip_string (data, '('); + tmp = strip_string (tmp, ')'); + strip_string (tmp, '"'); + strip_string (tmp, '\''); + if (conn) + g_hash_table_insert (conn, g_strdup (key_value[0]), + g_strdup (tmp)); + g_free (data); + g_strfreev (key_value); +} + +static void +destroy_connection_config (GHashTable * conn) +{ + gpointer key, value; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, conn); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (conn); +} + +// read settings from /etc/NetworkManager/nm-system-settings.conf +const char * +ifnet_get_global_setting (const char *group, const char *key) +{ + GError *error = NULL; + GKeyFile *keyfile = g_key_file_new (); + gchar *result = NULL; + + if (!g_key_file_load_from_file (keyfile, + IFNET_SYSTEM_SETTINGS_KEY_FILE, + G_KEY_FILE_NONE, &error)) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "loading system config file (%s) caused error: (%d) %s", + IFNET_SYSTEM_SETTINGS_KEY_FILE, + error ? error->code : -1, error + && error->message ? error->message : "(unknown)"); + } else { + result = g_key_file_get_string (keyfile, group, key, &error); + } + g_key_file_free (keyfile); + return result; +} + +static void +strip_function (GIOChannel * channel, gchar * line) +{ + + int counter = 0; + gchar *p, *tmp; + gboolean begin = FALSE; + GString *function_str = g_string_new (line); + + g_string_append (function_str, "\n"); + while (1) { + p = line; + while (*p != '\0') { + if (*p == '{') { + counter++; + begin = TRUE; + } else if (*p == '}') + counter--; + p++; + } + if (begin && counter == 0) { + g_free (line); + goto done; + } + while (1) { + g_free (line); + if (g_io_channel_read_line + (channel, &line, NULL, NULL, + NULL) == G_IO_STATUS_EOF) + goto done; + g_string_append (function_str, line); + tmp = g_strdup (line); + g_strstrip (tmp); + if (tmp[0] != '#' && tmp[0] != '\0') { + g_free (tmp); + break; + } else + g_free (tmp); + } + } +done: + functions_list = + g_list_append (functions_list, g_strdup (function_str->str)); + g_string_free (function_str, TRUE); +} + +static gboolean +is_function (gchar * line) +{ + static gchar *func_names[] = + { "preup", "predown", "postup", "postdown", "failup", "faildown", + NULL, + }; + int i; + + for (i = 0; func_names[i]; i++) { + if (g_str_has_prefix (line, func_names[i])) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "Ignoring function: %s", func_names[i]); + return TRUE; + } + } + return FALSE; +} + +gboolean +ifnet_init (gchar * config_file) +{ + GIOChannel *channel = NULL; + gchar *line; + + /* Handle multiple lines with brackets */ + gboolean complete = TRUE; + + /* line buffer */ + GString *buf; + + net_parser_data_changed = FALSE; + + conn_table = g_hash_table_new (g_str_hash, g_str_equal); + global_settings_table = g_hash_table_new (g_str_hash, g_str_equal); + functions_list = NULL; + + if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR)) + channel = g_io_channel_new_file (config_file, "r", NULL); + if (channel == NULL) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Error: Can't open %s\n", config_file); + return FALSE; + } + + buf = g_string_new (NULL); + while (g_io_channel_read_line + (channel, &line, NULL, NULL, NULL) != G_IO_STATUS_EOF) { + g_strstrip (line); + /* convert multiple lines to a complete line and + * pass it to init_block_by_line() */ + if (is_function (line)) { + strip_function (channel, line); + continue; + } + if (line[0] != '#' && line[0] != '\0') { + gchar *pos = NULL; + + if (!complete) { + complete = + g_strrstr (line, + ")") == NULL ? FALSE : TRUE; + if ((pos = strchr (line, '#')) != NULL) + *pos = '\0'; + g_strstrip (line); + if (line[0] != '\0') { + g_string_append_printf (buf, + " %s", line); + } + g_free (line); + if (!complete) + continue; + } else { + complete = + (g_strrstr (line, "(") != NULL + && g_strrstr (line, ")") != NULL) + || g_strrstr (line, "(") == NULL; + if ((pos = strchr (line, '#')) != NULL) + *pos = '\0'; + g_strstrip (line); + if (line[0] != '\0') + g_string_append (buf, line); + g_free (line); + if (!complete) + continue; + } + init_block_by_line (buf->str); + g_string_free (buf, TRUE); + buf = g_string_new (NULL); + } else + /* Blank line or comment line */ + g_free (line); + } + + g_string_free (buf, TRUE); + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return TRUE; +} + +const char * +ifnet_get_data (const char *conn_name, const char *key) +{ + GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); + + if (conn) + return g_hash_table_lookup (conn, key); + return NULL; +} + +void +ifnet_set_data (const char *conn_name, const char *key, const char *value) +{ + gpointer old_key = NULL, old_value = NULL; + GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); + gchar * stripped = NULL; + + if (!conn) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "%s does not exsit!", conn_name); + return; + } + if (value){ + stripped = g_strdup (value); + strip_string (stripped, '"'); + } + /* Remove existing key value pair */ + if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) { + if (stripped && !strcmp(old_value, stripped)){ + g_free (stripped); + return; + } + g_hash_table_remove (conn, old_key); + g_free (old_key); + g_free (old_value); + } else if (!value) + return; + if (stripped) + g_hash_table_insert (conn, g_strdup (key), stripped); + net_parser_data_changed = TRUE; +} + +// Remember to free return value +const char * +ifnet_get_global_data (const gchar * key) +{ + return g_hash_table_lookup (global_settings_table, key); +} + +// Return names of legal connections +GList * +ifnet_get_connection_names (void) +{ + GList *names = g_hash_table_get_keys (conn_table); + GList *result = NULL; + + while (names) { + if (!ignore_connection_name (names->data)) + result = g_list_prepend (result, names->data); + names = names->next; + } + g_list_free (names); + return g_list_reverse (result); +} + +/* format IP and route for writing */ +static void +format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name) +{ + gchar **ipset; + guint length, i; + GString *formated_string = g_string_new (NULL); + + strip_string (value, '"'); + ipset = g_strsplit (value, "\" \"", 0); + length = g_strv_length (ipset); + + //only one line + if (length < 2) { + *out_line = + g_strdup_printf ("%s_%s=( \"%s\" )\n", key, name, value); + goto done; + } + // Multiple lines + g_string_append_printf (formated_string, "%s_%s=(\n", key, name); + for (i = 0; i < length; i++) + g_string_append_printf (formated_string, + "\t\"%s\"\n", ipset[i]); + g_string_append (formated_string, ")\n"); + *out_line = g_strdup (formated_string->str); +done: + g_string_free (formated_string, TRUE); + g_strfreev (ipset); +} + +gboolean +ifnet_flush_to_file (const char *config_file) +{ + GIOChannel *channel; + GError **error = NULL; + gpointer key, value, name, network; + GHashTableIter iter, iter_network; + GList *list_iter; + gchar *out_line; + gsize bytes_written; + gboolean result = FALSE; + + if (!net_parser_data_changed) + return TRUE; + if (!conn_table || !global_settings_table) + return FALSE; + + channel = g_io_channel_new_file (config_file, "w", NULL); + if (!channel) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't open file %s for writing", config_file); + return FALSE; + } + g_hash_table_iter_init (&iter, global_settings_table); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file); + g_io_channel_write_chars (channel, + "#Generated by NetworkManager\n" + "###### Global Configuration ######\n", + -1, &bytes_written, error); + /* Writing global data */ + while (g_hash_table_iter_next (&iter, &key, &value)) { + out_line = + g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, error); + if (bytes_written == 0 || (error && *error)) + break; + g_free (out_line); + } + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto done; + } + + /* Writing connection data */ + g_io_channel_write_chars (channel, + "\n###### Connection Configuration ######\n", + -1, &bytes_written, error); + g_hash_table_iter_init (&iter, conn_table); + while (g_hash_table_iter_next (&iter, &name, &network)) { + g_hash_table_iter_init (&iter_network, (GHashTable *) network); + g_io_channel_write_chars (channel, + "#----------------------------------\n", + -1, &bytes_written, error); + + while (g_hash_table_iter_next (&iter_network, &key, &value)) { + if (!g_str_has_prefix ((gchar *) key, "name") + && !g_str_has_prefix ((gchar *) key, "type")) { + /* These keys contain brackets */ + if (strcmp + ((gchar *) key, + "config") == 0 + || strcmp ((gchar *) key, + "routes") == 0 + || strcmp ((gchar *) key, + "pppd") == 0 + || strcmp ((gchar *) key, "chat") == 0) + format_ips (value, &out_line, (gchar *) + key, (gchar *) + name); + else + out_line = + g_strdup_printf + ("%s_%s=\"%s\"\n", + (gchar *) key, + (gchar *) name, (gchar *) value); + g_io_channel_write_chars + (channel, out_line, -1, + &bytes_written, error); + if (bytes_written == 0 || (error && *error)) + break; + g_free (out_line); + } + } + } + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto done; + } + + /* Writing reserved functions */ + if (functions_list) { + g_io_channel_write_chars (channel, + "\n###### Reserved Functions ######\n", + -1, &bytes_written, error); + /* Writing functions */ + for (list_iter = functions_list; list_iter; + list_iter = g_list_next (list_iter)) { + out_line = + g_strdup_printf ("%s\n", (gchar *) list_iter->data); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, error); + if (bytes_written == 0 || (error && *error)) + break; + g_free (out_line); + } + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto done; + } + } + + g_io_channel_flush (channel, error); + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Found error: %s", (*error)->message); + goto done; + } + result = TRUE; + net_parser_data_changed = FALSE; +done: + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return result; +} + +gboolean +ifnet_delete_network (const char *conn_name) +{ + GHashTable *network = NULL; + + g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Deleting network for %s", conn_name); + network = g_hash_table_lookup (conn_table, conn_name); + if (!network) + return FALSE; + g_hash_table_remove (conn_table, conn_name); + destroy_connection_config (network); + net_parser_data_changed = TRUE; + return TRUE; +} + +void +ifnet_destroy (void) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + GList *list_iter; + + /* Destroy connection setting */ + if (conn_table) { + g_hash_table_iter_init (&iter, conn_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + destroy_connection_config ((GHashTable *) + value); + } + g_hash_table_destroy (conn_table); + conn_table = NULL; + } + + /* Destroy global data */ + if (global_settings_table) { + g_hash_table_iter_init (&iter, global_settings_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + g_hash_table_destroy (global_settings_table); + global_settings_table = NULL; + } + for (list_iter = functions_list; list_iter; + list_iter = g_list_next (list_iter)) + g_free (list_iter->data); + g_list_free (functions_list); +} diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h new file mode 100644 index 00000000..0411e939 --- /dev/null +++ b/src/settings/plugins/ifnet/net_parser.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _NET_PARSER_H +#define _NET_PARSER_H + +#include <glib.h> + +#define CONF_NET_FILE "/etc/conf.d/net" +#define IFNET_SYSTEM_SETTINGS_KEY_FILE "/etc/NetworkManager/nm-system-settings.conf" +#define IFNET_KEY_FILE_GROUP "ifnet" + +gboolean ifnet_init (gchar * config_file); +void ifnet_destroy (void); + +/* Reader functions */ +GList *ifnet_get_connection_names (void); +const char *ifnet_get_data (const char *conn_name, const char *key); +const char *ifnet_get_global_data (const char *key); +const char *ifnet_get_global_setting (const char *group, const char *key); +gboolean ifnet_has_network (const char *conn_name); + +/* Writer functions */ +gboolean ifnet_flush_to_file (const char *config_file); +void ifnet_set_data (const char *conn_name, const char *key, const char *value); +gboolean ifnet_add_network (const char *name, const char *type); +gboolean ifnet_delete_network (const char *conn_name); +#endif diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c new file mode 100644 index 00000000..83f86ab5 --- /dev/null +++ b/src/settings/plugins/ifnet/net_utils.c @@ -0,0 +1,974 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <nm-utils.h> +#include <nm-system-config-interface.h> +#include "net_utils.h" +#include "wpa_parser.h" +#include "net_parser.h" + +/* emit heading and tailing blank space, tab, character t */ +gchar * +strip_string (gchar * str, gchar t) +{ + gchar *ret = str; + gint length = 0; + guint i = 0; + + while (ret[i] != '\0' + && (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) { + length++; + i++; + } + i = 0; + while (ret[i + length] != '\0') { + ret[i] = ret[i + length]; + i++; + } + ret[i] = '\0'; + length = strlen (ret); + while ((length - 1) >= 0 + && (ret[length - 1] == ' ' || ret[length - 1] == '\n' + || ret[length - 1] == '\t' || ret[length - 1] == t)) + length--; + ret[length] = '\0'; + return ret; +} + +gboolean +is_hex (const char *value) +{ + const char *p = value; + + if (!p) + return FALSE; + while (*p) { + if (!isxdigit (*p++)) + return FALSE; + } + return TRUE; +} + +gboolean +is_ascii (const char *value) +{ + const char *p = value; + + while (*p) { + if (!isascii (*p++)) + return FALSE; + } + return TRUE; + +} + +gboolean +is_true (const char *str) +{ + if (!g_ascii_strcasecmp (str, "yes") + || !g_ascii_strcasecmp (str, "true")) + return TRUE; + return FALSE; +} + +static int +hex2num (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int +hex2byte (const char *hex) +{ + int a, b; + + a = hex2num (*hex++); + if (a < 0) + return -1; + b = hex2num (*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +/* free return value by caller */ +gchar * +utils_hexstr2bin (const gchar * hex, size_t len) +{ + size_t i; + int a; + const gchar *ipos = hex; + gchar *buf = NULL; + gchar *opos; + + /* Length must be a multiple of 2 */ + if ((len % 2) != 0) + return NULL; + + opos = buf = g_malloc0 ((len / 2) + 1); + for (i = 0; i < len; i += 2) { + a = hex2byte (ipos); + if (a < 0) { + g_free (buf); + return NULL; + } + *opos++ = a; + ipos += 2; + } + return buf; +} + +/* free return value by caller */ +gchar * +utils_bin2hexstr (const gchar * bytes, int len, int final_len) +{ + static gchar hex_digits[] = "0123456789abcdef"; + gchar *result; + int i; + gsize buflen = (len * 2) + 1; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */ + if (final_len > -1) + g_return_val_if_fail (final_len < buflen, NULL); + + result = g_malloc0 (buflen); + for (i = 0; i < len; i++) { + result[2 * i] = hex_digits[(bytes[i] >> 4) & 0xf]; + result[2 * i + 1] = hex_digits[bytes[i] & 0xf]; + } + /* Cut converted key off at the correct length for this cipher type */ + if (final_len > -1) + result[final_len] = '\0'; + else + result[buflen - 1] = '\0'; + + return result; +} + +GQuark +ifnet_plugin_error_quark (void) +{ + static GQuark error_quark = 0; + + if (G_UNLIKELY (error_quark == 0)) + error_quark = + g_quark_from_static_string ("ifnet-plugin-error-quark"); + return error_quark; +} + +static char * +find_default_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "default via ")) != NULL) { + return tmp + strlen ("default via "); + } else if ((tmp = strstr (str, "default gw ")) != NULL) { + return tmp + strlen ("default gw "); + } + return NULL; +} + +static char * +find_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "via ")) != NULL) { + return tmp + strlen ("via "); + } else if ((tmp = strstr (str, "gw ")) != NULL) { + return tmp + strlen ("gw "); + } + return NULL; +} + +gboolean +reload_parsers (void) +{ + ifnet_destroy (); + wpa_parser_destroy (); + if (!ifnet_init (CONF_NET_FILE)) + return FALSE; + wpa_parser_init (WPA_SUPPLICANT_CONF); + return TRUE; +} + +gchar * +read_hostname (const char *path) +{ + gchar *contents = NULL, *result = NULL, *tmp; + gchar **all_lines = NULL; + guint line_num, i; + + if (!g_file_get_contents (path, &contents, NULL, NULL)) + return NULL; + all_lines = g_strsplit (contents, "\n", 0); + line_num = g_strv_length (all_lines); + for (i = 0; i < line_num; i++) { + g_strstrip (all_lines[i]); + if (all_lines[i][0] == '#' || all_lines[i][0] == '\0') + continue; + if (g_str_has_prefix (all_lines[i], "hostname")) { + tmp = strstr (all_lines[i], "="); + tmp++; + tmp = strip_string (tmp, '"'); + result = g_strdup (tmp); + break; + } + + } + g_strfreev (all_lines); + g_free (contents); + return result; +} + +gboolean +write_hostname (const gchar *hostname, const char *path) +{ + gboolean result; + char *contents; + + contents = g_strdup_printf ("#Generated by NetworkManager\n" + "hostname=\"%s\"\n", hostname); + result = g_file_set_contents (path, contents, -1, NULL); + g_free (contents); + return result; +} + +gboolean +is_static_ip4 (const char *conn_name) +{ + const char *data = ifnet_get_data (conn_name, "config"); + const char *dhcp6; + + if (!data) + return FALSE; + if (!strcmp (data, "shared")) + return FALSE; + if (!strcmp (data, "autoip")) + return FALSE; + dhcp6 = strstr (data, "dhcp6"); + if (dhcp6) { + gchar *dhcp4; + + if (strstr (data, "dhcp ")) + return FALSE; + dhcp4 = strstr (data, "dhcp"); + if (!dhcp4) + return TRUE; + if (dhcp4[4] == '\0') + return FALSE; + return TRUE; + } + return strstr (data, "dhcp") == NULL ? TRUE : FALSE; +} + +gboolean +is_static_ip6 (const char *conn_name) +{ + const char *data = ifnet_get_data (conn_name, "config"); + + if (!data) + return TRUE; + return strstr (data, "dhcp6") == NULL ? TRUE : FALSE; +} + +gboolean +is_ip4_address (const char *in_address) +{ + const char *pattern = + "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$"; + gchar *address = g_strdup (in_address); + gboolean result = FALSE; + gchar *tmp; + GRegex *regex = g_regex_new (pattern, 0, 0, NULL); + GMatchInfo *match_info; + + if (!address) + goto done; + g_strstrip (address); + if ((tmp = strstr (address, "/")) != NULL) + *tmp = '\0'; + if ((tmp = strstr (address, " ")) != NULL) + *tmp = '\0'; + g_regex_match (regex, address, 0, &match_info); + result = g_match_info_matches (match_info); +done: + if (match_info) + g_match_info_free (match_info); + g_regex_unref (regex); + g_free (address); + return result; +} + +gboolean +is_ip6_address (const char *in_address) +{ + struct in6_addr tmp_ip6_addr; + gchar *tmp, *address; + gboolean result = FALSE; + + if (!in_address) + return FALSE; + address = g_strdup (in_address); + g_strstrip (address); + if ((tmp = strchr (address, '/')) != NULL) + *tmp = '\0'; + if (inet_pton (AF_INET6, address, &tmp_ip6_addr)) + result = TRUE; + g_free (address); + return result; + +} + +gboolean +has_ip6_address (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + + g_return_val_if_fail (conn_name != NULL, FALSE); + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + if (!is_ip6_address (ipset[i])) + continue; + else { + g_strfreev (ipset); + return TRUE; + } + + } + g_strfreev (ipset); + return FALSE; +} + +gboolean +has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)) +{ + char *routes = NULL, *end, *tmp; + gboolean success = FALSE; + + g_return_val_if_fail (conn_name != NULL, FALSE); + + routes = g_strdup (ifnet_get_data (conn_name, "routes")); + if (!routes) + return FALSE; + tmp = find_default_gateway_str (routes); + if (tmp) { + g_strstrip (tmp); + if ((end = strstr (tmp, "\"")) != NULL) + *end = '\0'; + if (check_fn (tmp)) + success = TRUE; + } + + g_free (routes); + return success; +} + +static ip_block * +create_ip4_block (gchar * ip) +{ + ip_block *iblock = g_slice_new0 (ip_block); + struct in_addr tmp_ip4_addr; + int i; + guint length; + gchar **ip_mask; + + /* prefix format */ + if (strstr (ip, "/")) { + gchar *prefix; + + ip_mask = g_strsplit (ip, "/", 0); + length = g_strv_length (ip_mask); + if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + goto error; + iblock->ip = tmp_ip4_addr.s_addr; + prefix = ip_mask[1]; + i = 0; + while (i < length && isdigit (prefix[i])) + i++; + prefix[i] = '\0'; + iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32) + atoi (ip_mask + [1])); + } else if (strstr (ip, "netmask")) { + ip_mask = g_strsplit (ip, " ", 0); + length = g_strv_length (ip_mask); + if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + goto error; + iblock->ip = tmp_ip4_addr.s_addr; + i = 0; + while (i < length && !strstr (ip_mask[++i], "netmask")) ; + while (i < length && ip_mask[++i][0] == '\0') ; + if (i >= length) + goto error; + if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) + goto error; + iblock->netmask = tmp_ip4_addr.s_addr; + } else { + g_slice_free (ip_block, iblock); + if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't handle ipv4 address: %s, missing netmask or prefix", + ip); + return NULL; + } + g_strfreev (ip_mask); + return iblock; +error: + if (!is_ip6_address (ip)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 address: %s", + ip); + g_strfreev (ip_mask); + g_slice_free (ip_block, iblock); + return NULL; +} + +static ip6_block * +create_ip6_block (gchar * ip) +{ + ip6_block *iblock = g_slice_new0 (ip6_block); + gchar *dup_ip = g_strdup (ip); + struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); + gchar *prefix = NULL; + + if ((prefix = strstr (dup_ip, "/")) != NULL) { + *prefix = '\0'; + prefix++; + } + if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) { + goto error; + } + iblock->ip = tmp_ip6_addr; + if (prefix) { + errno = 0; + iblock->prefix = strtol (prefix, NULL, 10); + if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { + goto error; + } + } else + iblock->prefix = 64; + g_free (dup_ip); + return iblock; +error: + if (!is_ip4_address (ip)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 address: %s", + ip); + g_slice_free (ip6_block, iblock); + g_slice_free (struct in6_addr, tmp_ip6_addr); + + g_free (dup_ip); + return NULL; +} + +static guint32 +get_ip4_gateway (gchar * gateway) +{ + gchar *tmp, *split; + struct in_addr tmp_ip4_addr; + + if (!gateway) + return 0; + tmp = find_gateway_str (gateway); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain gateway in \"%s\"", gateway); + return 0; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + if ((split = strstr (tmp, "\"")) != NULL) + *split = '\0'; + if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) + goto error; + g_free (tmp); + return tmp_ip4_addr.s_addr; +error: + if (!is_ip6_address (tmp)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 gateway: %s", + tmp); + g_free (tmp); + return 0; +} + +static struct in6_addr * +get_ip6_next_hop (gchar * next_hop) +{ + gchar *tmp; + struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); + + if (!next_hop) + return 0; + tmp = find_gateway_str (next_hop); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain next_hop in \"%s\"", next_hop); + return 0; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + g_strstrip (tmp); + if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr)) + goto error; + g_free (tmp); + return tmp_ip6_addr; +error: + if (!is_ip4_address (tmp)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't handle IPv6 next_hop: %s", tmp); + g_free (tmp); + g_slice_free (struct in6_addr, tmp_ip6_addr); + + return NULL; +} + +ip_block * +convert_ip4_config_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + guint32 def_gateway = 0; + const char *routes; + gchar *pos; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + const char *pattern = + "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))"; + + g_return_val_if_fail (conn_name != NULL, NULL); + + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + length = g_strv_length (ipset); + + routes = ifnet_get_data (conn_name, "routes"); + if (routes) + def_gateway = get_ip4_gateway (strstr (routes, "default")); + + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + //Handle ip like 192.168.4.{1..3} + if ((pos = strchr (ip, '{')) != NULL) { + gchar *ip_start, *ip_prefix; + gchar *begin_str, *end_str; + int begin, end, j; + GRegex *regex; + GMatchInfo *match_info; + + regex = g_regex_new (pattern, 0, 0, NULL); + g_regex_match (regex, ip, 0, &match_info); + g_regex_unref (regex); + + if (!g_match_info_matches (match_info)) { + g_match_info_free (match_info); + continue; + } + begin_str = g_match_info_fetch (match_info, 3); + end_str = g_match_info_fetch (match_info, 4); + begin = atoi (begin_str); + end = atoi (end_str); + ip_start = g_match_info_fetch (match_info, 2); + ip_prefix = g_match_info_fetch (match_info, 5); + if (end < begin || begin < 1 || end > 254) { + g_match_info_free (match_info); + continue; + } + + for (j = begin; j <= end; j++) { + char suf[4]; + gchar *newip; + + sprintf (suf, "%d", j); + newip = + g_strconcat (ip_start, suf, ip_prefix, + NULL); + iblock = create_ip4_block (newip); + if (iblock == NULL) { + g_free (newip); + continue; + } + if (!iblock->gateway && def_gateway != 0) + iblock->gateway = def_gateway; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + g_free (newip); + } + g_free (begin_str); + g_free (end_str); + g_free (ip_start); + g_free (ip_prefix); + g_match_info_free (match_info); + } else { + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + if (!iblock->gateway && def_gateway != 0) + iblock->gateway = def_gateway; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + } + g_strfreev (ipset); + return start; +} + +ip6_block * +convert_ip6_config_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + ip6_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + iblock = create_ip6_block (ip); + if (iblock == NULL) + continue; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip_block * +convert_ip4_routes_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + const char *routes; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + + routes = ifnet_get_data (conn_name, "routes"); + if (!routes) + return NULL; + ipset = g_strsplit (routes, "\" \"", 0); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + if (find_default_gateway_str (ip) || strstr (ip, "::") + || !find_gateway_str (ip)) + continue; + ip = strip_string (ip, '"'); + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + iblock->gateway = get_ip4_gateway (ip); + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip6_block * +convert_ip6_routes_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip, *tmp_addr; + const char *routes; + ip6_block *start = NULL, *current = NULL, *iblock = NULL; + struct in6_addr *tmp_ip6_addr; + + g_return_val_if_fail (conn_name != NULL, NULL); + routes = ifnet_get_data (conn_name, "routes"); + if (!routes) + return NULL; + ipset = g_strsplit (routes, "\" \"", 0); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + if (ip[0] == '\0') + continue; + if ((tmp_addr = find_default_gateway_str (ip)) != NULL) { + if (!is_ip6_address (tmp_addr)) + continue; + else { + tmp_ip6_addr = g_slice_new0 (struct in6_addr); + + if (inet_pton (AF_INET6, "::", tmp_ip6_addr)) { + iblock = g_slice_new0 (ip6_block); + iblock->ip = tmp_ip6_addr; + iblock->prefix = 128; + } else { + g_slice_free (struct in6_addr, + tmp_ip6_addr); + continue; + } + } + } else + iblock = create_ip6_block (ip); + if (iblock == NULL) + continue; + iblock->next_hop = get_ip6_next_hop (ip); + if (iblock->next_hop == NULL) { + destroy_ip6_block (iblock); + continue; + } + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +void +destroy_ip_block (ip_block * iblock) +{ + g_slice_free (ip_block, iblock); +} + +void +destroy_ip6_block (ip6_block * iblock) +{ + g_slice_free (struct in6_addr, iblock->ip); + g_slice_free (struct in6_addr, iblock->next_hop); + + g_slice_free (ip6_block, iblock); +} + +void +set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name) +{ + const char *dns_servers; + gchar **server_list, *stripped; + guint length, i; + struct in_addr tmp_ip4_addr; + guint32 new_dns; + + dns_servers = ifnet_get_data (conn_name, "dns_servers"); + if (!dns_servers) + return; + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) { + if (!is_ip6_address (server_list[i])) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignored dns: %s\n", + server_list[i]); + continue; + } + new_dns = tmp_ip4_addr.s_addr; + if (new_dns && !nm_setting_ip4_config_add_dns (s_ip4, new_dns)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "warning: duplicate DNS server %s", + server_list[i]); + } + g_strfreev (server_list); +} + +void +set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name) +{ + const char *dns_servers; + gchar **server_list, *stripped; + guint length, i; + struct in6_addr tmp_ip6_addr; + + dns_servers = ifnet_get_data (conn_name, "dns_servers"); + if (!dns_servers) + return; + + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) { + if (is_ip6_address (server_list[i])) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignored dns: %s\n", + server_list[i]); + continue; + } + if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_ip6_addr) + && !nm_setting_ip6_config_add_dns (s_ip6, &tmp_ip6_addr)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "warning: duplicate DNS server %s", + server_list[i]); + } + g_strfreev (server_list); +} + +gboolean +is_managed (const char *conn_name) +{ + gchar *config; + + g_return_val_if_fail (conn_name != NULL, FALSE); + config = (gchar *) ifnet_get_data (conn_name, "managed"); + if (!config) + return TRUE; + if (strcmp (config, "false") == 0) + return FALSE; + return TRUE; +} + +void +get_dhcp_hostname_and_client_id (char **hostname, char **client_id) +{ + const char *dhcp_client; + const gchar *dhcpcd_conf = "/etc/dhcpcd.conf"; + const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf"; + gchar *line = NULL, *tmp = NULL, *contents = NULL; + gchar **all_lines; + guint line_num, i; + + *hostname = NULL; + *client_id = NULL; + dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + if (dhcp_client) { + if (!strcmp (dhcp_client, "dhclient")) + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + else if (!strcmp (dhcp_client, "dhcpcd")) + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + } else { + if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + } + if (!contents) + return; + all_lines = g_strsplit (contents, "\n", 0); + line_num = g_strv_length (all_lines); + for (i = 0; i < line_num; i++) { + line = all_lines[i]; + // dhcpcd.conf + g_strstrip (line); + if (g_str_has_prefix (line, "hostname")) { + tmp = line + strlen ("hostname"); + g_strstrip (tmp); + if (tmp[0] != '\0') + *hostname = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhcpcd hostname not defined, ignoring"); + } else if (g_str_has_prefix (line, "clientid")) { + tmp = line + strlen ("clientid"); + g_strstrip (tmp); + if (tmp[0] != '\0') + *client_id = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhcpcd clientid not defined, ignoring"); + } + // dhclient.conf + else if ((tmp = strstr (line, "send host-name")) != NULL) { + tmp += strlen ("send host-name"); + g_strstrip (tmp); + strip_string (tmp, ';'); + strip_string (tmp, '"'); + if (tmp[0] != '\0') + *hostname = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhclient hostname not defined, ignoring"); + } else if ((tmp = strstr (line, "send dhcp-client-identifier")) + != NULL) { + tmp += strlen ("send dhcp-client-identifier"); + g_strstrip (tmp); + strip_string (tmp, ';'); + if (tmp[0] != '\0') + *client_id = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhclient clientid not defined, ignoring"); + } + } + g_strfreev (all_lines); + g_free (contents); +} diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h new file mode 100644 index 00000000..42f8d672 --- /dev/null +++ b/src/settings/plugins/ifnet/net_utils.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _IFNET_UTILS_H +#define _IFNET_UTILS_H +#define IFNET_PLUGIN_NAME "SCPlugin-Ifnet" +#include <glib.h> +#include <arpa/inet.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-ip4-config.h> +#include "net_parser.h" +#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address) +#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) + +typedef struct _ip_block { + guint32 ip; + guint32 netmask; + guint32 gateway; + struct _ip_block *next; +} ip_block; + +typedef struct _ip6_block { + struct in6_addr *ip; + long int prefix; + struct in6_addr *next_hop; + struct _ip6_block *next; +} ip6_block; + +gchar *read_hostname (const char *path); +gboolean write_hostname (const char *hostname, const char *path); +gboolean is_static_ip4 (const char *conn_name); +gboolean is_static_ip6 (const char *conn_name); +gboolean is_ip4_address (const char *in_address); +gboolean is_ip6_address (const char *in_address); +gboolean has_ip6_address (const char *conn_name); +gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)); +gboolean reload_parsers (void); + +ip_block *convert_ip4_config_block (const char *conn_name); +ip6_block *convert_ip6_config_block (const char *conn_name); +ip_block *convert_ip4_routes_block (const char *conn_name); +ip6_block *convert_ip6_routes_block (const char *conn_name); +void destroy_ip_block (ip_block * iblock); +void destroy_ip6_block (ip6_block * iblock); + +void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, const char *conn_name); +void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, const char *conn_name); + +gchar *strip_string (gchar *str, gchar t); +gboolean is_managed (const char *conn_name); + +GQuark ifnet_plugin_error_quark (void); +gchar *utils_hexstr2bin (const gchar * hex, size_t len); +gchar *utils_bin2hexstr (const gchar * bytes, int len, int final_len); + +gboolean is_hex (const char *value); +gboolean is_ascii (const char *value); +gboolean is_true (const char *str); + +void get_dhcp_hostname_and_client_id (char **hostname, char **client_id); + +#endif diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.c b/src/settings/plugins/ifnet/nm-ifnet-connection.c new file mode 100644 index 00000000..8b7a153c --- /dev/null +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.c @@ -0,0 +1,191 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <string.h> +#include <glib/gstdio.h> +#include <NetworkManager.h> +#include <nm-utils.h> +#include <nm-setting-wireless-security.h> +#include <nm-settings-connection.h> +#include <nm-system-config-interface.h> +#include <nm-settings-error.h> +#include "nm-ifnet-connection.h" +#include "connection_parser.h" +#include "net_parser.h" +#include "net_utils.h" +#include "wpa_parser.h" +#include "plugin.h" + +G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_IFNET_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionPrivate)) +enum { + PROP_ZERO, + PROP_CONN_NAME, + _PROP_END, +}; + +enum { + IFNET_SETUP_MONITORS, + IFNET_CANCEL_MONITORS, + IFNET_LAST_SIGNAL +}; + +static guint signals[IFNET_LAST_SIGNAL] = { 0 }; + +typedef struct { + gchar *conn_name; + NMSystemConfigInterface *config; +} NMIfnetConnectionPrivate; + +NMIfnetConnection * +nm_ifnet_connection_new (const char *conn_name, NMConnection *source) +{ + NMConnection *tmp; + GObject *object; + GError *error = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + + if (source) + tmp = g_object_ref (source); + else { + tmp = ifnet_update_connection_from_config_block (conn_name, &error); + if (!tmp){ + g_error_free (error); + return NULL; + } + } + + object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL); + if (!object) { + g_object_unref (tmp); + return NULL; + } + + NM_IFNET_CONNECTION_GET_PRIVATE (object)->conn_name = g_strdup (conn_name); + nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, NULL); + g_object_unref (tmp); + + return NM_IFNET_CONNECTION (object); +} + +static void +nm_ifnet_connection_init (NMIfnetConnection * connection) +{ +} + +static void +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + GError *error = NULL; + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection); + gchar *new_name = NULL; + + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); + if (!ifnet_update_parsers_by_connection (NM_CONNECTION (connection), + priv->conn_name, + CONF_NET_FILE, + WPA_SUPPLICANT_CONF, + &new_name, + &error)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s", priv->conn_name); + reload_parsers (); + callback (connection, error, user_data); + g_error_free (error); + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); + return; + } + + g_free (priv->conn_name); + priv->conn_name = new_name; + + NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", priv->conn_name); + + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); +} + +static void +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + GError *error = NULL; + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection); + + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); + if (!ifnet_delete_connection_in_parsers + (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to delete %s", + priv->conn_name); + reload_parsers (); + callback (connection, error, user_data); + g_error_free (error); + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); + return; + } + + NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data); + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s", + priv->conn_name); + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); +} + +static void +finalize (GObject * object) +{ + NMIfnetConnectionPrivate *priv = + NM_IFNET_CONNECTION_GET_PRIVATE (object); + g_return_if_fail (priv); + + g_free (priv->conn_name); + G_OBJECT_CLASS (nm_ifnet_connection_parent_class)->finalize (object); +} + +static void +nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class); + + g_type_class_add_private (ifnet_connection_class, + sizeof (NMIfnetConnectionPrivate)); + + object_class->finalize = finalize; + settings_class->delete = do_delete; + settings_class->commit_changes = commit_changes; + + signals[IFNET_SETUP_MONITORS] = + g_signal_new ("ifnet_setup_monitors", + G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[IFNET_CANCEL_MONITORS] = + g_signal_new ("ifnet_cancel_monitors", + G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.h b/src/settings/plugins/ifnet/nm-ifnet-connection.h new file mode 100644 index 00000000..9423f20d --- /dev/null +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef NM_IFNET_CONNECTION_H +#define NM_IFNET_CONNECTION_H + +#include <nm-settings-connection.h> +#include "net_parser.h" + +G_BEGIN_DECLS + +#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ()) +#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection)) +#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) +#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) +#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) +#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) + +typedef struct { + NMSettingsConnection parent; +} NMIfnetConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMIfnetConnectionClass; + +GType nm_ifnet_connection_get_type (void); + +NMIfnetConnection *nm_ifnet_connection_new (const char *conn_name, + NMConnection *source); + +G_END_DECLS +#endif /* NM_IFNET_CONNECTION_H */ diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c new file mode 100644 index 00000000..69b7bc80 --- /dev/null +++ b/src/settings/plugins/ifnet/plugin.c @@ -0,0 +1,541 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <string.h> + +#include <gmodule.h> +#include <glib.h> +#include <gio/gio.h> + +#include <nm-utils.h> +#include <nm-setting-connection.h> + +#include "NetworkManager.h" +#include "nm-system-config-interface.h" +#include "nm-ifnet-connection.h" + +#include "plugin.h" +#include "net_utils.h" +#include "net_parser.h" +#include "wpa_parser.h" +#include "connection_parser.h" + +#define IFNET_PLUGIN_NAME_PRINT "ifnet" +#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix." +#define IFNET_SYSTEM_HOSTNAME_FILE "/etc/conf.d/hostname" +#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE +#define IFNET_KEY_FILE_KEY_MANAGED "managed" + +typedef struct { + GHashTable *config_connections; + gchar *hostname; + gboolean unmanaged_well_known; + + GFileMonitor *hostname_monitor; + GFileMonitor *net_monitor; + GFileMonitor *wpa_monitor; + +} SCPluginIfnetPrivate; + +typedef void (*FileChangedFn) (gpointer user_data); + +typedef struct { + FileChangedFn callback; + gpointer user_data; +} FileMonitorInfo; + +static void system_config_interface_init (NMSystemConfigInterface *class); + +static void reload_connections (gpointer config); + +G_DEFINE_TYPE_EXTENDED (SCPluginIfnet, sc_plugin_ifnet, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, system_config_interface_init)) +#define SC_PLUGIN_IFNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetPrivate)) +/* +static void +ignore_cb(NMSettingsConnectionInterface * connection, + GError * error, gpointer user_data) +{ +} +*/ +static const char * +get_hostname (NMSystemConfigInterface * config) +{ + return SC_PLUGIN_IFNET_GET_PRIVATE (config)->hostname; +} + +static void +update_system_hostname (gpointer config) +{ + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); + + if (priv->hostname) + g_free (priv->hostname); + priv->hostname = read_hostname (IFNET_SYSTEM_HOSTNAME_FILE); + + g_object_notify (G_OBJECT (config), + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Hostname updated to: %s", + priv->hostname); +} + +static void +write_system_hostname (NMSystemConfigInterface * config, + const gchar * newhostname) +{ + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); + + g_return_if_fail (newhostname); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Write system hostname: %s", + newhostname); + if (write_hostname (newhostname, IFNET_SYSTEM_HOSTNAME_FILE)) { + g_free (priv->hostname); + priv->hostname = g_strdup (newhostname); + g_object_notify (G_OBJECT (config), + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); + } else + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Write system hostname: %s failed", newhostname); +} + +static gboolean +is_managed_plugin () +{ + const char *result = NULL; + + result = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED); + if (result) + return is_true (result); + return IFNET_MANAGE_WELL_KNOWN_DEFAULT; +} + +static void +file_changed (GFileMonitor * monitor, + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, gpointer user_data) +{ + FileMonitorInfo *info; + + switch (event_type) { + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + info = (FileMonitorInfo *) user_data; + info->callback (info->user_data); + break; + default: + break; + } +} + +static GFileMonitor * +monitor_file_changes (const char *filename, + FileChangedFn callback, gpointer user_data) +{ + GFile *file; + GFileMonitor *monitor; + FileMonitorInfo *info; + GError **error = NULL; + + if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + return NULL; + file = g_file_new_for_path (filename); + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error); + g_object_unref (file); + + if (monitor) { + info = g_new0 (FileMonitorInfo, 1); + info->callback = callback; + info->user_data = user_data; + g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, + info); + g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), + info); + } else + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Monitoring %s failed, error: %s", filename, + error == NULL ? "nothing" : (*error)->message); + + return monitor; +} + +/* Callback for nm_settings_connection_replace_and_commit. Report any errors + * encountered when commiting connection settings updates. */ +static void +commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) +{ + if (error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, " error updating: %s", + (error && error->message) ? error->message : "(unknown)"); + } else { + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), + NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated", + nm_setting_connection_get_id (s_con)); + } +} + +static void +setup_monitors (NMIfnetConnection * connection, gpointer user_data) +{ + SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data); + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self); + + priv->hostname_monitor = + monitor_file_changes (IFNET_SYSTEM_HOSTNAME_FILE, + update_system_hostname, user_data); + priv->net_monitor = + monitor_file_changes (CONF_NET_FILE, reload_connections, user_data); + priv->wpa_monitor = + monitor_file_changes (WPA_SUPPLICANT_CONF, reload_connections, + user_data); +} + +static void +cancel_monitors (NMIfnetConnection * connection, gpointer user_data) +{ + SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data); + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self); + + if (priv->hostname_monitor) { + g_file_monitor_cancel (priv->hostname_monitor); + g_object_unref (priv->hostname_monitor); + } + if (priv->net_monitor) { + g_file_monitor_cancel (priv->net_monitor); + g_object_unref (priv->net_monitor); + } + if (priv->wpa_monitor) { + g_file_monitor_cancel (priv->wpa_monitor); + g_object_unref (priv->wpa_monitor); + } +} + +static void +reload_connections (gpointer config) +{ + SCPluginIfnet *self = SC_PLUGIN_IFNET (config); + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self); + GList *conn_names = NULL, *n_iter = NULL; + + /* save names for removing unused connections */ + GHashTable *new_conn_names = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + if (priv->unmanaged_well_known) + return; + + if (!reload_parsers ()) + return; + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections"); + + conn_names = ifnet_get_connection_names (); + new_conn_names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) { + NMIfnetConnection *new; + NMIfnetConnection *old; + const char *conn_name = n_iter->data; + + /* read the new connection */ + new = nm_ifnet_connection_new (conn_name, NULL); + if (!new) + continue; + + g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors", + G_CALLBACK (setup_monitors), config); + g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors", + G_CALLBACK (cancel_monitors), config); + + old = g_hash_table_lookup (priv->config_connections, conn_name); + if (old && new) { + const char *auto_refresh; + + auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh"); + if (auto_refresh && is_true (auto_refresh)) { + if (!nm_connection_compare (NM_CONNECTION (old), + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_EXACT)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); + + /* Remove and re-add to disconnect and reconnect with new settings */ + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old)); + g_hash_table_remove (priv->config_connections, conn_name); + g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); + if (is_managed_plugin () && is_managed (conn_name)) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); + } + } else { + /* Update existing connection with new settings */ + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (old), + NM_CONNECTION (new), + commit_cb, NULL); + g_object_unref (new); + } + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } else if (new) { + g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); + if (is_managed_plugin () && is_managed (conn_name)) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); + } + g_hash_table_insert (new_conn_names, (gpointer) conn_name, (gpointer) conn_name); + } + + /* remove unused connections */ + g_hash_table_iter_init (&iter, priv->config_connections); + while (g_hash_table_iter_next (&iter, &key, &value)) { + if (!g_hash_table_lookup (new_conn_names, key)) { + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (value)); + g_hash_table_remove (priv->config_connections, key); + } + } + g_hash_table_destroy (new_conn_names); + g_list_free (conn_names); +} + +static NMSettingsConnection * +add_connection (NMSystemConfigInterface *config, + NMConnection *source, + GError **error) +{ + NMIfnetConnection *connection = NULL; + char *conn_name; + + conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error); + if (conn_name) + connection = nm_ifnet_connection_new (conn_name, source); + reload_connections (config); + return connection ? NM_SETTINGS_CONNECTION (connection) : NULL; +} + +static void +check_unmanaged (gpointer key, gpointer data, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + gchar *conn_name = (gchar *) key; + const char *unmanaged_spec; + GSList *iter; + + if (is_managed (conn_name)) + return; + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Checking unmanaged: %s", conn_name); + unmanaged_spec = ifnet_get_data (conn_name, "mac"); + if (!unmanaged_spec) + return; + + /* Just return if the unmanaged spec is already in the list */ + for (iter = *list; iter; iter = g_slist_next (iter)) { + if (!strcmp ((char *) iter->data, unmanaged_spec)) + return; + } + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Add unmanaged: %s", unmanaged_spec); + *list = + g_slist_prepend (*list, g_strdup_printf ("mac:%s", unmanaged_spec)); +} + +static GSList * +get_unmanaged_specs (NMSystemConfigInterface * config) +{ + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); + GSList *list = NULL; + + g_return_val_if_fail (priv->config_connections != NULL, NULL); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "getting unmanaged specs..."); + g_hash_table_foreach (priv->config_connections, check_unmanaged, &list); + return list; +} + +static void +SCPluginIfnet_init (NMSystemConfigInterface * config) +{ + SCPluginIfnet *self = SC_PLUGIN_IFNET (config); + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self); + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initializing!"); + if (!priv->config_connections) + priv->config_connections = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + g_object_unref); + priv->unmanaged_well_known = !is_managed_plugin (); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "management mode: %s", + priv->unmanaged_well_known ? "unmanaged" : "managed"); + // GFileMonitor setup + setup_monitors (NULL, config); + reload_connections (config); + /* Read hostname */ + update_system_hostname (self); + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initialzation complete!"); +} + +static GSList * +get_connections (NMSystemConfigInterface * config) +{ + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); + GSList *connections = NULL; + GHashTableIter iter; + gpointer key, value; + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) ... get_connections.", + GPOINTER_TO_UINT (config)); + if (priv->unmanaged_well_known) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "(%d) ... get_connections (managed=false): return empty list.", + GPOINTER_TO_UINT (config)); + return NULL; + } + + g_hash_table_iter_init (&iter, priv->config_connections); + while (g_hash_table_iter_next (&iter, &key, &value)) + if (is_managed ((gchar *) key)) + connections = g_slist_prepend (connections, value); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) connections count: %d", + GPOINTER_TO_UINT (config), g_slist_length (connections)); + return connections; +} + +static void +system_config_interface_init (NMSystemConfigInterface *class) +{ + class->init = SCPluginIfnet_init; + class->get_connections = get_connections; + class->get_unmanaged_specs = get_unmanaged_specs; + class->add_connection = add_connection; +} + +static void +sc_plugin_ifnet_init (SCPluginIfnet * plugin) +{ +} + +static void +get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object); + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, IFNET_PLUGIN_INFO); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS + | + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + g_value_set_string (value, get_hostname (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) +{ + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:{ + const gchar *hostname = g_value_get_string (value); + + if (hostname && strlen (hostname) < 1) + hostname = NULL; + write_system_hostname (NM_SYSTEM_CONFIG_INTERFACE + (object), hostname); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject * object) +{ + SCPluginIfnet *plugin = SC_PLUGIN_IFNET (object); + SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (plugin); + + cancel_monitors (NULL, object); + if (priv->config_connections) { + g_hash_table_remove_all (priv->config_connections); + g_hash_table_destroy (priv->config_connections); + } + + g_free (priv->hostname); + ifnet_destroy (); + wpa_parser_destroy (); + G_OBJECT_CLASS (sc_plugin_ifnet_parent_class)->dispose (object); +} + +static void +sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginIfnetPrivate)); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +G_MODULE_EXPORT GObject * +nm_system_config_factory (void) +{ + static SCPluginIfnet *singleton = NULL; + + if (!singleton) + singleton + = + SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL)); + else + g_object_ref (singleton); + return G_OBJECT (singleton); +} diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h new file mode 100644 index 00000000..83099b63 --- /dev/null +++ b/src/settings/plugins/ifnet/plugin.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <glib-object.h> + +#define SC_TYPE_PLUGIN_IFNET (sc_plugin_ifnet_get_type ()) +#define SC_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnet)) +#define SC_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass)) +#define SC_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFNET)) +#define SC_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFNET)) +#define SC_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass)) + +typedef struct _SCPluginIfnet SCPluginIfnet; +typedef struct _SCPluginIfnetClass SCPluginIfnetClass; + +struct _SCPluginIfnet { + GObject parent; +}; + +struct _SCPluginIfnetClass { + GObjectClass parent; +}; + +GType sc_plugin_ifnet_get_type (void); +#endif diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am new file mode 100644 index 00000000..20a26805 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES=-I$(srcdir)/../ \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/settings +TESTS = check_ifnet +check_PROGRAMS = check_ifnet +check_ifnet_SOURCES = test_all.c +check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS) +check_ifnet_LDADD = $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../lib-ifnet-io.la \ + $(CHECK_LIBS) \ + $(GLIB_LIBS) +EXTRA_DIST = hostname \ + net \ + net.all \ + nm-system-settings.conf \ + wpa_supplicant.conf diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in new file mode 100644 index 00000000..adb1816c --- /dev/null +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -0,0 +1,716 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = check_ifnet$(EXEEXT) +check_PROGRAMS = check_ifnet$(EXEEXT) +subdir = src/settings/plugins/ifnet/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_check_ifnet_OBJECTS = check_ifnet-test_all.$(OBJEXT) +check_ifnet_OBJECTS = $(am_check_ifnet_OBJECTS) +am__DEPENDENCIES_1 = +check_ifnet_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../lib-ifnet-io.la $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(check_ifnet_SOURCES) +DIST_SOURCES = $(check_ifnet_SOURCES) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(srcdir)/../ \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/settings + +check_ifnet_SOURCES = test_all.c +check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS) +check_ifnet_LDADD = $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../lib-ifnet-io.la \ + $(CHECK_LIBS) \ + $(GLIB_LIBS) + +EXTRA_DIST = hostname \ + net \ + net.all \ + nm-system-settings.conf \ + wpa_supplicant.conf + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_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 +check_ifnet$(EXEEXT): $(check_ifnet_OBJECTS) $(check_ifnet_DEPENDENCIES) + @rm -f check_ifnet$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_ifnet_OBJECTS) $(check_ifnet_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_ifnet-test_all.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +check_ifnet-test_all.o: test_all.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT check_ifnet-test_all.o -MD -MP -MF $(DEPDIR)/check_ifnet-test_all.Tpo -c -o check_ifnet-test_all.o `test -f 'test_all.c' || echo '$(srcdir)/'`test_all.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_ifnet-test_all.Tpo $(DEPDIR)/check_ifnet-test_all.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_all.c' object='check_ifnet-test_all.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o check_ifnet-test_all.o `test -f 'test_all.c' || echo '$(srcdir)/'`test_all.c + +check_ifnet-test_all.obj: test_all.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT check_ifnet-test_all.obj -MD -MP -MF $(DEPDIR)/check_ifnet-test_all.Tpo -c -o check_ifnet-test_all.obj `if test -f 'test_all.c'; then $(CYGPATH_W) 'test_all.c'; else $(CYGPATH_W) '$(srcdir)/test_all.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_ifnet-test_all.Tpo $(DEPDIR)/check_ifnet-test_all.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_all.c' object='check_ifnet-test_all.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o check_ifnet-test_all.obj `if test -f 'test_all.c'; then $(CYGPATH_W) 'test_all.c'; else $(CYGPATH_W) '$(srcdir)/test_all.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifnet/tests/hostname b/src/settings/plugins/ifnet/tests/hostname new file mode 100644 index 00000000..25c76165 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/hostname @@ -0,0 +1,2 @@ +#Generated by NetworkManager +hostname="gentoo" diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net new file mode 100644 index 00000000..e7550002 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/net @@ -0,0 +1,147 @@ +# This blank configuration will automatically use DHCP for any net.* +# scripts in /etc/init.d. To create a more complete configuration, +# please review /etc/conf.d/net.example and save your configuration +# in /etc/conf.d/net (this file :]!). + +config_eth0=( +"202.117.16.121 netmask 255.255.255.0 brd 202.117.16.255" +"192.168.4.121/24" +"dhcp6" +) +routes_eth0=( "default via 202.117.16.1" + "192.168.4.0/24 via 192.168.4.1") +dns_servers_eth0="202.117.0.20 202.117.0.21" +dns_search_eth0="p12.edu.cn p13.edu.cn" + +config_eth1=( + "dhcp" +) +enable_ipv6_eth1="true" +routes_eth1=( "default via 202.117.16.1" ) +dns_servers_eth1="202.117.0.20 202.117.0.21" +config_eth2=( +"202.117.16.1211 netmask 255.255.255.0 brd 202.117.16.255" +"192.168.4.121/24" +"4321:0:1:2:3:4:567:89ab/64" +) +routes_eth2=("default via 4321:0:1:2:3:4:567:89ab") +enable_ipv6_eth2="true" +config_eth3=("nufjlsjlll") +managed_eth4=("false") +routes_eth4=("default via 4321:0:1:2:3:4:567:89ab") +config_eth5=("dhcp") +config_eth6=("192.168.4.{1..101}/24") + +config_eth7=( "dhcp" ) +auto_eth7="true" + + +config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") +routes_myxjtu2=("default via 202.117.16.1") +dns_servers_myxjtu2="202.117.0.20 202.117.0.21" +#key_myxjtu2="[1] s:xjtud key [1] enc restricted" +#key_eth6="[1] aaaa-4444-3d [2] s:xjtudlc key [1] enc open" + + +username_ppp0='user' +password_ppp0='password' + +config_qiaomuf=("dhcp") + +config_1xtest=("dhcp") + +config_0xab3ace=("dhcp") + +modules=( "iproute2" ) + config_kvm0=( "null" ) + config_kvm1=( "null" ) + + tuntap_kvm0="tap" + tuntap_kvm1="tap" + tunctl_kvm0="-u user" + tunctl_kvm1="-u user" + +bridge_br0="eth0 kvm0 kvm1" +config_br0=( "192.168.1.10/24" ) + brctl_br0=( "setfd 0") + dhcp_eth1="nosendhost nontp -I" + +predown() { + # The default in the script is to test for NFS root and disallow + # downing interfaces in that case. Note that if you specify a + # predown() function you will override that logic. Here it is, in + # case you still want it... + if is_net_fs /; then + eerror "root filesystem is network mounted -- can't stop ${IFACE}" + return 1 + fi + + # Remember to return 0 on success + return 0 +} + +postup() { + # This function could be used, for example, to register with a + # dynamic DNS service. Another possibility would be to + # send/receive mail once the interface is brought up. + + # Here is an example that allows the use of iproute rules + # which have been configured using the rules_eth0 variable. + #rules_eth0=" \ + # 'from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100' \ + # 'from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100' \ + #" + eval set -- \$rules_${IFVAR} + if [ $# != 0 ]; then + einfo "Adding IP policy routing rules" + eindent + # Ensure that the kernel supports policy routing + if ! ip rule list | grep -q "^"; then + eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" + eerror "in your kernel to use ip rules" + else + for x; do + ebegin "${x}" + ip rule add ${x} + eend $? + done + fi + eoutdent + # Flush the cache + ip route flush cache dev "${IFACE}" + fi + +} + +postdown() { + # Enable Wake-On-LAN for every interface except for lo + # Probably a good idea to set ifdown="no" in /etc/conf.d/net + # as well ;) + [ "${IFACE}" != "lo" ] && ethtool -s "${IFACE}" wol g + + Automatically erase any ip rules created in the example postup above + if interface_exists "${IFACE}"; then + # Remove any rules for this interface + local rule + ip rule list | grep " iif ${IFACE}[ ]*" | { + while read rule; do + rule="${rule#*:}" + ip rule del ${rule} + done + } + # Flush the route cache + ip route flush cache dev "${IFACE}" + fi + + # Return 0 always + return 0 +} + +failup() { + # This function is mostly here for completeness... I haven't + # thought of anything nifty to do with it yet ;-) +} + +faildown() +{} + diff --git a/src/settings/plugins/ifnet/tests/net.all b/src/settings/plugins/ifnet/tests/net.all new file mode 100644 index 00000000..a30a1b95 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/net.all @@ -0,0 +1,864 @@ +############################################################################## +# QUICK-START +# +# The quickest start is if you want to use DHCP. +# In that case, everything should work out of the box, no configuration +# necessary, though the startup script will warn you that you haven't +# specified anything. + +# WARNING :- some examples have a mixture of IPv4 (ie 192.168.0.1) and IPv6 +# (ie 4321:0:1:2:3:4:567:89ab) internet addresses. They only work if you have +# the relevant kernel option enabled. So if you don't have an IPv6 enabled +# kernel then remove the IPv6 address from your config. + +# If you want to use a static address or use DHCP explicitly, jump +# down to the section labelled INTERFACE HANDLERS. +# +# If you want to do anything more fancy, you should take the time to +# read through the rest of this file. + +############################################################################## +# MODULES +# +# We now support modular networking scripts which means we can easily +# add support for new interface types and modules while keeping +# compatability with existing ones. +# +# Modules load by default if the package they need is installed. If +# you specify a module here that doesn't have it's package installed +# then you get an error stating which package you need to install. +# Ideally, you only use the modules setting when you have two or more +# packages installed that supply the same service. +# +# In other words, you probably should DO NOTHING HERE... + +# Prefer ifconfig over iproute2 +modules=( "ifconfig" ) + +# You can also specify other modules for an interface +# In this case we prefer udhcpc over dhcpcd +modules_eth0=( "udhcpc" ) + +# You can also specify which modules not to use - for example you may be +# using a supplicant or linux-wlan-ng to control wireless configuration but +# you still want to configure network settings per ESSID associated with. +modules=( "!iwconfig" "!wpa_supplicant" ) +# IMPORTANT: If you need the above, please disable modules in that order + + +############################################################################## +# INTERFACE HANDLERS +# +# We provide two interface handlers presently: ifconfig and iproute2. +# You need one of these to do any kind of network configuration. +# For ifconfig support, emerge sys-apps/net-tools +# For iproute2 support, emerge sys-apps/iproute2 + +# If you don't specify an interface then we prefer iproute2 if it's installed +# To prefer ifconfig over iproute2 +modules=( "ifconfig" ) + +# For a static configuration, use something like this +# (They all do exactly the same thing btw) +config_eth0=( "192.168.0.2/24" ) +config_eth0=( "192.168.0.2 netmask 255.255.255.0" ) + +# We can also specify a broadcast +config_eth0=( "192.168.0.2/24 brd 192.168.0.255" ) +config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" ) + +# If you need more than one address, you can use something like this +# NOTE: ifconfig creates an aliased device for each extra IPv4 address +# (eth0:1, eth0:2, etc) +# iproute2 does not do this as there is no need to +config_eth0=( + "192.168.0.2/24" + "192.168.0.3/24" + "192.168.0.4/24" +) +# Or you can use sequence expressions +config_eth0=( "192.168.0.{2..4}/24" ) +# which does the same as above. Be careful though as if you use this and +# fallbacks, you have to ensure that both end up with the same number of +# values otherwise your fallback won't work correctly. + +# You can also use IPv6 addresses +# (you should always specify a prefix length with IPv6 here) +config_eth0=( + "192.168.0.2/24" + "4321:0:1:2:3:4:567:89ab/64" + "4321:0:1:2:3:4:567:89ac/64" +) + +# If you wish to keep existing addresses + routing and the interface is up, +# you can specify a noop (no operation). If the interface is down or there +# are no addresses assigned, then we move onto the next step (default dhcp) +# This is useful when configuring your interface with a kernel command line +# or similar +config_eth0=( "noop" "192.168.0.2/24" ) + +# If you don't want ANY address (only useful when calling for advanced stuff) +config_eth0=( "null" ) + +# Here's how to do routing if you need it +routes_eth0=( + "default via 192.168.0.1" # IPv4 default route + "10.0.0.0/8 via 192.168.0.1" # IPv4 subnet route + "::/0" # IPv6 unicast +) + +# If a specified module fails (like dhcp - see below), you can specify a +# fallback like so +fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" ) +fallback_route_eth0=( "default via 192.168.0.1" ) + +# NOTE: fallback entry must match the entry location in config_eth0 +# As such you can only have one fallback route. + +# Some users may need to alter the MTU - here's how +mtu_eth0="1500" + +# Each module described below can set a default base metric, lower is +# preferred over higher. This is so we can prefer a wired route over a +# wireless route automaticaly. You can override this by setting +metric_eth0="100" +# or on a global basis +metric="100" +# The only downside of the global setting is that you have to ensure that +# there are no conflicting routes yourself. For users with large routing +# tables you may have to set a global metric as the due to a simple read of +# the routing table taking over a minute at a time. + +############################################################################## +# OPTIONAL MODULES + +# INTERFACE RENAMING +# There is no consistent device renaming scheme for Linux. +# The preferred way of naming devices is via the kernel module directly or +# by using udev (http://www.reactivated.net/udevrules.php) + +# If you are unable to write udev rules, then we do provide a way of renaming +# the interface based on it's MAC address, but it is not optimal. +# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55 +# to foo1 +rename_001122334455="foo1" + +# You can also do this based on current device name - although this is not +# recommended. Here we rename eth1 to foo2. +rename_eth1="foo2" + +#----------------------------------------------------------------------------- +# WIRELESS (802.11 support) +# Wireless can be provided by iwconfig or wpa_supplicant + +# iwconfig +# emerge net-wireless/wireless-tools +# Wireless options are held in /etc/conf.d/wireless - but could be here too +# Consult the sample file /etc/conf.d/wireless.example for instructions +# iwconfig is the default + +# wpa_supplicant +# emerge net-wireless/wpa-supplicant +# Wireless options are held in /etc/wpa_supplicant.conf +# Consult the sample file /etc/wpa_supplicant.conf.example for instructions +# To choose wpa_supplicant over iwconfig +modules=( "wpa_supplicant" ) +# To configure wpa_supplicant +wpa_supplicant_eth0="-Dwext" # For generic wireless +wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards +# Consult wpa_supplicant for more drivers +# By default don't wait for wpa_suppliant to associate and authenticate. +# If you would like to, so can specify how long in seconds +associate_timeout_eth0=60 +# A value of 0 means wait forever. + +# GENERIC WIRELESS OPTIONS +# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR +# HOW TO USE THIS ESSID VARIABLE +# You can also override any settings found here per ESSID - which is very +# handy if you use different networks a lot +config_ESSID=( "dhcp" ) +dhcpcd_ESSID="-t 5" + +# Setting name/domain server causes /etc/resolv.conf to be overwritten +# Note that if DHCP is used, and you want this to take precedence then + set dhcp_ESSID="nodns" +dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" ) +dns_domain_ESSID="some.domain" +dns_search_ESSID="search.this.domain search.that.domain" +# Please check the man page for resolv.conf for more information +# as domain and search are mutually exclusive. + +# You can also override any settings found here per MAC address of the AP +# in case you use Access Points with the same ESSID but need different +# networking configs. Below is an example - of course you use the same +# method with other variables +mac_config_001122334455=( "dhcp" ) +mac_dhcpcd_001122334455="-t 10" +mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" ) + +# When an interface has been associated with an Access Point, a global +# variable called ESSID is set to the Access Point's ESSID for use in the +# pre/post user functions below (although it's not available in preup as you +# won't have associated then) + +# If you're using anything else to configure wireless on your interface AND +# you have installed any of the above packages, you need to disable them +modules=( "!iwconfig" "!wpa_supplicant" ) + +#----------------------------------------------------------------------------- +# DHCP +# DHCP can be provided by dhclient, dhcpcd, pump or udhcpc. +# +# dhclient: emerge net-misc/dhcp +# dhcpcd: emerge net-misc/dhcpcd +# pump: emerge net-misc/pump +# udhcpc: emerge net-misc/udhcp + +# If you have more than one DHCP client installed, you need to specify which +# one to use - otherwise we default to dhcpcd if available. +modules=( "dhclient" ) # to select dhclient over dhcpcd +# +# Notes: +# - All clients send the current hostname to the DHCP server by default +# - dhcpcd does not daemonize when the lease time is infinite +# - udhcp-0.9.3-r3 and earlier do not support getting NTP servers +# - pump does not support getting NIS servers +# - DHCP tends to erase any existing device information - so add +# static addresses after dhcp if you need them +# - dhclient and udhcpc can set other resolv.conf options such as "option" +# and "sortlist"- see the System module for more details + +# Regardless of which DHCP client you prefer, you configure them the +# same way using one of following depending on which interface modules +# you're using. +config_eth0=( "dhcp" ) + +# For passing custom options to dhcpcd use something like the following. This +# example reduces the timeout for retrieving an address from 60 seconds (the +# default) to 10 seconds. +dhcpcd_eth0="-t 10" + +# dhclient, udhcpc and pump don't have many runtime options +# You can pass options to them in a similar manner to dhcpcd though +dhclient_eth0="..." +udhcpc_eth0="..." +pump_eth0="..." + +# GENERIC DHCP OPTIONS +# Set generic DHCP options like so +dhcp_eth0="release nodns nontp nonis nogateway nosendhost" + +# This tells the dhcp client to release it's lease when it stops, not to +# overwrite dns, ntp and nis settings, not to set a default route and not to +# send the current hostname to the dhcp server and when it starts. +# You can use any combination of the above options - the default is not to +# use any of them. + +#----------------------------------------------------------------------------- +# For APIPA support, emerge net-misc/iputils or net-analyzer/arping + +# APIPA is a module that tries to find a free address in the range +# 169.254.0.0-169.254.255.255 by arping a random address in that range on the +# interface. If no reply is found then we assign that address to the interface + +# This is only useful for LANs where there is no DHCP server and you don't +# connect directly to the internet. +config_eth0=( "dhcp" ) +fallback_eth0=( "apipa" ) + +#----------------------------------------------------------------------------- +# ARPING Gateway configuration +# and +# Automatic Private IP Addressing (APIPA) +# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping +# +# This is a module that tries to find a gateway IP. If it exists then we use +# that gateways configuration for our own. For the configuration variables +# simply ensure that each octet is zero padded and the dots are removed. +# Below is an example. +# +gateways_eth0="192.168.0.1 10.0.0.1" +config_192168000001=( "192.168.0.2/24" ) +routes_192168000001=( "default via 192.168.0.1" ) +dns_servers_192168000001=( "192.168.0.1" ) +config_010000000001=( "10.0.0.254/8" ) +routes_010000000001=( "default via 10.0.0.1" ) +dns_servers_010000000001=( "10.0.0.1" ) + +# We can also specify a specific MAC address for each gateway if different +# networks have the same gateway. +gateways_eth0="192.168.0.1,00:11:22:AA:BB:CC 10.0.0.1,33:44:55:DD:EE:FF" +config_192168000001_001122AABBCC=( "192.168.0.2/24" ) +routes_192168000001_001122AABBCC=( "default via 192.168.0.1" ) +dns_servers_192168000001_001122AABBCC=( "192.168.0.1" ) +config_010000000001_334455DDEEFF=( "10.0.0.254/8" ) +routes_010000000001_334455DDEEFF=( "default via 10.0.0.1" ) +dns_servers_010000000001_334455DDEEFF=( "10.0.0.1" ) + +# If we don't find any gateways (or there are none configured) then we try and +# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255 +# by arping a random address in that range on the interface. If no reply is +# found then we assign that address to the interface. + +# This is only useful for LANs where there is no DHCP server. +config_eth0=( "arping" ) + +# or if no DHCP server can be found +config_eth0=( "dhcp" ) +fallback_eth0=( "arping" ) + +# NOTE: We default to sleeping for 1 second the first time we attempt an +# arping to give the interface time to settle on the LAN. This appears to +# be a good default for most instances, but if not you can alter it here. +arping_sleep=5 +arping_sleep_lan=7 + +# NOTE: We default to waiting 3 seconds to get an arping response. You can +# change the default wait like so. +arping_wait=3 +arping_wait_lan=2 + +#----------------------------------------------------------------------------- +# VLAN (802.1q support) +# For VLAN support, emerge net-misc/vconfig + +# Specify the VLAN numbers for the interface like so +# Please ensure your VLAN IDs are NOT zero-padded +vlans_eth0="1 2" + +# You may not want to assign an IP the the physical interface, but we still +# need it up. +config_eth0=( "null" ) + +# You can also configure the VLAN - see for vconfig man page for more details +vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" ) +vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" ) +config_vlan1=( "172.16.3.1 netmask 255.255.254.0" ) +config_vlan2=( "172.16.2.1 netmask 255.255.254.0" ) + +# NOTE: Vlans can be configured with a . in their interface names +# When configuring vlans with this name type, you need to replace . with a _ +config_eth0.1=( "dhcp" ) - does not work +config_eth0_1=( "dhcp" ) - does work + +# NOTE: Vlans are controlled by their physical interface and not per vlan +# This means you do not need to create init scripts in /etc/init.d for each +# vlan, you must need to create one for the physical interface. +# If you wish to control the configuration of each vlan through a separate +# script, or wish to rename the vlan interface to something that vconfig +# cannot then you need to do this. +vlan_start_eth0="no" + +# If you do the above then you may want to depend on eth0 like so + RC_NEED_vlan1="net.eth0" +# NOTE: depend functions only work in /etc/conf.d/net +# and not in profile configs such as /etc/conf.d/net.foo + +#----------------------------------------------------------------------------- +# Bonding +# For link bonding/trunking emerge net-misc/ifenslave + +# To bond interfaces together +slaves_bond0="eth0 eth1 eth2" +config_bond0=( "null" ) # You may not want to assign an IP the the bond + +# If any of the slaves require extra configuration - for example wireless or +# ppp devices - we need to depend function on the bonded interfaces +RC_NEED_bond0="net.eth0 net.eth1" + + +#----------------------------------------------------------------------------- +# Classical IP over ATM +# For CLIP support emerge net-dialup/linux-atm + +# Ensure that you have /etc/atmsigd.conf setup correctly +# Now setup each clip interface like so +clip_atm0=( "peer_ip [if.]vpi.vci [opts]" ... ) +# where "peer_ip" is the IP address of a PVC peer (in case of an ATM connection +# with your ISP, your only peer is usually the ISP gateway closest to you), +# "if" is the number of the ATM interface which will carry the PVC, "vpi.vci" +# is the ATM VC address, and "opts" may optionally specify VC parameters like +# qos, pcr, and the like (see "atmarp -s" for further reference). Please also +# note quoting: it is meant to distinguish the VCs you want to create. You may, +# in example, create an atm0 interface to more peers, like this: +clip_atm0=( "1.1.1.254 0.8.35" "1.1.1.253 1.8.35" ) + +# By default, the PVC will use the LLC/SNAP encapsulation. If you rather need a +# null encapsulation (aka "VC mode"), please add the keyword "null" to opts. + + +#----------------------------------------------------------------------------- +# PPP +# For PPP support, emerge net-dialup/ppp +# PPP is used for most dialup connections, including ADSL. +# The older ADSL module is documented below, but you are encouraged to try +# this module first. +# +# You need to create the PPP net script yourself. Make it like so +#ln -s net.lo /etc/init.d/net.ppp0 +# +# We have to instruct ppp0 to actually use ppp +config_ppp0=( "ppp" ) +# +# Each PPP interface requires an interface to use as a "Link" +link_ppp0="/dev/ttyS0" # Most PPP links will use a serial port +link_ppp0="eth0" # PPPoE requires an ethernet interface +link_ppp0="[itf.]vpi.vci" # PPPoA requires the ATM VC's address +link_ppp0="/dev/null" # ISDN links should have this +link_ppp0="pty 'your_link_command'" # PPP links over ssh, rsh, etc +# +# Here you should specify what pppd plugins you want to use +# Available plugins are: pppoe, pppoa, capi, dhcpc, minconn, radius, +# radattr, radrealms and winbind +plugins_ppp0=( + "pppoe" # Required plugin for PPPoE + "pppoa vc-encaps" # Required plugin for PPPoA with an option + "capi" # Required plugin for ISDN +) +# +# PPP requires at least a username. You can optionally set a password here too +# If you don't, then it will use the password specified in /etc/ppp/*-secrets +# against the specified username +username_ppp0='user' +password_ppp0='password' +# NOTE: You can set a blank password like so +password_ppp0= +# +# The PPP daemon has many options you can specify - although there are many +# and may seem daunting, it is recommended that you read the pppd man page +# before enabling any of them +pppd_ppp0=( + "maxfail 0" # WARNING: It's not recommended you use this + # if you don't specify maxfail then we assume 0 + "updetach" # If not set, "/etc/init.d/net.ppp0 start" will return + # immediately, without waiting the link to come up + # for the first time. + # Do not use it for dial-on-demand links! + "debug" # Enables syslog debugging + "noauth" # Do not require the peer to authenticate itself + "defaultroute" # Make this PPP interface the default route + "usepeerdns" # Use the DNS settings provided by PPP + +# On demand options + "demand" # Enable dial on demand + "idle 30" # Link goes down after 30 seconds of inactivity + "10.112.112.112:10.112.112.113" # Phony IP addresses + "ipcp-accept-remote" # Accept the peers idea of remote address + "ipcp-accept-local" # Accept the peers idea of local address + "holdoff 3" # Wait 3 seconds after link dies before re-starting + +# Dead peer detection + "lcp-echo-interval 15" # Send a LCP echo every 15 seconds + "lcp-echo-failure 3" # Make peer dead after 3 consective + # echo-requests + +# Compression options - use these to completely disable compression +# noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp + +# Dial-up settings + "lock" # Lock serial port + "115200" # Set the serial port baud rate + "modem crtscts" # Enable hardware flow control + "192.168.0.1:192.168.0.2" # Local and remote IP addresses +) +# +# Dial-up PPP users need to specify at least one telephone number +phone_number_ppp0=( "12345689" ) # Maximum 2 phone numbers are supported +# They will also need a chat script - here's a good one +chat_ppp0=( +# 'ABORT' 'BUSY' +# 'ABORT' 'ERROR' +# 'ABORT' 'NO ANSWER' +# 'ABORT' 'NO CARRIER' +# 'ABORT' 'NO DIALTONE' +# 'ABORT' 'Invalid Login' +# 'ABORT' 'Login incorrect' +# 'TIMEOUT' '5' +# '' 'ATZ' +# 'OK' 'AT' # Put your modem initialization string here +# 'OK' 'ATDT\T' +# 'TIMEOUT' '60' +# 'CONNECT' '' +# 'TIMEOUT' '5' +# '~--' '' +) + +# If the link require extra configuration - for example wireless or +# RFC 268 bridge - we need to depend on the bridge so they get +# configured correctly. +RC_NEED_ppp0="net.nas0" + +#WARNING: if MTU of the PPP interface is less than 1500 and you use this +#machine as a router, you should add the following rule to your firewall +# +#iptables -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + +#----------------------------------------------------------------------------- +# ADSL +# For ADSL support, emerge net-dialup/rp-pppoe +# WARNING: This ADSL module is being deprecated in favour of the PPP module +# above. +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ADSL +config_eth0=( "adsl" ) + +# You probably won't need to edit /etc/ppp/pppoe.conf if you set this +adsl_user_eth0="my-adsl-username" + +#----------------------------------------------------------------------------- +# ISDN +# For ISDN support, emerge net-dialup/isdn4k-utils +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ISDN +config_ippp0=( "dhcp" ) +# It's important to specify dhcp if you need it! +config_ippp0=( "192.168.0.1/24" ) +# Otherwise, you can use a static IP + +# NOTE: The interface name must be either ippp or isdn followed by a number + +# You may need this option to set the default route +ipppd_eth0="defaultroute" + +#----------------------------------------------------------------------------- +# MAC changer +# To set a specific MAC address +mac_eth0="00:11:22:33:44:55" + +# For changing MAC addresses using the below, emerge net-analyzer/macchanger +# - to randomize the last 3 bytes only +mac_eth0="random-ending" +# - to randomize between the same physical type of connection (e.g. fibre, +# copper, wireless) , all vendors +mac_eth0="random-samekind" +# - to randomize between any physical type of connection (e.g. fibre, copper, +# wireless) , all vendors +mac_eth0="random-anykind" +# - full randomization - WARNING: some MAC addresses generated by this may NOT +# act as expected +mac_eth0="random-full" +# custom - passes all parameters directly to net-analyzer/macchanger +mac_eth0="some custom set of parameters" + +# You can also set other options based on the MAC address of your network card +# Handy if you use different docking stations with laptops +config_001122334455=( "dhcp" ) + +#----------------------------------------------------------------------------- +# TUN/TAP +# For TUN/TAP support emerge net-misc/openvpn or sys-apps/usermode-utilities +# +# You must specify if we're a tun or tap device. Then you can give it any +# name you like - such as vpn +tuntap_vpn="tun" +config_vpn=( "192.168.0.1/24") + +# Or stick wit the generic names - like tap0 +tuntap_tap0="tap" +config_tap0=( "192.168.0.1/24") + +# For passing custom options to tunctl use something like the following. This +# example sets the owner to adm +tunctl_tun1="-u adm" +# When using openvpn, there are no options + +#----------------------------------------------------------------------------- +# Bridging (802.1d) +# For bridging support emerge net-misc/bridge-utils + +# To add ports to bridge br0 +bridge_br0="eth0 eth1" +# or dynamically add them when the interface comes up +bridge_add_eth0="br0" +bridge_add_eth1="br0" + +# You need to configure the ports to null values so dhcp does not get started +config_eth0=( "null" ) +config_eth1=( "null" ) + +# Finally give the bridge an address - dhcp or a static IP +config_br0=( "dhcp" ) # may not work when adding ports dynamically +config_br0=( "192.168.0.1/24" ) + +# If any of the ports require extra configuration - for example wireless or +# ppp devices - we need to depend on them like so. +RC_NEED_br0="net.eth0 net.eth1" + +# Below is an example of configuring the bridge +# Consult "man brctl" for more details +brctl_br0=( "setfd 0" "sethello 0" "stp off" ) + +#----------------------------------------------------------------------------- +# RFC 2684 Bridge Support +# For RFC 2684 bridge support emerge net-misc/br2684ctl + +# Interface names have to be of the form nas0, nas1, nas2, etc. +# You have to specify a VPI and VCI for the interface like so +br2684ctl_nas0="-a 0.38" # UK VPI and VCI + +# You may want to configure the encapsulation method as well by adding the -e +# option to the command above (may need to be before the -a command) +# -e 0 # LLC (default) +# -e 1 # VC mux + +# Then you can configure the interface as normal +config_nas0=( "192.168.0.1/24" ) + +#----------------------------------------------------------------------------- +# Tunnelling +# WARNING: For tunnelling it is highly recommended that you +# emerge sys-apps/iproute2 +# +# For GRE tunnels +iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255" + +# For IPIP tunnels +iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255" + +# To configure the interface +config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style +config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style + +# 6to4 Tunnels allow IPv6 to work over IPv4 addresses, provided you +# have a non-private address configured on an interface. + link_6to4="eth0" # Interface to base it's addresses on + config_6to4=( "ip6to4" ) +# You may want to depend on eth0 like so +RC_NEED_6to4="net.eth0" +# To ensure that eth0 is configured before 6to4. Of course, the tunnel could be +# any name and this also works for any configured interface. +# NOTE: If you're not using iproute2 then your 6to4 tunnel has to be called +# sit0 - otherwise use a different name like 6to4 in the example above. + + +#----------------------------------------------------------------------------- +# System +# For configuring system specifics such as domain, dns, ntp and nis servers +# It's rare that you would need todo this, but you can anyway. +# This is most benefit to wireless users who don't use DHCP so they can change +# their configs based on ESSID. See wireless.example for more details + +# To use dns settings such as these, dns_servers_eth0 must be set! +# If you omit the _eth0 suffix, then it applies to all interfaces unless +# overridden by the interface suffix. +dns_domain_eth0="your.domain" +dns_servers_eth0="192.168.0.2 192.168.0.3" +dns_search_eth0="this.domain that.domain" +dns_options_eth0=( "timeout 1" "rotate" ) +dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0" +# See the man page for resolv.conf for details about the options and sortlist +# directives + +ntp_servers_eth0="192.168.0.2 192.168.0.3" + +nis_domain_eth0="domain" +nis_servers_eth0="192.168.0.2 192.168.0.3" + +# NOTE: Setting any of these will stamp on the files in question. So if you +# don't specify dns_servers but you do specify dns_domain then no nameservers +# will be listed in /etc/resolv.conf even if there were any there to start +# with. +# If this is an issue for you then maybe you should look into a resolv.conf +# manager like resolvconf-gentoo to manage this file for you. All packages +# that baselayout supports use resolvconf-gentoo if installed. + +#----------------------------------------------------------------------------- +# Cable in/out detection +# Sometimes the cable is in, others it's out. Obviously you don't want to +# restart net.eth0 every time when you plug it in either. +# +# netplug is a package that detects this and requires no extra configuration +# on your part. +# emerge sys-apps/netplug +# or +# emerge sys-apps/ifplugd +# and you're done :) + +# By default we don't wait for netplug/ifplugd to configure the interface. +# If you would like it to wait so that other services now that network is up +# then you can specify a timeout here. +plug_timeout="10" +# A value of 0 means wait forever. + +# If you don't want to use netplug on a specific interface but you have it +# installed, you can disable it for that interface via the modules statement +modules_eth0=( "!netplug" ) +# You can do the same for ifplugd +# +# You can disable them both with the generic plug +modules_eth0=( "!plug" ) + +# To use specific ifplugd options, fex specifying wireless mode +ifplugd_eth0="--api-mode=wlan" +# man ifplugd for more options + +############################################################################## +# ADVANCED CONFIGURATION +# +# Four functions can be defined which will be called surrounding the +# start/stop operations. The functions are called with the interface +# name first so that one function can control multiple adapters. An extra two +# functions can be defined when an interface fails to start or stop. +# +# The return values for the preup and predown functions should be 0 +# (success) to indicate that configuration or deconfiguration of the +# interface can continue. If preup returns a non-zero value, then +# interface configuration will be aborted. If predown returns a +# non-zero value, then the interface will not be allowed to continue +# deconfiguration. +# +# The return values for the postup, postdown, failup and faildown functions are +# ignored since there's nothing to do if they indicate failure. +# +# ${IFACE} is set to the interface being brought up/down +# ${IFVAR} is ${IFACE} converted to variable name bash allows + +#preup() { +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the mii-diag +# # package to be installed. +# if mii-tool "${IFACE}" 2> /dev/null | grep -q 'no link'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the ethtool +# # package to be installed. +# if ethtool "${IFACE}" | grep -q 'Link detected: no'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# +# # Remember to return 0 on success +# return 0 +#} + +#predown() { +# # The default in the script is to test for NFS root and disallow +# # downing interfaces in that case. Note that if you specify a +# # predown() function you will override that logic. Here it is, in +# # case you still want it... +# if is_net_fs /; then +# eerror "root filesystem is network mounted -- can't stop ${IFACE}" +# return 1 +# fi +# +# # Remember to return 0 on success +# return 0 +#} + +#postup() { +# # This function could be used, for example, to register with a +# # dynamic DNS service. Another possibility would be to +# # send/receive mail once the interface is brought up. + +# # Here is an example that allows the use of iproute rules +# # which have been configured using the rules_eth0 variable. +# #rules_eth0=( +# # "from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100" +# # "from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100" +# #) +# local x="rules_${IFVAR}[@]" +# local -a rules=( "${!x}" ) +# if [[ -n ${rules} ]] ; then +# einfo "Adding IP policy routing rules" +# eindent +# # Ensure that the kernel supports policy routing +# if ! ip rule list | grep -q "^" ; then +# eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" +# eerror "in your kernel to use ip rules" +# else +# for x in "${rules[@]}" ; do +# ebegin "${x}" +# ip rule add ${x} dev "${IFACE}" +# eend $? +# done +# fi +# eoutdent +# # Flush the cache +# ip route flush cache dev "${IFACE}" +# fi + +#} + +#postdown() { +# # Enable Wake-On-LAN for every interface except for lo +# # Probably a good idea to set RC_DOWN_INTERFACE="no" in /etc/conf.d/rc +# # as well ;) +# [[ ${IFACE} != "lo" ]] && ethtool -s "${IFACE}" wol g + +# Automatically erase any ip rules created in the example postup above +# if interface_exists "${IFACE}" ; then +# # Remove any rules for this interface +# local rule +# ip rule list | grep " iif ${IFACE}[ ]*" | { +# while read rule ; do +# rule="${rule#*:}" +# ip rule del ${rule} +# done +# } +# # Flush the route cache +# ip route flush cache dev "${IFACE}" +# fi + +# # Return 0 always +# return 0 +#} + +#failup() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +#faildown() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +############################################################################## +# FORCING MODULES +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! +# +# Loading modules is a slow affair - we have to check each one for the following +# 1) Code sanity +# 2) Has the required package been emerged? +# 3) Has it modified anything? +# 4) Have all the dependant modules been loaded? + +# Then we have to strip out the conflicting modules based on user preference +# and default configuration and sort them into the correct order. +# Finally we check the end result for dependencies. + +# This, of course, takes valuable CPU time so we provide module forcing as a +# means to speed things up. We still do *some* checking but not much. + +# It is essential that you force modules in the correct order and supply all +# the modules you need. You must always supply an interface module - we +# supply ifconfig or iproute2. + +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! + +# Now that we've warned you twice, here's how to do it +modules_force=( "ifconfig" ) +modules_force=( "iproute2" "dhcpcd" ) + +# We can also apply this to a specific interface +modules_force_eth1=( "iproute2" ) + +# The below will not work +modules_force=( "dhcpcd" ) +# No interface (ifconfig/iproute2) +modules_force=( "ifconfig" "essidnet" "iwconfig" ) +# Although it will not crash, essidnet will not work as it has to come after +# iwconfig +modules_force=( "iproute2" "ifconfig" ) +# The interface will be setup twice which will cause problems diff --git a/src/settings/plugins/ifnet/tests/nm-system-settings.conf b/src/settings/plugins/ifnet/tests/nm-system-settings.conf new file mode 100644 index 00000000..39bc87b8 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/nm-system-settings.conf @@ -0,0 +1,5 @@ +[main] +plugins=ifnet,keyfile + +[ifnet] +managed=false diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c new file mode 100644 index 00000000..d114bbba --- /dev/null +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -0,0 +1,399 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <nm-utils.h> + +#include "net_parser.h" +#include "nm-test-helpers.h" +#include "net_utils.h" +#include "wpa_parser.h" +#include "connection_parser.h" + +static void +test_getdata () +{ + ASSERT (ifnet_get_data ("eth1", "config") + && strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0, + "get data", "config_eth1 is not correct"); + ASSERT (ifnet_get_data ("ppp0", "username") + && strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0, + "get data", "config_ppp0 username is not correctly read"); + ASSERT (ifnet_get_data ("ppp0", "password") + && strcmp (ifnet_get_data ("ppp0", "password"), + "password") == 0, "get data", + "config_ppp0 password is not correctly read"); +} + +static void +test_read_hostname () +{ + gchar *hostname = read_hostname ("hostname"); + + ASSERT (hostname != NULL, "get hostname", "hostname is NULL"); + ASSERT (strcmp ("gentoo", hostname) == 0, + "get hostname", + "hostname is not correctly read, read:%s, expected: gentoo", + hostname); + g_free (hostname); +} + +static void +test_write_hostname () +{ + gchar *hostname = read_hostname ("hostname"); + gchar *tmp; + + write_hostname ("gentoo-nm", "hostname"); + tmp = read_hostname ("hostname"); + ASSERT (strcmp (tmp, "gentoo-nm") == 0, + "write hostname", "write hostname error"); + write_hostname (hostname, "hostname"); + g_free (tmp); + g_free (hostname); +} + +static void +test_is_static () +{ + ASSERT (is_static_ip4 ("eth1") == FALSE, "is static", + "a dhcp interface is recognized as static"); + ASSERT (is_static_ip4 ("eth0") == TRUE, "is static", + "a static interface is recognized as dhcp"); + ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static", + "a static interface is recognized as dhcp"); +} + +static void +test_has_default_route () +{ + ASSERT (has_default_ip4_route ("eth0"), + "has default route", "eth0 should have a default ipv4 route"); + ASSERT (has_default_ip6_route ("eth4"), + "has default route", "eth4 should have a default ipv6 route"); + ASSERT (!has_default_ip4_route ("eth5") + && !has_default_ip6_route ("eth5"), + "has default route", "eth5 shouldn't have a default route"); +} + +static void +test_has_ip6_address () +{ + ASSERT (has_ip6_address ("eth2"), "has ip6 address", + "eth2 should have a ipv6 address"); + ASSERT (!has_ip6_address ("eth0"), "has ip6 address", + "eth0 shouldn't have a ipv6 address") + +} + +static void +test_is_ip4_address () +{ + gchar *address1 = "192.168.4.232/24"; + gchar *address2 = "192.168.100.{1..254}/24"; + gchar *address3 = "192.168.4.2555/24"; + + ASSERT (is_ip4_address (address1), "is ip4 address", + "%s should be a valid address", address1); + ASSERT (is_ip4_address (address2), "is ip4 address", + "%s should be a valid address", address2); + ASSERT (!is_ip4_address (address3), "is ip4 address", + "%s should be an invalid address", address3); +} + +static void +test_is_ip6_address () +{ + gchar *address1 = "4321:0:1:2:3:4:567:89ac/24"; + + ASSERT (is_ip6_address (address1), "is ip6 address", + "%s should be a valid address", address1); +} + +static void +check_ip_block (ip_block * iblock, gchar * ip, gchar * netmask, gchar * gateway) +{ + char *str; + struct in_addr tmp_ip4_addr; + + str = malloc (INET_ADDRSTRLEN); + tmp_ip4_addr.s_addr = iblock->ip; + inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); + ASSERT (strcmp (ip, str) == 0, "check ip", + "ip expected:%s, find:%s", ip, str); + tmp_ip4_addr.s_addr = iblock->netmask; + inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); + ASSERT (strcmp (netmask, str) == 0, "check netmask", + "netmask expected:%s, find:%s", netmask, str); + tmp_ip4_addr.s_addr = iblock->gateway; + inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); + ASSERT (strcmp (gateway, str) == 0, "check gateway", + "gateway expected:%s, find:%s", gateway, str); + free (str); +} + +static void +test_convert_ipv4_config_block () +{ + ip_block *iblock = convert_ip4_config_block ("eth0"); + ip_block *tmp = iblock; + + ASSERT (iblock != NULL, "convert ipv4 block", + "block eth0 should not be NULL"); + check_ip_block (iblock, "202.117.16.121", "255.255.255.0", + "202.117.16.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + ASSERT (iblock != NULL, "convert ipv4 block", + "block eth0 should have a second IP address"); + check_ip_block (iblock, "192.168.4.121", "255.255.255.0", + "202.117.16.1"); + destroy_ip_block (iblock); + iblock = convert_ip4_config_block ("eth2"); + ASSERT (iblock != NULL + && iblock->next == NULL, + "convert error IPv4 address", "should only get one address"); + check_ip_block (iblock, "192.168.4.121", "255.255.255.0", "0.0.0.0"); + destroy_ip_block (iblock); + iblock = convert_ip4_config_block ("eth3"); + ASSERT (iblock == NULL, "convert config_block", + "convert error configuration"); + destroy_ip_block (iblock); + iblock = convert_ip4_config_block ("eth6"); + ASSERT (iblock != NULL, "convert config_block", + "convert error configuration"); + destroy_ip_block (iblock); +} + +static void +test_convert_ipv4_routes_block () +{ + ip_block *iblock = convert_ip4_routes_block ("eth0"); + ip_block *tmp = iblock; + + ASSERT (iblock != NULL, "convert ip4 routes", "should get one route"); + check_ip_block (iblock, "192.168.4.0", "255.255.255.0", "192.168.4.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + ASSERT (iblock == NULL, "convert ip4 routes", + "should only get one route"); +} + +static void +test_wpa_parser () +{ + const char *value; + + ASSERT (exist_ssid ("example"), "get wsec", + "ssid myxjtu2 is not found"); + ASSERT (exist_ssid ("static-wep-test"), "exist_ssid", + "ssid static-wep-test is not found"); + value = wpa_get_value ("static-wep-test", "key_mgmt"); + ASSERT (value + && strcmp (value, "NONE") == 0, "get wpa data", + "key_mgmt of static-wep-test should be NONE, find %s", value); + value = wpa_get_value ("static-wep-test", "wep_key0"); + ASSERT (value + && strcmp (value, "\"abcde\"") == 0, + "get wpa data", + "wep_key0 of static-wep-test should be abcde, find %s", value); + ASSERT (exist_ssid ("leap-example"), "get wsec", + "ssid leap-example is not found"); +} + +static void +test_strip_string () +{ + gchar *str = "( \"default via 202.117.16.1\" )"; + gchar *result = g_strdup (str); + gchar *result_b = result; + + result = strip_string (result, '('); + result = strip_string (result, ')'); + result = strip_string (result, '"'); + ASSERT (strcmp (result, "default via 202.117.16.1") == + 0, "strip_string", + "string isn't stripped, result is: %s", result); + g_free (result_b); +} + +static void +test_is_unmanaged () +{ + ASSERT (is_managed ("eth0"), "test_is_unmanaged", + "eth0 should be managed"); + ASSERT (!is_managed ("eth4"), "test_is_unmanaged", + "eth4 should be unmanaged"); +} + +static void +test_new_connection () +{ + GError **error = NULL; + NMConnection *connection; + + connection = ifnet_update_connection_from_config_block ("eth2", error); + ASSERT (connection != NULL, "new connection", + "new connection failed: %s", + error == NULL ? "None" : (*error)->message); + g_object_unref (connection); + connection = + ifnet_update_connection_from_config_block ("qiaomuf", error); + ASSERT (connection != NULL, "new connection", + "new connection failed: %s", error + && (*error) ? (*error)->message : "NONE"); + g_object_unref (connection); + connection = + ifnet_update_connection_from_config_block ("myxjtu2", error); + ASSERT (connection != NULL, "new connection", + "new connection failed: %s", error + && (*error) ? (*error)->message : "NONE"); + g_object_unref (connection); +} + +#define NET_GEN_NAME "net.generate" +#define SUP_GEN_NAME "wpa_supplicant.conf.generate" + +static void +test_update_connection () +{ + GError **error = NULL; + NMConnection *connection; + gboolean success; + + connection = ifnet_update_connection_from_config_block ("eth0", error); + ASSERT (connection != NULL, "get connection", + "get connection failed: %s", + error == NULL ? "None" : (*error)->message); + + success = ifnet_update_parsers_by_connection (connection, "eth0", + NET_GEN_NAME, + SUP_GEN_NAME, + NULL, + error); + ASSERT (success, "update connection", "update connection failed %s", "eth0"); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("0xab3ace", error); + ASSERT (connection != NULL, "get connection", "get connection failed: %s", + error == NULL ? "None" : (*error)->message); + + success = ifnet_update_parsers_by_connection (connection, "0xab3ace", + NET_GEN_NAME, + SUP_GEN_NAME, + NULL, + error); + ASSERT (success, "update connection", "update connection failed %s", "0xab3ace"); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +test_add_connection () +{ + NMConnection *connection; + + connection = ifnet_update_connection_from_config_block ("eth0", NULL); + ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL), + "add connection", "add connection failed: %s", "eth0"); + g_object_unref (connection); + connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL); + ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL), + "add connection", "add connection failed: %s", "myxjtu2"); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +test_delete_connection () +{ + GError *error = NULL; + NMConnection *connection; + + connection = ifnet_update_connection_from_config_block ("eth7", &error); + ASSERT (connection != NULL, "get connection", + "get connection failed: %s", + error ? error->message : "None"); + ASSERT (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME), + "delete connection", "delete connection failed: %s", "eth7"); + g_object_unref (connection); + connection = ifnet_update_connection_from_config_block ("qiaomuf", &error); + ASSERT (connection != NULL, "get connection", + "get connection failed: %s", + error ? error->message : "None"); + ASSERT (ifnet_delete_connection_in_parsers ("qiaomuf", NET_GEN_NAME, SUP_GEN_NAME), + "delete connection", "delete connection failed: %s", "qiaomuf"); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +run_all (gboolean run) +{ + if (run) { + test_strip_string (); + test_is_static (); + test_has_ip6_address (); + test_has_default_route (); + test_getdata (); + test_read_hostname (); + test_write_hostname (); + test_is_ip4_address (); + test_is_ip6_address (); + test_convert_ipv4_config_block (); + test_convert_ipv4_routes_block (); + test_is_unmanaged (); + test_wpa_parser (); + test_convert_ipv4_routes_block (); + test_new_connection (); + test_update_connection (); + test_add_connection (); + test_delete_connection (); + } +} + +int +main (void) +{ +// g_mem_set_vtable(glib_mem_profiler_table); +// g_atexit(g_mem_profile); + g_type_init (); + ifnet_destroy (); + wpa_parser_destroy (); + ifnet_init ("net"); + wpa_parser_init ("wpa_supplicant.conf"); + printf ("Initialization complete\n"); + run_all (TRUE); + ifnet_destroy (); + wpa_parser_destroy (); + return 0; +} diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf new file mode 100644 index 00000000..a2595d42 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf @@ -0,0 +1,864 @@ +##### Example wpa_supplicant configuration file ############################### +# +# This file describes configuration file format and lists all available option. +# Please also take a look at simpler configuration examples in 'examples' +# subdirectory. +# +# Empty lines and lines starting with # are ignored + +# NOTE! This file may contain password information and should probably be made +# readable only by root user on multiuser systems. + +# Note: All file paths in this configuration file should use full (absolute, +# not relative to working directory) path in order to allow working directory +# to be changed. This can happen if wpa_supplicant is run in the background. + +# Whether to allow wpa_supplicant to update (overwrite) configuration +# +# This option can be used to allow wpa_supplicant to overwrite configuration +# file whenever configuration is changed (e.g., new network block is added with +# wpa_cli or wpa_gui, or a password is changed). This is required for +# wpa_cli/wpa_gui to be able to store the configuration changes permanently. +# Please note that overwriting configuration file will remove the comments from +# it. +#update_config=1 + +# global configuration (shared by all network blocks) +# +# Parameters for the control interface. If this is specified, wpa_supplicant +# will open a control interface that is available for external programs to +# manage wpa_supplicant. The meaning of this string depends on which control +# interface mechanism is used. For all cases, the existance of this parameter +# in configuration is used to determine whether the control interface is +# enabled. +# +# For UNIX domain sockets (default on Linux and BSD): This is a directory that +# will be created for UNIX domain sockets for listening to requests from +# external programs (CLI/GUI, etc.) for status information and configuration. +# The socket file will be named based on the interface name, so multiple +# wpa_supplicant processes can be run at the same time if more than one +# interface is used. +# /var/run/wpa_supplicant is the recommended directory for sockets and by +# default, wpa_cli will use it when trying to connect with wpa_supplicant. +# +# Access control for the control interface can be configured by setting the +# directory to allow only members of a group to use sockets. This way, it is +# possible to run wpa_supplicant as root (since it needs to change network +# configuration and open raw sockets) and still allow GUI/CLI components to be +# run as non-root users. However, since the control interface can be used to +# change the network configuration, this access needs to be protected in many +# cases. By default, wpa_supplicant is configured to use gid 0 (root). If you +# want to allow non-root users to use the control interface, add a new group +# and change this value to match with that group. Add users that should have +# control interface access to this group. If this variable is commented out or +# not included in the configuration file, group will not be changed from the +# value it got by default when the directory or socket was created. +# +# When configuring both the directory and group, use following format: +# DIR=/var/run/wpa_supplicant GROUP=wheel +# DIR=/var/run/wpa_supplicant GROUP=0 +# (group can be either group name or gid) +# +# For UDP connections (default on Windows): The value will be ignored. This +# variable is just used to select that the control interface is to be created. +# The value can be set to, e.g., udp (ctrl_interface=udp) +# +# For Windows Named Pipe: This value can be used to set the security descriptor +# for controlling access to the control interface. Security descriptor can be +# set using Security Descriptor String Format (see http://msdn.microsoft.com/ +# library/default.asp?url=/library/en-us/secauthz/security/ +# security_descriptor_string_format.asp). The descriptor string needs to be +# prefixed with SDDL=. For example, ctrl_interface=SDDL=D: would set an empty +# DACL (which will reject all connections). See README-Windows.txt for more +# information about SDDL string format. +# +ctrl_interface=/var/run/wpa_supplicant + +# IEEE 802.1X/EAPOL version +# wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which defines +# EAPOL version 2. However, there are many APs that do not handle the new +# version number correctly (they seem to drop the frames completely). In order +# to make wpa_supplicant interoperate with these APs, the version number is set +# to 1 by default. This configuration value can be used to set it to the new +# version (2). +eapol_version=1 + +# AP scanning/selection +# By default, wpa_supplicant requests driver to perform AP scanning and then +# uses the scan results to select a suitable AP. Another alternative is to +# allow the driver to take care of AP scanning and selection and use +# wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association +# information from the driver. +# 1: wpa_supplicant initiates scanning and AP selection +# 0: driver takes care of scanning, AP selection, and IEEE 802.11 association +# parameters (e.g., WPA IE generation); this mode can also be used with +# non-WPA drivers when using IEEE 802.1X mode; do not try to associate with +# APs (i.e., external program needs to control association). This mode must +# also be used when using wired Ethernet drivers. +# 2: like 0, but associate with APs using security policy and SSID (but not +# BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to +# enable operation with hidden SSIDs and optimized roaming; in this mode, +# the network blocks in the configuration file are tried one by one until +# the driver reports successful association; each network block should have +# explicit security policy (i.e., only one option in the lists) for +# key_mgmt, pairwise, group, proto variables +ap_scan=1 + +# EAP fast re-authentication +# By default, fast re-authentication is enabled for all EAP methods that +# support it. This variable can be used to disable fast re-authentication. +# Normally, there is no need to disable this. +fast_reauth=1 + +# OpenSSL Engine support +# These options can be used to load OpenSSL engines. +# The two engines that are supported currently are shown below: +# They are both from the opensc project (http://www.opensc.org/) +# By default no engines are loaded. +# make the opensc engine available +#opensc_engine_path=/usr/lib64/engine_opensc.so +# make the pkcs11 engine available +#pkcs11_engine_path=/usr/lib64/engine_pkcs11.so +# configure the path to the pkcs11 module required by the pkcs11 engine +#pkcs11_module_path=/usr/lib64/opensc-pkcs11.so + +# Dynamic EAP methods +# If EAP methods were built dynamically as shared object files, they need to be +# loaded here before being used in the network blocks. By default, EAP methods +# are included statically in the build, so these lines are not needed +#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_tls.so +#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_md5.so + +# Driver interface parameters +# This field can be used to configure arbitrary driver interace parameters. The +# format is specific to the selected driver interface. This field is not used +# in most cases. +#driver_param="field=value" + +# Country code +# The ISO/IEC alpha2 country code for the country in which this device is +# currently operating. +#country=US + +# Maximum lifetime for PMKSA in seconds; default 43200 +#dot11RSNAConfigPMKLifetime=43200 +# Threshold for reauthentication (percentage of PMK lifetime); default 70 +#dot11RSNAConfigPMKReauthThreshold=70 +# Timeout for security association negotiation in seconds; default 60 +#dot11RSNAConfigSATimeout=60 + +# Wi-Fi Protected Setup (WPS) parameters + +# Universally Unique IDentifier (UUID; see RFC 4122) of the device +# If not configured, UUID will be generated based on the local MAC address. +#uuid=12345678-9abc-def0-1234-56789abcdef0 + +# Device Name +# User-friendly description of device; up to 32 octets encoded in UTF-8 +#device_name=Wireless Client + +# Manufacturer +# The manufacturer of the device (up to 64 ASCII characters) +#manufacturer=Company + +# Model Name +# Model of the device (up to 32 ASCII characters) +#model_name=cmodel + +# Model Number +# Additional device description (up to 32 ASCII characters) +#model_number=123 + +# Serial Number +# Serial number of the device (up to 32 characters) +#serial_number=12345 + +# Primary Device Type +# Used format: <categ>-<OUI>-<subcateg> +# categ = Category as an integer value +# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for +# default WPS OUI +# subcateg = OUI-specific Sub Category as an integer value +# Examples: +# 1-0050F204-1 (Computer / PC) +# 1-0050F204-2 (Computer / Server) +# 5-0050F204-1 (Storage / NAS) +# 6-0050F204-1 (Network Infrastructure / AP) +#device_type=1-0050F204-1 + +# OS Version +# 4-octet operating system version number (hex string) +#os_version=01020300 + +# Credential processing +# 0 = process received credentials internally (default) +# 1 = do not process received credentials; just pass them over ctrl_iface to +# external program(s) +# 2 = process received credentials internally and pass them over ctrl_iface +# to external program(s) +#wps_cred_processing=0 + +# network block +# +# Each network (usually AP's sharing the same SSID) is configured as a separate +# block in this configuration file. The network blocks are in preference order +# (the first match is used). +# +# network block fields: +# +# disabled: +# 0 = this network can be used (default) +# 1 = this network block is disabled (can be enabled through ctrl_iface, +# e.g., with wpa_cli or wpa_gui) +# +# id_str: Network identifier string for external scripts. This value is passed +# to external action script through wpa_cli as WPA_ID_STR environment +# variable to make it easier to do network specific configuration. +# +# ssid: SSID (mandatory); either as an ASCII string with double quotation or +# as hex string; network name +# +# scan_ssid: +# 0 = do not scan this SSID with specific Probe Request frames (default) +# 1 = scan with SSID-specific Probe Request frames (this can be used to +# find APs that do not accept broadcast SSID or use multiple SSIDs; +# this will add latency to scanning, so enable this only when needed) +# +# bssid: BSSID (optional); if set, this network block is used only when +# associating with the AP using the configured BSSID +# +# priority: priority group (integer) +# By default, all networks will get same priority group (0). If some of the +# networks are more desirable, this field can be used to change the order in +# which wpa_supplicant goes through the networks when selecting a BSS. The +# priority groups will be iterated in decreasing priority (i.e., the larger the +# priority value, the sooner the network is matched against the scan results). +# Within each priority group, networks will be selected based on security +# policy, signal strength, etc. +# Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are not +# using this priority to select the order for scanning. Instead, they try the +# networks in the order that used in the configuration file. +# +# mode: IEEE 802.11 operation mode +# 0 = infrastructure (Managed) mode, i.e., associate with an AP (default) +# 1 = IBSS (ad-hoc, peer-to-peer) +# Note: IBSS can only be used with key_mgmt NONE (plaintext and static WEP) +# and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). In addition, ap_scan has +# to be set to 2 for IBSS. WPA-None requires following network block options: +# proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not +# both), and psk must also be set. +# +# frequency: Channel frequency in megahertz (MHz) for IBSS, e.g., +# 2412 = IEEE 802.11b/g channel 1. This value is used to configure the initial +# channel for IBSS (adhoc) networks. It is ignored in the infrastructure mode. +# In addition, this value is only used by the station that creates the IBSS. If +# an IBSS network with the configured SSID is already present, the frequency of +# the network will be used instead of this configured value. +# +# proto: list of accepted protocols +# WPA = WPA/IEEE 802.11i/D3.0 +# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN) +# If not set, this defaults to: WPA RSN +# +# key_mgmt: list of accepted authenticated key management protocols +# WPA-PSK = WPA pre-shared key (this requires 'psk' field) +# WPA-EAP = WPA using EAP authentication +# IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically +# generated WEP keys +# NONE = WPA is not used; plaintext or static WEP could be used +# WPA-PSK-SHA256 = Like WPA-PSK but using stronger SHA256-based algorithms +# WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms +# If not set, this defaults to: WPA-PSK WPA-EAP +# +# auth_alg: list of allowed IEEE 802.11 authentication algorithms +# OPEN = Open System authentication (required for WPA/WPA2) +# SHARED = Shared Key authentication (requires static WEP keys) +# LEAP = LEAP/Network EAP (only used with LEAP) +# If not set, automatic selection is used (Open System with LEAP enabled if +# LEAP is allowed as one of the EAP methods). +# +# pairwise: list of accepted pairwise (unicast) ciphers for WPA +# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] +# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] +# NONE = Use only Group Keys (deprecated, should not be included if APs support +# pairwise keys) +# If not set, this defaults to: CCMP TKIP +# +# group: list of accepted group (broadcast/multicast) ciphers for WPA +# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] +# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] +# WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key +# WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key [IEEE 802.11] +# If not set, this defaults to: CCMP TKIP WEP104 WEP40 +# +# psk: WPA preshared key; 256-bit pre-shared key +# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e., +# 32 bytes or as an ASCII passphrase (in which case, the real PSK will be +# generated using the passphrase and SSID). ASCII passphrase must be between +# 8 and 63 characters (inclusive). +# This field is not needed, if WPA-EAP is used. +# Note: Separate tool, wpa_passphrase, can be used to generate 256-bit keys +# from ASCII passphrase. This process uses lot of CPU and wpa_supplicant +# startup and reconfiguration time can be optimized by generating the PSK only +# only when the passphrase or SSID has actually changed. +# +# eapol_flags: IEEE 802.1X/EAPOL options (bit field) +# Dynamic WEP key required for non-WPA mode +# bit0 (1): require dynamically generated unicast WEP key +# bit1 (2): require dynamically generated broadcast WEP key +# (3 = require both keys; default) +# Note: When using wired authentication, eapol_flags must be set to 0 for the +# authentication to be completed successfully. +# +# mixed_cell: This option can be used to configure whether so called mixed +# cells, i.e., networks that use both plaintext and encryption in the same +# SSID, are allowed when selecting a BSS form scan results. +# 0 = disabled (default) +# 1 = enabled +# +# proactive_key_caching: +# Enable/disable opportunistic PMKSA caching for WPA2. +# 0 = disabled (default) +# 1 = enabled +# +# wep_key0..3: Static WEP key (ASCII in double quotation, e.g. "abcde" or +# hex without quotation, e.g., 0102030405) +# wep_tx_keyidx: Default WEP key index (TX) (0..3) +# +# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e DLS) is +# allowed. This is only used with RSN/WPA2. +# 0 = disabled (default) +# 1 = enabled +#peerkey=1 +# +# wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to +# enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies. +# +# Following fields are only used with internal EAP implementation. +# eap: space-separated list of accepted EAP methods +# MD5 = EAP-MD5 (unsecure and does not generate keying material -> +# cannot be used with WPA; to be used as a Phase 2 method +# with EAP-PEAP or EAP-TTLS) +# MSCHAPV2 = EAP-MSCHAPv2 (cannot be used separately with WPA; to be used +# as a Phase 2 method with EAP-PEAP or EAP-TTLS) +# OTP = EAP-OTP (cannot be used separately with WPA; to be used +# as a Phase 2 method with EAP-PEAP or EAP-TTLS) +# GTC = EAP-GTC (cannot be used separately with WPA; to be used +# as a Phase 2 method with EAP-PEAP or EAP-TTLS) +# TLS = EAP-TLS (client and server certificate) +# PEAP = EAP-PEAP (with tunnelled EAP authentication) +# TTLS = EAP-TTLS (with tunnelled EAP or PAP/CHAP/MSCHAP/MSCHAPV2 +# authentication) +# If not set, all compiled in methods are allowed. +# +# identity: Identity string for EAP +# This field is also used to configure user NAI for +# EAP-PSK/PAX/SAKE/GPSK. +# anonymous_identity: Anonymous identity string for EAP (to be used as the +# unencrypted identity with EAP types that support different tunnelled +# identity, e.g., EAP-TTLS) +# password: Password string for EAP. This field can include either the +# plaintext password (using ASCII or hex string) or a NtPasswordHash +# (16-byte MD4 hash of password) in hash:<32 hex digits> format. +# NtPasswordHash can only be used when the password is for MSCHAPv2 or +# MSCHAP (EAP-MSCHAPv2, EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP). +# EAP-PSK (128-bit PSK), EAP-PAX (128-bit PSK), and EAP-SAKE (256-bit +# PSK) is also configured using this field. For EAP-GPSK, this is a +# variable length PSK. +# ca_cert: File path to CA certificate file (PEM/DER). This file can have one +# or more trusted CA certificates. If ca_cert and ca_path are not +# included, server certificate will not be verified. This is insecure and +# a trusted CA certificate should always be configured when using +# EAP-TLS/TTLS/PEAP. Full path should be used since working directory may +# change when wpa_supplicant is run in the background. +# On Windows, trusted CA certificates can be loaded from the system +# certificate store by setting this to cert_store://<name>, e.g., +# ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT". +# Note that when running wpa_supplicant as an application, the user +# certificate store (My user account) is used, whereas computer store +# (Computer account) is used when running wpasvc as a service. +# ca_path: Directory path for CA certificate files (PEM). This path may +# contain multiple CA certificates in OpenSSL format. Common use for this +# is to point to system trusted CA list which is often installed into +# directory like /etc/ssl/certs. If configured, these certificates are +# added to the list of trusted CAs. ca_cert may also be included in that +# case, but it is not required. +# client_cert: File path to client certificate file (PEM/DER) +# Full path should be used since working directory may change when +# wpa_supplicant is run in the background. +# Alternatively, a named configuration blob can be used by setting this +# to blob://<blob name>. +# private_key: File path to client private key file (PEM/DER/PFX) +# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be +# commented out. Both the private key and certificate will be read from +# the PKCS#12 file in this case. Full path should be used since working +# directory may change when wpa_supplicant is run in the background. +# Windows certificate store can be used by leaving client_cert out and +# configuring private_key in one of the following formats: +# cert://substring_to_match +# hash://certificate_thumbprint_in_hex +# for example: private_key="hash://63093aa9c47f56ae88334c7b65a4" +# Note that when running wpa_supplicant as an application, the user +# certificate store (My user account) is used, whereas computer store +# (Computer account) is used when running wpasvc as a service. +# Alternatively, a named configuration blob can be used by setting this +# to blob://<blob name>. +# private_key_passwd: Password for private key file (if left out, this will be +# asked through control interface) +# dh_file: File path to DH/DSA parameters file (in PEM format) +# This is an optional configuration file for setting parameters for an +# ephemeral DH key exchange. In most cases, the default RSA +# authentication does not use this configuration. However, it is possible +# setup RSA to use ephemeral DH key exchange. In addition, ciphers with +# DSA keys always use ephemeral DH keys. This can be used to achieve +# forward secrecy. If the file is in DSA parameters format, it will be +# automatically converted into DH params. +# subject_match: Substring to be matched against the subject of the +# authentication server certificate. If this string is set, the server +# sertificate is only accepted if it contains this string in the subject. +# The subject string is in following format: +# /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com +# altsubject_match: Semicolon separated string of entries to be matched against +# the alternative subject name of the authentication server certificate. +# If this string is set, the server sertificate is only accepted if it +# contains one of the entries in an alternative subject name extension. +# altSubjectName string is in following format: TYPE:VALUE +# Example: EMAIL:server@example.com +# Example: DNS:server.example.com;DNS:server2.example.com +# Following types are supported: EMAIL, DNS, URI +# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters +# (string with field-value pairs, e.g., "peapver=0" or +# "peapver=1 peaplabel=1") +# 'peapver' can be used to force which PEAP version (0 or 1) is used. +# 'peaplabel=1' can be used to force new label, "client PEAP encryption", +# to be used during key derivation when PEAPv1 or newer. Most existing +# PEAPv1 implementation seem to be using the old label, "client EAP +# encryption", and wpa_supplicant is now using that as the default value. +# Some servers, e.g., Radiator, may require peaplabel=1 configuration to +# interoperate with PEAPv1; see eap_testing.txt for more details. +# 'peap_outer_success=0' can be used to terminate PEAP authentication on +# tunneled EAP-Success. This is required with some RADIUS servers that +# implement draft-josefsson-pppext-eap-tls-eap-05.txt (e.g., +# Lucent NavisRadius v4.4.0 with PEAP in "IETF Draft 5" mode) +# include_tls_length=1 can be used to force wpa_supplicant to include +# TLS Message Length field in all TLS messages even if they are not +# fragmented. +# sim_min_num_chal=3 can be used to configure EAP-SIM to require three +# challenges (by default, it accepts 2 or 3) +# result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use +# protected result indication. +# 'crypto_binding' option can be used to control PEAPv0 cryptobinding +# behavior: +# * 0 = do not use cryptobinding (default) +# * 1 = use cryptobinding if server supports it +# * 2 = require cryptobinding +# EAP-WSC (WPS) uses following options: pin=<Device Password> or +# pbc=1. +# phase2: Phase2 (inner authentication with TLS tunnel) parameters +# (string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or +# "autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS) +# Following certificate/private key fields are used in inner Phase2 +# authentication when using EAP-TTLS or EAP-PEAP. +# ca_cert2: File path to CA certificate file. This file can have one or more +# trusted CA certificates. If ca_cert2 and ca_path2 are not included, +# server certificate will not be verified. This is insecure and a trusted +# CA certificate should always be configured. +# ca_path2: Directory path for CA certificate files (PEM) +# client_cert2: File path to client certificate file +# private_key2: File path to client private key file +# private_key2_passwd: Password for private key file +# dh_file2: File path to DH/DSA parameters file (in PEM format) +# subject_match2: Substring to be matched against the subject of the +# authentication server certificate. +# altsubject_match2: Substring to be matched against the alternative subject +# name of the authentication server certificate. +# +# fragment_size: Maximum EAP fragment size in bytes (default 1398). +# This value limits the fragment size for EAP methods that support +# fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set +# small enough to make the EAP messages fit in MTU of the network +# interface used for EAPOL. The default value is suitable for most +# cases. +# +# EAP-FAST variables: +# pac_file: File path for the PAC entries. wpa_supplicant will need to be able +# to create this file and write updates to it when PAC is being +# provisioned or refreshed. Full path to the file should be used since +# working directory may change when wpa_supplicant is run in the +# background. Alternatively, a named configuration blob can be used by +# setting this to blob://<blob name> +# phase1: fast_provisioning option can be used to enable in-line provisioning +# of EAP-FAST credentials (PAC): +# 0 = disabled, +# 1 = allow unauthenticated provisioning, +# 2 = allow authenticated provisioning, +# 3 = allow both unauthenticated and authenticated provisioning +# fast_max_pac_list_len=<num> option can be used to set the maximum +# number of PAC entries to store in a PAC list (default: 10) +# fast_pac_format=binary option can be used to select binary format for +# storing PAC entries in order to save some space (the default +# text format uses about 2.5 times the size of minimal binary +# format) +# +# wpa_supplicant supports number of "EAP workarounds" to work around +# interoperability issues with incorrectly behaving authentication servers. +# These are enabled by default because some of the issues are present in large +# number of authentication servers. Strict EAP conformance mode can be +# configured by disabling workarounds with eap_workaround=0. + +# Example blocks: + +# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers +network={ + ssid="simple" + psk="very secret passphrase" + priority=5 +} + +# Same as previous, but request SSID-specific scanning (for APs that reject +# broadcast SSID) +network={ + ssid="second ssid" + scan_ssid=1 + psk="very secret passphrase" + priority=2 +} + +# Only WPA-PSK is used. Any valid cipher combination is accepted. +network={ + ssid="example" + proto=WPA + key_mgmt=WPA-PSK + pairwise=CCMP TKIP + group=CCMP TKIP WEP104 WEP40 + psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb + priority=2 +} + +# WPA-Personal(PSK) with TKIP and enforcement for frequent PTK rekeying +network={ + ssid="example" + proto=WPA + key_mgmt=WPA-PSK + pairwise=TKIP + group=TKIP + psk="not so secure passphrase" + wpa_ptk_rekey=600 +} + +# Only WPA-EAP is used. Both CCMP and TKIP is accepted. An AP that used WEP104 +# or WEP40 as the group cipher will not be accepted. +network={ + ssid="example" + proto=RSN + key_mgmt=WPA-EAP + pairwise=CCMP TKIP + group=CCMP TKIP + eap=TLS + identity="user@example.com" + ca_cert="/etc/cert/ca.pem" + client_cert="/etc/cert/user.pem" + private_key="/etc/cert/user.prv" + private_key_passwd="password" + priority=1 +} + +# EAP-PEAP/MSCHAPv2 configuration for RADIUS servers that use the new peaplabel +# (e.g., Radiator) +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=PEAP + identity="user@example.com" + password="foobar" + ca_cert="/etc/cert/ca.pem" + phase1="peaplabel=1" + phase2="auth=MSCHAPV2" + priority=10 +} + +# EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the +# unencrypted use. Real identity is sent only within an encrypted TLS tunnel. +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=TTLS + identity="user@example.com" + anonymous_identity="anonymous@example.com" + password="foobar" + ca_cert="/etc/cert/ca.pem" + priority=2 +} + +# EAP-TTLS/MSCHAPv2 configuration with anonymous identity for the unencrypted +# use. Real identity is sent only within an encrypted TLS tunnel. +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=TTLS + identity="user@example.com" + anonymous_identity="anonymous@example.com" + password="foobar" + ca_cert="/etc/cert/ca.pem" + phase2="auth=MSCHAPV2" +} + +# WPA-EAP, EAP-TTLS with different CA certificate used for outer and inner +# authentication. +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=TTLS + # Phase1 / outer authentication + anonymous_identity="anonymous@example.com" + ca_cert="/etc/cert/ca.pem" + # Phase 2 / inner authentication + phase2="autheap=TLS" + ca_cert2="/etc/cert/ca2.pem" + client_cert2="/etc/cer/user.pem" + private_key2="/etc/cer/user.prv" + private_key2_passwd="password" + priority=2 +} + +# Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and +# group cipher. +network={ + ssid="example" + bssid=00:11:22:33:44:55 + proto=WPA RSN + key_mgmt=WPA-PSK WPA-EAP + pairwise=CCMP + group=CCMP + psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb +} + +# Special characters in SSID, so use hex string. Default to WPA-PSK, WPA-EAP +# and all valid ciphers. +network={ + ssid=00010203 + psk=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +} + + +# EAP-SIM with a GSM SIM or USIM +network={ + ssid="eap-sim-test" + key_mgmt=WPA-EAP + eap=SIM + pin="1234" + pcsc="" +} + + +# EAP-PSK +network={ + ssid="eap-psk-test" + key_mgmt=WPA-EAP + eap=PSK + anonymous_identity="eap_psk_user" + password=06b4be19da289f475aa46a33cb793029 + identity="eap_psk_user@example.com" +} + + +# IEEE 802.1X/EAPOL with dynamically generated WEP keys (i.e., no WPA) using +# EAP-TLS for authentication and key generation; require both unicast and +# broadcast WEP keys. +network={ + ssid="1xtest" + key_mgmt=IEEE8021X + eap=TLS + identity="user@example.com" + ca_cert="/etc/cert/ca.pem" + client_cert="/etc/cert/user.pem" + private_key="/etc/cert/user.prv" + private_key_passwd="password" + eapol_flags=3 +} + + +# LEAP with dynamic WEP keys +network={ + ssid="leap-example" + key_mgmt=IEEE8021X + eap=LEAP + identity="user" + password="foobar" +} + +# EAP-IKEv2 using shared secrets for both server and peer authentication +network={ + ssid="ikev2-example" + key_mgmt=WPA-EAP + eap=IKEV2 + identity="user" + password="foobar" +} + +# EAP-FAST with WPA (WPA or WPA2) +network={ + ssid="eap-fast-test" + key_mgmt=WPA-EAP + eap=FAST + anonymous_identity="FAST-000102030405" + identity="username" + password="password" + phase1="fast_provisioning=1" + pac_file="/etc/wpa_supplicant.eap-fast-pac" +} + +network={ + ssid="eap-fast-test" + key_mgmt=WPA-EAP + eap=FAST + anonymous_identity="FAST-000102030405" + identity="username" + password="password" + phase1="fast_provisioning=1" + pac_file="blob://eap-fast-pac" +} + +# Plaintext connection (no WPA, no IEEE 802.1X) +network={ + ssid="plaintext-test" + key_mgmt=NONE +} + + +# Shared WEP key connection (no WPA, no IEEE 802.1X) +network={ + ssid="static-wep-test" + key_mgmt=NONE + wep_key0="abcde" + wep_key1=0102030405 + wep_key2="1234567890123" + wep_tx_keyidx=0 + priority=5 +} + + +# Shared WEP key connection (no WPA, no IEEE 802.1X) using Shared Key +# IEEE 802.11 authentication +network={ + ssid="static-wep-test2" + key_mgmt=NONE + wep_key0="abcde" + wep_key1=0102030405 + wep_key2="1234567890123" + wep_tx_keyidx=0 + priority=5 + auth_alg=SHARED +} + + +# IBSS/ad-hoc network with WPA-None/TKIP. +network={ + ssid="test adhoc" + mode=1 + frequency=2412 + proto=WPA + key_mgmt=WPA-NONE + pairwise=NONE + group=TKIP + psk="secret passphrase" +} + + +# Catch all example that allows more or less all configuration modes +network={ + ssid="example" + scan_ssid=1 + key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE + pairwise=CCMP TKIP + group=CCMP TKIP WEP104 WEP40 + psk="very secret passphrase" + eap=TTLS PEAP TLS + identity="user@example.com" + password="foobar" + ca_cert="/etc/cert/ca.pem" + client_cert="/etc/cert/user.pem" + private_key="/etc/cert/user.prv" + private_key_passwd="password" + phase1="peaplabel=0" +} + +# Example of EAP-TLS with smartcard (openssl engine) +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=TLS + proto=RSN + pairwise=CCMP TKIP + group=CCMP TKIP + identity="user@example.com" + ca_cert="/etc/cert/ca.pem" + client_cert="/etc/cert/user.pem" + + engine=1 + + # The engine configured here must be available. Look at + # OpenSSL engine support in the global section. + # The key available through the engine must be the private key + # matching the client certificate configured above. + + # use the opensc engine + #engine_id="opensc" + #key_id="45" + + # use the pkcs11 engine + engine_id="pkcs11" + key_id="id_45" + + # Optional PIN configuration; this can be left out and PIN will be + # asked through the control interface + pin="1234" +} + +# Example configuration showing how to use an inlined blob as a CA certificate +# data instead of using external file +network={ + ssid="example" + key_mgmt=WPA-EAP + eap=TTLS + identity="user@example.com" + anonymous_identity="anonymous@example.com" + password="foobar" + ca_cert="blob://exampleblob" + priority=20 +} + +blob-base64-exampleblob={ +SGVsbG8gV29ybGQhCg== +} + + +# Wildcard match for SSID (plaintext APs only). This example select any +# open AP regardless of its SSID. +network={ + key_mgmt=NONE +} +network={ + ssid="myxjtu2" + scan_ssid=1 + key_mgmt=WPA-PSK + psk="xjtudlc3731" + disabled=0 + key_mgmt=NONE + wep_key0="12345" + wep_key1=1234567890 + wep_key2="zxcvb" + wep_tx_keyidx=1 + auth_alg=OPEN + mode=1 +} +network={ + ssid=ab3ace + key_mgmt=WPA-EAP + eap=TTLS + identity="user@example.com" + anonymous_identity="anonymous@example.com" + password="foobar" + ca_cert="blob://exampleblob" + priority=20 +} diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c new file mode 100644 index 00000000..da2bc3bb --- /dev/null +++ b/src/settings/plugins/ifnet/wpa_parser.c @@ -0,0 +1,566 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <string.h> +#include <stdlib.h> +#include <nm-system-config-interface.h> +#include "wpa_parser.h" +#include "net_parser.h" +#include "net_utils.h" + +/* Security information */ +static GHashTable *wsec_table = NULL; + +/* Global information used for writing */ +static GHashTable *wsec_global_table = NULL; + +static gboolean wpa_parser_data_changed = FALSE; + +static long +wpa_get_long (GHashTable *table, const char *key) +{ + return atol (g_hash_table_lookup (table, key)); +} + +static void +destroy_security (GHashTable * network) +{ + gpointer key, value; + GHashTableIter iter; + + g_return_if_fail (network); + g_hash_table_iter_init (&iter, network); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (network); +} + +static GHashTable * +add_security (GHashTable *security) +{ + GHashTable *oldsecurity; + const char *ssid, *value; + char *ssid_key; + gboolean is_hex_ssid; + + /* Every security information should have a ssid */ + ssid = g_hash_table_lookup (security, "ssid"); + if (!ssid) { + destroy_security (security); + return NULL; + } + + /* Hex format begins with " */ + is_hex_ssid = (ssid[0] != '"'); + if ((value = g_hash_table_lookup (security, "disabled")) != NULL) { + if (strcmp (value, "1") == 0) + return NULL; + } + + /* Default priority is 1 */ + if (g_hash_table_lookup (security, "priority") == NULL) + g_hash_table_insert (security, g_strdup ("priority"), + g_strdup ("1")); + + oldsecurity = g_hash_table_lookup (wsec_table, ssid); + /* Security with lower priority will be ignored */ + if (oldsecurity != NULL) { + if (wpa_get_long (oldsecurity, "priority") >= + wpa_get_long (security, "priority")) { + destroy_security (security); + return NULL; + } else { + g_hash_table_remove (wsec_table, ssid); + destroy_security (oldsecurity); + } + } + + /* format ssid */ + ssid_key = + is_hex_ssid ? g_strdup_printf ("0x%s", + ssid) : + strip_string (g_strdup (ssid), '"'); + g_hash_table_insert (wsec_table, ssid_key, security); + return security; +} + +static void +add_key_value (GHashTable * network, gchar * line) +{ + gchar **key_value; + + if (g_str_has_prefix (line, "network={")) + line += 9; + strip_string (line, '{'); + strip_string (line, '}'); + if (line[0] == '\0') + return; + key_value = g_strsplit (line, "=", 2); + if (g_strv_length (key_value) != 2) { + g_strfreev (key_value); + return; + } + g_strstrip (key_value[0]); + g_strstrip (key_value[1]); + + /* Reserve quotes for psk, wep_key, ssid + * Quotes will determine whether they are hex format */ + if (strcmp (key_value[0], "psk") != 0 + && !g_str_has_prefix (key_value[0], "wep_key") + && strcmp (key_value[0], "ssid") != 0) + strip_string (key_value[1], '"'); + g_hash_table_insert (network, g_strdup (key_value[0]), + g_strdup (key_value[1])); + g_strfreev (key_value); +} + +static void +add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key) +{ + if (one_wep_key[0] == 's') { + //asc key + g_hash_table_insert (table, + g_strdup_printf ("wep_key%d", key_num - 1), + g_strdup_printf ("\"%s\"", + one_wep_key + 2)); + } else { + gchar buf[30]; + int i = 0, j = 0; + + //hex key + while (one_wep_key[i] != '\0') { + if (one_wep_key[i] != '-') + buf[j++] = one_wep_key[i]; + i++; + } + buf[j] = '\0'; + g_hash_table_insert (table, + g_strdup_printf ("wep_key%d", key_num - 1), + g_strdup (buf)); + + } +} + +/* Reading wep security information from /etc/conf.d/net. + * This should not be used in futre, use wpa_supplicant instead. */ +static void +add_keys_from_net () +{ + GList *names = ifnet_get_connection_names (); + GList *iter = names; + gchar *wep_keys = "(\\[([1-4])\\]\\s+(s:\\w{5}|s:\\w{13}|" + "([\\da-fA-F]{4}\\-){2}[\\da-fA-F]{2}|" + "([\\da-fA-F]{4}\\-){6}[\\da-fA-F]{2})\\s+)"; + gchar *key_method = + "\\s+key\\s+\\[([1-4])\\]\\s+enc\\s+(open|restricted)"; + GRegex *regex_keys = g_regex_new (wep_keys, 0, 0, NULL); + GRegex *regex_method = g_regex_new (key_method, 0, 0, NULL); + GMatchInfo *keys_info; + GMatchInfo *method_info; + + while (iter) { + gchar *conn_name = iter->data; + GHashTable *table; + const char *key_str; + + if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) { + iter = g_list_next (iter); + continue; + } + + wpa_add_security (conn_name); + table = _get_hash_table (conn_name); + /* Give lowest priority */ + wpa_set_data (conn_name, "priority", "0"); + g_regex_match (regex_keys, key_str, 0, &keys_info); + /* add wep keys */ + while (g_match_info_matches (keys_info)) { + gchar *key_num = g_match_info_fetch (keys_info, 2); + gchar *one_wep_key = g_match_info_fetch (keys_info, 3); + + add_one_wep_key (table, atoi (key_num), one_wep_key); + g_free (key_num); + g_free (one_wep_key); + g_match_info_next (keys_info, NULL); + } + g_match_info_free (keys_info); + + g_regex_match (regex_method, key_str, 0, &method_info); + /* set default key index and auth alg */ + if (g_match_info_matches (method_info)) { + gchar *default_idx = + g_match_info_fetch (method_info, 1); + gchar *method = g_match_info_fetch (method_info, 2); + + default_idx[0]--; + g_hash_table_insert (table, g_strdup ("wep_tx_keyidx"), + default_idx); + g_hash_table_insert (table, g_strdup ("auth_alg"), + g_ascii_strup (method, -1)); + } + g_match_info_free (method_info); + add_security (table); + iter = g_list_next (iter); + } + g_list_free (names); + g_regex_unref (regex_keys); + g_regex_unref (regex_method); +} + +static void +add_global_data (gchar * line) +{ + gchar **key_value; + + g_strstrip (line); + key_value = g_strsplit (line, "=", 2); + if (g_strv_length (key_value) != 2) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle this line: %s\n", + line); + g_strfreev (key_value); + return; + } + g_hash_table_insert (wsec_global_table, + g_strdup (g_strstrip (key_value[0])), + g_strdup (g_strstrip (key_value[1]))); + g_strfreev (key_value); +} + +void +wpa_parser_init (const char *wpa_supplicant_conf) +{ + GIOChannel *channel = NULL; + gchar *line; + gboolean complete = FALSE; + + wpa_parser_data_changed = FALSE; + wsec_table = g_hash_table_new (g_str_hash, g_str_equal); + wsec_global_table = g_hash_table_new (g_str_hash, g_str_equal); + + if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR)) + channel = + g_io_channel_new_file (wpa_supplicant_conf, "r", NULL); + if (channel == NULL) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't open %s for wireless security", + wpa_supplicant_conf); + return; + } + + while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL) + != G_IO_STATUS_EOF) { + g_strstrip (line); + if (line[0] != '#' && line[0] != '\0') { + if (strstr (line, "network={") == NULL) { + add_global_data (line); + g_free (line); + continue; + } else { + GHashTable *network = + g_hash_table_new (g_str_hash, g_str_equal); + gchar *tmp; + + do { + if (line[0] == '#' || line[0] == '\0') { + g_free (line); + continue; + } + /* ignore inline comments */ + if ((tmp = strchr (line, '#')) != NULL) + *tmp = '\0'; + if (strstr (line, "}") != NULL) + complete = TRUE; + add_key_value (network, line); + g_free (line); + } while (complete == FALSE + && + g_io_channel_read_line + (channel, &line, NULL, + NULL, NULL) != G_IO_STATUS_EOF); + add_security (network); + //EOF in inner loop + if (complete == FALSE) { + g_free (line); + break; + } + complete = FALSE; + } + } else + g_free (line); + } + + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + + add_keys_from_net (); +} + +const char * +wpa_get_value (const char *ssid, const char *key) +{ + GHashTable *target = g_hash_table_lookup (wsec_table, ssid); + + if (target) + return g_hash_table_lookup (target, key); + return NULL; +} + +gboolean +exist_ssid (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid) != NULL; +} + +GHashTable * +_get_hash_table (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid); +} + +static gchar *quoted_keys[] = + { "identity", "cert", "private", "phase", "password", NULL }; + +/* tell whether the key needs quotes when writing is performed */ +static gboolean +need_quote (gchar * key) +{ + int i = 0; + + while (quoted_keys[i] != NULL) { + if (strstr (key, quoted_keys[i])) + return TRUE; + i++; + } + return FALSE; +} + +gboolean +wpa_flush_to_file (const char *config_file) +{ + GIOChannel *channel; + GError **error = NULL; + gpointer key, value, ssid, security; + GHashTableIter iter, iter_security; + gchar *out_line; + gsize bytes_written; + gboolean result = FALSE; + + if (!wpa_parser_data_changed) + return TRUE; + if (!wsec_table || !wsec_global_table) + return FALSE; + + channel = g_io_channel_new_file (config_file, "w", NULL); + if (!channel) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't open file %s for writing", config_file); + return FALSE; + } + g_hash_table_iter_init (&iter, wsec_global_table); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file); + g_io_channel_write_chars (channel, + "#Generated by NetworkManager\n" + "###### Global Configuration ######\n", + -1, &bytes_written, error); + + /* Writing global information */ + while (g_hash_table_iter_next (&iter, &key, &value)) { + out_line = + g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, &bytes_written, + error); + if (bytes_written == 0 || (error && *error)) + break; + g_free (out_line); + } + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", + (*error)->message); + goto done; + } + g_io_channel_write_chars (channel, + "\n###### Security Configuration ######\n", + -1, &bytes_written, error); + + g_hash_table_iter_init (&iter, wsec_table); + /* Writing security */ + while (g_hash_table_iter_next (&iter, &ssid, &security)) { + g_hash_table_iter_init (&iter_security, + (GHashTable *) security); + g_io_channel_write_chars (channel, "network={\n", -1, + &bytes_written, error); + while (g_hash_table_iter_next (&iter_security, &key, &value)) { + out_line = + g_strdup_printf (need_quote ((gchar *) key) ? + "\t%s=\"%s\"\n" : "\t%s=%s\n", + (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, error); + if (bytes_written == 0 || (error && *error)) + break; + g_free (out_line); + } + g_io_channel_write_chars (channel, + "}\n\n", -1, &bytes_written, error); + + } + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", + (*error)->message); + goto done; + } + g_io_channel_flush (channel, error); + + if (error && *error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", + (*error)->message); + goto done; + } + wpa_parser_data_changed = FALSE; + result = TRUE; +done: + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return result; +} + +/* If value is NULL, this method will delete old key value pair */ +void +wpa_set_data (const char *ssid, const char *key, const char *value) +{ + gpointer old_key = NULL, old_value = NULL; + GHashTable *security = g_hash_table_lookup (wsec_table, ssid); + gchar * stripped = NULL; + + g_return_if_fail (security != NULL); + + if (value){ + stripped = g_strdup(value); + if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0 + && !g_str_has_prefix (key, "wep_key")) + strip_string (stripped, '"'); + } + + /* Remove old key value pairs */ + if (g_hash_table_lookup_extended + (security, key, &old_key, &old_value)) { + if (stripped && !strcmp(old_value, stripped)){ + g_free (stripped); + return; + } + g_hash_table_remove (security, old_key); + g_free (old_key); + g_free (old_value); + } else if (!value) + return; + + /* Add new key value */ + if (stripped) + g_hash_table_insert (security, g_strdup (key), stripped); + wpa_parser_data_changed = TRUE; +} + +gboolean +wpa_has_security (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid) != NULL; +} + +gboolean +wpa_add_security (const char *ssid) +{ + if (wpa_has_security (ssid)) + return TRUE; + else { + GHashTable *security = + g_hash_table_new (g_str_hash, g_str_equal); + gchar *ssid_i; + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding security for %s", + ssid); + if (g_str_has_prefix (ssid, "0x")) { + /* hex ssid */ + ssid_i = g_strdup (ssid + 2); + } else { + /* ascii ssid requires quotes */ + ssid_i = g_strdup_printf ("\"%s\"", ssid); + } + g_hash_table_insert (security, strdup ("ssid"), ssid_i); + g_hash_table_insert (security, strdup ("priority"), + strdup ("1")); + g_hash_table_insert (wsec_table, g_strdup (ssid), security); + wpa_parser_data_changed = TRUE; + return TRUE; + } +} + +gboolean +wpa_delete_security (const char *ssid) +{ + gpointer old_key, old_value; + + g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Deleting security for %s", ssid); + if (!g_hash_table_lookup_extended + (wsec_table, ssid, &old_key, &old_value)) + return FALSE; + g_hash_table_remove (wsec_table, old_key); + g_free (old_key); + destroy_security ((GHashTable *) old_value); + wpa_parser_data_changed = TRUE; + return TRUE; + +} + +void +wpa_parser_destroy (void) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + + /* Destroy security */ + if (wsec_table) { + g_hash_table_iter_init (&iter, wsec_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + destroy_security ((GHashTable *) value); + g_free (key); + } + + g_hash_table_destroy (wsec_table); + wsec_table = NULL; + } + + /* Destroy global data */ + if (wsec_global_table) { + g_hash_table_iter_init (&iter, wsec_global_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (wsec_global_table); + wsec_global_table = NULL; + } +} diff --git a/src/settings/plugins/ifnet/wpa_parser.h b/src/settings/plugins/ifnet/wpa_parser.h new file mode 100644 index 00000000..7fd77a05 --- /dev/null +++ b/src/settings/plugins/ifnet/wpa_parser.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _WPA_PARSER_H +#define _WPA_PARSER_H +#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant/wpa_supplicant.conf" +#include <glib.h> +void wpa_parser_init (const char *wpa_supplicant_conf); +void wpa_parser_destroy (void); + +/* reader functions */ +const char *wpa_get_value (const char *ssid, const char *key); +gboolean exist_ssid (const char *ssid); +GHashTable *_get_hash_table (const char *ssid); +gboolean wpa_has_security (const char *ssid); + +/* writer functions */ +gboolean wpa_flush_to_file (const char *config_file); +void wpa_set_data (const char *ssid, const char *key, const char *value); +gboolean wpa_add_security (const char *ssid); +gboolean wpa_delete_security (const char *ssid); +#endif diff --git a/src/settings/plugins/ifupdown/Makefile.am b/src/settings/plugins/ifupdown/Makefile.am new file mode 100644 index 00000000..9f9d0218 --- /dev/null +++ b/src/settings/plugins/ifupdown/Makefile.am @@ -0,0 +1,53 @@ +SUBDIRS=. tests + +INCLUDES = \ + -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util + +noinst_LTLIBRARIES = libifupdown-io.la + +libifupdown_io_la_SOURCES = \ + interface_parser.c \ + interface_parser.h \ + parser.c \ + parser.h + +libifupdown_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libifupdown_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la + +libnm_settings_plugin_ifupdown_la_SOURCES = \ + nm-ifupdown-connection.c \ + nm-ifupdown-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifupdown_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifupdown_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + libifupdown-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GUDEV_LIBS) + diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in new file mode 100644 index 00000000..af545df7 --- /dev/null +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -0,0 +1,898 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ifupdown +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libifupdown_io_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libifupdown_io_la_OBJECTS = libifupdown_io_la-interface_parser.lo \ + libifupdown_io_la-parser.lo +libifupdown_io_la_OBJECTS = $(am_libifupdown_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnm_settings_plugin_ifupdown_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/logging/libnm-logging.la libifupdown-io.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libnm_settings_plugin_ifupdown_la_OBJECTS = \ + libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo \ + libnm_settings_plugin_ifupdown_la-plugin.lo +libnm_settings_plugin_ifupdown_la_OBJECTS = \ + $(am_libnm_settings_plugin_ifupdown_la_OBJECTS) +libnm_settings_plugin_ifupdown_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_ifupdown_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libifupdown_io_la_SOURCES) \ + $(libnm_settings_plugin_ifupdown_la_SOURCES) +DIST_SOURCES = $(libifupdown_io_la_SOURCES) \ + $(libnm_settings_plugin_ifupdown_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests +INCLUDES = \ + -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util + +noinst_LTLIBRARIES = libifupdown-io.la +libifupdown_io_la_SOURCES = \ + interface_parser.c \ + interface_parser.h \ + parser.c \ + parser.h + +libifupdown_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libifupdown_io_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) + +pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la +libnm_settings_plugin_ifupdown_la_SOURCES = \ + nm-ifupdown-connection.c \ + nm-ifupdown-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_ifupdown_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ifupdown_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + libifupdown-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(GUDEV_LIBS) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libifupdown-io.la: $(libifupdown_io_la_OBJECTS) $(libifupdown_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libifupdown_io_la_OBJECTS) $(libifupdown_io_la_LIBADD) $(LIBS) +libnm-settings-plugin-ifupdown.la: $(libnm_settings_plugin_ifupdown_la_OBJECTS) $(libnm_settings_plugin_ifupdown_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_ifupdown_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifupdown_la_OBJECTS) $(libnm_settings_plugin_ifupdown_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifupdown_io_la-interface_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifupdown_io_la-parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libifupdown_io_la-interface_parser.lo: interface_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifupdown_io_la-interface_parser.lo -MD -MP -MF $(DEPDIR)/libifupdown_io_la-interface_parser.Tpo -c -o libifupdown_io_la-interface_parser.lo `test -f 'interface_parser.c' || echo '$(srcdir)/'`interface_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifupdown_io_la-interface_parser.Tpo $(DEPDIR)/libifupdown_io_la-interface_parser.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='interface_parser.c' object='libifupdown_io_la-interface_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifupdown_io_la-interface_parser.lo `test -f 'interface_parser.c' || echo '$(srcdir)/'`interface_parser.c + +libifupdown_io_la-parser.lo: parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifupdown_io_la-parser.lo -MD -MP -MF $(DEPDIR)/libifupdown_io_la-parser.Tpo -c -o libifupdown_io_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifupdown_io_la-parser.Tpo $(DEPDIR)/libifupdown_io_la-parser.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parser.c' object='libifupdown_io_la-parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifupdown_io_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c + +libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo: nm-ifupdown-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Tpo -c -o libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo `test -f 'nm-ifupdown-connection.c' || echo '$(srcdir)/'`nm-ifupdown-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifupdown-connection.c' object='libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo `test -f 'nm-ifupdown-connection.c' || echo '$(srcdir)/'`nm-ifupdown-connection.c + +libnm_settings_plugin_ifupdown_la-plugin.lo: plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifupdown_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Tpo -c -o libnm_settings_plugin_ifupdown_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifupdown_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifupdown_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pkglibLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkglibLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-pkglibLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c new file mode 100644 index 00000000..b7c64242 --- /dev/null +++ b/src/settings/plugins/ifupdown/interface_parser.c @@ -0,0 +1,307 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ +/* NetworkManager -- Network link manager + * + * Tom Parker <palfrey@tevp.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2004 Tom Parker + */ + +#include "config.h" +#include "interface_parser.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "nm-utils.h" + +if_block* first; +if_block* last; + +if_data* last_data; + +void add_block(const char *type, const char* name) +{ + if_block *ret = (if_block*)calloc(1,sizeof(struct _if_block)); + ret->name = g_strdup(name); + ret->type = g_strdup(type); + if (first == NULL) + first = last = ret; + else + { + last->next = ret; + last = ret; + } + last_data = NULL; + //printf("added block '%s' with type '%s'\n",name,type); +} + +void add_data(const char *key,const char *data) +{ + if_data *ret; + char *idx; + + // Check if there is a block where we can attach our data + if (first == NULL) + return; + + ret = (if_data*) calloc(1,sizeof(struct _if_data)); + ret->key = g_strdup(key); + // Normalize keys. Convert '_' to '-', as ifupdown accepts both variants. + // When querying keys via ifparser_getkey(), use '-'. + while ((idx = strrchr(ret->key, '_'))) { + *idx = '-'; + } + ret->data = g_strdup(data); + + if (last->info == NULL) + { + last->info = ret; + last_data = ret; + } + else + { + last_data->next = ret; + last_data = last_data->next; + } + //printf("added data '%s' with key '%s'\n",data,key); +} + +// join values in src with spaces into dst; dst needs to be large enough +static char *join_values_with_spaces(char *dst, char **src) +{ + if (dst != NULL) { + *dst = '\0'; + if (src != NULL && *src != NULL) { + strcat(dst, *src); + + for (src++; *src != NULL; src++) { + strcat(dst, " "); + strcat(dst, *src); + } + } + } + return(dst); +} + +void ifparser_init (const char *eni_file, int quiet) +{ + FILE *inp = fopen (eni_file, "r"); + char line[255]; + int skip_to_block = 1; + int skip_long_line = 0; + int offs = 0; + + if (inp == NULL) { + if (!quiet) + g_warning ("Error: Can't open %s\n", eni_file); + return; + } + + first = last = NULL; + while (!feof(inp)) + { + char *token[128]; // 255 chars can only be split into 127 tokens + char value[255]; // large enough to join previously split tokens + char *safeptr; + int toknum; + int len = 0; + + char *ptr = fgets(line+offs, 255-offs, inp); + if (ptr == NULL) + break; + + len = strlen(line); + // skip over-long lines + if (!feof(inp) && len > 0 && line[len-1] != '\n') { + if (!skip_long_line) { + if (!quiet) + g_message ("Error: Skipping over-long-line '%s...'\n", line); + } + skip_long_line = 1; + continue; + } + + // trailing '\n' found: remove it & reset offset to 0 + if (len > 0 && line[len-1] == '\n') { + line[--len] = '\0'; + offs = 0; + } + + // if we're in long_line_skip mode, terminate it for real next line + if (skip_long_line) { + if (len == 0 || line[len-1] != '\\') + skip_long_line = 0; + continue; + } + + // unwrap wrapped lines + if (len > 0 && line[len-1] == '\\') { + offs = len - 1; + continue; + } + + //printf(">>%s<<\n", line); + +#define SPACES " \t" + // tokenize input; + for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr); + token[toknum] != NULL; + toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr)) + ; + + // ignore comments and empty lines + if (toknum == 0 || *token[0]=='#') + continue; + + if (toknum < 2) { + if (!quiet) { + g_message ("Error: Can't parse interface line '%s'\n", + join_values_with_spaces(value, token)); + } + skip_to_block = 1; + continue; + } + + // There are four different stanzas: + // iface, mapping, auto and allow-*. Create a block for each of them. + + // iface stanza takes at least 3 parameters + if (strcmp(token[0], "iface") == 0) { + if (toknum < 4) { + if (!quiet) { + g_message ("Error: Can't parse iface line '%s'\n", + join_values_with_spaces(value, token)); + } + continue; + } + add_block(token[0], token[1]); + skip_to_block = 0; + add_data(token[2], join_values_with_spaces(value, token + 3)); + } + // auto and allow-auto stanzas are equivalent, + // both can take multiple interfaces as parameters: add one block for each + else if (strcmp(token[0], "auto") == 0 || + strcmp(token[0], "allow-auto") == 0) { + int i; + for (i = 1; i < toknum; i++) + add_block("auto", token[i]); + skip_to_block = 0; + } + else if (strcmp(token[0], "mapping") == 0) { + add_block(token[0], join_values_with_spaces(value, token + 1)); + skip_to_block = 0; + } + // allow-* can take multiple interfaces as parameters: add one block for each + else if (strncmp(token[0],"allow-",6) == 0) { + int i; + for (i = 1; i < toknum; i++) + add_block(token[0], token[i]); + skip_to_block = 0; + } + else { + if (skip_to_block) { + if (!quiet) { + g_message ("Error: ignoring out-of-block data '%s'\n", + join_values_with_spaces(value, token)); + } + } else + add_data(token[0], join_values_with_spaces(value, token + 1)); + } + } + fclose(inp); +} + +void _destroy_data(if_data *ifd) +{ + if (ifd == NULL) + return; + _destroy_data(ifd->next); + free(ifd->key); + free(ifd->data); + free(ifd); + return; +} + +void _destroy_block(if_block* ifb) +{ + if (ifb == NULL) + return; + _destroy_block(ifb->next); + _destroy_data(ifb->info); + free(ifb->name); + free(ifb->type); + free(ifb); + return; +} + +void ifparser_destroy(void) +{ + _destroy_block(first); + first = last = NULL; +} + +if_block *ifparser_getfirst(void) +{ + return first; +} + +int ifparser_get_num_blocks(void) +{ + int i = 0; + if_block *iter = first; + + while (iter) { + i++; + iter = iter->next; + } + return i; +} + +if_block *ifparser_getif(const char* iface) +{ + if_block *curr = first; + while(curr!=NULL) + { + if (strcmp(curr->type,"iface")==0 && strcmp(curr->name,iface)==0) + return curr; + curr = curr->next; + } + return NULL; +} + +const char *ifparser_getkey(if_block* iface, const char *key) +{ + if_data *curr = iface->info; + while(curr!=NULL) + { + if (strcmp(curr->key,key)==0) + return curr->data; + curr = curr->next; + } + return NULL; +} + +int ifparser_get_num_info(if_block* iface) +{ + int i = 0; + if_data *iter = iface->info; + + while (iter) { + i++; + iter = iter->next; + } + return i; +} diff --git a/src/settings/plugins/ifupdown/interface_parser.h b/src/settings/plugins/ifupdown/interface_parser.h new file mode 100644 index 00000000..0c1de23a --- /dev/null +++ b/src/settings/plugins/ifupdown/interface_parser.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ +/* NetworkManager -- Network link manager + * + * Tom Parker <palfrey@tevp.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2004 Tom Parker + */ + + +#ifndef _INTERFACE_PARSER_H +#define _INTERFACE_PARSER_H + +typedef struct _if_data +{ + char *key; + char *data; + struct _if_data *next; +} if_data; + +typedef struct _if_block +{ + char *type; + char *name; + if_data *info; + struct _if_block *next; +} if_block; + +void ifparser_init(const char *eni_file, int quiet); +void ifparser_destroy(void); + +if_block *ifparser_getif(const char* iface); +if_block *ifparser_getfirst(void); +const char *ifparser_getkey(if_block* iface, const char *key); +int ifparser_get_num_blocks(void); +int ifparser_get_num_info(if_block* iface); + +void add_block(const char *type, const char* name); +void add_data(const char *key,const char *data); +void _destroy_data(if_data *ifd); +void _destroy_block(if_block* ifb); +#endif diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.c b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c new file mode 100644 index 00000000..0cc73b34 --- /dev/null +++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -0,0 +1,168 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007,2008 Canonical Ltd. + */ + +#include <string.h> +#include <glib/gstdio.h> +#include <NetworkManager.h> +#include <nm-utils.h> +#include <nm-setting-wireless-security.h> +#include <nm-settings-connection.h> +#include <nm-system-config-interface.h> +#include <nm-settings-error.h> +#include "nm-ifupdown-connection.h" +#include "parser.h" + +G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_IFUPDOWN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionPrivate)) + +typedef struct { + if_block *ifblock; +} NMIfupdownConnectionPrivate; + +enum { + PROP_ZERO, + PROP_IFBLOCK, + _PROP_END, +}; + + +NMIfupdownConnection* +nm_ifupdown_connection_new (if_block *block) +{ + g_return_val_if_fail (block != NULL, NULL); + + return (NMIfupdownConnection *) g_object_new (NM_TYPE_IFUPDOWN_CONNECTION, + NM_IFUPDOWN_CONNECTION_IFBLOCK, block, + NULL); +} + +static gboolean +supports_secrets (NMSettingsConnection *connection, const char *setting_name) +{ + PLUGIN_PRINT ("SCPlugin-Ifupdown", "supports_secrets() for setting_name: '%s'", setting_name); + + return (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); +} + +static void +nm_ifupdown_connection_init (NMIfupdownConnection *connection) +{ +} + +static GObject * +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMIfupdownConnectionPrivate *priv; + GError *error = NULL; + + object = G_OBJECT_CLASS (nm_ifupdown_connection_parent_class)->constructor (type, n_construct_params, construct_params); + g_return_val_if_fail (object, NULL); + + priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object); + if (!priv) { + g_warning ("%s.%d - no private instance.", __FILE__, __LINE__); + goto err; + } + if (!priv->ifblock) { + g_warning ("(ifupdown) ifblock not provided to constructor."); + goto err; + } + + if (!ifupdown_update_connection_from_if_block (NM_CONNECTION (object), priv->ifblock, &error)) { + g_warning ("%s.%d - invalid connection read from /etc/network/interfaces: (%d) %s", + __FILE__, + __LINE__, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + goto err; + } + + return object; + + err: + g_object_unref (object); + return NULL; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMIfupdownConnectionPrivate *priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object); + g_return_if_fail (priv); + + switch (prop_id) { + case PROP_IFBLOCK: + priv->ifblock = g_value_get_pointer (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMIfupdownConnectionPrivate *priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object); + g_return_if_fail (priv); + + switch (prop_id) { + case PROP_IFBLOCK: + g_value_set_pointer (value, priv->ifblock); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class); + NMSettingsConnectionClass *connection_class = NM_SETTINGS_CONNECTION_CLASS (ifupdown_connection_class); + + g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate)); + + /* Virtual methods */ + object_class->constructor = constructor; + object_class->set_property = set_property; + object_class->get_property = get_property; + + connection_class->supports_secrets = supports_secrets; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_IFBLOCK, + g_param_spec_pointer (NM_IFUPDOWN_CONNECTION_IFBLOCK, + "ifblock", + "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h new file mode 100644 index 00000000..510a4d56 --- /dev/null +++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Canonical Ltd. + */ + +#ifndef NM_IFUPDOWN_CONNECTION_H +#define NM_IFUPDOWN_CONNECTION_H + +#include <nm-settings-connection.h> +#include "interface_parser.h" + +G_BEGIN_DECLS + +#define NM_TYPE_IFUPDOWN_CONNECTION (nm_ifupdown_connection_get_type ()) +#define NM_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnection)) +#define NM_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass)) +#define NM_IS_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFUPDOWN_CONNECTION)) +#define NM_IS_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFUPDOWN_CONNECTION)) +#define NM_IFUPDOWN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass)) + +#define NM_IFUPDOWN_CONNECTION_IFBLOCK "ifblock" + +typedef struct { + NMSettingsConnection parent; +} NMIfupdownConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMIfupdownConnectionClass; + +GType nm_ifupdown_connection_get_type (void); + +NMIfupdownConnection *nm_ifupdown_connection_new (if_block *block); + +G_END_DECLS + +#endif /* NM_IFUPDOWN_CONNECTION_H */ diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c new file mode 100644 index 00000000..dc2f8abf --- /dev/null +++ b/src/settings/plugins/ifupdown/parser.c @@ -0,0 +1,577 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Canonical Ltd. + */ + +#include <string.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <errno.h> + +#include <nm-connection.h> +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ppp.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-8021x.h> +#include <nm-system-config-interface.h> +#include <nm-utils.h> + +#include "parser.h" +#include "plugin.h" + + +#define WPA_PMK_LEN 32 + +#include "parser.h" + +static const gchar* +_ifupdownplugin_guess_connection_type (if_block *block) +{ + if_data *curr = block->info; + const gchar* ret_type = NULL; + const gchar* value = ifparser_getkey(block, "inet"); + if(value && !strcmp("ppp", value)) { + ret_type = NM_SETTING_PPP_SETTING_NAME; + } + + while(!ret_type && curr) { + if(!strncmp("wireless-", curr->key, strlen("wireless-")) || + !strncmp("wpa-", curr->key, strlen("wpa-"))) { + ret_type = NM_SETTING_WIRELESS_SETTING_NAME; + } + curr = curr->next; + } + + if(!ret_type) + ret_type = NM_SETTING_WIRED_SETTING_NAME; + + PLUGIN_PRINT("SCPluginIfupdown", + "guessed connection type (%s) = %s", + block->name, ret_type); + return ret_type; +} + + +struct _Mapping { + const gchar *domain; + const gpointer target; +}; + +static gpointer +map_by_mapping(struct _Mapping *mapping, const gchar *key) +{ + struct _Mapping *curr = mapping; + while(curr->domain) { + if(!strcmp(curr->domain, key)) + return curr->target; + curr++; + } + return NULL; +} + +static void +update_wireless_setting_from_if_block(NMConnection *connection, + if_block *block) +{ + gint wpa_l= strlen("wpa-"); + gint wireless_l= strlen("wireless-"); + + if_data *curr = block->info; + const gchar* value = ifparser_getkey (block, "inet"); + struct _Mapping mapping[] = { + {"ssid", "ssid"}, + { NULL, NULL} + }; + + NMSettingWireless *wireless_setting = NULL; + + if(value && !strcmp("ppp", value)) { + return; + } + + PLUGIN_PRINT ("SCPlugin-Ifupdown", "update wireless settings (%s).", block->name); + wireless_setting = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + + while(curr) { + if(strlen(curr->key) > wireless_l && + !strncmp("wireless-", curr->key, wireless_l)) { + const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l); + PLUGIN_PRINT ("SCPlugin-Ifupdown", "wireless setting key: %s='%s'", + newkey, curr->data); + if(newkey && !strcmp("ssid", newkey)) { + GByteArray *ssid; + gint len = strlen(curr->data); + + ssid = g_byte_array_sized_new (len); + g_byte_array_append (ssid, (const guint8 *) curr->data, len); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_byte_array_free (ssid, TRUE); + PLUGIN_PRINT("SCPlugin-Ifupdown", "setting wireless ssid = %d", len); + } else { + g_object_set(wireless_setting, + newkey, curr->data, + NULL); + } + } else if(strlen(curr->key) > wpa_l && + !strncmp("wpa-", curr->key, wpa_l)) { + const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l); + + if(newkey && !strcmp("ssid", newkey)) { + GByteArray *ssid; + gint len = strlen(curr->data); + + ssid = g_byte_array_sized_new (len); + g_byte_array_append (ssid, (const guint8 *) curr->data, len); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_byte_array_free (ssid, TRUE); + PLUGIN_PRINT("SCPlugin-Ifupdown", "setting wpa ssid = %d", len); + } else if(newkey) { + + g_object_set(wireless_setting, + newkey, curr->data, + NULL); + PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wpa newkey(%s)=data(%s)", newkey, curr->data); + } + } + curr = curr->next; + } + nm_connection_add_setting(connection, (NMSetting*) wireless_setting); +} + +typedef gchar* (*IfupdownStrDupeFunc) (gpointer value, gpointer data); +typedef gpointer (*IfupdownStrToTypeFunc) (const gchar* value); + +static char* +normalize_dupe_wireless_key (gpointer value, gpointer data) { + char* valuec = value; + char* endc = valuec + strlen (valuec); + char* delim = valuec; + char* next = delim; + char* result = malloc (strlen (valuec) + 1); + char* result_cur = result; + + while (*delim && (next = strchr (delim, '-')) != NULL) { + if (next == delim) { + delim++; + continue; + } + strncpy (result_cur, delim, next - delim); + result_cur += next - delim; + delim = next + 1; + } + if (*delim && strlen (valuec) > GPOINTER_TO_UINT(delim - valuec)) { + strncpy (result_cur, delim, endc - delim); + result_cur += endc - delim; + } + *result_cur = '\0'; + return result; +} + +static char* +normalize_dupe (gpointer value, gpointer data) { + return g_strdup(value); +} + +static char* +normalize_tolower (gpointer value, gpointer data) { + return g_ascii_strdown(value, -1); +} + +static char *normalize_psk (gpointer value, gpointer data) +{ + if (strlen (value) >= 8 && strlen (value) <= 64) + return g_strdup (value); + return NULL; +} + +static gpointer +string_to_gpointerint(const gchar* data) +{ + gint result = (gint) strtol (data, NULL, 10); + return GINT_TO_POINTER(result); +} + +static gpointer +string_to_glist_of_strings(const gchar* data) +{ + GSList *ret = NULL; + gchar *string = (gchar*) data; + while(string) { + gchar* next = NULL; + if( (next = strchr(string, ' ')) || + (next = strchr(string, '\t')) || + (next = strchr(string, '\0')) ) { + + gchar *part = g_strndup(string, (next - string)); + ret = g_slist_append(ret, part); + if (*next) + string = next+1; + else + string = NULL; + } else { + string = NULL; + } + } + return ret; +} + +static void +slist_free_all(gpointer slist) +{ + GSList *list = (GSList *) slist; + g_slist_foreach (list, (GFunc) g_free, NULL); + g_slist_free (list); +} + +static void +update_wireless_security_setting_from_if_block(NMConnection *connection, + if_block *block) +{ + gint wpa_l= strlen("wpa-"); + gint wireless_l= strlen("wireless-"); + if_data *curr = block->info; + const gchar* value = ifparser_getkey (block, "inet"); + struct _Mapping mapping[] = { + {"psk", "psk"}, + {"identity", "leap-username"}, + {"password", "leap-password"}, + {"key", "wep-key0"}, + {"key-mgmt", "key-mgmt"}, + {"group", "group"}, + {"pairwise", "pairwise"}, + {"proto", "proto"}, + {"pin", "pin"}, + {"wep-key0", "wep-key0"}, + {"wep-key1", "wep-key1"}, + {"wep-key2", "wep-key2"}, + {"wep-key3", "wep-key3"}, + {"wep-tx-keyidx", "wep-tx-keyidx"}, + { NULL, NULL} + }; + + struct _Mapping dupe_mapping[] = { + {"psk", normalize_psk}, + {"identity", normalize_dupe}, + {"password", normalize_dupe}, + {"key", normalize_dupe_wireless_key}, + {"key-mgmt", normalize_tolower}, + {"group", normalize_tolower}, + {"pairwise", normalize_tolower}, + {"proto", normalize_tolower}, + {"pin", normalize_dupe}, + {"wep-key0", normalize_dupe_wireless_key}, + {"wep-key1", normalize_dupe_wireless_key}, + {"wep-key2", normalize_dupe_wireless_key}, + {"wep-key3", normalize_dupe_wireless_key}, + {"wep-tx-keyidx", normalize_dupe}, + { NULL, NULL} + }; + + struct _Mapping type_mapping[] = { + {"group", string_to_glist_of_strings}, + {"pairwise", string_to_glist_of_strings}, + {"proto", string_to_glist_of_strings}, + {"wep-tx-keyidx", string_to_gpointerint}, + { NULL, NULL} + }; + + struct _Mapping free_type_mapping[] = { + {"group", slist_free_all}, + {"pairwise", slist_free_all}, + {"proto", slist_free_all}, + { NULL, NULL} + }; + + NMSettingWirelessSecurity *wireless_security_setting; + NMSettingWireless *s_wireless; + gboolean security = FALSE; + + if(value && !strcmp("ppp", value)) { + return; + } + + s_wireless = NM_SETTING_WIRELESS(nm_connection_get_setting(connection, + NM_TYPE_SETTING_WIRELESS)); + g_return_if_fail(s_wireless); + + PLUGIN_PRINT ("SCPlugin-Ifupdown","update wireless security settings (%s).", block->name); + wireless_security_setting = + NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); + + while(curr) { + if(strlen(curr->key) > wireless_l && + !strncmp("wireless-", curr->key, wireless_l)) { + + gchar *property_value = NULL; + gpointer typed_property_value = NULL; + const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l); + IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wireless_l); + IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wireless_l); + GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wireless_l); + if(!newkey || !dupe_func) { + g_warning("no (wireless) mapping found for key: %s", curr->key); + goto next; + } + property_value = (*dupe_func) (curr->data, connection); + PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wireless security key: %s=%s", + newkey, property_value); + + if (type_map_func) { + errno = 0; + typed_property_value = (*type_map_func) (property_value); + if(errno) + goto wireless_next; + } + + g_object_set(wireless_security_setting, + newkey, typed_property_value ? typed_property_value : property_value, + NULL); + security = TRUE; + + wireless_next: + g_free(property_value); + if (typed_property_value && free_func) + (*free_func) (typed_property_value); + + } else if(strlen(curr->key) > wpa_l && + !strncmp("wpa-", curr->key, wpa_l)) { + + gchar *property_value = NULL; + gpointer typed_property_value = NULL; + const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l); + IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wpa_l); + IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wpa_l); + GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wpa_l); + if(!newkey || !dupe_func) { + goto next; + } + property_value = (*dupe_func) (curr->data, connection); + PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wpa security key: %s=%s", + newkey, +#ifdef DEBUG_SECRETS + property_value +#else // DEBUG_SECRETS + !strcmp("key", newkey) || + !strcmp("leap-password", newkey) || + !strcmp("pin", newkey) || + !strcmp("psk", newkey) || + !strcmp("wep-key0", newkey) || + !strcmp("wep-key1", newkey) || + !strcmp("wep-key2", newkey) || + !strcmp("wep-key3", newkey) || + NULL ? + "<omitted>" : property_value +#endif // DEBUG_SECRETS + ); + + if (type_map_func) { + errno = 0; + typed_property_value = (*type_map_func) (property_value); + if(errno) + goto wpa_next; + } + + g_object_set(wireless_security_setting, + newkey, typed_property_value ? typed_property_value : property_value, + NULL); + security = TRUE; + + wpa_next: + g_free(property_value); + if (free_func && typed_property_value) + (*free_func) (typed_property_value); + } + next: + curr = curr->next; + } + + + if(security) { + nm_connection_add_setting(connection, NM_SETTING(wireless_security_setting)); + g_object_set(s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL); + } + +} + +static void +update_wired_setting_from_if_block(NMConnection *connection, + if_block *block) +{ + NMSettingWired *s_wired = NULL; + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); +} + +static GQuark +eni_plugin_error_quark() { + static GQuark error_quark = 0; + + if(!error_quark) { + error_quark = g_quark_from_static_string ("eni-plugin-error-quark"); + } + + return error_quark; +} + + +static void +update_ip4_setting_from_if_block(NMConnection *connection, + if_block *block) +{ + + NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new()); + const char *type = ifparser_getkey(block, "inet"); + gboolean is_static = type && !strcmp("static", type); + + if(!is_static) { + g_object_set(ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + } else { + struct in_addr tmp_ip4_addr; + NMIP4Address *ip4_addr = nm_ip4_address_new (); + + const char *address_v = ifparser_getkey(block, "address"); + const char *netmask_v = ifparser_getkey(block, "netmask"); + const char *gateway_v = ifparser_getkey(block, "gateway"); + const char *nameserver_v = ifparser_getkey(block, "dns-nameserver"); + const char *nameservers_v = ifparser_getkey(block, "dns-nameservers"); + GSList* nameservers_list = NULL; + GSList* nameservers_list_i = NULL; + GError *error = NULL; + + if(nameservers_v) + nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v); + if(nameserver_v) + nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v)); + + if (!address_v) + address_v = g_strdup ("0.0.0.0"); + + if (inet_pton (AF_INET, address_v, &tmp_ip4_addr)) + nm_ip4_address_set_address (ip4_addr, tmp_ip4_addr.s_addr); + else + g_set_error (&error, eni_plugin_error_quark (), 0, + "Invalid %s IP4 address '%s'", "address", address_v); + if (!netmask_v) + netmask_v = g_strdup( "255.255.255.255"); + + if (inet_pton (AF_INET, netmask_v, &tmp_ip4_addr)) + nm_ip4_address_set_prefix (ip4_addr, nm_utils_ip4_netmask_to_prefix(tmp_ip4_addr.s_addr)); + else + g_set_error (&error, eni_plugin_error_quark (), 0, + "Invalid %s IP4 address '%s'", "netmask", netmask_v); + + if (!gateway_v) + gateway_v = g_strdup (address_v); + + if (inet_pton (AF_INET, gateway_v, &tmp_ip4_addr)) + nm_ip4_address_set_gateway (ip4_addr, tmp_ip4_addr.s_addr); + else + g_set_error (&error, eni_plugin_error_quark (), 0, + "Invalid %s IP4 address '%s'", "gateway", gateway_v); + + if (nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d", + nm_setting_ip4_config_get_num_addresses (ip4_setting)); + } else { + PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP4 address"); + } + + while(nameservers_list_i) { + gchar *dns = nameservers_list_i->data; + nameservers_list_i = nameservers_list_i -> next; + if(!dns) + continue; + if (inet_pton (AF_INET, dns, &tmp_ip4_addr)) { + if (!nm_setting_ip4_config_add_dns (ip4_setting, tmp_ip4_addr.s_addr)) + PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns); + } else + g_set_error (&error, eni_plugin_error_quark (), 0, + "Invalid %s IP4 address nameserver '%s'", "nameserver", dns); + } + if (!nm_setting_ip4_config_get_num_dns (ip4_setting)) + PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces"); + + g_object_set(ip4_setting, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + g_slist_foreach (nameservers_list, (GFunc) g_free, NULL); + g_slist_free (nameservers_list); + } + + nm_connection_add_setting(connection, NM_SETTING(ip4_setting)); +} + +gboolean +ifupdown_update_connection_from_if_block (NMConnection *connection, + if_block *block, + GError **error) +{ + const char *type = NULL; + char *idstr = NULL; + char *uuid_base = NULL; + char *uuid = NULL; + NMSettingConnection *s_con; + gboolean success = FALSE; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if(!s_con) { + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new()); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + } + + type = _ifupdownplugin_guess_connection_type (block); + idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); + uuid_base = idstr; + + uuid = nm_utils_uuid_generate_from_string (uuid_base); + g_object_set (s_con, + NM_SETTING_CONNECTION_TYPE, type, + NM_SETTING_CONNECTION_ID, idstr, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_READ_ONLY, TRUE, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NULL); + g_free (uuid); + + PLUGIN_PRINT("SCPlugin-Ifupdown", "update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", + block->name, type, idstr, nm_setting_connection_get_uuid (s_con)); + + if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type)) + update_wired_setting_from_if_block (connection, block); + else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { + update_wireless_setting_from_if_block (connection, block); + update_wireless_security_setting_from_if_block (connection, block); + } + + update_ip4_setting_from_if_block (connection, block); + + success = nm_connection_verify (connection, error); + + g_free (idstr); + return success; +} diff --git a/src/settings/plugins/ifupdown/parser.h b/src/settings/plugins/ifupdown/parser.h new file mode 100644 index 00000000..6aebb8c7 --- /dev/null +++ b/src/settings/plugins/ifupdown/parser.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Canonical Ltd. + */ + +#include <nm-connection.h> +#include "interface_parser.h" + +G_BEGIN_DECLS + +gboolean +ifupdown_update_connection_from_if_block (NMConnection *connection, + if_block *block, + GError **error); + +G_END_DECLS diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c new file mode 100644 index 00000000..9679edea --- /dev/null +++ b/src/settings/plugins/ifupdown/plugin.c @@ -0,0 +1,727 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007,2008 Canonical Ltd. + * (C) Copyright 2009 Red Hat, Inc. + */ + +#include <string.h> +#include <sys/inotify.h> + +#include <net/ethernet.h> +#include <netinet/ether.h> + +#include <gmodule.h> +#include <glib-object.h> +#include <glib/gi18n.h> +#include <glib.h> +#include <nm-setting-connection.h> + +#include "interface_parser.h" + +#include "NetworkManager.h" +#include "nm-system-config-interface.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wired.h" +#include "nm-setting-ppp.h" + +#include "nm-ifupdown-connection.h" +#include "plugin.h" +#include "parser.h" +#include "nm-inotify-helper.h" + +#include "nm-logging.h" + +#include <arpa/inet.h> + +#include <gudev/gudev.h> + +#define ENI_INTERFACES_FILE "/etc/network/interfaces" + +#define IFUPDOWN_PLUGIN_NAME "ifupdown" +#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list." +#define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname" + +#define IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf" +#define IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf" + +#define IFUPDOWN_KEY_FILE_GROUP "ifupdown" +#define IFUPDOWN_KEY_FILE_KEY_MANAGED "managed" +#define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE + +/* #define ALWAYS_UNMANAGE TRUE */ +#ifndef ALWAYS_UNMANAGE +# define ALWAYS_UNMANAGE FALSE +#endif + +typedef struct { + GUdevClient *client; + + GHashTable *iface_connections; + gchar* hostname; + + GHashTable *well_known_interfaces; + GHashTable *well_known_ifaces; + gboolean unmanage_well_known; + const char *conf_file; + + gulong inotify_event_id; + int inotify_system_hostname_wd; +} SCPluginIfupdownPrivate; + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); + +G_DEFINE_TYPE_EXTENDED (SCPluginIfupdown, sc_plugin_ifupdown, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) + +#define SC_PLUGIN_IFUPDOWN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownPrivate)) + +static void +sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class); + +static void +SCPluginIfupdown_init (NMSystemConfigInterface *config); + +/* Returns the plugins currently known list of connections. The returned + * list is freed by the system settings service. + */ +static GSList* +SCPluginIfupdown_get_connections (NMSystemConfigInterface *config); + +/* + * Return a list of device specifications which NetworkManager should not + * manage. Returned list will be freed by the system settings service, and + * each element must be allocated using g_malloc() or its variants. + */ +static GSList* +SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config); + + +/* GObject */ +static void +GObject__get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); + +static void +GObject__set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); + +static void +GObject__dispose (GObject *object); + +/* other helpers */ +static const char * +get_hostname (NMSystemConfigInterface *config); + + +static void +update_system_hostname(NMInotifyHelper *inotify_helper, + struct inotify_event *evt, + const char *path, + NMSystemConfigInterface *config); + + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class) +{ + system_config_interface_class->init = SCPluginIfupdown_init; + system_config_interface_class->get_connections = SCPluginIfupdown_get_connections; + system_config_interface_class->get_unmanaged_specs = SCPluginIfupdown_get_unmanaged_specs; +} + +static void +sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginIfupdownPrivate)); + + object_class->dispose = GObject__dispose; + object_class->get_property = GObject__get_property; + object_class->set_property = GObject__set_property; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +ignore_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ +} + +static void +bind_device_to_connection (SCPluginIfupdown *self, + GUdevDevice *device, + NMIfupdownConnection *exported) +{ + GByteArray *mac_address; + NMSetting *s_wired = NULL; + NMSetting *s_wifi = NULL; + const char *iface, *address; + struct ether_addr *tmp_mac; + + iface = g_udev_device_get_name (device); + if (!iface) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device."); + return; + } + + address = g_udev_device_get_sysfs_attr (device, "address"); + if (!address || !strlen (address)) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface); + return; + } + + tmp_mac = ether_aton (address); + if (!tmp_mac) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", + address, iface); + return; + } + + mac_address = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN); + + s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED); + s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS); + if (s_wired) { + PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); + } else if (s_wifi) { + PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting"); + g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); + } + g_byte_array_free (mac_address, TRUE); + + nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); +} + +static void +udev_device_added (SCPluginIfupdown *self, GUdevDevice *device) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + NMIfupdownConnection *exported; + + iface = g_udev_device_get_name (device); + path = g_udev_device_get_sysfs_path (device); + if (!iface || !path) + return; + + PLUGIN_PRINT("SCPlugin-Ifupdown", + "devices added (path: %s, iface: %s)", path, iface); + + /* if we have a configured connection for this particular iface + * we want to either unmanage the device or lock it + */ + exported = (NMIfupdownConnection *) g_hash_table_lookup (priv->iface_connections, iface); + if (!exported && !g_hash_table_lookup (priv->well_known_interfaces, iface)) { + PLUGIN_PRINT("SCPlugin-Ifupdown", + "device added (path: %s, iface: %s): no ifupdown configuration found.", path, iface); + return; + } + + g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device)); + + if (exported) + bind_device_to_connection (self, device, exported); + + if (ALWAYS_UNMANAGE || priv->unmanage_well_known) + g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); +} + +static void +udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + + iface = g_udev_device_get_name (device); + path = g_udev_device_get_sysfs_path (device); + if (!iface || !path) + return; + + PLUGIN_PRINT("SCPlugin-Ifupdown", + "devices removed (path: %s, iface: %s)", path, iface); + + if (!g_hash_table_remove (priv->well_known_ifaces, iface)) + return; + + if (ALWAYS_UNMANAGE || priv->unmanage_well_known) + g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); +} + +static void +handle_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (user_data); + const char *subsys; + + g_return_if_fail (action != NULL); + + /* A bit paranoid */ + subsys = g_udev_device_get_subsystem (device); + g_return_if_fail (subsys != NULL); + g_return_if_fail (strcmp (subsys, "net") == 0); + + if (!strcmp (action, "add")) + udev_device_added (self, device); + else if (!strcmp (action, "remove")) + udev_device_removed (self, device); +} + +static void +SCPluginIfupdown_init (NMSystemConfigInterface *config) +{ + SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config); + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + GHashTable *auto_ifaces; + if_block *block = NULL; + NMInotifyHelper *inotify_helper; + GKeyFile* keyfile; + GError *error = NULL; + GList *keys, *iter; + const char *subsys[2] = { "net", NULL }; + + auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); + + if(!priv->iface_connections) + priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal); + + if(!priv->well_known_ifaces) + priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + if(!priv->well_known_interfaces) + priv->well_known_interfaces = g_hash_table_new (g_str_hash, g_str_equal); + + PLUGIN_PRINT("SCPlugin-Ifupdown", "init!"); + + priv->client = g_udev_client_new (subsys); + if (!priv->client) { + PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev"); + } else + g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); + + priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT; + + inotify_helper = nm_inotify_helper_get (); + priv->inotify_event_id = g_signal_connect (inotify_helper, + "event", + G_CALLBACK (update_system_hostname), + config); + + priv->inotify_system_hostname_wd = + nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE); + + update_system_hostname (inotify_helper, NULL, NULL, config); + + /* Read in all the interfaces */ + ifparser_init (ENI_INTERFACES_FILE, 0); + block = ifparser_getfirst (); + while (block) { + if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) + g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); + else if (!strcmp ("iface", block->type)) { + NMIfupdownConnection *exported; + + /* Bridge configuration */ + if(!strncmp ("br", block->name, 2)) { + /* Try to find bridge ports */ + const char *ports = ifparser_getkey (block, "bridge-ports"); + if (ports) { + int i; + int state = 0; + char **port_ifaces; + + PLUGIN_PRINT("SCPlugin-Ifupdown", "found bridge ports %s for %s", ports, block->name); + + port_ifaces = g_strsplit_set (ports, " \t", -1); + for (i = 0; i < g_strv_length (port_ifaces); i++) { + char *token = port_ifaces[i]; + /* Skip crazy stuff like regex or all */ + if (!strcmp ("all", token)) { + continue; + } + /* Small SM to skip everything inside regex */ + if (!strcmp ("regex", token)) { + state++; + continue; + } + if (!strcmp ("noregex", token)) { + state--; + continue; + } + if (state == 0 && strlen (token) > 0) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding bridge port %s to well_known_interfaces", token); + g_hash_table_insert (priv->well_known_interfaces, g_strdup (token), "known"); + } + } + g_strfreev (port_ifaces); + } + goto next; + } + + /* Skip loopback configuration */ + if(!strcmp ("lo", block->name)) { + goto next; + } + + /* Remove any connection for this block that was previously found */ + exported = g_hash_table_lookup (priv->iface_connections, block->name); + if (exported) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); + g_hash_table_remove (priv->iface_connections, block->name); + } + + /* add the new connection */ + exported = nm_ifupdown_connection_new (block); + if (exported) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding %s to iface_connections", block->name); + g_hash_table_insert (priv->iface_connections, block->name, exported); + } + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding iface %s to well_known_interfaces", block->name); + g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); + } else if (!strcmp ("mapping", block->type)) { + g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name); + } + next: + block = block->next; + } + + /* Make 'auto' interfaces autoconnect=TRUE */ + keys = g_hash_table_get_keys (priv->iface_connections); + for (iter = keys; iter; iter = g_list_next (iter)) { + NMIfupdownConnection *exported; + NMSetting *setting; + + if (!g_hash_table_lookup (auto_ifaces, iter->data)) + continue; + + exported = g_hash_table_lookup (priv->iface_connections, iter->data); + setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); + g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); + + nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); + + PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); + } + g_list_free (keys); + g_hash_table_destroy (auto_ifaces); + + /* Find the config file */ + if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS)) + priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE; + else + priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE; + + keyfile = g_key_file_new (); + if (!g_key_file_load_from_file (keyfile, + priv->conf_file, + G_KEY_FILE_NONE, + &error)) { + nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s", + priv->conf_file, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + } else { + gboolean manage_well_known; + error = NULL; + + manage_well_known = g_key_file_get_boolean (keyfile, + IFUPDOWN_KEY_FILE_GROUP, + IFUPDOWN_KEY_FILE_KEY_MANAGED, + &error); + if (error) { + nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s", + IFUPDOWN_KEY_FILE_GROUP, + IFUPDOWN_KEY_FILE_KEY_MANAGED, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + } else + priv->unmanage_well_known = !manage_well_known; + } + PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); + if (keyfile) + g_key_file_free (keyfile); + + /* Add well-known interfaces */ + keys = g_udev_client_query_by_subsystem (priv->client, "net"); + for (iter = keys; iter; iter = g_list_next (iter)) { + udev_device_added (self, G_UDEV_DEVICE (iter->data)); + g_object_unref (G_UDEV_DEVICE (iter->data)); + } + g_list_free (keys); + + /* Now if we're running in managed mode, let NM know there are new connections */ + if (!priv->unmanage_well_known) { + GList *con_list = g_hash_table_get_values (priv->iface_connections); + GList *cl_iter; + + for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { + g_signal_emit_by_name (self, + NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, + NM_SETTINGS_CONNECTION (cl_iter->data)); + } + g_list_free (con_list); + } + + PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init."); +} + + +/* Returns the plugins currently known list of connections. The returned + * list is freed by the system settings service. + */ +static GSList* +SCPluginIfupdown_get_connections (NMSystemConfigInterface *config) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + GSList *connections = NULL; + GHashTableIter iter; + gpointer value; + + PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) ... get_connections.", GPOINTER_TO_UINT(config)); + + if(priv->unmanage_well_known) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) ... get_connections (managed=false): return empty list.", GPOINTER_TO_UINT(config)); + return NULL; + } + + g_hash_table_iter_init (&iter, priv->iface_connections); + while (g_hash_table_iter_next (&iter, NULL, &value)) + connections = g_slist_prepend (connections, value); + + PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections)); + return connections; +} + +/* + * Return a list of device specifications which NetworkManager should not + * manage. Returned list will be freed by the system settings service, and + * each element must be allocated using g_malloc() or its variants. + */ +static GSList* +SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + GSList *specs = NULL; + GHashTableIter iter; + gpointer value; + + if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known) + return NULL; + + PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", + g_hash_table_size (priv->well_known_ifaces)); + + g_hash_table_iter_init (&iter, priv->well_known_ifaces); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + GUdevDevice *device = G_UDEV_DEVICE (value); + const char *address; + + address = g_udev_device_get_sysfs_attr (device, "address"); + if (address) + specs = g_slist_append (specs, g_strdup_printf ("mac:%s", address)); + } + return specs; +} + + +static const char * +get_hostname (NMSystemConfigInterface *config) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + return priv->hostname; +} + +static void +update_system_hostname(NMInotifyHelper *inotify_helper, + struct inotify_event *evt, + const char *path, + NMSystemConfigInterface *config) +{ + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + gchar *hostname_file = NULL; + gsize hostname_file_len = 0; + GError *error = NULL; + + PLUGIN_PRINT ("SCPlugin-Ifupdown", "update_system_hostname"); + + if (evt && evt->wd != priv->inotify_system_hostname_wd) + return; + + if(!g_file_get_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE, + &hostname_file, + &hostname_file_len, + &error)) { + nm_log_warn (LOGD_SETTINGS, "update_system_hostname() - couldn't read " + IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)", + error->code, error->message); + return; + } + + g_free(priv->hostname); + priv->hostname = g_strstrip(hostname_file); + + /* We shouldn't return a zero-length hostname, but NULL */ + if (priv->hostname && !strlen (priv->hostname)) { + g_free (priv->hostname); + priv->hostname = NULL; + } + + g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +write_system_hostname(NMSystemConfigInterface *config, + const char *newhostname) +{ + GError *error = NULL; + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + PLUGIN_PRINT ("SCPlugin-Ifupdown", "write_system_hostname: %s", newhostname); + + g_return_if_fail (newhostname); + + if(!g_file_set_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE, + newhostname, + -1, + &error)) { + nm_log_warn (LOGD_SETTINGS, "update_system_hostname() - couldn't write hostname (%s) to " + IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)", + newhostname, error->code, error->message); + } else { + priv->hostname = g_strdup (newhostname); + } + g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + + +static void +sc_plugin_ifupdown_init (SCPluginIfupdown *plugin) +{ +} + +static void +GObject__get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object); + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, IFUPDOWN_PLUGIN_NAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, IFUPDOWN_PLUGIN_INFO); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + { + g_value_set_string (value, get_hostname(self)); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +GObject__set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + { + const gchar *hostname = g_value_get_string (value); + if (hostname && strlen (hostname) < 1) + hostname = NULL; + write_system_hostname(NM_SYSTEM_CONFIG_INTERFACE(object), + hostname); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +GObject__dispose (GObject *object) +{ + SCPluginIfupdown *plugin = SC_PLUGIN_IFUPDOWN (object); + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin); + NMInotifyHelper *inotify_helper = nm_inotify_helper_get (); + + g_signal_handler_disconnect (inotify_helper, priv->inotify_event_id); + + if (priv->inotify_system_hostname_wd >= 0) + nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd); + + if (priv->well_known_ifaces) + g_hash_table_destroy(priv->well_known_ifaces); + + if (priv->well_known_interfaces) + g_hash_table_destroy(priv->well_known_interfaces); + + if (priv->client) + g_object_unref (priv->client); + + G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object); +} + +G_MODULE_EXPORT GObject * +nm_system_config_factory (void) +{ + static SCPluginIfupdown *singleton = NULL; + + if (!singleton) + singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL)); + else + g_object_ref (singleton); + + return G_OBJECT (singleton); +} + diff --git a/src/settings/plugins/ifupdown/plugin.h b/src/settings/plugins/ifupdown/plugin.h new file mode 100644 index 00000000..09f8767a --- /dev/null +++ b/src/settings/plugins/ifupdown/plugin.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager system settings service (ifupdown) + * + * Alexander Sack <asac@ubuntu.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Canonical Ltd. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <glib-object.h> + +#define PLUGIN_NAME "ifupdown" + +#define SC_TYPE_PLUGIN_IFUPDOWN (sc_plugin_ifupdown_get_type ()) +#define SC_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdown)) +#define SC_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownClass)) +#define SC_IS_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFUPDOWN)) +#define SC_IS_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFUPDOWN)) +#define SC_PLUGIN_IFUPDOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownClass)) + +typedef struct _SCPluginIfupdown SCPluginIfupdown; +typedef struct _SCPluginIfupdownClass SCPluginIfupdownClass; + +struct _SCPluginIfupdown { + GObject parent; +}; + +struct _SCPluginIfupdownClass { + GObjectClass parent; +}; + +GType sc_plugin_ifupdown_get_type (void); + +GQuark ifupdown_plugin_error_quark (void); + +#endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am new file mode 100644 index 00000000..aed86197 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/Makefile.am @@ -0,0 +1,32 @@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +noinst_PROGRAMS = test-ifupdown + +test_ifupdown_SOURCES = \ + test-ifupdown.c + +test_ifupdown_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_ENI_DIR=\"$(abs_srcdir)\" + +test_ifupdown_LDADD = \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifupdown-io.la \ + $(DBUS_LIBS) + +if WITH_TESTS + +check-local: test-ifupdown + $(abs_builddir)/test-ifupdown + +endif + +EXTRA_DIST = \ + test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ + test13 test14 test15 test16 diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in new file mode 100644 index 00000000..8bd83a15 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -0,0 +1,632 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-ifupdown$(EXEEXT) +subdir = src/settings/plugins/ifupdown/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_ifupdown_OBJECTS = test_ifupdown-test-ifupdown.$(OBJEXT) +test_ifupdown_OBJECTS = $(am_test_ifupdown_OBJECTS) +am__DEPENDENCIES_1 = +test_ifupdown_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifupdown-io.la $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(test_ifupdown_SOURCES) +DIST_SOURCES = $(test_ifupdown_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +test_ifupdown_SOURCES = \ + test-ifupdown.c + +test_ifupdown_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_ENI_DIR=\"$(abs_srcdir)\" + +test_ifupdown_LDADD = \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(builddir)/../libifupdown-io.la \ + $(DBUS_LIBS) + +EXTRA_DIST = \ + test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ + test13 test14 test15 test16 + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_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 +test-ifupdown$(EXEEXT): $(test_ifupdown_OBJECTS) $(test_ifupdown_DEPENDENCIES) + @rm -f test-ifupdown$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ifupdown_OBJECTS) $(test_ifupdown_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifupdown-test-ifupdown.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_ifupdown-test-ifupdown.o: test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifupdown-test-ifupdown.o -MD -MP -MF $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o test_ifupdown-test-ifupdown.o `test -f 'test-ifupdown.c' || echo '$(srcdir)/'`test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo $(DEPDIR)/test_ifupdown-test-ifupdown.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifupdown.c' object='test_ifupdown-test-ifupdown.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifupdown-test-ifupdown.o `test -f 'test-ifupdown.c' || echo '$(srcdir)/'`test-ifupdown.c + +test_ifupdown-test-ifupdown.obj: test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifupdown-test-ifupdown.obj -MD -MP -MF $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o test_ifupdown-test-ifupdown.obj `if test -f 'test-ifupdown.c'; then $(CYGPATH_W) 'test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/test-ifupdown.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo $(DEPDIR)/test_ifupdown-test-ifupdown.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifupdown.c' object='test_ifupdown-test-ifupdown.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifupdown-test-ifupdown.obj `if test -f 'test-ifupdown.c'; then $(CYGPATH_W) 'test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/test-ifupdown.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@WITH_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +@WITH_TESTS_TRUE@check-local: test-ifupdown +@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifupdown + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c new file mode 100644 index 00000000..16465364 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -0,0 +1,496 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + * + */ + +#include <glib.h> +#include <string.h> + +#include "interface_parser.h" +#include "parser.h" + +typedef struct { + char *key; + char *data; +} ExpectedKey; + +typedef struct { + char *type; + char *name; + GSList *keys; +} ExpectedBlock; + +typedef struct { + GSList *blocks; +} Expected; + +static ExpectedKey * +expected_key_new (const char *key, const char *data) +{ + ExpectedKey *k; + + k = g_malloc0 (sizeof (ExpectedKey)); + g_assert (k); + k->key = g_strdup (key); + g_assert (k->key); + k->data = g_strdup (data); + g_assert (k->data); + return k; +} + +static void +expected_key_free (ExpectedKey *k) +{ + g_assert (k); + g_free (k->key); + g_free (k->data); + memset (k, 0, sizeof (ExpectedKey)); + g_free (k); +} + +static ExpectedBlock * +expected_block_new (const char *type, const char *name) +{ + ExpectedBlock *b; + + g_assert (type); + g_assert (name); + b = g_malloc0 (sizeof (ExpectedBlock)); + g_assert (b); + b->type = g_strdup (type); + b->name = g_strdup (name); + return b; +} + +static void +expected_block_free (ExpectedBlock *b) +{ + g_assert (b); + g_slist_foreach (b->keys, (GFunc) expected_key_free, NULL); + g_slist_free (b->keys); + g_free (b->type); + g_free (b->name); + memset (b, 0, sizeof (ExpectedBlock)); + g_free (b); +} + +static void +expected_block_add_key (ExpectedBlock *b, ExpectedKey *k) +{ + g_assert (b); + g_assert (k); + b->keys = g_slist_append (b->keys, k); +} + +static Expected * +expected_new (void) +{ + Expected *e; + + e = g_malloc0 (sizeof (Expected)); + g_assert (e); + return e; +} + +static void +expected_add_block (Expected *e, ExpectedBlock *b) +{ + g_assert (e); + g_assert (b); + e->blocks = g_slist_append (e->blocks, b); +} + +static void +expected_free (Expected *e) +{ + g_assert (e); + g_slist_foreach (e->blocks, (GFunc) expected_block_free, NULL); + g_slist_free (e->blocks); + memset (e, 0, sizeof (Expected)); + g_free (e); +} + +static void +compare_expected_to_ifparser (Expected *e) +{ + if_block *n; + GSList *biter, *kiter; + + g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks ()); + + for (n = ifparser_getfirst (), biter = e->blocks; + n && biter; + n = n->next, biter = g_slist_next (biter)) { + if_data *m; + ExpectedBlock *b = biter->data; + + g_assert (b->type && n->type); + g_assert_cmpstr (b->type, ==, n->type); + g_assert (b->name && n->name); + g_assert_cmpstr (b->name, ==, n->name); + + g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n)); + + for (m = n->info, kiter = b->keys; + m && kiter; + m = m->next, kiter = g_slist_next (kiter)) { + ExpectedKey *k = kiter->data; + + g_assert (k->key && m->key); + g_assert_cmpstr (k->key, ==, m->key); + g_assert (k->data && m->data); + g_assert_cmpstr (k->data, ==, m->data); + } + } +} + +static void +dump_blocks (void) +{ + if_block *n; + + g_message ("\n***************************************************"); + for (n = ifparser_getfirst (); n != NULL; n = n->next) { + if_data *m; + + // each block start with its type & name + // (single quotes used to show typ & name baoundaries) + g_print("'%s' '%s'\n", n->type, n->name); + + // each key-value pair within a block is indented & separated by a tab + // (single quotes used to show typ & name baoundaries) + for (m = n->info; m != NULL; m = m->next) + g_print("\t'%s'\t'%s'\n", m->key, m->data); + + // blocks are separated by an empty line + g_print("\n"); + } + g_message ("##################################################\n"); +} + +static void +init_ifparser_with_file (const char *path, const char *file) +{ + char *tmp; + + tmp = g_strdup_printf ("%s/%s", path, file); + ifparser_init (tmp, 1); + g_free (tmp); +} + +static void +test1_ignore_line_before_first_block (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("auto", "eth0"); + expected_add_block (e, b); + b = expected_block_new ("iface", "eth0"); + expected_add_block (e, b); + expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + + init_ifparser_with_file (path, "test1"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test2_wrapped_line (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("auto", "lo"); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test2"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test3_wrapped_multiline_multiarg (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("allow-hotplug", "eth0"); + expected_add_block (e, b); + b = expected_block_new ("allow-hotplug", "wlan0"); + expected_add_block (e, b); + b = expected_block_new ("allow-hotplug", "bnep0"); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test3"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test4_allow_auto_is_auto (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("auto", "eth0"); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test4"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test5_allow_auto_multiarg (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("allow-hotplug", "eth0"); + expected_add_block (e, b); + b = expected_block_new ("allow-hotplug", "wlan0"); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test5"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test6_mixed_whitespace (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "lo"); + expected_block_add_key (b, expected_key_new ("inet", "loopback")); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test6"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test7_long_line (const char *path) +{ + init_ifparser_with_file (path, "test7"); + g_assert_cmpint (ifparser_get_num_blocks (), ==, 0); + ifparser_destroy (); +} + +static void +test8_long_line_wrapped (const char *path) +{ + init_ifparser_with_file (path, "test8"); + g_assert_cmpint (ifparser_get_num_blocks (), ==, 0); + ifparser_destroy (); +} + +static void +test9_wrapped_lines_in_block (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "eth0"); + expected_add_block (e, b); + expected_block_add_key (b, expected_key_new ("inet", "static")); + expected_block_add_key (b, expected_key_new ("address", "10.250.2.3")); + expected_block_add_key (b, expected_key_new ("netmask", "255.255.255.192")); + expected_block_add_key (b, expected_key_new ("broadcast", "10.250.2.63")); + expected_block_add_key (b, expected_key_new ("gateway", "10.250.2.50")); + + init_ifparser_with_file (path, "test9"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test11_complex_wrap (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "pppoe"); + expected_add_block (e, b); + expected_block_add_key (b, expected_key_new ("inet", "manual")); + expected_block_add_key (b, expected_key_new ("pre-up", "/sbin/ifconfig eth0 up")); + + init_ifparser_with_file (path, "test11"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test12_complex_wrap_split_word (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "pppoe"); + expected_add_block (e, b); + expected_block_add_key (b, expected_key_new ("inet", "manual")); + expected_block_add_key (b, expected_key_new ("up", "ifup ppp0=dsl")); + + init_ifparser_with_file (path, "test12"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test13_more_mixed_whitespace (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "dsl"); + expected_block_add_key (b, expected_key_new ("inet", "ppp")); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test13"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test14_mixed_whitespace_block_start (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "wlan0"); + expected_block_add_key (b, expected_key_new ("inet", "manual")); + expected_add_block (e, b); + b = expected_block_new ("iface", "wlan-adpm"); + expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + expected_add_block (e, b); + b = expected_block_new ("iface", "wlan-default"); + expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test14"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test15_trailing_space (const char *path) +{ + Expected *e; + ExpectedBlock *b; + + e = expected_new (); + b = expected_block_new ("iface", "bnep0"); + expected_block_add_key (b, expected_key_new ("inet", "static")); + expected_add_block (e, b); + + init_ifparser_with_file (path, "test15"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +static void +test16_missing_newline (const char *path) +{ + Expected *e; + + e = expected_new (); + expected_add_block (e, expected_block_new ("mapping", "eth0")); + + init_ifparser_with_file (path, "test16"); + compare_expected_to_ifparser (e); + + ifparser_destroy (); + expected_free (e); +} + +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else +typedef void (*TCFunc)(void); +#endif + +#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) + +int main (int argc, char **argv) +{ + GTestSuite *suite; + + g_test_init (&argc, &argv, NULL); + + suite = g_test_get_root (); + + if (0) + dump_blocks (); + + g_test_suite_add (suite, TESTCASE (test1_ignore_line_before_first_block, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test2_wrapped_line, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test3_wrapped_multiline_multiarg, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test4_allow_auto_is_auto, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test5_allow_auto_multiarg, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test6_mixed_whitespace, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test7_long_line, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test8_long_line_wrapped, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test9_wrapped_lines_in_block, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test11_complex_wrap, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test12_complex_wrap_split_word, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test13_more_mixed_whitespace, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test14_mixed_whitespace_block_start, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR)); + g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR)); + + return g_test_run (); +} + diff --git a/src/settings/plugins/ifupdown/tests/test1 b/src/settings/plugins/ifupdown/tests/test1 new file mode 100644 index 00000000..74c23b45 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test1 @@ -0,0 +1,6 @@ +# case 1: line before 1st block (must be ignored) +address 10.250.2.3 + +auto eth0 +iface eth0 inet dhcp + diff --git a/src/settings/plugins/ifupdown/tests/test11 b/src/settings/plugins/ifupdown/tests/test11 new file mode 100644 index 00000000..89561dd7 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test11 @@ -0,0 +1,5 @@ +iface pppoe inet manual +# case 11: wrapped line (without leading space on the wrapped part, wrap within a multi-word value) + pre-up /sbin/ifconfig \ +eth0 up + diff --git a/src/settings/plugins/ifupdown/tests/test12 b/src/settings/plugins/ifupdown/tests/test12 new file mode 100644 index 00000000..6096842e --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test12 @@ -0,0 +1,5 @@ +iface pppoe inet manual +# case 12: wrapped line, splitting a word (must be joined again) + up ifup ppp0\ +=dsl + diff --git a/src/settings/plugins/ifupdown/tests/test13 b/src/settings/plugins/ifupdown/tests/test13 new file mode 100644 index 00000000..c001f7ef --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test13 @@ -0,0 +1,3 @@ +# case 13: variations of tabs & spaces +iface dsl inet ppp + diff --git a/src/settings/plugins/ifupdown/tests/test14 b/src/settings/plugins/ifupdown/tests/test14 new file mode 100644 index 00000000..4a153ab3 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test14 @@ -0,0 +1,5 @@ +# case 14: variations of tabs and spaces (all must be recognized as lines starting an iface block) +iface wlan0 inet manual + iface wlan-adpm inet dhcp +iface wlan-default inet dhcp + diff --git a/src/settings/plugins/ifupdown/tests/test15 b/src/settings/plugins/ifupdown/tests/test15 new file mode 100644 index 00000000..c3ceca24 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test15 @@ -0,0 +1,3 @@ +# case 15: trailing space (must be ignored) +iface bnep0 inet static + diff --git a/src/settings/plugins/ifupdown/tests/test16 b/src/settings/plugins/ifupdown/tests/test16 new file mode 100644 index 00000000..f4f74fb5 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test16 @@ -0,0 +1,2 @@ +# case 16: last line that is not followed by LF (added with 'echo -n "mapping eth0" >> /e/n/i') +mapping eth0 \ No newline at end of file diff --git a/src/settings/plugins/ifupdown/tests/test2 b/src/settings/plugins/ifupdown/tests/test2 new file mode 100644 index 00000000..7462b352 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test2 @@ -0,0 +1,4 @@ +# case 2: wrapped line +auto \ +lo + diff --git a/src/settings/plugins/ifupdown/tests/test3 b/src/settings/plugins/ifupdown/tests/test3 new file mode 100644 index 00000000..f6293bbd --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test3 @@ -0,0 +1,5 @@ +# case 3: line wrapped over multiple lines & multi-argument allow-* +allow-hotplug eth0 \ + wlan0 \ + bnep0 + diff --git a/src/settings/plugins/ifupdown/tests/test4 b/src/settings/plugins/ifupdown/tests/test4 new file mode 100644 index 00000000..46a40bc9 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test4 @@ -0,0 +1,3 @@ +# case 4: 'allow-auto' is synonymous to 'auto' +allow-auto eth0 + diff --git a/src/settings/plugins/ifupdown/tests/test5 b/src/settings/plugins/ifupdown/tests/test5 new file mode 100644 index 00000000..b69fc42b --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test5 @@ -0,0 +1,3 @@ +# case 5: multi-argument allow-* (even worse: trailing space) +allow-hotplug eth0 wlan0 + diff --git a/src/settings/plugins/ifupdown/tests/test6 b/src/settings/plugins/ifupdown/tests/test6 new file mode 100644 index 00000000..50ac69bd --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test6 @@ -0,0 +1,3 @@ +# case 6: mix between tabs and spaces + iface lo inet loopback + diff --git a/src/settings/plugins/ifupdown/tests/test7 b/src/settings/plugins/ifupdown/tests/test7 new file mode 100644 index 00000000..03cb131a --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test7 @@ -0,0 +1,3 @@ +# case 7: over-long line (must be ignored completely) +123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 + diff --git a/src/settings/plugins/ifupdown/tests/test8 b/src/settings/plugins/ifupdown/tests/test8 new file mode 100644 index 00000000..311f7e15 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test8 @@ -0,0 +1,5 @@ +# case 8: over-long line that wraps to consecutive lines (must be ignored completely) +123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 \ +allow-test eth0 \ +eth0 + diff --git a/src/settings/plugins/ifupdown/tests/test9 b/src/settings/plugins/ifupdown/tests/test9 new file mode 100644 index 00000000..7d94563a --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/test9 @@ -0,0 +1,10 @@ +iface eth0 inet static +# case 9: wrapped lines inside a block (to be on the safe side) + address \ + 10.250.2.3 + netmask \ + 255.255.255.192 + + broadcast 10.250.2.63 + gateway 10.250.2.50 + diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am new file mode 100644 index 00000000..3b242142 --- /dev/null +++ b/src/settings/plugins/keyfile/Makefile.am @@ -0,0 +1,61 @@ +SUBDIRS=. tests + +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util + +noinst_LTLIBRARIES = \ + libkeyfile-io.la \ + libnm-settings-plugin-keyfile.la + +##### I/O library for testcases ##### + +libkeyfile_io_la_SOURCES = \ + reader.c \ + reader.h \ + writer.c \ + writer.h \ + errors.c \ + utils.c \ + utils.h \ + common.h + +libkeyfile_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_DISABLE_DEPRECATED + +libkeyfile_io_la_LIBADD = $(GLIB_LIBS) + +##################################### + +libnm_settings_plugin_keyfile_la_SOURCES = \ + nm-keyfile-connection.c \ + nm-keyfile-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_keyfile_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_DISABLE_DEPRECATED + +libnm_settings_plugin_keyfile_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + libkeyfile-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(DBUS_LIBS) \ + $(GIO_LIBS) + +libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic + +keyfiledir=$(sysconfdir)/NetworkManager/system-connections + +install-data-hook: + $(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir) + diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in new file mode 100644 index 00000000..409499d7 --- /dev/null +++ b/src/settings/plugins/keyfile/Makefile.in @@ -0,0 +1,865 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/keyfile +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libkeyfile_io_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libkeyfile_io_la_OBJECTS = libkeyfile_io_la-reader.lo \ + libkeyfile_io_la-writer.lo libkeyfile_io_la-errors.lo \ + libkeyfile_io_la-utils.lo +libkeyfile_io_la_OBJECTS = $(am_libkeyfile_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libnm_settings_plugin_keyfile_la_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la libkeyfile-io.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libnm_settings_plugin_keyfile_la_OBJECTS = \ + libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo \ + libnm_settings_plugin_keyfile_la-plugin.lo +libnm_settings_plugin_keyfile_la_OBJECTS = \ + $(am_libnm_settings_plugin_keyfile_la_OBJECTS) +libnm_settings_plugin_keyfile_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_keyfile_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libkeyfile_io_la_SOURCES) \ + $(libnm_settings_plugin_keyfile_la_SOURCES) +DIST_SOURCES = $(libkeyfile_io_la_SOURCES) \ + $(libnm_settings_plugin_keyfile_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests +INCLUDES = \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util + +noinst_LTLIBRARIES = \ + libkeyfile-io.la \ + libnm-settings-plugin-keyfile.la + + +##### I/O library for testcases ##### +libkeyfile_io_la_SOURCES = \ + reader.c \ + reader.h \ + writer.c \ + writer.h \ + errors.c \ + utils.c \ + utils.h \ + common.h + +libkeyfile_io_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_DISABLE_DEPRECATED + +libkeyfile_io_la_LIBADD = $(GLIB_LIBS) + +##################################### +libnm_settings_plugin_keyfile_la_SOURCES = \ + nm-keyfile-connection.c \ + nm-keyfile-connection.h \ + plugin.c \ + plugin.h + +libnm_settings_plugin_keyfile_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_DISABLE_DEPRECATED + +libnm_settings_plugin_keyfile_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + libkeyfile-io.la \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(DBUS_LIBS) \ + $(GIO_LIBS) + +libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic +keyfiledir = $(sysconfdir)/NetworkManager/system-connections +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libkeyfile-io.la: $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_LIBADD) $(LIBS) +libnm-settings-plugin-keyfile.la: $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_keyfile_la_LINK) $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-errors.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-reader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-writer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libkeyfile_io_la-reader.lo: reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-reader.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-reader.Tpo -c -o libkeyfile_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-reader.Tpo $(DEPDIR)/libkeyfile_io_la-reader.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reader.c' object='libkeyfile_io_la-reader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c + +libkeyfile_io_la-writer.lo: writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-writer.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-writer.Tpo -c -o libkeyfile_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-writer.Tpo $(DEPDIR)/libkeyfile_io_la-writer.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writer.c' object='libkeyfile_io_la-writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c + +libkeyfile_io_la-errors.lo: errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-errors.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-errors.Tpo -c -o libkeyfile_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-errors.Tpo $(DEPDIR)/libkeyfile_io_la-errors.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libkeyfile_io_la-errors.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c + +libkeyfile_io_la-utils.lo: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-utils.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-utils.Tpo -c -o libkeyfile_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-utils.Tpo $(DEPDIR)/libkeyfile_io_la-utils.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libkeyfile_io_la-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c + +libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo: nm-keyfile-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Tpo -c -o libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo `test -f 'nm-keyfile-connection.c' || echo '$(srcdir)/'`nm-keyfile-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Tpo $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-keyfile-connection.c' object='libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo `test -f 'nm-keyfile-connection.c' || echo '$(srcdir)/'`nm-keyfile-connection.c + +libnm_settings_plugin_keyfile_la-plugin.lo: plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_keyfile_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Tpo -c -o libnm_settings_plugin_keyfile_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_keyfile_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_keyfile_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-data-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am + + +install-data-hook: + $(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h new file mode 100644 index 00000000..6c8f9ceb --- /dev/null +++ b/src/settings/plugins/keyfile/common.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include <glib.h> + +#define SWP_TAG ".swp" +#define SWPX_TAG ".swpx" + +#define KEYFILE_PLUGIN_NAME "keyfile" +#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." + +#define KEYFILE_DIR SYSCONFDIR "/NetworkManager/system-connections" + +#define VPN_SECRETS_GROUP "vpn-secrets" + +#define KEYFILE_PLUGIN_ERROR (keyfile_plugin_error_quark ()) +GQuark keyfile_plugin_error_quark (void); + +#endif /* __COMMON_H__ */ + diff --git a/src/settings/plugins/keyfile/errors.c b/src/settings/plugins/keyfile/errors.c new file mode 100644 index 00000000..e2e97690 --- /dev/null +++ b/src/settings/plugins/keyfile/errors.c @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + */ + +#include <glib.h> +#include "common.h" + +GQuark +keyfile_plugin_error_quark (void) +{ + static GQuark error_quark = 0; + + if (G_UNLIKELY (error_quark == 0)) + error_quark = g_quark_from_static_string ("keyfile-plugin-error-quark"); + + return error_quark; +} + + diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c new file mode 100644 index 00000000..23618f7c --- /dev/null +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c @@ -0,0 +1,173 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <string.h> +#include <glib/gstdio.h> +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-utils.h> + +#include "nm-system-config-interface.h" +#include "nm-dbus-glib-types.h" +#include "nm-keyfile-connection.h" +#include "reader.h" +#include "writer.h" +#include "common.h" + +G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) + +typedef struct { + char *path; +} NMKeyfileConnectionPrivate; + +NMKeyfileConnection * +nm_keyfile_connection_new (const char *full_path, + NMConnection *source, + GError **error) +{ + GObject *object; + NMKeyfileConnectionPrivate *priv; + NMConnection *tmp; + const char *uuid; + + g_return_val_if_fail (full_path != NULL, NULL); + + /* If we're given a connection already, prefer that instead of re-reading */ + if (source) + tmp = g_object_ref (source); + else { + tmp = nm_keyfile_plugin_connection_from_file (full_path, error); + if (!tmp) + return NULL; + } + + object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); + if (!object) + goto out; + + priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); + priv->path = g_strdup (full_path); + + /* Update our settings with what was read from the file */ + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) { + g_object_unref (object); + object = NULL; + goto out; + } + + uuid = nm_connection_get_uuid (NM_CONNECTION (object)); + if (!uuid) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Connection in file %s had no UUID", full_path); + g_object_unref (object); + object = NULL; + } + +out: + g_object_unref (tmp); + return (NMKeyfileConnection *) object; +} + +const char * +nm_keyfile_connection_get_path (NMKeyfileConnection *self) +{ + g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL); + + return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path; +} + +static void +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) +{ + NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); + char *path = NULL; + GError *error = NULL; + + if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), + priv->path, + &path, + &error)) { + callback (connection, error, user_data); + g_clear_error (&error); + return; + } + + /* Update the filename if it changed */ + if (path) { + g_free (priv->path); + priv->path = path; + } + + NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, + callback, + user_data); +} + +static void +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) +{ + NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); + + g_unlink (priv->path); + + NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, + callback, + user_data); +} + +/* GObject */ + +static void +nm_keyfile_connection_init (NMKeyfileConnection *connection) +{ +} + +static void +finalize (GObject *object) +{ + NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); + + nm_connection_clear_secrets (NM_CONNECTION (object)); + + g_free (priv->path); + + G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object); +} + +static void +nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class); + + g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + settings_class->commit_changes = commit_changes; + settings_class->delete = do_delete; +} diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h new file mode 100644 index 00000000..bf64e69a --- /dev/null +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#ifndef NM_KEYFILE_CONNECTION_H +#define NM_KEYFILE_CONNECTION_H + +#include <nm-settings-connection.h> + +G_BEGIN_DECLS + +#define NM_TYPE_KEYFILE_CONNECTION (nm_keyfile_connection_get_type ()) +#define NM_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnection)) +#define NM_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass)) +#define NM_IS_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION)) +#define NM_IS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION)) +#define NM_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass)) + +typedef struct { + NMSettingsConnection parent; +} NMKeyfileConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMKeyfileConnectionClass; + +GType nm_keyfile_connection_get_type (void); + +NMKeyfileConnection *nm_keyfile_connection_new (const char *filename, + NMConnection *source, + GError **error); + +const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self); + +G_END_DECLS + +#endif /* NM_KEYFILE_CONNECTION_H */ diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c new file mode 100644 index 00000000..ffc614bc --- /dev/null +++ b/src/settings/plugins/keyfile/plugin.c @@ -0,0 +1,654 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/types.h> +#include <netinet/ether.h> +#include <string.h> + +#include <gmodule.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <gio/gio.h> + +#include <nm-connection.h> +#include <nm-setting.h> +#include <nm-setting-connection.h> + +#include "plugin.h" +#include "nm-system-config-interface.h" +#include "nm-keyfile-connection.h" +#include "writer.h" +#include "common.h" +#include "utils.h" + +#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf" +#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf" + +static char *plugin_get_hostname (SCPluginKeyfile *plugin); +static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); + +G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) + +#define SC_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfilePrivate)) + +typedef struct { + GHashTable *hash; + + GFileMonitor *monitor; + guint monitor_id; + + const char *conf_file; + GFileMonitor *conf_file_monitor; + guint conf_file_monitor_id; + + char *hostname; + + gboolean disposed; +} SCPluginKeyfilePrivate; + +static NMSettingsConnection * +_internal_new_connection (SCPluginKeyfile *self, + const char *full_path, + NMConnection *source, + GError **error) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + NMKeyfileConnection *connection; + + g_return_val_if_fail (full_path != NULL, NULL); + + connection = nm_keyfile_connection_new (full_path, source, error); + if (connection) { + g_hash_table_insert (priv->hash, + (gpointer) nm_keyfile_connection_get_path (connection), + connection); + } + + return (NMSettingsConnection *) connection; +} + +static void +read_connections (NMSystemConfigInterface *config) +{ + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + GDir *dir; + GError *error = NULL; + const char *item; + + dir = g_dir_open (KEYFILE_DIR, 0, &error); + if (!dir) { + PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s", + KEYFILE_DIR, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + return; + } + + while ((item = g_dir_read_name (dir))) { + NMSettingsConnection *connection; + char *full_path; + + if (nm_keyfile_plugin_utils_should_ignore_file (item)) + continue; + + full_path = g_build_filename (KEYFILE_DIR, item, NULL); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); + + connection = _internal_new_connection (self, full_path, NULL, &error); + if (connection) { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", + nm_connection_get_id (NM_CONNECTION (connection))); + } else { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", + (error && error->message) ? error->message : "(unknown)"); + } + g_clear_error (&error); + g_free (full_path); + } + g_dir_close (dir); +} + +static void +update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, gpointer user_data) +{ + if (error) { + g_warning ("%s: '%s' / '%s' invalid: %d", + __func__, + error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)", + (error && error->message) ? error->message : "(none)", + error ? error->code : -1); + g_clear_error (&error); + + nm_settings_connection_signal_remove (orig); + } +} + +static void +update_connection_settings (NMKeyfileConnection *orig, + NMKeyfileConnection *new) +{ + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (orig), + NM_CONNECTION (new), + update_connection_settings_commit_cb, NULL); +} + +/* Monitoring */ + +static void +remove_connection (SCPluginKeyfile *self, + NMKeyfileConnection *connection, + const char *name) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (name != NULL); + + /* Removing from the hash table should drop the last reference */ + g_object_ref (connection); + g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); + g_object_unref (connection); +} + +static NMKeyfileConnection * +find_by_uuid (SCPluginKeyfile *self, const char *uuid) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data = NULL; + + g_return_val_if_fail (uuid != NULL, NULL); + + g_hash_table_iter_init (&iter, priv->hash); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *candidate = NM_CONNECTION (data); + + if (strcmp (uuid, nm_connection_get_uuid (candidate)) == 0) + return NM_KEYFILE_CONNECTION (candidate); + } + return NULL; +} + +static void +dir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data); + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + char *full_path; + NMKeyfileConnection *connection; + GError *error = NULL; + + full_path = g_file_get_path (file); + if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) { + g_free (full_path); + return; + } + + connection = g_hash_table_lookup (priv->hash, full_path); + + switch (event_type) { + case G_FILE_MONITOR_EVENT_DELETED: + if (connection) { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", full_path); + remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); + } + break; + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + if (connection) { + /* Update */ + NMKeyfileConnection *tmp; + + tmp = nm_keyfile_connection_new (full_path, NULL, &error); + if (tmp) { + if (!nm_connection_compare (NM_CONNECTION (connection), + NM_CONNECTION (tmp), + NM_SETTING_COMPARE_FLAG_EXACT)) { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); + update_connection_settings (connection, tmp); + } + g_object_unref (tmp); + } else { + /* Error; remove the connection */ + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); + } + } else { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); + + /* New */ + connection = nm_keyfile_connection_new (full_path, NULL, &error); + if (connection) { + NMKeyfileConnection *found = NULL; + + /* Connection renames will show up as different files but with + * the same UUID. Try to find the original connection. + * A connection rename is treated just like an update except + * there's a bit more housekeeping with the hash table. + */ + found = find_by_uuid (self, nm_connection_get_uuid (NM_CONNECTION (connection))); + if (found) { + const char *old_path = nm_keyfile_connection_get_path (connection); + + /* Removing from the hash table should drop the last reference, + * but of course we want to keep the connection around. + */ + g_object_ref (found); + g_hash_table_remove (priv->hash, old_path); + + /* Updating settings should update the NMKeyfileConnection's + * filename property too. + */ + update_connection_settings (found, connection); + + /* Re-insert the connection back into the hash with the new filename */ + g_hash_table_insert (priv->hash, + (gpointer) nm_keyfile_connection_get_path (found), + found); + + /* Get rid of the temporary connection */ + g_object_unref (connection); + } else { + g_hash_table_insert (priv->hash, + (gpointer) nm_keyfile_connection_get_path (connection), + connection); + g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); + } + } else { + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + } + } + break; + default: + break; + } + + g_free (full_path); +} + +static void +conf_file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer data) +{ + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (data); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + char *tmp; + + switch (event_type) { + case G_FILE_MONITOR_EVENT_DELETED: + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + + /* hostname */ + tmp = plugin_get_hostname (self); + if ((tmp && !priv->hostname) + || (!tmp && priv->hostname) + || (priv->hostname && tmp && strcmp (priv->hostname, tmp))) { + + g_free (priv->hostname); + priv->hostname = tmp; + tmp = NULL; + g_object_notify (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); + } + + g_free (tmp); + + break; + default: + break; + } +} + +static void +setup_monitoring (NMSystemConfigInterface *config) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); + GFile *file; + GFileMonitor *monitor; + + priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + + file = g_file_new_for_path (KEYFILE_DIR); + monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); + + if (monitor) { + priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config); + priv->monitor = monitor; + } + + file = g_file_new_for_path (priv->conf_file); + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); + + if (monitor) { + priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config); + priv->conf_file_monitor = monitor; + } +} + +/* Plugin */ + +static GSList * +get_connections (NMSystemConfigInterface *config) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); + GHashTableIter iter; + gpointer data = NULL; + GSList *list = NULL; + + if (!priv->hash) { + setup_monitoring (config); + read_connections (config); + } + + g_hash_table_iter_init (&iter, priv->hash); + while (g_hash_table_iter_next (&iter, NULL, &data)) + list = g_slist_prepend (list, data); + return list; +} + +static NMSettingsConnection * +add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error) +{ + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + NMSettingsConnection *added = NULL; + char *path = NULL; + + /* Write it out first, then add the connection to our internal list */ + if (nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) { + added = _internal_new_connection (self, path, connection, error); + g_free (path); + } + return added; +} + +static GSList * +get_unmanaged_specs (NMSystemConfigInterface *config) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); + GKeyFile *key_file; + GSList *specs = NULL; + GError *error = NULL; + + key_file = g_key_file_new (); + if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { + char *str; + + str = g_key_file_get_value (key_file, "keyfile", "unmanaged-devices", NULL); + if (str) { + char **udis; + int i; + + udis = g_strsplit (str, ";", -1); + g_free (str); + + for (i = 0; udis[i] != NULL; i++) { + /* Verify unmanaged specification and add it to the list */ + if (strlen (udis[i]) > 4 && !strncmp (udis[i], "mac:", 4) && ether_aton (udis[i] + 4)) { + char *p = udis[i]; + + /* To accept uppercase MACs in configuration file, we have to convert values to lowercase here. + * Unmanaged MACs in specs are always in lowercase. */ + while (*p) { + *p = g_ascii_tolower (*p); + p++; + } + specs = g_slist_append (specs, udis[i]); + } else { + g_warning ("Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); + g_free (udis[i]); + } + } + + g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ + } + } else { + g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); + g_error_free (error); + } + + g_key_file_free (key_file); + + return specs; +} + +static char * +plugin_get_hostname (SCPluginKeyfile *plugin) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); + GKeyFile *key_file; + char *hostname = NULL; + GError *error = NULL; + + key_file = g_key_file_new (); + if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) + hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL); + else { + g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); + g_error_free (error); + } + + g_key_file_free (key_file); + + return hostname; +} + +static gboolean +plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); + GKeyFile *key_file; + GError *error = NULL; + gboolean result = FALSE; + + key_file = g_key_file_new (); + if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { + char *data; + gsize len; + + g_key_file_set_string (key_file, "keyfile", "hostname", hostname); + + data = g_key_file_to_data (key_file, &len, &error); + if (data) { + g_file_set_contents (priv->conf_file, data, len, &error); + g_free (data); + + g_free (priv->hostname); + priv->hostname = g_strdup (hostname); + result = TRUE; + } + + if (error) { + g_warning ("Error saving hostname: %s", error->message); + g_error_free (error); + } + } else { + g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); + g_error_free (error); + } + + g_key_file_free (key_file); + + return result; +} + +/* GObject */ + +static void +sc_plugin_keyfile_init (SCPluginKeyfile *plugin) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); + + if (g_file_test (CONF_FILE, G_FILE_TEST_EXISTS)) + priv->conf_file = CONF_FILE; + else + priv->conf_file = OLD_CONF_FILE; + + priv->hostname = plugin_get_hostname (plugin); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, KEYFILE_PLUGIN_NAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, KEYFILE_PLUGIN_INFO); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS | + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + g_value_set_string (value, SC_PLUGIN_KEYFILE_GET_PRIVATE (object)->hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + const char *hostname; + + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME: + hostname = g_value_get_string (value); + if (hostname && strlen (hostname) < 1) + hostname = NULL; + plugin_set_hostname (SC_PLUGIN_KEYFILE (object), hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (object); + + if (priv->disposed) + return; + + priv->disposed = TRUE; + + if (priv->monitor) { + if (priv->monitor_id) + g_signal_handler_disconnect (priv->monitor, priv->monitor_id); + + g_file_monitor_cancel (priv->monitor); + g_object_unref (priv->monitor); + } + + if (priv->conf_file_monitor) { + if (priv->conf_file_monitor_id) + g_signal_handler_disconnect (priv->conf_file_monitor, priv->conf_file_monitor_id); + + g_file_monitor_cancel (priv->conf_file_monitor); + g_object_unref (priv->conf_file_monitor); + } + + g_free (priv->hostname); + + if (priv->hash) + g_hash_table_destroy (priv->hash); + + G_OBJECT_CLASS (sc_plugin_keyfile_parent_class)->dispose (object); +} + +static void +sc_plugin_keyfile_class_init (SCPluginKeyfileClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginKeyfilePrivate)); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class) +{ + /* interface implementation */ + system_config_interface_class->get_connections = get_connections; + system_config_interface_class->add_connection = add_connection; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; +} + +GObject * +nm_settings_keyfile_plugin_new (void) +{ + static SCPluginKeyfile *singleton = NULL; + + if (!singleton) + singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL)); + else + g_object_ref (singleton); + + return G_OBJECT (singleton); +} diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h new file mode 100644 index 00000000..af5147ef --- /dev/null +++ b/src/settings/plugins/keyfile/plugin.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Red Hat, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include <glib-object.h> + +#define SC_TYPE_PLUGIN_KEYFILE (sc_plugin_keyfile_get_type ()) +#define SC_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfile)) +#define SC_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass)) +#define SC_IS_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE)) +#define SC_IS_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE)) +#define SC_PLUGIN_KEYFILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass)) + +typedef struct { + GObject parent; +} SCPluginKeyfile; + +typedef struct { + GObjectClass parent; +} SCPluginKeyfileClass; + +GType sc_plugin_keyfile_get_type (void); + +GQuark keyfile_plugin_error_quark (void); + +GObject *nm_settings_keyfile_plugin_new (void); + +#endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c new file mode 100644 index 00000000..a8eaaa8e --- /dev/null +++ b/src/settings/plugins/keyfile/reader.c @@ -0,0 +1,1266 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2009 Novell, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. + */ + +#include <errno.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/types.h> +#include <dbus/dbus-glib.h> +#include <nm-setting.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-vpn.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-bluetooth.h> +#include <nm-setting-8021x.h> +#include <arpa/inet.h> +#include <netinet/ether.h> +#include <string.h> +#include <ctype.h> + +#include "nm-dbus-glib-types.h" +#include "reader.h" +#include "common.h" + +static gboolean +read_array_of_uint (GKeyFile *file, + NMSetting *setting, + const char *key) +{ + GArray *array = NULL; + gsize length; + int i; + gint *tmp; + + tmp = g_key_file_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); + array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); + for (i = 0; i < length; i++) + g_array_append_val (array, tmp[i]); + + if (array) { + g_object_set (setting, key, array, NULL); + g_array_free (array, TRUE); + } + + return TRUE; +} + +static gboolean +get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *out) +{ + long tmp; + + errno = 0; + tmp = strtol (str, NULL, 10); + if (errno || (tmp < 0) || (tmp > max_val)) { + g_warning ("%s: ignoring invalid IP %s item '%s'", __func__, key_name, str); + return FALSE; + } + + *out = (guint32) tmp; + return TRUE; +} + +static void +free_one_ip4_address (gpointer data, gpointer user_data) +{ + g_array_free ((GArray *) data, TRUE); +} + +static GPtrArray * +read_ip4_addresses (GKeyFile *file, + const char *setting_name, + const char *key) +{ + GPtrArray *addresses; + int i = 0; + + addresses = g_ptr_array_sized_new (3); + + /* Look for individual addresses */ + while (i++ < 1000) { + gchar **tmp, **iter; + char *key_name; + gsize length = 0; + int ret; + GArray *address; + guint32 empty = 0; + int j; + + key_name = g_strdup_printf ("%s%d", key, i); + tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL); + g_free (key_name); + + if (!tmp || !length) + break; /* all done */ + + if ((length < 2) || (length > 3)) { + g_warning ("%s: ignoring invalid IPv4 address item '%s'", __func__, key_name); + goto next; + } + + /* convert the string array into IP addresses */ + address = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); + for (iter = tmp, j = 0; *iter; iter++, j++) { + struct in_addr addr; + + if (j == 1) { + guint32 prefix = 0; + + /* prefix */ + if (!get_one_int (*iter, 32, key_name, &prefix)) { + g_array_free (address, TRUE); + goto next; + } + + g_array_append_val (address, prefix); + } else { + /* address and gateway */ + ret = inet_pton (AF_INET, *iter, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter); + g_array_free (address, TRUE); + goto next; + } + g_array_append_val (address, addr.s_addr); + } + } + + /* fill in blank gateway if not specified */ + if (address->len == 2) + g_array_append_val (address, empty); + + g_ptr_array_add (addresses, address); + +next: + g_strfreev (tmp); + } + + if (addresses->len < 1) { + g_ptr_array_free (addresses, TRUE); + addresses = NULL; + } + + return addresses; +} + +static void +ip4_addr_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + GPtrArray *addresses; + const char *setting_name = nm_setting_get_name (setting); + + addresses = read_ip4_addresses (keyfile, setting_name, key); + + /* Work around for previous syntax */ + if (!addresses && !strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES)) + addresses = read_ip4_addresses (keyfile, setting_name, "address"); + + if (addresses) { + g_object_set (setting, key, addresses, NULL); + g_ptr_array_foreach (addresses, free_one_ip4_address, NULL); + g_ptr_array_free (addresses, TRUE); + } +} + +static void +free_one_ip4_route (gpointer data, gpointer user_data) +{ + g_array_free ((GArray *) data, TRUE); +} + +static GPtrArray * +read_ip4_routes (GKeyFile *file, + const char *setting_name, + const char *key) +{ + GPtrArray *routes; + int i = 0; + + routes = g_ptr_array_sized_new (3); + + /* Look for individual routes */ + while (i++ < 1000) { + gchar **tmp, **iter; + char *key_name; + gsize length = 0; + int ret; + GArray *route; + int j; + + key_name = g_strdup_printf ("%s%d", key, i); + tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL); + g_free (key_name); + + if (!tmp || !length) + break; /* all done */ + + if (length != 4) { + g_warning ("%s: ignoring invalid IPv4 route item '%s'", __func__, key_name); + goto next; + } + + /* convert the string array into IP addresses */ + route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4); + for (iter = tmp, j = 0; *iter; iter++, j++) { + struct in_addr addr; + + if (j == 1) { + guint32 prefix = 0; + + /* prefix */ + if (!get_one_int (*iter, 32, key_name, &prefix)) { + g_array_free (route, TRUE); + goto next; + } + + g_array_append_val (route, prefix); + } else if (j == 3) { + guint32 metric = 0; + + /* metric */ + if (!get_one_int (*iter, G_MAXUINT32, key_name, &metric)) { + g_array_free (route, TRUE); + goto next; + } + + g_array_append_val (route, metric); + } else { + /* address and next hop */ + ret = inet_pton (AF_INET, *iter, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter); + g_array_free (route, TRUE); + goto next; + } + g_array_append_val (route, addr.s_addr); + } + } + g_ptr_array_add (routes, route); + +next: + g_strfreev (tmp); + } + + if (routes->len < 1) { + g_ptr_array_free (routes, TRUE); + routes = NULL; + } + + return routes; +} + +static void +ip4_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + GPtrArray *routes; + const char *setting_name = nm_setting_get_name (setting); + + routes = read_ip4_routes (keyfile, setting_name, key); + if (routes) { + g_object_set (setting, key, routes, NULL); + g_ptr_array_foreach (routes, free_one_ip4_route, NULL); + g_ptr_array_free (routes, TRUE); + } +} + +static void +ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + GArray *array = NULL; + gsize length; + char **list, **iter; + int ret; + + list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL); + if (!list || !g_strv_length (list)) + return; + + array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); + for (iter = list; *iter; iter++) { + struct in_addr addr; + + ret = inet_pton (AF_INET, *iter, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid DNS server address '%s'", __func__, *iter); + continue; + } + + g_array_append_val (array, addr.s_addr); + } + g_strfreev (list); + + if (array) { + g_object_set (setting, key, array, NULL); + g_array_free (array, TRUE); + } +} + +static void +free_one_ip6_address (gpointer data, gpointer user_data) +{ + g_value_array_free ((GValueArray *) data); +} + +static char * +split_prefix (char *addr) +{ + char *slash; + + g_return_val_if_fail (addr != NULL, NULL); + + /* Find the prefix and split the string */ + slash = strchr (addr, '/'); + if (slash && slash > addr) { + slash++; + *(slash - 1) = '\0'; + } + + return slash; +} + +static char * +split_gw (char *str) +{ + char *comma; + + g_return_val_if_fail (str != NULL, NULL); + + /* Find the prefix and split the string */ + comma = strchr (str, ','); + if (comma && comma > str) { + comma++; + *(comma - 1) = '\0'; + return comma; + } + return NULL; +} + +static GPtrArray * +read_ip6_addresses (GKeyFile *file, + const char *setting_name, + const char *key) +{ + GPtrArray *addresses; + struct in6_addr addr, gw; + guint32 prefix; + int i = 0; + + addresses = g_ptr_array_sized_new (3); + + /* Look for individual addresses */ + while (i++ < 1000) { + char *tmp, *key_name, *str_prefix, *str_gw; + int ret; + GValueArray *values; + GByteArray *address; + GByteArray *gateway; + GValue value = { 0 }; + + key_name = g_strdup_printf ("%s%d", key, i); + tmp = g_key_file_get_string (file, setting_name, key_name, NULL); + g_free (key_name); + + if (!tmp) + break; /* all done */ + + /* convert the string array into IPv6 addresses */ + values = g_value_array_new (2); /* NMIP6Address has 2 items */ + + /* Split the address and prefix */ + str_prefix = split_prefix (tmp); + + /* address */ + ret = inet_pton (AF_INET6, tmp, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp); + g_value_array_free (values); + goto next; + } + + address = g_byte_array_new (); + g_byte_array_append (address, (guint8 *) addr.s6_addr, 16); + g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_take_boxed (&value, address); + g_value_array_append (values, &value); + g_value_unset (&value); + + /* prefix */ + prefix = 0; + if (str_prefix) { + if (!get_one_int (str_prefix, 128, key_name, &prefix)) { + g_value_array_free (values); + goto next; + } + } else { + /* Missing prefix defaults to /64 */ + prefix = 64; + } + + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, prefix); + g_value_array_append (values, &value); + g_value_unset (&value); + + /* Gateway (optional) */ + str_gw = split_gw (str_prefix); + if (str_gw) { + ret = inet_pton (AF_INET6, str_gw, &gw); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv6 %s gateway '%s'", __func__, key_name, tmp); + g_value_array_free (values); + goto next; + } + + if (!IN6_IS_ADDR_UNSPECIFIED (&gw)) { + gateway = g_byte_array_new (); + g_byte_array_append (gateway, (guint8 *) gw.s6_addr, 16); + g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_take_boxed (&value, gateway); + g_value_array_append (values, &value); + g_value_unset (&value); + } + } + + g_ptr_array_add (addresses, values); + +next: + g_free (tmp); + } + + if (addresses->len < 1) { + g_ptr_array_free (addresses, TRUE); + addresses = NULL; + } + + return addresses; +} + +static void +ip6_addr_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + GPtrArray *addresses; + const char *setting_name = nm_setting_get_name (setting); + + addresses = read_ip6_addresses (keyfile, setting_name, key); + if (addresses) { + g_object_set (setting, key, addresses, NULL); + g_ptr_array_foreach (addresses, free_one_ip6_address, NULL); + g_ptr_array_free (addresses, TRUE); + } +} + +static void +free_one_ip6_route (gpointer data, gpointer user_data) +{ + g_value_array_free ((GValueArray *) data); +} + +static GPtrArray * +read_ip6_routes (GKeyFile *file, + const char *setting_name, + const char *key) +{ + GPtrArray *routes; + struct in6_addr addr; + guint32 prefix, metric; + int i = 0; + + routes = g_ptr_array_sized_new (3); + + /* Look for individual routes */ + while (i++ < 1000) { + gchar **tmp; + char *key_name, *str_prefix; + gsize length = 0; + int ret; + GValueArray *values; + GByteArray *address; + GValue value = { 0 }; + + key_name = g_strdup_printf ("%s%d", key, i); + tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL); + g_free (key_name); + + if (!tmp || !length) + break; /* all done */ + + if (length != 3) { + g_warning ("%s: ignoring invalid IPv6 address item '%s'", __func__, key_name); + goto next; + } + + /* convert the string array into IPv6 routes */ + values = g_value_array_new (4); /* NMIP6Route has 4 items */ + + /* Split the route and prefix */ + str_prefix = split_prefix (tmp[0]); + + /* destination address */ + ret = inet_pton (AF_INET6, tmp[0], &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp[0]); + g_value_array_free (values); + goto next; + } + address = g_byte_array_new (); + g_byte_array_append (address, (guint8 *) addr.s6_addr, 16); + g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_take_boxed (&value, address); + g_value_array_append (values, &value); + g_value_unset (&value); + + /* prefix */ + prefix = 0; + if (str_prefix) { + if (!get_one_int (str_prefix, 128, key_name, &prefix)) { + g_value_array_free (values); + goto next; + } + } else { + /* default to 64 if unspecified */ + prefix = 64; + } + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, prefix); + g_value_array_append (values, &value); + g_value_unset (&value); + + /* next hop address */ + ret = inet_pton (AF_INET6, tmp[1], &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp[1]); + g_value_array_free (values); + goto next; + } + address = g_byte_array_new (); + g_byte_array_append (address, (guint8 *) addr.s6_addr, 16); + g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_take_boxed (&value, address); + g_value_array_append (values, &value); + g_value_unset (&value); + + /* metric */ + metric = 0; + if (!get_one_int (tmp[2], G_MAXUINT32, key_name, &metric)) { + g_value_array_free (values); + goto next; + } + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, metric); + g_value_array_append (values, &value); + g_value_unset (&value); + + g_ptr_array_add (routes, values); + +next: + g_strfreev (tmp); + } + + if (routes->len < 1) { + g_ptr_array_free (routes, TRUE); + routes = NULL; + } + + return routes; +} + +static void +ip6_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + GPtrArray *routes; + const char *setting_name = nm_setting_get_name (setting); + + routes = read_ip6_routes (keyfile, setting_name, key); + + if (routes) { + g_object_set (setting, key, routes, NULL); + g_ptr_array_foreach (routes, free_one_ip6_route, NULL); + g_ptr_array_free (routes, TRUE); + } +} + +static void +free_one_ip6_dns (gpointer data, gpointer user_data) +{ + g_byte_array_free ((GByteArray *) data, TRUE); +} + +static void +ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + GPtrArray *array = NULL; + gsize length; + char **list, **iter; + int ret; + + list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL); + if (!list || !g_strv_length (list)) + return; + + array = g_ptr_array_sized_new (length); + for (iter = list; *iter; iter++) { + GByteArray *byte_array; + struct in6_addr addr; + + ret = inet_pton (AF_INET6, *iter, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter); + continue; + } + byte_array = g_byte_array_new (); + g_byte_array_append (byte_array, (guint8 *) addr.s6_addr, 16); + + g_ptr_array_add (array, byte_array); + } + g_strfreev (list); + + if (array) { + g_object_set (setting, key, array, NULL); + g_ptr_array_foreach (array, free_one_ip6_dns, NULL); + g_ptr_array_free (array, TRUE); + } +} + +static void +mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + struct ether_addr *eth; + char *tmp_string = NULL, *p; + gint *tmp_list; + GByteArray *array = NULL; + gsize length; + int i; + + p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); + if (tmp_string) { + /* Look for enough ':' characters to signify a MAC address */ + i = 0; + while (*p) { + if (*p == ':') + i++; + p++; + } + if (i == 5) { + /* parse as a MAC address */ + eth = ether_aton (tmp_string); + if (eth) { + g_free (tmp_string); + array = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN); + goto done; + } + } + } + g_free (tmp_string); + + /* Old format; list of ints */ + tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); + array = g_byte_array_sized_new (length); + for (i = 0; i < length; i++) { + int val = tmp_list[i]; + unsigned char v = (unsigned char) (val & 0xFF); + + if (val < 0 || val > 255) { + g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); + } else + g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); + } + g_free (tmp_list); + +done: + if (array->len == ETH_ALEN) { + g_object_set (setting, key, array, NULL); + } else { + g_warning ("%s: ignoring invalid MAC address for %s / %s", + __func__, setting_name, key); + } + g_byte_array_free (array, TRUE); +} + +static void +read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) +{ + char **keys, **iter; + char *value; + const char *setting_name = nm_setting_get_name (setting); + + keys = g_key_file_get_keys (file, setting_name, NULL, NULL); + if (!keys || !*keys) + return; + + for (iter = keys; *iter; iter++) { + value = g_key_file_get_string (file, setting_name, *iter, NULL); + if (!value) + continue; + + if (NM_IS_SETTING_VPN (setting)) { + if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE)) + nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value); + } + g_free (value); + } + g_strfreev (keys); +} + +static GByteArray * +get_uchar_array (GKeyFile *keyfile, + const char *setting_name, + const char *key) +{ + GByteArray *array = NULL; + char *p, *tmp_string; + gint *tmp_list; + gsize length; + int i; + + /* New format: just a string. We try parsing the new format if there are + * no ';' in the string or it's not just numbers. + */ + p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); + if (tmp_string) { + gboolean new_format = FALSE; + + if (strchr (p, ';') == NULL) + new_format = TRUE; + else { + new_format = TRUE; + while (p && *p) { + if (!isdigit (*p++)) { + new_format = FALSE; + break; + } + } + } + + if (new_format) { + array = g_byte_array_sized_new (strlen (tmp_string)); + g_byte_array_append (array, (guint8 *) tmp_string, strlen (tmp_string)); + } + g_free (tmp_string); + } + + if (!array) { + /* Old format; list of ints */ + tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); + array = g_byte_array_sized_new (length); + for (i = 0; i < length; i++) { + int val = tmp_list[i]; + unsigned char v = (unsigned char) (val & 0xFF); + + if (val < 0 || val > 255) { + g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); + } else + g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); + } + g_free (tmp_list); + } + + if (array->len == 0) { + g_byte_array_free (array, TRUE); + array = NULL; + } + return array; +} + +static void +ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + GByteArray *array; + + array = get_uchar_array (keyfile, setting_name, key); + if (array) { + g_object_set (setting, key, array, NULL); + g_byte_array_free (array, TRUE); + } else { + g_warning ("%s: ignoring invalid SSID for %s / %s", + __func__, setting_name, key); + } +} + +static char * +get_cert_path (const char *keyfile_path, GByteArray *cert_path) +{ + const char *base; + char *p = NULL, *path, *dirname, *tmp; + + g_return_val_if_fail (keyfile_path != NULL, NULL); + g_return_val_if_fail (cert_path != NULL, NULL); + + base = path = g_malloc0 (cert_path->len + 1); + memcpy (path, cert_path->data, cert_path->len); + + if (path[0] == '/') + return path; + + p = strrchr (path, '/'); + if (p) + base = p + 1; + + dirname = g_path_get_dirname (keyfile_path); + tmp = g_build_path ("/", dirname, base, NULL); + g_free (dirname); + g_free (path); + return tmp; +} + +#define SCHEME_PATH "file://" + +static void +cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + GByteArray *array; + gboolean success = FALSE; + + array = get_uchar_array (keyfile, setting_name, key); + if (array) { + /* Value could be either: + * 1) the raw key/cert data as a blob + * 2) a path scheme (ie, starts with "file://") + * 3) a plain path + */ + if ( (array->len > strlen (SCHEME_PATH)) + && g_str_has_prefix ((const char *) array->data, SCHEME_PATH) + && (array->data[array->len - 1] == '\0')) { + /* It's the PATH scheme, can just set plain data */ + g_object_set (setting, key, array, NULL); + success = TRUE; + } else if ( (array->len < 500) + && g_utf8_validate ((const char *) array->data, array->len, NULL)) { + GByteArray *val; + char *path; + + path = get_cert_path (keyfile_path, array); + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + /* Construct the proper value as required for the PATH scheme */ + val = g_byte_array_sized_new (strlen (SCHEME_PATH) + array->len + 1); + g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (val, array->data, array->len); + g_byte_array_append (val, (const guint8 *) "\0", 1); + g_object_set (setting, key, val, NULL); + g_byte_array_free (val, TRUE); + success = TRUE; + } + g_free (path); + } + + if (!success) { + /* Assume it's a simple blob value of the certificate or private key's data */ + g_object_set (setting, key, array, NULL); + } + + g_byte_array_free (array, TRUE); + } else { + g_warning ("%s: ignoring invalid SSID for %s / %s", + __func__, setting_name, key); + } +} + +typedef struct { + const char *setting_name; + const char *key; + gboolean check_for_key; + void (*parser) (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path); +} KeyParser; + +/* A table of keys that require further parsing/conversion because they are + * stored in a format that can't be automatically read using the key's type. + * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are + * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored + * in struct in6_addr internally, but as string in keyfiles. + */ +static KeyParser key_parsers[] = { + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES, + FALSE, + ip4_addr_parser }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES, + FALSE, + ip6_addr_parser }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES, + FALSE, + ip4_route_parser }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES, + FALSE, + ip6_route_parser }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS, + FALSE, + ip4_dns_parser }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS, + FALSE, + ip6_dns_parser }, + { NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS, + TRUE, + mac_address_parser }, + { NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + TRUE, + mac_address_parser }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS, + TRUE, + mac_address_parser }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + TRUE, + mac_address_parser }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID, + TRUE, + mac_address_parser }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR, + TRUE, + mac_address_parser }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID, + TRUE, + ssid_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT, + TRUE, + cert_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT, + TRUE, + cert_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY, + TRUE, + cert_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CA_CERT, + TRUE, + cert_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + TRUE, + cert_parser }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + TRUE, + cert_parser }, + { NULL, NULL, FALSE } +}; + +typedef struct { + GKeyFile *keyfile; + const char *keyfile_path; +} ReadInfo; + +static void +read_one_setting_value (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + ReadInfo *info = user_data; + const char *setting_name; + GType type; + GError *err = NULL; + gboolean check_for_key = TRUE; + KeyParser *parser = &key_parsers[0]; + + /* Property is not writable */ + if (!(flags & G_PARAM_WRITABLE)) + return; + + /* Setting name gets picked up from the keyfile's section name instead */ + if (!strcmp (key, NM_SETTING_NAME)) + return; + + /* Don't read the NMSettingConnection object's 'read-only' property */ + if ( NM_IS_SETTING_CONNECTION (setting) + && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) + return; + + setting_name = nm_setting_get_name (setting); + + /* Look through the list of handlers for non-standard format key values */ + while (parser->setting_name) { + if (!strcmp (parser->setting_name, setting_name) && !strcmp (parser->key, key)) { + check_for_key = parser->check_for_key; + break; + } + parser++; + } + + /* VPN properties don't have the exact key name */ + if (NM_IS_SETTING_VPN (setting)) + check_for_key = FALSE; + + /* Check for the exact key in the GKeyFile if required. Most setting + * properties map 1:1 to a key in the GKeyFile, but for those properties + * like IP addresses and routes where more than one value is actually + * encoded by the setting property, this won't be true. + */ + if (check_for_key && !g_key_file_has_key (info->keyfile, setting_name, key, &err)) { + /* Key doesn't exist or an error ocurred, thus nothing to do. */ + if (err) { + g_warning ("Error loading setting '%s' value: %s", setting_name, err->message); + g_error_free (err); + } + return; + } + + /* If there's a custom parser for this key, handle that before the generic + * parsers below. + */ + if (parser && parser->setting_name) { + (*parser->parser) (setting, key, info->keyfile, info->keyfile_path); + return; + } + + type = G_VALUE_TYPE (value); + + if (type == G_TYPE_STRING) { + char *str_val; + + str_val = g_key_file_get_string (info->keyfile, setting_name, key, NULL); + g_object_set (setting, key, str_val, NULL); + g_free (str_val); + } else if (type == G_TYPE_UINT) { + int int_val; + + int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + if (int_val < 0) + g_warning ("Casting negative value (%i) to uint", int_val); + g_object_set (setting, key, int_val, NULL); + } else if (type == G_TYPE_INT) { + int int_val; + + int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + g_object_set (setting, key, int_val, NULL); + } else if (type == G_TYPE_BOOLEAN) { + gboolean bool_val; + + bool_val = g_key_file_get_boolean (info->keyfile, setting_name, key, NULL); + g_object_set (setting, key, bool_val, NULL); + } else if (type == G_TYPE_CHAR) { + int int_val; + + int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + if (int_val < G_MININT8 || int_val > G_MAXINT8) + g_warning ("Casting value (%i) to char", int_val); + + g_object_set (setting, key, int_val, NULL); + } else if (type == G_TYPE_UINT64) { + char *tmp_str; + guint64 uint_val; + + tmp_str = g_key_file_get_value (info->keyfile, setting_name, key, NULL); + uint_val = g_ascii_strtoull (tmp_str, NULL, 10); + g_free (tmp_str); + g_object_set (setting, key, uint_val, NULL); + } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { + gint *tmp; + GByteArray *array; + gsize length; + int i; + + tmp = g_key_file_get_integer_list (info->keyfile, setting_name, key, &length, NULL); + + array = g_byte_array_sized_new (length); + for (i = 0; i < length; i++) { + int val = tmp[i]; + unsigned char v = (unsigned char) (val & 0xFF); + + if (val < 0 || val > 255) { + g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); + } else + g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); + } + + g_object_set (setting, key, array, NULL); + g_byte_array_free (array, TRUE); + g_free (tmp); + } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { + gchar **sa; + gsize length; + int i; + GSList *list = NULL; + + sa = g_key_file_get_string_list (info->keyfile, setting_name, key, &length, NULL); + for (i = 0; i < length; i++) + list = g_slist_prepend (list, sa[i]); + + list = g_slist_reverse (list); + g_object_set (setting, key, list, NULL); + + g_slist_free (list); + g_strfreev (sa); + } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { + read_hash_of_string (info->keyfile, setting, key); + } else if (type == DBUS_TYPE_G_UINT_ARRAY) { + if (!read_array_of_uint (info->keyfile, setting, key)) { + g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", + setting_name, key, G_VALUE_TYPE_NAME (value)); + } + } else { + g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", + setting_name, key, G_VALUE_TYPE_NAME (value)); + } +} + +static NMSetting * +read_setting (GKeyFile *file, const char *keyfile_path, const char *setting_name) +{ + NMSetting *setting; + ReadInfo info = { file, keyfile_path }; + + setting = nm_connection_create_setting (setting_name); + if (setting) + nm_setting_enumerate_values (setting, read_one_setting_value, &info); + else + g_warning ("Invalid setting name '%s'", setting_name); + + return setting; +} + +static void +read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) +{ + char **keys, **iter; + + keys = g_key_file_get_keys (file, VPN_SECRETS_GROUP, NULL, NULL); + for (iter = keys; *iter; iter++) { + char *secret; + + secret = g_key_file_get_string (file, VPN_SECRETS_GROUP, *iter, NULL); + if (secret) { + nm_setting_vpn_add_secret (s_vpn, *iter, secret); + g_free (secret); + } + } + g_strfreev (keys); +} + +NMConnection * +nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) +{ + GKeyFile *key_file; + struct stat statbuf; + gboolean bad_owner, bad_permissions; + NMConnection *connection = NULL; + NMSettingConnection *s_con; + NMSetting *setting; + gchar **groups; + gsize length; + int i; + gboolean vpn_secrets = FALSE; + const char *ctype; + GError *verify_error = NULL; + + if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) { + g_set_error_literal (error, KEYFILE_PLUGIN_ERROR, 0, + "File did not exist or was not a regular file"); + return NULL; + } + + bad_owner = getuid () != statbuf.st_uid; + bad_permissions = statbuf.st_mode & 0077; + + if (bad_owner || bad_permissions) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "File permissions (%o) or owner (%d) were insecure", + statbuf.st_mode, statbuf.st_uid); + return NULL; + } + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) + goto out; + + connection = nm_connection_new (); + + groups = g_key_file_get_groups (key_file, &length); + for (i = 0; i < length; i++) { + /* Only read out secrets when needed */ + if (!strcmp (groups[i], VPN_SECRETS_GROUP)) { + vpn_secrets = TRUE; + continue; + } + + setting = read_setting (key_file, filename, groups[i]); + if (setting) + nm_connection_add_setting (connection, setting); + } + + /* Make sure that we have the base device type setting even if + * the keyfile didn't include it, which can happen when the base + * device type setting is all default values (like ethernet). + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (s_con) { + ctype = nm_setting_connection_get_connection_type (s_con); + setting = nm_connection_get_setting_by_name (connection, ctype); + if (ctype) { + if (!setting && !strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)) + nm_connection_add_setting (connection, nm_setting_wired_new ()); + } + } + + /* Handle vpn secrets after the 'vpn' setting was read */ + if (vpn_secrets) { + NMSettingVPN *s_vpn; + + s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + if (s_vpn) + read_vpn_secrets (key_file, s_vpn); + } + + g_strfreev (groups); + + /* Verify the connection */ + if (!nm_connection_verify (connection, &verify_error)) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "invalid or missing connection property '%s'", + (verify_error && verify_error->message) ? verify_error->message : "(unknown)"); + g_clear_error (&verify_error); + g_object_unref (connection); + connection = NULL; + } + +out: + g_key_file_free (key_file); + return connection; +} diff --git a/src/settings/plugins/keyfile/reader.h b/src/settings/plugins/keyfile/reader.h new file mode 100644 index 00000000..55819630 --- /dev/null +++ b/src/settings/plugins/keyfile/reader.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Red Hat, Inc. + */ + +#ifndef _KEYFILE_PLUGIN_READER_H +#define _KEYFILE_PLUGIN_READER_H + +#include <glib.h> +#include <nm-connection.h> + +NMConnection *nm_keyfile_plugin_connection_from_file (const char *filename, GError **error); + +#endif /* _KEYFILE_PLUGIN_READER_H */ diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am new file mode 100644 index 00000000..affe8dca --- /dev/null +++ b/src/settings/plugins/keyfile/tests/Makefile.am @@ -0,0 +1,32 @@ +SUBDIRS=keyfiles + +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +noinst_PROGRAMS = test-keyfile + +test_keyfile_SOURCES = \ + test-keyfile.c + +test_keyfile_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" + +test_keyfile_LDADD = \ + $(builddir)/../libkeyfile-io.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) + +if WITH_TESTS + +check-local: test-keyfile + $(abs_builddir)/test-keyfile + +endif + diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in new file mode 100644 index 00000000..733b4916 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -0,0 +1,782 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-keyfile$(EXEEXT) +subdir = src/settings/plugins/keyfile/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_keyfile_OBJECTS = test_keyfile-test-keyfile.$(OBJEXT) +test_keyfile_OBJECTS = $(am_test_keyfile_OBJECTS) +am__DEPENDENCIES_1 = +test_keyfile_DEPENDENCIES = $(builddir)/../libkeyfile-io.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(test_keyfile_SOURCES) +DIST_SOURCES = $(test_keyfile_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = keyfiles +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib \ + -I$(srcdir)/../ + +test_keyfile_SOURCES = \ + test-keyfile.c + +test_keyfile_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" + +test_keyfile_LDADD = \ + $(builddir)/../libkeyfile-io.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_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 +test-keyfile$(EXEEXT): $(test_keyfile_OBJECTS) $(test_keyfile_DEPENDENCIES) + @rm -f test-keyfile$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_keyfile_OBJECTS) $(test_keyfile_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_keyfile-test-keyfile.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_keyfile-test-keyfile.o: test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_keyfile-test-keyfile.o -MD -MP -MF $(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o test_keyfile-test-keyfile.o `test -f 'test-keyfile.c' || echo '$(srcdir)/'`test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_keyfile-test-keyfile.Tpo $(DEPDIR)/test_keyfile-test-keyfile.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-keyfile.c' object='test_keyfile-test-keyfile.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_keyfile-test-keyfile.o `test -f 'test-keyfile.c' || echo '$(srcdir)/'`test-keyfile.c + +test_keyfile-test-keyfile.obj: test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_keyfile-test-keyfile.obj -MD -MP -MF $(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o test_keyfile-test-keyfile.obj `if test -f 'test-keyfile.c'; then $(CYGPATH_W) 'test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/test-keyfile.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_keyfile-test-keyfile.Tpo $(DEPDIR)/test_keyfile-test-keyfile.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-keyfile.c' object='test_keyfile-test-keyfile.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_keyfile-test-keyfile.obj `if test -f 'test-keyfile.c'; then $(CYGPATH_W) 'test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/test-keyfile.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +@WITH_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am check-local clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags ctags-recursive \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am + + +@WITH_TESTS_TRUE@check-local: test-keyfile +@WITH_TESTS_TRUE@ $(abs_builddir)/test-keyfile + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT new file mode 100644 index 00000000..cc8a9ee3 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT @@ -0,0 +1,23 @@ + +[connection] +id=AT&T Data Connect BT +uuid=089130ab-ce28-46e4-ad77-d44869b03d19 +type=bluetooth +autoconnect=false + +[ipv4] +method=auto + +[gsm] +number=*99# +username=ISP@CINGULARGPRS.COM +password=CINGULAR1 +apn=ISP.CINGULAR + +[serial] +baud=115200 + +[bluetooth] +bdaddr=00:11:22:33:44:55 +type=dun + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain new file mode 100644 index 00000000..236cca0e --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain @@ -0,0 +1,20 @@ + +[connection] +id=AT&T Data Connect +uuid=15d742f1-2b5a-421e-9f27-fcb1fc26d72c +type=gsm +autoconnect=false + +[ipv4] +method=auto + +[gsm] +number=*99# +username=ISP@CINGULARGPRS.COM +password=CINGULAR1 +apn=ISP.CINGULAR +network-id=24005 +pin=2345 + +[serial] +baud=115200 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am new file mode 100644 index 00000000..0ce03209 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am @@ -0,0 +1,23 @@ +KEYFILES = \ + Test_Wired_Connection \ + Test_GSM_Connection \ + Test_Wireless_Connection \ + Test_Wired_Connection_MAC_Case \ + Test_Wired_Connection_IP6 \ + ATT_Data_Connect_BT \ + ATT_Data_Connect_Plain \ + Test_String_SSID \ + Test_Wired_TLS_Old \ + Test_Wired_TLS_New + +CERTS = \ + test-ca-cert.pem \ + test-key-and-cert.pem + +EXTRA_DIST = $(KEYFILES) $(CERTS) + +check-local: + @for f in $(KEYFILES); do \ + chmod 0600 $(abs_srcdir)/$$f; \ + done + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in new file mode 100644 index 00000000..0b0b3551 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -0,0 +1,475 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/keyfile/tests/keyfiles +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +KEYFILES = \ + Test_Wired_Connection \ + Test_GSM_Connection \ + Test_Wireless_Connection \ + Test_Wired_Connection_MAC_Case \ + Test_Wired_Connection_IP6 \ + ATT_Data_Connect_BT \ + ATT_Data_Connect_Plain \ + Test_String_SSID \ + Test_Wired_TLS_Old \ + Test_Wired_TLS_New + +CERTS = \ + test-ca-cert.pem \ + test-key-and-cert.pem + +EXTRA_DIST = $(KEYFILES) $(CERTS) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-am check-local clean clean-generic \ + clean-libtool distclean distclean-generic distclean-libtool \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am + + +check-local: + @for f in $(KEYFILES); do \ + chmod 0600 $(abs_srcdir)/$$f; \ + done + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection new file mode 100644 index 00000000..3d58fee0 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection @@ -0,0 +1,41 @@ + +[serial] +baud=115200 +bits=8 +parity=110 +stopbits=1 +send-delay=0 + +[connection] +id=Test GSM Connection +uuid=05a5ec81-fa72-4b7c-9f85-4a0dfd36c84f +type=gsm +autoconnect=false +timestamp=0 + +[gsm] +number=*99# +username=username +apn=my.apn +network-type=0 +band=0 + +[ppp] +noauth=false +refuse-eap=false +refuse-pap=false +refuse-chap=false +refuse-mschap=false +refuse-mschapv2=false +nobsdcomp=false +nodeflate=false +no-vj-comp=false +require-mppe=false +require-mppe-128=false +mppe-stateful=false +crtscts=false +baud=0 +mru=0 +mtu=0 +lcp-echo-failure=5 +lcp-echo-interval=30 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID b/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID new file mode 100644 index 00000000..4a3b56d2 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID @@ -0,0 +1,11 @@ +[connection] +id=Test +uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa +type=802-11-wireless + +[802-11-wireless] +ssid=blah blah ssid 1234 + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection new file mode 100644 index 00000000..5785dc24 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection @@ -0,0 +1,32 @@ + +[connection] +id=Test Wired Connection +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=802-3-ethernet +autoconnect=true +timestamp=6654332 + +[802-3-ethernet] +mac-address=00:11:22:33:44:55 +speed=0 +duplex=full +auto-negotiate=true +mtu=1400 + +[ipv4] +method=manual +dns=4.2.2.1;4.2.2.2; +addresses1=192.168.0.5;24;192.168.0.1; +addresses2=1.2.3.4;16;1.2.1.1; +ignore-auto-routes=false +ignore-auto-dns=false + +[ipv6] +method=manual +dns=1111:dddd::aaaa;1::cafe; +dns-search=super-domain.com;redhat.com;gnu.org; +addresses1=abcd:1234:ffff::cdde/64 +addresses2=1:2:3:4:5:6:7:8/96 +routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99; +ignore-auto-routes=false +ignore-auto-dns=false diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6 b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6 new file mode 100644 index 00000000..a42dd5d2 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6 @@ -0,0 +1,20 @@ + +[connection] +id=Test Wired Connection IP6 +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=802-3-ethernet +autoconnect=true +timestamp=6654332 + +[802-3-ethernet] +auto-negotiate=true +mtu=1400 + +[ipv4] +method=disabled + +[ipv6] +method=manual +addresses1=abcd:1234:ffff::cdde/64,abcd:1234:ffff::cdd1 +dns=1111:dddd::aaaa;1::cafe; + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case new file mode 100644 index 00000000..29aef494 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case @@ -0,0 +1,32 @@ + +[connection] +id=Test Wired Connection MAC Case +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=802-3-ethernet +autoconnect=true +timestamp=6654332 + +[802-3-ethernet] +mac-address=00:11:aa:BB:CC:55 +speed=0 +duplex=full +auto-negotiate=true +mtu=1400 + +[ipv4] +method=manual +dns=4.2.2.1;4.2.2.2; +addresses1=192.168.0.5;24;192.168.0.1; +addresses2=1.2.3.4;16;1.2.1.1; +ignore-auto-routes=false +ignore-auto-dns=false + +[ipv6] +method=manual +dns=1111:dddd::aaaa;1::cafe; +dns-search=super-domain.com;redhat.com;gnu.org; +addresses1=abcd:1234:ffff::cdde/64 +addresses2=1:2:3:4:5:6:7:8/96 +routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99; +ignore-auto-routes=false +ignore-auto-dns=false diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New new file mode 100644 index 00000000..4cd86686 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New @@ -0,0 +1,22 @@ + +[connection] +id=Wired TLS +uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488 +type=802-3-ethernet + +[802-1x] +eap=tls; +identity=Bill Smith +ca-cert=test-ca-cert.pem +client-cert=test-key-and-cert.pem +private-key=test-key-and-cert.pem +private-key-password=12345testing + +[ipv4] +method=auto + +[802-3-ethernet] +duplex=full + +[ipv6] +method=ignore diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old new file mode 100644 index 00000000..61afdd91 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old @@ -0,0 +1,22 @@ + +[connection] +id=Wired TLS +uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488 +type=802-3-ethernet + +[802-1x] +eap=tls; +identity=Bill Smith +ca-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;67;65;47;101;97;112;116;101;115;116;95;99;97;95;99;101;114;116;46;112;101;109;0; +client-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +private-key=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +private-key-password=12345testing + +[ipv4] +method=auto + +[802-3-ethernet] +duplex=full + +[ipv6] +method=ignore diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection new file mode 100644 index 00000000..b1949d0d --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection @@ -0,0 +1,22 @@ +[connection] +id=Test Wireless Connection +uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa +type=802-11-wireless +autoconnect=false +timestamp=1226604314 + +[802-11-wireless] +ssid=110;109;45;116;101;115;116;45;97;112; +mode=infrastructure +channel=0 +rate=0 +tx-power=0 +mtu=0 +bssid=00:1a:33:44:99:82 + +[ipv4] +method=auto +ignore-auto-routes=false +ignore-auto-dns=false +never-default=false + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem b/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem new file mode 100644 index 00000000..ef1be20d --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE +AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx +NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ +QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55 +IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3 +DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU +xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc +Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3 +FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4 +HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm +J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P +T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF +ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL +EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl +c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc +JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT +p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t +qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn +B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp +3nniskIjbH0xjgZf/nVMyLnjxg== +-----END CERTIFICATE----- diff --git a/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem b/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem new file mode 100644 index 00000000..dec9aa1b --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem @@ -0,0 +1,118 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4DE0615F23D82107 + +QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz +L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7 +zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU +h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW +ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv +QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na +eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo +cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m +RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8 +xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr +T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI +ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo +RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ +EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt +lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5 +r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4 +aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W +GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e +DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE +lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO +8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3 +VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt +G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ +tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW +QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1 +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com + Validity + Not Before: Mar 10 15:13:16 2009 GMT + Not After : Mar 8 15:13:16 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a: + 82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48: + ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49: + c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8: + 03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14: + ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9: + c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c: + 60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d: + 44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b: + f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d: + c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75: + d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2: + 06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38: + ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba: + ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36: + 2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11: + a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f: + a3:43 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C + X509v3 Authority Key Identifier: + keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10 + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com + serial:EB:E7:64:FB:79:F7:22:19 + + Signature Algorithm: md5WithRSAEncryption + 7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82: + f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89: + b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b: + 12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76: + 1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48: + 32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02: + 85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1: + fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c: + cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43: + 8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71: + 1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19: + 07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69: + 7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62: + 8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7: + 3b:65:fe:f9 +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx +HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN +MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl +MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG +A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR +XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA +vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9 +jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF +TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX +gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj +ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy +YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww +gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ +BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx +FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD +VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3 +IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/ +DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2 +8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr +vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD +T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa +PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk= +-----END CERTIFICATE----- diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c new file mode 100644 index 00000000..bfe5aa43 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -0,0 +1,2353 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <netinet/ether.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#include <nm-utils.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-bluetooth.h> +#include <nm-setting-serial.h> +#include <nm-setting-ppp.h> +#include <nm-setting-gsm.h> +#include <nm-setting-8021x.h> + +#include "nm-test-helpers.h" + +#include "reader.h" +#include "writer.h" + +#define TEST_WIRED_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection" +#define TEST_WIRELESS_FILE TEST_KEYFILES_DIR"/Test_Wireless_Connection" + +static void +test_read_valid_wired_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + GError *error = NULL; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + const char *tmp; + const char *expected_id = "Test Wired Connection"; + const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; + const guint64 expected_timestamp = 6654332; + guint64 timestamp; + const char *expected_dns1 = "4.2.2.1"; + const char *expected_dns2 = "4.2.2.2"; + struct in_addr addr; + const char *expected_address1 = "192.168.0.5"; + const char *expected_address2 = "1.2.3.4"; + const char *expected_address1_gw = "192.168.0.1"; + const char *expected_address2_gw = "1.2.1.1"; + NMIP4Address *ip4_addr; + const char *expected6_dns1 = "1111:dddd::aaaa"; + const char *expected6_dns2 = "1::cafe"; + const char *expected6_dnssearch1 = "super-domain.com"; + const char *expected6_dnssearch2 = "redhat.com"; + const char *expected6_dnssearch3 = "gnu.org"; + struct in6_addr addr6; + const char *expected6_address1 = "abcd:1234:ffff::cdde"; + const char *expected6_address2 = "1:2:3:4:5:6:7:8"; + const char *expected6_route_dest = "a:b:c:d::"; + const char *expected6_route_nh = "f:e:d:c:1:2:3:4"; + NMIP6Address *ip6_addr; + NMIP6Route *ip6_route; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_WIRED_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_WIRED_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID */ + tmp = nm_setting_connection_get_uuid (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + ASSERT (strcmp (tmp, expected_uuid) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + + /* Timestamp */ + timestamp = nm_setting_connection_get_timestamp (s_con); + ASSERT (timestamp == expected_timestamp, + "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, + "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_WIRED_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "connection-verify-wired", "failed to verify %s: missing %s setting", + TEST_WIRED_FILE, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "connection-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_WIRED_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_WIRED_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + ASSERT (nm_setting_wired_get_mtu (s_wired) == 1400, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MTU); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "connection-verify-ip4", "failed to verify %s: missing %s setting", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + /* DNS Addresses */ + ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #1", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 2, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* Address #1 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + ASSERT (ip4_addr, + "connection-verify-wired", "failed to verify %s: missing IP4 address #1", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1 prefix", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1 gateway", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1 gateway", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + /* Address #2 */ + ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 1); + ASSERT (ip4_addr, + "connection-verify-wired", "failed to verify %s: missing IP4 address #2", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 16, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2 prefix", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address2, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET, expected_address2_gw, &addr) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2 gateway", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2 gateway", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "connection-verify-ip6", "failed to verify %s: missing %s setting", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + /* DNS Addresses */ + ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected6_dns1, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP6 address #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (inet_pton (AF_INET6, expected6_dns2, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 2, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + /* DNS Searches */ + ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 3, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 0), expected6_dnssearch1), + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 1), expected6_dnssearch2), + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 2), expected6_dnssearch3), + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #3", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + + /* Address #1 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + "connection-verify-wired", "failed to verify %s: missing IP6 address #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64, + "connection-verify-wired", "failed to verify %s: unexpected IP6 address #1 prefix", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* Address #2 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); + ASSERT (ip6_addr, + "connection-verify-wired", "failed to verify %s: missing IP6 address #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 96, + "connection-verify-wired", "failed to verify %s: unexpected IP6 address #2 prefix", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET6, expected6_address2, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP6 address #2", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + /* Route #1 */ + ip6_route = nm_setting_ip6_config_get_route (s_ip6, 0); + ASSERT (ip6_route, + "connection-verify-wired", "failed to verify %s: missing IP6 route #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + ASSERT (inet_pton (AF_INET6, expected6_route_dest, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP route dest #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_dest (ip6_route), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP4 route dest #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + ASSERT (nm_ip6_route_get_prefix (ip6_route) == 64, + "connection-verify-wired", "failed to verify %s: unexpected IP6 route #1 prefix", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + ASSERT (inet_pton (AF_INET6, expected6_route_nh, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP route next hop #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_next_hop (ip6_route), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP4 route dest #1", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + ASSERT (nm_ip6_route_get_metric (ip6_route) == 99, + "connection-verify-wired", "failed to verify %s: unexpected IP6 route #1 metric", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES); + + g_object_unref (connection); +} + +static void +add_one_ip4_address (NMSettingIP4Config *s_ip4, + const char *addr, + const char *gw, + guint32 prefix) +{ + struct in_addr tmp; + NMIP4Address *ip4_addr; + + ip4_addr = nm_ip4_address_new (); + nm_ip4_address_set_prefix (ip4_addr, prefix); + + inet_pton (AF_INET, addr, &tmp); + nm_ip4_address_set_address (ip4_addr, tmp.s_addr); + + inet_pton (AF_INET, gw, &tmp); + nm_ip4_address_set_gateway (ip4_addr, tmp.s_addr); + + nm_setting_ip4_config_add_address (s_ip4, ip4_addr); + nm_ip4_address_unref (ip4_addr); +} + +static void +add_one_ip4_route (NMSettingIP4Config *s_ip4, + const char *dest, + const char *nh, + guint32 prefix, + guint32 metric) +{ + struct in_addr addr; + NMIP4Route *route; + + route = nm_ip4_route_new (); + nm_ip4_route_set_prefix (route, prefix); + nm_ip4_route_set_metric (route, metric); + + inet_pton (AF_INET, dest, &addr); + nm_ip4_route_set_dest (route, addr.s_addr); + + inet_pton (AF_INET, nh, &addr); + nm_ip4_route_set_next_hop (route, addr.s_addr); + + nm_setting_ip4_config_add_route (s_ip4, route); + nm_ip4_route_unref (route); +} + +static void +add_one_ip6_address (NMSettingIP6Config *s_ip6, + const char *addr, + guint32 prefix, + const char *gw) +{ + struct in6_addr tmp; + NMIP6Address *ip6_addr; + + ip6_addr = nm_ip6_address_new (); + nm_ip6_address_set_prefix (ip6_addr, prefix); + + inet_pton (AF_INET6, addr, &tmp); + nm_ip6_address_set_address (ip6_addr, &tmp); + + if (gw) { + inet_pton (AF_INET6, gw, &tmp); + nm_ip6_address_set_gateway (ip6_addr, &tmp); + } + + nm_setting_ip6_config_add_address (s_ip6, ip6_addr); + nm_ip6_address_unref (ip6_addr); +} + +static void +add_one_ip6_route (NMSettingIP6Config *s_ip6, + const char *dest, + const char *nh, + guint32 prefix, + guint32 metric) +{ + struct in6_addr addr; + NMIP6Route *route; + + route = nm_ip6_route_new (); + nm_ip6_route_set_prefix (route, prefix); + nm_ip6_route_set_metric (route, metric); + + inet_pton (AF_INET6, dest, &addr); + nm_ip6_route_set_dest (route, &addr); + + inet_pton (AF_INET6, nh, &addr); + nm_ip6_route_set_next_hop (route, &addr); + + nm_setting_ip6_config_add_route (s_ip6, route); + nm_ip6_route_unref (route); +} + + +static void +test_write_wired_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + GByteArray *mac; + unsigned char tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44 }; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + struct in_addr addr; + struct in6_addr addr6; + const char *dns1 = "4.2.2.1"; + const char *dns2 = "4.2.2.2"; + const char *address1 = "192.168.0.5"; + const char *address1_gw = "192.168.0.1"; + const char *address2 = "1.2.3.4"; + const char *address2_gw = "1.2.1.1"; + const char *route1 = "10.10.10.2"; + const char *route1_nh = "10.10.10.1"; + const char *route2 = "1.1.1.1"; + const char *route2_nh = "1.2.1.1"; + const char *dns6_1 = "1::cafe"; + const char *dns6_2 = "2::cafe"; + const char *address6_1 = "abcd::beef"; + const char *address6_2 = "dcba::beef"; + const char *route6_1 = "1:2:3:4:5:6:7:8"; + const char *route6_1_nh = "8:7:6:5:4:3:2:1"; + const char *route6_2 = "2001::1000"; + const char *route6_2_nh = "2001::1111"; + guint64 timestamp = 0x12345678L; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Work Wired", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + + /* Wired setting */ + + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + ASSERT (s_wired != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, mac, + NM_SETTING_WIRED_MTU, 900, + NULL); + g_byte_array_free (mac, TRUE); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* Addresses */ + add_one_ip4_address (s_ip4, address1, address1_gw, 24); + add_one_ip4_address (s_ip4, address2, address2_gw, 8); + + /* Routes */ + add_one_ip4_route (s_ip4, route1, route1_nh, 24, 3); + add_one_ip4_route (s_ip4, route2, route2_nh, 8, 1); + + /* DNS servers */ + inet_pton (AF_INET, dns1, &addr); + nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr); + inet_pton (AF_INET, dns2, &addr); + nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr); + + /* IP6 setting */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + ASSERT (s_ip6 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL); + + /* Addresses */ + add_one_ip6_address (s_ip6, address6_1, 64, NULL); + add_one_ip6_address (s_ip6, address6_2, 56, NULL); + + /* Routes */ + add_one_ip6_route (s_ip6, route6_1, route6_1_nh, 64, 3); + add_one_ip6_route (s_ip6, route6_2, route6_2_nh, 56, 1); + + /* DNS servers */ + inet_pton (AF_INET6, dns6_1, &addr6); + nm_setting_ip6_config_add_dns (s_ip6, &addr6); + inet_pton (AF_INET6, dns6_2, &addr6); + nm_setting_ip6_config_add_dns (s_ip6, &addr6); + + /* DNS searches */ + nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com"); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_WIRED_IP6_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_IP6" + +static void +test_read_ip6_wired_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + GError *error = NULL; + const char *tmp; + const char *expected_id = "Test Wired Connection IP6"; + const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; + struct in6_addr addr6; + const char *expected6_address1 = "abcd:1234:ffff::cdde"; + const char *expected6_gw1 = "abcd:1234:ffff::cdd1"; + NMIP6Address *ip6_addr; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_IP6_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_WIRED_IP6_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_WIRED_IP6_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_WIRED_IP6_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_IP6_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID */ + tmp = nm_setting_connection_get_uuid (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_IP6_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + ASSERT (strcmp (tmp, expected_uuid) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "connection-verify-wired", "failed to verify %s: missing %s setting", + TEST_WIRED_IP6_FILE, + NM_SETTING_WIRED_SETTING_NAME); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "connection-verify-ip4", "failed to verify %s: missing %s setting", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG)); + ASSERT (s_ip6 != NULL, + "connection-verify-ip6", "failed to verify %s: missing %s setting", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip6_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_METHOD); + + ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS); + + /* Address #1 */ + ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ASSERT (ip6_addr, + "connection-verify-wired", "failed to verify %s: missing IP6 address #1", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64, + "connection-verify-wired", "failed to verify %s: unexpected IP6 address #1 prefix", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + ASSERT (inet_pton (AF_INET6, expected6_gw1, &addr6) > 0, + "connection-verify-wired", "failed to verify %s: couldn't convert GW address #1", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_gateway (ip6_addr), &addr6), + "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES); + + g_object_unref (connection); +} + +static void +test_write_ip6_wired_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + struct in6_addr addr6; + const char *dns = "1::cafe"; + const char *address = "abcd::beef"; + const char *gw = "dcba::beef"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Work Wired IP6", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + ASSERT (s_wired != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + + /* IP6 setting */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + ASSERT (s_ip6 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL); + + /* Addresses */ + add_one_ip6_address (s_ip6, address, 64, gw); + + /* DNS servers */ + inet_pton (AF_INET6, dns, &addr6); + nm_setting_ip6_config_add_dns (s_ip6, &addr6); + + /* DNS searches */ + nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com"); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_WIRED_MAC_CASE_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_MAC_Case" + +static void +test_read_wired_mac_case (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + GError *error = NULL; + const GByteArray *array; + char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; + const char *tmp; + const char *expected_id = "Test Wired Connection MAC Case"; + const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_WIRED_MAC_CASE_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_WIRED_MAC_CASE_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID */ + tmp = nm_setting_connection_get_uuid (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + ASSERT (strcmp (tmp, expected_uuid) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "connection-verify-wired", "failed to verify %s: missing %s setting", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array != NULL, + "connection-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (array->len == ETH_ALEN, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_MAC_CASE_FILE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + g_object_unref (connection); +} + +static void +test_read_valid_wireless_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + GError *error = NULL; + const GByteArray *array; + char expected_bssid[ETH_ALEN] = { 0x00, 0x1a, 0x33, 0x44, 0x99, 0x82 }; + const char *tmp; + const char *expected_id = "Test Wireless Connection"; + const char *expected_uuid = "2f962388-e5f3-45af-a62c-ac220b8f7baa"; + const guint64 expected_timestamp = 1226604314; + guint64 timestamp; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRELESS_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_WIRELESS_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_WIRELESS_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID */ + tmp = nm_setting_connection_get_uuid (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + ASSERT (strcmp (tmp, expected_uuid) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + + /* Timestamp */ + timestamp = nm_setting_connection_get_timestamp (s_con); + ASSERT (timestamp == expected_timestamp, + "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP); + + /* Autoconnect */ + ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE, + "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT); + + /* ===== WIRED SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "connection-verify-wireless", "failed to verify %s: missing %s setting", + TEST_WIRELESS_FILE, + NM_SETTING_WIRED_SETTING_NAME); + + /* BSSID */ + array = nm_setting_wireless_get_bssid (s_wireless); + ASSERT (array != NULL, + "connection-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_WIRELESS_FILE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + ASSERT (array->len == ETH_ALEN, + "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", + TEST_WIRELESS_FILE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + ASSERT (memcmp (array->data, &expected_bssid[0], sizeof (expected_bssid)) == 0, + "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRELESS_FILE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "connection-verify-ip4", "failed to verify %s: missing %s setting", + TEST_WIRELESS_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, + "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRELESS_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + +static void +test_write_wireless_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + GByteArray *bssid; + unsigned char tmpbssid[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 }; + GByteArray *ssid; + unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + guint64 timestamp = 0x12344433L; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Work Wireless", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + + /* Wireless setting */ + + s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + ASSERT (s_wireless != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wireless)); + + bssid = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bssid, &tmpbssid[0], sizeof (tmpbssid)); + + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + + g_object_set (s_wireless, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRED_MTU, 1000, + NULL); + + g_byte_array_free (bssid, TRUE); + g_byte_array_free (ssid, TRUE); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + ASSERT (s_ip6 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_STRING_SSID_FILE TEST_KEYFILES_DIR"/Test_String_SSID" + +static void +test_read_string_ssid (void) +{ + NMConnection *connection; + NMSettingWireless *s_wireless; + GError *error = NULL; + const GByteArray *array; + const char *expected_ssid = "blah blah ssid 1234"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_STRING_SSID_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_STRING_SSID_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_STRING_SSID_FILE, error->message); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "connection-verify-wireless", "failed to verify %s: missing %s setting", + TEST_STRING_SSID_FILE, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* SSID */ + array = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (array != NULL, + "connection-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_STRING_SSID_FILE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + ASSERT (memcmp (array->data, expected_ssid, sizeof (expected_ssid)) == 0, + "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_STRING_SSID_FILE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + + g_object_unref (connection); +} + +static void +test_write_string_ssid (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingIP4Config *s_ip4; + char *uuid, *testfile = NULL, *tmp; + GByteArray *ssid; + unsigned char tmpssid[] = { 65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93 }; + gboolean success; + NMConnection *reread; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + GKeyFile *keyfile; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "String SSID Test", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wireless setting */ + + s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + ASSERT (s_wireless != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wireless)); + + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_byte_array_free (ssid, TRUE); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Ensure the SSID was written out as a string */ + keyfile = g_key_file_new (); + ASSERT (g_key_file_load_from_file (keyfile, testfile, 0, NULL) == TRUE, + "string-ssid-verify", "failed to load keyfile to verify"); + tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, NULL); + ASSERT (tmp, "string-ssid-verify", "failed to load 'ssid' key from file"); + ASSERT (strlen (tmp) == sizeof (tmpssid), + "string-ssid-verify", "reread SSID and expected were different sizes"); + ASSERT (memcmp (tmp, tmpssid, sizeof (tmpssid)) == 0, + "string-ssid-verify", "reread SSID and expected were different"); + g_free (tmp); + g_key_file_free (keyfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_BT_DUN_FILE TEST_KEYFILES_DIR"/ATT_Data_Connect_BT" + +static void +test_read_bt_dun_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingBluetooth *s_bluetooth; + NMSettingSerial *s_serial; + NMSettingGsm *s_gsm; + GError *error = NULL; + const GByteArray *array; + char expected_bdaddr[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + const char *tmp; + const char *expected_id = "AT&T Data Connect BT"; + const char *expected_uuid = "089130ab-ce28-46e4-ad77-d44869b03d19"; + const char *expected_apn = "ISP.CINGULAR"; + const char *expected_username = "ISP@CINGULARGPRS.COM"; + const char *expected_password = "CINGULAR1"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_BT_DUN_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_BT_DUN_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_BT_DUN_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_BT_DUN_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID */ + tmp = nm_setting_connection_get_uuid (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + ASSERT (strcmp (tmp, expected_uuid) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRELESS_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + + /* ===== BLUETOOTH SETTING ===== */ + + s_bluetooth = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH)); + ASSERT (s_bluetooth != NULL, + "connection-verify-bt", "failed to verify %s: missing %s setting", + TEST_WIRELESS_FILE, + NM_SETTING_WIRED_SETTING_NAME); + + /* BDADDR */ + array = nm_setting_bluetooth_get_bdaddr (s_bluetooth); + ASSERT (array != NULL, + "connection-verify-bt", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + ASSERT (array->len == ETH_ALEN, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value length", + TEST_BT_DUN_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + ASSERT (memcmp (array->data, &expected_bdaddr[0], sizeof (expected_bdaddr)) == 0, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + + /* Type */ + tmp = nm_setting_bluetooth_get_connection_type (s_bluetooth); + ASSERT (tmp != NULL, + "connection-verify-bt", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + ASSERT (strcmp (tmp, NM_SETTING_BLUETOOTH_TYPE_DUN) == 0, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + + /* ===== GSM SETTING ===== */ + + s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + ASSERT (s_gsm != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s setting", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME); + + /* APN */ + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_APN); + ASSERT (strcmp (tmp, expected_apn) == 0, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_APN); + + /* Username */ + tmp = nm_setting_gsm_get_username (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_USERNAME); + ASSERT (strcmp (tmp, expected_username) == 0, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_USERNAME); + + /* Password */ + tmp = nm_setting_gsm_get_password (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD); + ASSERT (strcmp (tmp, expected_password) == 0, + "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD); + + /* ===== SERIAL SETTING ===== */ + + s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL)); + ASSERT (s_serial != NULL, + "connection-verify-serial", "failed to verify %s: missing %s setting", + TEST_BT_DUN_FILE, + NM_SETTING_SERIAL_SETTING_NAME); + + g_object_unref (connection); +} + +static void +test_write_bt_dun_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingBluetooth *s_bt; + NMSettingIP4Config *s_ip4; + NMSettingGsm *s_gsm; + char *uuid; + GByteArray *bdaddr; + unsigned char tmpbdaddr[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 }; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + guint64 timestamp = 0x12344433L; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + + /* Bluetooth setting */ + + s_bt = NM_SETTING_BLUETOOTH (nm_setting_bluetooth_new ()); + ASSERT (s_bt != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_BLUETOOTH_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_bt)); + + bdaddr = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bdaddr, &tmpbdaddr[0], sizeof (tmpbdaddr)); + + g_object_set (s_bt, + NM_SETTING_BLUETOOTH_BDADDR, bdaddr, + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN, + NULL); + + g_byte_array_free (bdaddr, TRUE); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* GSM setting */ + s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); + ASSERT (s_gsm != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_GSM_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + + g_object_set (s_gsm, + NM_SETTING_GSM_APN, "internet2.voicestream.com", + NM_SETTING_GSM_USERNAME, "george.clinton", + NM_SETTING_GSM_PASSWORD, "parliament", + NM_SETTING_GSM_NUMBER, "*99#", + NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_GSM_FILE TEST_KEYFILES_DIR"/ATT_Data_Connect_Plain" + +static void +test_read_gsm_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingSerial *s_serial; + NMSettingGsm *s_gsm; + NMSetting *s_bluetooth; + GError *error = NULL; + const char *tmp; + const char *expected_id = "AT&T Data Connect"; + const char *expected_apn = "ISP.CINGULAR"; + const char *expected_username = "ISP@CINGULARGPRS.COM"; + const char *expected_password = "CINGULAR1"; + const char *expected_network_id = "24005"; + const char *expected_pin = "2345"; + + connection = nm_keyfile_plugin_connection_from_file (TEST_GSM_FILE, NULL); + ASSERT (connection != NULL, + "connection-read", "failed to read %s", TEST_GSM_FILE); + + ASSERT (nm_connection_verify (connection, &error), + "connection-verify", "failed to verify %s: %s", TEST_GSM_FILE, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "connection-verify-connection", "failed to verify %s: missing %s setting", + TEST_GSM_FILE, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + tmp = nm_setting_connection_get_connection_type (s_con); + ASSERT (tmp != NULL, + "connection-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, NM_SETTING_GSM_SETTING_NAME) == 0, + "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + + /* ===== BLUETOOTH SETTING ===== */ + + /* Plain GSM, so no BT setting expected */ + s_bluetooth = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + ASSERT (s_bluetooth == NULL, + "connection-verify-bt", "unexpected %s setting", + TEST_GSM_FILE, + NM_SETTING_BLUETOOTH_SETTING_NAME); + + /* ===== GSM SETTING ===== */ + + s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)); + ASSERT (s_gsm != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s setting", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME); + + /* APN */ + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_APN); + ASSERT (strcmp (tmp, expected_apn) == 0, + "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_APN); + + /* Username */ + tmp = nm_setting_gsm_get_username (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_USERNAME); + ASSERT (strcmp (tmp, expected_username) == 0, + "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_USERNAME); + + /* Password */ + tmp = nm_setting_gsm_get_password (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD); + ASSERT (strcmp (tmp, expected_password) == 0, + "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD); + + /* Network ID */ + tmp = nm_setting_gsm_get_network_id (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_NETWORK_ID); + ASSERT (strcmp (tmp, expected_network_id) == 0, + "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_NETWORK_ID); + + /* PIN */ + tmp = nm_setting_gsm_get_pin (s_gsm); + ASSERT (tmp != NULL, + "connection-verify-gsm", "failed to verify %s: missing %s / %s key", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PIN); + ASSERT (strcmp (tmp, expected_pin) == 0, + "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PIN); + + /* ===== SERIAL SETTING ===== */ + + s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL)); + ASSERT (s_serial != NULL, + "connection-verify-serial", "failed to verify %s: missing %s setting", + TEST_GSM_FILE, + NM_SETTING_SERIAL_SETTING_NAME); + + g_object_unref (connection); +} + +static void +test_write_gsm_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingGsm *s_gsm; + char *uuid; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + guint64 timestamp = 0x12344433L; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "connection-write", "failed to allocate new connection"); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + ASSERT (s_con != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic 2", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + ASSERT (s_ip4 != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* GSM setting */ + s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); + ASSERT (s_gsm != NULL, + "connection-write", "failed to allocate new %s setting", + NM_SETTING_GSM_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + + g_object_set (s_gsm, + NM_SETTING_GSM_APN, "internet2.voicestream.com", + NM_SETTING_GSM_USERNAME, "george.clinton.again", + NM_SETTING_GSM_PASSWORD, "parliament2", + NM_SETTING_GSM_NUMBER, "*99#", + NM_SETTING_GSM_PIN, "123456", + NM_SETTING_GSM_NETWORK_ID, "254098", + NM_SETTING_GSM_HOME_ONLY, TRUE, + NM_SETTING_GSM_NETWORK_TYPE, NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA, + NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + ASSERT (success == TRUE, + "connection-write", "failed to allocate write keyfile: %s", + error ? error->message : "(none)"); + + ASSERT (testfile != NULL, + "connection-write", "didn't get keyfile name back after writing connection"); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); + ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "connection-write", "written and re-read connection weren't the same"); + + g_clear_error (&error); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +#define TEST_WIRED_TLS_OLD_FILE TEST_KEYFILES_DIR"/Test_Wired_TLS_Old" + +static void +test_read_wired_8021x_tls_old_connection (void) +{ + NMConnection *connection; + NMSetting *s_wired; + NMSetting8021x *s_8021x; + GError *error = NULL; + const char *tmp; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_OLD_FILE, &error); + if (connection == NULL) { + g_assert (error); + g_warning ("Failed to read %s: %s", TEST_WIRED_TLS_OLD_FILE, error->message); + g_assert (connection); + } + + success = nm_connection_verify (connection, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify %s: %s", TEST_WIRED_TLS_OLD_FILE, error->message); + g_assert (success); + } + + /* ===== Wired Setting ===== */ + s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + g_assert (s_wired != NULL); + + /* ===== 802.1x Setting ===== */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x != NULL); + + g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + g_assert (g_strcmp0 (tmp, "tls") == 0); + + tmp = nm_setting_802_1x_get_identity (s_8021x); + g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + + tmp = nm_setting_802_1x_get_private_key_password (s_8021x); + g_assert (g_strcmp0 (tmp, "12345testing") == 0); + + tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); + g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0); + + tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); + g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0); + + tmp = nm_setting_802_1x_get_private_key_path (s_8021x); + g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0); + + g_object_unref (connection); +} + +#define TEST_WIRED_TLS_NEW_FILE TEST_KEYFILES_DIR"/Test_Wired_TLS_New" + +static void +test_read_wired_8021x_tls_new_connection (void) +{ + NMConnection *connection; + NMSetting *s_wired; + NMSetting8021x *s_8021x; + GError *error = NULL; + const char *tmp; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_NEW_FILE, &error); + if (connection == NULL) { + g_assert (error); + g_warning ("Failed to read %s: %s", TEST_WIRED_TLS_NEW_FILE, error->message); + g_assert (connection); + } + + success = nm_connection_verify (connection, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to verify %s: %s", TEST_WIRED_TLS_NEW_FILE, error->message); + g_assert (success); + } + + /* ===== Wired Setting ===== */ + s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + g_assert (s_wired != NULL); + + /* ===== 802.1x Setting ===== */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x != NULL); + + g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); + g_assert (g_strcmp0 (tmp, "tls") == 0); + + tmp = nm_setting_802_1x_get_identity (s_8021x); + g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + + tmp = nm_setting_802_1x_get_private_key_password (s_8021x); + g_assert (g_strcmp0 (tmp, "12345testing") == 0); + + tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); + g_assert (g_strcmp0 (tmp, "test-ca-cert.pem") == 0); + + tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); + g_assert (g_strcmp0 (tmp, "test-key-and-cert.pem") == 0); + + tmp = nm_setting_802_1x_get_private_key_path (s_8021x); + g_assert (g_strcmp0 (tmp, "test-key-and-cert.pem") == 0); + + g_object_unref (connection); +} + +#define TEST_WIRED_TLS_CA_CERT TEST_KEYFILES_DIR"/test-ca-cert.pem" +#define TEST_WIRED_TLS_CLIENT_CERT TEST_KEYFILES_DIR"/test-key-and-cert.pem" +#define TEST_WIRED_TLS_PRIVKEY TEST_KEYFILES_DIR"/test-key-and-cert.pem" + +static NMConnection * +create_wired_tls_connection (NMSetting8021xCKScheme scheme) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSetting *s_wired; + NMSetting8021x *s_8021x; + char *uuid; + gboolean success; + GError *error = NULL; + + connection = nm_connection_new (); + g_assert (connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Wired Really Secure TLS", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + /* Wired setting */ + s_wired = nm_setting_wired_new (); + g_assert (s_wired); + nm_connection_add_setting (connection, s_wired); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + g_assert (s_8021x); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + success = nm_setting_802_1x_set_ca_cert (s_8021x, + TEST_WIRED_TLS_CA_CERT, + scheme, + NULL, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set CA cert %s: %s", TEST_WIRED_TLS_CA_CERT, error->message); + g_assert (success); + } + + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_WIRED_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set client cert %s: %s", TEST_WIRED_TLS_CA_CERT, error->message); + g_assert (success); + } + + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_WIRED_TLS_PRIVKEY, + "test1", + scheme, + NULL, + &error); + if (!success) { + g_assert (error); + g_warning ("Failed to set private key %s: %s", TEST_WIRED_TLS_CA_CERT, error->message); + g_assert (success); + } + + return connection; +} + +static void +test_write_wired_8021x_tls_connection_path (void) +{ + NMConnection *connection; + char *tmp; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + GKeyFile *keyfile; + + connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert (connection != NULL); + + /* Write out the connection */ + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, geteuid (), getegid (), &testfile, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to write keyfile: %s", error->message); + g_assert (success); + } + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + if (!reread) { + g_assert (error); + g_warning ("Failed to re-read test connection: %s", error->message); + g_assert (reread); + } + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + if (!reread) { + g_warning ("Written and re-read connection weren't the same"); + g_assert (success); + } + + /* Ensure the cert and key values are properly written out */ + keyfile = g_key_file_new (); + g_assert (keyfile); + success = g_key_file_load_from_file (keyfile, testfile, G_KEY_FILE_NONE, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to re-read test file %s: %s", testfile, error->message); + g_assert (success); + } + + /* CA cert */ + tmp = g_key_file_get_string (keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT, + NULL); + g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_CA_CERT) == 0); + g_free (tmp); + + /* Client cert */ + tmp = g_key_file_get_string (keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT, + NULL); + g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_CLIENT_CERT) == 0); + g_free (tmp); + + /* Private key */ + tmp = g_key_file_get_string (keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY, + NULL); + g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_PRIVKEY) == 0); + g_free (tmp); + + g_key_file_free (keyfile); + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +static void +test_write_wired_8021x_tls_connection_blob (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + char *new_ca_cert; + char *new_client_cert; + char *new_priv_key; + const char *uuid; + GError *error = NULL; + + connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_BLOB); + g_assert (connection != NULL); + + /* Write out the connection */ + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, geteuid (), getegid (), &testfile, &error); + if (!success) { + g_assert (error); + g_warning ("Failed to write keyfile: %s", error->message); + g_assert (success); + } + g_assert (testfile); + + /* Check that the new certs got written out */ + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + uuid = nm_setting_connection_get_uuid (s_con); + g_assert (uuid); + + new_ca_cert = g_strdup_printf ("%s/%s-ca-cert.pem", TEST_SCRATCH_DIR, uuid); + g_assert (new_ca_cert); + g_assert (g_file_test (new_ca_cert, G_FILE_TEST_EXISTS)); + + new_client_cert = g_strdup_printf ("%s/%s-client-cert.pem", TEST_SCRATCH_DIR, uuid); + g_assert (new_client_cert); + g_assert (g_file_test (new_client_cert, G_FILE_TEST_EXISTS)); + + new_priv_key = g_strdup_printf ("%s/%s-private-key.pem", TEST_SCRATCH_DIR, uuid); + g_assert (new_priv_key); + g_assert (g_file_test (new_priv_key, G_FILE_TEST_EXISTS)); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + if (!reread) { + g_assert (error); + g_warning ("Failed to re-read test connection: %s", error->message); + g_assert (reread); + } + + /* Ensure the re-read connection's certificates use the path scheme */ + s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X); + g_assert (s_8021x); + g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert (nm_setting_802_1x_get_private_key_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + + unlink (testfile); + g_free (testfile); + + /* Clean up written certs */ + unlink (new_ca_cert); + g_free (new_ca_cert); + + unlink (new_client_cert); + g_free (new_client_cert); + + unlink (new_priv_key); + g_free (new_priv_key); + + g_object_unref (reread); + g_object_unref (connection); +} + +int main (int argc, char **argv) +{ + GError *error = NULL; + char *base; + + g_type_init (); + + if (!nm_utils_init (&error)) + FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + + /* The tests */ + test_read_valid_wired_connection (); + test_write_wired_connection (); + + test_read_ip6_wired_connection (); + test_write_ip6_wired_connection (); + + test_read_wired_mac_case (); + + test_read_valid_wireless_connection (); + test_write_wireless_connection (); + + test_read_string_ssid (); + test_write_string_ssid (); + + test_read_bt_dun_connection (); + test_write_bt_dun_connection (); + + test_read_gsm_connection (); + test_write_gsm_connection (); + + test_read_wired_8021x_tls_old_connection (); + test_read_wired_8021x_tls_new_connection (); + test_write_wired_8021x_tls_connection_path (); + test_write_wired_8021x_tls_connection_blob (); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/src/settings/plugins/keyfile/utils.c b/src/settings/plugins/keyfile/utils.c new file mode 100644 index 00000000..7b93a245 --- /dev/null +++ b/src/settings/plugins/keyfile/utils.c @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Red Hat, Inc. + */ + +#include <glib.h> +#include <stdlib.h> +#include <string.h> +#include "utils.h" + + +static const char temp_letters[] = +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* + * Check '.[a-zA-Z0-9]{6}' file suffix used for temporary files by g_file_set_contents() (mkstemp()). + */ +static gboolean +check_mkstemp_suffix (const char *path) +{ + const char *ptr; + + g_return_val_if_fail (path != NULL, FALSE); + + /* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */ + ptr = strrchr (path, '.'); + if (ptr && (strspn (ptr + 1, temp_letters) == 6) && (! ptr[7])) + return TRUE; + return FALSE; +} + +static gboolean +check_prefix (const char *base, const char *tag) +{ + int len, tag_len; + + g_return_val_if_fail (base != NULL, TRUE); + g_return_val_if_fail (tag != NULL, TRUE); + + len = strlen (base); + tag_len = strlen (tag); + if ((len > tag_len) && !strncasecmp (base, tag, tag_len)) + return TRUE; + return FALSE; +} + +static gboolean +check_suffix (const char *base, const char *tag) +{ + int len, tag_len; + + g_return_val_if_fail (base != NULL, TRUE); + g_return_val_if_fail (tag != NULL, TRUE); + + len = strlen (base); + tag_len = strlen (tag); + if ((len > tag_len) && !strcasecmp (base + len - tag_len, tag)) + return TRUE; + return FALSE; +} + +gboolean +nm_keyfile_plugin_utils_should_ignore_file (const char *filename) +{ + char *base; + gboolean ignore = FALSE; + + g_return_val_if_fail (filename != NULL, TRUE); + + base = g_path_get_basename (filename); + g_return_val_if_fail (base != NULL, TRUE); + + /* Ignore files with certain patterns */ + if ( (check_prefix (base, ".") && check_suffix (base, SWP_TAG)) /* vim temporary files: .filename.swp */ + || (check_prefix (base, ".") && check_suffix (base, SWPX_TAG)) /* vim temporary files: .filename.swpx */ + || check_mkstemp_suffix (base) /* temporary files created by mkstemp() */ + || base[strlen (base) - 1] == '~') + ignore = TRUE; + + g_free (base); + return ignore; +} + diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h new file mode 100644 index 00000000..68e6e56f --- /dev/null +++ b/src/settings/plugins/keyfile/utils.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Red Hat, Inc. + */ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include <glib.h> +#include "common.h" + +gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename); + +#endif /* _UTILS_H_ */ + diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c new file mode 100644 index 00000000..5ecf5891 --- /dev/null +++ b/src/settings/plugins/keyfile/writer.c @@ -0,0 +1,1044 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include <config.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> + +#include <dbus/dbus-glib.h> +#include <nm-setting.h> +#include <nm-setting-connection.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-vpn.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-bluetooth.h> +#include <nm-setting-8021x.h> +#include <nm-utils.h> +#include <string.h> +#include <arpa/inet.h> +#include <netinet/ether.h> +#include <ctype.h> + +#include "nm-dbus-glib-types.h" +#include "writer.h" +#include "common.h" + +static gboolean +write_array_of_uint (GKeyFile *file, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GArray *array; + int i; + int *tmp_array; + + array = (GArray *) g_value_get_boxed (value); + if (!array || !array->len) + return TRUE; + + tmp_array = g_new (gint, array->len); + for (i = 0; i < array->len; i++) + tmp_array[i] = g_array_index (array, int, i); + + g_key_file_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); + g_free (tmp_array); + return TRUE; +} + +static void +ip4_dns_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GArray *array; + char **list; + int i, num = 0; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY)); + + array = (GArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + list = g_new0 (char *, array->len + 1); + + for (i = 0; i < array->len; i++) { + char buf[INET_ADDRSTRLEN + 1]; + struct in_addr addr; + + addr.s_addr = g_array_index (array, guint32, i); + if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) { + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); + } else + list[num++] = g_strdup (buf); + } + + g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); + g_strfreev (list); +} + +static void +write_ip4_values (GKeyFile *file, + const char *setting_name, + const char *key, + GPtrArray *array, + guint32 tuple_len, + guint32 addr1_pos, + guint32 addr2_pos) +{ + char **list = NULL; + int i, j; + + list = g_new (char *, tuple_len); + + for (i = 0, j = 0; i < array->len; i++, j++) { + GArray *tuple = g_ptr_array_index (array, i); + gboolean success = TRUE; + char *key_name; + int k; + + memset (list, 0, tuple_len * sizeof (char *)); + + for (k = 0; k < tuple_len; k++) { + if (k == addr1_pos || k == addr2_pos) { + char buf[INET_ADDRSTRLEN + 1]; + struct in_addr addr; + + /* IP addresses */ + addr.s_addr = g_array_index (tuple, guint32, k); + if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) { + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); + success = FALSE; + break; + } else { + list[k] = g_strdup (buf); + } + } else { + /* prefix, metric */ + list[k] = g_strdup_printf ("%d", g_array_index (tuple, guint32, k)); + } + } + + if (success) { + key_name = g_strdup_printf ("%s%d", key, j + 1); + g_key_file_set_string_list (file, setting_name, key_name, (const char **) list, tuple_len); + g_free (key_name); + } + + for (k = 0; k < tuple_len; k++) + g_free (list[k]); + } + g_free (list); +} + +static void +ip4_addr_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GPtrArray *array; + const char *setting_name = nm_setting_get_name (setting); + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); + + array = (GPtrArray *) g_value_get_boxed (value); + if (array && array->len) + write_ip4_values (file, setting_name, key, array, 3, 0, 2); +} + +static void +ip4_route_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GPtrArray *array; + const char *setting_name = nm_setting_get_name (setting); + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); + + array = (GPtrArray *) g_value_get_boxed (value); + if (array && array->len) + write_ip4_values (file, setting_name, key, array, 4, 0, 2); +} + +static void +ip6_dns_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GPtrArray *array; + GByteArray *byte_array; + char **list; + int i, num = 0; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)); + + array = (GPtrArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + list = g_new0 (char *, array->len + 1); + + for (i = 0; i < array->len; i++) { + char buf[INET6_ADDRSTRLEN]; + + byte_array = g_ptr_array_index (array, i); + if (!inet_ntop (AF_INET6, (struct in6_addr *) byte_array->data, buf, sizeof (buf))) { + int j; + GString *ip6_str = g_string_new (NULL); + g_string_append_printf (ip6_str, "%02X", byte_array->data[0]); + for (j = 1; j < 16; j++) + g_string_append_printf (ip6_str, " %02X", byte_array->data[j]); + g_warning ("%s: error converting IP6 address %s", + __func__, ip6_str->str); + g_string_free (ip6_str, TRUE); + } else + list[num++] = g_strdup (buf); + } + + g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); + g_strfreev (list); +} + +static gboolean +ip6_array_to_addr (GValueArray *values, + guint32 idx, + char *buf, + size_t buflen, + gboolean *out_is_unspec) +{ + GByteArray *byte_array; + GValue *addr_val; + struct in6_addr *addr; + + g_return_val_if_fail (buflen >= INET6_ADDRSTRLEN, FALSE); + + addr_val = g_value_array_get_nth (values, idx); + byte_array = g_value_get_boxed (addr_val); + addr = (struct in6_addr *) byte_array->data; + + if (out_is_unspec && IN6_IS_ADDR_UNSPECIFIED (addr)) + *out_is_unspec = TRUE; + + errno = 0; + if (!inet_ntop (AF_INET6, addr, buf, buflen)) { + GString *ip6_str = g_string_sized_new (INET6_ADDRSTRLEN + 10); + + /* error converting the address */ + g_string_append_printf (ip6_str, "%02X", byte_array->data[0]); + for (idx = 1; idx < 16; idx++) + g_string_append_printf (ip6_str, " %02X", byte_array->data[idx]); + g_warning ("%s: error %d converting IP6 address %s", + __func__, errno, ip6_str->str); + g_string_free (ip6_str, TRUE); + return FALSE; + } + + return TRUE; +} + +static char * +ip6_array_to_addr_prefix (GValueArray *values) +{ + GValue *prefix_val; + char *ret = NULL; + GString *ip6_str; + char buf[INET6_ADDRSTRLEN + 1]; + gboolean is_unspec = FALSE; + + /* address */ + if (ip6_array_to_addr (values, 0, buf, sizeof (buf), NULL)) { + /* Enough space for the address, '/', and the prefix */ + ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5); + + /* prefix */ + g_string_append (ip6_str, buf); + prefix_val = g_value_array_get_nth (values, 1); + g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val)); + + if (ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec)) { + if (!is_unspec) + g_string_append_printf (ip6_str, ",%s", buf); + } + + ret = ip6_str->str; + g_string_free (ip6_str, FALSE); + } + + return ret; +} + +static void +ip6_addr_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GPtrArray *array; + const char *setting_name = nm_setting_get_name (setting); + int i, j; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); + + array = (GPtrArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + for (i = 0, j = 1; i < array->len; i++) { + GValueArray *values = g_ptr_array_index (array, i); + char *key_name, *ip6_addr; + + if (values->n_values != 3) { + g_warning ("%s: error writing IP6 address %d (address array length " + "%d is not 3)", + __func__, i, values->n_values); + continue; + } + + ip6_addr = ip6_array_to_addr_prefix (values); + if (ip6_addr) { + /* Write it out */ + key_name = g_strdup_printf ("%s%d", key, j++); + g_key_file_set_string (file, setting_name, key_name, ip6_addr); + g_free (key_name); + g_free (ip6_addr); + } + } +} + +static void +ip6_route_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GPtrArray *array; + const char *setting_name = nm_setting_get_name (setting); + char *list[3]; + int i, j; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE)); + + array = (GPtrArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + for (i = 0, j = 1; i < array->len; i++) { + GValueArray *values = g_ptr_array_index (array, i); + char *key_name; + guint32 int_val; + char buf[INET6_ADDRSTRLEN + 1]; + gboolean is_unspec = FALSE; + + memset (list, 0, sizeof (list)); + + /* Address and prefix */ + list[0] = ip6_array_to_addr_prefix (values); + if (!list[0]) + continue; + + /* Next Hop */ + if (!ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec)) + continue; + if (is_unspec) + continue; + list[1] = g_strdup (buf); + + /* Metric */ + value = g_value_array_get_nth (values, 3); + int_val = g_value_get_uint (value); + list[2] = g_strdup_printf ("%d", int_val); + + /* Write it out */ + key_name = g_strdup_printf ("%s%d", key, j++); + g_key_file_set_string_list (file, setting_name, key_name, (const char **) list, 3); + g_free (key_name); + + g_free (list[0]); + g_free (list[1]); + g_free (list[2]); + } +} + + +static void +mac_address_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GByteArray *array; + const char *setting_name = nm_setting_get_name (setting); + char *mac; + struct ether_addr tmp; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); + + array = (GByteArray *) g_value_get_boxed (value); + if (!array) + return; + + if (array->len != ETH_ALEN) { + g_warning ("%s: invalid %s / %s MAC address length %d", + __func__, setting_name, key, array->len); + return; + } + + memcpy (tmp.ether_addr_octet, array->data, ETH_ALEN); + mac = ether_ntoa (&tmp); + g_key_file_set_string (file, setting_name, key, mac); +} + +static void +write_hash_of_string (GKeyFile *file, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GHashTableIter iter; + const char *property = NULL, *data = NULL; + const char *group_name = nm_setting_get_name (setting); + gboolean vpn_secrets = FALSE; + + /* Write VPN secrets out to a different group to keep them separate */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + group_name = VPN_SECRETS_GROUP; + vpn_secrets = TRUE; + } + + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) { + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Handle VPN secrets specially; they are nested in the property's hash; + * we don't want to write them if the secret is not saved or not required. + */ + if (vpn_secrets && nm_setting_get_secret_flags (setting, property, &flags, NULL)) { + if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + continue; + } + + g_key_file_set_string (file, group_name, property, data); + } +} + +static void +ssid_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + GByteArray *array; + const char *setting_name = nm_setting_get_name (setting); + gboolean new_format = TRUE; + int i, *tmp_array; + char *ssid; + + g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); + + array = (GByteArray *) g_value_get_boxed (value); + if (!array || !array->len) + return; + + /* Check whether each byte is printable. If not, we have to use an + * integer list, otherwise we can just use a string. + */ + for (i = 0; i < array->len; i++) { + char c = array->data[i] & 0xFF; + if (!isprint (c)) { + new_format = FALSE; + break; + } + } + + if (new_format) { + ssid = g_malloc0 (array->len + 1); + memcpy (ssid, array->data, array->len); + g_key_file_set_string (file, setting_name, key, ssid); + g_free (ssid); + } else { + tmp_array = g_new (gint, array->len); + for (i = 0; i < array->len; i++) + tmp_array[i] = (int) array->data[i]; + g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len); + g_free (tmp_array); + } +} + +typedef struct ObjectType { + const char *key; + const char *suffix; + const char *privkey_pw_prop; + NMSetting8021xCKScheme (*scheme_func) (NMSetting8021x *setting); + NMSetting8021xCKFormat (*format_func) (NMSetting8021x *setting); + const char * (*path_func) (NMSetting8021x *setting); + const GByteArray * (*blob_func) (NMSetting8021x *setting); +} ObjectType; + +static const ObjectType objtypes[10] = { + { NM_SETTING_802_1X_CA_CERT, + "ca-cert", + NULL, + nm_setting_802_1x_get_ca_cert_scheme, + NULL, + nm_setting_802_1x_get_ca_cert_path, + nm_setting_802_1x_get_ca_cert_blob }, + + { NM_SETTING_802_1X_PHASE2_CA_CERT, + "inner-ca-cert", + NULL, + nm_setting_802_1x_get_phase2_ca_cert_scheme, + NULL, + nm_setting_802_1x_get_phase2_ca_cert_path, + nm_setting_802_1x_get_phase2_ca_cert_blob }, + + { NM_SETTING_802_1X_CLIENT_CERT, + "client-cert", + NULL, + nm_setting_802_1x_get_client_cert_scheme, + NULL, + nm_setting_802_1x_get_client_cert_path, + nm_setting_802_1x_get_client_cert_blob }, + + { NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + "inner-client-cert", + NULL, + nm_setting_802_1x_get_phase2_client_cert_scheme, + NULL, + nm_setting_802_1x_get_phase2_client_cert_path, + nm_setting_802_1x_get_phase2_client_cert_blob }, + + { NM_SETTING_802_1X_PRIVATE_KEY, + "private-key", + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, + nm_setting_802_1x_get_private_key_scheme, + nm_setting_802_1x_get_private_key_format, + nm_setting_802_1x_get_private_key_path, + nm_setting_802_1x_get_private_key_blob }, + + { NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + "inner-private-key", + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, + nm_setting_802_1x_get_phase2_private_key_scheme, + nm_setting_802_1x_get_phase2_private_key_format, + nm_setting_802_1x_get_phase2_private_key_path, + nm_setting_802_1x_get_phase2_private_key_blob }, + + { NULL }, +}; + +static gboolean +write_cert_key_file (const char *path, + const GByteArray *data, + GError **error) +{ + char *tmppath; + int fd = -1, written; + gboolean success = FALSE; + + tmppath = g_malloc0 (strlen (path) + 10); + g_assert (tmppath); + memcpy (tmppath, path, strlen (path)); + strcat (tmppath, ".XXXXXX"); + + errno = 0; + fd = mkstemp (tmppath); + if (fd < 0) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Could not create temporary file for '%s': %d", + path, errno); + goto out; + } + + /* Only readable by root */ + errno = 0; + if (fchmod (fd, S_IRUSR | S_IWUSR) != 0) { + close (fd); + unlink (tmppath); + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Could not set permissions for temporary file '%s': %d", + path, errno); + goto out; + } + + errno = 0; + written = write (fd, data->data, data->len); + if (written != data->len) { + close (fd); + unlink (tmppath); + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Could not write temporary file for '%s': %d", + path, errno); + goto out; + } + close (fd); + + /* Try to rename */ + errno = 0; + if (rename (tmppath, path) == 0) + success = TRUE; + else { + unlink (tmppath); + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Could not rename temporary file to '%s': %d", + path, errno); + } + +out: + g_free (tmppath); + return success; +} + +static void +cert_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + const char *setting_name = nm_setting_get_name (setting); + NMSetting8021xCKScheme scheme; + NMSetting8021xCKFormat format; + const char *path = NULL, *ext = "pem"; + const ObjectType *objtype = NULL; + int i; + + for (i = 0; i < G_N_ELEMENTS (objtypes) && objtypes[i].key; i++) { + if (g_strcmp0 (objtypes[i].key, key) == 0) { + objtype = &objtypes[i]; + break; + } + } + g_return_if_fail (objtype != NULL); + + scheme = objtypes->scheme_func (NM_SETTING_802_1X (setting)); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + path = objtype->path_func (NM_SETTING_802_1X (setting)); + g_assert (path); + g_key_file_set_string (file, setting_name, key, path); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + const GByteArray *blob; + gboolean success; + GError *error = NULL; + char *new_path; + + blob = objtype->blob_func (NM_SETTING_802_1X (setting)); + g_assert (blob); + + if (objtype->format_func) { + /* Get the extension for a private key */ + format = objtype->format_func (NM_SETTING_802_1X (setting)); + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + ext = "p12"; + } else { + /* DER or PEM format certificate? */ + if (blob->len > 2 && blob->data[0] == 0x30 && blob->data[1] == 0x82) + ext = "der"; + } + + /* Write the raw data out to the standard file so that we can use paths + * from now on instead of pushing around the certificate data. + */ + new_path = g_strdup_printf ("%s/%s-%s.%s", keyfile_dir, uuid, objtype->suffix, ext); + g_assert (new_path); + + success = write_cert_key_file (new_path, blob, &error); + if (success) { + /* Write the path value to the keyfile */ + g_key_file_set_string (file, setting_name, key, new_path); + } else { + g_warning ("Failed to write certificate/key %s: %s", new_path, error->message); + g_error_free (error); + } + g_free (new_path); + } else + g_assert_not_reached (); +} + +typedef struct { + const char *setting_name; + const char *key; + void (*writer) (GKeyFile *keyfile, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value); +} KeyWriter; + +/* A table of keys that require further parsing/conversion because they are + * stored in a format that can't be automatically read using the key's type. + * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are + * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored + * in struct in6_addr internally, but as string in keyfiles. + */ +static KeyWriter key_writers[] = { + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ADDRESSES, + ip4_addr_writer }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDRESSES, + ip6_addr_writer }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_ROUTES, + ip4_route_writer }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ROUTES, + ip6_route_writer }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DNS, + ip4_dns_writer }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DNS, + ip6_dns_writer }, + { NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS, + mac_address_writer }, + { NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + mac_address_writer }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS, + mac_address_writer }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + mac_address_writer }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID, + mac_address_writer }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR, + mac_address_writer }, + { NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID, + ssid_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT, + cert_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT, + cert_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY, + cert_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CA_CERT, + cert_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + cert_writer }, + { NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + cert_writer }, + { NULL, NULL, NULL } +}; + +typedef struct { + GKeyFile *keyfile; + const char *keyfile_dir; + const char *uuid; +} WriteInfo; + +static void +write_setting_value (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flag, + gpointer user_data) +{ + WriteInfo *info = user_data; + const char *setting_name; + GType type = G_VALUE_TYPE (value); + KeyWriter *writer = &key_writers[0]; + GParamSpec *pspec; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Setting name gets picked up from the keyfile's section name instead */ + if (!strcmp (key, NM_SETTING_NAME)) + return; + + /* Don't write the NMSettingConnection object's 'read-only' property */ + if ( NM_IS_SETTING_CONNECTION (setting) + && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) + return; + + setting_name = nm_setting_get_name (setting); + + /* If the value is the default value, remove the item from the keyfile */ + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); + if (pspec) { + if (g_param_value_defaults (pspec, (GValue *) value)) { + g_key_file_remove_key (info->keyfile, setting_name, key, NULL); + return; + } + } + + /* Don't write secrets that are owned by user secret agents or aren't + * supposed to be saved. + */ + if ( (pspec->flags & NM_SETTING_PARAM_SECRET) + && nm_setting_get_secret_flags (setting, key, &flags, NULL) + && (flags != NM_SETTING_SECRET_FLAG_NONE)) + return; + + /* Look through the list of handlers for non-standard format key values */ + while (writer->setting_name) { + if (!strcmp (writer->setting_name, setting_name) && !strcmp (writer->key, key)) { + (*writer->writer) (info->keyfile, info->keyfile_dir, info->uuid, setting, key, value); + return; + } + writer++; + } + + if (type == G_TYPE_STRING) { + const char *str; + + str = g_value_get_string (value); + if (str) + g_key_file_set_string (info->keyfile, setting_name, key, str); + } else if (type == G_TYPE_UINT) + g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value)); + else if (type == G_TYPE_INT) + g_key_file_set_integer (info->keyfile, setting_name, key, g_value_get_int (value)); + else if (type == G_TYPE_UINT64) { + char *numstr; + + numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value)); + g_key_file_set_value (info->keyfile, setting_name, key, numstr); + g_free (numstr); + } else if (type == G_TYPE_BOOLEAN) { + g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); + } else if (type == G_TYPE_CHAR) { + g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_char (value)); + } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { + GByteArray *array; + + array = (GByteArray *) g_value_get_boxed (value); + if (array && array->len > 0) { + int *tmp_array; + int i; + + tmp_array = g_new (gint, array->len); + for (i = 0; i < array->len; i++) + tmp_array[i] = (int) array->data[i]; + + g_key_file_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len); + g_free (tmp_array); + } + } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { + GSList *list; + GSList *iter; + + list = (GSList *) g_value_get_boxed (value); + if (list) { + char **array; + int i = 0; + + array = g_new (char *, g_slist_length (list)); + for (iter = list; iter; iter = iter->next) + array[i++] = iter->data; + + g_key_file_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i); + g_free (array); + } + } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { + write_hash_of_string (info->keyfile, setting, key, value); + } else if (type == DBUS_TYPE_G_UINT_ARRAY) { + if (!write_array_of_uint (info->keyfile, setting, key, value)) { + g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", + setting_name, key, g_type_name (type)); + } + } else { + g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", + setting_name, key, g_type_name (type)); + } +} + +static char * +_writer_id_to_filename (const char *id) +{ + char *filename, *f; + const char *i = id; + + f = filename = g_malloc0 (strlen (id) + 1); + + /* Convert '/' to '*' */ + while (*i) { + if (*i == '/') + *f++ = '*'; + else + *f++ = *i; + i++; + } + + return filename; +} + +static gboolean +_internal_write_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + const char *existing_path, + char **out_path, + GError **error) +{ + GKeyFile *key_file; + char *data; + gsize len; + gboolean success = FALSE; + char *filename = NULL, *path; + const char *id; + WriteInfo info; + + if (out_path) + g_return_val_if_fail (*out_path == NULL, FALSE); + + id = nm_connection_get_id (connection); + if (!id) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: connection had no ID", __FILE__, __LINE__); + return FALSE; + } + + info.keyfile = key_file = g_key_file_new (); + info.keyfile_dir = keyfile_dir; + info.uuid = nm_connection_get_uuid (connection); + g_assert (info.uuid); + nm_connection_for_each_setting_value (connection, write_setting_value, &info); + data = g_key_file_to_data (key_file, &len, error); + if (!data) + goto out; + + filename = _writer_id_to_filename (id); + path = g_build_filename (keyfile_dir, filename, NULL); + + /* If a file with this path already exists (but isn't the existing path + * of the connection) then we need another name. Multiple connections + * can have the same ID (ie if two connections with the same ID are visible + * to different users) but of course can't have the same path. Yeah, + * there's a race here, but there's not a lot we can do about it, and + * we shouldn't get more than one connection with the same UUID either. + */ + if (g_file_test (path, G_FILE_TEST_EXISTS) && (g_strcmp0 (path, existing_path) != 0)) { + /* A keyfile with this connection's ID already exists. Pick another name. */ + g_free (path); + + path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection)); + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + /* Hmm, this is odd. Give up. */ + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: could not find suitable keyfile file name (%s already used)", + __FILE__, __LINE__, path); + g_free (path); + goto out; + } + } + + g_file_set_contents (path, data, len, error); + if (chown (path, owner_uid, owner_grp) < 0) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: error chowning '%s': %d", __FILE__, __LINE__, + path, errno); + unlink (path); + } else { + if (chmod (path, S_IRUSR | S_IWUSR) < 0) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: error setting permissions on '%s': %d", __FILE__, + __LINE__, path, errno); + unlink (path); + } else { + if (out_path && g_strcmp0 (existing_path, path)) { + *out_path = path; /* pass path out to caller */ + path = NULL; + } + success = TRUE; + } + } + g_free (path); + +out: + g_free (filename); + g_free (data); + g_key_file_free (key_file); + return success; +} + +gboolean +nm_keyfile_plugin_write_connection (NMConnection *connection, + const char *existing_path, + char **out_path, + GError **error) +{ + return _internal_write_connection (connection, + KEYFILE_DIR, + 0, 0, + existing_path, + out_path, + error); +} + +gboolean +nm_keyfile_plugin_write_test_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error) +{ + return _internal_write_connection (connection, + keyfile_dir, + owner_uid, owner_grp, + NULL, + out_path, + error); +} + diff --git a/src/settings/plugins/keyfile/writer.h b/src/settings/plugins/keyfile/writer.h new file mode 100644 index 00000000..a602f2f4 --- /dev/null +++ b/src/settings/plugins/keyfile/writer.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service - keyfile plugin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#ifndef _KEYFILE_PLUGIN_WRITER_H +#define _KEYFILE_PLUGIN_WRITER_H + +#include <sys/types.h> +#include <glib.h> +#include <nm-connection.h> + +gboolean nm_keyfile_plugin_write_connection (NMConnection *connection, + const char *existing_path, + char **out_path, + GError **error); + +gboolean nm_keyfile_plugin_write_test_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error); + +#endif /* _KEYFILE_PLUGIN_WRITER_H */ diff --git a/src/settings/tests/Makefile.am b/src/settings/tests/Makefile.am new file mode 100644 index 00000000..4a451398 --- /dev/null +++ b/src/settings/tests/Makefile.am @@ -0,0 +1,32 @@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/src/settings + +noinst_PROGRAMS = \ + test-wired-defname + +####### wired defname test ####### + +test_wired_defname_SOURCES = \ + test-wired-defname.c + +test_wired_defname_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_wired_defname_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/settings/libtest-settings-utils.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + +########################################### + +if WITH_TESTS + +check-local: test-wired-defname + $(abs_builddir)/test-wired-defname + +endif + diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in new file mode 100644 index 00000000..70e6b17e --- /dev/null +++ b/src/settings/tests/Makefile.in @@ -0,0 +1,632 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-wired-defname$(EXEEXT) +subdir = src/settings/tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_wired_defname_OBJECTS = \ + test_wired_defname-test-wired-defname.$(OBJEXT) +test_wired_defname_OBJECTS = $(am_test_wired_defname_OBJECTS) +am__DEPENDENCIES_1 = +test_wired_defname_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/settings/libtest-settings-utils.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(test_wired_defname_SOURCES) +DIST_SOURCES = $(test_wired_defname_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCLIENT_VERSION = @DHCLIENT_VERSION@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_PATH = @PKGCONFIG_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/src/settings + + +####### wired defname test ####### +test_wired_defname_SOURCES = \ + test-wired-defname.c + +test_wired_defname_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_wired_defname_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/settings/libtest-settings-utils.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_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 +test-wired-defname$(EXEEXT): $(test_wired_defname_OBJECTS) $(test_wired_defname_DEPENDENCIES) + @rm -f test-wired-defname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_wired_defname_OBJECTS) $(test_wired_defname_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_wired_defname-test-wired-defname.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_wired_defname-test-wired-defname.o: test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wired_defname-test-wired-defname.o -MD -MP -MF $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o test_wired_defname-test-wired-defname.o `test -f 'test-wired-defname.c' || echo '$(srcdir)/'`test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo $(DEPDIR)/test_wired_defname-test-wired-defname.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wired-defname.c' object='test_wired_defname-test-wired-defname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wired_defname-test-wired-defname.o `test -f 'test-wired-defname.c' || echo '$(srcdir)/'`test-wired-defname.c + +test_wired_defname-test-wired-defname.obj: test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wired_defname-test-wired-defname.obj -MD -MP -MF $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o test_wired_defname-test-wired-defname.obj `if test -f 'test-wired-defname.c'; then $(CYGPATH_W) 'test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/test-wired-defname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo $(DEPDIR)/test_wired_defname-test-wired-defname.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wired-defname.c' object='test_wired_defname-test-wired-defname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wired_defname-test-wired-defname.obj `if test -f 'test-wired-defname.c'; then $(CYGPATH_W) 'test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/test-wired-defname.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@WITH_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +########################################### + +@WITH_TESTS_TRUE@check-local: test-wired-defname +@WITH_TESTS_TRUE@ $(abs_builddir)/test-wired-defname + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/tests/test-wired-defname.c b/src/settings/tests/test-wired-defname.c new file mode 100644 index 00000000..f6627fa9 --- /dev/null +++ b/src/settings/tests/test-wired-defname.c @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + * + */ + +#include <glib.h> +#include <glib-object.h> + +#include <nm-connection.h> +#include <nm-setting-connection.h> +#include "nm-settings-utils.h" + +static NMConnection * +_new_connection (const char *id) +{ + NMConnection *a; + NMSetting *setting; + + a = nm_connection_new (); + setting = nm_setting_connection_new (); + g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NULL); + nm_connection_add_setting (a, setting); + return a; +} + +/*******************************************/ + +static void +test_defname_no_connections (void) +{ + GHashTable *hash; + char *name; + + hash = g_hash_table_new (g_direct_hash, g_direct_equal); + + name = nm_settings_utils_get_default_wired_name (hash); + g_assert_cmpstr (name, ==, "Wired connection 1"); + + g_hash_table_destroy (hash); +} + +/*******************************************/ + +static void +test_defname_no_conflict (void) +{ + GHashTable *hash; + char *name; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); + + g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf")); + g_hash_table_insert (hash, "b", _new_connection ("work wifi")); + g_hash_table_insert (hash, "c", _new_connection ("random gsm connection")); + + name = nm_settings_utils_get_default_wired_name (hash); + g_assert_cmpstr (name, ==, "Wired connection 1"); + + g_hash_table_destroy (hash); +} + +/*******************************************/ + +static void +test_defname_conflict (void) +{ + GHashTable *hash; + char *name; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); + + g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf")); + g_hash_table_insert (hash, "b", _new_connection ("Wired connection 1")); + g_hash_table_insert (hash, "c", _new_connection ("random gsm connection")); + + name = nm_settings_utils_get_default_wired_name (hash); + g_assert_cmpstr (name, ==, "Wired connection 2"); + + g_hash_table_destroy (hash); +} + +/*******************************************/ + +static void +test_defname_multiple_conflicts (void) +{ + GHashTable *hash; + char *name; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); + + g_hash_table_insert (hash, "a", _new_connection ("random gsm connection")); + g_hash_table_insert (hash, "b", _new_connection ("home wifi")); + g_hash_table_insert (hash, "c", _new_connection ("Wired connection 1")); + g_hash_table_insert (hash, "d", _new_connection ("Wired connection 2")); + g_hash_table_insert (hash, "e", _new_connection ("Wired connection 3")); + g_hash_table_insert (hash, "f", _new_connection ("work wifi")); + g_hash_table_insert (hash, "g", _new_connection ("a vpn")); + + name = nm_settings_utils_get_default_wired_name (hash); + g_assert_cmpstr (name, ==, "Wired connection 4"); + + g_hash_table_destroy (hash); +} + +/*******************************************/ + +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else +typedef void (*TCFunc)(void); +#endif + +#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) + +int main (int argc, char **argv) +{ + GTestSuite *suite; + + g_type_init (); + g_test_init (&argc, &argv, NULL); + + suite = g_test_get_root (); + + g_test_suite_add (suite, TESTCASE (test_defname_no_connections, NULL)); + g_test_suite_add (suite, TESTCASE (test_defname_no_conflict, NULL)); + g_test_suite_add (suite, TESTCASE (test_defname_conflict, NULL)); + g_test_suite_add (suite, TESTCASE (test_defname_multiple_conflicts, NULL)); + + return g_test_run (); +} + |