diff options
| author | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
| commit | 2c032d8f1c6292c1338a615e6ec40252889ba85c (patch) | |
| tree | 1f77182220b2b0264288ba4a476ab47e5bc48716 /libnm-core/tests | |
| parent | 33491bc4279481db8ae47213e34a6d695a0e8830 (diff) | |
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'libnm-core/tests')
24 files changed, 7921 insertions, 0 deletions
diff --git a/libnm-core/tests/Makefile.am b/libnm-core/tests/Makefile.am new file mode 100644 index 00000000..a21c131c --- /dev/null +++ b/libnm-core/tests/Makefile.am @@ -0,0 +1,56 @@ +if ENABLE_TESTS + +certsdir = $(srcdir)/certs + +AM_CPPFLAGS = \ + -I${top_srcdir}/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + -DTEST_CERT_DIR=\"$(certsdir)\" + +noinst_PROGRAMS = \ + test-compare \ + test-crypto \ + test-general \ + test-secrets \ + test-setting-8021x \ + test-setting-dcb \ + test-settings-defaults + +LDADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + $(GLIB_LIBS) + +TESTS = $(noinst_PROGRAMS) + +endif + +# test-cert.p12 created with: +# +# openssl pkcs12 -export \ +# -in test_key_and_cert.pem \ +# -inkey test_key_and_cert.pem \ +# -certfile test_ca_cert.pem \ +# -name "test-pkcs12" \ +# -out test-cert.p12 + +EXTRA_DIST = \ + certs/test_ca_cert.pem \ + certs/test_ca_cert.der \ + certs/test_key_and_cert.pem \ + certs/test-cert.p12 \ + certs/test2_ca_cert.pem \ + certs/test2_key_and_cert.pem \ + certs/test2-cert.p12 \ + certs/ca-no-ending-newline.pem \ + certs/test-key-only.pem \ + certs/test-key-only-decrypted.der \ + certs/test-key-only-decrypted.pem \ + certs/pkcs8-enc-key.pem \ + certs/pkcs8-noenc-key.pem \ + certs/pkcs8-decrypted.der \ + certs/test-aes-key.pem + diff --git a/libnm-core/tests/Makefile.in b/libnm-core/tests/Makefile.in new file mode 100644 index 00000000..b62df8b4 --- /dev/null +++ b/libnm-core/tests/Makefile.in @@ -0,0 +1,959 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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@ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-compare$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-crypto$(EXEEXT) test-general$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-secrets$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-8021x$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-dcb$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-settings-defaults$(EXEEXT) +subdir = libnm-core/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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) +test_compare_SOURCES = test-compare.c +test_compare_OBJECTS = test-compare.$(OBJEXT) +test_compare_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +@ENABLE_TESTS_TRUE@test_compare_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +test_crypto_SOURCES = test-crypto.c +test_crypto_OBJECTS = test-crypto.$(OBJEXT) +test_crypto_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_crypto_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_general_SOURCES = test-general.c +test_general_OBJECTS = test-general.$(OBJEXT) +test_general_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_general_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_secrets_SOURCES = test-secrets.c +test_secrets_OBJECTS = test-secrets.$(OBJEXT) +test_secrets_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_secrets_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_setting_8021x_SOURCES = test-setting-8021x.c +test_setting_8021x_OBJECTS = test-setting-8021x.$(OBJEXT) +test_setting_8021x_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_setting_8021x_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_setting_dcb_SOURCES = test-setting-dcb.c +test_setting_dcb_OBJECTS = test-setting-dcb.$(OBJEXT) +test_setting_dcb_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_setting_dcb_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_settings_defaults_SOURCES = test-settings-defaults.c +test_settings_defaults_OBJECTS = test-settings-defaults.$(OBJEXT) +test_settings_defaults_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_settings_defaults_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = test-compare.c test-crypto.c test-general.c test-secrets.c \ + test-setting-8021x.c test-setting-dcb.c \ + test-settings-defaults.c +DIST_SOURCES = test-compare.c test-crypto.c test-general.c \ + test-secrets.c test-setting-8021x.c test-setting-dcb.c \ + test-settings-defaults.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +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@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +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@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +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@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +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@ +PERL = @PERL@ +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_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +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_CXX = @ac_ct_CXX@ +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@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +@ENABLE_TESTS_TRUE@certsdir = $(srcdir)/certs +@ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ +@ENABLE_TESTS_TRUE@ -I${top_srcdir}/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ +@ENABLE_TESTS_TRUE@ -DTEST_CERT_DIR=\"$(certsdir)\" + +@ENABLE_TESTS_TRUE@LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) + +@ENABLE_TESTS_TRUE@TESTS = $(noinst_PROGRAMS) + +# test-cert.p12 created with: +# +# openssl pkcs12 -export \ +# -in test_key_and_cert.pem \ +# -inkey test_key_and_cert.pem \ +# -certfile test_ca_cert.pem \ +# -name "test-pkcs12" \ +# -out test-cert.p12 +EXTRA_DIST = \ + certs/test_ca_cert.pem \ + certs/test_ca_cert.der \ + certs/test_key_and_cert.pem \ + certs/test-cert.p12 \ + certs/test2_ca_cert.pem \ + certs/test2_key_and_cert.pem \ + certs/test2-cert.p12 \ + certs/ca-no-ending-newline.pem \ + certs/test-key-only.pem \ + certs/test-key-only-decrypted.der \ + certs/test-key-only-decrypted.pem \ + certs/pkcs8-enc-key.pem \ + certs/pkcs8-noenc-key.pem \ + certs/pkcs8-decrypted.der \ + certs/test-aes-key.pem + +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 libnm-core/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libnm-core/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-compare$(EXEEXT): $(test_compare_OBJECTS) $(test_compare_DEPENDENCIES) $(EXTRA_test_compare_DEPENDENCIES) + @rm -f test-compare$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_compare_OBJECTS) $(test_compare_LDADD) $(LIBS) + +test-crypto$(EXEEXT): $(test_crypto_OBJECTS) $(test_crypto_DEPENDENCIES) $(EXTRA_test_crypto_DEPENDENCIES) + @rm -f test-crypto$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_crypto_OBJECTS) $(test_crypto_LDADD) $(LIBS) + +test-general$(EXEEXT): $(test_general_OBJECTS) $(test_general_DEPENDENCIES) $(EXTRA_test_general_DEPENDENCIES) + @rm -f test-general$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_general_OBJECTS) $(test_general_LDADD) $(LIBS) + +test-secrets$(EXEEXT): $(test_secrets_OBJECTS) $(test_secrets_DEPENDENCIES) $(EXTRA_test_secrets_DEPENDENCIES) + @rm -f test-secrets$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_secrets_OBJECTS) $(test_secrets_LDADD) $(LIBS) + +test-setting-8021x$(EXEEXT): $(test_setting_8021x_OBJECTS) $(test_setting_8021x_DEPENDENCIES) $(EXTRA_test_setting_8021x_DEPENDENCIES) + @rm -f test-setting-8021x$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_setting_8021x_OBJECTS) $(test_setting_8021x_LDADD) $(LIBS) + +test-setting-dcb$(EXEEXT): $(test_setting_dcb_OBJECTS) $(test_setting_dcb_DEPENDENCIES) $(EXTRA_test_setting_dcb_DEPENDENCIES) + @rm -f test-setting-dcb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_setting_dcb_OBJECTS) $(test_setting_dcb_LDADD) $(LIBS) + +test-settings-defaults$(EXEEXT): $(test_settings_defaults_OBJECTS) $(test_settings_defaults_DEPENDENCIES) $(EXTRA_test_settings_defaults_DEPENDENCIES) + @rm -f test-settings-defaults$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_settings_defaults_OBJECTS) $(test_settings_defaults_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-compare.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-secrets.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-8021x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-dcb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-settings-defaults.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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 $(AM_TESTS_FD_REDIRECT); 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 \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$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-TESTS +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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 TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am 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 tags-am 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/libnm-core/tests/certs/ca-no-ending-newline.pem b/libnm-core/tests/certs/ca-no-ending-newline.pem new file mode 100644 index 00000000..664e299a --- /dev/null +++ b/libnm-core/tests/certs/ca-no-ending-newline.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- \ No newline at end of file diff --git a/libnm-core/tests/certs/pkcs8-decrypted.der b/libnm-core/tests/certs/pkcs8-decrypted.der new file mode 100644 index 00000000..2cbdeb5e --- /dev/null +++ b/libnm-core/tests/certs/pkcs8-decrypted.der Binary files differdiff --git a/libnm-core/tests/certs/pkcs8-enc-key.pem b/libnm-core/tests/certs/pkcs8-enc-key.pem new file mode 100644 index 00000000..0d08f2d2 --- /dev/null +++ b/libnm-core/tests/certs/pkcs8-enc-key.pem @@ -0,0 +1,29 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIwiGFT4Jz6RsCAggABIIEyJNMddDYofbhydUp +J3VyrYIjv3LziJ7dkTXE3+mEYRCQrGLgljWBbib2JOLVCFt8melL6Yv1RcoVR7X7 +vrRqyycu0DumI4f5+Bf4wc234JNVhSaLYsw244fFtcnK2Gyn4IaVmWmrNvrwfX/w +SKcVmO30D5C5PCKzv2bou5FmnJLKdDQV1t816cr9T8pTx7MHvBzSZXbh86334BhF +T3zNwo8j2/+Gq2NBWUn+2GTTV8/r26aIwPcFi4QH6I2ghBwFmFHqU3/PoRm6nkmg +CqJj2Dggy+8zE5qg0iId7lrio0OjCH+Qed6NGwIa2lgv/bhuJVP3FOk4gqamJWHi +WMaq9McmS+03q2iokYeSQGbx85x+I90RTFZKhFx4dkerf6oTC/YoL4F++ff0e91v +sOrQsBkgRhrRtFwa9OFCzbsknlixONdd+ITkyX490xz1wcZTDkKtMDRLIPWa2O0b +MEq75jPYThZ5pF1vc5r+rqPafN7SfI+DDmhzJYEQNRoCWA4pH9Gwv0ayKnOgoj4K +TuFhXvcyWzTnVXmcqEFyf3CRrB0Ti+Z61enupC+FCuYV5lGsx9kJaTumTk2UPD02 +9Ap3asDLozdEPSXBG3+oCM2s01/IJlxtR84C97r9rpmWTc9K6DCBScETe9KnIghW +PU7XFogueG5Gwpe+x+IlTDq+qiyUNVX1uMGDcIaCC3VsoWqZrpnGGBhsovwBaXKt +T9fT2nE27Fd6DRWso4fgos6PPx7RVveu17BTMVQeUq9L8GrV4JNrE3a9aoXdbUhc +6gMiyAqxh/HEyciYoXsR9oVNi+VM0y8q3hL5nIcgDrCZr/c9aQ8+fuQBDXRrmrQd +bR2iwNLCBnbmQmM/vM333VhJ4MSOKd3SGw/j41K+Nr3uP5KRZUwV+5yy3ef/hGxU +i9JjCmSUt2bfWRUFlNaf1hCTYaKD0xnVr1SLFU4snIgh2qKawyqVc9EE2f+FcOM5 +0RtwQ3ku6FOk3cy6/xeKpResCHbWDS6nQaIKYyLukV+gm5MJIhOMkj2z4T1eXGUr +Nu/L7Gz+ps7ct0lM8W82n5lzSEa5/l1eNGM0wtQoAwutFEZp7Nx/IBKK87jVttr6 +82UVJeRk7rO2Mpobfw2LbKwga4rsuLrx3UwVDBWdLx7dNIc1rGoAxhsc72+skFgF +Uztwy4Yv1Uiji4T6v+mObPZD/HiIDL0vF02Pz08rNlgB0DgaTKrpql2FutIuQAdf +AciffQIoh9VGERlJoWuunG/UTxg2XRl2m1vCDrgBMInax+PXCv7/5Vh21AQc3fWP +uf4k6JSy46hYni7VTVKn6C/Di9z7oIrGl/jDkDsaenAbToyX9VWr3s7EBwnhTQ/I +OQ9bkWCagHIQlwJbu4M4/VAbiR26NrcR0C3JXBlPlT0qvFFB8gKbJAQEXtwIFS2h +m2fe0k6mQASMwdbJYXZ/wfsg5PPAWsKtny1aMvi0mTPSD5uRhIfEGEuR+AT4UbEW +BkEIE0lgGly4P1SpunKDQQE6m/e7h8Nl4pi8SMSme3YoX5MJwCP/CNkLBDVenAZI +oBrdoVox86SjwnUozVG192lcEAULlk+3ZGt6T9JXLBQl9hpNtyTC6SFh84R+5RoN +AevNl1bDfO+Vci0uJw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libnm-core/tests/certs/pkcs8-noenc-key.pem b/libnm-core/tests/certs/pkcs8-noenc-key.pem new file mode 100644 index 00000000..f73fb55a --- /dev/null +++ b/libnm-core/tests/certs/pkcs8-noenc-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC80HGgFdlFIL2F +W5rHQ99xOkMrWcZ7an9YurDebAE3M0UwqxM24+5mWbxc8FJ8yYugdMzuI5Nq77IA +DwJpv9ZjMfnKC1VDMj3bmmMdPurfx8pLdLw/jhk3wBaYk6vMvh4z66Yvmb7valGq +Pxh6CRTnekNGI9XA7me4JNBlisl0Qasn9g4pl9PiGJAruEamS4Pk6dSWbfw58bs7 +/Yo5ejyt/Mn1n0Q/r3Gv/lAS0qRvmrW6GE1rMtANMfuGRNlAln21TzNcJzykm+sp +RWptxXEI0NY7u9+RP4M3C1mJxWir7AZDbtinpOZH6vF+92yMzgEYOLK/WZVdSPdW +tROv9xtPAgMBAAECggEBAJAfp+vjYZJjuGaYEuAxjdhW+biYcWn5U7V9484TsSXa +i+DnZOZMO8iCjMaAZuZ7zYmwPlE0dK12w29KBbSEy3eySRIRboa5TgBXq3pCcXRZ +g6/vLlZw+AzXIiha6BODt3g4UwUYnWcQx79lJCDa18sNR1a9ucbn8+Har/wiYT3M +JjTbUT6wR6rKEXchB58ZugYGhOTfugSDQg4U/dwEHPIaJ/wme++JUV5B/tjeGCG3 +F43o2Oos5vjfrDSpUKIYZn+2BdhP434jkwj22wQ2sy0ruU/kQx8nogMTRfP1v4GU +9QmNXj/DB24K388ZxcDmcxBJxrGAJ0MohYFo28DqRBECgYEA6hyKEqe2UbJx/+B6 +8mYgHb+pS2j0M4jPl11q9MMLVxLnDY9xZ85IEyWHQEC0GavPSAois0oiDeGAm32c +j6TFyV3/oPTmZSyV93/agWgnH9Xtc481pbNAb0GMfyotvRRE/+6ti9+Cl7oH9Qmm +ldMk7Hn6sK9t2mUOW8idPjKqlqcCgYEAzne25BryLJoIinbRMZg9KTfxfgUE6EKc +Tk5+9CFQn0/AItQJuKbIUyggYH4psWW5hWq6hFlmMYMR48FKv9ry7pZTB0djaoYD +lN+wSuhzUYWXedkAjvPmekITmf6rbnPfwOZvsr8CGMEUekqJPnPLzsQy+Ea2y/fb +QY4SHe7gExkCgYEAr+1scOJpZvFjK7ckjT3jipd6ADpJsORxo7zG4FImFnQU/6K4 +xRpGHWVJQyaccOIkrW04cGUYPDgmrjJx0ZwwKceijvEaphMgS1JgAHklVY4sl3ea +CAAxPqoSi4lFv94Yj/9rmT4IZD6fNivfbJ20FKUBl37tXX4tkRmr2I64lOcCgYEA +x3eqzrclrmdlxvfBZOuScwbkHP6WXhk0TwbQ6eRhsnfmxP8bITSoJoaGuRJKD2Oa +l0WkSobgDwd0uhecsrvBpTS/pDGY32n3fdWZyNTHzEOHMyWtv23tBcJek5ERaBU0 +X3WBBiw4x1eKBBeMfjR6+xhbsbcHlQiw36V05UxJWMkCgYEAhtcYvrfU4K48IJTU +qp03nvd+dMY3IUTdZNOCh8bswLKyn3aq3MfWF9Vp7kDAI3cfyMpSrAQnmg4nVcn6 +Gf3wakG8bpiSRbJnGN+iLm8JsD+3Vw9KzvKOOQVmpT7xt5Kupx1hWvLHQWvfYgOG +qEtTM8/+LD7W3I7midJNt50CD8A= +-----END PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-aes-key.pem b/libnm-core/tests/certs/test-aes-key.pem new file mode 100644 index 00000000..aab8f463 --- /dev/null +++ b/libnm-core/tests/certs/test-aes-key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,800391B7DD72364B4C2562E0B6AEA000 + +E9dgNCIATOr4CN5c8o6B+8wdqq/I1BLmPmW2qT7YZepoF7E+RUb8ZLjo1VO2XsJw +Ir4EzuH7837zBD9dP5CjlY8cWfR63gZpEWRY5Jub8kzvqiL4UZ0Qr8IHOZxAkKEz +EL1Pn7e+tYt4kA372LPZHWO3vRCgmL1iSJj2/k3avPWAx7NUie4bzGI+00WNv699 +ClKzsJbWB1eiQvYgOr4aVV26oWfa896JkBoGhgZQ6ckqFpsdAos8m46iOSVZrwgq +Y2/d1CvfQod+87c8LRatwAjf+d6YAJJaeMyxjCGuAY6/JyDsorUkM2OlvbTt6WOA +gSPWO8I+Ov6THb4IuPhpIJ30Sl88tc6MlIByW49EWu2G1jPw3L8iqRzZ50Z85dyz +N9yFP91wEwi5F0Zed4iEpg3NVfklEe/VYqCldc5f9fZ84G5V98ZlAdNSqwd/UNBU +iPTflGqVpp1u+J2isOk+Agpj1MCxh2q0RNuvY9KHzOYBScirfbG4DKNbQgS/5Zw7 +3g9YL5Wbo7BczHLiXf/2adu6T8wI1LKRjkeLV9dK1Vw3ZaGy3mB9oFhCgjh9BNHw +wC78CVcUErjtOXdQagiCQn5k5EGeAB97QFROoAFjAmGvq3xCi4EHd9Sk6fcMm7Oi +1fuVR5EXUubF4Llq06lFzQp01s2F73noH49bs3qwdf0n8nrL2XhKB0XCOV/I3K5c +Y3W+YSl361QGjZ/NUcFLIIy+Uro90MmUBNk6af+wGHRJeflpVnK0ATX1PtpNHziz +jiMiIZicjgfVLxl1a5zTl6KUmGWKlZb533adQ0s6q9Qmi5Vk5L5W/GdMjcFtZbM6 +GU7EOkwihMLb3DVsNbm7vb8tUXqe/e5RmXtij8Yb+2a6/M9yaOHa0VjHzdiKHecr +eEYaKQDj7NCWLslNnRRh9GmgXcu2pqBhqRM3HAt3cEaHKKWHTcoWcz11pFwMHNtn +bU9GjGRVc3lCGhVNRiloO0zrKHmcBpDVLw2+ycXXpj/RaBW2fy0xRLKolyla+jEr +zdLzVI61O50ZMycOtPmE7DVZpkokn32hGer1eCOFnsN1lywi4cWLvU0jbQC+CJyw +T9vS8zB3WgOl8rC1AHsfQ4KYajlKleQm89deurQymnt/Qx49SiQA+TpwG9Xvx2TP +3Vc1NwZfM9ZZ1+6xit/rTuS3LhnmhEnGnV5ZyvAdmkCcV2iHjOnLnQWWQn24MHU3 +8Y9D4AdpI5V7Igwr3vH2NZMiw1W2Yc5EJuPAT8nIs5sgOYhXB/QLPJvulvOQhuNC +NPwJ6A505JrVNfHuEaoGUyA+mPeWuLwQo8y8cM6ZdFMG3RrwFNzuYTrc1Z/9GsmA +C0UfHf5dL0r7oWZ1SbpSvsmHYqc8sIypq0ohuLEbpegS/hWP8b2/XDRTjfTiJOrM +4LsUH9PMOJSxDlwS+7e3FdcGfgXfsMgB3aOjQvNpKEolOuv4A5LVFeMrrwtw4Xo1 +EuhstZwyarUTJenDUXzkakhA+8Yw/g2a7RsnANVTkeBuv2PbqFL4zdlsWvcpkz41 +ESxx1siSeU1E9beOII0zSi8vUD0IAevRHaWSlfU2po600IzX1FN97pa4DJV2ycgn +-----END RSA PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-cert.p12 b/libnm-core/tests/certs/test-cert.p12 new file mode 100644 index 00000000..ae4a6830 --- /dev/null +++ b/libnm-core/tests/certs/test-cert.p12 Binary files differdiff --git a/libnm-core/tests/certs/test-key-only-decrypted.der b/libnm-core/tests/certs/test-key-only-decrypted.der new file mode 100644 index 00000000..c8652537 --- /dev/null +++ b/libnm-core/tests/certs/test-key-only-decrypted.der Binary files differdiff --git a/libnm-core/tests/certs/test-key-only-decrypted.pem b/libnm-core/tests/certs/test-key-only-decrypted.pem new file mode 100644 index 00000000..1a25da5e --- /dev/null +++ b/libnm-core/tests/certs/test-key-only-decrypted.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAztLp+/SkzmaHzIst0sO4+r7qUwiVnidKBHgxoTbS5UL1dvck +cbjTEP23V4ZoKQIb6ZMrr8B+PVgWNBAlhX4oLUL8NH/WTwrntrlAUcjliWDNc1Fj +Z+FZNjFe0IdLXZeKQiLTQvKDYnmERVvYIJfi0TQjXuy/ikF8rYBQ85scUV3kKRzB +xnyhAHAP9nl3AyL1S6t2yiCr4U5TbIZo6dYPbpVLtbXP02zUc9vAPR0gIHKrPiW7 +P81fLXf91wuo6wxzwD90JxdWzzGaqe3BOSfHqul3SPRtVok1XHlb9i+Mn5O8ExzQ +dF8wGxVDcY7/Gt9lZWnCilqrBEqA3iApjUgcgwIDAQABAoIBAQC77HCmepf04ryp +Yhz00NoXG7mWUMqBtXlPrlaKAWKG5dxbiBwZKLK/UYlxgbLK8BuklBCx1Nnfq1Yh +YDp3nTWsSp0WpsF3eJUqNhD3Pu8xcD+9dEo6bUu+LgXUu9oC5Fq/1RzYS7qNk5RX +4Sf0FY4GQLWS3tL7MJ20mE71yg5k7qRbDydOyhTh1m1CpRYONWxSsWVLM8KGRDJp +iF0cdPfD5yoPFpgDk8gwzrnXJH2Wqzv8GvyYykRK5AW7tE50y0rTAM42WZ7YS6aZ +FNMmtYxeyzXLY3LgPP0uko5anz3OXRcqCfHfFANG0y7B9MehbrjMgI6S1BbzFl07 +V1zVQVqhAoGBAPIfrWMlh1fHlRh4iRGXK2Hvxyv2oNz9KvQ4qRaLV9ejRDzdt7Pi +/utbi5LGBuDw9016nXM3I77b6PukHzsHFnWGRnyRSbkMMt6mE17nggmNqcpFWfE8 +E7HcKMhk4gbuo5AHD3Ee1Gac2AUDnzYiE+sS6WI3O9d77cc5ych5jZ+nAoGBANqt +VZCttjY0E+hEyTP37eaE8u0jfdK8AflTJlNUHWKXglES525iu8I/Bso8KaQYsYF3 +SezGRd3KQepQhtMjFKfSpF+tbnboP57Y3XGo8xhbxqV4kRX+XGsVoW3Vg2nPKBrR ++dIY5nMwua+gkHWp9RDcemD2reiIZBVx95fK8dfFAoGAdCSH2pBs/MlrFqLzNTHr +iH4pb0hN39O9YAsx6POMfo79s6izbyHLIID4Ub6WHB7ashrIHjVr+yin+NXAeWMr +/dIcS7Kxx4c3e5/0mMi6kvSWZsWfoF0uIVo3YfEqjyK36OXKHXwpbNN9t+IF5ESy +g0e+FfPiy7nR1Ig+5+CO8+8CgYEAp/75+Ug677FaidouaMpT7gC9UAkwJLFjItQK +YYIBgTi8WOSY/2jCrhwVb1CA/RwrYjbuiARasGUt9oEe0x3kRHnC5e4rKxaJqdMZ +bLRK7a+0EHNrouXiwjG/7s1VQ/ht6wzdS9btVBlezdogoQSMzQNU0SExwa7mlMMV +X3v+B7ECgYAK+Yt4jnLH1LNWoDTU0Ug5hyXsQXV8lVBSnrkvS7GtP6ZA/4OqG7lJ +/bTYFZGoiAGzOnC+YlAqSIu45CEnpr2xBsThQiWUVxspmQD1lEWWFcd77DPUwn3C +59pLgx0AqJE3n6lBOwehiXbFKBdVzX8PfPZpuCK6qc/RiTILktwURA== +-----END RSA PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-key-only.pem b/libnm-core/tests/certs/test-key-only.pem new file mode 100644 index 00000000..5ef530e9 --- /dev/null +++ b/libnm-core/tests/certs/test-key-only.pem @@ -0,0 +1,92 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----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=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e + diff --git a/libnm-core/tests/certs/test2-cert.p12 b/libnm-core/tests/certs/test2-cert.p12 new file mode 100644 index 00000000..9d5732b0 --- /dev/null +++ b/libnm-core/tests/certs/test2-cert.p12 Binary files differdiff --git a/libnm-core/tests/certs/test2_ca_cert.pem b/libnm-core/tests/certs/test2_ca_cert.pem new file mode 100644 index 00000000..9a487ca4 --- /dev/null +++ b/libnm-core/tests/certs/test2_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCA4ygAwIBAgIJANDnVhixAO1GMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD +VQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czERMA8GA1UEBxMIV2VzdGZv +cmQxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5n +MRAwDgYDVQQDEwdlYXB0ZXN0MRgwFgYJKoZIhvcNAQkBFglpdEBpdC5jb20wHhcN +MDcxMTA5MTU0ODI1WhcNMTcxMTA2MTU0ODI1WjCBkjELMAkGA1UEBhMCVVMxFjAU +BgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQK +Ew1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMH +ZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAz9zRLSiQyQangDgEliEP8xSpnPJS7GjXzrkZS3sk +gZLuVuwoFeZRq3Hsrq/wGd/vM0KUFNmEaMc+47jnuv0UHQcQ45ZACO7s4/Aflhzj +lkmud/z06hVknIzjXmvS6q2ttCviHsXnfokl+wAxuUhsd+le0xjP9H1jXny4YBuS +jP+yGUz7PL4w1sFFghKIPrlB7m4GkFbQRqvH7FSJg86GWopPwJvNvIzhOZiO1a1D +CAAL4Ru3jxtNFxqWT87C/qUEe/2Qb7jtNyqFcKfwZyZh4u1bo0c8bjErlUZERbWz +zM3hTFypuw+i2v+0h3A8/Xb0hTjcHkUoJgfSdbsOLC5TOwIDAQABo4H6MIH3MB0G +A1UdDgQWBBR+UOaH4e8nrEuMcEXJl7UN5r/wDTCBxwYDVR0jBIG/MIG8gBR+UOaH +4e8nrEuMcEXJl7UN5r/wDaGBmKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgT +DU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQg +SGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVz +dDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tggkA0OdWGLEA7UYwDAYDVR0TBAUw +AwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAmE2jqUymfxN2Vv7bPafoK/EpZwGPxu+z +phRFsgUgWVzidc/GtOxN81LduJ+ow8MEbQIabo4JV/MdKzuPuhAHToAQdeb0LIWa +p59vTIZiVhUt0cMAbQwKcTnfmDnXw9wytvtKgeAXJq0Jd6F+uNXTiR1btlYLZqmF +oSu54cHQlXpUT9z0BnQ8eXd7m0TwfzGQkTHQI7xBa87lZDAkJaTlhv7fR5vPmJYY +0LiXii71ce+4hxdlp7hQfwQ2sb8FPY3RlVboTRD0CvGaWypWhdSZnS790dBXgZOs +NCge6NGuHzW5LtiZE9ppuv8qJysVcIFdAqt8dkx58ksOqFcARCerXw== +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test2_key_and_cert.pem b/libnm-core/tests/certs/test2_key_and_cert.pem new file mode 100644 index 00000000..a668596e --- /dev/null +++ b/libnm-core/tests/certs/test2_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,5FA2D6D6242C26D0 + +dyNdbh115sczbUEhiaGYJ6fazyvJss5thPFEmkP6aftYlvXY6vPtc++xFCCktiSd +qFVEyi6oDyV4iGPmX7pCJ0e+pSI6uFNXKFtxh5/+/wXZcOEMCvfu7w2IrvYF2LHY +qJDljcISSRxeINuYO7TETD5fLLRKj2X9vwwkwVN02b2N5jsrm6Bt//WbatqSB3ln +FHyQhVKkvdl9Hr1XNmEfgGfZSxxDoPu1DjhtZ5ja2LZj64C2CXdI0oq2wcAVvQNn +rZeeg9sinQJkz9rwsNaWqlYw4X+YD2JRSwZuvwkWRydYMwgb1XS/jCxtuFF8NXWP +RBAOAZZUy7onzohsJHVVa05wCKQ4klo+PEfI3vn7BeuHyciCc0eFqGRvz8eFDybH +ZdPbU/3vGp+mOB7gd27TptttTCQQy9uM5CIyovNSYsAIw1Z583Ea4q8eXgzkgD6D +isCqkGXMfPbNXU3myQGDnQwWRi2CqX+rXM8PJUhdewLAlmHRz/aYSuql2BRixJKx +eASzmFBYdAjrvafda5D+xTyJwXEwdq/HlqMK9cY28ZbNrzA2Kor2X23EKC1+VG8k +B67OsfUhW27j4u6aV5JdLf87OtF3mHFRR+Lzs7i7LYvJ8ACE+jiIi7PboZjK5Oiv +JqTK0BwDaeNYjkd6jiJh8It/ReMbLk65J3eldOklN0VMPYiqcQnHvSPC2DD1YAy+ +Rv/JVj6TvzvgEAj+hgH6MAAF6u3ARj6+10DlvhUubkOC5RztLKReu8B+427TuuDb +T03gFpHD6X9IqSiq/QfYFyHFojCVSrv6wDZOcHc1s71kpJ8R14YIVe+DrrZN/0D4 +M631jdNg3JARMZXcXTHrghGIdPmOtrsRyTTRZuGoVup/DW9MRzOzCTMSNCX8T+eq +13HMSNQEO9lMwy0sYeO5c7sjHY4K1ubZuVE1mvXq4JLz3YxXJIvgp8TUvqDnAsK+ +Fv63bDoTg5Tq63XvnaKc7Lawneyg5ZAMzPN3nM0/1EZcn/2ICI5c4Yepc5t63EI5 +KytuXx86Mcx234enj3uMeuM22POQ1SnKOef6dFzK/CE8J8eUEY/aDhX4eBl/s3nd +U4+aaFKYz3HTazePayt2SC6rP/KKMmS14q59bOQA1DiWxCvmA2ypRyP87fV5DstH +I53RD5xp1P38iaO8U/divD0W2dkv748s9DQqYrHPtWALT9esxNU07CgB8Zt070si +7pzjQ8FDCZ8ygDmwWGNSBz1nA90Cpd6gAFDrep7HAtDE4qgNfokycpaJZkXBei/U +tC4tWYRbqDEsEbeBHvQRJzzqWzk9e/P4fQoelM3aryKzKLG5z7KvywVifKMLECQ+ +tIpzoRp06nuTA/O+iLFdkCy3JEWszfvvOwTwtIIV6+3s8TU0k9MmzEe3rGL+QqT/ +Tf+9/dN5LK+LWyc99BfmCOrBuFtQmHyEXkfe6EuFYEwj0B2ZfnLCon6cdRujjK7H +IJslC1B/cBVqG3KCrbBzjeygKfJ5Ijo72oXZJOCFTLeJefZKGGWJCp9nG9h9Wrcf +fEN/mj3wBvTa90/PYFj9NuaBtrvMF8Rn9XDeYPq2JGL8YkNdPuO8A+2Yko8wcvST +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Massachusetts, L=Westford, O=Red Hat, Inc., OU=Engineering, CN=eaptest/emailAddress=it@it.com + Validity + Not Before: Nov 9 15:50:14 2007 GMT + Not After : Nov 6 15:50:14 2017 GMT + Subject: C=US, ST=Massachusetts, O=Red Hat, Inc., OU=Engineering, CN=client/emailAddress=it@it.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:b0:8f:4f:1c:93:d4:43:e7:87:b7:22:33:55:a8: + 35:a1:c4:01:b0:f1:ed:26:23:96:ab:65:c2:c2:54: + db:79:22:03:ad:3f:6f:22:e3:63:3f:f4:21:6d:fa: + 88:c8:8f:1a:ce:55:49:7c:98:33:6a:67:8a:8d:d9: + 34:b0:c3:42:f4:72:a4:45:43:05:72:5d:0c:d3:42: + f8:9c:66:3b:b8:f8:77:ea:f6:b6:94:d7:cc:5d:62: + 34:2a:14:48:0a:bc:65:94:f5:7a:63:98:6c:88:4c: + 25:d8:95:f1:40:3d:00:d2:fb:43:28:fa:02:fb:2c: + 80:b3:e1:33:e7:8c:ce:8a:a0:1b:3d:04:4d:bc:a1: + b6:a2:42:8b:8e:f3:5b:4a:72:34:7d:8d:ba:d8:46: + 22:35:da:5c:f8:dd:fc:6d:9e:59:22:b7:6b:e7:78: + 56:54:9f:4c:d1:e2:4a:23:a3:bc:04:ea:46:6b:70: + 8a:fb:fe:8a:73:ca:36:d5:f3:e9:17:e3:22:d5:b3: + 70:05:e7:f7:37:b7:21:b5:90:53:27:27:ea:36:9b: + 00:ff:35:b0:66:3d:dc:a9:2f:95:d2:21:18:98:4f: + 28:07:09:70:20:a8:b1:82:aa:a5:df:ae:0f:e3:36: + be:68:8c:9e:80:d3:33:d0:f5:84:17:d9:0f:eb:9d: + af:0b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 71:AB:BB:91:B7:04:DE:43:35:36:07:8A:35:CA:BE:5C:3E:EB:B1:09 + X509v3 Authority Key Identifier: + keyid:7E:50:E6:87:E1:EF:27:AC:4B:8C:70:45:C9:97:B5:0D:E6:BF:F0:0D + DirName:/C=US/ST=Massachusetts/L=Westford/O=Red Hat, Inc./OU=Engineering/CN=eaptest/emailAddress=it@it.com + serial:D0:E7:56:18:B1:00:ED:46 + + Signature Algorithm: md5WithRSAEncryption + ce:43:6d:f7:f8:4a:66:fd:8a:2c:41:a6:e0:03:0e:60:30:d4: + 41:01:ba:46:ba:81:97:64:68:83:25:9c:e1:2c:03:8b:2d:ca: + 85:cf:bc:fa:ca:22:c4:59:28:23:8f:ff:50:94:60:1c:90:dd: + 75:f4:d4:ea:8c:fa:61:61:08:35:4a:8f:aa:a7:e9:3d:76:e9: + 08:28:55:01:c4:03:42:c7:ad:58:bb:ee:94:f7:09:b3:9a:9b: + 8b:d0:25:95:18:a6:22:d5:2c:fc:b7:bb:91:0c:7c:03:7f:9b: + 85:de:b0:e4:95:a8:73:94:27:0a:11:4e:e3:67:ae:2b:cc:e7: + 51:29:10:23:57:5c:3e:e7:ea:47:e0:f0:8f:5b:a2:9f:26:cf: + 7f:b5:7c:44:b1:7b:83:67:3c:41:ae:c6:66:64:e0:d2:ef:57: + a4:5c:1b:94:11:ce:28:e5:91:51:ef:e1:98:b7:3b:9a:cc:f7: + b9:85:76:eb:a8:2b:15:4a:cc:1a:a3:42:fa:be:1c:ce:b8:eb: + ee:12:d7:2f:e4:a8:cf:eb:2a:8f:78:e8:91:88:fa:c2:98:75: + 6a:4c:92:3f:2e:0d:e1:20:39:36:c6:2c:be:67:30:c3:f3:c3: + 65:81:ac:e3:3c:19:6a:21:ee:ea:f5:22:66:74:b2:07:53:7c: + 9a:0c:24:a6 +-----BEGIN CERTIFICATE----- +MIIEtDCCA5ygAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UE +AxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMB4XDTA3MTEwOTE1 +NTAxNFoXDTE3MTEwNjE1NTAxNFowfjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1h +c3NhY2h1c2V0dHMxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0Vu +Z2luZWVyaW5nMQ8wDQYDVQQDEwZjbGllbnQxGDAWBgkqhkiG9w0BCQEWCWl0QGl0 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCPTxyT1EPnh7ci +M1WoNaHEAbDx7SYjlqtlwsJU23kiA60/byLjYz/0IW36iMiPGs5VSXyYM2pnio3Z +NLDDQvRypEVDBXJdDNNC+JxmO7j4d+r2tpTXzF1iNCoUSAq8ZZT1emOYbIhMJdiV +8UA9ANL7Qyj6AvssgLPhM+eMzoqgGz0ETbyhtqJCi47zW0pyNH2NuthGIjXaXPjd +/G2eWSK3a+d4VlSfTNHiSiOjvATqRmtwivv+inPKNtXz6RfjItWzcAXn9ze3IbWQ +Uycn6jabAP81sGY93KkvldIhGJhPKAcJcCCosYKqpd+uD+M2vmiMnoDTM9D1hBfZ +D+udrwsCAwEAAaOCASYwggEiMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w +ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRxq7uRtwTeQzU2 +B4o1yr5cPuuxCTCBxwYDVR0jBIG/MIG8gBR+UOaH4e8nrEuMcEXJl7UN5r/wDaGB +mKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAP +BgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQL +EwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJ +aXRAaXQuY29tggkA0OdWGLEA7UYwDQYJKoZIhvcNAQEEBQADggEBAM5Dbff4Smb9 +iixBpuADDmAw1EEBuka6gZdkaIMlnOEsA4styoXPvPrKIsRZKCOP/1CUYByQ3XX0 +1OqM+mFhCDVKj6qn6T126QgoVQHEA0LHrVi77pT3CbOam4vQJZUYpiLVLPy3u5EM +fAN/m4XesOSVqHOUJwoRTuNnrivM51EpECNXXD7n6kfg8I9bop8mz3+1fESxe4Nn +PEGuxmZk4NLvV6RcG5QRzijlkVHv4Zi3O5rM97mFduuoKxVKzBqjQvq+HM646+4S +1y/kqM/rKo946JGI+sKYdWpMkj8uDeEgOTbGLL5nMMPzw2WBrOM8GWoh7ur1ImZ0 +sgdTfJoMJKY= +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test_ca_cert.der b/libnm-core/tests/certs/test_ca_cert.der new file mode 100644 index 00000000..e844f65b --- /dev/null +++ b/libnm-core/tests/certs/test_ca_cert.der Binary files differdiff --git a/libnm-core/tests/certs/test_ca_cert.pem b/libnm-core/tests/certs/test_ca_cert.pem new file mode 100644 index 00000000..faa3fc29 --- /dev/null +++ b/libnm-core/tests/certs/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEhjCCA26gAwIBAgIJAOZMXJYmXtbQMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxME +dGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAyMDIwMjIx +NTJaFw0xOTAxMzEwMjIxNTJaMIGIMQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVy +a3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0 +ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3DQEJARYN +dGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZz +iHfFR6Gqdz5Gq1elSaf7J2tznfialPyMkRoqngSItrM3JWlkfBu3ZIpGSYG8+Z8H +JjaKh/zkCCH73HcjADCocm/XtgxlOlccDtBvfDqifb2dBikcmcfh0tX0o4JU9L+z +WP7sVcUkJG7C5811lA5pAsLVooJxrZnrta6XstGvFgTSxI2Y4Jowf0syM5b/AHIQ ++htsVhSyj1DWM9day3QsEMZl55SCxCLTB6ZIJLF6NmTYwdnzWWTQf4k7kcptZJU8 +Fqv60b/ATvvUf7S+ZMGLopFIIlmc1Kkn7VTseIKy4ycYuDpyimQy3Yw4flC00vhl +hTijH+5dlVOUFrRh0bsCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUUjMuImZ5guVBLo07 +suXM+r6ZM44wgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6ZM46hgY6k +gYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcT +B05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQLEwR0ZXN0 +MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA +5kxcliZe1tAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAZsWzGp9D +10NWf8ts3A9mhcEb8oDgKNpCOZF9gqr2usZygJjY9MX2n0n81T8XaWDk1wZLlcDW +hzIalCY8rpE57Dj3MEmdCmYr3BrAy6GVlc/MO7ffTHxogl9ouScSYo8ETTtNMKCg +zwkDnXjGzmb1e59DIXMVHBBbTmJXJbM8XP9A2azJkVUyE2fSdWksXMP0XklGbW2p +DksJ+8G1IWkyRhnINV5GZLLNAT5gBA6sUv/iqQKwk8r2dsweMPtLoLWZPAaZErYh +sthGy00Q0GJkmkJpQl8QIlPq5vylNcMUhvc8tmzwk+rDVUj3jTJWqFwMtnHAaNyC +FXl9ynWpe5J28w== +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test_key_and_cert.pem b/libnm-core/tests/certs/test_key_and_cert.pem new file mode 100644 index 00000000..c00495d0 --- /dev/null +++ b/libnm-core/tests/certs/test_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----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=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e +-----BEGIN CERTIFICATE----- +MIIErjCCA5agAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxHDAa +BgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMjAyMDIyMjI1WhcNMTkw +MTMxMDIyMjI1WjCBizELMAkGA1UEBhMCVVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEX +MBUGA1UEChMOTXkgQ29tcGFueSBMdGQxFDASBgNVBAsTC3Rlc3QtY2xpZW50MRQw +EgYDVQQDEwt0ZXN0LWNsaWVudDEjMCEGCSqGSIb3DQEJARYUdGVzdC1jbGllbnRA +dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO0un79KTO +ZofMiy3Sw7j6vupTCJWeJ0oEeDGhNtLlQvV29yRxuNMQ/bdXhmgpAhvpkyuvwH49 +WBY0ECWFfigtQvw0f9ZPCue2uUBRyOWJYM1zUWNn4Vk2MV7Qh0tdl4pCItNC8oNi +eYRFW9ggl+LRNCNe7L+KQXytgFDzmxxRXeQpHMHGfKEAcA/2eXcDIvVLq3bKIKvh +TlNshmjp1g9ulUu1tc/TbNRz28A9HSAgcqs+Jbs/zV8td/3XC6jrDHPAP3QnF1bP +MZqp7cE5J8eq6XdI9G1WiTVceVv2L4yfk7wTHNB0XzAbFUNxjv8a32VlacKKWqsE +SoDeICmNSByDAgMBAAGjggEcMIIBGDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf +Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNOlc2PzH +r/dd9BPTghrNUg9Kuwswgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6Z +M46hgY6kgYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQL +EwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qu +Y29tggkA5kxcliZe1tAwDQYJKoZIhvcNAQEEBQADggEBAIjE3cVKpo4fNmKAMWsr +hTQNbKfc4Vo83XRX21m+i/J5QC29m+GrDgN1IHUv6pf51H4VdcKC9bE35Isk1O8C +OxlqVrufw6W0xDmgZJZbw6gZdOwLzzPf8xLz4qsdfd4hZM2xoG96d4TUYopQ5nZd +rzrvGocOGjjE+Q0vFOAgMkwucNJxgtXlyRMsTrTIY2UdSOjDVm2IhFdlEx5CSLQD +JXFOEp0aiGXVcSE7Dr43HPCIa0UMDmzlYMuGv79AMMTPlPgcYNQb34gCekV+0cbz +B7mxjypVL753n9FGZAW3Z8WyrIxCj2pRpA0rFqTWOaX4Je1oJRO1Gaxs6ezuA2uA +OG4= +-----END CERTIFICATE----- diff --git a/libnm-core/tests/test-compare.c b/libnm-core/tests/test-compare.c new file mode 100644 index 00000000..12db9c23 --- /dev/null +++ b/libnm-core/tests/test-compare.c @@ -0,0 +1,248 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include "nm-glib-compat.h" + +#include "nm-property-compare.h" + +#include "nm-test-utils.h" + +static void +compare_ints (void) +{ + GVariant *value1, *value2; + + value1 = g_variant_new_int32 (5); + value2 = g_variant_new_int32 (5); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_int32 (10); + g_assert (nm_property_compare (value1, value2) < 0); + + g_variant_unref (value2); + value2 = g_variant_new_int32 (-1); + g_assert (nm_property_compare (value1, value2) > 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_strings (void) +{ + GVariant *value1, *value2; + const char *str1 = "hello"; + const char *str2 = "world"; + + value1 = g_variant_new_string (str1); + value2 = g_variant_new_string (str1); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_string (str2); + g_assert (nm_property_compare (value1, value2) < 0); + + g_assert (nm_property_compare (value2, value1) > 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_strv (void) +{ + GVariant *value1, *value2; + const char * const strv1[] = { "foo", "bar", "baz", NULL }; + const char * const strv2[] = { "foo", "bar", "bar", NULL }; + const char * const strv3[] = { "foo", "bar", NULL }; + const char * const strv4[] = { "foo", "bar", "baz", "bam", NULL }; + + value1 = g_variant_new_strv (strv1, -1); + value2 = g_variant_new_strv (strv1, -1); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv2, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv3, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv4, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_arrays (void) +{ + GVariant *value1, *value2; + guint32 array[] = { 0, 1, 2, 3, 4 }; + + value1 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array + 1, G_N_ELEMENTS (array) - 1, + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); + + array[0] = 7; + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_str_hash (void) +{ + GVariant *value1, *value2; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value1 = g_variant_builder_end (&builder); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) != 0); + g_assert (nm_property_compare (value2, value1) != 0); + + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "moon"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_ip6_addresses (void) +{ + GVariant *value1, *value2; + struct in6_addr addr1; + struct in6_addr addr2; + struct in6_addr addr3; + guint32 prefix1 = 64; + guint32 prefix2 = 64; + guint32 prefix3 = 0; + + inet_pton (AF_INET6, "1:2:3:4:5:6:7:8", &addr1); + inet_pton (AF_INET6, "ffff:2:3:4:5:6:7:8", &addr2); + inet_pton (AF_INET6, "::", &addr3); + + value1 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr2.s6_addr, 16, 1), + prefix2, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1), + prefix3, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +NMTST_DEFINE (); + +int +main (int argc, char *argv[]) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_func ("/libnm/compare/ints", compare_ints); + g_test_add_func ("/libnm/compare/strings", compare_strings); + g_test_add_func ("/libnm/compare/strv", compare_strv); + g_test_add_func ("/libnm/compare/arrays", compare_arrays); + g_test_add_func ("/libnm/compare/str_hash", compare_str_hash); + g_test_add_func ("/libnm/compare/ip6_addresses", compare_ip6_addresses); + + return g_test_run (); +} diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c new file mode 100644 index 00000000..1c8ae477 --- /dev/null +++ b/libnm-core/tests/test-crypto.c @@ -0,0 +1,501 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * Dan Williams <dcbw@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include <unistd.h> +#include <stdlib.h> +#include <glib/gi18n.h> +#include <stdio.h> +#include <string.h> + +#include "crypto.h" +#include "nm-utils.h" +#include "nm-errors.h" +#include "nm-core-internal.h" + +#include "nm-test-utils.h" + +#if 0 +static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; +static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; + +static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; +static const char *pem_dsa_key_end = "-----END DSA PRIVATE KEY-----"; + +static void +dump_key_to_pem (const char *key, gsize key_len, int key_type) +{ + char *b64 = NULL; + GString *str = NULL; + const char *start_tag; + const char *end_tag; + char *p; + + switch (key_type) { + case NM_CRYPTO_KEY_TYPE_RSA: + start_tag = pem_rsa_key_begin; + end_tag = pem_rsa_key_end; + break; + case NM_CRYPTO_KEY_TYPE_DSA: + start_tag = pem_dsa_key_begin; + end_tag = pem_dsa_key_end; + break; + default: + g_warning ("Unknown key type %d", key_type); + return; + } + + b64 = g_base64_encode ((const unsigned char *) key, key_len); + if (!b64) { + g_warning ("Couldn't base64 encode the key."); + goto out; + } + + str = g_string_new (NULL); + + g_string_append (str, start_tag); + g_string_append_c (str, '\n'); + + for (p = b64; p < (b64 + strlen (b64)); p += 64) { + g_string_append_len (str, p, strnlen (p, 64)); + g_string_append_c (str, '\n'); + } + + g_string_append (str, end_tag); + g_string_append_c (str, '\n'); + + g_message ("Decrypted private key:\n\n%s", str->str); + +out: + g_free (b64); + if (str) + g_string_free (str, TRUE); +} +#endif + +static void +test_cert (gconstpointer test_data) +{ + char *path; + GByteArray *array; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GError *error = NULL; + + path = g_build_filename (TEST_CERT_DIR, (const char *) test_data, NULL); + + array = crypto_load_and_verify_certificate (path, &format, &error); + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_X509); + + g_byte_array_free (array, TRUE); + + g_assert (nm_utils_file_is_certificate (path)); +} + +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); + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + g_free (contents); + } + return array; +} + +static void +test_load_private_key (const char *path, + const char *password, + const char *decrypted_path, + int expected_error) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + gboolean is_encrypted = FALSE; + GByteArray *array, *decrypted; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, &is_encrypted)); + g_assert (is_encrypted); + + array = crypto_decrypt_openssl_private_key (path, password, &key_type, &error); + /* Even if the password is wrong, we should determine the key type */ + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + if (expected_error != -1) { + g_assert (array == NULL); + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_clear_error (&error); + return; + } + + if (password == NULL) { + g_assert (array == NULL); + g_assert_no_error (error); + return; + } + + g_assert (array != NULL); + + if (decrypted_path) { + /* Compare the crypto decrypted key against a known-good decryption */ + decrypted = file_to_byte_array (decrypted_path); + g_assert (decrypted != NULL); + g_assert (decrypted->len == array->len); + g_assert (memcmp (decrypted->data, array->data, array->len) == 0); + + g_byte_array_free (decrypted, TRUE); + } + + g_byte_array_free (array, TRUE); +} + +static void +test_load_pkcs12 (const char *path, + const char *password, + int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + format = crypto_verify_private_key (path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error (&error); + } else { + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert (is_encrypted); + } +} + +static void +test_load_pkcs12_no_password (const char *path) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + /* We should still get a valid returned crypto file format */ + format = crypto_verify_private_key (path, NULL, &is_encrypted, &error); + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert (is_encrypted); +} + +static void +test_is_pkcs12 (const char *path, gboolean expect_fail) +{ + gboolean is_pkcs12; + GError *error = NULL; + + is_pkcs12 = crypto_is_pkcs12_file (path, &error); + + if (expect_fail) { + g_assert_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_INVALID_DATA); + g_assert (!is_pkcs12); + } else { + g_assert_no_error (error); + g_assert (is_pkcs12); + } +} + +static void +test_load_pkcs8 (const char *path, + const char *password, + int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + format = crypto_verify_private_key (path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error (&error); + } else { + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_RAW_KEY); + g_assert (is_encrypted); + } +} + +static void +test_encrypt_private_key (const char *path, + const char *password) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + GByteArray *array, *encrypted, *re_decrypted; + GError *error = NULL; + + array = crypto_decrypt_openssl_private_key (path, password, &key_type, &error); + g_assert_no_error (error); + g_assert (array != NULL); + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Now re-encrypt the private key */ + encrypted = nm_utils_rsa_key_encrypt (array->data, array->len, password, NULL, &error); + g_assert_no_error (error); + g_assert (encrypted != NULL); + + /* Then re-decrypt the private key */ + key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + re_decrypted = crypto_decrypt_openssl_private_key_data (encrypted->data, encrypted->len, + password, &key_type, &error); + g_assert_no_error (error); + g_assert (re_decrypted != NULL); + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Compare the original decrypted key with the re-decrypted key */ + g_assert_cmpint (array->len, ==, re_decrypted->len); + g_assert (!memcmp (array->data, re_decrypted->data, array->len)); + + g_byte_array_free (re_decrypted, TRUE); + g_byte_array_free (encrypted, TRUE); + g_byte_array_free (array, TRUE); +} + +static void +test_key (gconstpointer test_data) +{ + char **parts, *path, *password, *decrypted_path; + int len; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + len = g_strv_length (parts); + if (len != 2 && len != 3) + g_error ("wrong number of arguments (<key file>, <password>, [<decrypted key file>])"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + decrypted_path = parts[2] ? g_build_filename (TEST_CERT_DIR, parts[2], NULL) : NULL; + + test_is_pkcs12 (path, TRUE); + test_load_private_key (path, password, decrypted_path, -1); + test_load_private_key (path, "blahblahblah", NULL, NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_private_key (path, NULL, NULL, -1); + test_encrypt_private_key (path, password); + + g_free (path); + g_free (decrypted_path); + g_strfreev (parts); +} + +static void +test_key_decrypted (gconstpointer test_data) +{ + const char *file = (const char *) test_data; + gboolean is_encrypted = FALSE; + char *path; + + path = g_build_filename (TEST_CERT_DIR, file, NULL); + + g_assert (nm_utils_file_is_private_key (path, &is_encrypted)); + g_assert (!is_encrypted); + + g_free (path); +} + +static void +test_pkcs12 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + if (g_strv_length (parts) != 2) + g_error ("wrong number of arguments (<file>, <password>)"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, FALSE); + test_load_pkcs12 (path, password, -1); + test_load_pkcs12 (path, "blahblahblah", NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_pkcs12_no_password (path); + + g_free (path); + g_strfreev (parts); +} + +static void +test_pkcs8 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + if (g_strv_length (parts) != 2) + g_error ("wrong number of arguments (<file>, <password>)"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, TRUE); + test_load_pkcs8 (path, password, -1); + /* Until gnutls and NSS grow support for all the ciphers that openssl + * can use with PKCS#8, we can't actually verify the password. So we + * expect a bad password to work for the time being. + */ + test_load_pkcs8 (path, "blahblahblah", -1); + + g_free (path); + g_strfreev (parts); +} + +#define SALT "sodium chloride" +#define SHORT_PASSWORD "short" +#define LONG_PASSWORD "this is a longer password than the short one" +#define SHORT_DIGEST 16 +#define LONG_DIGEST 57 + +struct { + const char *salt, *password; + gsize digest_size; + const char *result; +} md5_tests[] = { + { NULL, SHORT_PASSWORD, SHORT_DIGEST, + "4f09daa9d95bcb166a302407a0e0babe" }, + { NULL, SHORT_PASSWORD, LONG_DIGEST, + "4f09daa9d95bcb166a302407a0e0babeb7d62e5baf706830d007c253f0fe7584ad7e92dc00a599ec277293c298ae70ee3904c348e23be61c91" }, + { SALT, SHORT_PASSWORD, SHORT_DIGEST, + "774771f7292210233b5724991d1f9894" }, + { SALT, SHORT_PASSWORD, LONG_DIGEST, + "774771f7292210233b5724991d1f98941a6ffdb45e4dc7fa04b1fa6aceed379c1ade0577bc8f261d109942ed5736921c052664d72e0d5bade9" }, + { NULL, LONG_PASSWORD, SHORT_DIGEST, + "e9c03517f81ff29bb777dac21fb1699c" }, + { NULL, LONG_PASSWORD, LONG_DIGEST, + "e9c03517f81ff29bb777dac21fb1699c50968c7ccd8db4f0a59d00ffd87b05876d45f25a927d51a8400c35af60fbd64584349a8b7435d62fd9" }, + { SALT, LONG_PASSWORD, SHORT_DIGEST, + "4e5c076e2f85f5e03994acbf3a9e10d6" }, + { SALT, LONG_PASSWORD, LONG_DIGEST, + "4e5c076e2f85f5e03994acbf3a9e10d61a6969c9fdf47ae8b1f7e2725b3767b05cc974bfcb5344b630c91761e015e09d7794b5065662533bc9" }, + { NULL, "", SHORT_DIGEST, + "d41d8cd98f00b204e9800998ecf8427e" }, + { SALT, "", SHORT_DIGEST, + "7df1e0494c977195005d82a1809685e4" }, +}; + +static void +test_md5 (void) +{ + char digest[LONG_DIGEST], *hex; + int i; + + for (i = 0; i < G_N_ELEMENTS (md5_tests); i++) { + memset (digest, 0, sizeof (digest)); + crypto_md5_hash (md5_tests[i].salt, + /* crypto_md5_hash() used to clamp salt_len to 8. It + * doesn't any more, so we need to do it here now to + * get output that matches md5_tests[i].result. + */ + md5_tests[i].salt ? 8 : 0, + md5_tests[i].password, + strlen (md5_tests[i].password), + digest, md5_tests[i].digest_size); + + hex = nm_utils_bin2hexstr (digest, md5_tests[i].digest_size, -1); + g_assert_cmpstr (hex, ==, md5_tests[i].result); + g_free (hex); + } +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + GError *error = NULL; + int ret; + + nmtst_init (&argc, &argv, TRUE); + + if (!crypto_init (&error)) + FAIL ("crypto-init", "failed to initialize crypto: %s", error->message); + + g_test_add_data_func ("/libnm/crypto/cert/pem", + "test_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-2", + "test2_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/der", + "test_ca_cert.der", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-no-ending-newline", + "ca-no-ending-newline.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined", + "test_key_and_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined-2", + "test2_key_and_cert.pem", + test_cert); + + g_test_add_data_func ("/libnm/crypto/key/padding-6", + "test_key_and_cert.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/key-only", + "test-key-only.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/padding-8", + "test2_key_and_cert.pem, 12345testing", + test_key); + g_test_add_data_func ("/libnm/crypto/key/aes", + "test-aes-key.pem, test-aes-password", + test_key); + g_test_add_data_func ("/libnm/crypto/key/decrypted", + "test-key-only-decrypted.pem", + test_key_decrypted); + + g_test_add_data_func ("/libnm/crypto/PKCS#12/1", + "test-cert.p12, test", + test_pkcs12); + g_test_add_data_func ("/libnm/crypto/PKCS#12/2", + "test2-cert.p12, 12345testing", + test_pkcs12); + + g_test_add_data_func ("/libnm/crypto/PKCS#8", + "pkcs8-enc-key.pem, 1234567890", + test_pkcs8); + + g_test_add_func ("/libnm/crypto/md5", test_md5); + + ret = g_test_run (); + + return ret; +} + diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c new file mode 100644 index 00000000..d309c800 --- /dev/null +++ b/libnm-core/tests/test-general.c @@ -0,0 +1,3961 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include <nm-utils.h> + +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-core-internal.h" + +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-infiniband.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-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-simple-connection.h" + +#include "nm-test-utils.h" + +static void +vpn_check_func (const char *key, const char *value, gpointer user_data) +{ + const char *test = user_data; + + if (!strcmp (key, "foobar1")) { + ASSERT (strcmp (value, "blahblah1") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar2")) { + ASSERT (strcmp (value, "blahblah2") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar3")) { + ASSERT (strcmp (value, "blahblah3") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar4")) { + ASSERT (strcmp (value, "blahblah4") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + ASSERT (FALSE, test, "unexpected vpn item '%s'", key); +} + +static void +vpn_check_empty_func (const char *key, const char *value, gpointer user_data) +{ + const char *test = user_data; + + /* We don't expect any values */ + ASSERT (FALSE, test, "unexpected vpn item '%s'", key); +} + +static void +test_setting_vpn_items (void) +{ + NMSettingVpn *s_vpn; + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-items", + "error creating vpn setting"); + + nm_setting_vpn_add_data_item (s_vpn, "foobar1", "blahblah1"); + nm_setting_vpn_add_data_item (s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_data_item (s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_data_item (s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_func, "vpn-data"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar1"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar2"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar3"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar4"); + + nm_setting_vpn_add_secret (s_vpn, "foobar1", "blahblah1"); + nm_setting_vpn_add_secret (s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_secret (s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_secret (s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_secret (s_vpn, vpn_check_func, "vpn-secrets"); + nm_setting_vpn_remove_secret (s_vpn, "foobar1"); + nm_setting_vpn_remove_secret (s_vpn, "foobar2"); + nm_setting_vpn_remove_secret (s_vpn, "foobar3"); + nm_setting_vpn_remove_secret (s_vpn, "foobar4"); + + /* Try to add some blank values and make sure they are rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, NULL, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*item != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (item) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "foobar1", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1"); + g_test_assert_expected_messages (); + + nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, "vpn-data-empty"); + + /* Try to add some blank secrets and make sure they are rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_secret (s_vpn, NULL, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*secret != NULL*"); + nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (secret) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "foobar1", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "", "blahblah1"); + g_test_assert_expected_messages (); + + nm_setting_vpn_foreach_secret (s_vpn, vpn_check_empty_func, "vpn-secrets-empty"); + + g_object_unref (s_vpn); +} + +static void +test_setting_vpn_update_secrets (void) +{ + NMConnection *connection; + NMSettingVpn *s_vpn; + GVariantBuilder settings_builder, vpn_builder, secrets_builder; + GVariant *settings; + gboolean success; + GError *error = NULL; + const char *tmp; + const char *key1 = "foobar"; + const char *key2 = "blahblah"; + const char *val1 = "value1"; + const char *val2 = "value2"; + + connection = nm_simple_connection_new (); + ASSERT (connection != NULL, + "vpn-update-secrets", + "error creating connection"); + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-update-secrets", + "error creating vpn setting"); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + g_variant_builder_init (&settings_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&vpn_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_init (&secrets_builder, G_VARIANT_TYPE ("a{ss}")); + + g_variant_builder_add (&secrets_builder, "{ss}", key1, val1); + g_variant_builder_add (&secrets_builder, "{ss}", key2, val2); + + g_variant_builder_add (&vpn_builder, "{sv}", + NM_SETTING_VPN_SECRETS, + g_variant_builder_end (&secrets_builder)); + g_variant_builder_add (&settings_builder, "{sa{sv}}", + NM_SETTING_VPN_SETTING_NAME, + &vpn_builder); + settings = g_variant_builder_end (&settings_builder); + + success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error); + ASSERT (success == TRUE, + "vpn-update-secrets", "failed to update VPN secrets: %s", error->message); + + /* Read the secrets back out */ + tmp = nm_setting_vpn_get_secret (s_vpn, key1); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #1"); + ASSERT (strcmp (tmp, val1) == 0, + "vpn-update-secrets", "unexpected key #1 value"); + + tmp = nm_setting_vpn_get_secret (s_vpn, key2); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #2"); + ASSERT (strcmp (tmp, val2) == 0, + "vpn-update-secrets", "unexpected key #2 value"); + + g_variant_unref (settings); + g_object_unref (connection); +} + +#define TO_DEL_NUM 50 +typedef struct { + NMSettingVpn *s_vpn; + char *to_del[TO_DEL_NUM]; + guint called; +} IterInfo; + +static void +del_iter_func (const char *key, const char *value, gpointer user_data) +{ + IterInfo *info = user_data; + int i; + + /* Record how many times this function gets called; it should get called + * exactly as many times as there are keys in the hash table, regardless + * of what keys we delete from the table. + */ + info->called++; + + /* During the iteration, remove a bunch of stuff from the table */ + if (info->called == 1) { + for (i = 0; i < TO_DEL_NUM; i++) + nm_setting_vpn_remove_data_item (info->s_vpn, info->to_del[i]); + } +} + +static void +test_setting_vpn_modify_during_foreach (void) +{ + NMSettingVpn *s_vpn; + IterInfo info; + char *key, *val; + int i, u = 0; + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + g_assert (s_vpn); + + for (i = 0; i < TO_DEL_NUM * 2; i++) { + key = g_strdup_printf ("adsfasdfadf%d", i); + val = g_strdup_printf ("42263236236awt%d", i); + nm_setting_vpn_add_data_item (s_vpn, key, val); + + /* Cache some keys to delete */ + if (i % 2) + info.to_del[u++] = g_strdup (key); + + g_free (key); + g_free (val); + } + + /* Iterate over current table keys */ + info.s_vpn = s_vpn; + info.called = 0; + nm_setting_vpn_foreach_data_item (s_vpn, del_iter_func, &info); + + /* Make sure all the things we removed during iteration are really gone */ + for (i = 0; i < TO_DEL_NUM; i++) { + g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, info.to_del[i]), ==, NULL); + g_free (info.to_del[i]); + } + + /* And make sure the foreach callback was called the same number of times + * as there were keys in the table at the beginning of the foreach. + */ + g_assert_cmpint (info.called, ==, TO_DEL_NUM * 2); + + g_object_unref (s_vpn); +} + +static void +test_setting_ip4_config_labels (void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GVariant *label; + GPtrArray *addrs; + char **labels; + NMConnection *conn; + GVariant *dict, *dict2, *setting_dict, *value; + GError *error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new (AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error (error); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* The 'address-labels' property should be omitted from the serialization if + * there are no non-NULL labels. + */ + conn = nmtst_create_minimal_connection ("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, nm_setting_duplicate (NM_SETTING (s_ip4))); + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (conn); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "address-labels", NULL); + g_assert (value == NULL); + + g_variant_unref (setting_dict); + g_variant_unref (dict); + + /* Now back to constructing the original s_ip4... */ + + /* addr 2 */ + addr = nm_ip_address_new (AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "label", g_variant_new_string ("eth0:1")); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + /* addr 3 */ + addr = nm_ip_address_new (AF_INET, "3.4.5.6", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "label", NULL); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 2); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* Remove addr 1 and re-verify remaining addresses */ + nm_setting_ip_config_remove_address (s_ip4, 0); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* If we serialize as the daemon, the labels should appear in the D-Bus + * serialization under both 'address-labels' and 'address-data'. + */ + conn = nmtst_create_minimal_connection ("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "address-labels", G_VARIANT_TYPE_STRING_ARRAY); + g_assert (value != NULL); + g_variant_get (value, "^as", &labels); + g_assert_cmpint (g_strv_length (labels), ==, 2); + g_assert_cmpstr (labels[0], ==, "eth0:1"); + g_assert_cmpstr (labels[1], ==, ""); + g_variant_unref (value); + g_strfreev (labels); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_variant_unref (value); + g_assert (addrs != NULL); + g_assert_cmpint (addrs->len, ==, 2); + addr = addrs->pdata[0]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + addr = addrs->pdata[1]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + g_ptr_array_unref (addrs); + + g_variant_unref (setting_dict); + + /* We should be able to deserialize the labels from either 'address-labels' + * or 'address-data'. + */ + dict2 = g_variant_ref (dict); + + NMTST_VARIANT_EDITOR (dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); + ); + conn = nm_simple_connection_new_from_dbus (dict, &error); + g_assert_no_error (error); + g_variant_unref (dict); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + g_object_unref (conn); + + NMTST_VARIANT_EDITOR (dict2, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-labels"); + ); + conn = nm_simple_connection_new_from_dbus (dict2, &error); + g_assert_no_error (error); + g_variant_unref (dict2); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* Test explicit property assignment */ + g_object_get (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, + NULL); + + nm_setting_ip_config_clear_addresses (s_ip4); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 0); + + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_ADDRESSES, addrs, + NULL); + g_ptr_array_unref (addrs); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 2); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + g_object_unref (conn); +} + +static void +test_setting_ip4_config_address_data (void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GPtrArray *addrs; + NMConnection *conn; + GVariant *dict, *setting_dict, *value; + GError *error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new (AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "one", g_variant_new_string ("foo")); + nm_ip_address_set_attribute (addr, "two", g_variant_new_int32 (42)); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + /* addr 2 */ + addr = nm_ip_address_new (AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error (error); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + /* The client-side D-Bus serialization should include the attributes in + * "address-data", and should not have an "addresses" property. + */ + conn = nmtst_create_minimal_connection ("address-data test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "addresses", NULL); + g_assert (value == NULL); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_variant_unref (value); + g_assert (addrs != NULL); + g_assert_cmpint (addrs->len, ==, 2); + + addr = addrs->pdata[0]; + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value != NULL); + g_assert_cmpint (g_variant_get_int32 (value), ==, 42); + + g_ptr_array_unref (addrs); + g_variant_unref (setting_dict); + g_variant_unref (dict); + + /* The daemon-side serialization should include both 'addresses' and 'address-data' */ + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "addresses", G_VARIANT_TYPE ("aau")); + g_assert (value != NULL); + g_variant_unref (value); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + g_assert (value != NULL); + g_variant_unref (value); + + g_variant_unref (setting_dict); + g_object_unref (conn); + + /* When we reserialize that dictionary as a client, 'address-data' will be preferred. */ + conn = nm_simple_connection_new_from_dbus (dict, &error); + g_assert_no_error (error); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value != NULL); + g_assert_cmpint (g_variant_get_int32 (value), ==, 42); + + /* But on the server side, 'addresses' will have precedence. */ + _nm_utils_is_manager_process = TRUE; + conn = nm_simple_connection_new_from_dbus (dict, &error); + _nm_utils_is_manager_process = FALSE; + g_assert_no_error (error); + g_variant_unref (dict); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value == NULL); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value == NULL); + + g_object_unref (conn); +} + +static void +test_setting_gsm_apn_spaces (void) +{ + NMSettingGsm *s_gsm; + const char *tmp; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + ASSERT (s_gsm != NULL, + "gsm-apn-spaces", + "error creating GSM setting"); + + /* Trailing space */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar ", NULL); + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "gsm-apn-spaces", "empty APN"); + ASSERT (strcmp (tmp, "foobar") == 0, + "gsm-apn-spaces", "unexpected APN"); + + /* Leading space */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, " foobar", NULL); + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "gsm-apn-spaces", "empty APN"); + ASSERT (strcmp (tmp, "foobar") == 0, + "gsm-apn-spaces", "unexpected APN"); +} + +static void +test_setting_gsm_apn_bad_chars (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + ASSERT (s_gsm != NULL, + "gsm-apn-bad-chars", + "error creating GSM setting"); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); + + /* Make sure a valid APN works */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar123.-baz", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == TRUE, + "gsm-apn-bad-chars", "unexpectedly invalid GSM setting"); + + /* Random invalid chars */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "@#%$@#%@#%", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* Spaces */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar baz", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* 0 characters long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* 65-character long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); +} + +static void +test_setting_gsm_apn_underscore (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + g_assert (s_gsm); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); + + /* 65-character long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar_baz", NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); +} + +static void +test_setting_gsm_without_number (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + g_assert (s_gsm); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, NULL, NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "", NULL); + nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static NMSettingWirelessSecurity * +make_test_wsec_setting (const char *detail) +{ + NMSettingWirelessSecurity *s_wsec; + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, detail, "error creating setting"); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "foobarbaz", + NM_SETTING_WIRELESS_SECURITY_PSK, "random psk", + NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "aaaaaaaaaa", + NULL); + + return s_wsec; +} + +#define ASSERT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value != NULL, test_name, msg); \ + g_variant_unref (value); \ + } + +#define ASSERT_NOT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value == NULL, test_name, msg); \ + } + +static void +test_setting_to_dbus_all (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-all"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + + /* Make sure all keys are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_no_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-no-secrets"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_only_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-only-secrets"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + + /* Make sure non-secret keys are not there */ + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_transform (void) +{ + NMSetting *s_wired; + GVariant *dict, *val; + const char *test_mac_address = "11:22:33:44:55:66"; + const guint8 *dbus_mac_address; + guint8 cmp_mac_address[ETH_ALEN]; + gsize len; + + s_wired = nm_setting_wired_new (); + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, test_mac_address, + NULL); + + g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); + + dict = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRED_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING); + g_assert (val != NULL); + + dbus_mac_address = g_variant_get_fixed_array (val, &len, 1); + g_assert_cmpint (len, ==, ETH_ALEN); + + nm_utils_hwaddr_aton (test_mac_address, cmp_mac_address, ETH_ALEN); + g_assert (memcmp (dbus_mac_address, cmp_mac_address, ETH_ALEN) == 0); + + g_variant_unref (val); + g_variant_unref (dict); + g_object_unref (s_wired); +} + +static void +test_setting_to_dbus_enum (void) +{ + NMSetting *s_ip6, *s_wsec, *s_serial; + GVariant *dict, *val; + + /* enum */ + s_ip6 = nm_setting_ip6_config_new (); + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NULL); + + dict = _nm_setting_to_dbus (s_ip6, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_IP6_CONFIG_IP6_PRIVACY, G_VARIANT_TYPE_INT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_int32 (val), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_ip6); + + /* flags (and a transformed enum) */ + s_wsec = nm_setting_wireless_security_new (); + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_KEY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED), + NULL); + + dict = _nm_setting_to_dbus (s_wsec, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, G_VARIANT_TYPE_UINT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_uint32 (val), ==, NM_WEP_KEY_TYPE_KEY); + g_variant_unref (val); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, G_VARIANT_TYPE_UINT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_uint32 (val), ==, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_wsec); + + /* another transformed enum */ + s_serial = nm_setting_serial_new (); + g_object_set (s_serial, + NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_ODD, + NULL); + + dict = _nm_setting_to_dbus (s_serial, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_SERIAL_PARITY, G_VARIANT_TYPE_BYTE); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_byte (val), ==, 'o'); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_serial); +} + +static void +test_connection_to_dbus_setting_name (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + connection = nm_simple_connection_new (); + s_wsec = make_test_wsec_setting ("connection-to-dbus-setting-name"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Make sure the keys of the first level dict are setting names, not + * the GType name of the setting objects. + */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + "connection-to-dbus-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_variant_unref (dict); + g_object_unref (connection); +} + +static void +test_connection_to_dbus_deprecated_props (void) +{ + NMConnection *connection; + NMSetting *s_wireless; + GBytes *ssid; + NMSettingWirelessSecurity *s_wsec; + GVariant *dict, *wireless_dict, *sec_val; + + connection = nmtst_create_minimal_connection ("test-connection-to-dbus-deprecated-props", + NULL, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + s_wireless = nm_setting_wireless_new (); + ssid = g_bytes_new ("1234567", 7); + g_object_set (s_wireless, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, s_wireless); + + /* Serialization should not have an 802-11-wireless.security property */ + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); + + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); + g_assert (sec_val == NULL); + + g_variant_unref (wireless_dict); + g_variant_unref (dict); + + /* Now add an NMSettingWirelessSecurity and try again */ + s_wsec = make_test_wsec_setting ("test-connection-to-dbus-deprecated-props"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); + + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); + g_assert (g_variant_is_of_type (sec_val, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (sec_val, NULL), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_variant_unref (sec_val); + g_variant_unref (wireless_dict); + g_variant_unref (dict); + g_object_unref (connection); +} + +static void +test_setting_new_from_dbus (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-new-from-dbus"); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (s_wsec); + + s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, NULL); + g_variant_unref (dict); + + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); + g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, "foobarbaz"); + g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "random psk"); + g_object_unref (s_wsec); +} + +static void +test_setting_new_from_dbus_transform (void) +{ + NMSetting *s_wired; + GVariant *dict; + GVariantBuilder builder; + const char *test_mac_address = "11:22:33:44:55:66"; + guint8 dbus_mac_address[ETH_ALEN]; + GError *error = NULL; + + nm_utils_hwaddr_aton (test_mac_address, dbus_mac_address, ETH_ALEN); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRED_MAC_ADDRESS, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + dbus_mac_address, ETH_ALEN, 1)); + dict = g_variant_builder_end (&builder); + + s_wired = _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRED, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); + + g_variant_unref (dict); + g_object_unref (s_wired); +} + +static void +test_setting_new_from_dbus_enum (void) +{ + NMSettingIP6Config *s_ip6; + NMSettingWirelessSecurity *s_wsec; + NMSettingSerial *s_serial; + GVariant *dict; + GVariantBuilder builder; + GError *error = NULL; + + /* enum */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + g_variant_new_int32 (NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); + dict = g_variant_builder_end (&builder); + + s_ip6 = (NMSettingIP6Config *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_IP6_CONFIG, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (s_ip6), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + + g_variant_unref (dict); + g_object_unref (s_ip6); + + /* flags (and a transformed enum) */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32 (NM_WEP_KEY_TYPE_KEY)); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + g_variant_new_uint32 (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + dict = g_variant_builder_end (&builder); + + s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_wireless_security_get_wep_key_type (s_wsec), ==, NM_WEP_KEY_TYPE_KEY); + g_assert_cmpint (nm_setting_wireless_security_get_wep_key_flags (s_wsec), ==, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + + g_variant_unref (dict); + g_object_unref (s_wsec); + + /* another transformed enum */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_SERIAL_PARITY, + g_variant_new_byte ('E')); + dict = g_variant_builder_end (&builder); + + s_serial = (NMSettingSerial *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_SERIAL, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_serial_get_parity (s_serial), ==, NM_SETTING_SERIAL_PARITY_EVEN); + + g_variant_unref (dict); + g_object_unref (s_serial); +} + +static NMConnection * +new_test_connection (void) +{ + NMConnection *connection; + NMSetting *setting; + char *uuid; + guint64 timestamp = time (NULL); + + connection = nm_simple_connection_new (); + + setting = nm_setting_connection_new (); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_ID, "foobar", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_wired_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_WIRED_MTU, 1592, + NULL); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "eyeofthetiger", + NULL); + nm_connection_add_setting (connection, setting); + + return connection; +} + +static GVariant * +new_connection_dict (char **out_uuid, + const char **out_expected_id, + const char **out_expected_ip6_method) +{ + GVariantBuilder conn_builder, setting_builder; + + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + + *out_uuid = nm_utils_uuid_generate (); + *out_expected_id = "My happy connection"; + *out_expected_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + + /* Connection setting */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_NAME, + g_variant_new_string (NM_SETTING_CONNECTION_SETTING_NAME)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_ID, + g_variant_new_string (*out_expected_id)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_UUID, + g_variant_new_string (*out_uuid)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_TYPE, + g_variant_new_string (NM_SETTING_WIRED_SETTING_NAME)); + + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_CONNECTION_SETTING_NAME, + &setting_builder); + + /* Wired setting */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_WIRED_SETTING_NAME, + &setting_builder); + + /* IP6 */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_IP_CONFIG_METHOD, + g_variant_new_string (*out_expected_ip6_method)); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + &setting_builder); + + return g_variant_builder_end (&conn_builder); +} + +static void +test_connection_replace_settings (void) +{ + NMConnection *connection; + GVariant *new_settings; + GError *error = NULL; + gboolean success; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip6; + char *uuid = NULL; + const char *expected_id = NULL, *expected_method = NULL; + + connection = new_test_connection (); + + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); + g_assert (new_settings); + + /* Replace settings and test */ + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_no_error (error); + g_assert (success); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (nm_connection_get_setting_wired (connection)); + g_assert (!nm_connection_get_setting_ip4_config (connection)); + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, expected_method); + + g_free (uuid); + g_variant_unref (new_settings); + g_object_unref (connection); +} + +static void +test_connection_replace_settings_from_connection (void) +{ + NMConnection *connection, *replacement; + NMSettingConnection *s_con; + NMSetting *setting; + GBytes *ssid; + char *uuid = NULL; + const char *expected_id = "Awesome connection"; + + connection = new_test_connection (); + g_assert (connection); + + replacement = nm_simple_connection_new (); + g_assert (replacement); + + /* New connection setting */ + setting = nm_setting_connection_new (); + g_assert (setting); + + uuid = nm_utils_uuid_generate (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, expected_id, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + nm_connection_add_setting (replacement, setting); + + /* New wifi setting */ + setting = nm_setting_wireless_new (); + g_assert (setting); + + ssid = g_bytes_new ("1234567", 7); + g_object_set (setting, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (replacement, setting); + + /* Replace settings and test */ + nm_connection_replace_settings_from_connection (connection, replacement); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (!nm_connection_get_setting_wired (connection)); + g_assert (!nm_connection_get_setting_ip6_config (connection)); + g_assert (nm_connection_get_setting_wireless (connection)); + + g_free (uuid); + g_object_unref (replacement); + g_object_unref (connection); +} + +static void +test_connection_replace_settings_bad (void) +{ + NMConnection *connection, *new_connection; + GVariant *new_settings; + GVariantBuilder builder, setting_builder; + GError *error = NULL; + gboolean success; + NMSettingConnection *s_con; + + new_connection = new_test_connection (); + g_assert (nm_connection_verify (new_connection, NULL)); + s_con = nm_connection_get_setting_connection (new_connection); + g_object_set (s_con, + NM_SETTING_CONNECTION_UUID, NULL, + NM_SETTING_CONNECTION_ID, "bad-connection", + NULL); + g_assert (!nm_connection_verify (new_connection, NULL)); + + /* nm_connection_replace_settings_from_connection() should succeed */ + connection = new_test_connection (); + nm_connection_replace_settings_from_connection (connection, new_connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "bad-connection"); + g_assert (!nm_connection_verify (connection, NULL)); + g_object_unref (connection); + + /* nm_connection_replace_settings() should succeed */ + new_settings = nm_connection_to_dbus (new_connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (new_settings != NULL); + + connection = new_test_connection (); + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert_cmpstr (nm_connection_get_id (connection), ==, "bad-connection"); + g_assert (!nm_connection_verify (connection, NULL)); + g_object_unref (connection); + g_variant_unref (new_settings); + + /* But given an invalid dict, it should fail */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sa{sv}}", + "ip-over-avian-carrier", + &setting_builder); + new_settings = g_variant_builder_end (&builder); + + connection = new_test_connection (); + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + g_assert (!success); + + g_assert (nm_connection_verify (connection, NULL)); + g_object_unref (connection); + + g_variant_unref (new_settings); + g_object_unref (new_connection); +} + +static void +test_connection_new_from_dbus (void) +{ + NMConnection *connection; + GVariant *new_settings; + GError *error = NULL; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip6; + char *uuid = NULL; + const char *expected_id = NULL, *expected_method = NULL; + + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); + g_assert (new_settings); + + /* Replace settings and test */ + connection = nm_simple_connection_new_from_dbus (new_settings, &error); + g_assert_no_error (error); + g_assert (connection); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (nm_connection_get_setting_wired (connection)); + g_assert (nm_connection_get_setting_ip4_config (connection)); + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, expected_method); + + g_free (uuid); + g_variant_unref (new_settings); + g_object_unref (connection); +} + +static void +check_permission (NMSettingConnection *s_con, + guint32 idx, + const char *expected_uname, + const char *tag) +{ + gboolean success; + const char *ptype = NULL, *pitem = NULL, *detail = NULL; + + success = nm_setting_connection_get_permission (s_con, 0, &ptype, &pitem, &detail); + ASSERT (success == TRUE, tag, "unexpected failure getting added permission"); + + /* Permission type */ + ASSERT (ptype != NULL, tag, "unexpected failure getting permission type"); + ASSERT (strcmp (ptype, "user") == 0, tag, "retrieved unexpected permission type"); + + /* Permission item */ + ASSERT (pitem != NULL, tag, "unexpected failure getting permission item"); + ASSERT (strcmp (pitem, expected_uname) == 0, tag, "retrieved unexpected permission item"); + + ASSERT (detail == NULL, tag, "unexpected success getting permission detail"); +} + +#define TEST_UNAME "asdfasfasdf" + +static void +test_setting_connection_permissions_helpers (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + char **perms; + const char *expected_perm = "user:" TEST_UNAME ":"; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strcmp (ptype, \"user\") == 0*"); + success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*ptype*"); + success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*uname*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*uname[0] != '\\0'*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strchr (uname, ':')*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #3"); + + /* Ensure a non-UTF-8 [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*g_utf8_validate (uname, -1, NULL)*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", buf, NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #4"); + + /* Ensure a non-NULL [detail] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*detail == NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf"); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (success == TRUE, + "setting-connection-permissions-helpers", "unexpected failure adding valid user permisson"); + + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions"); + + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-helpers"); + + /* Check the actual GObject property just to be paranoid */ + g_object_get (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, &perms, NULL); + ASSERT (perms != NULL, + "setting-connection-permissions-helpers", "unexpected failure getting permissions"); + ASSERT (g_strv_length (perms) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions"); + ASSERT (strcmp (perms[0], expected_perm) == 0, + "setting-connection-permissions-helpers", "unexpected permission property data"); + g_strfreev (perms); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-helpers", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + +static void +add_permission_property (NMSettingConnection *s_con, + const char *ptype, + const char *pitem, + int pitem_len, + const char *detail) +{ + GString *str; + char *perms[2]; + + str = g_string_sized_new (50); + if (ptype) + g_string_append (str, ptype); + g_string_append_c (str, ':'); + + if (pitem) { + if (pitem_len >= 0) + g_string_append_len (str, pitem, pitem_len); + else + g_string_append (str, pitem); + } + + g_string_append_c (str, ':'); + + if (detail) + g_string_append (str, detail); + + perms[0] = str->str; + perms[1] = NULL; + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, perms, NULL); + + g_string_free (str, TRUE); +} + +static void +test_setting_connection_permissions_property (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0*"); + add_permission_property (s_con, "foobar", "blah", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0*"); + add_permission_property (s_con, NULL, "blah", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*last_colon > str*"); + add_permission_property (s_con, "user", NULL, -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*last_colon > str*"); + add_permission_property (s_con, "user", "", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' in the middle is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*str[i] != ':'*"); + add_permission_property (s_con, "user", "ad:asdf", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #3"); + + /* Ensure an [item] with ':' at the end is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*str[i] != ':'*"); + add_permission_property (s_con, "user", "adasdfaf:", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #4"); + + /* Ensure a non-UTF-8 [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*g_utf8_validate (str, -1, NULL)*"); + add_permission_property (s_con, "user", buf, (int) sizeof (buf), NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #5"); + + /* Ensure a non-NULL [detail] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*(last_colon + 1) == '\\0'*"); + add_permission_property (s_con, "user", "dafasdf", -1, "asdf"); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-permissions-property", "unexpected failure adding valid user permisson"); + + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-property"); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + +static void +test_connection_compare_same (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + g_assert (nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_key_only_in_a (void) +{ + NMConnection *a, *b; + NMSettingConnection *s_con; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_setting_only_in_a (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + nm_connection_remove_setting (b, NM_TYPE_SETTING_IP4_CONFIG); + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_key_only_in_b (void) +{ + NMConnection *a, *b; + NMSettingConnection *s_con; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_setting_only_in_b (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + nm_connection_remove_setting (a, NM_TYPE_SETTING_IP4_CONFIG); + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +typedef struct { + const char *key_name; + guint32 result; +} DiffKey; + +typedef struct { + const char *name; + DiffKey keys[30]; +} DiffSetting; + +#define ARRAY_LEN(a) (sizeof (a) / sizeof (a[0])) + +static void +ensure_diffs (GHashTable *diffs, const DiffSetting *check, gsize n_check) +{ + guint i; + + g_assert (g_hash_table_size (diffs) == n_check); + + /* Loop through the settings */ + for (i = 0; i < n_check; i++) { + GHashTable *setting_hash; + guint z = 0; + + setting_hash = g_hash_table_lookup (diffs, check[i].name); + g_assert (setting_hash); + + /* Get the number of keys to check */ + while (check[i].keys[z].key_name) + z++; + g_assert (g_hash_table_size (setting_hash) == z); + + /* Now compare the actual keys */ + for (z = 0; check[i].keys[z].key_name; z++) { + NMSettingDiffResult result; + + result = GPOINTER_TO_UINT (g_hash_table_lookup (setting_hash, check[i].keys[z].key_name)); + g_assert (result == check[i].keys[z].result); + } + } +} + +static void +test_connection_diff_a_only (void) +{ + NMConnection *connection; + GHashTable *out_diffs = NULL; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, { + { NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_READ_ONLY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } + } }, + { NM_SETTING_WIRED_SETTING_NAME, { + { NM_SETTING_WIRED_PORT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_SPEED, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_DUPLEX, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_NETTYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, { + { NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_GATEWAY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + connection = new_test_connection (); + + same = nm_connection_diff (connection, NULL, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (connection); +} + +static void +test_connection_diff_same (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + gboolean same; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_different (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + NMSettingIPConfig *s_ip4; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_IP4_CONFIG_SETTING_NAME, { + { NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_ip4 = nm_connection_get_setting_ip4_config (a); + g_assert (s_ip4); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_no_secrets (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + NMSetting *s_pppoe; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_PPPOE_SETTING_NAME, { + { NM_SETTING_PPPOE_PASSWORD, NM_SETTING_DIFF_RESULT_IN_B }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + s_pppoe = nm_setting_pppoe_new (); + g_object_set (G_OBJECT (s_pppoe), + NM_SETTING_PPPOE_USERNAME, "thomas", + NULL); + nm_connection_add_setting (a, s_pppoe); + + b = nm_simple_connection_new_clone (a); + + /* Add a secret to B */ + s_pppoe = NM_SETTING (nm_connection_get_setting_pppoe (b)); + g_assert (s_pppoe); + g_object_set (G_OBJECT (s_pppoe), + NM_SETTING_PPPOE_PASSWORD, "secretpassword", + NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + + /* Now make sure the diff returns results if secrets are not ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_inferrable (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + gboolean same; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + char *uuid; + const DiffSetting settings[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, { + { NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + + /* Change the UUID, wired MTU, and set ignore-auto-dns */ + s_con = nm_connection_get_setting_connection (a); + g_assert (s_con); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, "really neat connection", + NULL); + g_free (uuid); + + s_wired = nm_connection_get_setting_wired (a); + g_assert (s_wired); + g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MTU, 300, NULL); + + s_ip4 = nm_connection_get_setting_ip4_config (a); + g_assert (s_ip4); + g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + + /* And change a INFERRABLE property to ensure that it shows up in the diff results */ + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, "usb0", NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +add_generic_settings (NMConnection *connection, const char *ctype) +{ + NMSetting *setting; + char *uuid; + + uuid = nm_utils_uuid_generate (); + + setting = nm_setting_connection_new (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, "asdfasdfadf", + NM_SETTING_CONNECTION_TYPE, ctype, + NM_SETTING_CONNECTION_UUID, uuid, + NULL); + nm_connection_add_setting (connection, setting); + + g_free (uuid); + + setting = nm_setting_ip4_config_new (); + g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_ip6_config_new (); + g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, setting); +} + +static void +test_connection_good_base_types (void) +{ + NMConnection *connection; + NMSetting *setting; + gboolean success; + GError *error = NULL; + GBytes *ssid; + const char *bdaddr = "11:22:33:44:55:66"; + + /* Try a basic wired connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIRED_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Try a wired PPPoE connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_PPPOE_SETTING_NAME); + setting = nm_setting_pppoe_new (); + g_object_set (setting, NM_SETTING_PPPOE_USERNAME, "bob smith", NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Wifi connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIRELESS_SETTING_NAME); + + setting = nm_setting_wireless_new (); + ssid = g_bytes_new ("1234567", 7); + g_object_set (setting, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Bluetooth connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_BLUETOOTH_SETTING_NAME); + + setting = nm_setting_bluetooth_new (); + g_object_set (setting, + NM_SETTING_BLUETOOTH_BDADDR, bdaddr, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* WiMAX connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIMAX_SETTING_NAME); + setting = nm_setting_wimax_new (); + g_object_set (setting, NM_SETTING_WIMAX_NETWORK_NAME, "CLEAR", NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* GSM connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_GSM_SETTING_NAME); + + setting = nm_setting_gsm_new (); + g_object_set (setting, + NM_SETTING_GSM_NUMBER, "*99#", + NM_SETTING_GSM_APN, "metered.billing.sucks", + NULL); + nm_connection_add_setting (connection, setting); + + /* CDMA connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_CDMA_SETTING_NAME); + + setting = nm_setting_cdma_new (); + g_object_set (setting, + NM_SETTING_CDMA_NUMBER, "#777", + NM_SETTING_CDMA_USERNAME, "foobar@vzw.com", + NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); +} + +static void +test_connection_bad_base_types (void) +{ + NMConnection *connection; + NMSetting *setting; + gboolean success; + GError *error = NULL; + + /* Test various non-base connection types to make sure they are rejected; + * using a fake 'wired' connection so the rest of it verifies + */ + + /* Connection setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_CONNECTION_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* PPP setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_PPP_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + setting = nm_setting_ppp_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* Serial setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_SERIAL_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + setting = nm_setting_serial_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP4 setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_IP4_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP6 setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_IP6_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); +} + +static void +test_setting_compare_id (void) +{ + NMSetting *old, *new; + gboolean success; + + old = nm_setting_connection_new (); + g_object_set (old, + NM_SETTING_CONNECTION_ID, "really awesome cool connection", + NM_SETTING_CONNECTION_UUID, "fbbd59d5-acab-4e30-8f86-258d272617e7", + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NULL); + + new = nm_setting_duplicate (old); + g_object_set (new, NM_SETTING_CONNECTION_ID, "some different connection id", NULL); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_ID); + g_assert (success); +} + +static void +test_setting_compare_timestamp (void) +{ + NMSetting *old, *new; + gboolean success; + + old = nm_setting_connection_new (); + g_object_set (old, + NM_SETTING_CONNECTION_ID, "ignore timestamp connection", + NM_SETTING_CONNECTION_UUID, "b047a198-0e0a-4f0e-a653-eea09bb35e40", + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 1234567890, + NULL); + + new = nm_setting_duplicate (old); + g_object_set (new, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 1416316539, NULL); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP); + g_assert (success); +} + +typedef struct { + NMSettingSecretFlags secret_flags; + NMSettingCompareFlags comp_flags; + gboolean remove_secret; +} TestDataCompareSecrets; + +static TestDataCompareSecrets * +test_data_compare_secrets_new (NMSettingSecretFlags secret_flags, + NMSettingCompareFlags comp_flags, + gboolean remove_secret) +{ + TestDataCompareSecrets *data = g_new0 (TestDataCompareSecrets, 1); + + data->secret_flags = secret_flags; + data->comp_flags = comp_flags; + data->remove_secret = remove_secret; + return data; +} + +static void +test_setting_compare_secrets (gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + NMSetting *old, *new; + gboolean success; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_wireless_security_new (); + g_object_set (old, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, "really cool psk", + NULL); + nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, data->secret_flags, NULL); + + /* Clear the PSK from the duplicated setting */ + new = nm_setting_duplicate (old); + if (data->remove_secret) { + g_object_set (new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + } + + success = nm_setting_compare (old, new, data->comp_flags); + g_assert (success); +} + +static void +test_setting_compare_vpn_secrets (gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + NMSetting *old, *new; + gboolean success; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_vpn_new (); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "foobarbaz", "really secret password"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "asdfasdfasdf", "really adfasdfasdfasdf"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "0123456778", "abcdefghijklmnpqrstuvqxyz"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "borkbork", "yet another really secret password"); + nm_setting_set_secret_flags (old, "borkbork", data->secret_flags, NULL); + + /* Clear "borkbork" from the duplicated setting */ + new = nm_setting_duplicate (old); + if (data->remove_secret) { + nm_setting_vpn_remove_secret (NM_SETTING_VPN (new), "borkbork"); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + } + + success = nm_setting_compare (old, new, data->comp_flags); + g_assert (success); +} + +static void +test_hwaddr_aton_ether_normal (void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + + g_assert (nm_utils_hwaddr_aton ("00:11:22:33:44:55", buf, ETH_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_ib_normal (void) +{ + guint8 buf[100]; + const char *source = "00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90"; + guint8 expected[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, + 0x90 }; + + g_assert (nm_utils_hwaddr_aton (source, buf, INFINIBAND_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_no_leading_zeros (void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 }; + + g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:44:5", buf, ETH_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_malformed (void) +{ + guint8 buf[100]; + + g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:a@%%", buf, ETH_ALEN) == NULL); +} + +static void +test_hwaddr_equal (void) +{ + const char *string = "00:1a:2b:03:44:05"; + const char *upper_string = "00:1A:2B:03:44:05"; + const char *bad_string = "0:1a:2b:3:44:5"; + const guint8 binary[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 }; + const char *other_string = "1a:2b:03:44:05:00"; + const guint8 other_binary[ETH_ALEN] = { 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x00 }; + const char *long_string = "00:1a:2b:03:44:05:06:07"; + const guint8 long_binary[8] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x06, 0x07 }; + const char *null_string = "00:00:00:00:00:00"; + const guint8 null_binary[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + g_assert (nm_utils_hwaddr_matches (string, -1, string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, NULL, ETH_ALEN)); + + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_string, -1, string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), NULL, ETH_ALEN)); +} + +static void +test_hwaddr_canonical (void) +{ + const char *string = "00:1A:2B:03:44:05"; + const char *lower_string = "00:1a:2b:03:44:05"; + const char *short_string = "0:1a:2b:3:44:5"; + const char *hyphen_string = "00-1a-2b-03-44-05"; + const char *invalid_string = "00:1A:2B"; + char *canonical; + + canonical = nm_utils_hwaddr_canonical (string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (lower_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (short_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (hyphen_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (invalid_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, NULL); + + canonical = nm_utils_hwaddr_canonical (invalid_string, -1); + g_assert_cmpstr (canonical, ==, invalid_string); + g_free (canonical); +} + +static void +test_connection_changed_cb (NMConnection *connection, gboolean *data) +{ + *data = TRUE; +} + +static void +test_ip4_prefix_to_netmask (void) +{ + int i; + + for (i = 0; i<=32; i++) { + guint32 netmask = nm_utils_ip4_prefix_to_netmask (i); + int plen = nm_utils_ip4_netmask_to_prefix (netmask); + + g_assert_cmpint (i, ==, plen); + { + guint32 msk = 0x80000000; + guint32 netmask2 = 0; + guint32 prefix = i; + while (prefix > 0) { + netmask2 |= msk; + msk >>= 1; + prefix--; + } + g_assert_cmpint (netmask, ==, (guint32) htonl (netmask2)); + } + } +} + +static void +test_ip4_netmask_to_prefix (void) +{ + int i, j; + + GRand *rand = g_rand_new (); + + g_rand_set_seed (rand, 1); + + for (i = 2; i<=32; i++) { + guint32 netmask = nm_utils_ip4_prefix_to_netmask (i); + guint32 netmask_lowest_bit = netmask & ~nm_utils_ip4_prefix_to_netmask (i-1); + + g_assert_cmpint (i, ==, nm_utils_ip4_netmask_to_prefix (netmask)); + + for (j = 0; j < 2*i; j++) { + guint32 r = g_rand_int (rand); + guint32 netmask_holey; + guint32 prefix_holey; + + netmask_holey = (netmask & r) | netmask_lowest_bit; + + if (netmask_holey == netmask) + continue; + + /* create an invalid netmask with holes and check that the function + * returns the longest prefix. */ + prefix_holey = nm_utils_ip4_netmask_to_prefix (netmask_holey); + + g_assert_cmpint (i, ==, prefix_holey); + } + } + + g_rand_free (rand); +} + +#define ASSERT_CHANGED(statement) \ +{ \ + changed = FALSE; \ + statement; \ + g_assert (changed); \ +} + +#define ASSERT_UNCHANGED(statement) \ +{ \ + changed = FALSE; \ + statement; \ + g_assert (!changed); \ +} + +static void +test_connection_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + + connection = new_test_connection (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + /* Add new setting */ + ASSERT_CHANGED (nm_connection_add_setting (connection, nm_setting_vlan_new ())); + + /* Remove existing setting */ + ASSERT_CHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN)); + + /* Remove non-existing setting */ + ASSERT_UNCHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN)); + + g_object_unref (connection); +} + +static void +test_setting_connection_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingConnection *s_con; + char *uuid; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + ASSERT_CHANGED (g_object_set (s_con, NM_SETTING_CONNECTION_ID, "adfadfasdfaf", NULL)); + + ASSERT_CHANGED (nm_setting_connection_add_permission (s_con, "user", "billsmith", NULL)); + ASSERT_CHANGED (nm_setting_connection_remove_permission (s_con, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*iter != NULL*"); + ASSERT_UNCHANGED (nm_setting_connection_remove_permission (s_con, 1)); + g_test_assert_expected_messages (); + + uuid = nm_utils_uuid_generate (); + ASSERT_CHANGED (nm_setting_connection_add_secondary (s_con, uuid)); + ASSERT_CHANGED (nm_setting_connection_remove_secondary (s_con, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_connection_remove_secondary (s_con, 1)); + g_test_assert_expected_messages (); + + g_object_unref (connection); +} + +static void +test_setting_bond_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingBond *s_bond; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_bond = (NMSettingBond *) nm_setting_bond_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bond)); + + ASSERT_CHANGED (nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "10")); + ASSERT_CHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY)); + ASSERT_UNCHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY)); + + g_object_unref (connection); +} + +static void +test_setting_ip4_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + NMIPRoute *route; + GError *error = NULL; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip4, "11.22.0.0")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns (s_ip4, "33.44.0.0"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns (s_ip4)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 1)); + g_test_assert_expected_messages (); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip4)); + + addr = nm_ip_address_new (AF_INET, "22.33.0.0", 24, &error); + g_assert_no_error (error); + ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip4, addr)); + ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_address (s_ip4, addr); + ASSERT_CHANGED (nm_setting_ip_config_clear_addresses (s_ip4)); + + route = nm_ip_route_new (AF_INET, "22.33.0.0", 24, NULL, 0, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip4, route)); + ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_route (s_ip4, route); + ASSERT_CHANGED (nm_setting_ip_config_clear_routes (s_ip4)); + + nm_ip_address_unref (addr); + nm_ip_route_unref (route); + g_object_unref (connection); +} + +static void +test_setting_ip6_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip6; + NMIPAddress *addr; + NMIPRoute *route; + GError *error = NULL; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns (s_ip6)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip6)); + + addr = nm_ip_address_new (AF_INET6, "1:2:3::4:5:6", 64, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip6, addr)); + ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_address (s_ip6, addr); + ASSERT_CHANGED (nm_setting_ip_config_clear_addresses (s_ip6)); + + route = nm_ip_route_new (AF_INET6, "1:2:3::4:5:6", 128, NULL, 0, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip6, route)); + ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_route (s_ip6, route); + ASSERT_CHANGED (nm_setting_ip_config_clear_routes (s_ip6)); + + nm_ip_address_unref (addr); + nm_ip_route_unref (route); + g_object_unref (connection); +} + +static void +test_setting_vlan_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingVlan *s_vlan; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); + nm_connection_add_setting (connection, NM_SETTING (s_vlan)); + + ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, 3)); + ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < g_slist_length (list)*"); + ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1)); + g_test_assert_expected_messages (); + ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_INGRESS_MAP, "1:3")); + ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_INGRESS_MAP)); + + ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, 3)); + ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < g_slist_length (list)*"); + ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1)); + g_test_assert_expected_messages (); + ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_EGRESS_MAP, "1:3")); + ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_EGRESS_MAP)); + + g_object_unref (connection); +} + +static void +test_setting_vpn_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingVpn *s_vpn; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + ASSERT_CHANGED (nm_setting_vpn_add_data_item (s_vpn, "foobar", "baz")); + ASSERT_CHANGED (nm_setting_vpn_remove_data_item (s_vpn, "foobar")); + ASSERT_UNCHANGED (nm_setting_vpn_remove_data_item (s_vpn, "not added")); + + ASSERT_CHANGED (nm_setting_vpn_add_secret (s_vpn, "foobar", "baz")); + ASSERT_CHANGED (nm_setting_vpn_remove_secret (s_vpn, "foobar")); + ASSERT_UNCHANGED (nm_setting_vpn_remove_secret (s_vpn, "not added")); + + g_object_unref (connection); +} + +static void +test_setting_wired_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWired *s_wired; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + ASSERT_CHANGED (nm_setting_wired_add_s390_option (s_wired, "portno", "1")); + ASSERT_CHANGED (nm_setting_wired_remove_s390_option (s_wired, "portno")); + ASSERT_UNCHANGED (nm_setting_wired_remove_s390_option (s_wired, "layer2")); + + g_object_unref (connection); +} + +static void +test_setting_wireless_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWireless *s_wifi; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ASSERT_CHANGED (nm_setting_wireless_add_seen_bssid (s_wifi, "00:11:22:33:44:55")); + + g_object_unref (connection); +} + +static void +test_setting_wireless_security_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWirelessSecurity *s_wsec; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + /* Protos */ + ASSERT_CHANGED (nm_setting_wireless_security_add_proto (s_wsec, "wpa")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_proto (s_wsec, "wep"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_protos (s_wsec)); + + /* Pairwise ciphers */ + ASSERT_CHANGED (nm_setting_wireless_security_add_pairwise (s_wsec, "tkip")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_pairwise (s_wsec)); + + /* Group ciphers */ + ASSERT_CHANGED (nm_setting_wireless_security_add_group (s_wsec, "ccmp")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_group (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_group (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_groups (s_wsec)); + + /* WEP key secret flags */ + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key0", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key1", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key2", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key3", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + + g_object_unref (connection); +} + +static void +test_setting_802_1x_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSetting8021x *s_8021x; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + /* EAP methods */ + ASSERT_CHANGED (nm_setting_802_1x_add_eap_method (s_8021x, "tls")); + ASSERT_CHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + ASSERT_CHANGED (nm_setting_802_1x_clear_eap_methods (s_8021x)); + + /* alternate subject matches */ + ASSERT_CHANGED (nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED (nm_setting_802_1x_clear_altsubject_matches (s_8021x)); + + /* phase2 alternate subject matches */ + ASSERT_CHANGED (nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED (nm_setting_802_1x_clear_phase2_altsubject_matches (s_8021x)); + + g_object_unref (connection); +} + +static void +test_setting_old_uuid (void) +{ + NMSetting *setting; + + /* NetworkManager-0.9.4.0 generated 40-character UUIDs with no dashes, + * like this one. Test that we maintain compatibility. */ + const char *uuid = "f43bec2cdd60e5da381ebb1eb1fa39f3cc52660c"; + + setting = nm_setting_connection_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_ID, "uuidtest", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + + nmtst_assert_setting_verifies (NM_SETTING (setting)); +} + +/******************************************************************************/ + +static void +test_connection_normalize_uuid (void) +{ + gs_unref_object NMConnection *con = NULL; + + con = nmtst_create_minimal_connection ("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nmtst_assert_connection_verifies_and_normalizable (con); + + g_object_set (nm_connection_get_setting_connection (con), + NM_SETTING_CONNECTION_UUID, NULL, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); +} + +/******************************************************************************/ + +/* + * Test normalization of interface-name + */ +static void +test_connection_normalize_virtual_iface_name (void) +{ + NMConnection *con = NULL; + NMSettingConnection *s_con; + NMSettingVlan *s_vlan; + GVariant *connection_dict, *setting_dict, *var; + GError *error = NULL; + const char *IFACE_NAME = "iface"; + const char *IFACE_VIRT = "iface-X"; + + con = nmtst_create_minimal_connection ("test1", + "22001632-bbb4-4616-b277-363dce3dfb5b", + NM_SETTING_VLAN_SETTING_NAME, + &s_con); + + nm_connection_add_setting (con, + g_object_new (NM_TYPE_SETTING_IP4_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + nm_connection_add_setting (con, + g_object_new (NM_TYPE_SETTING_IP6_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + s_vlan = nm_connection_get_setting_vlan (con); + + g_object_set (G_OBJECT (s_vlan), + NM_SETTING_VLAN_PARENT, "eth0", + NULL); + + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, NULL); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + + connection_dict = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (con); + + /* Serialized form should include vlan.interface-name as well. */ + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + var = g_variant_lookup_value (setting_dict, "interface-name", NULL); + g_assert (var != NULL); + g_assert (g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (var, NULL), ==, IFACE_NAME); + + g_variant_unref (setting_dict); + g_variant_unref (var); + + /* If vlan.interface-name is invalid, deserialization will fail. */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + ":::this-is-not-a-valid-interface-name:::"); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_clear_error (&error); + + /* If vlan.interface-name is valid, but doesn't match, it will be ignored. */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + IFACE_VIRT); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + s_con = nm_connection_get_setting_connection (con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, IFACE_NAME); + g_object_unref (con); + + /* But removing connection.interface-name should result in vlan.connection-name + * being "promoted". + */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_VIRT); + s_con = nm_connection_get_setting_connection (con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, IFACE_VIRT); + g_object_unref (con); + + g_variant_unref (connection_dict); +} + +static void +_test_connection_normalize_type_normalizable_setting (const char *type, + void (*prepare_normalizable_fcn) (NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting *s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + if (prepare_normalizable_fcn) + prepare_normalizable_fcn (con); + + g_assert (!nm_connection_get_setting_by_name (con, type)); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); + + s_base = nm_connection_get_setting_by_name (con, type); + g_assert (s_base); + g_assert (G_OBJECT_TYPE (s_base) == base_type); +} + +static void +_test_connection_normalize_type_unnormalizable_setting (const char *type) +{ + NMSettingConnection *s_con; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); +} + +static void +_test_connection_normalize_type_normalizable_type (const char *type, + NMSetting *(*add_setting_fcn) (NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting *s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + if (add_setting_fcn) + s_base = add_setting_fcn (con); + else { + s_base = NM_SETTING (g_object_new (base_type, NULL)); + nm_connection_add_setting (con, s_base); + } + + g_assert (!nm_connection_get_connection_type (con)); + g_assert (nm_connection_get_setting_by_name (con, type) == s_base); + + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_assert_cmpstr (nm_connection_get_connection_type (con), ==, type); + g_assert (nm_connection_get_setting_by_name (con, type) == s_base); +} + +static NMSetting * +_add_setting_fcn_adsl (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_ADSL, + NM_SETTING_ADSL_USERNAME, "test-user", + NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOA, + NM_SETTING_ADSL_ENCAPSULATION, NM_SETTING_ADSL_ENCAPSULATION_VCMUX, + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bluetooth (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_BLUETOOTH, + NM_SETTING_BLUETOOTH_BDADDR, "11:22:33:44:55:66", + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bond (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_BOND, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bond", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_bridge (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_BRIDGE, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bridge", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_cdma (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_CDMA, + NM_SETTING_CDMA_NUMBER, "test-number", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_infiniband (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_INFINIBAND, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_olpc_mesh (NMConnection *con) +{ + NMSetting *setting; + const char *ssid_data = "ssid-test"; + GBytes *ssid; + + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + setting = g_object_new (NM_TYPE_SETTING_OLPC_MESH, + NM_SETTING_OLPC_MESH_SSID, ssid, + NM_SETTING_OLPC_MESH_CHANNEL, 1, + NULL); + g_bytes_unref (ssid); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_team (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_TEAM, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-team", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_vlan (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_VLAN, + NM_SETTING_VLAN_PARENT, "test-parent", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_vpn (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_VPN, + NM_SETTING_VPN_SERVICE_TYPE, "test-vpn-service-type", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wimax (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_WIMAX, + NM_SETTING_WIMAX_NETWORK_NAME, "test-network", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wireless (NMConnection *con) +{ + NMSetting *setting; + const char *ssid_data = "ssid-test"; + GBytes *ssid; + + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + setting = g_object_new (NM_TYPE_SETTING_WIRELESS, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + + nm_connection_add_setting (con, setting); + return setting; +} + +static void +_prepare_normalizable_fcn_vlan (NMConnection *con) +{ + nm_connection_add_setting (con, g_object_new (NM_TYPE_SETTING_WIRED, + NM_SETTING_WIRED_MAC_ADDRESS, "11:22:33:44:55:66", + NULL)); +} + +static void +test_connection_normalize_type (void) +{ + guint i; + struct { + const char *type; + gboolean normalizable; + NMSetting *(*add_setting_fcn) (NMConnection *con); + void (*prepare_normalizable_fcn) (NMConnection *con); + } types[] = { + { NM_SETTING_GENERIC_SETTING_NAME, TRUE }, + { NM_SETTING_GSM_SETTING_NAME, TRUE }, + { NM_SETTING_WIRED_SETTING_NAME, TRUE }, + { NM_SETTING_VLAN_SETTING_NAME, TRUE, _add_setting_fcn_vlan, _prepare_normalizable_fcn_vlan }, + + { NM_SETTING_ADSL_SETTING_NAME, FALSE, _add_setting_fcn_adsl }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, FALSE, _add_setting_fcn_bluetooth }, + { NM_SETTING_BOND_SETTING_NAME, FALSE, _add_setting_fcn_bond }, + { NM_SETTING_BRIDGE_SETTING_NAME, FALSE, _add_setting_fcn_bridge }, + { NM_SETTING_CDMA_SETTING_NAME, FALSE, _add_setting_fcn_cdma }, + { NM_SETTING_INFINIBAND_SETTING_NAME, FALSE, _add_setting_fcn_infiniband }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, FALSE, _add_setting_fcn_olpc_mesh }, + { NM_SETTING_TEAM_SETTING_NAME, FALSE, _add_setting_fcn_team }, + { NM_SETTING_VLAN_SETTING_NAME, FALSE, _add_setting_fcn_vlan }, + { NM_SETTING_VPN_SETTING_NAME, FALSE, _add_setting_fcn_vpn }, + { NM_SETTING_WIMAX_SETTING_NAME, FALSE, _add_setting_fcn_wimax }, + { NM_SETTING_WIRELESS_SETTING_NAME, FALSE, _add_setting_fcn_wireless }, + { 0 }, + }; + + for (i = 0; types[i].type; i++) { + const char *type = types[i].type; + + if (types[i].normalizable) + _test_connection_normalize_type_normalizable_setting (type, types[i].prepare_normalizable_fcn); + else + _test_connection_normalize_type_unnormalizable_setting (type); + _test_connection_normalize_type_normalizable_type (type, types[i].add_setting_fcn); + } +} + +static void +test_connection_normalize_slave_type_1 (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection *s_con; + + con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_1", + "cc4cd5df-45dc-483e-b291-6b76c2338ecb", + NM_SETTING_WIRED_SETTING_NAME, &s_con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set (s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", + NULL); + + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_slave_type_2 (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection *s_con; + + con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_2", + "40bea008-ca72-439a-946b-e65f827656f9", + NM_SETTING_WIRED_SETTING_NAME, &s_con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set (s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, + NULL); + nm_connection_add_setting (con, nm_setting_bridge_port_new ()); + + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_infiniband_mtu (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingInfiniband *s_infini; + + con = nmtst_create_minimal_connection ("test_connection_normalize_infiniband_mtu", NULL, + NM_SETTING_INFINIBAND_SETTING_NAME, NULL); + + s_infini = nm_connection_get_setting_infiniband (con); + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NULL); + nmtst_assert_connection_verifies_and_normalizable (con); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NM_SETTING_INFINIBAND_MTU, (guint) 2044, + NULL); + nmtst_assert_connection_verifies_without_normalization (con); + g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NM_SETTING_INFINIBAND_MTU, (guint) 2045, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NM_SETTING_INFINIBAND_MTU, (guint) 65520, + NULL); + nmtst_assert_connection_verifies_without_normalization (con); + g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NM_SETTING_INFINIBAND_MTU, (guint) 65521, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); +} + +static void +test_setting_ip4_gateway (void) +{ + NMConnection *conn; + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GVariant *conn_dict, *ip4_dict, *value; + GVariantIter iter; + GVariant *addr_var; + guint32 addr_vals_0[] = { htonl (0xc0a8010a), 0x00000018, htonl (0x00000000) }; + guint32 addr_vals_1[] = { htonl (0xc0a8010b), 0x00000018, htonl (0xc0a80101) }; + GVariantBuilder addrs_builder; + GError *error = NULL; + + g_assert_cmpstr (nm_utils_inet4_ntop (addr_vals_0[0], NULL), ==, "192.168.1.10"); + + /* When serializing on the daemon side, ipv4.gateway is copied to the first + * entry of ipv4.addresses + */ + conn = nmtst_create_minimal_connection ("test_setting_ip4_gateway", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "192.168.1.1", + NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + + addr = nm_ip_address_new (AF_INET, "192.168.1.10", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + ip4_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (ip4_dict != NULL); + + value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "192.168.1.1"); + g_variant_unref (value); + + value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("aau")); + g_assert (value != NULL); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "@au", &addr_var)) { + const guint32 *addr_array; + gsize length; + + addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32)); + g_assert_cmpint (length, ==, 3); + g_assert_cmpstr (nm_utils_inet4_ntop (addr_array[2], NULL), ==, "192.168.1.1"); + g_variant_unref (addr_var); + } + g_variant_unref (value); + + g_variant_unref (ip4_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv4.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + + g_object_unref (conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("aau")); + g_variant_builder_add (&addrs_builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + addr_vals_0, 3, 4)); + g_variant_builder_add (&addrs_builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + addr_vals_1, 3, 4)); + + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "addresses", "aau", &addrs_builder); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + g_variant_unref (conn_dict); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + + g_object_unref (conn); +} + +static void +test_setting_ip6_gateway (void) +{ + NMConnection *conn; + NMSettingIPConfig *s_ip6; + NMIPAddress *addr; + GVariant *conn_dict, *ip6_dict, *value; + GVariantIter iter; + GVariant *gateway_var; + GVariantBuilder addrs_builder; + guint8 addr_bytes_0[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a }; + guint8 addr_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b }; + guint8 gateway_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; + GError *error = NULL; + + /* When serializing on the daemon side, ipv6.gateway is copied to the first + * entry of ipv6.addresses + */ + conn = nmtst_create_minimal_connection ("test_setting_ip6_gateway", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "abcd::1", + NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip6)); + + addr = nm_ip_address_new (AF_INET6, "abcd::10", 64, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr); + nm_ip_address_unref (addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + ip6_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (ip6_dict != NULL); + + value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "abcd::1"); + + value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("a(ayuay)")); + g_assert (value != NULL); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "(@ayu@ay)", NULL, NULL, &gateway_var)) { + const guint8 *gateway_bytes; + gsize length; + + gateway_bytes = g_variant_get_fixed_array (gateway_var, &length, 1); + g_assert_cmpint (length, ==, 16); + g_assert_cmpstr (nm_utils_inet6_ntop ((struct in6_addr *) gateway_bytes, NULL), ==, "abcd::1"); + g_variant_unref (gateway_var); + } + g_variant_unref (value); + + g_variant_unref (ip6_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv6.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + "address-data"); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1"); + + g_object_unref (conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("a(ayuay)")); + g_variant_builder_add (&addrs_builder, "(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + addr_bytes_0, 16, 1), + 64, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &in6addr_any, 16, 1)); + g_variant_builder_add (&addrs_builder, "(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + addr_bytes_1, 16, 1), + 64, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + gateway_bytes_1, 16, 1)); + + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + "addresses", "a(ayuay)", &addrs_builder); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + g_variant_unref (conn_dict); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1"); + + g_object_unref (conn); +} + +typedef struct { + const char *str; + const guint8 expected[20]; + const guint expected_len; +} HexItem; + +static void +test_hexstr2bin (void) +{ + static const HexItem items[] = { + { "aaBBCCddDD10496a", { 0xaa, 0xbb, 0xcc, 0xdd, 0xdd, 0x10, 0x49, 0x6a }, 8 }, + { "aa:bb:cc:dd:10:49:6a", { 0xaa, 0xbb, 0xcc, 0xdd, 0x10, 0x49, 0x6a }, 7 }, + { "0xccddeeff", { 0xcc, 0xdd, 0xee, 0xff }, 4 }, + { "1:2:66:77:80", { 0x01, 0x02, 0x66, 0x77, 0x80 }, 5 }, + { "e", { 0x0e }, 1 }, + { "aabb1199:" }, + { ":aabb1199" }, + { "aabb$$dd" }, + { "aab:ccc:ddd" }, + { "aab::ccc:ddd" }, + }; + GBytes *b; + guint i; + + for (i = 0; i < G_N_ELEMENTS (items); i++) { + b = nm_utils_hexstr2bin (items[i].str); + if (items[i].expected_len) { + g_assert (b); + g_assert_cmpint (g_bytes_get_size (b), ==, items[i].expected_len); + g_assert (memcmp (g_bytes_get_data (b, NULL), items[i].expected, g_bytes_get_size (b)) == 0); + } else + g_assert (b == NULL); + } +} + +/******************************************************************************/ + +#define UUID_NIL "00000000-0000-0000-0000-000000000000" +#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + +static void +_test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize slen, gpointer type_args) +{ + gs_free char *uuid_test = NULL; + + uuid_test = nm_utils_uuid_generate_from_string (str, slen, uuid_type, type_args); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed: type=%d; text=%s, len=%lld, uuid=%s, expected=%s", uuid_type, + str, (long long) slen, uuid_test, expected_uuid); + } + + if (slen < 0) { + /* also test that passing slen==-1 yields the same result as passing strlen(str). */ + _test_uuid (uuid_type, expected_uuid, str, strlen (str), type_args); + } else if (str && slen == 0) { + /* also test if we accept NULL for slen==0 */ + _test_uuid (uuid_type, expected_uuid, NULL, 0, type_args); + } + + if (uuid_type == NM_UTILS_UUID_TYPE_VARIANT3 && !type_args) { + /* For NM_UTILS_UUID_TYPE_VARIANT3, a missing @type_args is equal to UUID_NIL */ + _test_uuid (uuid_type, expected_uuid, str, slen, UUID_NIL); + } +} + +static void +test_nm_utils_uuid_generate_from_string (void) +{ + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "d41d8cd9-8f00-b204-e980-0998ecf8427e", "", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "0cc175b9-c0f1-b6a8-31c3-99e269772661", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "70350f60-27bc-e371-3f6b-76473084309b", "a\0b", 3, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1", -1, NULL); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", "", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "0531103a-d8fc-3dd4-b972-d98e4750994e", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "96e17d7a-ac89-38cf-95e1-bf5098da34e1", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", "a\0b", 3, NULL); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", "", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", "a", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "45a113ac-c7f2-30b0-90a5-a399ab912716", "test", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "002a0ada-f547-375a-bab5-896a11d1927e", "a\0b", 3, UUID_NS_DNS); +} + +/******************************************************************************/ + +NMTST_DEFINE (); + +int main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + /* The tests */ + g_test_add_func ("/core/general/test_setting_vpn_items", test_setting_vpn_items); + g_test_add_func ("/core/general/test_setting_vpn_update_secrets", test_setting_vpn_update_secrets); + g_test_add_func ("/core/general/test_setting_vpn_modify_during_foreach", test_setting_vpn_modify_during_foreach); + g_test_add_func ("/core/general/test_setting_ip4_config_labels", test_setting_ip4_config_labels); + g_test_add_func ("/core/general/test_setting_ip4_config_address_data", test_setting_ip4_config_address_data); + g_test_add_func ("/core/general/test_setting_gsm_apn_spaces", test_setting_gsm_apn_spaces); + g_test_add_func ("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars); + g_test_add_func ("/core/general/test_setting_gsm_apn_underscore", test_setting_gsm_apn_underscore); + g_test_add_func ("/core/general/test_setting_gsm_without_number", test_setting_gsm_without_number); + g_test_add_func ("/core/general/test_setting_to_dbus_all", test_setting_to_dbus_all); + g_test_add_func ("/core/general/test_setting_to_dbus_no_secrets", test_setting_to_dbus_no_secrets); + g_test_add_func ("/core/general/test_setting_to_dbus_only_secrets", test_setting_to_dbus_only_secrets); + g_test_add_func ("/core/general/test_setting_to_dbus_transform", test_setting_to_dbus_transform); + g_test_add_func ("/core/general/test_setting_to_dbus_enum", test_setting_to_dbus_enum); + g_test_add_func ("/core/general/test_setting_compare_id", test_setting_compare_id); + g_test_add_func ("/core/general/test_setting_compare_timestamp", test_setting_compare_timestamp); +#define ADD_FUNC(func, secret_flags, comp_flags, remove_secret) \ + g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func), \ + test_data_compare_secrets_new (secret_flags, comp_flags, remove_secret), \ + func, g_free) + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE); + g_test_add_func ("/core/general/test_setting_old_uuid", test_setting_old_uuid); + + g_test_add_func ("/core/general/test_connection_to_dbus_setting_name", test_connection_to_dbus_setting_name); + g_test_add_func ("/core/general/test_connection_to_dbus_deprecated_props", test_connection_to_dbus_deprecated_props); + g_test_add_func ("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus); + g_test_add_func ("/core/general/test_setting_new_from_dbus_transform", test_setting_new_from_dbus_transform); + g_test_add_func ("/core/general/test_setting_new_from_dbus_enum", test_setting_new_from_dbus_enum); + g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings); + g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection); + g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad); + g_test_add_func ("/core/general/test_connection_new_from_dbus", test_connection_new_from_dbus); + g_test_add_func ("/core/general/test_connection_normalize_virtual_iface_name", test_connection_normalize_virtual_iface_name); + g_test_add_func ("/core/general/test_connection_normalize_uuid", test_connection_normalize_uuid); + g_test_add_func ("/core/general/test_connection_normalize_type", test_connection_normalize_type); + g_test_add_func ("/core/general/test_connection_normalize_slave_type_1", test_connection_normalize_slave_type_1); + g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2); + g_test_add_func ("/core/general/test_connection_normalize_infiniband_mtu", test_connection_normalize_infiniband_mtu); + + g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers); + g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property); + + g_test_add_func ("/core/general/test_connection_compare_same", test_connection_compare_same); + g_test_add_func ("/core/general/test_connection_compare_key_only_in_a", test_connection_compare_key_only_in_a); + g_test_add_func ("/core/general/test_connection_compare_setting_only_in_a", test_connection_compare_setting_only_in_a); + g_test_add_func ("/core/general/test_connection_compare_key_only_in_b", test_connection_compare_key_only_in_b); + g_test_add_func ("/core/general/test_connection_compare_setting_only_in_b", test_connection_compare_setting_only_in_b); + + g_test_add_func ("/core/general/test_connection_diff_a_only", test_connection_diff_a_only); + g_test_add_func ("/core/general/test_connection_diff_same", test_connection_diff_same); + g_test_add_func ("/core/general/test_connection_diff_different", test_connection_diff_different); + g_test_add_func ("/core/general/test_connection_diff_no_secrets", test_connection_diff_no_secrets); + g_test_add_func ("/core/general/test_connection_diff_inferrable", test_connection_diff_inferrable); + g_test_add_func ("/core/general/test_connection_good_base_types", test_connection_good_base_types); + g_test_add_func ("/core/general/test_connection_bad_base_types", test_connection_bad_base_types); + + g_test_add_func ("/core/general/test_hwaddr_aton_ether_normal", test_hwaddr_aton_ether_normal); + g_test_add_func ("/core/general/test_hwaddr_aton_ib_normal", test_hwaddr_aton_ib_normal); + g_test_add_func ("/core/general/test_hwaddr_aton_no_leading_zeros", test_hwaddr_aton_no_leading_zeros); + g_test_add_func ("/core/general/test_hwaddr_aton_malformed", test_hwaddr_aton_malformed); + g_test_add_func ("/core/general/test_hwaddr_equal", test_hwaddr_equal); + g_test_add_func ("/core/general/test_hwaddr_canonical", test_hwaddr_canonical); + + g_test_add_func ("/core/general/test_ip4_prefix_to_netmask", test_ip4_prefix_to_netmask); + g_test_add_func ("/core/general/test_ip4_netmask_to_prefix", test_ip4_netmask_to_prefix); + + g_test_add_func ("/core/general/test_connection_changed_signal", test_connection_changed_signal); + g_test_add_func ("/core/general/test_setting_connection_changed_signal", test_setting_connection_changed_signal); + g_test_add_func ("/core/general/test_setting_bond_changed_signal", test_setting_bond_changed_signal); + g_test_add_func ("/core/general/test_setting_ip4_changed_signal", test_setting_ip4_changed_signal); + g_test_add_func ("/core/general/test_setting_ip6_changed_signal", test_setting_ip6_changed_signal); + g_test_add_func ("/core/general/test_setting_vlan_changed_signal", test_setting_vlan_changed_signal); + g_test_add_func ("/core/general/test_setting_vpn_changed_signal", test_setting_vpn_changed_signal); + g_test_add_func ("/core/general/test_setting_wired_changed_signal", test_setting_wired_changed_signal); + g_test_add_func ("/core/general/test_setting_wireless_changed_signal", test_setting_wireless_changed_signal); + g_test_add_func ("/core/general/test_setting_wireless_security_changed_signal", test_setting_wireless_security_changed_signal); + g_test_add_func ("/core/general/test_setting_802_1x_changed_signal", test_setting_802_1x_changed_signal); + g_test_add_func ("/core/general/test_setting_ip4_gateway", test_setting_ip4_gateway); + g_test_add_func ("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway); + + g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin); + g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c new file mode 100644 index 00000000..1254dfff --- /dev/null +++ b/libnm-core/tests/test-secrets.c @@ -0,0 +1,766 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include "nm-setting-8021x.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-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" + +#include "nm-test-utils.h" + +#define TEST_NEED_SECRETS_EAP_TLS_CA_CERT TEST_CERT_DIR "/test_ca_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT TEST_CERT_DIR "/test_key_and_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY TEST_CERT_DIR "/test_key_and_cert.pem" + +static gboolean +find_hints_item (GPtrArray *hints, const char *item) +{ + int i; + + for (i = 0; i < hints->len; i++) { + if (!strcmp (item, (const char *) g_ptr_array_index (hints, i))) + return TRUE; + } + return FALSE; +} + +static NMConnection * +make_tls_connection (const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *uuid; + gboolean success; + GError *error = NULL; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets", + 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 (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + 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_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set CA certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message); + + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set client certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message); + + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set private key '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + return connection; +} + +static void +test_need_tls_secrets_path (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); + ASSERT (connection != NULL, + "need-tls-secrets-path-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-secrets-path-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-secrets-path-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-secrets-path-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-secrets-path-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-secrets-path-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), + "need-tls-secrets-path-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static void +test_need_tls_secrets_blob (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); + ASSERT (connection != NULL, + "need-tls-secrets-blob-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-secrets-blob-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-secrets-blob-key", + "hints should be NULL since no secrets were required"); + + /* Clear secrets and ensure password is again required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-secrets-blob-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-secrets-blob-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-secrets-blob-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), + "need-tls-secrets-blob-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static NMConnection * +make_tls_phase2_connection (const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *uuid; + gboolean success; + GError *error = NULL; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets", + 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 (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "blahblah", NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); + + success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 CA certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message); + + success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 client certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 private key '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + return connection; +} + +static void +test_need_tls_phase2_secrets_path (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key", + NM_SETTING_802_1X_CK_SCHEME_PATH); + ASSERT (connection != NULL, + "need-tls-phase2-secrets-path-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-phase2-secrets-path-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-phase2-secrets-path-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-phase2-secrets-path-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-phase2-secrets-path-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-phase2-secrets-path-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), + "need-tls-phase2-secrets-path-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static void +test_need_tls_phase2_secrets_blob (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key", + NM_SETTING_802_1X_CK_SCHEME_BLOB); + ASSERT (connection != NULL, + "need-tls-phase2-secrets-blob-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-phase2-secrets-blob-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-phase2-secrets-blob-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-phase2-secrets-blob-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-phase2-secrets-blob-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-phase2-secrets-blob-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), + "need-tls-phase2-secrets-blob-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static NMConnection * +wifi_connection_new (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; + char *uuid; + GBytes *ssid; + + connection = nm_simple_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Wireless", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + /* Wireless setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + /* Wifi security */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NULL); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + return connection; +} + +static GVariant * +build_wep_secrets (const char *wepkey) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + g_variant_new_string (wepkey)); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32 (NM_WEP_KEY_TYPE_KEY)); + + return g_variant_builder_end (&builder); +} + +static void +test_update_secrets_wifi_single_setting (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; + + /* Test update with a hashed setting of 802-11-wireless secrets */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (secrets); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + g_assert_cmpstr (tmp, ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_wifi_full_hash (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariantBuilder builder; + GVariant *all; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; + + /* Test update with a hashed connection containing only 802-11-wireless + * setting and secrets. + */ + + connection = wifi_connection_new (); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&builder, "{s@a{sv}}", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + build_wep_secrets (wepkey)); + all = g_variant_builder_end (&builder); + + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + all, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (all); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + g_assert_cmpstr (tmp, ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_wifi_bad_setting_name (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test that passing an invalid setting name to + * nm_connection_update_secrets() fails with the correct error. + */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + + success = nm_connection_update_secrets (connection, + "asdfasdfasdfasf", + secrets, + &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert (success == FALSE); + + g_variant_unref (secrets); + + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test calling nm_connection_update_secrets() with an entire hashed + * connection including non-secrets. + */ + + connection = wifi_connection_new (); + + /* Build up the secrets dictionary */ + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + NMTST_VARIANT_EDITOR (secrets, + NMTST_VARIANT_ADD_PROPERTY (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "s", + wepkey); + ); + + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_assert_no_error (error); + g_assert (success == TRUE); + + g_variant_unref (secrets); + + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_empty_hash (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + + /* Test that updating secrets with an empty connection hash returns success */ + + connection = wifi_connection_new (); + secrets = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_assert_no_error (error); + g_assert (success == TRUE); + g_variant_unref (secrets); + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_bad_setting (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets, *copy, *setting_hash; + const char *setting_name; + GVariantBuilder conn_builder; + GVariantIter conn_iter; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test that sending a hashed connection containing an invalid setting + * name fails with the right error. + */ + + connection = wifi_connection_new (); + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec != NULL); + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, wepkey, + NULL); + + /* Build up the secrets hash */ + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Copy the dict, renaming the wireless-security setting in the process + * (so we ensure libnm is returning the right error when it finds an entry + * in the connection hash that doesn't match any setting in the connection). + */ + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_iter_init (&conn_iter, secrets); + while (g_variant_iter_next (&conn_iter, "{&s@a{sv}}", &setting_name, &setting_hash)) { + if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0) + setting_name = "asdfasdfasdfasdf"; + + g_variant_builder_add (&conn_builder, "{s@a{sv}}", setting_name, setting_hash); + g_variant_unref (setting_hash); + } + copy = g_variant_builder_end (&conn_builder); + g_variant_unref (secrets); + + success = nm_connection_update_secrets (connection, NULL, copy, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert (success == FALSE); + + g_variant_unref (copy); + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_empty_base_setting (void) +{ + NMConnection *connection; + GVariant *secrets, *setting; + GError *error = NULL; + gboolean success; + + /* Test that a hashed connection which does not have any hashed secrets + * for the requested setting returns success. + */ + + connection = wifi_connection_new (); + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + g_assert_cmpint (g_variant_n_children (secrets), ==, 3); + + setting = g_variant_lookup_value (secrets, NM_SETTING_WIRELESS_SETTING_NAME, NULL); + g_assert (setting != NULL); + g_variant_unref (setting); + + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (secrets); + g_object_unref (connection); +} + +static void +test_update_secrets_null_setting_name_with_setting_hash (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Ensure that a NULL setting name and only a hashed setting fails */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, + "*nm_connection_update_secrets*setting_name != NULL || full_connection*"); + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_test_assert_expected_messages (); + g_assert_no_error (error); + g_assert (!success); + + g_variant_unref (secrets); + g_object_unref (connection); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + char *base; + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + nmtst_init (&argc, &argv, TRUE); + + /* The tests */ + test_need_tls_secrets_path (); + test_need_tls_secrets_blob (); + test_need_tls_phase2_secrets_path (); + test_need_tls_phase2_secrets_blob (); + + test_update_secrets_wifi_single_setting (); + test_update_secrets_wifi_full_hash (); + test_update_secrets_wifi_bad_setting_name (); + + test_update_secrets_whole_connection (); + test_update_secrets_whole_connection_empty_hash (); + test_update_secrets_whole_connection_bad_setting (); + test_update_secrets_whole_connection_empty_base_setting (); + test_update_secrets_null_setting_name_with_setting_hash (); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/libnm-core/tests/test-setting-8021x.c b/libnm-core/tests/test-setting-8021x.c new file mode 100644 index 00000000..637ab81c --- /dev/null +++ b/libnm-core/tests/test-setting-8021x.c @@ -0,0 +1,458 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include <nm-utils.h> + +#include "nm-setting-connection.h" +#include "nm-setting-8021x.h" + +#include "nm-test-utils.h" + +static void +compare_blob_data (const char *test, + const char *key_path, + GBytes *key) +{ + char *contents = NULL; + gsize len = 0; + GError *error = NULL; + gboolean success; + + success = g_file_get_contents (key_path, &contents, &len, &error); + ASSERT (success == TRUE, + test, "failed to read blob key file: %s", error->message); + + ASSERT (len > 0, test, "blob key file invalid (size 0)"); + + ASSERT (len == g_bytes_get_size (key), + test, "blob key file (%d) and setting key data (%d) lengths don't match", + len, g_bytes_get_size (key)); + + ASSERT (memcmp (contents, g_bytes_get_data (key, NULL), len) == 0, + test, "blob key file and blob key data don't match"); + + g_free (contents); +} + +#define SCHEME_PATH "file://" + +static void +check_scheme_path (GBytes *value, const char *path) +{ + const guint8 *p = g_bytes_get_data (value, NULL); + + g_assert (memcmp (p, SCHEME_PATH, strlen (SCHEME_PATH)) == 0); + p += strlen (SCHEME_PATH); + g_assert (memcmp (p, path, strlen (path)) == 0); + p += strlen (path); + g_assert (*p == '\0'); +} + +static void +test_private_key_import (const char *path, + const char *password, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError *error = NULL; + GBytes *tmp_key = NULL, *client_cert = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "private-key-import", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "private-key-import", "unexpected private key format (got %d)", format); + tmp_fmt = nm_setting_802_1x_get_private_key_format (s_8021x); + ASSERT (tmp_fmt == format, + "private-key-import", "unexpected re-read private key format (expected %d, got %d)", + format, tmp_fmt); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "private-key-import", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "private-key-import", "failed to compare private key password"); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_private_key_blob (s_8021x); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key blob"); + compare_blob_data ("private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + check_scheme_path (tmp_key, path); + g_bytes_unref (tmp_key); + } else + g_assert_not_reached (); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + + g_object_get (s_8021x, NM_SETTING_802_1X_CLIENT_CERT, &client_cert, NULL); + ASSERT (client_cert != NULL, "private-key-import", "missing client certificate value"); + + /* make sure they are the same */ + ASSERT (g_bytes_equal (tmp_key, client_cert), + "private-key-import", "unexpected different private key and client cert data"); + + g_bytes_unref (tmp_key); + g_bytes_unref (client_cert); + } + + g_object_unref (s_8021x); +} + +static void +test_phase2_private_key_import (const char *path, + const char *password, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError *error = NULL; + GBytes *tmp_key = NULL, *client_cert = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "phase2-private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "phase2-private-key-import", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "phase2-private-key-import", "unexpected private key format"); + tmp_fmt = nm_setting_802_1x_get_phase2_private_key_format (s_8021x); + ASSERT (tmp_fmt == format, + "phase2-private-key-import", "unexpected re-read private key format (expected %d, got %d)", + format, tmp_fmt); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "phase2-private-key-import", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "phase2-private-key-import", "failed to compare private key password"); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_phase2_private_key_blob (s_8021x); + ASSERT (tmp_key != NULL, "phase2-private-key-import", "missing private key blob"); + compare_blob_data ("phase2-private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "phase2-private-key-import", "missing private key value"); + check_scheme_path (tmp_key, path); + } else + g_assert_not_reached (); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, &client_cert, NULL); + ASSERT (client_cert != NULL, "private-key-import", "missing client certificate value"); + + /* make sure they are the same */ + ASSERT (g_bytes_equal (tmp_key, client_cert), + "private-key-import", "unexpected different private key and client cert data"); + + g_bytes_unref (tmp_key); + g_bytes_unref (client_cert); + } + + g_object_unref (s_8021x); +} + +static void +test_wrong_password_keeps_data (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "wrong-password-keeps-data", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "wrong-password-keeps-data", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-password-keeps-data", "unexpected private key format (got %d)", format); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key (s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == FALSE, + "wrong-password-keeps-data", "unexpected success reading private key"); + ASSERT (error != NULL, + "wrong-password-keeps-data", "unexpected missing error"); + ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-password-keeps-data", "unexpected success reading private key format"); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "wrong-password-keeps-data", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "wrong-password-keeps-data", "failed to compare private key password"); + + g_object_unref (s_8021x); +} + +static void +test_clear_private_key (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "clear-private-key", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "clear-private-key", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "clear-private-key", "unexpected private key format (got %d)", format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "clear-private-key", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "clear-private-key", "failed to compare private key password"); + + /* Now clear it */ + success = nm_setting_802_1x_set_private_key (s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + ASSERT (success == TRUE, + "clear-private-key", "unexpected failure clearing private key"); + ASSERT (error == NULL, + "clear-private-key", "unexpected error clearing private key"); + + /* Ensure the password is also now clear */ + ASSERT (nm_setting_802_1x_get_private_key_password (s_8021x) == NULL, + "clear-private-key", "unexpected private key password"); + + g_object_unref (s_8021x); +} + +static void +test_wrong_phase2_password_keeps_data (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "wrong-phase2-password-keeps-data", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "wrong-phase2-password-keeps-data", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-phase2-password-keeps-data", "unexpected private key format (got %d)", format); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == FALSE, + "wrong-phase2-password-keeps-data", "unexpected success reading private key"); + ASSERT (error != NULL, + "wrong-phase2-password-keeps-data", "unexpected missing error"); + ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-phase2-password-keeps-data", "unexpected success reading private key format"); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "wrong-phase2-password-keeps-data", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "wrong-phase2-password-keeps-data", "failed to compare private key password"); + + g_object_unref (s_8021x); +} + +static void +test_clear_phase2_private_key (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "clear-phase2-private-key", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "clear-phase2-private-key", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "clear-phase2-private-key", "unexpected private key format (got %d)", format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "clear-phase2-private-key", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "clear-phase2-private-key", "failed to compare private key password"); + + /* Now clear it */ + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + ASSERT (success == TRUE, + "clear-phase2-private-key", "unexpected failure clearing private key"); + ASSERT (error == NULL, + "clear-phase2-private-key", "unexpected error clearing private key"); + + /* Ensure the password is also now clear */ + ASSERT (nm_setting_802_1x_get_phase2_private_key_password (s_8021x) == NULL, + "clear-phase2-private-key", "unexpected private key password"); + + g_object_unref (s_8021x); +} + +static void +do_8021x_test (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + g_assert_cmpint (g_strv_length (parts), ==, 2); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + /* Test phase1 and phase2 path scheme */ + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Test phase1 and phase2 blob scheme */ + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Test that using a wrong password does not change existing data */ + test_wrong_password_keeps_data (path, password); + test_wrong_phase2_password_keeps_data (path, password); + + /* Test clearing the private key */ + test_clear_private_key (path, password); + test_clear_phase2_private_key (path, password); + + g_free (path); + g_strfreev (parts); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_data_func ("/libnm/setting-8021x/key-and-cert", + "test_key_and_cert.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/key-only", + "test-key-only.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/pkcs8-enc-key", + "pkcs8-enc-key.pem, 1234567890", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/pkcs12", + "test-cert.p12, test", + do_8021x_test); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-setting-dcb.c b/libnm-core/tests/test-setting-dcb.c new file mode 100644 index 00000000..8adab8ce --- /dev/null +++ b/libnm-core/tests/test-setting-dcb.c @@ -0,0 +1,326 @@ +/* -*- 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 2013 Red Hat, Inc. + * + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> +#include <nm-utils.h> +#include <nm-glib-compat.h> +#include "nm-setting-dcb.h" +#include "nm-connection.h" +#include "nm-errors.h" + +#define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \ + NM_SETTING_DCB_FLAG_ADVERTISE | \ + NM_SETTING_DCB_FLAG_WILLING) + +static void +test_dcb_flags_valid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, 0); + + g_object_set (G_OBJECT (s_dcb), + NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_ISCSI_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_FIP_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_FLAGS_ALL, + NULL); + /* Priority Group Bandwidth must total 100% */ + for (i = 0; i < 7; i++) + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 12); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); + + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, DCB_FLAGS_ALL); +} + +#define TEST_FLAG(p, f, v) \ +{ \ + /* GObject property min/max should ensure the property does not get set to \ + * the invalid value, so we ensure the value we just tried to set is 0 and \ + * that verify is successful since the property never got set. \ + */ \ + g_object_set (G_OBJECT (s_dcb), p, v, NULL); \ + g_assert_cmpint (f (s_dcb), ==, 0); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ +} + +static void +test_dcb_flags_invalid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_FCOE_FLAGS, nm_setting_dcb_get_app_fcoe_flags, 0x332523); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_ISCSI_FLAGS, nm_setting_dcb_get_app_iscsi_flags, 0xFF); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_FIP_FLAGS, nm_setting_dcb_get_app_fip_flags, 0x1111); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, nm_setting_dcb_get_priority_flow_control_flags, G_MAXUINT32); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, nm_setting_dcb_get_priority_group_flags, + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + 1); + g_test_assert_expected_messages (); +} + +#define TEST_APP_PRIORITY(lcprop, ucprop, v) \ +{ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \ + \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, v, NULL); \ + g_assert_cmpint (nm_setting_dcb_get_app_##lcprop##_priority (s_dcb), ==, v); \ + \ + /* Assert that the setting is invalid while the app is disabled unless v is default */ \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + if (v >= 0) { \ + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert (success == FALSE); \ + } else { \ + g_assert_no_error (error); \ + g_assert (success); \ + } \ + g_clear_error (&error); \ + \ + /* Set the enable flag and re-verify, this time it should be valid */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ + \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, 0, NULL); \ +} + +static void +test_dcb_app_priorities (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + /* Defaults */ + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, -1); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, -1); + g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, -1); + + TEST_APP_PRIORITY (fcoe, FCOE, 6); + TEST_APP_PRIORITY (iscsi, ISCSI, 5); + TEST_APP_PRIORITY (fip, FIP, 4); + + TEST_APP_PRIORITY (fcoe, FCOE, -1); + TEST_APP_PRIORITY (iscsi, ISCSI, -1); + TEST_APP_PRIORITY (fip, FIP, -1); +} + +#define TEST_PRIORITY_VALID(fn, id, val, flagsprop, verify) \ +{ \ + /* Assert that setting the value gets the same value back out */ \ + nm_setting_dcb_set_priority_##fn (s_dcb, id, val); \ + g_assert_cmpint (nm_setting_dcb_get_priority_##fn (s_dcb, id), ==, val); \ + \ + if (verify) { \ + if (val != 0) { \ + /* Assert that verify fails because the flags do not include 'enabled' \ + * and a value has been set. \ + */ \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert (success == FALSE); \ + g_clear_error (&error); \ + } \ + \ + /* Assert that adding the 'enabled' flag verifies the setting */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ + } \ + \ + /* Reset everything */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \ + nm_setting_dcb_set_priority_##fn (s_dcb, id, 0); \ +} + +/* If Priority Groups are enabled, PG bandwidth must equal 100% */ +#define SET_VALID_PRIORITY_GROUP_BANDWIDTH \ +{ \ + guint x; \ + for (x = 0; x < 7; x++) \ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, x, 12); \ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); \ +} + +static void +test_dcb_priorities_valid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID (flow_control, i, TRUE, FLOW_CONTROL, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (group_id, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (group_id, i, 7 - i, GROUP, TRUE); + } + + /* Clear PG bandwidth from earlier tests */ + for (i = 0; i < 8; i++) + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 0); + + /* Priority Group Bandwidth must add up to 100% if enabled, which requires + * some dancing for verifying individual values here. + */ + for (i = 0; i < 8; i++) { + guint other = 7 - (i % 8); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - i); + TEST_PRIORITY_VALID (group_bandwidth, i, i, GROUP, TRUE); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - (7 - i)); + TEST_PRIORITY_VALID (group_bandwidth, i, 7 - i, GROUP, TRUE); + + /* Clear remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 0); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (bandwidth, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (bandwidth, i, 7 - i, GROUP, TRUE); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID (strict_bandwidth, i, TRUE, GROUP, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (traffic_class, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (traffic_class, i, 7 - i, GROUP, TRUE); + } +} + +static void +test_dcb_bandwidth_sums (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + /* Assert that setting the value gets the same value back out */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 0, 9); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 1, 10); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 2, 11); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 3, 12); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 13); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 5, 14); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 6, 15); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); + + /* Assert verify success when sums total 100% */ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Assert verify fails when sums do not total 100% */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 20); + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (success == FALSE); + g_clear_error (&error); +} + +#define TPATH "/libnm/settings/dcb/" + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + +#if !GLIB_CHECK_VERSION(2,34,0) + g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); +#endif + + g_test_add_func (TPATH "flags-valid", test_dcb_flags_valid); + g_test_add_func (TPATH "flags-invalid", test_dcb_flags_invalid); + g_test_add_func (TPATH "app-priorities", test_dcb_app_priorities); + g_test_add_func (TPATH "priorities", test_dcb_priorities_valid); + g_test_add_func (TPATH "bandwidth-sums", test_dcb_bandwidth_sums); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-settings-defaults.c b/libnm-core/tests/test-settings-defaults.c new file mode 100644 index 00000000..0e786187 --- /dev/null +++ b/libnm-core/tests/test-settings-defaults.c @@ -0,0 +1,133 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include <nm-utils.h> + +#include "nm-setting-8021x.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-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-test-utils.h" + +static void +test_defaults (GType type, const char *name) +{ + GParamSpec **property_specs; + guint n_property_specs; + GObject *setting; + int i; + + setting = g_object_new (type, NULL); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + ASSERT (property_specs != NULL, + name, "couldn't find property specs for object of type '%s'", + g_type_name (G_OBJECT_TYPE (setting))); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = G_VALUE_INIT; + GValue defvalue = G_VALUE_INIT; + char *actual, *expected; + gboolean ok = FALSE; + + /* Ignore non-fundamental types since they won't really have + * defaults. + */ + if (!G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type)) + continue; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + + g_value_init (&defvalue, prop_spec->value_type); + g_param_value_set_default (prop_spec, &defvalue); + + actual = g_strdup_value_contents (&value); + expected = g_strdup_value_contents (&defvalue); + + if (!strcmp (prop_spec->name, NM_SETTING_NAME)) { + /* 'name' is always the setting name, not the default value */ + ok = !strcmp (nm_setting_get_name (NM_SETTING (setting)), name); + g_free (expected); + expected = g_strdup (name); + } else + ok = g_param_value_defaults (prop_spec, &value); + + ASSERT (ok, + name, "property '%s' value '%s' not the expected default value '%s'", + prop_spec->name, actual, expected); + + g_free (actual); + g_free (expected); + g_value_unset (&value); + g_value_unset (&defvalue); + } + + g_free (property_specs); + g_object_unref (setting); +} + +int +main (int argc, char **argv) +{ + char *base; + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + /* The tests */ + test_defaults (NM_TYPE_SETTING_CONNECTION, NM_SETTING_CONNECTION_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_802_1X, NM_SETTING_802_1X_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_GSM, NM_SETTING_GSM_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_PPP, NM_SETTING_PPP_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_VPN, NM_SETTING_VPN_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRED, NM_SETTING_WIRED_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRELESS, NM_SETTING_WIRELESS_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRELESS_SECURITY, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + |