diff options
Diffstat (limited to 'libnm-util')
44 files changed, 4398 insertions, 2064 deletions
diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index fd5eccef..0a29e9c5 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -24,18 +24,23 @@ libnm_util_include_HEADERS = \ nm-setting-gsm.h \ nm-setting-cdma.h \ nm-setting-olpc-mesh.h \ + nm-setting-wimax.h \ nm-setting-wired.h \ nm-setting-wireless.h \ nm-setting-wireless-security.h \ nm-setting-vpn.h \ nm-utils.h -libnm_util_la_SOURCES= \ - crypto.c \ +libnm_util_la_private_headers = \ crypto.h \ + nm-param-spec-specialized.h \ + nm-utils-private.h \ + nm-setting-private.h + +libnm_util_la_csources = \ + crypto.c \ nm-connection.c \ nm-param-spec-specialized.c \ - nm-param-spec-specialized.h \ nm-setting.c \ nm-setting-8021x.c \ nm-setting-bluetooth.c \ @@ -48,20 +53,23 @@ libnm_util_la_SOURCES= \ nm-setting-gsm.c \ nm-setting-cdma.c \ nm-setting-olpc-mesh.c \ + nm-setting-wimax.c \ nm-setting-wired.c \ nm-setting-wireless.c \ nm-setting-wireless-security.c \ nm-setting-vpn.c \ - nm-utils.c \ - nm-utils-private.h \ - $(libnm_util_include_HEADERS) + nm-utils.c + +libnm_util_la_SOURCES = \ + $(libnm_util_la_csources) \ + $(libnm_util_la_private_headers) libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) SYMBOL_VIS_FILE=$(srcdir)/libnm-util.ver libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "7:1:6" + -version-info "2:0:0" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c @@ -104,15 +112,40 @@ libtest_crypto_la_CPPFLAGS += $(NSS_CFLAGS) libtest_crypto_la_LIBADD += $(NSS_LIBS) endif - - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc DISTCLEANFILES = libnm-util.pc +CLEANFILES = EXTRA_DIST = libnm-util.pc.in libnm-util.ver +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = +INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) + +if HAVE_INTROSPECTION +introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) $(top_srcdir)/include/NetworkManager.h $(top_srcdir)/include/NetworkManagerVPN.h + +NetworkManager-1.0.gir: libnm-util.la +NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 +NetworkManager_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 +NetworkManager_1_0_gir_CFLAGS = $(INCLUDES) -I$(top_srcdir)/libnm-util +NetworkManager_1_0_gir_LIBS = libnm-util.la +NetworkManager_1_0_gir_FILES = $(introspection_sources) +NetworkManager_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ +INTROSPECTION_GIRS += NetworkManager-1.0.gir + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) +endif + if WITH_TESTS check-local: diff --git a/libnm-util/Makefile.in b/libnm-util/Makefile.in index d78365d7..d251ea8c 100644 --- a/libnm-util/Makefile.in +++ b/libnm-util/Makefile.in @@ -48,16 +48,23 @@ host_triplet = @host@ @WITH_NSS_TRUE@am__append_10 = crypto_nss.c @WITH_NSS_TRUE@am__append_11 = $(NSS_CFLAGS) @WITH_NSS_TRUE@am__append_12 = $(NSS_LIBS) +@HAVE_INTROSPECTION_TRUE@am__append_13 = NetworkManager-1.0.gir +@HAVE_INTROSPECTION_TRUE@am__append_14 = $(gir_DATA) $(typelib_DATA) subdir = libnm-util DIST_COMMON = $(libnm_util_include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/libnm-util.pc.in COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -85,7 +92,8 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" \ + "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" \ "$(DESTDIR)$(libnm_util_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @@ -95,27 +103,17 @@ am__DEPENDENCIES_1 = libnm_util_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) -am__libnm_util_la_SOURCES_DIST = crypto.c crypto.h nm-connection.c \ - nm-param-spec-specialized.c nm-param-spec-specialized.h \ - nm-setting.c nm-setting-8021x.c nm-setting-bluetooth.c \ - nm-setting-connection.c nm-setting-ip4-config.c \ - nm-setting-ip6-config.c nm-setting-ppp.c nm-setting-pppoe.c \ - nm-setting-serial.c nm-setting-gsm.c nm-setting-cdma.c \ - nm-setting-olpc-mesh.c nm-setting-wired.c \ - nm-setting-wireless.c nm-setting-wireless-security.c \ - nm-setting-vpn.c nm-utils.c nm-utils-private.h nm-connection.h \ - nm-setting.h nm-setting-8021x.h nm-setting-bluetooth.h \ - nm-setting-connection.h nm-setting-ip4-config.h \ - nm-setting-ip6-config.h nm-setting-ppp.h nm-setting-pppoe.h \ - nm-setting-serial.h nm-setting-gsm.h nm-setting-cdma.h \ - nm-setting-olpc-mesh.h nm-setting-wired.h \ - nm-setting-wireless.h nm-setting-wireless-security.h \ - nm-setting-vpn.h nm-utils.h crypto_gnutls.c crypto_nss.c -am__objects_1 = -@WITH_GNUTLS_TRUE@am__objects_2 = libnm_util_la-crypto_gnutls.lo -@WITH_NSS_TRUE@am__objects_3 = libnm_util_la-crypto_nss.lo -am_libnm_util_la_OBJECTS = libnm_util_la-crypto.lo \ - libnm_util_la-nm-connection.lo \ +am__libnm_util_la_SOURCES_DIST = crypto.c nm-connection.c \ + nm-param-spec-specialized.c nm-setting.c nm-setting-8021x.c \ + nm-setting-bluetooth.c nm-setting-connection.c \ + nm-setting-ip4-config.c nm-setting-ip6-config.c \ + nm-setting-ppp.c nm-setting-pppoe.c nm-setting-serial.c \ + nm-setting-gsm.c nm-setting-cdma.c nm-setting-olpc-mesh.c \ + nm-setting-wimax.c nm-setting-wired.c nm-setting-wireless.c \ + nm-setting-wireless-security.c nm-setting-vpn.c nm-utils.c \ + crypto.h nm-param-spec-specialized.h nm-utils-private.h \ + nm-setting-private.h crypto_gnutls.c crypto_nss.c +am__objects_1 = libnm_util_la-crypto.lo libnm_util_la-nm-connection.lo \ libnm_util_la-nm-param-spec-specialized.lo \ libnm_util_la-nm-setting.lo libnm_util_la-nm-setting-8021x.lo \ libnm_util_la-nm-setting-bluetooth.lo \ @@ -128,11 +126,16 @@ am_libnm_util_la_OBJECTS = libnm_util_la-crypto.lo \ libnm_util_la-nm-setting-gsm.lo \ libnm_util_la-nm-setting-cdma.lo \ libnm_util_la-nm-setting-olpc-mesh.lo \ + libnm_util_la-nm-setting-wimax.lo \ libnm_util_la-nm-setting-wired.lo \ libnm_util_la-nm-setting-wireless.lo \ libnm_util_la-nm-setting-wireless-security.lo \ - libnm_util_la-nm-setting-vpn.lo libnm_util_la-nm-utils.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) + libnm_util_la-nm-setting-vpn.lo libnm_util_la-nm-utils.lo +am__objects_2 = +@WITH_GNUTLS_TRUE@am__objects_3 = libnm_util_la-crypto_gnutls.lo +@WITH_NSS_TRUE@am__objects_4 = libnm_util_la-crypto_nss.lo +am_libnm_util_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) libnm_util_la_OBJECTS = $(am_libnm_util_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -144,13 +147,13 @@ libtest_crypto_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) am__libtest_crypto_la_SOURCES_DIST = crypto.c crypto_gnutls.c \ crypto_nss.c -@WITH_GNUTLS_TRUE@am__objects_4 = libtest_crypto_la-crypto_gnutls.lo -@WITH_NSS_TRUE@am__objects_5 = libtest_crypto_la-crypto_nss.lo +@WITH_GNUTLS_TRUE@am__objects_5 = libtest_crypto_la-crypto_gnutls.lo +@WITH_NSS_TRUE@am__objects_6 = libtest_crypto_la-crypto_nss.lo am_libtest_crypto_la_OBJECTS = libtest_crypto_la-crypto.lo \ - $(am__objects_4) $(am__objects_5) + $(am__objects_5) $(am__objects_6) libtest_crypto_la_OBJECTS = $(am_libtest_crypto_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -185,7 +188,7 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive -DATA = $(pkgconfig_DATA) +DATA = $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA) HEADERS = $(libnm_util_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive @@ -222,7 +225,6 @@ am__relativize = \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ -ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -231,13 +233,15 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ @@ -249,6 +253,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -257,6 +262,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GIO_CFLAGS = @GIO_CFLAGS@ GIO_LIBS = @GIO_LIBS@ @@ -265,8 +271,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ -GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ @@ -281,13 +287,23 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -295,6 +311,8 @@ LIBDL = @LIBDL@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ LIBM = @LIBM@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ @@ -303,13 +321,15 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ -MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -335,13 +355,12 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POFILES = @POFILES@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ RESOLVCONF_PATH = @RESOLVCONF_PATH@ SED = @SED@ @@ -355,11 +374,15 @@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -426,27 +449,50 @@ libnm_util_include_HEADERS = \ nm-setting-gsm.h \ nm-setting-cdma.h \ nm-setting-olpc-mesh.h \ + nm-setting-wimax.h \ nm-setting-wired.h \ nm-setting-wireless.h \ nm-setting-wireless-security.h \ nm-setting-vpn.h \ nm-utils.h -libnm_util_la_SOURCES = crypto.c crypto.h nm-connection.c \ - nm-param-spec-specialized.c nm-param-spec-specialized.h \ - nm-setting.c nm-setting-8021x.c nm-setting-bluetooth.c \ - nm-setting-connection.c nm-setting-ip4-config.c \ - nm-setting-ip6-config.c nm-setting-ppp.c nm-setting-pppoe.c \ - nm-setting-serial.c nm-setting-gsm.c nm-setting-cdma.c \ - nm-setting-olpc-mesh.c nm-setting-wired.c \ - nm-setting-wireless.c nm-setting-wireless-security.c \ - nm-setting-vpn.c nm-utils.c nm-utils-private.h \ - $(libnm_util_include_HEADERS) $(am__append_1) $(am__append_4) +libnm_util_la_private_headers = \ + crypto.h \ + nm-param-spec-specialized.h \ + nm-utils-private.h \ + nm-setting-private.h + +libnm_util_la_csources = \ + crypto.c \ + nm-connection.c \ + nm-param-spec-specialized.c \ + nm-setting.c \ + nm-setting-8021x.c \ + nm-setting-bluetooth.c \ + nm-setting-connection.c \ + nm-setting-ip4-config.c \ + nm-setting-ip6-config.c \ + nm-setting-ppp.c \ + nm-setting-pppoe.c \ + nm-setting-serial.c \ + nm-setting-gsm.c \ + nm-setting-cdma.c \ + nm-setting-olpc-mesh.c \ + nm-setting-wimax.c \ + nm-setting-wired.c \ + nm-setting-wireless.c \ + nm-setting-wireless-security.c \ + nm-setting-vpn.c \ + nm-utils.c + +libnm_util_la_SOURCES = $(libnm_util_la_csources) \ + $(libnm_util_la_private_headers) $(am__append_1) \ + $(am__append_4) libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) \ $(am__append_3) $(am__append_6) SYMBOL_VIS_FILE = $(srcdir)/libnm-util.ver libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "7:1:6" + -version-info "2:0:0" libnm_util_includedir = $(includedir)/NetworkManager @@ -462,7 +508,22 @@ libtest_crypto_la_LIBADD = $(GLIB_LIBS) $(am__append_9) \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc DISTCLEANFILES = libnm-util.pc +CLEANFILES = $(am__append_14) EXTRA_DIST = libnm-util.pc.in libnm-util.ver +INTROSPECTION_GIRS = $(am__append_13) +INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) +@HAVE_INTROSPECTION_TRUE@introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) $(top_srcdir)/include/NetworkManager.h $(top_srcdir)/include/NetworkManagerVPN.h +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_CFLAGS = $(INCLUDES) -I$(top_srcdir)/libnm-util +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_LIBS = libnm-util.la +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_FILES = $(introspection_sources) +@HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ +@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0 +@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS) +@HAVE_INTROSPECTION_TRUE@typelibdir = $(libdir)/girepository-1.0 +@HAVE_INTROSPECTION_TRUE@typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) all: all-recursive .SUFFIXES: @@ -567,6 +628,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-pppoe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-serial.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-vpn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-wimax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-wired.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-wireless-security.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_util_la-nm-setting-wireless.Plo@am__quote@ @@ -723,6 +785,14 @@ libnm_util_la-nm-setting-olpc-mesh.lo: nm-setting-olpc-mesh.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_util_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_util_la-nm-setting-olpc-mesh.lo `test -f 'nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`nm-setting-olpc-mesh.c +libnm_util_la-nm-setting-wimax.lo: nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_util_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_util_la-nm-setting-wimax.lo -MD -MP -MF $(DEPDIR)/libnm_util_la-nm-setting-wimax.Tpo -c -o libnm_util_la-nm-setting-wimax.lo `test -f 'nm-setting-wimax.c' || echo '$(srcdir)/'`nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_util_la-nm-setting-wimax.Tpo $(DEPDIR)/libnm_util_la-nm-setting-wimax.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-setting-wimax.c' object='libnm_util_la-nm-setting-wimax.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_util_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_util_la-nm-setting-wimax.lo `test -f 'nm-setting-wimax.c' || echo '$(srcdir)/'`nm-setting-wimax.c + libnm_util_la-nm-setting-wired.lo: nm-setting-wired.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_util_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_util_la-nm-setting-wired.lo -MD -MP -MF $(DEPDIR)/libnm_util_la-nm-setting-wired.Tpo -c -o libnm_util_la-nm-setting-wired.lo `test -f 'nm-setting-wired.c' || echo '$(srcdir)/'`nm-setting-wired.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_util_la-nm-setting-wired.Tpo $(DEPDIR)/libnm_util_la-nm-setting-wired.Plo @@ -808,6 +878,26 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-girDATA: $(gir_DATA) + @$(NORMAL_INSTALL) + test -z "$(girdir)" || $(MKDIR_P) "$(DESTDIR)$(girdir)" + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(girdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \ + done + +uninstall-girDATA: + @$(NORMAL_UNINSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(girdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(girdir)" && rm -f $$files install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @@ -828,6 +918,26 @@ uninstall-pkgconfigDATA: test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files +install-typelibDATA: $(typelib_DATA) + @$(NORMAL_INSTALL) + test -z "$(typelibdir)" || $(MKDIR_P) "$(DESTDIR)$(typelibdir)" + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(typelibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibdir)" || exit $$?; \ + done + +uninstall-typelibDATA: + @$(NORMAL_UNINSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(typelibdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(typelibdir)" && rm -f $$files install-libnm_util_includeHEADERS: $(libnm_util_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(libnm_util_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libnm_util_includedir)" @@ -1049,7 +1159,7 @@ check: check-recursive all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libnm_util_includedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libnm_util_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -1069,6 +1179,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -1101,8 +1212,8 @@ info: info-recursive info-am: -install-data-am: install-libnm_util_includeHEADERS \ - install-pkgconfigDATA +install-data-am: install-girDATA install-libnm_util_includeHEADERS \ + install-pkgconfigDATA install-typelibDATA install-dvi: install-dvi-recursive @@ -1148,8 +1259,9 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-libLTLIBRARIES \ - uninstall-libnm_util_includeHEADERS uninstall-pkgconfigDATA +uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ + uninstall-libnm_util_includeHEADERS uninstall-pkgconfigDATA \ + uninstall-typelibDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ ctags-recursive install-am install-strip tags-recursive @@ -1161,17 +1273,23 @@ uninstall-am: uninstall-libLTLIBRARIES \ 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-libLTLIBRARIES \ - install-libnm_util_includeHEADERS install-man install-pdf \ - install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am uninstall-libLTLIBRARIES \ - uninstall-libnm_util_includeHEADERS uninstall-pkgconfigDATA - + install-exec install-exec-am install-girDATA install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libnm_util_includeHEADERS \ + install-man install-pdf install-pdf-am install-pkgconfigDATA \ + install-ps install-ps-am install-strip install-typelibDATA \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-girDATA uninstall-libLTLIBRARIES \ + uninstall-libnm_util_includeHEADERS uninstall-pkgconfigDATA \ + uninstall-typelibDATA + + +-include $(INTROSPECTION_MAKEFILE) + +@HAVE_INTROSPECTION_TRUE@NetworkManager-1.0.gir: libnm-util.la @WITH_TESTS_TRUE@check-local: @WITH_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-util.so $(SYMBOL_VIS_FILE) diff --git a/libnm-util/crypto.c b/libnm-util/crypto.c index 70872db4..991b3c3e 100644 --- a/libnm-util/crypto.c +++ b/libnm-util/crypto.c @@ -18,9 +18,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. */ +#include "config.h" + #include <glib.h> #include <string.h> #include <strings.h> @@ -41,36 +43,43 @@ _nm_crypto_error_quark (void) } -static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; -static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; +#define PEM_RSA_KEY_BEGIN "-----BEGIN RSA PRIVATE KEY-----" +#define 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-----"; +#define PEM_DSA_KEY_BEGIN "-----BEGIN DSA PRIVATE KEY-----" +#define PEM_DSA_KEY_END "-----END DSA PRIVATE KEY-----" -static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----"; -static const char *pem_cert_end = "-----END CERTIFICATE-----"; +#define PEM_CERT_BEGIN "-----BEGIN CERTIFICATE-----" +#define PEM_CERT_END "-----END CERTIFICATE-----" -static const char * -find_tag (const char *tag, const char *buf, gsize len) +static gboolean +find_tag (const char *tag, + const GByteArray *array, + gsize start_at, + gsize *out_pos) { gsize i, taglen; + gsize len = array->len - start_at; - taglen = strlen (tag); - if (len < taglen) - return NULL; + g_return_val_if_fail (out_pos != NULL, FALSE); - for (i = 0; i < len - taglen + 1; i++) { - if (memcmp (buf + i, tag, taglen) == 0) - return buf + i; + taglen = strlen (tag); + if (len >= taglen) { + for (i = 0; i < len - taglen + 1; i++) { + if (memcmp (array->data + start_at + i, tag, taglen) == 0) { + *out_pos = start_at + i; + return TRUE; + } + } } - return NULL; + return FALSE; } #define DEK_INFO_TAG "DEK-Info: " #define PROC_TYPE_TAG "Proc-Type: " static GByteArray * -parse_old_openssl_key_file (GByteArray *contents, +parse_old_openssl_key_file (const GByteArray *contents, int key_type, char **out_cipher, char **out_iv, @@ -79,8 +88,7 @@ parse_old_openssl_key_file (GByteArray *contents, GByteArray *bindata = NULL; char **lines = NULL; char **ln = NULL; - const char *pos; - const char *end; + gsize start = 0, end = 0; GString *str = NULL; int enc_tags = 0; char *iv = NULL; @@ -89,15 +97,16 @@ parse_old_openssl_key_file (GByteArray *contents, gsize tmp_len = 0; const char *start_tag; const char *end_tag; + guint8 save_end = 0; switch (key_type) { case NM_CRYPTO_KEY_TYPE_RSA: - start_tag = pem_rsa_key_begin; - end_tag = pem_rsa_key_end; + 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; + start_tag = PEM_DSA_KEY_BEGIN; + end_tag = PEM_DSA_KEY_END; break; default: g_set_error (error, NM_CRYPTO_ERROR, @@ -108,23 +117,23 @@ parse_old_openssl_key_file (GByteArray *contents, return NULL; } - pos = find_tag (start_tag, (const char *) contents->data, contents->len); - if (!pos) + if (!find_tag (start_tag, contents, 0, &start)) goto parse_error; - pos += strlen (start_tag); - - end = find_tag (end_tag, pos, (const char *) contents->data + contents->len - pos); - if (end == NULL) { + start += strlen (start_tag); + if (!find_tag (end_tag, contents, start, &end)) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_FILE_FORMAT_INVALID, _("PEM key file had no end tag '%s'."), end_tag); goto parse_error; } - *((char *) end) = '\0'; - lines = g_strsplit (pos, "\n", 0); + save_end = contents->data[end]; + contents->data[end] = '\0'; + lines = g_strsplit ((const char *) (contents->data + start), "\n", 0); + contents->data[end] = save_end; + if (!lines || g_strv_length (lines) <= 1) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_FILE_FORMAT_INVALID, @@ -132,7 +141,7 @@ parse_old_openssl_key_file (GByteArray *contents, goto parse_error; } - str = g_string_new_len (NULL, end - pos); + str = g_string_new_len (NULL, end - start); if (!str) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_OUT_OF_MEMORY, @@ -242,64 +251,24 @@ parse_error: } static GByteArray * -file_to_g_byte_array (const char *filename, - gboolean privkey, - GError **error) +file_to_g_byte_array (const char *filename, GError **error) { - char *contents, *der = NULL; + char *contents; GByteArray *array = NULL; gsize length = 0; - const char *pos = NULL; - - if (!g_file_get_contents (filename, &contents, &length, error)) - return NULL; - - if (!privkey) - pos = find_tag (pem_cert_begin, contents, length); - - if (pos) { - const char *end; - - pos += strlen (pem_cert_begin); - end = find_tag (pem_cert_end, pos, contents + length - pos); - if (end == NULL) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_FILE_FORMAT_INVALID, - _("PEM certificate '%s' had no end tag '%s'."), - filename, pem_cert_end); - goto done; - } - contents[end - contents - 1] = '\0'; - der = (char *) g_base64_decode (pos, &length); - if (der == NULL || !length) { + if (g_file_get_contents (filename, &contents, &length, error)) { + array = g_byte_array_sized_new (length); + if (array) { + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + } else { g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_DECODE_FAILED, - _("Failed to decode certificate.")); - goto done; + NM_CRYPTO_ERR_OUT_OF_MEMORY, + _("Not enough memory to store certificate data.")); } + g_free (contents); } - - array = g_byte_array_sized_new (length); - if (!array) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_OUT_OF_MEMORY, - _("Not enough memory to store certificate data.")); - goto done; - } - - g_byte_array_append (array, der ? (unsigned char *) der : (unsigned char *) contents, length); - if (array->len != length) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_OUT_OF_MEMORY, - _("Not enough memory to store file data.")); - g_byte_array_free (array, TRUE); - array = NULL; - } - -done: - g_free (der); - g_free (contents); return array; } @@ -414,13 +383,12 @@ error: return NULL; } -static char * +static GByteArray * decrypt_key (const char *cipher, int key_type, GByteArray *data, const char *iv, const char *password, - gsize *out_len, GError **error) { char *bin_iv = NULL; @@ -428,6 +396,10 @@ decrypt_key (const char *cipher, char *key = NULL; gsize key_len = 0; char *output = NULL; + gsize decrypted_len = 0; + GByteArray *decrypted = NULL; + + g_return_val_if_fail (password != NULL, NULL); bin_iv = convert_iv (iv, &bin_iv_len, error); if (!bin_iv) @@ -442,58 +414,45 @@ decrypt_key (const char *cipher, data, bin_iv, bin_iv_len, key, key_len, - out_len, + &decrypted_len, error); - if (!output) - goto out; - - if (*out_len == 0) { - g_free (output); - output = NULL; - goto out; + if (output && decrypted_len) { + decrypted = g_byte_array_sized_new (decrypted_len); + if (decrypted) + g_byte_array_append (decrypted, (guint8 *) output, decrypted_len); + else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERR_OUT_OF_MEMORY, + _("Not enough memory to store decrypted private key.")); + } } - + out: - if (key) { - /* Don't leak stale key material */ + /* Don't leak stale key material */ + if (key) memset (key, 0, key_len); - g_free (key); - } + g_free (output); + g_free (key); g_free (bin_iv); - return output; + + return decrypted; } GByteArray * -crypto_get_private_key_data (GByteArray *contents, - const char *password, - NMCryptoKeyType *out_key_type, - NMCryptoFileFormat *out_file_type, - GError **error) +crypto_decrypt_private_key_data (const GByteArray *contents, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error) { - GByteArray *array = NULL; + GByteArray *decrypted = NULL; NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_RSA; GByteArray *data; char *iv = NULL; char *cipher = NULL; - char *decrypted = NULL; - gsize decrypted_len = 0; g_return_val_if_fail (contents != NULL, NULL); - g_return_val_if_fail (password != NULL, NULL); - g_return_val_if_fail (out_key_type != NULL, NULL); - g_return_val_if_fail (*out_key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, NULL); - g_return_val_if_fail (out_file_type != NULL, NULL); - g_return_val_if_fail (*out_file_type == NM_CRYPTO_FILE_FORMAT_UNKNOWN, NULL); - - /* Try PKCS#12 first */ - if (crypto_verify_pkcs12 (contents, password, NULL)) { - *out_key_type = NM_CRYPTO_KEY_TYPE_ENCRYPTED; - *out_file_type = NM_CRYPTO_FILE_FORMAT_PKCS12; - - array = g_byte_array_sized_new (contents->len); - g_byte_array_append (array, contents->data, contents->len); - return array; - } + if (out_key_type) + g_return_val_if_fail (*out_key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, NULL); /* OpenSSL non-standard legacy PEM files */ @@ -510,91 +469,142 @@ crypto_get_private_key_data (GByteArray *contents, g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_FILE_FORMAT_INVALID, _("Unable to determine private key type.")); - goto out; } } - decrypted = decrypt_key (cipher, - key_type, - data, - iv, - password, - &decrypted_len, - error); - if (!decrypted) - goto out; - - array = g_byte_array_sized_new (decrypted_len); - if (!array) { - g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_OUT_OF_MEMORY, - _("Not enough memory to store decrypted private key.")); - goto out; + if (data) { + /* return the key type even if decryption failed */ + if (out_key_type) + *out_key_type = key_type; + + if (password) { + decrypted = decrypt_key (cipher, + key_type, + data, + iv, + password, + error); + } + g_byte_array_free (data, TRUE); } - g_byte_array_append (array, (const guint8 *) decrypted, decrypted_len); - *out_key_type = key_type; - *out_file_type = NM_CRYPTO_FILE_FORMAT_RAW_KEY; - -out: - if (decrypted) { - /* Don't expose key material */ - memset (decrypted, 0, decrypted_len); - g_free (decrypted); - } - if (data) - g_byte_array_free (data, TRUE); g_free (cipher); g_free (iv); - return array; + + return decrypted; } GByteArray * -crypto_get_private_key (const char *file, - const char *password, - NMCryptoKeyType *out_key_type, - NMCryptoFileFormat *out_file_type, - GError **error) +crypto_decrypt_private_key (const char *file, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error) { GByteArray *contents; GByteArray *key = NULL; - contents = file_to_g_byte_array (file, TRUE, error); + contents = file_to_g_byte_array (file, error); if (contents) { - key = crypto_get_private_key_data (contents, password, out_key_type, out_file_type, error); + key = crypto_decrypt_private_key_data (contents, password, out_key_type, error); g_byte_array_free (contents, TRUE); } return key; } +static GByteArray * +extract_pem_cert_data (GByteArray *contents, GError **error) +{ + GByteArray *cert = NULL; + gsize start = 0, end = 0; + unsigned char *der = NULL; + guint8 save_end; + gsize length = 0; + + if (!find_tag (PEM_CERT_BEGIN, contents, 0, &start)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERR_FILE_FORMAT_INVALID, + _("PEM certificate had no start tag '%s'."), + PEM_CERT_BEGIN); + goto done; + } + + start += strlen (PEM_CERT_BEGIN); + if (!find_tag (PEM_CERT_END, contents, start, &end)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERR_FILE_FORMAT_INVALID, + _("PEM certificate had no end tag '%s'."), + PEM_CERT_END); + goto done; + } + + /* g_base64_decode() wants a NULL-terminated string */ + save_end = contents->data[end]; + contents->data[end] = '\0'; + der = g_base64_decode ((const char *) (contents->data + start), &length); + contents->data[end] = save_end; + + if (der && length) { + cert = g_byte_array_sized_new (length); + if (cert) { + g_byte_array_append (cert, der, length); + g_assert (cert->len == length); + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERR_OUT_OF_MEMORY, + _("Not enough memory to store certificate data.")); + } + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERR_DECODE_FAILED, + _("Failed to decode certificate.")); + } + +done: + g_free (der); + return cert; +} + GByteArray * crypto_load_and_verify_certificate (const char *file, NMCryptoFileFormat *out_file_format, GError **error) { - GByteArray *array; + GByteArray *array, *contents; g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (out_file_format != NULL, NULL); g_return_val_if_fail (*out_file_format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, NULL); - array = file_to_g_byte_array (file, FALSE, error); - if (!array) + contents = file_to_g_byte_array (file, error); + if (!contents) return NULL; - *out_file_format = crypto_verify_cert (array->data, array->len, error); - if (*out_file_format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { - /* Try PKCS#12 */ - if (crypto_is_pkcs12_data (array)) { - *out_file_format = NM_CRYPTO_FILE_FORMAT_PKCS12; - g_clear_error (error); - } else { - g_byte_array_free (array, TRUE); - array = NULL; + /* Check for PKCS#12 */ + if (crypto_is_pkcs12_data (contents)) { + *out_file_format = NM_CRYPTO_FILE_FORMAT_PKCS12; + return contents; + } + + /* Check for plain DER format */ + if (contents->len > 2 && contents->data[0] == 0x30 && contents->data[1] == 0x82) { + *out_file_format = crypto_verify_cert (contents->data, contents->len, error); + } else { + array = extract_pem_cert_data (contents, error); + if (!array) { + g_byte_array_free (contents, TRUE); + return NULL; } + + *out_file_format = crypto_verify_cert (array->data, array->len, error); + g_byte_array_free (array, TRUE); } - return array; + if (*out_file_format != NM_CRYPTO_FILE_FORMAT_X509) { + g_byte_array_free (contents, TRUE); + contents = NULL; + } + + return contents; } gboolean @@ -606,16 +616,14 @@ crypto_is_pkcs12_data (const GByteArray *data) g_return_val_if_fail (data != NULL, FALSE); success = crypto_verify_pkcs12 (data, NULL, &error); - if (success) - return TRUE; - - /* If the error was just a decryption error, then it's pkcs#12 */ - if (error) { - if (g_error_matches (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED)) - success = TRUE; - g_error_free (error); + if (success == FALSE) { + /* If the error was just a decryption error, then it's pkcs#12 */ + if (error) { + if (g_error_matches (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED)) + success = TRUE; + g_error_free (error); + } } - return success; } @@ -627,7 +635,7 @@ crypto_is_pkcs12_file (const char *file, GError **error) g_return_val_if_fail (file != NULL, FALSE); - contents = file_to_g_byte_array (file, TRUE, error); + contents = file_to_g_byte_array (file, error); if (contents) { success = crypto_is_pkcs12_data (contents); g_byte_array_free (contents, TRUE); @@ -635,3 +643,52 @@ crypto_is_pkcs12_file (const char *file, GError **error) return success; } +/* Verifies that a private key can be read, and if a password is given, that + * the private key can be decrypted with that password. + */ +NMCryptoFileFormat +crypto_verify_private_key_data (const GByteArray *contents, + const char *password, + GError **error) +{ + GByteArray *tmp; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + NMCryptoKeyType ktype = NM_CRYPTO_KEY_TYPE_UNKNOWN; + + g_return_val_if_fail (contents != NULL, FALSE); + + /* Check for PKCS#12 first */ + if (crypto_is_pkcs12_data (contents)) { + if (!password || crypto_verify_pkcs12 (contents, password, error)) + format = NM_CRYPTO_FILE_FORMAT_PKCS12; + } else { + tmp = crypto_decrypt_private_key_data (contents, password, &ktype, error); + if (tmp) { + /* Don't leave decrypted key data around */ + memset (tmp->data, 0, tmp->len); + g_byte_array_free (tmp, TRUE); + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } else if (!password && (ktype != NM_CRYPTO_KEY_TYPE_UNKNOWN)) + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } + return format; +} + +NMCryptoFileFormat +crypto_verify_private_key (const char *filename, + const char *password, + GError **error) +{ + GByteArray *contents; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + g_return_val_if_fail (filename != NULL, FALSE); + + contents = file_to_g_byte_array (filename, error); + if (contents) { + format = crypto_verify_private_key_data (contents, password, error); + g_byte_array_free (contents, TRUE); + } + return format; +} + diff --git a/libnm-util/crypto.h b/libnm-util/crypto.h index 38471cea..cdf053e7 100644 --- a/libnm-util/crypto.h +++ b/libnm-util/crypto.h @@ -18,9 +18,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. */ +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ + #include <glib.h> #define MD5_HASH_LEN 20 @@ -51,8 +54,7 @@ enum { typedef enum { NM_CRYPTO_KEY_TYPE_UNKNOWN = 0, NM_CRYPTO_KEY_TYPE_RSA, - NM_CRYPTO_KEY_TYPE_DSA, - NM_CRYPTO_KEY_TYPE_ENCRYPTED + NM_CRYPTO_KEY_TYPE_DSA } NMCryptoKeyType; typedef enum { @@ -69,26 +71,31 @@ gboolean crypto_init (GError **error); void crypto_deinit (void); -GByteArray * crypto_get_private_key_data (GByteArray *contents, - const char *password, - NMCryptoKeyType *out_key_type, - NMCryptoFileFormat *out_file_format, - GError **error); +GByteArray *crypto_decrypt_private_key_data (const GByteArray *contents, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error); -GByteArray * crypto_get_private_key (const char *file, - const char *password, - NMCryptoKeyType *out_key_type, - NMCryptoFileFormat *out_file_format, - GError **error); +GByteArray *crypto_decrypt_private_key (const char *file, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error); -GByteArray * crypto_load_and_verify_certificate (const char *file, - NMCryptoFileFormat *out_file_format, - GError **error); +GByteArray *crypto_load_and_verify_certificate (const char *file, + NMCryptoFileFormat *out_file_format, + GError **error); gboolean crypto_is_pkcs12_file (const char *file, GError **error); gboolean crypto_is_pkcs12_data (const GByteArray *data); +NMCryptoFileFormat crypto_verify_private_key_data (const GByteArray *contents, + const char *password, + GError **error); + +NMCryptoFileFormat crypto_verify_private_key (const char *file, + const char *password, + GError **error); /* Internal utils API bits for crypto providers */ @@ -129,3 +136,4 @@ gboolean crypto_verify_pkcs12 (const GByteArray *data, const char *password, GError **error); +#endif /* __CRYPTO_H__ */ diff --git a/libnm-util/crypto_gnutls.c b/libnm-util/crypto_gnutls.c index 0fee84c8..583eb8be 100644 --- a/libnm-util/crypto_gnutls.c +++ b/libnm-util/crypto_gnutls.c @@ -21,6 +21,7 @@ * (C) Copyright 2007 - 2009 Red Hat, Inc. */ +#include "config.h" #include <glib.h> #include <glib/gi18n.h> diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 7fce9a67..bb988bc4 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -10,11 +10,27 @@ global: nm_connection_error_get_type; nm_connection_error_quark; nm_connection_for_each_setting_value; + nm_connection_get_id; nm_connection_get_path; - nm_connection_get_scope; nm_connection_get_setting; + nm_connection_get_setting_802_1x; + nm_connection_get_setting_bluetooth; nm_connection_get_setting_by_name; + nm_connection_get_setting_cdma; + nm_connection_get_setting_connection; + nm_connection_get_setting_gsm; + nm_connection_get_setting_ip4_config; + nm_connection_get_setting_ip6_config; + nm_connection_get_setting_olpc_mesh; + nm_connection_get_setting_ppp; + nm_connection_get_setting_pppoe; + nm_connection_get_setting_vpn; + nm_connection_get_setting_wimax; + nm_connection_get_setting_wired; + nm_connection_get_setting_wireless; + nm_connection_get_setting_wireless_security; nm_connection_get_type; + nm_connection_get_uuid; nm_connection_lookup_setting_type; nm_connection_lookup_setting_type_by_quark; nm_connection_need_secrets; @@ -23,7 +39,6 @@ global: nm_connection_remove_setting; nm_connection_replace_settings; nm_connection_set_path; - nm_connection_set_scope; nm_connection_to_hash; nm_connection_update_secrets; nm_connection_verify; @@ -32,6 +47,7 @@ global: nm_ip4_address_get_address; nm_ip4_address_get_gateway; nm_ip4_address_get_prefix; + nm_ip4_address_get_type; nm_ip4_address_new; nm_ip4_address_ref; nm_ip4_address_set_address; @@ -44,6 +60,7 @@ global: nm_ip4_route_get_metric; nm_ip4_route_get_next_hop; nm_ip4_route_get_prefix; + nm_ip4_route_get_type; nm_ip4_route_new; nm_ip4_route_ref; nm_ip4_route_set_dest; @@ -56,6 +73,7 @@ global: nm_ip6_address_get_address; nm_ip6_address_get_gateway; nm_ip6_address_get_prefix; + nm_ip6_address_get_type; nm_ip6_address_new; nm_ip6_address_ref; nm_ip6_address_set_address; @@ -68,6 +86,7 @@ global: nm_ip6_route_get_metric; nm_ip6_route_get_next_hop; nm_ip6_route_get_prefix; + nm_ip6_route_get_type; nm_ip6_route_new; nm_ip6_route_ref; nm_ip6_route_set_dest; @@ -80,12 +99,10 @@ global: nm_setting_802_1x_error_get_type; nm_setting_802_1x_error_quark; nm_setting_802_1x_get_anonymous_identity; - nm_setting_802_1x_get_ca_cert; nm_setting_802_1x_get_ca_cert_blob; nm_setting_802_1x_get_ca_cert_path; nm_setting_802_1x_get_ca_cert_scheme; nm_setting_802_1x_get_ca_path; - nm_setting_802_1x_get_client_cert; nm_setting_802_1x_get_client_cert_blob; nm_setting_802_1x_get_client_cert_path; nm_setting_802_1x_get_client_cert_scheme; @@ -93,52 +110,42 @@ global: nm_setting_802_1x_get_identity; nm_setting_802_1x_get_num_eap_methods; nm_setting_802_1x_get_password; + nm_setting_802_1x_get_password_flags; nm_setting_802_1x_get_phase1_fast_provisioning; nm_setting_802_1x_get_phase1_peaplabel; nm_setting_802_1x_get_phase1_peapver; nm_setting_802_1x_get_phase2_auth; nm_setting_802_1x_get_phase2_autheap; - nm_setting_802_1x_get_phase2_ca_cert; nm_setting_802_1x_get_phase2_ca_cert_blob; nm_setting_802_1x_get_phase2_ca_cert_path; nm_setting_802_1x_get_phase2_ca_cert_scheme; nm_setting_802_1x_get_phase2_ca_path; - nm_setting_802_1x_get_phase2_client_cert; nm_setting_802_1x_get_phase2_client_cert_blob; nm_setting_802_1x_get_phase2_client_cert_path; nm_setting_802_1x_get_phase2_client_cert_scheme; - nm_setting_802_1x_get_phase2_private_key; nm_setting_802_1x_get_phase2_private_key_blob; nm_setting_802_1x_get_phase2_private_key_format; nm_setting_802_1x_get_phase2_private_key_password; + nm_setting_802_1x_get_phase2_private_key_password_flags; nm_setting_802_1x_get_phase2_private_key_path; nm_setting_802_1x_get_phase2_private_key_scheme; - nm_setting_802_1x_get_phase2_private_key_type; nm_setting_802_1x_get_pin; - nm_setting_802_1x_get_private_key; nm_setting_802_1x_get_private_key_blob; nm_setting_802_1x_get_private_key_format; nm_setting_802_1x_get_private_key_password; + nm_setting_802_1x_get_private_key_password_flags; nm_setting_802_1x_get_private_key_path; nm_setting_802_1x_get_private_key_scheme; - nm_setting_802_1x_get_private_key_type; - nm_setting_802_1x_get_psk; nm_setting_802_1x_get_system_ca_certs; nm_setting_802_1x_get_type; nm_setting_802_1x_new; nm_setting_802_1x_remove_eap_method; nm_setting_802_1x_set_ca_cert; - nm_setting_802_1x_set_ca_cert_from_file; nm_setting_802_1x_set_client_cert; - nm_setting_802_1x_set_client_cert_from_file; nm_setting_802_1x_set_phase2_ca_cert; - nm_setting_802_1x_set_phase2_ca_cert_from_file; nm_setting_802_1x_set_phase2_client_cert; - nm_setting_802_1x_set_phase2_client_cert_from_file; nm_setting_802_1x_set_phase2_private_key; - nm_setting_802_1x_set_phase2_private_key_from_file; nm_setting_802_1x_set_private_key; - nm_setting_802_1x_set_private_key_from_file; nm_setting_bluetooth_error_get_type; nm_setting_bluetooth_error_quark; nm_setting_bluetooth_get_bdaddr; @@ -149,40 +156,47 @@ global: nm_setting_cdma_error_quark; nm_setting_cdma_get_number; nm_setting_cdma_get_password; + nm_setting_cdma_get_password_flags; nm_setting_cdma_get_type; nm_setting_cdma_get_username; nm_setting_cdma_new; nm_setting_clear_secrets; nm_setting_compare; + nm_setting_connection_add_permission; nm_setting_connection_error_get_type; nm_setting_connection_error_quark; nm_setting_connection_get_autoconnect; nm_setting_connection_get_connection_type; nm_setting_connection_get_id; + nm_setting_connection_get_num_permissions; + nm_setting_connection_get_permission; nm_setting_connection_get_read_only; nm_setting_connection_get_timestamp; nm_setting_connection_get_type; nm_setting_connection_get_uuid; nm_setting_connection_new; + nm_setting_connection_permissions_user_allowed; + nm_setting_connection_remove_permission; nm_setting_diff; nm_setting_duplicate; nm_setting_enumerate_values; nm_setting_error_get_type; nm_setting_error_quark; nm_setting_get_name; + nm_setting_get_secret_flags; nm_setting_get_type; nm_setting_gsm_error_get_type; nm_setting_gsm_error_quark; nm_setting_gsm_get_allowed_bands; nm_setting_gsm_get_apn; - nm_setting_gsm_get_band; nm_setting_gsm_get_home_only; nm_setting_gsm_get_network_id; nm_setting_gsm_get_network_type; nm_setting_gsm_get_number; nm_setting_gsm_get_password; + nm_setting_gsm_get_password_flags; nm_setting_gsm_get_pin; - nm_setting_gsm_get_puk; + nm_setting_gsm_get_pin_flags; nm_setting_gsm_get_type; nm_setting_gsm_get_username; nm_setting_gsm_new; @@ -281,6 +295,7 @@ global: nm_setting_pppoe_error_get_type; nm_setting_pppoe_error_quark; nm_setting_pppoe_get_password; + nm_setting_pppoe_get_password_flags; nm_setting_pppoe_get_service; nm_setting_pppoe_get_type; nm_setting_pppoe_get_username; @@ -294,6 +309,7 @@ global: nm_setting_serial_get_stopbits; nm_setting_serial_get_type; nm_setting_serial_new; + nm_setting_set_secret_flags; nm_setting_to_hash; nm_setting_to_string; nm_setting_update_secrets; @@ -312,6 +328,12 @@ global: nm_setting_vpn_new; nm_setting_vpn_remove_data_item; nm_setting_vpn_remove_secret; + nm_setting_wimax_error_get_type; + nm_setting_wimax_error_quark; + nm_setting_wimax_get_mac_address; + nm_setting_wimax_get_network_name; + nm_setting_wimax_get_type; + nm_setting_wimax_new; nm_setting_wired_add_s390_option; nm_setting_wired_error_get_type; nm_setting_wired_error_quark; @@ -361,6 +383,7 @@ global: nm_setting_wireless_security_get_group; nm_setting_wireless_security_get_key_mgmt; nm_setting_wireless_security_get_leap_password; + nm_setting_wireless_security_get_leap_password_flags; nm_setting_wireless_security_get_leap_username; nm_setting_wireless_security_get_num_groups; nm_setting_wireless_security_get_num_pairwise; @@ -368,8 +391,10 @@ global: nm_setting_wireless_security_get_pairwise; nm_setting_wireless_security_get_proto; nm_setting_wireless_security_get_psk; + nm_setting_wireless_security_get_psk_flags; nm_setting_wireless_security_get_type; nm_setting_wireless_security_get_wep_key; + nm_setting_wireless_security_get_wep_key_flags; nm_setting_wireless_security_get_wep_key_type; nm_setting_wireless_security_get_wep_tx_keyidx; nm_setting_wireless_security_new; @@ -390,6 +415,8 @@ global: nm_utils_ip4_routes_to_gvalue; nm_utils_ip6_addresses_from_gvalue; nm_utils_ip6_addresses_to_gvalue; + nm_utils_ip6_dns_from_gvalue; + nm_utils_ip6_dns_to_gvalue; nm_utils_ip6_routes_from_gvalue; nm_utils_ip6_routes_to_gvalue; nm_utils_is_empty_ssid; diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 82e44b7b..cd9d53ff 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -29,6 +29,7 @@ #include "nm-connection.h" #include "nm-utils.h" #include "nm-utils-private.h" +#include "nm-dbus-glib-types.h" #include "nm-setting-8021x.h" #include "nm-setting-bluetooth.h" @@ -37,6 +38,7 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" +#include "nm-setting-wimax.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" @@ -65,12 +67,6 @@ * parameters (MTU, SSID, APN, channel, rate, etc) and IP-level parameters * (addresses, routes, addressing methods, etc). * - * Most connections also have a %NMConnectionScope; a connection will be - * provided over D-Bus either by the user settings service - * (org.freedesktop.NetworkManagerUserSettings) running in an active user - * session, or by the system-wide system settings service - * (org.freedesktop.NetworkManagerSystemSettings) which provides connections - * for all users. */ /** @@ -102,6 +98,7 @@ nm_connection_error_get_type (void) static const GEnumValue values[] = { ENUM_ENTRY (NM_CONNECTION_ERROR_UNKNOWN, "UnknownError"), ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "ConnectionSettingNotFound"), + ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "ConnectionTypeInvalid"), { 0, 0, 0 } }; etype = g_enum_register_static ("NMConnectionError", values); @@ -112,9 +109,6 @@ nm_connection_error_get_type (void) typedef struct { GHashTable *settings; - /* Type of the connection (system or user) */ - NMConnectionScope scope; - /* D-Bus path of the connection, if any */ char *path; } NMConnectionPrivate; @@ -125,7 +119,6 @@ G_DEFINE_TYPE (NMConnection, nm_connection, G_TYPE_OBJECT) enum { PROP_0, - PROP_SCOPE, PROP_PATH, LAST_PROP @@ -141,12 +134,13 @@ static guint signals[LAST_SIGNAL] = { 0 }; static GHashTable *registered_settings = NULL; -#define DEFAULT_MAP_SIZE 15 +#define DEFAULT_MAP_SIZE 16 static struct SettingInfo { const char *name; GType type; guint32 priority; + gboolean base_type; GQuark error_quark; } default_map[DEFAULT_MAP_SIZE] = { { NULL } }; @@ -168,7 +162,7 @@ setting_register (const char *name, GType type) g_hash_table_insert (registered_settings, g_strdup (name), g_strdup (g_type_name (type))); } -#if UNUSED +#if 0 static void setting_unregister (const char *name) { @@ -178,7 +172,11 @@ setting_unregister (const char *name) #endif static void -register_one_setting (const char *name, GType type, GQuark error_quark, guint32 priority) +register_one_setting (const char *name, + GType type, + GQuark error_quark, + guint32 priority, + gboolean base_type) { static guint32 i = 0; @@ -189,6 +187,7 @@ register_one_setting (const char *name, GType type, GQuark error_quark, guint32 default_map[i].type = type; default_map[i].error_quark = error_quark; default_map[i].priority = priority; + default_map[i].base_type = base_type; i++; setting_register (name, type); @@ -205,77 +204,82 @@ register_default_settings (void) register_one_setting (NM_SETTING_CONNECTION_SETTING_NAME, NM_TYPE_SETTING_CONNECTION, NM_SETTING_CONNECTION_ERROR, - 0); + 0, FALSE); register_one_setting (NM_SETTING_WIRED_SETTING_NAME, NM_TYPE_SETTING_WIRED, NM_SETTING_WIRED_ERROR, - 1); + 1, TRUE); register_one_setting (NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS, NM_SETTING_WIRELESS_ERROR, - 1); + 1, TRUE); register_one_setting (NM_SETTING_OLPC_MESH_SETTING_NAME, NM_TYPE_SETTING_OLPC_MESH, NM_SETTING_OLPC_MESH_ERROR, - 1); + 1, TRUE); register_one_setting (NM_SETTING_GSM_SETTING_NAME, NM_TYPE_SETTING_GSM, NM_SETTING_GSM_ERROR, - 1); + 1, TRUE); register_one_setting (NM_SETTING_CDMA_SETTING_NAME, NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_ERROR, - 1); + 1, TRUE); register_one_setting (NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_TYPE_SETTING_BLUETOOTH, - NM_SETTING_BLUETOOTH_ERROR, - 1); + NM_TYPE_SETTING_BLUETOOTH, + NM_SETTING_BLUETOOTH_ERROR, + 1, TRUE); + + register_one_setting (NM_SETTING_WIMAX_SETTING_NAME, + NM_TYPE_SETTING_WIMAX, + NM_SETTING_WIMAX_ERROR, + 1, TRUE); register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY, NM_SETTING_WIRELESS_SECURITY_ERROR, - 2); + 2, FALSE); register_one_setting (NM_SETTING_SERIAL_SETTING_NAME, NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_ERROR, - 2); + 2, FALSE); register_one_setting (NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP, NM_SETTING_PPP_ERROR, - 3); + 3, FALSE); register_one_setting (NM_SETTING_PPPOE_SETTING_NAME, NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_ERROR, - 3); + 3, TRUE); register_one_setting (NM_SETTING_802_1X_SETTING_NAME, NM_TYPE_SETTING_802_1X, NM_SETTING_802_1X_ERROR, - 3); + 3, FALSE); register_one_setting (NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN, NM_SETTING_VPN_ERROR, - 4); + 4, TRUE); register_one_setting (NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_ERROR, - 6); + 6, FALSE); register_one_setting (NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_ERROR, - 6); + 6, FALSE); /* Be sure to update DEFAULT_MAP_SIZE if you add another setting!! */ } @@ -293,6 +297,18 @@ get_priority_for_setting_type (GType type) return G_MAXUINT32; } +static gboolean +get_base_type_for_setting_type (GType type) +{ + int i; + + for (i = 0; default_map[i].name; i++) { + if (default_map[i].type == type) + return default_map[i].base_type; + } + return FALSE; +} + /** * nm_connection_lookup_setting_type: * @name: a setting name @@ -353,7 +369,7 @@ nm_connection_lookup_setting_type_by_quark (GQuark error_quark) * * Create a new #NMSetting object of the desired type, given a setting name. * - * Returns: the new setting object, or NULL if the setting name was unknown + * Returns: (transfer full): the new setting object, or NULL if the setting name was unknown **/ NMSetting * nm_connection_create_setting (const char *name) @@ -387,7 +403,7 @@ parse_one_setting (gpointer key, gpointer value, gpointer user_data) /** * nm_connection_add_setting: * @connection: a #NMConnection - * @setting: the #NMSetting to add to the connection object + * @setting: (transfer full): the #NMSetting to add to the connection object * * Adds a #NMSetting to the connection, replacing any previous #NMSetting of the * same name which has previously been added to the #NMConnection. The @@ -429,7 +445,7 @@ nm_connection_remove_setting (NMConnection *connection, GType setting_type) * Gets the #NMSetting with the given #GType, if one has been previously added * to the #NMConnection. * - * Returns: the #NMSetting, or NULL if no setting of that type was previously + * Returns: (transfer none): the #NMSetting, or NULL if no setting of that type was previously * added to the #NMConnection **/ NMSetting * @@ -450,7 +466,7 @@ nm_connection_get_setting (NMConnection *connection, GType setting_type) * Gets the #NMSetting with the given name, if one has been previously added * the the #NMConnection. * - * Returns: the #NMSetting, or NULL if no setting with that name was previously + * Returns: (transfer none): the #NMSetting, or NULL if no setting with that name was previously * added to the #NMConnection **/ NMSetting * @@ -466,10 +482,37 @@ nm_connection_get_setting_by_name (NMConnection *connection, const char *name) return type ? nm_connection_get_setting (connection, type) : NULL; } +static gboolean +validate_permissions_type (GHashTable *hash, GError **error) +{ + GHashTable *s_con; + GValue *permissions; + + /* Ensure the connection::permissions item (if present) is the correct + * type, otherwise the g_object_set() will throw a warning and ignore the + * error, leaving us with no permissions. + */ + s_con = g_hash_table_lookup (hash, NM_SETTING_CONNECTION_SETTING_NAME); + if (s_con) { + permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS); + if (permissions) { + if ( !G_VALUE_HOLDS (permissions, G_TYPE_STRV) + && !G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) { + g_set_error_literal (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Wrong permissions property type; should be a list of strings."); + return FALSE; + } + } + } + return TRUE; +} + /** * nm_connection_replace_settings: * @connection: a #NMConnection - * @new_settings: a #GHashTable of settings + * @new_settings: (element-type utf8 GHashTable<utf8,GValue>): a #GHashTable of settings * @error: location to store error, or %NULL * * Returns: %TRUE if the settings were valid and added to the connection, %FALSE @@ -486,6 +529,9 @@ nm_connection_replace_settings (NMConnection *connection, if (error) g_return_val_if_fail (*error == NULL, FALSE); + if (!validate_permissions_type (new_settings, error)) + return FALSE; + g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings); g_hash_table_foreach (new_settings, parse_one_setting, connection); @@ -594,8 +640,9 @@ diff_one_connection (NMConnection *a, * @a: a #NMConnection * @b: a second #NMConnection to compare with the first * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT - * @out_settings: if the connections differ, on return a hash table mapping - * setting names to second-level GHashTable, which contains key names that differ + * @out_settings: (element-type utf8 GHashTable<utf8,guint32>): if the + * connections differ, on return a hash table mapping setting names to + * second-level GHashTable, which contains key names that differ * * Compares two #NMConnection objects for similarity, with comparison behavior * modified by a set of flags. See nm_setting_compare() for a description of @@ -665,15 +712,17 @@ nm_connection_verify (NMConnection *connection, GError **error) gpointer value; GSList *all_settings = NULL; gboolean success = TRUE; + const char *ctype; + GType base_type; if (error) g_return_val_if_fail (*error == NULL, FALSE); if (!NM_IS_CONNECTION (connection)) { - g_set_error (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_UNKNOWN, - "invalid connection; failed verification"); + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_UNKNOWN, + "invalid connection; failed verification"); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); } @@ -682,10 +731,10 @@ nm_connection_verify (NMConnection *connection, GError **error) /* First, make sure there's at least 'connection' setting */ s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); if (!s_con) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, - "connection setting not found"); + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, + "connection setting not found"); return FALSE; } @@ -698,22 +747,57 @@ nm_connection_verify (NMConnection *connection, GError **error) g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, NULL, &value) && success) success = nm_setting_verify (NM_SETTING (value), all_settings, error); - g_slist_free (all_settings); - return success; + + if (success == FALSE) + return FALSE; + + /* Now make sure the given 'type' setting can actually be the base setting + * of the connection. Can't have type=ppp for example. + */ + ctype = nm_setting_connection_get_connection_type (NM_SETTING_CONNECTION (s_con)); + if (!ctype) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, + "connection type missing"); + return FALSE; + } + + base_type = nm_connection_lookup_setting_type (ctype); + if (base_type == 0) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, + "base setting GType not found"); + return FALSE; + } + + if (!get_base_type_for_setting_type (base_type)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, + "connection type '%s' is not a base type", + ctype); + return FALSE; + } + + return TRUE; } /** * nm_connection_update_secrets: * @connection: the #NMConnection * @setting_name: the setting object name to which the secrets apply - * @setting_secrets: a #GHashTable mapping string:#GValue of setting property names and - * secrets + * @setting_secrets: (element-type utf8 GObject.Value): a #GHashTable mapping + * string:#GValue of setting property names and secrets of the given @setting_name * @error: location to store error, or %NULL * * Update the specified setting's secrets, given a hash table of secrets - * intended for that setting (deserialized from D-Bus for example). - * + * intended for that setting (deserialized from D-Bus for example). Will also + * extract the given setting's secrets hash if given a hash of hashes, as would + * be returned from nm_connection_to_hash(). + * * Returns: %TRUE if the secrets were successfully updated and the connection * is valid, %FALSE on failure or if the setting was never added to the connection **/ @@ -725,6 +809,8 @@ nm_connection_update_secrets (NMConnection *connection, { NMSetting *setting; gboolean success; + GHashTable *tmp; + GType setting_type; g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); @@ -733,7 +819,16 @@ nm_connection_update_secrets (NMConnection *connection, if (error) g_return_val_if_fail (*error == NULL, FALSE); - setting = nm_connection_get_setting (connection, nm_connection_lookup_setting_type (setting_name)); + setting_type = nm_connection_lookup_setting_type (setting_name); + if (!setting_type) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, + setting_name); + return FALSE; + } + + setting = nm_connection_get_setting (connection, setting_type); if (!setting) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -742,7 +837,12 @@ nm_connection_update_secrets (NMConnection *connection, return FALSE; } - success = nm_setting_update_secrets (setting, setting_secrets, error); + /* Check if this is a hash of hashes, ie a full deserialized connection, + * not just a single hashed setting. + */ + tmp = g_hash_table_lookup (setting_secrets, setting_name); + + success = nm_setting_update_secrets (setting, tmp ? tmp : setting_secrets, error); if (success) g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name); return success; @@ -774,11 +874,12 @@ add_setting_to_list (gpointer key, gpointer data, gpointer user_data) /** * nm_connection_need_secrets: * @connection: the #NMConnection - * @hints: the address of a pointer to a #GPtrArray, initialized to NULL, which - * on return points to an allocated #GPtrArray containing the property names of - * secrets of the #NMSetting which may be required; the caller owns the array - * and must free the each array element with g_free(), as well as the array - * itself with g_ptr_array_free() + * @hints: (out callee-allocates) (element-type utf8) (allow-none) (transfer full): + * the address of a pointer to a #GPtrArray, initialized to NULL, which on + * return points to an allocated #GPtrArray containing the property names of + * secrets of the #NMSetting which may be required; the caller owns the array + * and must free the each array element with g_free(), as well as the array + * itself with g_ptr_array_free() * * Returns the name of the first setting object in the connection which would * need secrets to make a successful connection. The returned hints are only @@ -787,7 +888,7 @@ add_setting_to_list (gpointer key, gpointer data, gpointer user_data) * secrets are needed. * * Returns: the setting name of the #NMSetting object which has invalid or - * missing secrets + * missing secrets **/ const char * nm_connection_need_secrets (NMConnection *connection, @@ -855,26 +956,10 @@ nm_connection_clear_secrets (NMConnection *connection) g_hash_table_foreach (priv->settings, clear_setting_secrets, NULL); } -static void -add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) -{ - NMSetting *setting = (NMSetting *) data; - GHashTable *connection_hash = (GHashTable *) user_data; - GHashTable *setting_hash; - - g_return_if_fail (setting != NULL); - g_return_if_fail (connection_hash != NULL); - - setting_hash = nm_setting_to_hash (setting); - if (setting_hash) - g_hash_table_insert (connection_hash, - g_strdup (nm_setting_get_name (setting)), - setting_hash); -} - /** * nm_connection_to_hash: * @connection: the #NMConnection + * @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL * * Converts the #NMConnection into a #GHashTable describing the connection, * suitable for marshalling over D-Bus or serializing. The hash table mapping @@ -883,50 +968,50 @@ add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) * are #GHashTables mapping string:GValue, each of which represents the * properties of the #NMSetting object. * - * Returns: a new #GHashTable describing the connection, its settings, and - * each setting's properties. The caller owns the hash table and must unref - * the hash table with g_hash_table_unref() when it is no longer needed. + * Returns: (transfer full) (element-type utf8 GHashTable<utf8,GValue>): a new + * #GHashTable describing the connection, its settings, and each setting's + * properties. The caller owns the hash table and must unref the hash table + * with g_hash_table_unref() when it is no longer needed. **/ GHashTable * -nm_connection_to_hash (NMConnection *connection) +nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) { NMConnectionPrivate *priv; - GHashTable *connection_hash; + GHashTableIter iter; + gpointer key, data; + GHashTable *ret, *setting_hash; + g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - connection_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); + ret = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_hash_table_destroy); priv = NM_CONNECTION_GET_PRIVATE (connection); - g_hash_table_foreach (priv->settings, add_one_setting_to_hash, connection_hash); - /* Don't send empty hashes */ - if (g_hash_table_size (connection_hash) < 1) { - g_hash_table_destroy (connection_hash); - connection_hash = NULL; - } - - return connection_hash; -} + /* Add each setting's hash to the main hash */ + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, &key, &data)) { + NMSetting *setting = NM_SETTING (data); -typedef struct ForEachValueInfo { - NMSettingValueIterFn func; - gpointer user_data; -} ForEachValueInfo; + setting_hash = nm_setting_to_hash (setting, flags); + if (setting_hash) + g_hash_table_insert (ret, g_strdup (nm_setting_get_name (setting)), setting_hash); + } -static void -for_each_setting (gpointer key, gpointer value, gpointer user_data) -{ - ForEachValueInfo *info = (ForEachValueInfo *) user_data; + /* Don't send empty hashes */ + if (g_hash_table_size (ret) < 1) { + g_hash_table_destroy (ret); + ret = NULL; + } - nm_setting_enumerate_values (NM_SETTING (value), info->func, info->user_data); + return ret; } /** * nm_connection_for_each_setting_value: * @connection: the #NMConnection - * @func: user-supplied function called for each setting's property + * @func: (scope call): user-supplied function called for each setting's property * @user_data: user data passed to @func at each invocation * * Iterates over the properties of each #NMSetting object in the #NMConnection, @@ -937,25 +1022,15 @@ nm_connection_for_each_setting_value (NMConnection *connection, NMSettingValueIterFn func, gpointer user_data) { - NMConnectionPrivate *priv; - ForEachValueInfo *info; + GHashTableIter iter; + gpointer value; g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (func != NULL); - priv = NM_CONNECTION_GET_PRIVATE (connection); - - info = g_slice_new0 (ForEachValueInfo); - if (!info) { - g_warning ("Not enough memory to enumerate values."); - return; - } - info->func = func; - info->user_data = user_data; - - g_hash_table_foreach (priv->settings, for_each_setting, info); - - g_slice_free (ForEachValueInfo, info); + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, &value)) + nm_setting_enumerate_values (NM_SETTING (value), func, user_data); } static void @@ -985,43 +1060,6 @@ nm_connection_dump (NMConnection *connection) } /** - * nm_connection_set_scope: - * @connection: the #NMConnection - * @scope: the scope of the connection - * - * Sets the scope of the connection. This property is not serialized, and is - * only for the reference of the caller. A connection may have no scope - * (internal, temporary connections), "system" scope (provided by the system - * settings service), or "user" scope, provided by a user settings service. The - * creator of the #NMConnection object is responsible for setting the - * connection's scope if needed. Sets the #NMConnection:scope property. - **/ -void -nm_connection_set_scope (NMConnection *connection, NMConnectionScope scope) -{ - g_return_if_fail (NM_IS_CONNECTION (connection)); - - NM_CONNECTION_GET_PRIVATE (connection)->scope = scope; -} - -/** - * nm_connection_get_scope: - * @connection: the #NMConnection - * - * Returns the connection scope. - * - * Returns: the scope of the connection, previously set by a call to - * nm_connection_set_scope(). - **/ -NMConnectionScope -nm_connection_get_scope (NMConnection *connection) -{ - g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_CONNECTION_SCOPE_UNKNOWN); - - return NM_CONNECTION_GET_PRIVATE (connection)->scope; -} - -/** * nm_connection_set_path: * @connection: the #NMConnection * @path: the D-Bus path of the connection as given by the settings service @@ -1040,10 +1078,8 @@ nm_connection_set_path (NMConnection *connection, const char *path) priv = NM_CONNECTION_GET_PRIVATE (connection); - if (priv->path) { - g_free (priv->path); - priv->path = NULL; - } + g_free (priv->path); + priv->path = NULL; if (path) priv->path = g_strdup (path); @@ -1088,7 +1124,8 @@ nm_connection_new (void) /** * nm_connection_new_from_hash: - * @hash: the #GHashTable describing the connection + * @hash: (element-type utf8 GLib.HashTable): the #GHashTable describing + * the connection * @error: on unsuccessful return, an error * * Creates a new #NMConnection from a hash table describing the connection. See @@ -1105,6 +1142,9 @@ nm_connection_new_from_hash (GHashTable *hash, GError **error) g_return_val_if_fail (hash != NULL, NULL); + if (!validate_permissions_type (hash, error)) + return NULL; + connection = nm_connection_new (); g_hash_table_foreach (hash, parse_one_setting, connection); @@ -1128,7 +1168,7 @@ duplicate_cb (gpointer key, gpointer value, gpointer user_data) * * Duplicates a #NMConnection. * - * Returns: a new #NMConnection containing the same settings and properties + * Returns: (transfer full): a new #NMConnection containing the same settings and properties * as the source #NMConnection **/ NMConnection * @@ -1139,13 +1179,315 @@ nm_connection_duplicate (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); dup = nm_connection_new (); - nm_connection_set_scope (dup, nm_connection_get_scope (connection)); nm_connection_set_path (dup, nm_connection_get_path (connection)); g_hash_table_foreach (NM_CONNECTION_GET_PRIVATE (connection)->settings, duplicate_cb, dup); return dup; } +/** + * nm_connection_get_uuid: + * @connection: the #NMConnection + * + * A shortcut to return the UUID from the connection's #NMSettingConnection. + * + * Returns: the UUID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_uuid (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_uuid (s_con); +} + +/** + * nm_connection_get_id: + * @connection: the #NMConnection + * + * A shortcut to return the ID from the connection's #NMSettingConnection. + * + * Returns: the ID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_id (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_id (s_con); +} + +/*************************************************************/ + +/** + * nm_connection_get_setting_802_1x: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSetting8021x the connection might contain. + * + * Returns: (transfer none): an #NMSetting8021x if the connection contains one, otherwise NULL + **/ +NMSetting8021x * +nm_connection_get_setting_802_1x (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); +} + +/** + * nm_connection_get_setting_bluetooth: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBluetooth the connection might contain. + * + * Returns: (transfer none): an #NMSettingBluetooth if the connection contains one, otherwise NULL + **/ +NMSettingBluetooth * +nm_connection_get_setting_bluetooth (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); +} + +/** + * nm_connection_get_setting_cdma: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingCdma the connection might contain. + * + * Returns: (transfer none): an #NMSettingCdma if the connection contains one, otherwise NULL + **/ +NMSettingCdma * +nm_connection_get_setting_cdma (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); +} + +/** + * nm_connection_get_setting_connection: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingConnection the connection might contain. + * + * Returns: (transfer none): an #NMSettingConnection if the connection contains one, otherwise NULL + **/ +NMSettingConnection * +nm_connection_get_setting_connection (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); +} + +/** + * nm_connection_get_setting_gsm: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingGsm the connection might contain. + * + * Returns: (transfer none): an #NMSettingGsm if the connection contains one, otherwise NULL + **/ +NMSettingGsm * +nm_connection_get_setting_gsm (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); +} + +/** + * nm_connection_get_setting_ip4_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP4Config the connection might contain. + * + * Returns: (transfer none): an #NMSettingIP4Config if the connection contains one, otherwise NULL + **/ +NMSettingIP4Config * +nm_connection_get_setting_ip4_config (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); +} + +/** + * nm_connection_get_setting_ip6_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP6Config the connection might contain. + * + * Returns: (transfer none): an #NMSettingIP6Config if the connection contains one, otherwise NULL + **/ +NMSettingIP6Config * +nm_connection_get_setting_ip6_config (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); +} + +/** + * nm_connection_get_setting_olpc_mesh: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOlpcMesh the connection might contain. + * + * Returns: (transfer none): an #NMSettingOlpcMesh if the connection contains one, otherwise NULL + **/ +NMSettingOlpcMesh * +nm_connection_get_setting_olpc_mesh (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH); +} + +/** + * nm_connection_get_setting_ppp: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPPP the connection might contain. + * + * Returns: (transfer none): an #NMSettingPPP if the connection contains one, otherwise NULL + **/ +NMSettingPPP * +nm_connection_get_setting_ppp (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); +} + +/** + * nm_connection_get_setting_pppoe: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPPOE the connection might contain. + * + * Returns: (transfer none): an #NMSettingPPPOE if the connection contains one, otherwise NULL + **/ +NMSettingPPPOE * +nm_connection_get_setting_pppoe (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); +} + +/** + * nm_connection_get_setting_vpn: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVPN the connection might contain. + * + * Returns: (transfer none): an #NMSettingVPN if the connection contains one, otherwise NULL + **/ +NMSettingVPN * +nm_connection_get_setting_vpn (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); +} + +/** + * nm_connection_get_setting_wimax: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWimax the connection might contain. + * + * Returns: (transfer none): an #NMSettingWimax if the connection contains one, otherwise NULL + **/ +NMSettingWimax * +nm_connection_get_setting_wimax (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX); +} + +/** + * nm_connection_get_setting_wired: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWired the connection might contain. + * + * Returns: (transfer none): an #NMSettingWired if the connection contains one, otherwise NULL + **/ +NMSettingWired * +nm_connection_get_setting_wired (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); +} + +/** + * nm_connection_get_setting_wireless: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWireless the connection might contain. + * + * Returns: (transfer none): an #NMSettingWireless if the connection contains one, otherwise NULL + **/ +NMSettingWireless * +nm_connection_get_setting_wireless (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); +} + +/** + * nm_connection_get_setting_wireless_security: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWirelessSecurity the connection might contain. + * + * Returns: (transfer none): an #NMSettingWirelessSecurity if the connection contains one, otherwise NULL + **/ +NMSettingWirelessSecurity * +nm_connection_get_setting_wireless_security (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); +} + +/*************************************************************/ + static void nm_connection_init (NMConnection *connection) { @@ -1176,9 +1518,6 @@ set_property (GObject *object, guint prop_id, NMConnection *connection = NM_CONNECTION (object); switch (prop_id) { - case PROP_SCOPE: - nm_connection_set_scope (connection, g_value_get_uint (value)); - break; case PROP_PATH: nm_connection_set_path (connection, g_value_get_string (value)); break; @@ -1195,9 +1534,6 @@ get_property (GObject *object, guint prop_id, NMConnection *connection = NM_CONNECTION (object); switch (prop_id) { - case PROP_SCOPE: - g_value_set_uint (value, nm_connection_get_scope (connection)); - break; case PROP_PATH: g_value_set_string (value, nm_connection_get_path (connection)); break; @@ -1222,23 +1558,6 @@ nm_connection_class_init (NMConnectionClass *klass) /* Properties */ /** - * NMConnection:scope: - * - * The connection's scope, used only by the calling process as a record - * of which settings service the connection is provided by. One of the - * NM_CONNECTION_SCOPE_* defines. - **/ - g_object_class_install_property - (object_class, PROP_SCOPE, - g_param_spec_uint (NM_CONNECTION_SCOPE, - "Scope", - "Scope", - NM_CONNECTION_SCOPE_UNKNOWN, - NM_CONNECTION_SCOPE_USER, - NM_CONNECTION_SCOPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - /** * NMConnection:path: * * The connection's D-Bus path, used only by the calling process as a record diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 83d62d9b..87b053c1 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -30,6 +30,22 @@ #include <glib-object.h> #include <nm-setting.h> +#include <nm-setting-8021x.h> +#include <nm-setting-bluetooth.h> +#include <nm-setting-cdma.h> +#include <nm-setting-connection.h> +#include <nm-setting-gsm.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-ip6-config.h> +#include <nm-setting-olpc-mesh.h> +#include <nm-setting-ppp.h> +#include <nm-setting-pppoe.h> +#include <nm-setting-vpn.h> +#include <nm-setting-wimax.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> + G_BEGIN_DECLS #define NM_TYPE_CONNECTION (nm_connection_get_type ()) @@ -39,23 +55,6 @@ G_BEGIN_DECLS #define NM_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTION)) #define NM_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTION, NMConnectionClass)) -/** - * NMConnectionScope: - * @NM_CONNECTION_SCOPE_UNKNOWN: scope not known or not yet set - * @NM_CONNECTION_SCOPE_SYSTEM: connection is provided by the system settings - * service - * @NM_CONNECTION_SCOPE_USER: connection is provided by a user settings service - * - * Connection scope indicated what settings service, if any, provides the - * connection. - * - **/ -typedef enum { - NM_CONNECTION_SCOPE_UNKNOWN = 0, - NM_CONNECTION_SCOPE_SYSTEM, - NM_CONNECTION_SCOPE_USER -} NMConnectionScope; - /** * NMConnectionError: @@ -63,6 +62,10 @@ typedef enum { * @NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND: the #NMConnection object * did not contain the required #NMSettingConnection object, which must be * present for all connections + * @NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID: the 'type' property of the + * 'connection' setting did not point to a valid connection base type; ie + * it was not a hardware-related setting like #NMSettingWired or + * #NMSettingWireless. * * Describes errors that may result from operations involving a #NMConnection. * @@ -70,7 +73,8 @@ typedef enum { typedef enum { NM_CONNECTION_ERROR_UNKNOWN = 0, - NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND + NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, + NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID } NMConnectionError; #define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ()) @@ -79,7 +83,6 @@ GType nm_connection_error_get_type (void); #define NM_CONNECTION_ERROR nm_connection_error_quark () GQuark nm_connection_error_quark (void); -#define NM_CONNECTION_SCOPE "scope" #define NM_CONNECTION_PATH "path" /** @@ -107,8 +110,10 @@ NMConnection *nm_connection_new_from_hash (GHashTable *hash, GError **error); NMConnection *nm_connection_duplicate (NMConnection *connection); +NMSetting *nm_connection_create_setting (const char *name); + void nm_connection_add_setting (NMConnection *connection, - NMSetting *setting); + NMSetting *setting); void nm_connection_remove_setting (NMConnection *connection, GType setting_type); @@ -117,7 +122,7 @@ NMSetting *nm_connection_get_setting (NMConnection *connection, GType setting_type); NMSetting *nm_connection_get_setting_by_name (NMConnection *connection, - const char *name); + const char *name); gboolean nm_connection_replace_settings (NMConnection *connection, GHashTable *new_settings, @@ -144,28 +149,44 @@ gboolean nm_connection_update_secrets (NMConnection *connection, GHashTable *setting_secrets, GError **error); -void nm_connection_set_scope (NMConnection *connection, - NMConnectionScope scope); - -NMConnectionScope nm_connection_get_scope (NMConnection *connection); +void nm_connection_set_path (NMConnection *connection, + const char *path); -void nm_connection_set_path (NMConnection *connection, - const char *path); - -const char * nm_connection_get_path (NMConnection *connection); +const char * nm_connection_get_path (NMConnection *connection); void nm_connection_for_each_setting_value (NMConnection *connection, - NMSettingValueIterFn func, - gpointer user_data); + NMSettingValueIterFn func, + gpointer user_data); -GHashTable *nm_connection_to_hash (NMConnection *connection); -void nm_connection_dump (NMConnection *connection); +GHashTable *nm_connection_to_hash (NMConnection *connection, + NMSettingHashFlags flags); -NMSetting *nm_connection_create_setting (const char *name); - -GType nm_connection_lookup_setting_type (const char *name); +void nm_connection_dump (NMConnection *connection); -GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); +GType nm_connection_lookup_setting_type (const char *name); + +GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); + +/* Helpers */ +const char * nm_connection_get_uuid (NMConnection *connection); + +const char * nm_connection_get_id (NMConnection *connection); + +NMSetting8021x * nm_connection_get_setting_802_1x (NMConnection *connection); +NMSettingBluetooth * nm_connection_get_setting_bluetooth (NMConnection *connection); +NMSettingCdma * nm_connection_get_setting_cdma (NMConnection *connection); +NMSettingConnection * nm_connection_get_setting_connection (NMConnection *connection); +NMSettingGsm * nm_connection_get_setting_gsm (NMConnection *connection); +NMSettingIP4Config * nm_connection_get_setting_ip4_config (NMConnection *connection); +NMSettingIP6Config * nm_connection_get_setting_ip6_config (NMConnection *connection); +NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection); +NMSettingPPP * nm_connection_get_setting_ppp (NMConnection *connection); +NMSettingPPPOE * nm_connection_get_setting_pppoe (NMConnection *connection); +NMSettingVPN * nm_connection_get_setting_vpn (NMConnection *connection); +NMSettingWimax * nm_connection_get_setting_wimax (NMConnection *connection); +NMSettingWired * nm_connection_get_setting_wired (NMConnection *connection); +NMSettingWireless * nm_connection_get_setting_wireless (NMConnection *connection); +NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security (NMConnection *connection); G_END_DECLS diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index eea6ba5e..4cd22016 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -32,6 +32,7 @@ #include "nm-dbus-glib-types.h" #include "crypto.h" #include "nm-utils-private.h" +#include "nm-setting-private.h" /** * SECTION:nm-setting-8021x @@ -125,12 +126,15 @@ typedef struct { char *phase2_ca_path; GByteArray *phase2_client_cert; char *password; + NMSettingSecretFlags password_flags; char *pin; - char *psk; + NMSettingSecretFlags pin_flags; GByteArray *private_key; char *private_key_password; + NMSettingSecretFlags private_key_password_flags; GByteArray *phase2_private_key; char *phase2_private_key_password; + NMSettingSecretFlags phase2_private_key_password_flags; gboolean system_ca_certs; } NMSetting8021xPrivate; @@ -151,12 +155,15 @@ enum { PROP_PHASE2_CA_PATH, PROP_PHASE2_CLIENT_CERT, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, PROP_PRIVATE_KEY, PROP_PRIVATE_KEY_PASSWORD, + PROP_PRIVATE_KEY_PASSWORD_FLAGS, PROP_PHASE2_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY_PASSWORD, + PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, PROP_PIN, - PROP_PSK, + PROP_PIN_FLAGS, PROP_SYSTEM_CA_CERTS, LAST_PROP @@ -424,29 +431,6 @@ nm_setting_802_1x_get_ca_cert_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_ca_cert: - * @setting: the #NMSetting8021x - * - * Returns the CA certificate blob if the CA certificate is stored using the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use a - * CA certificate (LEAP for example), and those that can take advantage of the - * CA certificate allow it to be unset. Note that lack of a CA certificate - * reduces security by allowing man-in-the-middle attacks, because the identity - * of the network cannot be confirmed by the client. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_ca_cert_blob(). - * - * Returns: the CA certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_ca_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_ca_cert_blob (setting); -} - -/** * nm_setting_802_1x_get_ca_cert_path: * @setting: the #NMSetting8021x * @@ -472,6 +456,22 @@ nm_setting_802_1x_get_ca_cert_path (NMSetting8021x *setting) return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert->data + strlen (SCHEME_PATH)); } +static GByteArray * +path_to_scheme_value (const char *path) +{ + GByteArray *array; + + g_return_val_if_fail (path != NULL, NULL); + + /* Add the path scheme tag to the front, then the fielname */ + array = g_byte_array_sized_new (strlen (path) + strlen (SCHEME_PATH) + 1); + g_assert (array); + g_byte_array_append (array, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (array, (const guint8 *) path, strlen (path)); + g_byte_array_append (array, (const guint8 *) "\0", 1); + return array; +} + /** * nm_setting_802_1x_set_ca_cert: * @setting: the #NMSetting8021x @@ -546,13 +546,9 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *self, if (data) { if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) priv->ca_cert = data; - else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->ca_cert = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->ca_cert, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->ca_cert, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->ca_cert, (const guint8 *) "\0", 1); - } else + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->ca_cert = path_to_scheme_value (value); + else g_assert_not_reached (); } } @@ -560,61 +556,6 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *self, return priv->ca_cert != NULL; } -static NMSetting8021xCKType -ck_format_to_type (NMSetting8021xCKFormat format) -{ - switch (format) { - case NM_SETTING_802_1X_CK_FORMAT_X509: - return NM_SETTING_802_1X_CK_TYPE_X509; - case NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: - return NM_SETTING_802_1X_CK_TYPE_RAW_KEY; - case NM_SETTING_802_1X_CK_FORMAT_PKCS12: - return NM_SETTING_802_1X_CK_TYPE_PKCS12; - default: - break; - } - return NM_SETTING_802_1X_CK_TYPE_UNKNOWN; -} - -/** - * nm_setting_802_1x_set_ca_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the CA certificate file (PEM or DER format). Passing - * NULL clears the CA certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:ca-cert property - * with the raw certificate data using the %NM_SETTING_802_1X_CK_SCHEME_BLOB - * scheme. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_ca_cert() with the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_ca_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_client_cert_scheme: * @setting: the #NMSetting8021x @@ -657,26 +598,6 @@ nm_setting_802_1x_get_client_cert_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_client_cert: - * @setting: the #NMSetting8021x - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_client_cert_blob(). - * - * Returns: the client certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_client_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_client_cert_blob (setting); -} - -/** * nm_setting_802_1x_get_client_cert_path: * @setting: the #NMSetting8021x * @@ -781,13 +702,9 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *self, if (data) { if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) priv->client_cert = data; - else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->client_cert = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->client_cert, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->client_cert, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->client_cert, (const guint8 *) "\0", 1); - } else + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->client_cert = path_to_scheme_value (value); + else g_assert_not_reached (); } } @@ -796,48 +713,6 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *self, } /** - * nm_setting_802_1x_set_client_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the client certificate file (PEM, DER, or - * PKCS#12 format). Passing NULL clears the client certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:client-cert - * property with the raw certificate data. - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_client_cert() with the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_client_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - -/** * nm_setting_802_1x_get_phase1_peapver: * @setting: the #NMSetting8021x * @@ -983,28 +858,6 @@ nm_setting_802_1x_get_phase2_ca_cert_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_phase2_ca_cert: - * @setting: the #NMSetting8021x - * - * Returns the "phase 2" CA certificate blob. Not all EAP methods use - * a CA certificate (LEAP for example), and those that can take advantage of the - * CA certificate allow it to be unset. Note that lack of a CA certificate - * reduces security by allowing man-in-the-middle attacks, because the identity - * of the network cannot be confirmed by the client. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_ca_cert_blob(). - * - * Returns: the "phase 2" CA certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_ca_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_ca_cert_blob (setting); -} - -/** * nm_setting_802_1x_get_phase2_ca_cert_path: * @setting: the #NMSetting8021x * @@ -1104,13 +957,9 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *self, if (data) { if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) priv->phase2_ca_cert = data; - else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->phase2_ca_cert = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->phase2_ca_cert, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->phase2_ca_cert, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->phase2_ca_cert, (const guint8 *) "\0", 1); - } else + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_ca_cert = path_to_scheme_value (value); + else g_assert_not_reached (); } } @@ -1119,44 +968,6 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *self, } /** - * nm_setting_802_1x_set_phase2_ca_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the "phase2" CA certificate file (PEM or DER format). - * Passing NULL with any @scheme clears the "phase2" CA certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:phase2-ca-cert - * property with the raw certificate data. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_ca_cert(). - * with the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_phase2_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_ca_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - -/** * nm_setting_802_1x_get_phase2_client_cert_scheme: * @setting: the #NMSetting8021x * @@ -1200,26 +1011,6 @@ nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_phase2_client_cert: - * @setting: the #NMSetting8021x - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_client_cert_blob(). - * - * Returns: the "phase 2" client certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_client_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_client_cert_blob (setting); -} - -/** * nm_setting_802_1x_get_phase2_client_cert_path: * @setting: the #NMSetting8021x * @@ -1324,13 +1115,9 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *self, if (data) { if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) priv->phase2_client_cert = data; - else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->phase2_client_cert = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->phase2_client_cert, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->phase2_client_cert, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->phase2_client_cert, (const guint8 *) "\0", 1); - } else + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_client_cert = path_to_scheme_value (value); + else g_assert_not_reached (); } } @@ -1339,60 +1126,32 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *self, } /** - * nm_setting_802_1x_set_phase2_client_cert_from_file: + * nm_setting_802_1x_get_password: * @setting: the #NMSetting8021x - * @filename: pass the path of the "phase2" client certificate file (PEM, DER, - * or PKCS#12 format). Passing NULL clears the "phase2" client certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:phase2-client-cert - * property with the raw certificate data. - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_client_cert() with the. - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful + * Returns: the password used by the authentication method, if any, as specified + * by the #NMSetting8021x:password property **/ -gboolean -nm_setting_802_1x_set_phase2_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) +const char * +nm_setting_802_1x_get_password (NMSetting8021x *setting) { - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_client_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); - return success; + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password; } /** - * nm_setting_802_1x_get_password: + * nm_setting_802_1x_get_password_flags: * @setting: the #NMSetting8021x * - * Returns: the password used by the authentication method, if any, as specified - * by the #NMSetting8021x:password property + * Returns: the #NMSettingSecretFlags pertaining to the #NMSetting8021x:password **/ -const char * -nm_setting_802_1x_get_password (NMSetting8021x *setting) +NMSettingSecretFlags +nm_setting_802_1x_get_password_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); - return NM_SETTING_802_1X_GET_PRIVATE (setting)->password; + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_flags; } /** @@ -1411,18 +1170,18 @@ nm_setting_802_1x_get_pin (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_psk: + * nm_setting_802_1x_get_pin_flags: * @setting: the #NMSetting8021x * - * Returns: the Pre-Shared-Key used by the authentication method, if any, as - * specified by the #NMSetting8021x:psk property + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:pin **/ -const char * -nm_setting_802_1x_get_psk (NMSetting8021x *setting) +NMSettingSecretFlags +nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); - return NM_SETTING_802_1X_GET_PRIVATE (setting)->psk; + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin_flags; } /** @@ -1453,6 +1212,10 @@ nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * * Returns: the private key data **/ const GByteArray * @@ -1469,26 +1232,6 @@ nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_private_key: - * @setting: the #NMSetting8021x - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_blob(). - * - * Returns: the private key data - **/ -const GByteArray * -nm_setting_802_1x_get_private_key (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_private_key_blob (setting); -} - -/** * nm_setting_802_1x_get_private_key_path: * @setting: the #NMSetting8021x * @@ -1511,6 +1254,24 @@ nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting) return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key->data + strlen (SCHEME_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); + if (array) { + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + } + g_free (contents); + } + return array; +} + /** * nm_setting_802_1x_set_private_key: * @setting: the #NMSetting8021x @@ -1519,20 +1280,35 @@ nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting) * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use * g_filename_to_utf8() to convert if needed. Passing NULL with any @scheme * clears the private key. - * @password: password used to decrypt the private key + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. * @scheme: desired storage scheme for the private key * @out_format: on successful return, the type of the private key added * @error: on unsuccessful return, an error * - * Reads a private key from disk and sets the #NMSetting8021x:private-key - * property with the raw private key data if using the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the private key - * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. - * * Private keys are used to authenticate the connecting client to the network * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * This function reads a private key from disk and sets the + * #NMSetting8021x:private-key property with the private key file data if using + * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the private + * key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:private-key-password property with the given @password. If + * the decryption is unsuccessful, %FALSE is returned, @error is set, and no + * internal data is changed. If no @password is given, the private key is + * assumed to be valid, no decryption is performed, and the password may be set + * at a later time. + * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful **/ gboolean @@ -1545,8 +1321,6 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, { NMSetting8021xPrivate *priv; NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - GByteArray *data; g_return_val_if_fail (NM_IS_SETTING_802_1X (self), FALSE); @@ -1560,12 +1334,26 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, if (out_format) g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + /* Ensure the private key is a recognized format and if the password was + * given, that it decrypts the private key. + */ + if (value) { + format = crypto_verify_private_key (value, password, NULL); + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + } + priv = NM_SETTING_802_1X_GET_PRIVATE (self); - /* Clear out any previous private key blob */ + /* Clear out any previous private key data */ if (priv->private_key) { /* Try not to leave the private key around in memory */ - memset (priv->private_key, 0, priv->private_key->len); + memset (priv->private_key->data, 0, priv->private_key->len); g_byte_array_free (priv->private_key, TRUE); priv->private_key = NULL; } @@ -1573,81 +1361,23 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, g_free (priv->private_key_password); priv->private_key_password = NULL; - if (!value) + if (value == NULL) return TRUE; - /* Verify the key and the private key password */ - data = crypto_get_private_key (value, - password, - &key_type, - &format, - error); - if (!data) { - /* As a special case for private keys, even if the decrypt fails, - * return the key's file type. - */ - if (out_format && crypto_is_pkcs12_file (value, NULL)) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - - return FALSE; - } - - switch (format) { - case NM_CRYPTO_FILE_FORMAT_RAW_KEY: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; - break; - case NM_CRYPTO_FILE_FORMAT_X509: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - break; - default: - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - g_set_error (error, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, - NM_SETTING_802_1X_PRIVATE_KEY); - return FALSE; - } - - g_assert (data); + priv->private_key_password = g_strdup (password); if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - priv->private_key = data; - data = NULL; - - /* Always update the private key for blob + pkcs12 since the - * pkcs12 files are encrypted - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) - priv->private_key_password = g_strdup (password); - } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->private_key, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->private_key, (const guint8 *) "\0", 1); - - /* Always update the private key with paths since the key the - * cert refers to is encrypted. - */ - priv->private_key_password = g_strdup (password); - } else + /* Shouldn't fail this since we just verified the private key above */ + priv->private_key = file_to_byte_array (value); + g_assert (priv->private_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->private_key = path_to_scheme_value (value); + else g_assert_not_reached (); - /* Clear and free private key data if it's no longer needed */ - if (data) { - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - } - /* As required by NM and wpa_supplicant, set the client-cert * property to the same PKCS#12 data. */ + g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { if (priv->client_cert) g_byte_array_free (priv->client_cert, TRUE); @@ -1656,55 +1386,12 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, g_byte_array_append (priv->client_cert, priv->private_key->data, priv->private_key->len); } + if (out_format) + *out_format = format; return priv->private_key != NULL; } /** - * nm_setting_802_1x_set_private_key_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the private key file (PEM, DER, or PKCS#12 format). - * Passing NULL clears the private key. - * @password: password used to decrypt the private key - * @out_ck_type: on successful return, the type of the private key added - * @error: on unsuccessful return, an error - * - * Reads a private key from disk and sets the #NMSetting8021x:private-key - * property with the raw private key data. - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_private_key() with. - * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_private_key (setting, - filename, - password, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - -/** * nm_setting_802_1x_get_private_key_password: * @setting: the #NMSetting8021x * @@ -1722,6 +1409,21 @@ nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting) } /** + * nm_setting_802_1x_get_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password_flags; +} + +/** * nm_setting_802_1x_get_private_key_format: * @setting: the #NMSetting8021x * @@ -1745,7 +1447,7 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting) case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (crypto_is_pkcs12_data (priv->private_key)) return NM_SETTING_802_1X_CK_FORMAT_PKCS12; - return NM_SETTING_802_1X_CK_FORMAT_X509; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_private_key_path (setting); if (crypto_is_pkcs12_file (path, &error)) @@ -1755,7 +1457,7 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting) g_error_free (error); return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; } - return NM_SETTING_802_1X_CK_FORMAT_X509; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; default: break; } @@ -1764,23 +1466,6 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_private_key_type: - * @setting: the #NMSetting8021x - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_format(). - * - * Returns: the data format of the private key data stored in the - * #NMSetting8021x:private-key property - **/ -NMSetting8021xCKType -nm_setting_802_1x_get_private_key_type (NMSetting8021x *setting) -{ - return ck_format_to_type (nm_setting_802_1x_get_private_key_format (setting)); -} - -/** * nm_setting_802_1x_get_phase2_private_key_password: * @setting: the #NMSetting8021x * @@ -1798,6 +1483,21 @@ nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting) } /** + * nm_setting_802_1x_get_phase2_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password_flags; +} + +/** * nm_setting_802_1x_get_phase2_private_key_scheme: * @setting: the #NMSetting8021x * @@ -1825,6 +1525,10 @@ nm_setting_802_1x_get_phase2_private_key_scheme (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the phase2 private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * * Returns: the "phase 2" private key data **/ const GByteArray * @@ -1841,26 +1545,6 @@ nm_setting_802_1x_get_phase2_private_key_blob (NMSetting8021x *setting) } /** - * nm_setting_802_1x_get_phase2_private_key: - * @setting: the #NMSetting8021x - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_blob(). - * - * Returns: the "phase 2" private key data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_private_key (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_private_key_blob (setting); -} - -/** * nm_setting_802_1x_get_phase2_private_key_path: * @setting: the #NMSetting8021x * @@ -1887,24 +1571,39 @@ nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting) * nm_setting_802_1x_set_phase2_private_key: * @setting: the #NMSetting8021x * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or - * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; * use g_filename_to_utf8() to convert if needed. Passing NULL with any - * @scheme clears the "phase2" private key. - * @password: password used to decrypt the private key + * @scheme clears the private key. + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. * @scheme: desired storage scheme for the private key * @out_format: on successful return, the type of the private key added * @error: on unsuccessful return, an error * - * Reads a "phase 2" private key from disk and sets the - * #NMSetting8021x:phase2-private-key property with the raw private key data if - * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the - * private key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. - * * Private keys are used to authenticate the connecting client to the network * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * This function reads a private key from disk and sets the + * #NMSetting8021x:phase2-private-key property with the private key file data if + * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the + * private key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:phase2-private-key-password property with the given + * @password. If the decryption is unsuccessful, %FALSE is returned, @error is + * set, and no internal data is changed. If no @password is given, the private + * key is assumed to be valid, no decryption is performed, and the password may + * be set at a later time. + * + * WARNING: the "phase2" private key property is not a "secret" property, and + * thus unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful **/ gboolean @@ -1917,8 +1616,6 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, { NMSetting8021xPrivate *priv; NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - GByteArray *data; g_return_val_if_fail (NM_IS_SETTING_802_1X (self), FALSE); @@ -1932,12 +1629,26 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, if (out_format) g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + /* Ensure the private key is a recognized format and if the password was + * given, that it decrypts the private key. + */ + if (value) { + format = crypto_verify_private_key (value, password, NULL); + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + } + priv = NM_SETTING_802_1X_GET_PRIVATE (self); - /* Clear out any previous private key blob */ + /* Clear out any previous private key data */ if (priv->phase2_private_key) { /* Try not to leave the private key around in memory */ - memset (priv->phase2_private_key, 0, priv->phase2_private_key->len); + memset (priv->phase2_private_key->data, 0, priv->phase2_private_key->len); g_byte_array_free (priv->phase2_private_key, TRUE); priv->phase2_private_key = NULL; } @@ -1945,81 +1656,23 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, g_free (priv->phase2_private_key_password); priv->phase2_private_key_password = NULL; - if (!value) + if (value == NULL) return TRUE; - /* Verify the key and the private key password */ - data = crypto_get_private_key (value, - password, - &key_type, - &format, - error); - if (!data) { - /* As a special case for private keys, even if the decrypt fails, - * return the key's file type. - */ - if (out_format && crypto_is_pkcs12_file (value, NULL)) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - - return FALSE; - } - - switch (format) { - case NM_CRYPTO_FILE_FORMAT_RAW_KEY: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; - break; - case NM_CRYPTO_FILE_FORMAT_X509: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - break; - default: - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - g_set_error (error, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); - return FALSE; - } - - g_assert (data); + priv->phase2_private_key_password = g_strdup (password); if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - priv->phase2_private_key = data; - data = NULL; - - /* Always update the private key for blob + pkcs12 since the - * pkcs12 files are encrypted - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) - priv->phase2_private_key_password = g_strdup (password); - } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->phase2_private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) "\0", 1); - - /* Always update the private key with paths since the key the - * cert refers to is encrypted. - */ - priv->phase2_private_key_password = g_strdup (password); - } else + /* Shouldn't fail this since we just verified the private key above */ + priv->phase2_private_key = file_to_byte_array (value); + g_assert (priv->phase2_private_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_private_key = path_to_scheme_value (value); + else g_assert_not_reached (); - /* Clear and free private key data if it's no longer needed */ - if (data) { - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - } - /* As required by NM and wpa_supplicant, set the client-cert * property to the same PKCS#12 data. */ + g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { if (priv->phase2_client_cert) g_byte_array_free (priv->phase2_client_cert, TRUE); @@ -2028,55 +1681,12 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, g_byte_array_append (priv->phase2_client_cert, priv->phase2_private_key->data, priv->phase2_private_key->len); } + if (out_format) + *out_format = format; return priv->phase2_private_key != NULL; } /** - * nm_setting_802_1x_set_phase2_private_key_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the "phase2" private key file (PEM, DER, or PKCS#12 - * format). Passing NULL clears the "phase2" private key. - * @password: password used to decrypt the private key - * @out_ck_type: on successful return, the type of the private key added - * @error: on unsuccessful return, an error - * - * Reads a "phase 2" private key from disk and sets the - * #NMSetting8021x:phase2-private-key property with the raw private key data. - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_private_key() with - * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_phase2_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_private_key (setting, - filename, - password, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - -/** * nm_setting_802_1x_get_phase2_private_key_format: * @setting: the #NMSetting8021x * @@ -2100,7 +1710,7 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting) case NM_SETTING_802_1X_CK_SCHEME_BLOB: if (crypto_is_pkcs12_data (priv->phase2_private_key)) return NM_SETTING_802_1X_CK_FORMAT_PKCS12; - return NM_SETTING_802_1X_CK_FORMAT_X509; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_private_key_path (setting); if (crypto_is_pkcs12_file (path, &error)) @@ -2110,7 +1720,7 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting) g_error_free (error); return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; } - return NM_SETTING_802_1X_CK_FORMAT_X509; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; default: break; } @@ -2118,23 +1728,6 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting) return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; } -/** - * nm_setting_802_1x_get_phase2_private_key_type: - * @setting: the #NMSetting8021x - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_private_key_format(). - * - * Returns: the data format of the private key data stored in the - * #NMSetting8021x:phase2-private-key property - **/ -NMSetting8021xCKType -nm_setting_802_1x_get_phase2_private_key_type (NMSetting8021x *setting) -{ - return ck_format_to_type (nm_setting_802_1x_get_phase2_private_key_format (setting)); -} - static void need_secrets_password (NMSetting8021x *self, GPtrArray *secrets, @@ -2162,35 +1755,19 @@ need_private_key_password (const GByteArray *blob, const char *path, const char *password) { - /* Private key password is only un-needed if the private key scheme is BLOB, - * because BLOB keys are decrypted by the settings service. A private key - * password is required if the private key is PKCS#12 format, or if the - * private key scheme is PATH. - */ - if (path) { - GByteArray *tmp; - NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - NMCryptoFileFormat key_format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - - /* check the password */ - tmp = crypto_get_private_key (path, password, &key_type, &key_format, NULL); - if (tmp) { - /* Decrypt/verify successful; password must be OK */ - g_byte_array_free (tmp, TRUE); - return FALSE; - } - } else if (blob) { - /* Non-PKCS#12 blob-scheme keys are already decrypted by their settings - * service, thus if the private key is not PKCS#12 format, a new password - * is not required. If the PKCS#12 key can be decrypted with the given - * password, then we don't need a new password either. - */ - if (!crypto_is_pkcs12_data (blob) || crypto_verify_pkcs12 (blob, password, NULL)) - return FALSE; - } else - g_warning ("%s: unknown private key password scheme", __func__); + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - return TRUE; + /* Private key password is required */ + if (password) { + if (path) + format = crypto_verify_private_key (path, password, NULL); + else if (blob) + format = crypto_verify_private_key_data (blob, password, NULL); + else + g_warning ("%s: unknown private key password scheme", __func__); + } + + return (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN); } static void @@ -2204,11 +1781,6 @@ need_secrets_tls (NMSetting8021x *self, const char *path = NULL; if (phase2) { - if (!priv->phase2_private_key || !priv->phase2_private_key->len) { - g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); - return; - } - scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) path = nm_setting_802_1x_get_phase2_private_key_path (self); @@ -2223,11 +1795,6 @@ need_secrets_tls (NMSetting8021x *self, if (need_private_key_password (blob, path, priv->phase2_private_key_password)) g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); } else { - if (!priv->private_key || !priv->private_key->len) { - g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY); - return; - } - scheme = nm_setting_802_1x_get_private_key_scheme (self); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) path = nm_setting_802_1x_get_private_key_path (self); @@ -2264,8 +1831,23 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) return FALSE; } + /* Private key is required for TLS */ + if (!priv->phase2_private_key) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } else if (!priv->phase2_private_key->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + /* If the private key is PKCS#12, check that it matches the client cert */ - if (priv->phase2_private_key && crypto_is_pkcs12_data (priv->phase2_private_key)) { + if (crypto_is_pkcs12_data (priv->phase2_private_key)) { if (priv->phase2_private_key->len != priv->phase2_client_cert->len) { g_set_error (error, NM_SETTING_802_1X_ERROR, @@ -2299,8 +1881,23 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) return FALSE; } + /* Private key is required for TLS */ + if (!priv->private_key) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } else if (!priv->private_key->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + /* If the private key is PKCS#12, check that it matches the client cert */ - if (priv->private_key && crypto_is_pkcs12_data (priv->private_key)) { + if (crypto_is_pkcs12_data (priv->private_key)) { if (priv->private_key->len != priv->client_cert->len) { g_set_error (error, NM_SETTING_802_1X_ERROR, @@ -2817,6 +2414,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; case PROP_PRIVATE_KEY: if (priv->private_key) { g_byte_array_free (priv->private_key, TRUE); @@ -2833,6 +2433,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->private_key_password); priv->private_key_password = g_value_dup_string (value); break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + priv->private_key_password_flags = g_value_get_uint (value); + break; case PROP_PHASE2_PRIVATE_KEY: if (priv->phase2_private_key) { g_byte_array_free (priv->phase2_private_key, TRUE); @@ -2849,6 +2452,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->phase2_private_key_password); priv->phase2_private_key_password = g_value_dup_string (value); break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + priv->phase2_private_key_password_flags = g_value_get_uint (value); + break; case PROP_SYSTEM_CA_CERTS: priv->system_ca_certs = g_value_get_boolean (value); break; @@ -2911,18 +2517,27 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, priv->password); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, priv->password_flags); + break; case PROP_PRIVATE_KEY: g_value_set_boxed (value, priv->private_key); break; case PROP_PRIVATE_KEY_PASSWORD: g_value_set_string (value, priv->private_key_password); break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_uint (value, priv->private_key_password_flags); + break; case PROP_PHASE2_PRIVATE_KEY: g_value_set_boxed (value, priv->phase2_private_key); break; case PROP_PHASE2_PRIVATE_KEY_PASSWORD: g_value_set_string (value, priv->phase2_private_key_password); break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_uint (value, priv->phase2_private_key_password_flags); + break; case PROP_SYSTEM_CA_CERTS: g_value_set_boolean (value, priv->system_ca_certs); break; @@ -3098,7 +2713,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Sometimes when using older RADIUS servers, it is " "necessary to force the client to use a particular " "PEAP version. To do so, this property may be set to " - "'0' or '1; to force that specific PEAP version.", + "'0' or '1' to force that specific PEAP version.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -3286,11 +2901,31 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSetting8021x:password-flags: + * + * Flags indicating how to handle #NMSetting8021x:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the 802.1x password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSetting8021x:private-key: * * Contains the private key if the #NMSetting8021x:eap property is set to * 'tls'. Setting this property directly is discouraged; use the * nm_setting_802_1x_set_private_key() function instead. + * + * WARNING: #NMSetting8021x:private-key is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a + * private key password to prevent unauthorized access to unencrypted + * private key data. **/ g_object_class_install_property (object_class, PROP_PRIVATE_KEY, @@ -3299,28 +2934,28 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Contains the private key when the 'eap' property " "is set to 'tls'. Key data is specified using a " "'scheme'; two are currently supported: blob and " - "path. When using the blob scheme and X.509 private " - "keys, this property should be set to the keys's " - "decrypted DER encoded data. When using X.509 " - "private keys with the path scheme, this property " - "should be set to the full UTF-8 encoded path of " - "the key, prefixed with the string 'file://' and " - "and ending with a terminating NULL byte. When " - "using PKCS#12 format private keys and the blob " + "path. When using the blob scheme and private " + "keys, this property should be set to the key's " + "encrypted PEM encoded data. When using private " + "keys with the path scheme, this property should " + "be set to the full UTF-8 encoded path of the key, " + "prefixed with the string 'file://' and ending " + "with a terminating NULL byte. When using " + "PKCS#12 format private keys and the blob " "scheme, this property should be set to the " - "PKCS#12 data (which is encrypted) and the " + "PKCS#12 data and the 'private-key-password' " + "property must be set to password used to " + "decrypt the PKCS#12 certificate and key. When " + "using PKCS#12 files and the path scheme, this " + "property should be set to the full UTF-8 encoded " + "path of the key, prefixed with the string " + "'file://' and and ending with a terminating NULL " + "byte, and as with the blob scheme the " "'private-key-password' property must be set to " - "password used to decrypt the PKCS#12 certificate " - "and key. When using PKCS#12 files and the path " - "scheme, this property should be set to the full " - "UTF-8 encoded path of the key, prefixed with the " - "string 'file://' and and ending with a " - "terminating NULL byte, and as with the blob " - "scheme the 'private-key-password' property must " - "be set to the password used to decode the PKCS#12 " - "private key and certificate.", + "the password used to decode the PKCS#12 private " + "key and certificate.", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** * NMSetting8021x:private-key-password: @@ -3344,6 +2979,21 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSetting8021x:private-key-password-flags: + * + * Flags indicating how to handle #NMSetting8021x:private-key-password:. + **/ + g_object_class_install_property (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, + "Private Key Password Flags", + "Flags indicating how to handle the 802.1x private " + "key password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSetting8021x:phase2-private-key: * * Private key data used by "phase 2" inner authentication methods. @@ -3361,28 +3011,28 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "the 'phase2-eap' or 'phase2-autheap' property " "is set to 'tls'. Key data is specified using a " "'scheme'; two are currently supported: blob and " - "path. When using the blob scheme and X.509 private " - "keys, this property should be set to the keys's " - "decrypted DER encoded data. When using X.509 " - "private keys with the path scheme, this property " - "should be set to the full UTF-8 encoded path of " - "the key, prefixed with the string 'file://' and " - "and ending with a terminating NULL byte. When " - "using PKCS#12 format private keys and the blob " + "path. When using the blob scheme and private " + "keys, this property should be set to the key's " + "encrypted PEM encoded data. When using private " + "keys with the path scheme, this property should " + "be set to the full UTF-8 encoded path of the key, " + "prefixed with the string 'file://' and ending " + "with a terminating NULL byte. When using " + "PKCS#12 format private keys and the blob " "scheme, this property should be set to the " - "PKCS#12 data (which is encrypted) and the " - "'private-key-password' property must be set to " - "password used to decrypt the PKCS#12 certificate " - "and key. When using PKCS#12 files and the path " - "scheme, this property should be set to the full " - "UTF-8 encoded path of the key, prefixed with the " - "string 'file://' and and ending with a " - "terminating NULL byte, and as with the blob " - "scheme the 'private-key-password' property must " - "be set to the password used to decode the PKCS#12 " + "PKCS#12 data and the 'phase2-private-key-password' " + "property must be set to password used to " + "decrypt the PKCS#12 certificate and key. When " + "using PKCS#12 files and the path scheme, this " + "property should be set to the full UTF-8 encoded " + "path of the key, prefixed with the string " + "'file://' and and ending with a terminating NULL " + "byte, and as with the blob scheme the " + "'phase2-private-key-password' property must be " + "set to the password used to decode the PKCS#12 " "private key and certificate.", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** * NMSetting8021x:phase2-private-key-password: @@ -3406,6 +3056,21 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSetting8021x:phase2-private-key-password-flags: + * + * Flags indicating how to handle #NMSetting8021x:phase2-private-key-password:. + **/ + g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + "Phase2 Private Key Password Flags", + "Flags indicating how to handle the 802.1x phase2 " + "private key password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSetting8021x:system-ca-certs: * * When TRUE, overrides #NMSetting8021x:ca-path and diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 7ee868a0..bf587a90 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -30,6 +30,18 @@ G_BEGIN_DECLS +/** + * NMSetting8021xCKFormat: + * @NM_SETTING_802_1X_CK_FORMAT_UNKNOWN: unknown file format + * @NM_SETTING_802_1X_CK_FORMAT_X509: file contains an X.509 format certificate + * @NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: file contains an old-style OpenSSL PEM + * or DER private key + * @NM_SETTING_802_1X_CK_FORMAT_PKCS12: file contains a PKCS#12 certificate + * and private key + * + * #NMSetting8021xCKFormat values indicate the general type of a certificate + * or private key + */ typedef enum { NM_SETTING_802_1X_CK_FORMAT_UNKNOWN = 0, NM_SETTING_802_1X_CK_FORMAT_X509, @@ -37,12 +49,26 @@ typedef enum { NM_SETTING_802_1X_CK_FORMAT_PKCS12 } NMSetting8021xCKFormat; +/** + * NMSetting8021xCKScheme: + * @NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: unknown certificate or private key + * scheme + * @NM_SETTING_802_1X_CK_SCHEME_BLOB: certificate or key is stored as the raw + * item data + * @NM_SETTING_802_1X_CK_SCHEME_PATH: certificate or key is stored as a path + * to a file containing the certificate or key data + * + * #NMSetting8021xCKScheme values indicate how a certificate or private key is + * stored in the setting properties, either as a blob of the item's data, or as + * a path to a certificate or private key file on the filesystem + */ typedef enum { NM_SETTING_802_1X_CK_SCHEME_UNKNOWN = 0, NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_802_1X_CK_SCHEME_PATH } NMSetting8021xCKScheme; + #define NM_TYPE_SETTING_802_1X (nm_setting_802_1x_get_type ()) #define NM_SETTING_802_1X(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021x)) #define NM_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) @@ -81,36 +107,35 @@ GQuark nm_setting_802_1x_error_quark (void); #define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path" #define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert" #define NM_SETTING_802_1X_PASSWORD "password" +#define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags" #define NM_SETTING_802_1X_PRIVATE_KEY "private-key" #define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD "private-key-password" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS "private-key-password-flags" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD "phase2-private-key-password" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS "phase2-private-key-password-flags" #define NM_SETTING_802_1X_PIN "pin" -#define NM_SETTING_802_1X_PSK "psk" +#define NM_SETTING_802_1X_PIN_FLAGS "pin-flags" #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties - * using the "blob" scheme, the data must be passed in PKCS#12 format. In this - * case, the private key password must also be passed to NetworkManager, and the - * appropriate "client-cert" (or "phase2-client-cert") property of the - * NMSetting8021x object must also contain the exact same PKCS#12 data that the - * private key will when NetworkManager requests secrets. This is because the + * using the "blob" scheme, the data must be passed in PKCS#12 binary format. + * In this case, the appropriate "client-cert" (or "phase2-client-cert") + * property of the NMSetting8021x object must also contain the exact same + * PKCS#12 binary data that the private key does. This is because the * PKCS#12 file contains both the private key and client certificate, so both * properties need to be set to the same thing. When using the "path" scheme, - * just set both the private-key and client-cert properties to the same path, - * and set the private-key password correctly. + * just set both the private-key and client-cert properties to the same path. * * When setting OpenSSL-derived "traditional" format (ie S/MIME style, not * PKCS#8) RSA and DSA keys directly via properties with the "blob" scheme, they - * must passed to NetworkManager completely decrypted because the OpenSSL - * "traditional" format is non-standard and is not complete enough for all - * crypto libraries to use. Thus, for OpenSSL "traditional" format keys, the - * private key password is not passed to NetworkManager (because the data is - * already decrypted by the client), and the appropriate "client-cert" (or - * "phase2-client-cert") property of the NMSetting8021x object must be a valid - * client certificate. When using the "path" scheme, just set the private-key - * and client-cert properties to the paths to their respective objects, and - * set the private-key password correctly. + * should be passed to NetworkManager in PEM format with the "DEK-Info" and + * "Proc-Type" tags intact. Decrypted private keys should not be used as this + * is insecure and could allow unprivileged users to access the decrypted + * private key data. + * + * When using the "path" scheme, just set the private-key and client-cert + * properties to the paths to their respective objects. */ typedef struct { @@ -192,10 +217,10 @@ gboolean nm_setting_802_1x_set_phase2_client_cert (NMSett GError **error); const char * nm_setting_802_1x_get_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_flags (NMSetting8021x *setting); const char * nm_setting_802_1x_get_pin (NMSetting8021x *setting); - -const char * nm_setting_802_1x_get_psk (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting); NMSetting8021xCKScheme nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting); const GByteArray * nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting); @@ -207,6 +232,7 @@ gboolean nm_setting_802_1x_set_private_key (NMSett NMSetting8021xCKFormat *out_format, GError **error); const char * nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting); NMSetting8021xCKFormat nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting); @@ -220,61 +246,11 @@ gboolean nm_setting_802_1x_set_phase2_private_key (NMSett NMSetting8021xCKFormat *out_format, GError **error); const char * nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting); NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting); -/***** DEPRECATED; anything below will be removed in version 0.9 *****/ - -typedef enum { - NM_SETTING_802_1X_CK_TYPE_UNKNOWN = 0, - NM_SETTING_802_1X_CK_TYPE_X509, - NM_SETTING_802_1X_CK_TYPE_RAW_KEY, - NM_SETTING_802_1X_CK_TYPE_PKCS12 -} NMSetting8021xCKType; - -const GByteArray *nm_setting_802_1x_get_ca_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_client_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_phase2_ca_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_phase2_client_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_private_key (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error); - -NMSetting8021xCKType nm_setting_802_1x_get_private_key_type (NMSetting8021x *setting); - -const GByteArray *nm_setting_802_1x_get_phase2_private_key (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error); - -NMSetting8021xCKType nm_setting_802_1x_get_phase2_private_key_type (NMSetting8021x *setting); - G_END_DECLS #endif /* NM_SETTING_8021X_H */ diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index cff8dff4..cb5b27e8 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -18,12 +18,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. */ #include <string.h> #include "nm-setting-cdma.h" #include "nm-utils.h" +#include "nm-setting-private.h" /** * SECTION:nm-setting-cdma @@ -86,6 +87,7 @@ typedef struct { char *number; /* For dialing, duh */ char *username; char *password; + NMSettingSecretFlags password_flags; } NMSettingCdmaPrivate; enum { @@ -93,6 +95,7 @@ enum { PROP_NUMBER, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, LAST_PROP }; @@ -152,6 +155,20 @@ nm_setting_cdma_get_password (NMSettingCdma *setting) return NM_SETTING_CDMA_GET_PRIVATE (setting)->password; } +/** + * nm_setting_cdma_get_password_flags: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingCdma:password + **/ +NMSettingSecretFlags +nm_setting_cdma_get_password_flags (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->password_flags; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -200,8 +217,10 @@ need_secrets (NMSetting *setting) return NULL; if (priv->username) { - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_CDMA_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_CDMA_PASSWORD); + } } return secrets; @@ -244,6 +263,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -266,6 +288,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_cdma_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_cdma_get_password_flags (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -340,4 +365,18 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) "a password or accept any password.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + /** + * NMSettingCdma:password-flags: + * + * Flags indicating how to handle #NMSettingCdma:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_CDMA_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the CDMA password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-cdma.h b/libnm-util/nm-setting-cdma.h index 8a6c4505..8abfce4a 100644 --- a/libnm-util/nm-setting-cdma.h +++ b/libnm-util/nm-setting-cdma.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,9 +53,10 @@ GType nm_setting_cdma_error_get_type (void); #define NM_SETTING_CDMA_ERROR nm_setting_cdma_error_quark () GQuark nm_setting_cdma_error_quark (void); -#define NM_SETTING_CDMA_NUMBER "number" -#define NM_SETTING_CDMA_USERNAME "username" -#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_NUMBER "number" +#define NM_SETTING_CDMA_USERNAME "username" +#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_PASSWORD_FLAGS "password-flags" typedef struct { NMSetting parent; @@ -77,6 +78,7 @@ NMSetting *nm_setting_cdma_new (void); const char *nm_setting_cdma_get_number (NMSettingCdma *setting); const char *nm_setting_cdma_get_username (NMSettingCdma *setting); const char *nm_setting_cdma_get_password (NMSettingCdma *setting); +NMSettingSecretFlags nm_setting_cdma_get_password_flags (NMSettingCdma *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 65f613eb..b3bf4443 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -19,12 +19,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include <string.h> #include <ctype.h> +#include "nm-utils.h" +#include "nm-dbus-glib-types.h" +#include "nm-param-spec-specialized.h" #include "nm-setting-connection.h" /** @@ -81,10 +84,20 @@ G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) #define NM_SETTING_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) +typedef enum { + PERM_TYPE_USER = 0, +} PermType; + +typedef struct { + guint8 ptype; + char *item; +} Permission; + typedef struct { char *id; char *uuid; char *type; + GSList *permissions; /* list of Permission structs */ gboolean autoconnect; guint64 timestamp; gboolean read_only; @@ -95,6 +108,7 @@ enum { PROP_ID, PROP_UUID, PROP_TYPE, + PROP_PERMISSIONS, PROP_AUTOCONNECT, PROP_TIMESTAMP, PROP_READ_ONLY, @@ -102,6 +116,89 @@ enum { LAST_PROP }; +/***********************************************************************/ + +#define PERM_USER_PREFIX "user:" + +static Permission * +permission_new_from_str (const char *str) +{ + Permission *p; + const char *last_colon; + size_t ulen = 0, i; + + g_return_val_if_fail (strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0, NULL); + str += strlen (PERM_USER_PREFIX); + + last_colon = strrchr (str, ':'); + if (last_colon) { + /* Ensure that somebody didn't pass "user::" */ + g_return_val_if_fail (last_colon > str, NULL); + + /* Reject :[detail] for now */ + g_return_val_if_fail (*(last_colon + 1) == '\0', NULL); + + /* Make sure we don't include detail in the username */ + ulen = last_colon - str; + } else + ulen = strlen (str); + + /* Sanity check the length of the username */ + g_return_val_if_fail (ulen < 100, NULL); + + /* Make sure there's no ':' in the username */ + for (i = 0; i < ulen; i++) + g_return_val_if_fail (str[i] != ':', NULL); + + /* And the username must be valid UTF-8 */ + g_return_val_if_fail (g_utf8_validate (str, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + if (last_colon) { + p->item = g_malloc (ulen + 1); + memcpy (p->item, str, ulen); + p->item[ulen] = '\0'; + } else + p->item = g_strdup (str); + + return p; +} + +static Permission * +permission_new (const char *uname) +{ + Permission *p; + + g_return_val_if_fail (uname, NULL); + g_return_val_if_fail (uname[0] != '\0', NULL); + g_return_val_if_fail (strchr (uname, ':') == NULL, NULL); + g_return_val_if_fail (g_utf8_validate (uname, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + p->item = g_strdup (uname); + return p; +} + +static char * +permission_to_string (Permission *p) +{ + return g_strdup_printf (PERM_USER_PREFIX "%s:", p->item); +} + +static void +permission_free (Permission *p) +{ + g_free (p->item); + memset (p, 0, sizeof (*p)); + g_slice_free (Permission, p); +} + +/***********************************************************************/ + /** * nm_setting_connection_new: * @@ -162,6 +259,177 @@ nm_setting_connection_get_connection_type (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->type; } + +/** + * nm_setting_connection_get_num_permissions: + * @setting: the #NMSettingConnection + * + * Returns the number of entires in the #NMSettingConnection:permissions + * property of this setting. + * + * Returns: the number of permissions entires + */ +guint32 +nm_setting_connection_get_num_permissions (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions); +} + +/** + * nm_setting_connection_get_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permissions entry + * @out_ptype: on return, the permission type (at this time, always "user") + * @out_pitem: on return, the permission item (formatted accoring to @ptype, see + * #NMSettingConnection:permissions for more detail + * @out_detail: on return, the permission detail (at this time, always NULL) + * + * Retrieve one of the entries of the #NMSettingConnection:permissions property + * of this setting. + * + * Returns: %TRUE if a permission was returned, %FALSE if @idx was invalid + */ +gboolean +nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + g_return_val_if_fail (idx < g_slist_length (priv->permissions), FALSE); + + p = g_slist_nth_data (priv->permissions, idx); + if (out_ptype) + *out_ptype = "user"; + if (out_pitem) + *out_pitem = p->item; + if (out_detail) + *out_detail = NULL; + + return TRUE; +} + +/** + * nm_setting_connection_permissions_user_allowed: + * @setting: the #NMSettingConnection + * @uname: the user name to check permissions for + * + * Checks whether the given username is allowed to view/access this connection. + * + * Returns: %TRUE if the requested user is allowed to view this connection, + * %FALSE if the given user is not allowed to view this connection + */ +gboolean +nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, + const char *uname) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (uname != NULL, FALSE); + g_return_val_if_fail (*uname != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + /* If no permissions, visible to all */ + if (priv->permissions == NULL) + return TRUE; + + /* Find the username in the permissions list */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + Permission *p = iter->data; + + if (strcmp (uname, p->item) == 0) + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_connection_add_permission: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Adds a permission to the connection's permission list. At this time, only + * the "user" permission type is supported, and @pitem must be a username. See + * #NMSettingConnection:permissions: for more details. + * + * Returns: TRUE if the permission was unique and was successfully added to the + * list, FALSE if @ptype or @pitem was invalid or it the permission was already + * present in the list + */ +gboolean +nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (ptype, FALSE); + g_return_val_if_fail (strlen (ptype) > 0, FALSE); + g_return_val_if_fail (detail == NULL, FALSE); + + /* Only "user" for now... */ + g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + /* No dupes */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (strcmp (pitem, p->item) == 0) + return FALSE; + } + + p = permission_new (pitem); + g_return_val_if_fail (p != NULL, FALSE); + priv->permissions = g_slist_append (priv->permissions, p); + + return TRUE; +} + +/** + * nm_setting_connection_remove_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permission to remove + * + * Removes the permission at index @idx from the connection. + */ +void +nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_if_fail (NM_IS_SETTING_CONNECTION (setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + iter = g_slist_nth (priv->permissions, idx); + g_return_if_fail (iter != NULL); + + permission_free ((Permission *) iter->data); + priv->permissions = g_slist_delete_link (priv->permissions, iter); +} + + /** * nm_setting_connection_get_autoconnect: * @setting: the #NMSettingConnection @@ -308,13 +576,30 @@ finalize (GObject *object) g_free (priv->id); g_free (priv->uuid); g_free (priv->type); + nm_utils_slist_free (priv->permissions, (GDestroyNotify) permission_free); G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); } +static GSList * +perm_stringlist_to_permlist (GSList *strlist) +{ + GSList *list = NULL, *iter; + + for (iter = strlist; iter; iter = g_slist_next (iter)) { + Permission *p; + + p = permission_new_from_str ((const char *) iter->data); + if (p) + list = g_slist_append (list, p); + } + + return list; +} + static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object); @@ -331,6 +616,10 @@ set_property (GObject *object, guint prop_id, g_free (priv->type); priv->type = g_value_dup_string (value); break; + case PROP_PERMISSIONS: + nm_utils_slist_free (priv->permissions, (GDestroyNotify) permission_free); + priv->permissions = perm_stringlist_to_permlist (g_value_get_boxed (value)); + break; case PROP_AUTOCONNECT: priv->autoconnect = g_value_get_boolean (value); break; @@ -346,11 +635,22 @@ set_property (GObject *object, guint prop_id, } } +static GSList * +perm_permlist_to_stringlist (GSList *permlist) +{ + GSList *list = NULL, *iter; + + for (iter = permlist; iter; iter = g_slist_next (iter)) + list = g_slist_append (list, permission_to_string ((Permission *) iter->data)); + return list; +} + static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingConnection *setting = NM_SETTING_CONNECTION (object); + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); switch (prop_id) { case PROP_ID: @@ -362,6 +662,9 @@ get_property (GObject *object, guint prop_id, case PROP_TYPE: g_value_set_string (value, nm_setting_connection_get_connection_type (setting)); break; + case PROP_PERMISSIONS: + g_value_take_boxed (value, perm_permlist_to_stringlist (priv->permissions)); + break; case PROP_AUTOCONNECT: g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); break; @@ -465,6 +768,45 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** + * NMSettingConnection:permissions: + * + * An array of strings defining what access a given user has to this + * connection. If this is NULL or empty, all users are allowed to access + * this connection. Otherwise a user is allowed to access this connection + * if and only if they are in this list. Each entry is of the form + * "[type]:[id]:[reserved]", for example: + * + * user:dcbw:blah + * + * At this time only the 'user' [type] is allowed. Any other values are + * ignored and reserved for future use. [id] is the username that this + * permission refers to, which may not contain the ':' character. Any + * [reserved] information present must be ignored and is reserved for + * future use. All of [type], [id], and [reserved] must be valid UTF-8. + */ + g_object_class_install_property + (object_class, PROP_PERMISSIONS, + _nm_param_spec_specialized (NM_SETTING_CONNECTION_PERMISSIONS, + "Permissions", + "An array of strings defining what access a given " + "user has to this connection. If this is NULL or " + "empty, all users are allowed to access this " + "connection. Otherwise a user is allowed to access " + "this connection if and only if they are in this " + "array. Each entry is of the form " + "\"[type]:[id]:[reserved]\", for example: " + "\"user:dcbw:blah\" At this time only the 'user' " + "[type] is allowed. Any other values are ignored and " + "reserved for future use. [id] is the username that " + "this permission refers to, which may not contain the " + "':' character. Any [reserved] information (if " + "present) must be ignored and is reserved for future " + "use. All of [type], [id], and [reserved] must be " + "valid UTF-8.", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingConnection:autoconnect: * * Whether or not the connection should be automatically connected by diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 6dedca22..1ec5bf12 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -74,6 +74,7 @@ GQuark nm_setting_connection_error_quark (void); #define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" #define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" #define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" /** * NMSettingConnection: @@ -97,13 +98,27 @@ typedef struct { GType nm_setting_connection_get_type (void); -NMSetting * nm_setting_connection_new (void); -const char *nm_setting_connection_get_id (NMSettingConnection *setting); -const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); -const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); -gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); -guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); -gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); +NMSetting * nm_setting_connection_new (void); +const char *nm_setting_connection_get_id (NMSettingConnection *setting); +const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); +const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); +gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); +guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); +gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); + +guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); +gboolean nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail); +gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); +gboolean nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail); +void nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx); G_END_DECLS diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index aff8be08..a1b7a6d3 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -27,6 +27,7 @@ #include <ctype.h> #include "nm-setting-gsm.h" #include "nm-utils.h" +#include "nm-setting-private.h" GQuark nm_setting_gsm_error_quark (void) @@ -72,6 +73,7 @@ typedef struct { char *number; /* For dialing, duh */ char *username; char *password; + NMSettingSecretFlags password_flags; char *apn; /* NULL for dynamic */ char *network_id; /* for manual registration or NULL for automatic */ @@ -79,6 +81,7 @@ typedef struct { guint32 allowed_bands; /* A bitfield of NM_SETTING_GSM_BAND_* */ char *pin; + NMSettingSecretFlags pin_flags; gboolean home_only; } NMSettingGsmPrivate; @@ -88,12 +91,12 @@ enum { PROP_NUMBER, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, PROP_APN, PROP_NETWORK_ID, PROP_NETWORK_TYPE, - PROP_BAND, PROP_PIN, - PROP_PUK, + PROP_PIN_FLAGS, PROP_ALLOWED_BANDS, PROP_HOME_ONLY, @@ -130,6 +133,20 @@ nm_setting_gsm_get_password (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->password; } +/** + * nm_setting_gsm_get_password_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:password + **/ +NMSettingSecretFlags +nm_setting_gsm_get_password_flags (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->password_flags; +} + const char * nm_setting_gsm_get_apn (NMSettingGsm *setting) { @@ -154,13 +171,6 @@ nm_setting_gsm_get_network_type (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->network_type; } -int -nm_setting_gsm_get_band (NMSettingGsm *setting) -{ - g_warning ("Tried to get deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_BAND); - return -1; -} - guint32 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting) { @@ -177,11 +187,18 @@ nm_setting_gsm_get_pin (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->pin; } -const char * -nm_setting_gsm_get_puk (NMSettingGsm *setting) +/** + * nm_setting_gsm_get_pin_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:pin + **/ +NMSettingSecretFlags +nm_setting_gsm_get_pin_flags (NMSettingGsm *setting) { - g_warning ("Tried to get deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK); - return NULL; + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->pin_flags; } gboolean @@ -290,8 +307,10 @@ need_secrets (NMSetting *setting) return NULL; if (priv->username) { - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_GSM_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_GSM_PASSWORD); + } } return secrets; @@ -323,7 +342,6 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object); - const char *str; char *tmp; switch (prop_id) { @@ -339,6 +357,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; case PROP_APN: g_free (priv->apn); priv->apn = NULL; @@ -356,10 +377,6 @@ set_property (GObject *object, guint prop_id, case PROP_NETWORK_TYPE: priv->network_type = g_value_get_int (value); break; - case PROP_BAND: - if (g_value_get_int (value) != -1) - g_warning ("Tried to set deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_BAND); - break; case PROP_ALLOWED_BANDS: priv->allowed_bands = g_value_get_uint (value); break; @@ -367,10 +384,8 @@ set_property (GObject *object, guint prop_id, g_free (priv->pin); priv->pin = g_value_dup_string (value); break; - case PROP_PUK: - str = g_value_get_string (value); - if (str && strlen (str)) - g_warning ("Tried to set deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK); + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_uint (value); break; case PROP_HOME_ONLY: priv->home_only = g_value_get_boolean (value); @@ -397,6 +412,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_gsm_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_gsm_get_password_flags (setting)); + break; case PROP_APN: g_value_set_string (value, nm_setting_gsm_get_apn (setting)); break; @@ -412,13 +430,8 @@ get_property (GObject *object, guint prop_id, case PROP_PIN: g_value_set_string (value, nm_setting_gsm_get_pin (setting)); break; - case PROP_PUK: - /* deprecated */ - g_value_set_string (value, NULL); - break; - case PROP_BAND: - /* deprecated */ - g_value_set_int (value, -1); + case PROP_PIN_FLAGS: + g_value_set_uint (value, nm_setting_gsm_get_pin_flags (setting)); break; case PROP_HOME_ONLY: g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting)); @@ -501,6 +514,20 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSettingGsm:password-flags: + * + * Flags indicating how to handle #NMSettingGsm:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the GSM password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingGsm:apn: * * The GPRS Access Point Name specifying the APN used when establishing a @@ -620,6 +647,20 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSettingGsm:pin-flags: + * + * Flags indicating how to handle #NMSettingGsm:pin:. + **/ + g_object_class_install_property (object_class, PROP_PIN_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS, + "PIN Flags", + "Flags indicating how to handle the GSM SIM PIN.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingGsm:home-only: * * When TRUE, only connections to the home network will be allowed. @@ -634,31 +675,4 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) "not be made.", FALSE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - - /* Deprecated properties */ - /** - * NMSettingGsm:puk: - * - * DEPRECATED - **/ - g_object_class_install_property - (object_class, PROP_PUK, - g_param_spec_string (NM_SETTING_GSM_PUK, - "PUK (DEPRECATED and UNUSED)", - "PUK (DEPRECATED and UNUSED)", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); - - /** - * NMSettingGsm:band: - * - * DEPRECATED - **/ - g_object_class_install_property - (object_class, PROP_BAND, - g_param_spec_int (NM_SETTING_GSM_BAND, - "Band (DEPRECATED and UNUSED)", - "Band (DEPRECATED and UNUSED)", - -1, 5, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h index 0ac71224..855787c2 100644 --- a/libnm-util/nm-setting-gsm.h +++ b/libnm-util/nm-setting-gsm.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,26 +53,17 @@ GType nm_setting_gsm_error_get_type (void); #define NM_SETTING_GSM_ERROR nm_setting_gsm_error_quark () GQuark nm_setting_gsm_error_quark (void); -#define NM_SETTING_GSM_NUMBER "number" -#define NM_SETTING_GSM_USERNAME "username" -#define NM_SETTING_GSM_PASSWORD "password" -#define NM_SETTING_GSM_APN "apn" -#define NM_SETTING_GSM_NETWORK_ID "network-id" -#define NM_SETTING_GSM_NETWORK_TYPE "network-type" -#define NM_SETTING_GSM_ALLOWED_BANDS "allowed-bands" -#define NM_SETTING_GSM_PIN "pin" -#define NM_SETTING_GSM_HOME_ONLY "home-only" - -/* DEPRECATED & UNUSED */ -#define NM_SETTING_GSM_PUK "puk" -#define NM_SETTING_GSM_BAND "band" - -/* DEPRECATED, use NM_SETTING_NETWORK_TYPE_* instead */ -#define NM_GSM_NETWORK_ANY NM_SETTING_GSM_NETWORK_TYPE_ANY -#define NM_GSM_NETWORK_UMTS_HSPA NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA -#define NM_GSM_NETWORK_GPRS_EDGE NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE -#define NM_GSM_NETWORK_PREFER_UMTS_HSPA NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA -#define NM_GSM_NETWORK_PREFER_GPRS_EDGE NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE +#define NM_SETTING_GSM_NUMBER "number" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_NETWORK_TYPE "network-type" +#define NM_SETTING_GSM_ALLOWED_BANDS "allowed-bands" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" typedef enum { NM_SETTING_GSM_NETWORK_TYPE_ANY = -1, @@ -126,9 +117,8 @@ guint32 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting); const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); -/* DEPRECATED & UNUSED */ -const char *nm_setting_gsm_get_puk (NMSettingGsm *setting); -int nm_setting_gsm_get_band (NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_pin_flags (NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index ec8de7ce..6961050d 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -66,6 +66,10 @@ nm_setting_ip4_config_error_get_type (void) return etype; } +#if GLIB_CHECK_VERSION(2,26,0) +G_DEFINE_BOXED_TYPE (NMIP4Address, nm_ip4_address, nm_ip4_address_dup, nm_ip4_address_unref) +G_DEFINE_BOXED_TYPE (NMIP4Route, nm_ip4_route, nm_ip4_route_dup, nm_ip4_route_unref) +#endif G_DEFINE_TYPE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING) @@ -411,7 +415,7 @@ nm_setting_ip4_config_get_ignore_auto_dns (NMSettingIP4Config *setting) const char * nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting) { - g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL); return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_client_id; } @@ -427,7 +431,7 @@ nm_setting_ip4_config_get_dhcp_send_hostname (NMSettingIP4Config *setting) const char * nm_setting_ip4_config_get_dhcp_hostname (NMSettingIP4Config *setting) { - g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE); + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL); return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_hostname; } diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index 80ddd475..91cf0ea6 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -74,6 +74,8 @@ GQuark nm_setting_ip4_config_error_quark (void); typedef struct NMIP4Address NMIP4Address; +GType nm_ip4_address_get_type (void); + NMIP4Address * nm_ip4_address_new (void); NMIP4Address * nm_ip4_address_dup (NMIP4Address *source); void nm_ip4_address_ref (NMIP4Address *address); @@ -95,6 +97,8 @@ void nm_ip4_address_set_gateway (NMIP4Address *address, typedef struct NMIP4Route NMIP4Route; +GType nm_ip4_route_get_type (void); + NMIP4Route * nm_ip4_route_new (void); NMIP4Route * nm_ip4_route_dup (NMIP4Route *route); void nm_ip4_route_ref (NMIP4Route *route); diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index e8af0580..1adbbdcb 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -65,6 +65,10 @@ nm_setting_ip6_config_error_get_type (void) return etype; } +#if GLIB_CHECK_VERSION(2,26,0) +G_DEFINE_BOXED_TYPE (NMIP6Address, nm_ip6_address, nm_ip6_address_dup, nm_ip6_address_unref) +G_DEFINE_BOXED_TYPE (NMIP6Route, nm_ip6_route, nm_ip6_route_dup, nm_ip6_route_unref) +#endif G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING) @@ -498,9 +502,7 @@ finalize (GObject *object) NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object); g_free (priv->method); - - if (priv->dns) - g_slist_free (priv->dns); + g_slist_free (priv->dns); nm_utils_slist_free (priv->dns_search, g_free); nm_utils_slist_free (priv->addresses, g_free); diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h index e3e286e6..b9733b4a 100644 --- a/libnm-util/nm-setting-ip6-config.h +++ b/libnm-util/nm-setting-ip6-config.h @@ -74,6 +74,8 @@ GQuark nm_setting_ip6_config_error_quark (void); typedef struct NMIP6Address NMIP6Address; +GType nm_ip6_address_get_type (void); + NMIP6Address * nm_ip6_address_new (void); NMIP6Address * nm_ip6_address_dup (NMIP6Address *source); void nm_ip6_address_ref (NMIP6Address *address); @@ -95,6 +97,8 @@ void nm_ip6_address_set_gateway (NMIP6Address *address, typedef struct NMIP6Route NMIP6Route; +GType nm_ip6_route_get_type (void); + NMIP6Route * nm_ip6_route_new (void); NMIP6Route * nm_ip6_route_dup (NMIP6Route *route); void nm_ip6_route_ref (NMIP6Route *route); diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index d1aba43d..18dd7983 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -19,13 +19,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include <string.h> #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" +#include "nm-setting-private.h" GQuark nm_setting_pppoe_error_quark (void) @@ -71,6 +72,7 @@ typedef struct { char *service; char *username; char *password; + NMSettingSecretFlags password_flags; } NMSettingPPPOEPrivate; enum { @@ -78,6 +80,7 @@ enum { PROP_SERVICE, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, LAST_PROP }; @@ -112,6 +115,20 @@ nm_setting_pppoe_get_password (NMSettingPPPOE *setting) return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password; } +/** + * nm_setting_pppoe_get_password_flags: + * @setting: the #NMSettingPPPOE + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingPPPOE:password + **/ +NMSettingSecretFlags +nm_setting_pppoe_get_password_flags (NMSettingPPPOE *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password_flags; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -146,13 +163,15 @@ static GPtrArray * need_secrets (NMSetting *setting) { NMSettingPPPOEPrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (setting); - GPtrArray *secrets; + GPtrArray *secrets = NULL; if (priv->password) return NULL; - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_PPPOE_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_PPPOE_PASSWORD); + } return secrets; } @@ -182,6 +201,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -204,6 +226,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_pppoe_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_pppoe_get_password_flags (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -271,4 +296,18 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) "Password used to authenticate with the PPPoE service.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + /** + * NMSettingPPPOE:password-flags: + * + * Flags indicating how to handle #NMSettingPPPOE:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_PPPOE_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the PPPoE password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-pppoe.h b/libnm-util/nm-setting-pppoe.h index 83e95d4e..d163decb 100644 --- a/libnm-util/nm-setting-pppoe.h +++ b/libnm-util/nm-setting-pppoe.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,9 +53,10 @@ GType nm_setting_pppoe_error_get_type (void); #define NM_SETTING_PPPOE_ERROR nm_setting_pppoe_error_quark () GQuark nm_setting_pppoe_error_quark (void); -#define NM_SETTING_PPPOE_SERVICE "service" -#define NM_SETTING_PPPOE_USERNAME "username" -#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_SERVICE "service" +#define NM_SETTING_PPPOE_USERNAME "username" +#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_PASSWORD_FLAGS "password-flags" typedef struct { NMSetting parent; @@ -77,6 +78,7 @@ NMSetting *nm_setting_pppoe_new (void); const char *nm_setting_pppoe_get_service (NMSettingPPPOE *setting); const char *nm_setting_pppoe_get_username (NMSettingPPPOE *setting); const char *nm_setting_pppoe_get_password (NMSettingPPPOE *setting); +NMSettingSecretFlags nm_setting_pppoe_get_password_flags (NMSettingPPPOE *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h new file mode 100644 index 00000000..5c4e0a5e --- /dev/null +++ b/libnm-util/nm-setting-private.h @@ -0,0 +1,31 @@ +/* -*- 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. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTING_PRIVATE_H +#define NM_SETTING_PRIVATE_H + +#define NM_SETTING_SECRET_FLAGS_ALL \ + (NM_SETTING_SECRET_FLAG_NONE | \ + NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ + NM_SETTING_SECRET_FLAG_NOT_SAVED | \ + NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + +#endif /* NM_SETTING_PRIVATE_H */ + diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 53b609e2..d3aac030 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -18,16 +18,19 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include <string.h> +#include <errno.h> +#include <stdlib.h> #include <dbus/dbus-glib.h> #include "nm-setting-vpn.h" #include "nm-param-spec-specialized.h" #include "nm-utils.h" #include "nm-dbus-glib-types.h" +#include "nm-setting-private.h" GQuark nm_setting_vpn_error_quark (void) @@ -158,9 +161,17 @@ nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); } +/** + * nm_setting_vpn_foreach_data_item: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all data items stored in this setting + */ void nm_setting_vpn_foreach_data_item (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); @@ -200,9 +211,17 @@ nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); } +/** + * nm_setting_vpn_foreach_secret: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all secrets stored in this setting. + */ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); @@ -245,34 +264,158 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } static gboolean -update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +update_secret_string (NMSetting *setting, + const char *key, + const char *value, + GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); - char *str; g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - if (!G_VALUE_HOLDS_STRING (value)) { + if (!value || !strlen (value)) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "%s", key); + "Secret %s was empty", key); return FALSE; } - str = g_value_dup_string (value); - if (!str || !strlen (str)) { - g_set_error (error, NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Secret %s was empty", key); - g_free (str); - return FALSE; + g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value)); + return TRUE; +} + +static gboolean +update_secret_hash (NMSetting *setting, + GHashTable *secrets, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + GHashTableIter iter; + const char *name, *value; + + g_return_val_if_fail (secrets != NULL, FALSE); + + /* Make sure the items are valid */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (!name || !strlen (name)) { + g_set_error_literal (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret name was empty"); + return FALSE; + } + + if (!value || !strlen (value)) { + g_set_error (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret %s value was empty", name); + return FALSE; + } + } + + /* Now add the items to the settings' secrets list */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (value == NULL) { + g_warn_if_fail (value != NULL); + continue; + } + if (strlen (value) == 0) { + g_warn_if_fail (strlen (value) > 0); + continue; + } + + g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); + } + + return TRUE; +} + +static gboolean +update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +{ + gboolean success = FALSE; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if (G_VALUE_HOLDS_STRING (value)) { + /* Passing the string properties individually isn't correct, and won't + * produce the correct result, but for some reason that's how it used + * to be done. So even though it's not correct, keep the code around + * for compatibility's sake. + */ + success = update_secret_string (setting, key, g_value_get_string (value), error); + } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { + if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) { + g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET, + "Property %s not a secret property", key); + } else + success = update_secret_hash (setting, g_value_get_boxed (value), error); + } else + g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key); + + return success; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + gboolean success = FALSE; + char *flags_key; + gpointer val; + unsigned long tmp; + + flags_key = g_strdup_printf ("%s-flags", secret_name); + if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { + errno = 0; + tmp = strtoul ((const char *) val, NULL, 10); + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { + *out_flags = (guint32) tmp; + success = TRUE; + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Failed to convert '%s' value '%s' to uint", + flags_key, (const char *) val); + } + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_FOUND, + "Secret flags property '%s' not found", flags_key); } + g_free (flags_key); + return success; +} - g_hash_table_insert (priv->secrets, g_strdup (key), str); +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + g_strdup_printf ("%s-flags", secret_name), + g_strdup_printf ("%u", flags)); return TRUE; } +static GPtrArray * +need_secrets (NMSetting *setting) +{ + /* Assume that VPN connections need secrets since they almost always will */ + return g_ptr_array_sized_new (1); +} + static void destroy_one_secret (gpointer data) { @@ -309,6 +452,8 @@ finalize (GObject *object) static void copy_hash (gpointer key, gpointer value, gpointer user_data) { + g_return_if_fail (value != NULL); + g_return_if_fail (strlen (value)); g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value)); } @@ -386,8 +531,12 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + + parent_class->verify = verify; parent_class->update_one_secret = update_one_secret; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; + parent_class->need_secrets = need_secrets; /* Properties */ /** @@ -395,7 +544,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) * * D-Bus service name of the VPN plugin that this setting uses to connect * to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc - * plugin. + * plugin. **/ g_object_class_install_property (object_class, PROP_SERVICE_TYPE, diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index 9c684bbf..6ff19286 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -71,7 +71,7 @@ typedef struct { void (*_reserved4) (void); } NMSettingVPNClass; -typedef void (*VPNIterFunc) (const char *key, const char *value, gpointer user_data); +typedef void (*NMVPNIterFunc) (const char *key, const char *value, gpointer user_data); GType nm_setting_vpn_get_type (void); @@ -87,7 +87,7 @@ const char * nm_setting_vpn_get_data_item (NMSettingVPN *setting, void nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key); void nm_setting_vpn_foreach_data_item (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data); void nm_setting_vpn_add_secret (NMSettingVPN *setting, @@ -98,7 +98,7 @@ const char * nm_setting_vpn_get_secret (NMSettingVPN *setting, void nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key); void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data); G_END_DECLS diff --git a/libnm-util/nm-setting-wimax.c b/libnm-util/nm-setting-wimax.c new file mode 100644 index 00000000..628c81d3 --- /dev/null +++ b/libnm-util/nm-setting-wimax.c @@ -0,0 +1,243 @@ +/* -*- 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. + * + * (C) Copyright 2011 Red Hat, Inc. + * (C) Copyright 2009 Novell, Inc. + */ + +#include <string.h> +#include <net/ethernet.h> +#include <dbus/dbus-glib.h> + +#include "nm-setting-wimax.h" +#include "nm-param-spec-specialized.h" + +GQuark +nm_setting_wimax_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-wimax-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_wimax_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY, "MissingProperty"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingWimaxError", values); + } + return etype; +} + + +G_DEFINE_TYPE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING) + +#define NM_SETTING_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate)) + +typedef struct { + char *network_name; + GByteArray *mac_address; +} NMSettingWimaxPrivate; + +enum { + PROP_0, + PROP_NETWORK_NAME, + PROP_MAC_ADDRESS, + + LAST_PROP +}; + +NMSetting * +nm_setting_wimax_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIMAX, NULL); +} + +const char * +nm_setting_wimax_get_network_name (NMSettingWimax *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE (setting)->network_name; +} + +const GByteArray * +nm_setting_wimax_get_mac_address (NMSettingWimax *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE (setting)->mac_address; +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings, GError **error) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (setting); + + if (!priv->network_name) { + g_set_error (error, + NM_SETTING_WIMAX_ERROR, + NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY, + NM_SETTING_WIMAX_NETWORK_NAME); + + return FALSE; + } + + if (!strlen (priv->network_name)) { + g_set_error (error, + NM_SETTING_WIMAX_ERROR, + NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, + NM_SETTING_WIMAX_NETWORK_NAME); + + return FALSE; + } + + if (priv->mac_address && priv->mac_address->len != ETH_ALEN) { + g_set_error (error, + NM_SETTING_WIMAX_ERROR, + NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, + NM_SETTING_WIMAX_MAC_ADDRESS); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_wimax_init (NMSettingWimax *setting) +{ + g_object_set (setting, NM_SETTING_NAME, NM_SETTING_WIMAX_SETTING_NAME, NULL); +} + +static void +finalize (GObject *object) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object); + + g_free (priv->network_name); + if (priv->mac_address) + g_byte_array_free (priv->mac_address, TRUE); + + G_OBJECT_CLASS (nm_setting_wimax_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_free (priv->network_name); + priv->network_name = g_value_dup_string (value); + break; + case PROP_MAC_ADDRESS: + if (priv->mac_address) + g_byte_array_free (priv->mac_address, TRUE); + priv->mac_address = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingWimax *setting = NM_SETTING_WIMAX (object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_value_set_string (value, nm_setting_wimax_get_network_name (setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_boxed (value, nm_setting_wimax_get_mac_address (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingWimaxPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingWimax:network-name: + * + * Network Service Provider (NSP) name of the WiMAX network this connection + * should use. + **/ + g_object_class_install_property + (object_class, PROP_NETWORK_NAME, + g_param_spec_string (NM_SETTING_WIMAX_NETWORK_NAME, + "NetworkName", + "Network Service Provider (NSP) name of the WiMAX " + "network this connection should use.", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWimax:mac-address: + * + * If specified, this connection will only apply to the WiMAX device + * whose MAC address matches. This property does not change the MAC address + * of the device (known as MAC spoofing). + **/ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + _nm_param_spec_specialized (NM_SETTING_WIMAX_MAC_ADDRESS, + "MAC Address", + "If specified, this connection will only apply to " + "the WiMAX device whose MAC address matches. " + "This property does not change the MAC address " + "of the device (known as MAC spoofing).", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-wimax.h b/libnm-util/nm-setting-wimax.h new file mode 100644 index 00000000..a3e500be --- /dev/null +++ b/libnm-util/nm-setting-wimax.h @@ -0,0 +1,70 @@ +/* -*- 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. + * + * (C) Copyright 2009 Novell, Inc. + */ + +#ifndef NM_SETTING_WIMAX_H +#define NM_SETTING_WIMAX_H + +#include <nm-setting.h> + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIMAX (nm_setting_wimax_get_type ()) +#define NM_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimax)) +#define NM_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) +#define NM_IS_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIMAX)) +#define NM_IS_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_WIMAX)) +#define NM_SETTING_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) + +#define NM_SETTING_WIMAX_SETTING_NAME "wimax" + +typedef enum +{ + NM_SETTING_WIMAX_ERROR_UNKNOWN = 0, + NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, + NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY +} NMSettingWimaxError; + +#define NM_TYPE_SETTING_WIMAX_ERROR (nm_setting_wimax_error_get_type ()) +GType nm_setting_wimax_error_get_type (void); + +#define NM_SETTING_WIMAX_ERROR nm_setting_wimax_error_quark () +GQuark nm_setting_wimax_error_quark (void); + +#define NM_SETTING_WIMAX_NETWORK_NAME "network-name" +#define NM_SETTING_WIMAX_MAC_ADDRESS "mac-address" + +typedef struct { + NMSetting parent; +} NMSettingWimax; + +typedef struct { + NMSettingClass parent; +} NMSettingWimaxClass; + +GType nm_setting_wimax_get_type (void); + +NMSetting *nm_setting_wimax_new (void); +const char *nm_setting_wimax_get_network_name (NMSettingWimax *setting); +const GByteArray *nm_setting_wimax_get_mac_address (NMSettingWimax *setting); + +G_END_DECLS + +#endif /* NM_SETTING_WIMAX_H */ diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index ca789b42..3b4eba6f 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -33,6 +33,7 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" #include "nm-utils-private.h" +#include "nm-setting-private.h" GQuark nm_setting_wireless_security_error_quark (void) @@ -82,19 +83,28 @@ G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_ typedef struct { char *key_mgmt; - guint32 wep_tx_keyidx; char *auth_alg; GSList *proto; /* GSList of strings */ GSList *pairwise; /* GSList of strings */ GSList *group; /* GSList of strings */ + + /* LEAP */ char *leap_username; + char *leap_password; + NMSettingSecretFlags leap_password_flags; + + /* WEP */ char *wep_key0; char *wep_key1; char *wep_key2; char *wep_key3; - char *psk; - char *leap_password; + NMSettingSecretFlags wep_key_flags; NMWepKeyType wep_key_type; + guint32 wep_tx_keyidx; + + /* WPA-PSK */ + char *psk; + NMSettingSecretFlags psk_flags; } NMSettingWirelessSecurityPrivate; enum { @@ -110,9 +120,12 @@ enum { PROP_WEP_KEY1, PROP_WEP_KEY2, PROP_WEP_KEY3, + PROP_WEP_KEY_FLAGS, + PROP_WEP_KEY_TYPE, PROP_PSK, + PROP_PSK_FLAGS, PROP_LEAP_PASSWORD, - PROP_WEP_KEY_TYPE, + PROP_LEAP_PASSWORD_FLAGS, LAST_PROP }; @@ -343,6 +356,21 @@ nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting) return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk; } +/** + * nm_setting_wireless_security_get_psk_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:psk + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags; +} + const char * nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting) { @@ -359,6 +387,21 @@ nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setti return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password; } +/** + * nm_setting_wireless_security_get_leap_password_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:leap-password + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags; +} + const char * nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx) { @@ -428,6 +471,20 @@ nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting) return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->auth_alg; } +/** + * nm_setting_wireless_security_get_wep_key_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the all WEP keys + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags; +} + NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting) { @@ -771,6 +828,58 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return TRUE; } +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->get_secret_flags (setting, secret_name, verify_override, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->set_secret_flags (setting, secret_name, verify_override, flags, error); +} + static void nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting) { @@ -852,14 +961,23 @@ set_property (GObject *object, guint prop_id, case PROP_WEP_KEY3: nm_setting_wireless_security_set_wep_key (setting, 3, g_value_get_string (value)); break; + case PROP_WEP_KEY_FLAGS: + priv->wep_key_flags = g_value_get_uint (value); + break; case PROP_PSK: g_free (priv->psk); priv->psk = g_value_dup_string (value); break; + case PROP_PSK_FLAGS: + priv->psk_flags = g_value_get_uint (value); + break; case PROP_LEAP_PASSWORD: g_free (priv->leap_password); priv->leap_password = g_value_dup_string (value); break; + case PROP_LEAP_PASSWORD_FLAGS: + priv->leap_password_flags = g_value_get_uint (value); + break; case PROP_WEP_KEY_TYPE: priv->wep_key_type = g_value_get_uint (value); break; @@ -910,12 +1028,21 @@ get_property (GObject *object, guint prop_id, case PROP_WEP_KEY3: g_value_set_string (value, priv->wep_key3); break; + case PROP_WEP_KEY_FLAGS: + g_value_set_uint (value, priv->wep_key_flags); + break; case PROP_PSK: g_value_set_string (value, priv->psk); break; + case PROP_PSK_FLAGS: + g_value_set_uint (value, priv->psk_flags); + break; case PROP_LEAP_PASSWORD: g_value_set_string (value, priv->leap_password); break; + case PROP_LEAP_PASSWORD_FLAGS: + g_value_set_uint (value, priv->leap_password_flags); + break; case PROP_WEP_KEY_TYPE: g_value_set_uint (value, priv->wep_key_type); break; @@ -938,8 +1065,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->need_secrets = need_secrets; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; /* Properties */ /** @@ -1140,6 +1269,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSettingWirelessSecurity:wep-key-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity WEP keys. + **/ + g_object_class_install_property (object_class, PROP_WEP_KEY_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + "WEP Key Flags", + "Flags indicating how to handle the WEP keys.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingWirelessSecurity:psk: * * Pre-Shared-Key for WPA networks. If the key is 64-characters long, it @@ -1165,6 +1308,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSettingWirelessSecurity:psk-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity:psk + **/ + g_object_class_install_property (object_class, PROP_PSK_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, + "PSK Flags", + "Flags indicating how to handle the WPA PSK key.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingWirelessSecurity:leap-password: * * The login password for legacy LEAP connections (ie, key-mgmt = @@ -1180,6 +1337,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); /** + * NMSettingWirelessSecurity:leap-password-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity:leap-password. + **/ + g_object_class_install_property (object_class, PROP_LEAP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + "LEAP Password Flags", + "Flags indicating how to handle the LEAP password.", + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAGS_ALL, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** * NMSettingWirelessSecurity:wep-key-type: * * Controls the interpretation of WEP keys. Allowed values are 1 (interpret diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h index 90d971b2..743e161f 100644 --- a/libnm-util/nm-setting-wireless-security.h +++ b/libnm-util/nm-setting-wireless-security.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -75,9 +75,12 @@ typedef enum { #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS "wep-key-flags" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type" #define NM_SETTING_WIRELESS_SECURITY_PSK "psk" +#define NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS "psk-flags" #define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password" -#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags" typedef struct { NMSetting parent; @@ -118,14 +121,18 @@ void nm_setting_wireless_security_remove_group (NMSettingWirelessSec void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx); void nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key); guint32 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting); + +NMSettingSecretFlags nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting); NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index ec7d53ad..1e243f0f 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -130,11 +130,11 @@ match_cipher (const char *cipher, gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, - NMSettingWirelessSecurity *s_wireless_sec, - guint32 ap_flags, - guint32 ap_wpa, - guint32 ap_rsn, - guint32 ap_mode) + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode) { NMSettingWirelessPrivate *priv; const char *key_mgmt = NULL, *cipher; @@ -446,7 +446,7 @@ static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); - const char *valid_modes[] = { "infrastructure", "adhoc", NULL }; + const char *valid_modes[] = { NM_SETTING_WIRELESS_MODE_INFRA, NM_SETTING_WIRELESS_MODE_ADHOC, NULL }; const char *valid_bands[] = { "a", "bg", NULL }; GSList *iter; diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index 2216a246..d3e1ed41 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -26,6 +26,7 @@ #ifndef NM_SETTING_WIRELESS_H #define NM_SETTING_WIRELESS_H +#include <NetworkManager.h> #include <nm-setting.h> #include <nm-setting-wireless-security.h> @@ -68,6 +69,9 @@ GQuark nm_setting_wireless_error_quark (void); #define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" #define NM_SETTING_WIRELESS_SEC "security" +#define NM_SETTING_WIRELESS_MODE_ADHOC "adhoc" +#define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure" + typedef struct { NMSetting parent; } NMSettingWireless; @@ -106,11 +110,11 @@ const char *nm_setting_wireless_get_seen_bssid (NMSettingWireless guint32 i); gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, - NMSettingWirelessSecurity *s_wireless_sec, - guint32 ap_flags, - guint32 ap_wpa, - guint32 ap_rsn, - guint32 ap_mode); + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode); G_END_DECLS diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 6f014bff..0f8b7d4f 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -19,13 +19,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include <string.h> #include "nm-setting.h" +#include "nm-setting-private.h" #include "nm-setting-connection.h" #include "nm-utils.h" @@ -107,21 +108,23 @@ destroy_gvalue (gpointer data) /** * nm_setting_to_hash: * @setting: the #NMSetting + * @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL * * Converts the #NMSetting into a #GHashTable mapping each setting property * name to a GValue describing that property, suitable for marshalling over * D-Bus or serializing. The mapping is string:GValue. * - * Returns: a new #GHashTable describing the setting's properties + * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable describing the setting's properties **/ GHashTable * -nm_setting_to_hash (NMSetting *setting) +nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) { GHashTable *hash; GParamSpec **property_specs; guint n_property_specs; guint i; + g_return_val_if_fail (setting != NULL, NULL); g_return_val_if_fail (NM_IS_SETTING (setting), NULL); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); @@ -132,29 +135,41 @@ nm_setting_to_hash (NMSetting *setting) } hash = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - destroy_gvalue); + (GDestroyNotify) g_free, destroy_gvalue); for (i = 0; i < n_property_specs; i++) { GParamSpec *prop_spec = property_specs[i]; + GValue *value; - if (prop_spec->flags & NM_SETTING_PARAM_SERIALIZE) { - GValue *value; + if (!(prop_spec->flags & NM_SETTING_PARAM_SERIALIZE)) + continue; - value = g_slice_new0 (GValue); - g_value_init (value, prop_spec->value_type); - g_object_get_property (G_OBJECT (setting), prop_spec->name, value); + if ( (flags & NM_SETTING_HASH_FLAG_NO_SECRETS) + && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; - /* Don't serialize values with default values */ - if (!g_param_value_defaults (prop_spec, value)) - g_hash_table_insert (hash, g_strdup (prop_spec->name), value); - else - destroy_gvalue (value); - } - } + if ( (flags & NM_SETTING_HASH_FLAG_ONLY_SECRETS) + && !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; + value = g_slice_new0 (GValue); + g_value_init (value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, value); + + /* Don't serialize values with default values */ + if (!g_param_value_defaults (prop_spec, value)) + g_hash_table_insert (hash, g_strdup (prop_spec->name), value); + else + destroy_gvalue (value); + } g_free (property_specs); + /* Don't return empty hashes */ + if (g_hash_table_size (hash) < 1) { + g_hash_table_destroy (hash); + hash = NULL; + } + return hash; } @@ -176,7 +191,7 @@ one_property_cb (gpointer key, gpointer val, gpointer user_data) param_spec = g_object_class_find_property (info->class, prop_name); if (!param_spec || !(param_spec->flags & NM_SETTING_PARAM_SERIALIZE)) { /* Oh, we're so nice and only warn, maybe it should be a fatal error? */ - nm_warning ("Ignoring invalid property '%s'", prop_name); + g_warning ("Ignoring invalid property '%s'", prop_name); return; } @@ -185,8 +200,8 @@ one_property_cb (gpointer key, gpointer val, gpointer user_data) info->params[info->n_params].name = prop_name; info->n_params++; } else { - nm_warning ("Ignoring property '%s' with invalid type (%s)", - prop_name, G_VALUE_TYPE_NAME (src_value)); + g_warning ("Ignoring property '%s' with invalid type (%s)", + prop_name, G_VALUE_TYPE_NAME (src_value)); g_value_unset (dst_value); } } @@ -254,7 +269,7 @@ duplicate_setting (NMSetting *setting, * * Duplicates a #NMSetting. * - * Returns: a new #NMSetting containing the same properties and values as the + * Returns: (transfer full): a new #NMSetting containing the same properties and values as the * source #NMSetting **/ NMSetting * @@ -514,7 +529,7 @@ nm_setting_diff (NMSetting *a, /** * nm_setting_enumerate_values: * @setting: the #NMSetting - * @func: user-supplied function called for each property of the setting + * @func: (scope call): user-supplied function called for each property of the setting * @user_data: user data passed to @func at each invocation * * Iterates over each property of the #NMSetting object, calling the supplied @@ -589,7 +604,7 @@ nm_setting_clear_secrets (NMSetting *setting) * guide to what secrets may be required, because in some circumstances, there * is no way to conclusively determine exactly which secrets are needed. * - * Returns: a #GPtrArray containing the property names of secrets of the + * Returns: (transfer full) (element-type utf8): a #GPtrArray containing the property names of secrets of the * #NMSetting which may be required; the caller owns the array * and must free the each array element with g_free(), as well as the array * itself with g_ptr_array_free() @@ -684,6 +699,124 @@ nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **err return TRUE; } +static gboolean +is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) +{ + GParamSpec *pspec; + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), secret_name); + if (!pspec) { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_FOUND, + "Secret %s not provided by this setting", secret_name); + return FALSE; + } + + if (!(pspec->flags & NM_SETTING_PARAM_SECRET)) { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_SECRET, + "Property %s is not a secret", secret_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + char *flags_prop; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + if (verify_secret) + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL); + g_free (flags_prop); + + if (out_flags) + *out_flags = flags; + return TRUE; +} + +/** + * nm_setting_get_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to get flags for + * @out_flags: on success, the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), FALSE if not + **/ +gboolean +nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error) +{ + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->get_secret_flags (setting, secret_name, TRUE, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + char *flags_prop; + + if (verify_secret) + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_set (G_OBJECT (setting), flags_prop, flags, NULL); + g_free (flags_prop); + return TRUE; +} + +/** + * nm_setting_set_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to set flags for + * @flags: the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), FALSE if not + **/ +gboolean +nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error) +{ + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (flags <= NM_SETTING_SECRET_FLAGS_ALL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, TRUE, flags, error); +} + /** * nm_setting_to_string: * @setting: the #NMSetting @@ -775,7 +908,7 @@ constructor (GType type, priv = NM_SETTING_GET_PRIVATE (object); if (!priv->name) { - nm_warning ("Setting name is not set."); + g_warning ("Setting name is not set."); g_object_unref (object); object = NULL; } @@ -840,6 +973,8 @@ nm_setting_class_init (NMSettingClass *setting_class) object_class->finalize = finalize; setting_class->update_one_secret = update_one_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; /* Properties */ diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index 6b7e92ab..ef3011ad 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -84,6 +84,34 @@ GQuark nm_setting_error_quark (void); #define NM_SETTING_NAME "name" /** + * NMSettingSecretFlags: + * @NM_SETTING_SECRET_FLAG_NONE: the system is responsible for providing and + * storing this secret (default) + * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible + * for providing and storing this secret; when it is required agents will be + * asked to retrieve it + * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but + * should be requested from the user each time it is needed + * @NM_SETTING_SECRET_FLAG_NOT_REQUIRED: in situations where it cannot be + * automatically determined that the secret is required (some VPNs and PPP + * providers dont require all secrets) this flag indicates that the specific + * secret is not required + * + * These flags indicate specific behavior related to handling of a secret. Each + * secret has a corresponding set of these flags which indicate how the secret + * is to be stored and/or requested when it is needed. + * + **/ +typedef enum { + NM_SETTING_SECRET_FLAG_NONE = 0x00000000, + NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 0x00000004 + + /* NOTE: if adding flags, update nm-setting-private.h as well */ +} NMSettingSecretFlags; + +/** * NMSetting: * * The NMSetting struct contains only private data. @@ -108,6 +136,18 @@ typedef struct { GValue *value, GError **error); + gboolean (*get_secret_flags) (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error); + + gboolean (*set_secret_flags) (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -124,7 +164,25 @@ typedef void (*NMSettingValueIterFn) (NMSetting *setting, GType nm_setting_get_type (void); -GHashTable *nm_setting_to_hash (NMSetting *setting); +/** + * NMSettingHashFlags: + * @NM_SETTING_HASH_FLAG_ALL: hash all properties (including secrets) + * @NM_SETTING_HASH_FLAG_NO_SECRETS: do not include secrets + * @NM_SETTING_HASH_FLAG_ONLY_SECRETS: only hash secrets + * + * These flags determine which properties are added to the resulting hash + * when calling nm_setting_to_hash(). + * + **/ +typedef enum { + NM_SETTING_HASH_FLAG_ALL = 0x00000000, + NM_SETTING_HASH_FLAG_NO_SECRETS = 0x00000001, + NM_SETTING_HASH_FLAG_ONLY_SECRETS = 0x00000002, +} NMSettingHashFlags; + +GHashTable *nm_setting_to_hash (NMSetting *setting, + NMSettingHashFlags flags); + NMSetting *nm_setting_new_from_hash (GType setting_type, GHashTable *hash); @@ -193,6 +251,16 @@ gboolean nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error); +gboolean nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error); + +gboolean nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error); + G_END_DECLS #endif /* NM_SETTING_H */ diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 7f40fc7e..bac7fda3 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -24,6 +24,7 @@ * (C) Copyright 2005 - 2010 Red Hat, Inc. */ +#include "config.h" #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -214,45 +215,6 @@ get_encodings_for_lang (const char *lang, return success; } -static char * -string_to_utf8 (const char *str, gsize len) -{ - char *converted = NULL; - char *lang, *e1 = NULL, *e2 = NULL, *e3 = NULL; - - g_return_val_if_fail (str != NULL, NULL); - - if (g_utf8_validate (str, len, NULL)) - return g_strdup (str); - - /* LANG may be a good encoding hint */ - g_get_charset ((const char **)(&e1)); - if ((lang = getenv ("LANG"))) { - char * dot; - - lang = g_ascii_strdown (lang, -1); - if ((dot = strchr (lang, '.'))) - *dot = '\0'; - - get_encodings_for_lang (lang, &e1, &e2, &e3); - g_free (lang); - } - - converted = g_convert (str, len, "UTF-8", e1, NULL, NULL, NULL); - if (!converted && e2) - converted = g_convert (str, len, "UTF-8", e2, NULL, NULL, NULL); - - if (!converted && e3) - converted = g_convert (str, len, "UTF-8", e3, NULL, NULL, NULL); - - if (!converted) { - converted = g_convert_with_fallback (str, len, "UTF-8", e1, - "?", NULL, NULL, NULL); - } - - return converted; -} - /* init, deinit for libnm_util */ static gboolean initialized = FALSE; @@ -303,8 +265,7 @@ nm_utils_deinit (void) /** * nm_utils_ssid_to_utf8: - * @ssid: pointer to a buffer containing the SSID data - * @len: length of the SSID data in @ssid + * @ssid: a byte array containing the SSID data * * WiFi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID may * contain embedded NULLs and other unprintable characters. Often it is @@ -329,23 +290,46 @@ nm_utils_deinit (void) * Again, this function should be used for debugging and display purposes * _only_. * - * Returns: an allocated string containing a UTF-8 representation of the - * SSID, which must be freed by the caller using g_free(). Returns NULL - * on errors. + * Returns: (transfer full): an allocated string containing a UTF-8 + * representation of the SSID, which must be freed by the caller using g_free(). + * Returns NULL on errors. **/ char * -nm_utils_ssid_to_utf8 (const char *ssid, guint32 len) +nm_utils_ssid_to_utf8 (const GByteArray *ssid) { - char *converted = NULL, *buf; - gsize buflen = MIN (IW_ESSID_MAX_SIZE, (gsize) len); + char *converted = NULL; + char *lang, *e1 = NULL, *e2 = NULL, *e3 = NULL; g_return_val_if_fail (ssid != NULL, NULL); - /* New buffer to ensure NULL-termination of SSID */ - buf = g_malloc0 (IW_ESSID_MAX_SIZE + 1); - memcpy (buf, ssid, buflen); - converted = string_to_utf8 (buf, buflen); - g_free (buf); + if (g_utf8_validate ((const gchar *) ssid->data, ssid->len, NULL)) + return g_strndup ((const gchar *) ssid->data, ssid->len); + + /* LANG may be a good encoding hint */ + g_get_charset ((const char **)(&e1)); + if ((lang = getenv ("LANG"))) { + char * dot; + + lang = g_ascii_strdown (lang, -1); + if ((dot = strchr (lang, '.'))) + *dot = '\0'; + + get_encodings_for_lang (lang, &e1, &e2, &e3); + g_free (lang); + } + + converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e1, NULL, NULL, NULL); + if (!converted && e2) + converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e2, NULL, NULL, NULL); + + if (!converted && e3) + converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e3, NULL, NULL, NULL); + + if (!converted) { + converted = g_convert_with_fallback ((const gchar *) ssid->data, ssid->len, + "UTF-8", e1, "?", NULL, NULL, NULL); + } + return converted; } @@ -486,7 +470,7 @@ value_dup (gpointer key, gpointer val, gpointer user_data) * * Utility function to duplicate a hash table of GValues. * - * Returns: a newly allocated duplicated #GHashTable, caller must free the + * Returns: (transfer container) (element-type utf8 GObject.Value): a newly allocated duplicated #GHashTable, caller must free the * returned hash with g_hash_table_unref() or g_hash_table_destroy() **/ GHashTable * @@ -658,8 +642,8 @@ nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_val memset (buf, 0, sizeof (buf)); addr.s_addr = g_array_index (array, guint32, i++); if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - nm_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); g_string_append_printf (printable, "%u (%s)", addr.s_addr, buf); } g_string_append_c (printable, ']'); @@ -700,8 +684,8 @@ nm_utils_convert_ip4_addr_route_struct_array_to_string (const GValue *src_value, memset (buf, 0, sizeof (buf)); addr.s_addr = g_array_index (array, guint32, 0); if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - nm_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); if (is_addr) g_string_append_printf (printable, "ip = %s", buf); else @@ -718,8 +702,8 @@ nm_utils_convert_ip4_addr_route_struct_array_to_string (const GValue *src_value, memset (buf, 0, sizeof (buf)); addr.s_addr = g_array_index (array, guint32, 2); if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - nm_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); if (is_addr) g_string_append_printf (printable, "gw = %s", buf); else @@ -835,8 +819,8 @@ nm_utils_inet6_ntop (struct in6_addr *addr, char *buf) g_string_append_printf (ip6_str, "%02X", addr->s6_addr[0]); for (i = 1; i < 16; i++) g_string_append_printf (ip6_str, " %02X", addr->s6_addr[i]); - nm_warning ("%s: error converting IP6 address %s", - __func__, ip6_str->str); + g_warning ("%s: error converting IP6 address %s", + __func__, ip6_str->str); g_string_free (ip6_str, TRUE); return FALSE; } @@ -1358,7 +1342,7 @@ nm_utils_security_valid (NMUtilsSecurityType type, * this serialization is not guaranteed to be stable and the #GArray may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP4Address objects + * Returns: (transfer full) (element-type NetworkManager.IP4Address): a newly allocated #GSList of #NMIP4Address objects **/ GSList * nm_utils_ip4_addresses_from_gvalue (const GValue *value) @@ -1373,7 +1357,7 @@ nm_utils_ip4_addresses_from_gvalue (const GValue *value) NMIP4Address *addr; if (array->len < 3) { - nm_warning ("Ignoring invalid IP4 address"); + g_warning ("Ignoring invalid IP4 address"); continue; } @@ -1440,7 +1424,7 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) * format of this serialization is not guaranteed to be stable and may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP4Route objects + * Returns: (transfer full) (element-type NetworkManager.IP4Route): a newly allocated #GSList of #NMIP4Route objects **/ GSList * nm_utils_ip4_routes_from_gvalue (const GValue *value) @@ -1455,7 +1439,7 @@ nm_utils_ip4_routes_from_gvalue (const GValue *value) NMIP4Route *route; if (array->len < 4) { - nm_warning ("Ignoring invalid IP4 route"); + g_warning ("Ignoring invalid IP4 route"); continue; } @@ -1603,7 +1587,7 @@ nm_utils_ip4_get_default_prefix (guint32 ip) * this serialization is not guaranteed to be stable and the #GValueArray may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP6Address objects + * Returns: (transfer full) (element-type NetworkManager.IP6Address): a newly allocated #GSList of #NMIP6Address objects **/ GSList * nm_utils_ip6_addresses_from_gvalue (const GValue *value) @@ -1623,27 +1607,27 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) guint32 prefix; if (elements->n_values < 2 || elements->n_values > 3) { - nm_warning ("%s: ignoring invalid IP6 address structure", __func__); + g_warning ("%s: ignoring invalid IP6 address structure", __func__); continue; } if ( (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY) || (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) { - nm_warning ("%s: ignoring invalid IP6 address structure", __func__); + g_warning ("%s: ignoring invalid IP6 address structure", __func__); continue; } /* Check optional 3rd element (gateway) */ if ( elements->n_values == 3 && (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) { - nm_warning ("%s: ignoring invalid IP6 address structure", __func__); + g_warning ("%s: ignoring invalid IP6 address structure", __func__); continue; } tmp = g_value_array_get_nth (elements, 0); ba_addr = g_value_get_boxed (tmp); if (ba_addr->len != 16) { - nm_warning ("%s: ignoring invalid IP6 address of length %d", + g_warning ("%s: ignoring invalid IP6 address of length %d", __func__, ba_addr->len); continue; } @@ -1651,7 +1635,7 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) tmp = g_value_array_get_nth (elements, 1); prefix = g_value_get_uint (tmp); if (prefix > 128) { - nm_warning ("%s: ignoring invalid IP6 prefix %d", + g_warning ("%s: ignoring invalid IP6 prefix %d", __func__, prefix); continue; } @@ -1660,7 +1644,7 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) tmp = g_value_array_get_nth (elements, 2); ba_gw = g_value_get_boxed (tmp); if (ba_gw->len != 16) { - nm_warning ("%s: ignoring invalid IP6 gateway address of length %d", + g_warning ("%s: ignoring invalid IP6 gateway address of length %d", __func__, ba_gw->len); continue; } @@ -1746,7 +1730,7 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) * into a GSList of #NMIP6Route objects. The specific format of this serialization * is not guaranteed to be stable and may be extended in the future. * - * Returns: a newly allocated #GSList of #NMIP6Route objects + * Returns: (transfer full) (element-type NetworkManager.IP6Route): a newly allocated #GSList of #NMIP6Route objects **/ GSList * nm_utils_ip6_routes_from_gvalue (const GValue *value) @@ -1767,13 +1751,13 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) || (G_VALUE_TYPE (g_value_array_get_nth (route_values, 1)) != G_TYPE_UINT) || (G_VALUE_TYPE (g_value_array_get_nth (route_values, 2)) != DBUS_TYPE_G_UCHAR_ARRAY) || (G_VALUE_TYPE (g_value_array_get_nth (route_values, 3)) != G_TYPE_UINT)) { - nm_warning ("Ignoring invalid IP6 route"); + g_warning ("Ignoring invalid IP6 route"); continue; } dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); if (dest->len != 16) { - nm_warning ("%s: ignoring invalid IP6 dest address of length %d", + g_warning ("%s: ignoring invalid IP6 dest address of length %d", __func__, dest->len); continue; } @@ -1782,7 +1766,7 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); if (next_hop->len != 16) { - nm_warning ("%s: ignoring invalid IP6 next_hop address of length %d", + g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", __func__, next_hop->len); continue; } @@ -1862,6 +1846,18 @@ nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value) g_value_take_boxed (value, routes); } +/* FIXME: the Posix namespace does not exist, and thus neither does + the in6_addr struct. Marking (skip) for now */ +/** + * nm_utils_ip6_dns_from_gvalue: (skip): + * @value: a #GValue + * + * Converts a #GValue containing a #GPtrArray of IP6 DNS, represented as + * #GByteArray<!-- -->s into a #GSList of #in6_addr<!-- -->s. + * + * Returns: (transfer full) (element-type Posix.in6_addr): a #GSList of IP6 + * addresses. + */ GSList * nm_utils_ip6_dns_from_gvalue (const GValue *value) { @@ -1875,8 +1871,8 @@ nm_utils_ip6_dns_from_gvalue (const GValue *value) struct in6_addr *addr; if (bytearray->len != 16) { - nm_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, bytearray->len); + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, bytearray->len); continue; } @@ -1888,6 +1884,18 @@ nm_utils_ip6_dns_from_gvalue (const GValue *value) return g_slist_reverse (list); } +/** + * nm_utils_ip6_dns_to_gvalue: (skip): + * @list: a list of #NMIP6Route objects + * @value: a pointer to a #GValue into which to place the converted DNS server + * addresses, which should be unset by the caller (when no longer needed) with + * g_value_unset(). + * + * Utility function to convert a #GSList of 'struct in6_addr' structs into a + * GPtrArray of GByteArrays representing each server's IPv6 addresses in + * network byte order. The specific format of this serialization is not + * guaranteed to be stable and may be extended in the future. + */ void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value) { @@ -1943,9 +1951,9 @@ nm_utils_uuid_generate_from_string (const char *s) char *buf = NULL; if (!nm_utils_init (&error)) { - nm_warning ("error initializing crypto: (%d) %s", - error ? error->code : 0, - error ? error->message : "unknown"); + g_warning ("error initializing crypto: (%d) %s", + error ? error->code : 0, + error ? error->message : "unknown"); if (error) g_error_free (error); return NULL; @@ -1953,9 +1961,9 @@ nm_utils_uuid_generate_from_string (const char *s) uuid = g_malloc0 (sizeof (*uuid)); if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid), &error)) { - nm_warning ("error generating UUID: (%d) %s", - error ? error->code : 0, - error ? error->message : "unknown"); + g_warning ("error generating UUID: (%d) %s", + error ? error->code : 0, + error ? error->message : "unknown"); if (error) g_error_free (error); goto out; @@ -2045,8 +2053,8 @@ utils_bin2hexstr (const char *bytes, int len, int final_len) /** * nm_utils_rsa_key_encrypt: * @data: RSA private key data to be encrypted - * @in_password: existing password to use, if any - * @out_password: if @in_password was NULL, a random password will be generated + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was NULL, a random password will be generated * and returned in this argument * @error: detailed error information on return, if an error occurred * @@ -2054,7 +2062,7 @@ utils_bin2hexstr (const char *bytes, int len, int final_len) * a password if no password was given) and converts the data to PEM format * suitable for writing to a file. * - * Returns: on success, PEM-formatted data suitable for writing to a PEM-formatted + * Returns: (transfer full): on success, PEM-formatted data suitable for writing to a PEM-formatted * certificate/private key file. **/ GByteArray * diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index 6be91793..c3eb29bc 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -20,7 +20,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2010 Red Hat, Inc. + * (C) Copyright 2005 - 2011 Red Hat, Inc. */ #ifndef NM_UTILS_H @@ -33,138 +33,21 @@ G_BEGIN_DECLS -/*********************************************************/ -/* The API defined here is _NOT_ guaranteed in any way!! */ -/*********************************************************/ - -/** - * nm_print_backtrace: - * - * Prints a backtrace of the calling process to the logging location. - */ -#define nm_print_backtrace() \ -G_STMT_START \ -{ \ - void *_call_stack[512]; \ - int _call_stack_size; \ - char **_symbols; \ - _call_stack_size = backtrace (_call_stack, \ - G_N_ELEMENTS (_call_stack)); \ - _symbols = backtrace_symbols (_call_stack, _call_stack_size); \ - if (_symbols != NULL) \ - { \ - int _i; \ - _i = 0; \ - g_critical ("traceback:\n"); \ - while (_i < _call_stack_size) \ - { \ - g_critical ("\t%s\n", _symbols[_i]); \ - _i++; \ - } \ - free (_symbols); \ - } \ -} \ -G_STMT_END - -/** - * nm_get_timestamp: - * @timestamp: location in which to place the current timestamp - * - * For debugging only. - */ -#define nm_get_timestamp(timestamp) \ -G_STMT_START \ -{ \ - GTimeVal _tv; \ - g_get_current_time (&_tv); \ - *timestamp = (_tv.tv_sec * (1.0 * G_USEC_PER_SEC) + \ - _tv.tv_usec) / G_USEC_PER_SEC; \ -} \ -G_STMT_END - -#define nm_info(fmt, args...) \ -G_STMT_START \ -{ \ - g_message ("<info> " fmt "\n", ##args); \ -} G_STMT_END - -#define nm_info_str(fmt_str, args...) \ -G_STMT_START \ -{ \ - g_message ("<info> %s\n", fmt_str, ##args); \ -} G_STMT_END - -#define nm_debug(fmt, args...) \ -G_STMT_START \ -{ \ - gdouble _timestamp; \ - nm_get_timestamp (&_timestamp); \ - g_debug ("<debug> [%f] %s(): " fmt "\n", _timestamp, \ - G_STRFUNC, ##args); \ -} G_STMT_END - -#define nm_debug_str(fmt_str, args...) \ -G_STMT_START \ -{ \ - gdouble _timestamp; \ - nm_get_timestamp (&_timestamp); \ - g_debug ("<debug> [%f] %s(): %s\n", _timestamp, \ - G_STRFUNC, fmt_str, ##args); \ -} G_STMT_END - -#define nm_warning(fmt, args...) \ -G_STMT_START \ -{ \ - g_warning ("<WARN> %s(): " fmt "\n", \ - G_STRFUNC, ##args); \ -} G_STMT_END - -#define nm_warning_str(fmt_str, args...) \ -G_STMT_START \ -{ \ - g_warning ("<WARN> %s(): %s\n", \ - G_STRFUNC, fmt_str, ##args); \ -} G_STMT_END - -#define nm_error(fmt, args...) \ -G_STMT_START \ -{ \ - gdouble _timestamp; \ - nm_get_timestamp (&_timestamp); \ - g_critical ("<ERROR>\t[%f] %s (): " fmt "\n", _timestamp, \ - G_STRFUNC, ##args); \ - nm_print_backtrace (); \ - G_BREAKPOINT (); \ -} G_STMT_END - -#define nm_error_str(fmt_str, args...) \ -G_STMT_START \ -{ \ - gdouble _timestamp; \ - nm_get_timestamp (&_timestamp); \ - g_critical ("<ERROR>\t[%f] %s (): %s\n", _timestamp, \ - G_STRFUNC, fmt_str, ##args); \ - nm_print_backtrace (); \ - G_BREAKPOINT (); \ -} G_STMT_END - /* init, deinit nm_utils */ gboolean nm_utils_init (GError **error); void nm_utils_deinit (void); /* SSID helpers */ -gboolean nm_utils_is_empty_ssid (const guint8 * ssid, int len); -const char *nm_utils_escape_ssid (const guint8 *ssid, guint32 len); -gboolean nm_utils_same_ssid (const GByteArray * ssid1, - const GByteArray * ssid2, - gboolean ignore_trailing_null); - -char *nm_utils_ssid_to_utf8 (const char *ssid, guint32 len); +gboolean nm_utils_is_empty_ssid (const guint8 *ssid, int len); +const char *nm_utils_escape_ssid (const guint8 *ssid, guint32 len); +gboolean nm_utils_same_ssid (const GByteArray *ssid1, + const GByteArray *ssid2, + gboolean ignore_trailing_null); +char * nm_utils_ssid_to_utf8 (const GByteArray *ssid); GHashTable *nm_utils_gvalue_hash_dup (GHashTable *hash); -void nm_utils_slist_free (GSList *list, - GDestroyNotify elem_destroy_fn); +void nm_utils_slist_free (GSList *list, GDestroyNotify elem_destroy_fn); typedef enum { NMU_SEC_INVALID = 0, diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am index a0b4779c..daf4d688 100644 --- a/libnm-util/tests/Makefile.am +++ b/libnm-util/tests/Makefile.am @@ -79,61 +79,52 @@ check-local: test-settings-defaults test-crypto test-secrets $(abs_builddir)/test-general # Private key and CA certificate in the same file (PEM) - $(abs_builddir)/test-setting-8021x \ - $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ - "test" \ - $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der + $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test" # Private key by itself (PEM) - $(abs_builddir)/test-setting-8021x \ - $(top_srcdir)/libnm-util/tests/certs/test-key-only.pem \ - "test" \ - $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der + $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-key-only.pem "test" # Private key and CA certificate in the same file (pkcs12) - $(abs_builddir)/test-setting-8021x \ - $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ - "test" + $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-cert.p12 "test" # Normal CA certificate - $(abs_builddir)/test-crypto --cert \ - $(top_srcdir)/libnm-util/tests/certs/test_ca_cert.pem + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.pem # Another CA certificate - $(abs_builddir)/test-crypto --cert \ - $(top_srcdir)/libnm-util/tests/certs/test2_ca_cert.pem + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_ca_cert.pem + +# Normal CA certificate (DER format) + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.der # CA certificate without an ending newline - $(abs_builddir)/test-crypto --cert \ - $(top_srcdir)/libnm-util/tests/certs/ca-no-ending-newline.pem + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/ca-no-ending-newline.pem # Combined user cert and private key - $(abs_builddir)/test-crypto --cert \ - $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_key_and_cert.pem # Another combined user cert and private key - $(abs_builddir)/test-crypto --cert \ - $(top_srcdir)/libnm-util/tests/certs/test2_key_and_cert.pem + $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_key_and_cert.pem # Private key with 8 bytes of tail padding $(abs_builddir)/test-crypto --key \ - $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ - "test" + $(srcdir)/certs/test_key_and_cert.pem \ + "test" \ + $(srcdir)/certs/test-key-only-decrypted.der + +# Private key only (not combined with a cert) + $(abs_builddir)/test-crypto --key \ + $(srcdir)/certs/test-key-only.pem \ + "test" \ + $(srcdir)/certs/test-key-only-decrypted.der # Private key with 6 bytes of tail padding - $(abs_builddir)/test-crypto --key \ - $(top_srcdir)/libnm-util/tests/certs/test2_key_and_cert.pem \ - "12345testing" + $(abs_builddir)/test-crypto --key $(srcdir)/certs/test2_key_and_cert.pem "12345testing" # PKCS#12 file - $(abs_builddir)/test-crypto --p12 \ - $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ - "test" + $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test-cert.p12 "test" # Another PKCS#12 file - $(abs_builddir)/test-crypto --p12 \ - $(top_srcdir)/libnm-util/tests/certs/test2-cert.p12 \ - "12345testing" + $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test2-cert.p12 "12345testing" endif diff --git a/libnm-util/tests/Makefile.in b/libnm-util/tests/Makefile.in index ab69399a..9e65094c 100644 --- a/libnm-util/tests/Makefile.in +++ b/libnm-util/tests/Makefile.in @@ -41,11 +41,16 @@ subdir = libnm-util/tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -83,7 +88,7 @@ test_settings_defaults_DEPENDENCIES = \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -156,7 +161,6 @@ am__relativize = \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ -ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -165,13 +169,15 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ @@ -183,6 +189,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -191,6 +198,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GIO_CFLAGS = @GIO_CFLAGS@ GIO_LIBS = @GIO_LIBS@ @@ -199,8 +207,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ -GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ @@ -215,13 +223,23 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -229,6 +247,8 @@ LIBDL = @LIBDL@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ LIBM = @LIBM@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ @@ -237,13 +257,15 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ -MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -269,13 +291,12 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POFILES = @POFILES@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ RESOLVCONF_PATH = @RESOLVCONF_PATH@ SED = @SED@ @@ -289,11 +310,15 @@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -911,61 +936,52 @@ uninstall-am: @WITH_TESTS_TRUE@ $(abs_builddir)/test-general # Private key and CA certificate in the same file (PEM) -@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ -@WITH_TESTS_TRUE@ "test" \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der +@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test" # Private key by itself (PEM) -@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test-key-only.pem \ -@WITH_TESTS_TRUE@ "test" \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der +@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-key-only.pem "test" # Private key and CA certificate in the same file (pkcs12) -@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ -@WITH_TESTS_TRUE@ "test" +@WITH_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-cert.p12 "test" # Normal CA certificate -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test_ca_cert.pem +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.pem # Another CA certificate -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test2_ca_cert.pem +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_ca_cert.pem + +# Normal CA certificate (DER format) +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.der # CA certificate without an ending newline -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/ca-no-ending-newline.pem +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/ca-no-ending-newline.pem # Combined user cert and private key -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_key_and_cert.pem # Another combined user cert and private key -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test2_key_and_cert.pem +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_key_and_cert.pem # Private key with 8 bytes of tail padding @WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --key \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ -@WITH_TESTS_TRUE@ "test" +@WITH_TESTS_TRUE@ $(srcdir)/certs/test_key_and_cert.pem \ +@WITH_TESTS_TRUE@ "test" \ +@WITH_TESTS_TRUE@ $(srcdir)/certs/test-key-only-decrypted.der + +# Private key only (not combined with a cert) +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --key \ +@WITH_TESTS_TRUE@ $(srcdir)/certs/test-key-only.pem \ +@WITH_TESTS_TRUE@ "test" \ +@WITH_TESTS_TRUE@ $(srcdir)/certs/test-key-only-decrypted.der # Private key with 6 bytes of tail padding -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --key \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test2_key_and_cert.pem \ -@WITH_TESTS_TRUE@ "12345testing" +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --key $(srcdir)/certs/test2_key_and_cert.pem "12345testing" # PKCS#12 file -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ -@WITH_TESTS_TRUE@ "test" +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test-cert.p12 "test" # Another PKCS#12 file -@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 \ -@WITH_TESTS_TRUE@ $(top_srcdir)/libnm-util/tests/certs/test2-cert.p12 \ -@WITH_TESTS_TRUE@ "12345testing" +@WITH_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test2-cert.p12 "12345testing" # 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. diff --git a/libnm-util/tests/certs/Makefile.am b/libnm-util/tests/certs/Makefile.am index 4cd8a24b..02d5a5f5 100644 --- a/libnm-util/tests/certs/Makefile.am +++ b/libnm-util/tests/certs/Makefile.am @@ -9,6 +9,7 @@ EXTRA_DIST = \ test_ca_cert.pem \ + test_ca_cert.der \ test_key_and_cert.pem \ test-cert.p12 \ test2_ca_cert.pem \ diff --git a/libnm-util/tests/certs/Makefile.in b/libnm-util/tests/certs/Makefile.in index 0821f71d..873218e8 100644 --- a/libnm-util/tests/certs/Makefile.in +++ b/libnm-util/tests/certs/Makefile.in @@ -46,11 +46,16 @@ subdir = libnm-util/tests/certs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -67,7 +72,6 @@ SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ -ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -76,13 +80,15 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ @@ -94,6 +100,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -102,6 +109,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GIO_CFLAGS = @GIO_CFLAGS@ GIO_LIBS = @GIO_LIBS@ @@ -110,8 +118,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ -GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ @@ -126,13 +134,23 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -140,6 +158,8 @@ LIBDL = @LIBDL@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ LIBM = @LIBM@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ @@ -148,13 +168,15 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ -MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -180,13 +202,12 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POFILES = @POFILES@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ RESOLVCONF_PATH = @RESOLVCONF_PATH@ SED = @SED@ @@ -200,11 +221,15 @@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -254,6 +279,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ test_ca_cert.pem \ + test_ca_cert.der \ test_key_and_cert.pem \ test-cert.p12 \ test2_ca_cert.pem \ diff --git a/libnm-util/tests/certs/test_ca_cert.der b/libnm-util/tests/certs/test_ca_cert.der new file mode 100644 index 00000000..e844f65b --- /dev/null +++ b/libnm-util/tests/certs/test_ca_cert.der Binary files differdiff --git a/libnm-util/tests/test-crypto.c b/libnm-util/tests/test-crypto.c index a5466bc8..6cfb6ac2 100644 --- a/libnm-util/tests/test-crypto.c +++ b/libnm-util/tests/test-crypto.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. */ #include <glib.h> @@ -113,28 +113,46 @@ test_load_cert (const char *path, const char *desc) g_byte_array_free (array, TRUE); } +static GByteArray * +file_to_byte_array (const char *filename) +{ + char *contents; + GByteArray *array = NULL; + gsize length = 0; + + if (g_file_get_contents (filename, &contents, &length, NULL)) { + array = g_byte_array_sized_new (length); + if (array) { + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + } + g_free (contents); + } + return array; +} + static void test_load_private_key (const char *path, const char *password, + const char *decrypted_path, gboolean expect_fail, const char *desc) { NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - GByteArray *array; + GByteArray *array, *decrypted; GError *error = NULL; - array = crypto_get_private_key (path, password, &key_type, &format, &error); + array = crypto_decrypt_private_key (path, password, &key_type, &error); if (expect_fail) { ASSERT (array == NULL, desc, "unexpected success reading private key file '%s' with " "invalid password", path); - ASSERT (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, desc, - "unexpected success determining private key file '%s' " - "format with invalid password (expected %d, got %d)", - path, NM_CRYPTO_FILE_FORMAT_UNKNOWN, format); + ASSERT (key_type != NM_CRYPTO_KEY_TYPE_UNKNOWN, desc, + "unexpected failure determining private key file '%s' " + "type with invalid password (expected %d, got %d)", + path, NM_CRYPTO_KEY_TYPE_UNKNOWN, key_type); return; } @@ -142,13 +160,28 @@ test_load_private_key (const char *path, "couldn't read private key file '%s': %d %s", path, error->code, error->message); - ASSERT (format == NM_CRYPTO_FILE_FORMAT_RAW_KEY, desc, - "%s: unexpected private key file format (expected %d, got %d)", - path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); - ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc, "%s: unexpected private key type (expected %d, got %d)", - path, NM_CRYPTO_KEY_TYPE_RSA, format); + path, NM_CRYPTO_KEY_TYPE_RSA, key_type); + + if (decrypted_path) { + /* Compare the crypto decrypted key against a known-good decryption */ + decrypted = file_to_byte_array (decrypted_path); + ASSERT (decrypted != NULL, desc, + "couldn't read decrypted private key file '%s': %d %s", + decrypted_path, error->code, error->message); + + ASSERT (decrypted->len > 0, desc, "decrypted key file invalid (size 0)"); + + ASSERT (decrypted->len == array->len, + desc, "decrypted key file (%d) and decrypted key data (%d) lengths don't match", + decrypted->len, array->len); + + ASSERT (memcmp (decrypted->data, array->data, array->len) == 0, + desc, "decrypted key file and decrypted key data don't match"); + + g_byte_array_free (decrypted, TRUE); + } g_byte_array_free (array, TRUE); } @@ -159,46 +192,35 @@ test_load_pkcs12 (const char *path, gboolean expect_fail, const char *desc) { - NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - GByteArray *array; GError *error = NULL; - array = crypto_get_private_key (path, password, &key_type, &format, &error); + format = crypto_verify_private_key (path, password, &error); if (expect_fail) { - ASSERT (array == NULL, desc, + ASSERT (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, desc, "unexpected success reading PKCS#12 private key file " "'%s' with invalid password", path); - - /* PKCS#12 file format can be determined even if the password - * is wrong; check that. - */ - ASSERT (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, desc, - "unexpected success determining PKCS#12 private key " - "'%s' file format with invalid password (expected %d, " - "got %d)", - path, NM_CRYPTO_FILE_FORMAT_UNKNOWN, format); - ASSERT (key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, desc, - "unexpected success determining PKCS#12 private key " - "'%s' type with invalid password (expected %d, got %d)", - path, NM_CRYPTO_KEY_TYPE_UNKNOWN, key_type); - return; + } else { + ASSERT (format == NM_CRYPTO_FILE_FORMAT_PKCS12, desc, + "%s: unexpected PKCS#12 private key file format (expected %d, got " + "%d): %d %s", + path, NM_CRYPTO_FILE_FORMAT_PKCS12, format, error->code, error->message); } +} - ASSERT (array != NULL, desc, - "couldn't read PKCS#12 private key file '%s': %d %s", - path, error->code, error->message); +static void +test_load_pkcs12_no_password (const char *path, const char *desc) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GError *error = NULL; + /* We should still get a valid returned crypto file format */ + format = crypto_verify_private_key (path, NULL, &error); ASSERT (format == NM_CRYPTO_FILE_FORMAT_PKCS12, desc, - "%s: unexpected PKCS#12 private key file format (expected %d, got %d)", - path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); - - ASSERT (key_type == NM_CRYPTO_KEY_TYPE_ENCRYPTED, desc, - "%s: unexpected PKCS#12 private key type (expected %d, got %d)", - path, NM_CRYPTO_KEY_TYPE_ENCRYPTED, format); - - g_byte_array_free (array, TRUE); + "%s: unexpected PKCS#12 private key file format (expected %d, got " + "%d): %d %s", + path, NM_CRYPTO_FILE_FORMAT_PKCS12, format, error->code, error->message); } static void @@ -211,10 +233,9 @@ test_is_pkcs12 (const char *path, gboolean expect_fail, const char *desc) ASSERT (is_pkcs12 == FALSE, desc, "unexpected success reading non-PKCS#12 file '%s'", path); - return; + } else { + ASSERT (is_pkcs12 == TRUE, desc, "couldn't read PKCS#12 file '%s'", path); } - - ASSERT (is_pkcs12 == TRUE, desc, "couldn't read PKCS#12 file '%s'", path); } static void @@ -223,23 +244,17 @@ test_encrypt_private_key (const char *path, const char *desc) { NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; GByteArray *array, *encrypted, *re_decrypted; GError *error = NULL; - array = crypto_get_private_key (path, password, &key_type, &format, &error); - + array = crypto_decrypt_private_key (path, password, &key_type, &error); ASSERT (array != NULL, desc, "couldn't read private key file '%s': %d %s", path, error->code, error->message); - ASSERT (format == NM_CRYPTO_FILE_FORMAT_RAW_KEY, desc, - "%s: unexpected private key file format (expected %d, got %d)", - path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); - ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc, "%s: unexpected private key type (expected %d, got %d)", - path, NM_CRYPTO_KEY_TYPE_RSA, format); + path, NM_CRYPTO_KEY_TYPE_RSA, key_type); /* Now re-encrypt the private key */ encrypted = nm_utils_rsa_key_encrypt (array, password, NULL, &error); @@ -249,20 +264,14 @@ test_encrypt_private_key (const char *path, /* Then re-decrypt the private key */ key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - re_decrypted = crypto_get_private_key_data (encrypted, password, &key_type, &format, &error); - + re_decrypted = crypto_decrypt_private_key_data (encrypted, password, &key_type, &error); ASSERT (re_decrypted != NULL, desc, "couldn't read private key file '%s': %d %s", path, error->code, error->message); - ASSERT (format == NM_CRYPTO_FILE_FORMAT_RAW_KEY, desc, - "%s: unexpected private key file format (expected %d, got %d)", - path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); - ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc, "%s: unexpected private key type (expected %d, got %d)", - path, NM_CRYPTO_KEY_TYPE_RSA, format); + path, NM_CRYPTO_KEY_TYPE_RSA, key_type); /* Compare the original decrypted key with the re-decrypted key */ ASSERT (array->len == re_decrypted->len, desc, @@ -292,17 +301,21 @@ int main (int argc, char **argv) if (!strcmp (argv[1], "--cert")) test_load_cert (argv[2], "cert"); else if (!strcmp (argv[1], "--key")) { - ASSERT (argc == 4, "test-crypto", - "wrong number of arguments (--key <key file> <password>)"); + const char *decrypted_path = (argc == 5) ? argv[4] : NULL; + + ASSERT (argc == 4 || argc == 5, "test-crypto", + "wrong number of arguments (--key <key file> <password> [<decrypted key file>])"); - test_load_private_key (argv[2], argv[3], FALSE, "private-key"); - test_load_private_key (argv[2], "blahblahblah", TRUE, "private-key-bad-password"); + test_is_pkcs12 (argv[2], TRUE, "not-pkcs12"); + test_load_private_key (argv[2], argv[3], decrypted_path, FALSE, "private-key"); + test_load_private_key (argv[2], "blahblahblah", NULL, TRUE, "private-key-bad-password"); + test_load_private_key (argv[2], NULL, NULL, TRUE, "private-key-no-password"); test_encrypt_private_key (argv[2], argv[3], "private-key-rencrypt"); - test_is_pkcs12 (argv[2], TRUE, "is-pkcs12-not-pkcs12"); } else if (!strcmp (argv[1], "--p12")) { test_is_pkcs12 (argv[2], FALSE, "is-pkcs12"); test_load_pkcs12 (argv[2], argv[3], FALSE, "pkcs12-private-key"); test_load_pkcs12 (argv[2], "blahblahblah", TRUE, "pkcs12-private-key-bad-password"); + test_load_pkcs12_no_password (argv[2], "pkcs12-private-key-no-password"); } else { ASSERT (argc > 2, "test-crypto", "unknown test type (not --cert, --key, or --p12)"); } diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index c7421faf..1ce80622 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. * */ @@ -29,10 +29,13 @@ #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-gsm.h" +#include "nm-setting-cdma.h" #include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" #include "nm-setting-ip6-config.h" #include "nm-setting-ip4-config.h" #include "nm-setting-pppoe.h" +#include "nm-setting-serial.h" #include "nm-dbus-glib-types.h" static void @@ -133,6 +136,65 @@ test_setting_vpn_items (void) g_object_unref (s_vpn); } +static void +test_setting_vpn_update_secrets (void) +{ + NMConnection *connection; + NMSettingVPN *s_vpn; + GHashTable *settings, *vpn, *secrets; + GValue val = { 0 }; + 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_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)); + + settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy); + vpn = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset); + g_hash_table_insert (settings, NM_SETTING_VPN_SETTING_NAME, vpn); + + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING); + g_value_take_boxed (&val, secrets); + g_hash_table_insert (vpn, NM_SETTING_VPN_SECRETS, &val); + + /* Add some secrets */ + g_hash_table_insert (secrets, (char *) key1, (char *) val1); + g_hash_table_insert (secrets, (char *) key2, (char *) val2); + + 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_object_unref (connection); +} + #define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) #define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS)) @@ -292,6 +354,319 @@ test_setting_gsm_apn_bad_chars (void) "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); } +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_WEP_KEY0, "aaaaaaaaaa", + NULL); + + return s_wsec; +} + +static void +test_setting_to_hash_all (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-all"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ALL); + + /* Make sure all keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + +static void +test_setting_to_hash_no_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-no-secrets"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_NO_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), + "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), + "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK) == NULL, + "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) == NULL, + "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + +static void +test_setting_to_hash_only_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-only-secrets"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ONLY_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT) == NULL, + "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME) == NULL, + "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), + "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), + "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + +static void +test_connection_to_hash_setting_name (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + connection = nm_connection_new (); + s_wsec = make_test_wsec_setting ("connection-to-hash-setting-name"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + /* Make sure the keys of the first level hash are setting names, not + * the GType name of the setting objects. + */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != NULL, + "connection-to-hash-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_hash_table_destroy (hash); + 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 }; + GSList *list = NULL; + const char *expected_perm = "user:" TEST_UNAME ":"; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "", NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #3"); + + /* Ensure a non-UTF-8 [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", buf, NULL); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #4"); + + /* Ensure a non-NULL [detail] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf"); + 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, &list, NULL); + ASSERT (list != NULL, + "setting-connection-permissions-helpers", "unexpected failure getting permissions list"); + ASSERT (g_slist_length (list) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions in list"); + ASSERT (strcmp (list->data, expected_perm) == 0, + "setting-connection-permissions-helpers", "unexpected permission property data"); + + /* 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; + GSList *list = NULL; + + 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); + + list = g_slist_append (list, str->str); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, list, NULL); + + g_string_free (str, TRUE); + g_slist_free (list); +} + +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 */ + add_permission_property (s_con, "foobar", "blah", -1, NULL); + 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 */ + add_permission_property (s_con, NULL, "blah", -1, NULL); + 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 */ + add_permission_property (s_con, "user", NULL, -1, NULL); + 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 */ + add_permission_property (s_con, "user", "", -1, NULL); + 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 */ + add_permission_property (s_con, "user", "ad:asdf", -1, NULL); + 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 */ + add_permission_property (s_con, "user", "adasdfaf:", -1, NULL); + 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 */ + add_permission_property (s_con, "user", buf, (int) sizeof (buf), NULL); + 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 */ + add_permission_property (s_con, "user", "dafasdf", -1, "asdf"); + 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 NMConnection * new_test_connection (void) { @@ -385,6 +760,7 @@ test_connection_diff_a_only (void) { NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_CONNECTION_AUTOCONNECT, 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 }, { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } } }, { NM_SETTING_WIRED_SETTING_NAME, { @@ -526,6 +902,221 @@ test_connection_diff_no_secrets (void) 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_IP4_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_IP6_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; + GByteArray *array; + const guint8 bdaddr[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + + /* Try a basic wired connection */ + connection = nm_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_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_connection_new (); + add_generic_settings (connection, NM_SETTING_WIRELESS_SETTING_NAME); + + setting = nm_setting_wireless_new (); + array = g_byte_array_new (); + g_byte_array_append (array, (const guint8 *) "1234567", 7); + g_object_set (setting, + NM_SETTING_WIRELESS_SSID, array, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_byte_array_free (array, TRUE); + 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_connection_new (); + add_generic_settings (connection, NM_SETTING_BLUETOOTH_SETTING_NAME); + + setting = nm_setting_bluetooth_new (); + array = g_byte_array_new (); + g_byte_array_append (array, bdaddr, sizeof (bdaddr)); + g_object_set (setting, + NM_SETTING_BLUETOOTH_BDADDR, array, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + g_byte_array_free (array, TRUE); + 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_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_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_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_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_CONNECTION_TYPE_INVALID); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* PPP setting */ + connection = nm_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_CONNECTION_TYPE_INVALID); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* Serial setting */ + connection = nm_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_CONNECTION_TYPE_INVALID); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP4 setting */ + connection = nm_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_CONNECTION_TYPE_INVALID); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP6 setting */ + connection = nm_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_CONNECTION_TYPE_INVALID); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -540,13 +1131,22 @@ int main (int argc, char **argv) /* The tests */ test_setting_vpn_items (); + test_setting_vpn_update_secrets (); test_setting_ip6_config_old_address_array (); test_setting_gsm_apn_spaces (); test_setting_gsm_apn_bad_chars (); + test_setting_to_hash_all (); + test_setting_to_hash_no_secrets (); + test_setting_to_hash_only_secrets (); + test_connection_to_hash_setting_name (); + test_setting_connection_permissions_helpers (); + test_setting_connection_permissions_property (); test_connection_diff_a_only (); test_connection_diff_same (); test_connection_diff_different (); test_connection_diff_no_secrets (); + test_connection_good_base_types (); + test_connection_bad_base_types (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); diff --git a/libnm-util/tests/test-secrets.c b/libnm-util/tests/test-secrets.c index da6f610d..6d46f99e 100644 --- a/libnm-util/tests/test-secrets.c +++ b/libnm-util/tests/test-secrets.c @@ -155,7 +155,6 @@ test_need_tls_secrets_path (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); ASSERT (connection != NULL, @@ -171,44 +170,12 @@ test_need_tls_secrets_path (void) "need-tls-secrets-path-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then 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", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-secrets-path-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-secrets-path-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY), - "need-tls-secrets-path-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_connection ("need-tls-secrets-path-key-password", NM_SETTING_802_1X_CK_SCHEME_PATH); - ASSERT (connection != NULL, - "need-tls-secrets-path-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-secrets-path-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); - - 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, @@ -231,7 +198,6 @@ test_need_tls_secrets_blob (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); ASSERT (connection != NULL, @@ -247,50 +213,24 @@ test_need_tls_secrets_blob (void) "need-tls-secrets-blob-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then 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", + "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", + "need-tls-secrets-blob-key-password", "unexpected setting secrets required"); ASSERT (hints != NULL, - "need-tls-secrets-blob-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY), - "need-tls-secrets-blob-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_connection ("need-tls-secrets-blob-key-password", NM_SETTING_802_1X_CK_SCHEME_BLOB); - ASSERT (connection != NULL, - "need-tls-secrets-blob-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-secrets-blob-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); - - /* Blobs are already decrypted and don't need a password */ - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name == NULL, - "need-tls-secrets-blob-key-password", - "unexpected secrets failure"); - ASSERT (hints == NULL, "need-tls-secrets-blob-key-password", - "hints should be NULL since no secrets were required"); + "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); } @@ -397,7 +337,6 @@ test_need_tls_phase2_secrets_path (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); @@ -414,45 +353,12 @@ test_need_tls_phase2_secrets_path (void) "need-tls-phase2-secrets-path-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then 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", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-phase2-secrets-path-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-phase2-secrets-path-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), - "need-tls-phase2-secrets-path-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key-password", - NM_SETTING_802_1X_CK_SCHEME_PATH); - ASSERT (connection != NULL, - "need-tls-phase2-secrets-path-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-phase2-secrets-path-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL); - - 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, @@ -475,7 +381,6 @@ test_need_tls_phase2_secrets_blob (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); @@ -492,53 +397,79 @@ test_need_tls_phase2_secrets_blob (void) "need-tls-phase2-secrets-blob-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then 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", + "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", + "need-tls-phase2-secrets-blob-key-password", "unexpected setting secrets required"); ASSERT (hints != NULL, - "need-tls-phase2-secrets-blob-key", + "need-tls-phase2-secrets-blob-key-password", "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), - "need-tls-phase2-secrets-blob-key", - "expected to require private key, but it wasn't"); + 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); +} - /*** Just clear the private key this time ***/ +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; + GByteArray *ssid; - connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key-password", - NM_SETTING_802_1X_CK_SCHEME_BLOB); - ASSERT (connection != NULL, - "need-tls-phase2-secrets-blob-key-password", - "error creating test connection"); + connection = nm_connection_new (); + g_assert (connection); - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-phase2-secrets-blob-key-password", - "error getting test 802.1x setting"); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL); + 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)); - /* Blobs are already decrypted and don't need a password */ - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name == NULL, - "need-tls-phase2-secrets-blob-key-password", - "unexpected secrets failure"); - ASSERT (hints == NULL, - "need-tls-phase2-secrets-blob-key-password", - "hints should be NULL since no secrets were required"); + /* Wireless setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); - g_object_unref (connection); + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + g_byte_array_free (ssid, TRUE); + 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 void @@ -572,77 +503,100 @@ uint_to_gvalue (guint32 i) } static void -test_update_secrets_wifi (void) +test_update_secrets_wifi_single_setting (void) { NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; - const char *wepkey = "11111111111111111111111111"; GHashTable *secrets; GError *error = NULL; - char *uuid; - GByteArray *ssid; gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; - connection = nm_connection_new (); - g_assert (connection); + connection = wifi_connection_new (); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - g_assert (s_con); + /* Build up the secrets hash */ + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); + g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); + g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); - 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)); + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error (error); + g_assert (success); - /* Wireless setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - g_assert (s_wifi); + /* Make sure the secret is now in the connection */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + g_assert (s_wsec); + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + g_assert_cmpstr (tmp, ==, wepkey); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NULL); - g_byte_array_free (ssid, TRUE); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + g_object_unref (connection); +} - /* Wifi security */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - g_assert (s_wsec); +static void +test_update_secrets_wifi_full_hash (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GHashTable *secrets, *all; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; - g_object_set (G_OBJECT (s_wsec), - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + connection = wifi_connection_new (); /* Build up the secrets hash */ + all = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy); secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); + g_hash_table_insert (all, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets); success = nm_connection_update_secrets (connection, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - secrets, + all, &error); - if (!success) { - /* Print the warning message before we assert success */ - g_assert (error); - g_warning ("Error updating connection secrets: %s", error->message); - g_clear_error (&error); - } + g_assert_no_error (error); g_assert (success); + + /* Make sure the secret is now in the connection */ + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + 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; + GHashTable *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + connection = wifi_connection_new (); + + /* Build up the secrets hash */ + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); + g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); + g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); + + success = nm_connection_update_secrets (connection, + "asdfasdfasdfasf", + secrets, + &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND); + g_assert (success == FALSE); + + g_object_unref (connection); +} int main (int argc, char **argv) { @@ -662,7 +616,9 @@ int main (int argc, char **argv) test_need_tls_phase2_secrets_path (); test_need_tls_phase2_secrets_blob (); - test_update_secrets_wifi (); + test_update_secrets_wifi_single_setting (); + test_update_secrets_wifi_full_hash (); + test_update_secrets_wifi_bad_setting_name (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); diff --git a/libnm-util/tests/test-setting-8021x.c b/libnm-util/tests/test-setting-8021x.c index 6202a142..6d1e3bd0 100644 --- a/libnm-util/tests/test-setting-8021x.c +++ b/libnm-util/tests/test-setting-8021x.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2009 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. * */ @@ -30,8 +30,8 @@ #include "nm-setting-8021x.h" static void -compare_decrypted (const char *test, - const char *decrypted_path, +compare_blob_data (const char *test, + const char *key_path, const GByteArray *key) { char *contents = NULL; @@ -39,32 +39,48 @@ compare_decrypted (const char *test, GError *error = NULL; gboolean success; - success = g_file_get_contents (decrypted_path, &contents, &len, &error); + success = g_file_get_contents (key_path, &contents, &len, &error); ASSERT (success == TRUE, - test, "failed to read decrypted key file: %s", error->message); + test, "failed to read blob key file: %s", error->message); - ASSERT (len > 0, test, "decrypted key file invalid (size 0)"); + ASSERT (len > 0, test, "blob key file invalid (size 0)"); ASSERT (len == key->len, - test, "decrypted key file (%d) and decrypted key data (%d) lengths don't match", + test, "blob key file (%d) and setting key data (%d) lengths don't match", len, key->len); ASSERT (memcmp (contents, key->data, len) == 0, - test, "decrypted key file and decrypted key data don't match"); + test, "blob key file and blob key data don't match"); g_free (contents); } +#define SCHEME_PATH "file://" + +static void +check_scheme_path (GByteArray *value, const char *path) +{ + guint8 *p = value->data; + + 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, - const char *decrypted_path, NMSetting8021xCKScheme scheme) { NMSetting8021x *s_8021x; gboolean success; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; GError *error = NULL; + GByteArray *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"); @@ -77,16 +93,48 @@ test_private_key_import (const char *path, &error); ASSERT (success == TRUE, "private-key-import", "error reading private key: %s", error->message); - - if ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB - && format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { - const GByteArray *key; - - ASSERT (decrypted_path != NULL, "private-key-import", "missing decrypted key file"); - - key = nm_setting_802_1x_get_private_key_blob (s_8021x); - ASSERT (key != NULL, "private-key-import", "missing private key blob"); - compare_decrypted ("private-key-import", decrypted_path, key); + 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 = (GByteArray *) 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_byte_array_free (tmp_key, TRUE); + } 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 (tmp_key->len == client_cert->len, + "private-key-import", "unexpected different private key and client cert lengths"); + ASSERT (memcmp (tmp_key->data, client_cert->data, tmp_key->len) == 0, + "private-key-import", "unexpected different private key and client cert data"); + + g_byte_array_free (tmp_key, TRUE); + g_byte_array_free (client_cert, TRUE); } g_object_unref (s_8021x); @@ -95,13 +143,15 @@ test_private_key_import (const char *path, static void test_phase2_private_key_import (const char *path, const char *password, - const char *decrypted_path, NMSetting8021xCKScheme scheme) { NMSetting8021x *s_8021x; gboolean success; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; GError *error = NULL; + GByteArray *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"); @@ -114,17 +164,242 @@ test_phase2_private_key_import (const char *path, &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 = (GByteArray *) 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 (tmp_key->len == client_cert->len, + "private-key-import", "unexpected different private key and client cert lengths"); + ASSERT (memcmp (tmp_key->data, client_cert->data, tmp_key->len) == 0, + "private-key-import", "unexpected different private key and client cert data"); + + g_byte_array_free (tmp_key, TRUE); + g_byte_array_free (client_cert, TRUE); + } - if ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB - && format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { - const GByteArray *key; + g_object_unref (s_8021x); +} - ASSERT (decrypted_path != NULL, "phase2-private-key-import", "missing decrypted key file"); +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; - key = nm_setting_802_1x_get_phase2_private_key_blob (s_8021x); - ASSERT (key != NULL, "phase2-private-key-import", "missing private key blob"); - compare_decrypted ("phase2-private-key-import", decrypted_path, key); - } + 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); } @@ -134,13 +409,9 @@ int main (int argc, char **argv) GError *error = NULL; DBusGConnection *bus; char *base; - const char *decrypted = NULL; if (argc < 3) - FAIL ("init", "need at least two arguments: <path> <password> [decrypted private key]"); - - if (argc == 4) - decrypted = argv[3]; + FAIL ("init", "need at least two arguments: <path> <password>"); g_type_init (); bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); @@ -148,12 +419,21 @@ int main (int argc, char **argv) if (!nm_utils_init (&error)) FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); - /* The tests */ - test_private_key_import (argv[1], argv[2], NULL, NM_SETTING_802_1X_CK_SCHEME_PATH); - test_phase2_private_key_import (argv[1], argv[2], NULL, NM_SETTING_802_1X_CK_SCHEME_PATH); + /* Test phase1 and phase2 path scheme */ + test_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Test phase1 and phase2 blob scheme */ + test_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Test that using a wrong password does not change existing data */ + test_wrong_password_keeps_data (argv[1], argv[2]); + test_wrong_phase2_password_keeps_data (argv[1], argv[2]); - test_private_key_import (argv[1], argv[2], decrypted, NM_SETTING_802_1X_CK_SCHEME_BLOB); - test_phase2_private_key_import (argv[1], argv[2], decrypted, NM_SETTING_802_1X_CK_SCHEME_BLOB); + /* Test clearing the private key */ + test_clear_private_key (argv[1], argv[2]); + test_clear_phase2_private_key (argv[1], argv[2]); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); |