diff options
Diffstat (limited to 'src/supplicant-manager')
| -rw-r--r-- | src/supplicant-manager/Makefile.am | 35 | ||||
| -rw-r--r-- | src/supplicant-manager/Makefile.in | 760 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-config.c | 1014 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-config.h | 84 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-interface.c | 1429 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-interface.h | 145 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-manager.c | 343 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-manager.h | 88 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-settings-verify.c | 238 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-settings-verify.h | 37 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-types.h | 28 | ||||
| -rw-r--r-- | src/supplicant-manager/tests/Makefile.am | 27 | ||||
| -rw-r--r-- | src/supplicant-manager/tests/Makefile.in | 579 | ||||
| -rw-r--r-- | src/supplicant-manager/tests/test-supplicant-config.c | 518 |
14 files changed, 5325 insertions, 0 deletions
diff --git a/src/supplicant-manager/Makefile.am b/src/supplicant-manager/Makefile.am new file mode 100644 index 00000000..e59ae843 --- /dev/null +++ b/src/supplicant-manager/Makefile.am @@ -0,0 +1,35 @@ +SUBDIRS=. tests + +INCLUDES = \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/marshallers \ + -I${top_srcdir}/src/named-manager + +noinst_LTLIBRARIES = libsupplicant-manager.la + +libsupplicant_manager_la_SOURCES = \ + nm-supplicant-types.h \ + nm-supplicant-manager.h \ + nm-supplicant-manager.c \ + nm-supplicant-config.h \ + nm-supplicant-config.c \ + nm-supplicant-interface.c \ + nm-supplicant-interface.h \ + nm-supplicant-settings-verify.h \ + nm-supplicant-settings-verify.c + +libsupplicant_manager_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + -DNM_PKGDATADIR=\"$(pkgdatadir)\" \ + -DNM_LOCALSTATEDIR=\"$(localstatedir)\" + +libsupplicant_manager_la_LIBADD = \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in new file mode 100644 index 00000000..9d326ba7 --- /dev/null +++ b/src/supplicant-manager/Makefile.in @@ -0,0 +1,760 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/supplicant-manager +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)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsupplicant_manager_la_DEPENDENCIES = \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libsupplicant_manager_la_OBJECTS = \ + libsupplicant_manager_la-nm-supplicant-manager.lo \ + libsupplicant_manager_la-nm-supplicant-config.lo \ + libsupplicant_manager_la-nm-supplicant-interface.lo \ + libsupplicant_manager_la-nm-supplicant-settings-verify.lo +libsupplicant_manager_la_OBJECTS = \ + $(am_libsupplicant_manager_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libsupplicant_manager_la_SOURCES) +DIST_SOURCES = $(libsupplicant_manager_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +IPTABLES_PATH = @IPTABLES_PATH@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +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@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . tests +INCLUDES = \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/marshallers \ + -I${top_srcdir}/src/named-manager + +noinst_LTLIBRARIES = libsupplicant-manager.la +libsupplicant_manager_la_SOURCES = \ + nm-supplicant-types.h \ + nm-supplicant-manager.h \ + nm-supplicant-manager.c \ + nm-supplicant-config.h \ + nm-supplicant-config.c \ + nm-supplicant-interface.c \ + nm-supplicant-interface.h \ + nm-supplicant-settings-verify.h \ + nm-supplicant-settings-verify.c + +libsupplicant_manager_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + -DNM_PKGDATADIR=\"$(pkgdatadir)\" \ + -DNM_LOCALSTATEDIR=\"$(localstatedir)\" + +libsupplicant_manager_la_LIBADD = \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/supplicant-manager/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/supplicant-manager/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsupplicant-manager.la: $(libsupplicant_manager_la_OBJECTS) $(libsupplicant_manager_la_DEPENDENCIES) + $(LINK) $(libsupplicant_manager_la_OBJECTS) $(libsupplicant_manager_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsupplicant_manager_la-nm-supplicant-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsupplicant_manager_la-nm-supplicant-interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsupplicant_manager_la-nm-supplicant-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsupplicant_manager_la-nm-supplicant-settings-verify.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libsupplicant_manager_la-nm-supplicant-manager.lo: nm-supplicant-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsupplicant_manager_la-nm-supplicant-manager.lo -MD -MP -MF $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-manager.Tpo -c -o libsupplicant_manager_la-nm-supplicant-manager.lo `test -f 'nm-supplicant-manager.c' || echo '$(srcdir)/'`nm-supplicant-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-manager.Tpo $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-supplicant-manager.c' object='libsupplicant_manager_la-nm-supplicant-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsupplicant_manager_la-nm-supplicant-manager.lo `test -f 'nm-supplicant-manager.c' || echo '$(srcdir)/'`nm-supplicant-manager.c + +libsupplicant_manager_la-nm-supplicant-config.lo: nm-supplicant-config.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsupplicant_manager_la-nm-supplicant-config.lo -MD -MP -MF $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-config.Tpo -c -o libsupplicant_manager_la-nm-supplicant-config.lo `test -f 'nm-supplicant-config.c' || echo '$(srcdir)/'`nm-supplicant-config.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-config.Tpo $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-supplicant-config.c' object='libsupplicant_manager_la-nm-supplicant-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsupplicant_manager_la-nm-supplicant-config.lo `test -f 'nm-supplicant-config.c' || echo '$(srcdir)/'`nm-supplicant-config.c + +libsupplicant_manager_la-nm-supplicant-interface.lo: nm-supplicant-interface.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsupplicant_manager_la-nm-supplicant-interface.lo -MD -MP -MF $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-interface.Tpo -c -o libsupplicant_manager_la-nm-supplicant-interface.lo `test -f 'nm-supplicant-interface.c' || echo '$(srcdir)/'`nm-supplicant-interface.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-interface.Tpo $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-supplicant-interface.c' object='libsupplicant_manager_la-nm-supplicant-interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsupplicant_manager_la-nm-supplicant-interface.lo `test -f 'nm-supplicant-interface.c' || echo '$(srcdir)/'`nm-supplicant-interface.c + +libsupplicant_manager_la-nm-supplicant-settings-verify.lo: nm-supplicant-settings-verify.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsupplicant_manager_la-nm-supplicant-settings-verify.lo -MD -MP -MF $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-settings-verify.Tpo -c -o libsupplicant_manager_la-nm-supplicant-settings-verify.lo `test -f 'nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`nm-supplicant-settings-verify.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-settings-verify.Tpo $(DEPDIR)/libsupplicant_manager_la-nm-supplicant-settings-verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-supplicant-settings-verify.c' object='libsupplicant_manager_la-nm-supplicant-settings-verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsupplicant_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsupplicant_manager_la-nm-supplicant-settings-verify.lo `test -f 'nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`nm-supplicant-settings-verify.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c new file mode 100644 index 00000000..b516de52 --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -0,0 +1,1014 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdlib.h> +#include <glib.h> +#include <netinet/ether.h> +#include <dbus/dbus-glib.h> + +#include "nm-supplicant-config.h" +#include "nm-supplicant-settings-verify.h" +#include "nm-logging.h" +#include "nm-setting.h" +#include "NetworkManagerUtils.h" + +static char *hexstr2bin (const char *hex, size_t len); + +#define NM_SUPPLICANT_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SUPPLICANT_CONFIG, \ + NMSupplicantConfigPrivate)) + +G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT) + +typedef struct { + char *value; + guint32 len; + OptType type; +} ConfigOption; + +typedef struct +{ + GHashTable *config; + GHashTable *blobs; + guint32 ap_scan; + gboolean dispose_has_run; +} NMSupplicantConfigPrivate; + +NMSupplicantConfig * +nm_supplicant_config_new (void) +{ + return g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL); +} + +static void +config_option_free (ConfigOption *opt) +{ + g_free (opt->value); + g_slice_free (ConfigOption, opt); +} + +static void +blob_free (GByteArray *array) +{ + g_byte_array_free (array, TRUE); +} + +static void +nm_supplicant_config_init (NMSupplicantConfig * self) +{ + NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + + priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) config_option_free); + + priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) blob_free); + + priv->ap_scan = 1; + priv->dispose_has_run = FALSE; +} + +static gboolean +nm_supplicant_config_add_option_with_type (NMSupplicantConfig *self, + const char *key, + const char *value, + gint32 len, + OptType opt_type, + gboolean secret) +{ + NMSupplicantConfigPrivate *priv; + ConfigOption *old_opt; + ConfigOption *opt; + OptType type; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + + if (len < 0) + len = strlen (value); + + if (opt_type != TYPE_INVALID) + type = opt_type; + else { + type = nm_supplicant_settings_verify_setting (key, value, len); + if (type == TYPE_INVALID) { + char buf[255]; + memset (&buf[0], 0, sizeof (buf)); + memcpy (&buf[0], value, len > 254 ? 254 : len); + nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or value '%s' invalid.", key, buf); + return FALSE; + } + } + + old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key); + if (old_opt) { + nm_log_warn (LOGD_SUPPLICANT, "Key '%s' already in table.", key); + return FALSE; + } + + opt = g_slice_new0 (ConfigOption); + if (opt == NULL) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't allocate memory for new config option."); + return FALSE; + } + + opt->value = g_malloc0 ((sizeof (char) * len) + 1); + if (opt->value == NULL) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't allocate memory for new config option value."); + g_slice_free (ConfigOption, opt); + return FALSE; + } + memcpy (opt->value, value, len); + + opt->len = len; + opt->type = type; + + { + char buf[255]; + memset (&buf[0], 0, sizeof (buf)); + memcpy (&buf[0], opt->value, opt->len > 254 ? 254 : opt->len); + nm_log_info (LOGD_SUPPLICANT, "Config: added '%s' value '%s'", key, secret ? "<omitted>" : &buf[0]); + } + + g_hash_table_insert (priv->config, g_strdup (key), opt); + + return TRUE; +} + +static gboolean +nm_supplicant_config_add_option (NMSupplicantConfig *self, + const char *key, + const char *value, + gint32 len, + gboolean secret) +{ + return nm_supplicant_config_add_option_with_type (self, key, value, len, TYPE_INVALID, secret); +} + +static gboolean +nm_supplicant_config_add_blob (NMSupplicantConfig *self, + const char *key, + const GByteArray *value, + const char *blobid) +{ + NMSupplicantConfigPrivate *priv; + ConfigOption *old_opt; + ConfigOption *opt; + OptType type; + GByteArray *blob; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (value->len > 0, FALSE); + g_return_val_if_fail (blobid != NULL, FALSE); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + + type = nm_supplicant_settings_verify_setting (key, (const char *) value->data, value->len); + if (type == TYPE_INVALID) { + nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or it's contained value is invalid.", key); + return FALSE; + } + + old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key); + if (old_opt) { + nm_log_warn (LOGD_SUPPLICANT, "Key '%s' already in table.", key); + return FALSE; + } + + blob = g_byte_array_sized_new (value->len); + if (!blob) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't allocate memory for new config blob."); + return FALSE; + } + g_byte_array_append (blob, value->data, value->len); + + opt = g_slice_new0 (ConfigOption); + if (opt == NULL) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't allocate memory for new config option."); + g_byte_array_free (blob, TRUE); + return FALSE; + } + + opt->value = g_strdup_printf ("blob://%s", blobid); + if (opt->value == NULL) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't allocate memory for new config option value."); + g_byte_array_free (blob, TRUE); + g_slice_free (ConfigOption, opt); + return FALSE; + } + + opt->len = strlen (opt->value); + opt->type = type; + + nm_log_info (LOGD_SUPPLICANT, "Config: added '%s' value '%s'", key, opt->value); + + g_hash_table_insert (priv->config, g_strdup (key), opt); + g_hash_table_insert (priv->blobs, g_strdup (blobid), blob); + + return TRUE; +} + +static void +nm_supplicant_config_finalize (GObject *object) +{ + /* Complete object destruction */ + g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config); + g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->blobs); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object); +} + + +static void +nm_supplicant_config_class_init (NMSupplicantConfigClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = nm_supplicant_config_finalize; + + g_type_class_add_private (object_class, sizeof (NMSupplicantConfigPrivate)); +} + +guint32 +nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 1); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan; +} + +void +nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, + guint32 ap_scan) +{ + g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); + g_return_if_fail (ap_scan >= 0 && ap_scan <= 2); + + NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan; +} + +static void +get_hash_cb (gpointer key, gpointer value, gpointer user_data) +{ + ConfigOption *opt = (ConfigOption *) value; + GValue *variant; + GByteArray *array; + + variant = g_slice_new0 (GValue); + + switch (opt->type) { + case TYPE_INT: + g_value_init (variant, G_TYPE_INT); + g_value_set_int (variant, atoi (opt->value)); + break; + case TYPE_BYTES: + array = g_byte_array_sized_new (opt->len); + g_byte_array_append (array, (const guint8 *) opt->value, opt->len); + g_value_init (variant, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_set_boxed (variant, array); + g_byte_array_free (array, TRUE); + break; + case TYPE_KEYWORD: + case TYPE_STRING: + g_value_init (variant, G_TYPE_STRING); + g_value_set_string (variant, opt->value); + break; + default: + g_slice_free (GValue, variant); + return; + } + + g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), variant); +} + +static void +destroy_hash_value (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +GHashTable * +nm_supplicant_config_get_hash (NMSupplicantConfig * self) +{ + NMSupplicantConfigPrivate *priv; + GHashTable *hash; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + destroy_hash_value); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + g_hash_table_foreach (priv->config, get_hash_cb, hash); + return hash; +} + +GHashTable * +nm_supplicant_config_get_blobs (NMSupplicantConfig * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->blobs; +} + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] + +gboolean +nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, + NMSettingWireless * setting, + gboolean is_broadcast, + guint32 adhoc_freq, + gboolean has_scan_capa_ssid) +{ + NMSupplicantConfigPrivate *priv; + gboolean is_adhoc; + const char *mode; + const GByteArray *id; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + g_return_val_if_fail (setting != NULL, FALSE); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + + mode = nm_setting_wireless_get_mode (setting); + is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE; + if (is_adhoc) + priv->ap_scan = 2; + else if (is_broadcast == FALSE) { + /* drivers that support scanning specific SSIDs should use + * ap_scan=1, while those that do not should use ap_scan=2. + */ + priv->ap_scan = has_scan_capa_ssid ? 1 : 2; + } + + id = nm_setting_wireless_get_ssid (setting); + if (!nm_supplicant_config_add_option (self, "ssid", (char *) id->data, id->len, FALSE)) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding SSID to supplicant config."); + return FALSE; + } + + if (is_adhoc) { + if (!nm_supplicant_config_add_option (self, "mode", "1", -1, FALSE)) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding mode to supplicant config."); + return FALSE; + } + + if (adhoc_freq) { + char *str_freq; + + str_freq = g_strdup_printf ("%u", adhoc_freq); + if (!nm_supplicant_config_add_option (self, "frequency", str_freq, -1, FALSE)) { + g_free (str_freq); + nm_log_warn (LOGD_SUPPLICANT, "Error adding Ad-Hoc frequency to supplicant config."); + return FALSE; + } + g_free (str_freq); + } + } + + /* Except for Ad-Hoc networks, request that the driver probe for the + * specific SSID we want to associate with. + */ + if (!is_adhoc) { + if (!nm_supplicant_config_add_option (self, "scan_ssid", "1", -1, FALSE)) + return FALSE; + } + + id = nm_setting_wireless_get_bssid (setting); + if (id && id->len) { + char *str_bssid; + + str_bssid = g_strdup_printf (MAC_FMT, MAC_ARG (id->data)); + if (!nm_supplicant_config_add_option (self, "bssid", + str_bssid, strlen (str_bssid), + FALSE)) { + g_free (str_bssid); + nm_log_warn (LOGD_SUPPLICANT, "Error adding BSSID to supplicant config."); + return FALSE; + } + g_free (str_bssid); + } + + // FIXME: band & channel config items + + return TRUE; +} + +static gboolean +add_string_val (NMSupplicantConfig *self, + const char *field, + const char *name, + gboolean ucase, + gboolean secret) +{ + gboolean success; + char *value; + + if (!field) + return TRUE; + + value = ucase ? g_ascii_strup (field, -1) : g_strdup (field); + success = nm_supplicant_config_add_option (self, name, value, strlen (field), secret); + if (!success) + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); + g_free (value); + return success; +} + +#define ADD_STRING_LIST_VAL(setting, setting_name, field, field_plural, name, ucase, secret) \ + if (nm_setting_##setting_name##_get_num_##field_plural (setting)) { \ + guint32 k; \ + GString *str = g_string_new (NULL); \ + for (k = 0; k < nm_setting_##setting_name##_get_num_##field_plural (setting); k++) { \ + const char *item = nm_setting_##setting_name##_get_##field (setting, k); \ + if (!str->len) { \ + g_string_append (str, item); \ + } else { \ + g_string_append_c (str, ' '); \ + g_string_append (str, item); \ + } \ + } \ + if (ucase) \ + g_string_ascii_up (str); \ + if (str->len) \ + success = nm_supplicant_config_add_option (self, name, str->str, -1, secret); \ + else \ + success = TRUE; \ + g_string_free (str, TRUE); \ + if (!success) { \ + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); \ + return FALSE; \ + } \ + } + +static char * +get_blob_id (const char *name, const char *seed_uid) +{ + char *uid = g_strdup_printf ("%s-%s", seed_uid, name); + char *p = uid; + while (*p) { + if (*p == '/') *p = '-'; + p++; + } + return uid; +} + +#define ADD_BLOB_VAL(field, name, con_uid) \ + if (field && field->len) { \ + char *uid = get_blob_id (name, con_uid); \ + success = nm_supplicant_config_add_blob (self, name, field, uid); \ + g_free (uid); \ + if (!success) { \ + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); \ + return FALSE; \ + } \ + } + + +static gboolean +wep128_passphrase_hash (const char *input, + size_t input_len, + guint8 *out_digest, + size_t *out_digest_len) +{ + GChecksum *sum; + guint8 data[64]; + int i; + + g_return_val_if_fail (out_digest != NULL, FALSE); + g_return_val_if_fail (out_digest_len != NULL, FALSE); + g_return_val_if_fail (*out_digest_len >= 16, FALSE); + + /* Get at least 64 bytes by repeating the passphrase into the buffer */ + for (i = 0; i < sizeof (data); i++) + data[i] = input[i % input_len]; + + sum = g_checksum_new (G_CHECKSUM_MD5); + g_assert (sum); + g_checksum_update (sum, data, sizeof (data)); + g_checksum_get_digest (sum, out_digest, out_digest_len); + g_checksum_free (sum); + + g_assert (*out_digest_len == 16); + /* WEP104 keys are 13 bytes in length (26 hex characters) */ + *out_digest_len = 13; + return TRUE; +} + +static gboolean +add_wep_key (NMSupplicantConfig *self, + const char *key, + const char *name, + NMWepKeyType wep_type) +{ + char *value; + gboolean success; + size_t key_len = key ? strlen (key) : 0; + + if (!key || !key_len) + return TRUE; + + if ( (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) + || (wep_type == NM_WEP_KEY_TYPE_KEY)) { + if ((key_len == 10) || (key_len == 26)) { + value = hexstr2bin (key, strlen (key)); + success = nm_supplicant_config_add_option (self, name, value, key_len / 2, TRUE); + g_free (value); + if (!success) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); + return FALSE; + } + } else if ((key_len == 5) || (key_len == 13)) { + if (!nm_supplicant_config_add_option (self, name, key, key_len, TRUE)) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); + return FALSE; + } + } else { + nm_log_warn (LOGD_SUPPLICANT, "Invalid WEP key '%s'", name); + return FALSE; + } + } else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) { + guint8 digest[16]; + size_t digest_len = sizeof (digest); + + success = wep128_passphrase_hash (key, key_len, digest, &digest_len); + if (success) + success = nm_supplicant_config_add_option (self, name, (const char *) digest, digest_len, TRUE); + if (!success) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); + return FALSE; + } + } + + return TRUE; +} + +gboolean +nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, + NMSettingWirelessSecurity *setting, + NMSetting8021x *setting_8021x, + const char *connection_uid) +{ + char *value; + gboolean success; + const char *key_mgmt, *auth_alg; + const char *psk; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (connection_uid != NULL, FALSE); + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting); + if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE)) + return FALSE; + + auth_alg = nm_setting_wireless_security_get_auth_alg (setting); + if (!add_string_val (self, auth_alg, "auth_alg", TRUE, FALSE)) + return FALSE; + + psk = nm_setting_wireless_security_get_psk (setting); + if (psk) { + size_t psk_len = strlen (psk); + + if (psk_len == 64) { + /* Hex PSK */ + value = hexstr2bin (psk, psk_len); + success = nm_supplicant_config_add_option (self, "psk", value, psk_len / 2, TRUE); + g_free (value); + if (!success) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding 'psk' to supplicant config."); + return FALSE; + } + } else if (psk_len >= 8 && psk_len <= 63) { + /* Use TYPE_STRING here so that it gets pushed to the + * supplicant as a string, and therefore gets quoted, + * and therefore the supplicant will interpret it as a + * passphrase and not a hex key. + */ + if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, TRUE)) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding 'psk' to supplicant config."); + return FALSE; + } + } else { + /* Invalid PSK */ + nm_log_warn (LOGD_SUPPLICANT, "Invalid PSK length %u: not between 8 and 63 characters inclusive.", (guint32) psk_len); + return FALSE; + } + } + + /* Only WPA-specific things when using WPA */ + if ( !strcmp (key_mgmt, "wpa-none") + || !strcmp (key_mgmt, "wpa-psk") + || !strcmp (key_mgmt, "wpa-eap")) { + ADD_STRING_LIST_VAL (setting, wireless_security, proto, protos, "proto", TRUE, FALSE); + ADD_STRING_LIST_VAL (setting, wireless_security, pairwise, pairwise, "pairwise", TRUE, FALSE); + ADD_STRING_LIST_VAL (setting, wireless_security, group, groups, "group", TRUE, FALSE); + } + + /* WEP keys if required */ + if (!strcmp (key_mgmt, "none")) { + NMWepKeyType wep_type = nm_setting_wireless_security_get_wep_key_type (setting); + const char *wep0 = nm_setting_wireless_security_get_wep_key (setting, 0); + const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1); + const char *wep2 = nm_setting_wireless_security_get_wep_key (setting, 2); + const char *wep3 = nm_setting_wireless_security_get_wep_key (setting, 3); + + if (!add_wep_key (self, wep0, "wep_key0", wep_type)) + return FALSE; + if (!add_wep_key (self, wep1, "wep_key1", wep_type)) + return FALSE; + if (!add_wep_key (self, wep2, "wep_key2", wep_type)) + return FALSE; + if (!add_wep_key (self, wep3, "wep_key3", wep_type)) + return FALSE; + + if (wep0 || wep1 || wep2 || wep3) { + value = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (setting)); + success = nm_supplicant_config_add_option (self, "wep_tx_keyidx", value, -1, FALSE); + g_free (value); + if (!success) { + nm_log_warn (LOGD_SUPPLICANT, "Error adding wep_tx_keyidx to supplicant config."); + return FALSE; + } + } + } + + if (auth_alg && !strcmp (auth_alg, "leap")) { + /* LEAP */ + if (!strcmp (key_mgmt, "ieee8021x")) { + const char *tmp; + + tmp = nm_setting_wireless_security_get_leap_username (setting); + if (!add_string_val (self, tmp, "identity", FALSE, FALSE)) + return FALSE; + + tmp = nm_setting_wireless_security_get_leap_password (setting); + if (!add_string_val (self, tmp, "password", FALSE, TRUE)) + return FALSE; + + if (!add_string_val (self, "leap", "eap", TRUE, FALSE)) + return FALSE; + } else { + return FALSE; + } + } else { + /* 802.1x for Dynamic WEP and WPA-Enterprise */ + if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) { + if (!setting_8021x) + return FALSE; + if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, connection_uid, FALSE)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, + NMSetting8021x *setting, + const char *connection_uid, + gboolean wired) +{ + char *tmp; + const char *peapver, *value, *path; + gboolean success, added; + GString *phase1, *phase2; + const GByteArray *array; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (connection_uid != NULL, FALSE); + + value = nm_setting_802_1x_get_password (setting); + if (!add_string_val (self, value, "password", FALSE, TRUE)) + return FALSE; + value = nm_setting_802_1x_get_pin (setting); + if (!add_string_val (self, value, "pin", FALSE, TRUE)) + return FALSE; + + if (wired) { + if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE)) + return FALSE; + /* Wired 802.1x must always use eapol_flags=0 */ + if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE)) + return FALSE; + } + + ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", TRUE, FALSE); + + /* Drop the fragment size a bit for better compatibility */ + if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE)) + return FALSE; + + phase1 = g_string_new (NULL); + peapver = nm_setting_802_1x_get_phase1_peapver (setting); + if (peapver) { + if (!strcmp (peapver, "0")) + g_string_append (phase1, "peapver=0"); + else if (!strcmp (peapver, "1")) + g_string_append (phase1, "peapver=1"); + } + + if (nm_setting_802_1x_get_phase1_peaplabel (setting)) { + if (phase1->len) + g_string_append_c (phase1, ' '); + g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting)); + } + + if (phase1->len) { + if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE)) { + g_string_free (phase1, TRUE); + return FALSE; + } + } + g_string_free (phase1, TRUE); + + phase2 = g_string_new (NULL); + if (nm_setting_802_1x_get_phase2_auth (setting)) { + tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1); + g_string_append_printf (phase2, "auth=%s", tmp); + g_free (tmp); + } + + if (nm_setting_802_1x_get_phase2_autheap (setting)) { + if (phase2->len) + g_string_append_c (phase2, ' '); + tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_autheap (setting), -1); + g_string_append_printf (phase2, "autheap=%s", tmp); + g_free (tmp); + } + + if (phase2->len) { + if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE)) { + g_string_free (phase2, TRUE); + return FALSE; + } + } + g_string_free (phase2, TRUE); + + /* CA path */ + path = nm_setting_802_1x_get_ca_path (setting); + if (nm_setting_802_1x_get_system_ca_certs (setting)) + path = SYSTEM_CA_PATH; + if (path) { + if (!add_string_val (self, path, "ca_path", FALSE, FALSE)) + return FALSE; + } + + /* Phase2 CA path */ + path = nm_setting_802_1x_get_phase2_ca_path (setting); + if (nm_setting_802_1x_get_system_ca_certs (setting)) + path = SYSTEM_CA_PATH; + if (path) { + if (!add_string_val (self, path, "ca_path2", FALSE, FALSE)) + return FALSE; + } + + /* CA certificate */ + switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_ca_cert_blob (setting); + ADD_BLOB_VAL (array, "ca_cert", connection_uid); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_ca_cert_path (setting); + if (!add_string_val (self, path, "ca_cert", FALSE, FALSE)) + return FALSE; + break; + default: + break; + } + + /* Phase 2 CA certificate */ + switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); + ADD_BLOB_VAL (array, "ca_cert2", connection_uid); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_phase2_ca_cert_path (setting); + if (!add_string_val (self, path, "ca_cert2", FALSE, FALSE)) + return FALSE; + break; + default: + break; + } + + /* Private key */ + added = FALSE; + switch (nm_setting_802_1x_get_private_key_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_private_key_blob (setting); + ADD_BLOB_VAL (array, "private_key", connection_uid); + added = TRUE; + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_private_key_path (setting); + if (!add_string_val (self, path, "private_key", FALSE, FALSE)) + return FALSE; + added = TRUE; + break; + default: + break; + } + + if (added) { + NMSetting8021xCKFormat format; + NMSetting8021xCKScheme scheme; + + format = nm_setting_802_1x_get_private_key_format (setting); + scheme = nm_setting_802_1x_get_private_key_scheme (setting); + + if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH + || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + /* Only add the private key password for PKCS#12 blobs and + * all path schemes, since in both of these cases the private key + * isn't decrypted at all. + */ + value = nm_setting_802_1x_get_private_key_password (setting); + if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE)) + return FALSE; + } + + if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + /* Only add the client cert if the private key is not PKCS#12, as + * wpa_supplicant configuration directs us to do. + */ + switch (nm_setting_802_1x_get_client_cert_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_client_cert_blob (setting); + ADD_BLOB_VAL (array, "client_cert", connection_uid); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_client_cert_path (setting); + if (!add_string_val (self, path, "client_cert", FALSE, FALSE)) + return FALSE; + break; + default: + break; + } + } + } + + /* Phase 2 private key */ + added = FALSE; + switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_phase2_private_key_blob (setting); + ADD_BLOB_VAL (array, "private_key2", connection_uid); + added = TRUE; + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_phase2_private_key_path (setting); + if (!add_string_val (self, path, "private_key2", FALSE, FALSE)) + return FALSE; + added = TRUE; + break; + default: + break; + } + + if (added) { + NMSetting8021xCKFormat format; + NMSetting8021xCKScheme scheme; + + format = nm_setting_802_1x_get_phase2_private_key_format (setting); + scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting); + + if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PATH + || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + /* Only add the private key password for PKCS#12 blobs and + * all path schemes, since in both of these cases the private key + * isn't decrypted at all. + */ + value = nm_setting_802_1x_get_phase2_private_key_password (setting); + if (!add_string_val (self, value, "private_key_passwd2", FALSE, TRUE)) + return FALSE; + } + + if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + /* Only add the client cert if the private key is not PKCS#12, as + * wpa_supplicant configuration directs us to do. + */ + switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + array = nm_setting_802_1x_get_phase2_client_cert_blob (setting); + ADD_BLOB_VAL (array, "client_cert2", connection_uid); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_phase2_client_cert_path (setting); + if (!add_string_val (self, path, "client_cert2", FALSE, FALSE)) + return FALSE; + break; + default: + break; + } + } + } + + value = nm_setting_802_1x_get_identity (setting); + if (!add_string_val (self, value, "identity", FALSE, FALSE)) + return FALSE; + value = nm_setting_802_1x_get_anonymous_identity (setting); + if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE)) + return FALSE; + + return TRUE; +} + +gboolean +nm_supplicant_config_add_no_security (NMSupplicantConfig *self) +{ + return nm_supplicant_config_add_option (self, "key_mgmt", "NONE", -1, FALSE); +} + +/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */ + +static int hex2num (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex2byte (const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +static char * +hexstr2bin (const char *hex, size_t len) +{ + size_t i; + int a; + const char * ipos = hex; + char * buf = NULL; + char * opos; + + /* Length must be a multiple of 2 */ + if ((len % 2) != 0) + return NULL; + + opos = buf = g_malloc0 ((len / 2) + 1); + for (i = 0; i < len; i += 2) { + a = hex2byte (ipos); + if (a < 0) { + g_free (buf); + return NULL; + } + *opos++ = a; + ipos += 2; + } + return buf; +} + +/* End from hostap */ + diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h new file mode 100644 index 00000000..dad23e29 --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -0,0 +1,84 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef NM_SUPPLICANT_CONFIG_H +#define NM_SUPPLICANT_CONFIG_H + +#include <glib-object.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> +#include <nm-setting-8021x.h> +#include "nm-supplicant-types.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SUPPLICANT_CONFIG (nm_supplicant_config_get_type ()) +#define NM_SUPPLICANT_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfig)) +#define NM_SUPPLICANT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfigClass)) +#define NM_IS_SUPPLICANT_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUPPLICANT_CONFIG)) +#define NM_IS_SUPPLICANT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_CONFIG)) +#define NM_SUPPLICANT_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfigClass)) + +struct _NMSupplicantConfig +{ + GObject parent; +}; + +typedef struct +{ + GObjectClass parent; +} NMSupplicantConfigClass; + + +GType nm_supplicant_config_get_type (void); + +NMSupplicantConfig *nm_supplicant_config_new (void); + +guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self); + +void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self, + guint32 ap_scan); + +GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig *self); + +GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self); + +gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self, + NMSettingWireless *setting, + gboolean is_broadcast, + guint32 adhoc_freq, + gboolean has_scan_capa_ssid); + +gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, + NMSettingWirelessSecurity *setting, + NMSetting8021x *setting_8021x, + const char *connection_uid); + +gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self); + +gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, + NMSetting8021x *setting, + const char *connection_uid, + gboolean wired); + +G_END_DECLS + +#endif /* NM_SUPPLICANT_CONFIG_H */ diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c new file mode 100644 index 00000000..a65a458f --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -0,0 +1,1429 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#include "nm-supplicant-interface.h" +#include "nm-supplicant-manager.h" +#include "nm-logging.h" +#include "nm-marshal.h" +#include "nm-supplicant-config.h" +#include "nm-dbus-manager.h" +#include "nm-call-store.h" +#include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" + +#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface" +#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID" +#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" +#define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface" +#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".ExistsError" + + +G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT) + + +#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SUPPLICANT_INTERFACE, \ + NMSupplicantInterfacePrivate)) + +static void nm_supplicant_interface_set_property (GObject * object, + guint prop_id, + const GValue * value, + GParamSpec * pspec); + +static void nm_supplicant_interface_get_property (GObject * object, + guint prop_id, + GValue * value, + GParamSpec * pspec); + +static void nm_supplicant_interface_start (NMSupplicantInterface *self); + +static void nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface *self, + gboolean get_only); + +static void nm_supplicant_interface_smgr_state_changed (NMSupplicantManager *smgr, + guint32 new_state, + guint32 old_state, + gpointer user_data); + +static void nm_supplicant_interface_set_state (NMSupplicantInterface *self, + guint32 new_state); + + +/* Signals */ +enum { + STATE, /* change in the interface's state */ + REMOVED, /* interface was removed by the supplicant */ + SCANNED_AP, /* interface saw a new access point from a scan */ + SCAN_REQ_RESULT, /* result of a wireless scan request */ + SCAN_RESULTS, /* scan results returned from supplicant */ + CONNECTION_STATE, /* link state of the device's connection */ + CONNECTION_ERROR, /* an error occurred during a connection request */ + LAST_SIGNAL +}; +static guint nm_supplicant_interface_signals[LAST_SIGNAL] = { 0 }; + + +/* Properties */ +enum { + PROP_0 = 0, + PROP_SUPPLICANT_MANAGER, + PROP_DEVICE, + PROP_STATE, + PROP_CONNECTION_STATE, + PROP_SCANNING, + LAST_PROP +}; + + +typedef struct +{ + NMSupplicantManager * smgr; + gulong smgr_state_sig_handler; + NMDBusManager * dbus_mgr; + char * dev; + gboolean is_wireless; + + char * object_path; + guint32 state; + NMCallStore * assoc_pcalls; + NMCallStore * other_pcalls; + + guint32 con_state; + gboolean scanning; + + DBusGProxy * iface_proxy; + DBusGProxy * net_proxy; + + guint scan_results_timeout; + guint32 last_scan; + + NMSupplicantConfig * cfg; + + gboolean dispose_has_run; +} NMSupplicantInterfacePrivate; + +static gboolean +cancel_all_cb (GObject *object, gpointer call_id, gpointer user_data) +{ + dbus_g_proxy_cancel_call (DBUS_G_PROXY (object), (DBusGProxyCall *) call_id); + + return TRUE; +} + +static void +cancel_all_callbacks (NMCallStore *store) +{ + nm_call_store_foreach (store, NULL, cancel_all_cb, NULL); + nm_call_store_clear (store); +} + +typedef struct { + NMSupplicantInterface *interface; + DBusGProxy *proxy; + NMCallStore *store; + DBusGProxyCall *call; + gboolean disposing; +} NMSupplicantInfo; + +static NMSupplicantInfo * +nm_supplicant_info_new (NMSupplicantInterface *interface, + DBusGProxy *proxy, + NMCallStore *store) +{ + NMSupplicantInfo *info; + + info = g_slice_new0 (NMSupplicantInfo); + info->interface = g_object_ref (interface); + info->proxy = g_object_ref (proxy); + info->store = store; + + return info; +} + +static void +nm_supplicant_info_set_call (NMSupplicantInfo *info, DBusGProxyCall *call) +{ + g_return_if_fail (info != NULL); + g_return_if_fail (call != NULL); + + nm_call_store_add (info->store, G_OBJECT (info->proxy), (gpointer) call); + info->call = call; +} + +static void +nm_supplicant_info_destroy (gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + + /* Guard against double-disposal; since DBusGProxy doesn't guard against + * double-disposal, we could infinite loop here if we're in the middle of + * some wpa_supplicant D-Bus calls. When the supplicant dies we'll dispose + * of the proxy, which kills all its pending calls, which brings us here. + * Then when we unref the proxy here, its dispose() function will get called + * again, and we get right back here until we segfault because our callstack + * is too long. + */ + if (!info->disposing) { + info->disposing = TRUE; + + if (info->call) { + nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call); + info->call = NULL; + } + + g_object_unref (info->proxy); + info->proxy = NULL; + g_object_unref (info->interface); + info->interface = NULL; + + memset (info, 0, sizeof (NMSupplicantInfo)); + g_slice_free (NMSupplicantInfo, info); + } +} + + +NMSupplicantInterface * +nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless) +{ + NMSupplicantInterface * iface; + + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL); + g_return_val_if_fail (ifname != NULL, NULL); + + iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE, + "supplicant-manager", smgr, + "device", ifname, + NULL); + if (iface) { + NM_SUPPLICANT_INTERFACE_GET_PRIVATE (iface)->is_wireless = is_wireless; + nm_supplicant_interface_start (iface); + } + + return iface; +} + +static void +nm_supplicant_interface_init (NMSupplicantInterface * self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT; + priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED; + priv->assoc_pcalls = nm_call_store_new (); + priv->other_pcalls = nm_call_store_new (); + + priv->dispose_has_run = FALSE; + + priv->dbus_mgr = nm_dbus_manager_get (); +} + + +static void +nm_supplicant_interface_set_property (GObject * object, + guint prop_id, + const GValue * value, + GParamSpec * pspec) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); + gulong id; + + switch (prop_id) { + case PROP_SUPPLICANT_MANAGER: + priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value)); + g_object_ref (G_OBJECT (priv->smgr)); + + id = g_signal_connect (priv->smgr, + "state", + G_CALLBACK (nm_supplicant_interface_smgr_state_changed), + object); + priv->smgr_state_sig_handler = id; + break; + case PROP_DEVICE: + /* Construct-only */ + priv->dev = g_strdup (g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_supplicant_interface_get_property (GObject * object, + guint prop_id, + GValue * value, + GParamSpec * pspec) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SUPPLICANT_MANAGER: + g_value_set_object (value, G_OBJECT (priv->smgr)); + break; + case PROP_DEVICE: + g_value_set_string (value, priv->dev); + break; + case PROP_STATE: + g_value_set_uint (value, priv->state); + break; + case PROP_CONNECTION_STATE: + g_value_set_uint (value, priv->con_state); + break; + case PROP_SCANNING: + g_value_set_boolean (value, priv->scanning); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +try_remove_iface (DBusGConnection *g_connection, + const char *path) +{ + DBusGProxy *proxy; + + g_return_if_fail (g_connection != NULL); + g_return_if_fail (path != NULL); + + proxy = dbus_g_proxy_new_for_name (g_connection, + WPAS_DBUS_SERVICE, + WPAS_DBUS_PATH, + WPAS_DBUS_INTERFACE); + if (!proxy) + return; + + dbus_g_proxy_call_no_reply (proxy, "removeInterface", + DBUS_TYPE_G_OBJECT_PATH, path, + G_TYPE_INVALID); + g_object_unref (proxy); +} + +static void +nm_supplicant_interface_dispose (GObject *object) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); + guint32 sm_state; + + if (priv->dispose_has_run) { + G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object); + return; + } + + priv->dispose_has_run = TRUE; + + /* Ask wpa_supplicant to remove this interface */ + sm_state = nm_supplicant_manager_get_state (priv->smgr); + if (sm_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) { + if (priv->object_path) { + try_remove_iface (nm_dbus_manager_get_connection (priv->dbus_mgr), + priv->object_path); + } + } + + if (priv->iface_proxy) + g_object_unref (priv->iface_proxy); + + if (priv->net_proxy) + g_object_unref (priv->net_proxy); + + if (priv->scan_results_timeout) + g_source_remove (priv->scan_results_timeout); + + if (priv->smgr) { + g_signal_handler_disconnect (priv->smgr, + priv->smgr_state_sig_handler); + g_object_unref (priv->smgr); + } + + g_free (priv->dev); + + /* Cancel pending calls before unrefing the dbus manager */ + cancel_all_callbacks (priv->other_pcalls); + nm_call_store_destroy (priv->other_pcalls); + + cancel_all_callbacks (priv->assoc_pcalls); + nm_call_store_destroy (priv->assoc_pcalls); + + if (priv->dbus_mgr) + g_object_unref (priv->dbus_mgr); + + if (priv->cfg) + g_object_unref (priv->cfg); + + g_free (priv->object_path); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object); +} + +static void +nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate)); + + object_class->dispose = nm_supplicant_interface_dispose; + object_class->set_property = nm_supplicant_interface_set_property; + object_class->get_property = nm_supplicant_interface_get_property; + + /* Properties */ + g_object_class_install_property (object_class, + PROP_SUPPLICANT_MANAGER, + g_param_spec_object ("supplicant-manager", + "Supplicant Manager", + "Supplicant manager to which this interface belongs", + NM_TYPE_SUPPLICANT_MANAGER, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_DEVICE, + g_param_spec_string ("device", + "Device", + "Device which this interface represents to the supplicant", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_STATE, + g_param_spec_uint ("state", + "State", + "State of the supplicant interface; INIT, READY, or DOWN", + NM_SUPPLICANT_INTERFACE_STATE_INIT, + NM_SUPPLICANT_INTERFACE_STATE_LAST - 1, + NM_SUPPLICANT_INTERFACE_STATE_INIT, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_SCANNING, + g_param_spec_boolean ("scanning", + "Scanning", + "Scanning", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + nm_supplicant_interface_signals[STATE] = + g_signal_new ("state", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state), + NULL, NULL, + _nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + + nm_supplicant_interface_signals[REMOVED] = + g_signal_new ("removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + nm_supplicant_interface_signals[SCANNED_AP] = + g_signal_new ("scanned-ap", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scanned_ap), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + nm_supplicant_interface_signals[SCAN_REQ_RESULT] = + g_signal_new ("scan-req-result", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_req_result), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + nm_supplicant_interface_signals[SCAN_RESULTS] = + g_signal_new ("scan-results", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_results), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + nm_supplicant_interface_signals[CONNECTION_STATE] = + g_signal_new ("connection-state", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_state), + NULL, NULL, + _nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + + nm_supplicant_interface_signals[CONNECTION_ERROR] = + g_signal_new ("connection-error", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error), + NULL, NULL, + _nm_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); +} + +static void +emit_error_helper (NMSupplicantInterface *self, + GError *err) +{ + const char *name = NULL; + + if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION) + name = dbus_g_error_get_name (err); + + g_signal_emit (self, + nm_supplicant_interface_signals[CONNECTION_ERROR], + 0, + name, + err->message); +} + +static void +bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + GHashTable *hash = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_MAP_OF_VARIANT, &hash, + G_TYPE_INVALID)) { + if (!strstr (err->message, "The BSSID requested was invalid")) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.", + err->message); + } + g_error_free (err); + } else { + g_signal_emit (info->interface, + nm_supplicant_interface_signals[SCANNED_AP], + 0, + hash); + + g_hash_table_destroy (hash); + } +} + +static void +request_bssid_properties (NMSupplicantInterface * self, + const char * op) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxy *proxy; + DBusGProxyCall *call; + + proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + op, + WPAS_DBUS_IFACE_BSSID); + info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (proxy, "properties", + bssid_properties_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + g_object_unref (proxy); +} + +static void +scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + GError *err = NULL; + GPtrArray *array = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &array, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "could not get scan results: %s.", err->message); + g_error_free (err); + } else { + int i; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + + /* Notify listeners of the result of the scan */ + g_signal_emit (info->interface, + nm_supplicant_interface_signals[SCAN_RESULTS], + 0, + array->len); + + /* Fire off a "properties" call for each returned BSSID */ + for (i = 0; i < array->len; i++) { + char *op = g_ptr_array_index (array, i); + + request_bssid_properties (info->interface, op); + g_free (op); + } + + g_ptr_array_free (array, TRUE); + } +} + +static gboolean +request_scan_results (gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + GTimeVal cur_time; + + priv->scan_results_timeout = 0; + + g_return_val_if_fail (priv->iface_proxy != NULL, FALSE); + + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanResults", + scan_results_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + + g_get_current_time (&cur_time); + priv->last_scan = cur_time.tv_sec; + return FALSE; +} + +static void +wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data); + GTimeVal cur_time; + + /* Only query scan results if a query is not queued */ + if (priv->scan_results_timeout) + return; + + g_get_current_time (&cur_time); + + /* Only fetch scan results every 4s max, but initially do it right away */ + if (priv->last_scan + 4 < cur_time.tv_sec) { + priv->scan_results_timeout = g_idle_add (request_scan_results, + user_data); + } else { + priv->scan_results_timeout = + g_timeout_add_seconds ((4 - (cur_time.tv_sec - priv->last_scan)), + request_scan_results, user_data); + } +} + +static guint32 +wpas_state_string_to_enum (const char * str_state) +{ + guint32 enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED; + + if (!strcmp (str_state, "DISCONNECTED")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED; + else if (!strcmp (str_state, "INACTIVE")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE; + else if (!strcmp (str_state, "SCANNING")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING; + else if (!strcmp (str_state, "ASSOCIATING")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING; + else if (!strcmp (str_state, "ASSOCIATED")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED; + else if (!strcmp (str_state, "4WAY_HANDSHAKE")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE; + else if (!strcmp (str_state, "GROUP_HANDSHAKE")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE; + else if (!strcmp (str_state, "COMPLETED")) + enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED; + + return enum_state; +} + +static void +wpas_iface_handle_state_change (DBusGProxy *proxy, + const char *str_new_state, + const char *str_old_state, + gpointer user_data) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data); + guint32 old_state, enum_new_state; + + enum_new_state = wpas_state_string_to_enum (str_new_state); + old_state = priv->con_state; + priv->con_state = enum_new_state; + if (priv->con_state != old_state) { + g_signal_emit (user_data, + nm_supplicant_interface_signals[CONNECTION_STATE], + 0, + priv->con_state, + old_state); + } +} + + +static void +iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + GError *err = NULL; + char *state_str = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + G_TYPE_STRING, &state_str, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "could not get interface state: %s.", err->message); + g_error_free (err); + } else { + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + + priv->con_state = wpas_state_string_to_enum (state_str); + g_free (state_str); + nm_supplicant_interface_set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_READY); + } +} + +static void +wpas_iface_get_state (NMSupplicantInterface *self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "state", + iface_state_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); +} + +static void +iface_scanning_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + gboolean scanning = FALSE; + + if (dbus_g_proxy_end_call (proxy, call_id, NULL, + G_TYPE_BOOLEAN, &scanning, + G_TYPE_INVALID)) { + if (scanning != priv->scanning) { + priv->scanning = scanning; + g_object_notify (G_OBJECT (info->interface), "scanning"); + } + } +} + +static void +wpas_iface_get_scanning (NMSupplicantInterface *self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanning", + iface_scanning_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); +} + +static void +wpas_iface_handle_scanning (DBusGProxy *proxy, + gboolean scanning, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + if (scanning != priv->scanning) { + priv->scanning = scanning; + g_object_notify (G_OBJECT (self), "scanning"); + } +} + +gboolean +nm_supplicant_interface_get_scanning (NMSupplicantInterface *self) +{ + NMSupplicantInterfacePrivate *priv; + + g_return_val_if_fail (self != NULL, FALSE); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + if (priv->scanning) + return TRUE; + if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING) + return TRUE; + return FALSE; +} + +static void +nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GError *err = NULL; + char *path = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_OBJECT_PATH, &path, + G_TYPE_INVALID)) { + + if (dbus_g_error_has_name (err, WPAS_ERROR_INVALID_IFACE)) { + /* Interface not added, try to add it */ + nm_supplicant_interface_add_to_supplicant (info->interface, FALSE); + } else if (dbus_g_error_has_name (err, WPAS_ERROR_EXISTS_ERROR)) { + /* Interface already added, just try to get the interface */ + nm_supplicant_interface_add_to_supplicant (info->interface, TRUE); + } else { + nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s", + priv->dev, err->message); + } + + g_error_free (err); + } else { + nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev); + + priv->object_path = path; + + priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + path, + WPAS_DBUS_IFACE_INTERFACE); + + dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID); + + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_add_signal (priv->iface_proxy, "StateChange", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable", + G_CALLBACK (wpas_iface_query_scan_results), + info->interface, + NULL); + + dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange", + G_CALLBACK (wpas_iface_handle_state_change), + info->interface, + NULL); + + dbus_g_proxy_add_signal (priv->iface_proxy, "Scanning", G_TYPE_BOOLEAN, G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (priv->iface_proxy, "Scanning", + G_CALLBACK (wpas_iface_handle_scanning), + info->interface, + NULL); + + /* Interface added to the supplicant; get its initial state. */ + wpas_iface_get_state (info->interface); + wpas_iface_get_scanning (info->interface); + } +} + +static void +nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self, + gboolean get_only) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxy *proxy; + DBusGProxyCall *call; + + proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + WPAS_DBUS_PATH, + WPAS_DBUS_INTERFACE); + info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); + + if (get_only) { + call = dbus_g_proxy_begin_call (proxy, "getInterface", + nm_supplicant_interface_add_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, priv->dev, + G_TYPE_INVALID); + } else { + GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + GValue *driver; + + driver = g_new0 (GValue, 1); + g_value_init (driver, G_TYPE_STRING); + g_value_set_string (driver, priv->is_wireless ? "wext" : "wired"); + g_hash_table_insert (hash, "driver", driver); + + call = dbus_g_proxy_begin_call (proxy, "addInterface", + nm_supplicant_interface_add_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, priv->dev, + DBUS_TYPE_G_MAP_OF_VARIANT, hash, + G_TYPE_INVALID); + + g_value_unset (driver); + g_free (driver); + g_hash_table_destroy (hash); + } + + g_object_unref (proxy); + + nm_supplicant_info_set_call (info, call); +} + +static void +nm_supplicant_interface_start (NMSupplicantInterface * self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + guint32 state; + + /* Can only start the interface from INIT state */ + g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT); + + nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev); + + state = nm_supplicant_manager_get_state (priv->smgr); + if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) { + nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING); + nm_supplicant_interface_add_to_supplicant (self, FALSE); + } else if (state == NM_SUPPLICANT_MANAGER_STATE_DOWN) { + /* Don't do anything; wait for signal from supplicant manager + * that its state has changed. + */ + } else + nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!"); +} + +static void +nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self) +{ + switch (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state) { + case NM_SUPPLICANT_INTERFACE_STATE_INIT: + /* Move to STARTING state when supplicant is ready */ + nm_supplicant_interface_start (self); + break; + case NM_SUPPLICANT_INTERFACE_STATE_STARTING: + /* Don't do anything here, though we should never hit this */ + break; + case NM_SUPPLICANT_INTERFACE_STATE_READY: + /* Don't do anything here, though we should never hit this */ + break; + case NM_SUPPLICANT_INTERFACE_STATE_DOWN: + /* Don't do anything here; interface can't get out of DOWN state */ + break; + default: + nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant interface state!"); + break; + } +} + + +static void +nm_supplicant_interface_set_state (NMSupplicantInterface * self, + guint32 new_state) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + guint32 old_state; + + g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST); + + if (new_state == priv->state) + return; + + old_state = priv->state; + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + /* If the interface is transitioning to DOWN and there's are + * in-progress pending calls, cancel them. + */ + cancel_all_callbacks (priv->other_pcalls); + cancel_all_callbacks (priv->assoc_pcalls); + } + + priv->state = new_state; + g_signal_emit (self, + nm_supplicant_interface_signals[STATE], + 0, + priv->state, + old_state); +} + +static void +nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr, + guint32 new_state, + guint32 old_state, + gpointer user_data) +{ + NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (user_data); + + switch (new_state) { + case NM_SUPPLICANT_MANAGER_STATE_DOWN: + /* The supplicant went away, likely the connection to it is also + * gone. Therefore, this interface must move to the DOWN state + * and be disposed of. + */ + nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN); + break; + case NM_SUPPLICANT_MANAGER_STATE_IDLE: + /* Handle the supplicant now being available. */ + nm_supplicant_interface_handle_supplicant_manager_idle_state (self); + break; + default: + nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!"); + break; + } +} + + +static void +remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + GError *err = NULL; + guint tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_dbg (LOGD_SUPPLICANT, "Couldn't remove network from supplicant interface: %s.", + err->message); + g_error_free (err); + } +} + +static void +disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + GError *err = NULL; + guint tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't disconnect supplicant interface: %s.", + err->message); + g_error_free (err); + } +} + +void +nm_supplicant_interface_disconnect (NMSupplicantInterface * self) +{ + NMSupplicantInterfacePrivate *priv; + + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self)); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + /* Clear and cancel all pending calls related to a prior + * connection attempt. + */ + cancel_all_callbacks (priv->assoc_pcalls); + + /* Don't do anything if there is no connection to the supplicant yet. */ + if (!priv->iface_proxy) + return; + + /* Don't try to disconnect if the supplicant interface is already + * disconnected. + */ + if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED + || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) { + if (priv->net_proxy) { + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; + } + + return; + } + + /* Remove any network that was added by NetworkManager */ + if (priv->net_proxy) { + dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork", + remove_network_cb, + NULL, NULL, + DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy), + G_TYPE_INVALID); + + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; + } + + dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect", + disconnect_cb, + NULL, NULL, + G_TYPE_INVALID); +} + +static void +select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't select network config: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } +} + +static void +set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GError *err = NULL; + guint tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network config: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } else { + DBusGProxyCall *call; + + info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "selectNetwork", + select_network_cb, + info, + nm_supplicant_info_destroy, + DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (proxy), + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + } +} + +static void +call_set_network (NMSupplicantInfo *info) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GHashTable *config_hash; + DBusGProxyCall *call; + + config_hash = nm_supplicant_config_get_hash (priv->cfg); + call = dbus_g_proxy_begin_call (priv->net_proxy, "set", + set_network_cb, + info, + nm_supplicant_info_destroy, + DBUS_TYPE_G_MAP_OF_VARIANT, config_hash, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + g_hash_table_destroy (config_hash); +} + +static void +set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GError *err = NULL; + guint tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } else { + info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); + call_set_network (info); + } +} + +static GValue * +byte_array_to_gvalue (const GByteArray *array) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_set_boxed (val, array); + + return val; +} + +static void +blob_free (GValue *val) +{ + g_value_unset (val); + g_slice_free (GValue, val); +} + +static void +convert_blob (const char *key, const GByteArray *value, GHashTable *hash) +{ + GValue *val; + + val = byte_array_to_gvalue (value); + g_hash_table_insert (hash, g_strdup (key), val); +} + +static void +call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + DBusGProxyCall *call; + GHashTable *blobs; + + blobs = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) blob_free); + if (!blobs) { + const char *msg = "Not enough memory to create blob table."; + + nm_log_warn (LOGD_SUPPLICANT, "%s", msg); + g_signal_emit (info->interface, + nm_supplicant_interface_signals[CONNECTION_ERROR], + 0, "SendBlobError", msg); + return; + } + + g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs); + + call = dbus_g_proxy_begin_call (priv->iface_proxy, "setBlobs", + set_blobs_cb, + info, + nm_supplicant_info_destroy, + DBUS_TYPE_G_MAP_OF_VARIANT, blobs, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + g_hash_table_destroy (blobs); +} + +static void +add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + char *path = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_OBJECT_PATH, &path, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.", + err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } else { + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GHashTable *blobs; + + priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + path, + WPAS_DBUS_IFACE_NETWORK); + g_free (path); + + info = nm_supplicant_info_new (info->interface, + priv->net_proxy, + priv->assoc_pcalls); + /* Send any blobs first; if there aren't any jump to sending the + * config settings. + */ + blobs = nm_supplicant_config_get_blobs (priv->cfg); + if (g_hash_table_size (blobs) > 0) + call_set_blobs (info, blobs); + else + call_set_network (info); + } +} + +static void +set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + GError *err = NULL; + guint32 tmp; + DBusGProxyCall *call; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Couldn't send AP scan mode to the supplicant interface: %s.", + err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + return; + } + + nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d", + nm_supplicant_config_get_ap_scan (priv->cfg)); + + info = nm_supplicant_info_new (info->interface, proxy, info->store); + call = dbus_g_proxy_begin_call (proxy, "addNetwork", + add_network_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); +} + +gboolean +nm_supplicant_interface_set_config (NMSupplicantInterface * self, + NMSupplicantConfig * cfg) +{ + NMSupplicantInterfacePrivate *priv; + NMSupplicantInfo *info; + DBusGProxyCall *call; + guint32 ap_scan; + + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + nm_supplicant_interface_disconnect (self); + + if (priv->cfg) + g_object_unref (priv->cfg); + priv->cfg = cfg; + + if (cfg == NULL) + return TRUE; + + g_object_ref (priv->cfg); + + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan", + set_ap_scan_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_UINT, ap_scan, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + + return call != NULL; +} + +const char * +nm_supplicant_interface_get_device (NMSupplicantInterface * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL); + + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev; +} + +static void +scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint32 success = 0; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + G_TYPE_UINT, &success, + G_TYPE_INVALID)) { + nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", err->message); + g_error_free (err); + } + + /* Notify listeners of the result of the scan */ + g_signal_emit (info->interface, + nm_supplicant_interface_signals[SCAN_REQ_RESULT], + 0, + success ? TRUE : FALSE); +} + +gboolean +nm_supplicant_interface_request_scan (NMSupplicantInterface * self) +{ + NMSupplicantInterfacePrivate *priv; + NMSupplicantInfo *info; + DBusGProxyCall *call; + + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan", + scan_request_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + + return call != NULL; +} + +guint32 +nm_supplicant_interface_get_state (NMSupplicantInterface * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_STATE_DOWN); + + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state; +} + +guint32 +nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED); + + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->con_state; +} + +const char * +nm_supplicant_interface_state_to_string (guint32 state) +{ + switch (state) { + case NM_SUPPLICANT_INTERFACE_STATE_INIT: + return "init"; + case NM_SUPPLICANT_INTERFACE_STATE_STARTING: + return "starting"; + case NM_SUPPLICANT_INTERFACE_STATE_READY: + return "ready"; + case NM_SUPPLICANT_INTERFACE_STATE_DOWN: + return "down"; + default: + break; + } + return "unknown"; +} + +const char * +nm_supplicant_interface_connection_state_to_string (guint32 state) +{ + switch (state) { + case NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED: + return "disconnected"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE: + return "inactive"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING: + return "scanning"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING: + return "associating"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED: + return "associated"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE: + return "4-way handshake"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE: + return "group handshake"; + case NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED: + return "completed"; + default: + break; + } + return "unknown"; +} + diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h new file mode 100644 index 00000000..bee5436f --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -0,0 +1,145 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef NM_SUPPLICANT_INTERFACE_H +#define NM_SUPPLICANT_INTERFACE_H + +#include <glib-object.h> +#include <dbus/dbus.h> +#include "nm-supplicant-types.h" + +G_BEGIN_DECLS + +/* + * Supplicant interface states + * The states are linear, ie INIT -> READY -> DOWN and state may only be + * changed in one direction. If an interface reaches the DOWN state, it + * cannot be re-initialized; it must be torn down and a new one created. + * + * INIT: interface has been created, but cannot be used yet; it is waiting + * for pending requests of the supplicant to complete. + * READY: interface is ready for use + * DOWN: interface has been removed or has otherwise been made invalid; it + * must be torn down. + * + * Note: LAST is an invalid state and only used for boundary checking. + */ +enum { + NM_SUPPLICANT_INTERFACE_STATE_INIT = 0, + NM_SUPPLICANT_INTERFACE_STATE_STARTING, + NM_SUPPLICANT_INTERFACE_STATE_READY, + NM_SUPPLICANT_INTERFACE_STATE_DOWN, + NM_SUPPLICANT_INTERFACE_STATE_LAST +}; + + +/* + * Supplicant interface connection states + * The wpa_supplicant state for the connection. + */ +enum { + NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED = 0, + NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE, + NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING, + NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING, + NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED, + NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE, + NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE, + NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED, + NM_SUPPLICANT_INTERFACE_CON_STATE_LAST +}; + +#define NM_TYPE_SUPPLICANT_INTERFACE (nm_supplicant_interface_get_type ()) +#define NM_SUPPLICANT_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterface)) +#define NM_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) +#define NM_IS_SUPPLICANT_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUPPLICANT_INTERFACE)) +#define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE)) +#define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) + +struct _NMSupplicantInterface { + GObject parent; +}; + +typedef struct { + GObjectClass parent; + + /* Signals */ + + /* change in the interface's state */ + void (*state) (NMSupplicantInterface * iface, + guint32 new_state, + guint32 old_state); + + /* interface was removed by the supplicant */ + void (*removed) (NMSupplicantInterface * iface); + + /* interface saw a new access point from a scan */ + void (*scanned_ap) (NMSupplicantInterface * iface, + DBusMessage * message); + + /* result of a wireless scan request */ + void (*scan_req_result) (NMSupplicantInterface * iface, + gboolean success); + + /* scan results returned from supplicant */ + void (*scan_results) (NMSupplicantInterface * iface, + guint num_bssids); + + /* link state of the device's connection */ + void (*connection_state) (NMSupplicantInterface * iface, + guint32 new_state, + guint32 old_state); + + /* an error occurred during a connection request */ + void (*connection_error) (NMSupplicantInterface * iface, + const char * name, + const char * message); +} NMSupplicantInterfaceClass; + + +GType nm_supplicant_interface_get_type (void); + +NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr, + const char *ifname, + gboolean is_wireless); + +gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, + NMSupplicantConfig * cfg); + +void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); + +const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface); + +gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self); + +guint32 nm_supplicant_interface_get_state (NMSupplicantInterface * self); + +guint32 nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self); + +const char *nm_supplicant_interface_state_to_string (guint32 state); + +const char *nm_supplicant_interface_connection_state_to_string (guint32 state); + +gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self); + +G_END_DECLS + +#endif /* NM_SUPPLICANT_INTERFACE_H */ diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c new file mode 100644 index 00000000..a2cf58eb --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -0,0 +1,343 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include <string.h> +#include <glib.h> +#include <dbus/dbus.h> + +#include "nm-supplicant-manager.h" +#include "nm-supplicant-interface.h" +#include "nm-dbus-manager.h" +#include "nm-marshal.h" +#include "nm-logging.h" +#include "nm-glib-compat.h" + +#define SUPPLICANT_POKE_INTERVAL 120 + +typedef struct { + NMDBusManager * dbus_mgr; + guint32 state; + GSList * ifaces; + gboolean dispose_has_run; + guint poke_id; +} NMSupplicantManagerPrivate; + +#define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SUPPLICANT_MANAGER, \ + NMSupplicantManagerPrivate)) + +G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT) + + +static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old, + const char *new, + gpointer user_data); + +static void nm_supplicant_manager_set_state (NMSupplicantManager * self, + guint32 new_state); + +static gboolean nm_supplicant_manager_startup (NMSupplicantManager * self); + + +/* Signals */ +enum { + STATE, /* change in the manager's state */ + LAST_SIGNAL +}; +static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 }; + + +NMSupplicantManager * +nm_supplicant_manager_get (void) +{ + static NMSupplicantManager * singleton = NULL; + + if (!singleton) { + singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL)); + } else { + g_object_ref (singleton); + } + + g_assert (singleton); + return singleton; +} + +static gboolean +poke_supplicant_cb (gpointer user_data) +{ + NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data); + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + DBusGConnection *g_connection; + DBusGProxy *proxy; + const char *tmp = "ignoreme"; + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + proxy = dbus_g_proxy_new_for_name (g_connection, + WPAS_DBUS_SERVICE, + WPAS_DBUS_PATH, + WPAS_DBUS_INTERFACE); + if (!proxy) { + nm_log_warn (LOGD_SUPPLICANT, "Error: could not init wpa_supplicant proxy"); + goto out; + } + + nm_log_info (LOGD_SUPPLICANT, "Trying to start the supplicant..."); + dbus_g_proxy_call_no_reply (proxy, "getInterface", G_TYPE_STRING, tmp, G_TYPE_INVALID); + g_object_unref (proxy); + +out: + /* Reschedule the poke */ + priv->poke_id = g_timeout_add_seconds (SUPPLICANT_POKE_INTERVAL, + poke_supplicant_cb, + (gpointer) self); + + return FALSE; +} + +static void +nm_supplicant_manager_init (NMSupplicantManager * self) +{ + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + gboolean running; + + priv->dispose_has_run = FALSE; + priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN; + priv->dbus_mgr = nm_dbus_manager_get (); + priv->poke_id = 0; + + running = nm_supplicant_manager_startup (self); + + g_signal_connect (priv->dbus_mgr, + "name-owner-changed", + G_CALLBACK (nm_supplicant_manager_name_owner_changed), + self); + + if (!running) { + /* Try to activate the supplicant */ + priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self); + } +} + +static void +nm_supplicant_manager_dispose (GObject *object) +{ + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object); + + if (priv->dispose_has_run) { + G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); + return; + } + + priv->dispose_has_run = TRUE; + + if (priv->poke_id) { + g_source_remove (priv->poke_id); + priv->poke_id = 0; + } + + if (priv->dbus_mgr) { + g_object_unref (G_OBJECT (priv->dbus_mgr)); + priv->dbus_mgr = NULL; + } + + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); +} + +static void +nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate)); + + object_class->dispose = nm_supplicant_manager_dispose; + + /* Signals */ + nm_supplicant_manager_signals[STATE] = + g_signal_new ("state", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantManagerClass, state), + NULL, NULL, + _nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); +} + +static void +nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMSupplicantManager * self = (NMSupplicantManager *) user_data; + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + gboolean old_owner_good = (old_owner && strlen (old_owner)); + gboolean new_owner_good = (new_owner && strlen (new_owner)); + + /* Can't handle the signal if its not from the supplicant service */ + if (strcmp (WPAS_DBUS_SERVICE, name) != 0) + return; + + if (!old_owner_good && new_owner_good) { + gboolean running; + + running = nm_supplicant_manager_startup (self); + + if (running && priv->poke_id) { + g_source_remove (priv->poke_id); + priv->poke_id = 0; + } + } else if (old_owner_good && !new_owner_good) { + nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_DOWN); + + if (priv->poke_id) + g_source_remove (priv->poke_id); + + /* Poke the supplicant so that it gets activated by dbus system bus + * activation. + */ + priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self); + } +} + + +guint32 +nm_supplicant_manager_get_state (NMSupplicantManager * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE); + + return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state; +} + +static void +nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state) +{ + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + guint32 old_state; + + if (new_state == priv->state) + return; + + old_state = priv->state; + priv->state = new_state; + g_signal_emit (self, + nm_supplicant_manager_signals[STATE], + 0, + priv->state, + old_state); +} + +static gboolean +nm_supplicant_manager_startup (NMSupplicantManager * self) +{ + gboolean running; + + /* FIXME: convert to pending call */ + running = nm_dbus_manager_name_has_owner (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->dbus_mgr, + WPAS_DBUS_SERVICE); + if (running) + nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE); + + return running; +} + +NMSupplicantInterface * +nm_supplicant_manager_get_iface (NMSupplicantManager * self, + const char *ifname, + gboolean is_wireless) +{ + NMSupplicantManagerPrivate *priv; + NMSupplicantInterface * iface = NULL; + GSList * elt; + + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); + g_return_val_if_fail (ifname != NULL, NULL); + + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + + /* Ensure we don't already have this interface */ + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { + NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; + + if (!strcmp (ifname, nm_supplicant_interface_get_device (if_tmp))) { + iface = if_tmp; + break; + } + } + + if (!iface) { + nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname); + iface = nm_supplicant_interface_new (self, ifname, is_wireless); + if (iface) + priv->ifaces = g_slist_append (priv->ifaces, iface); + } else { + nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname); + } + + return iface; +} + +void +nm_supplicant_manager_release_iface (NMSupplicantManager * self, + NMSupplicantInterface * iface) +{ + NMSupplicantManagerPrivate *priv; + GSList * elt; + + g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface)); + + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { + NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; + + if (if_tmp == iface) { + /* Remove the iface from the supplicant manager's list and + * dereference to match additional reference in get_iface. + */ + priv->ifaces = g_slist_remove_link (priv->ifaces, elt); + g_slist_free_1 (elt); + g_object_unref (iface); + break; + } + } +} + +const char * +nm_supplicant_manager_state_to_string (guint32 state) +{ + switch (state) { + case NM_SUPPLICANT_MANAGER_STATE_DOWN: + return "down"; + case NM_SUPPLICANT_MANAGER_STATE_IDLE: + return "idle"; + default: + break; + } + return "unknown"; +} + + diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h new file mode 100644 index 00000000..fef2a774 --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -0,0 +1,88 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef NM_SUPPLICANT_MANAGER_H +#define NM_SUPPLICANT_MANAGER_H + +#include <glib-object.h> +#include "nm-supplicant-types.h" +#include "nm-device.h" + +#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant" +#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant" +#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant" + + +G_BEGIN_DECLS + +/* + * Supplicant manager states + * Either state may transition to the other state at any time. + * + * DOWN: supplicant manager has been created, but cannot be used; the supplicant + * is either not running or has not yet been fully initialized. + * IDLE: supplicant manager is ready for use + * + * Note: LAST is an invalid state and only used for boundary checking. + */ +enum { + NM_SUPPLICANT_MANAGER_STATE_DOWN = 0, + NM_SUPPLICANT_MANAGER_STATE_IDLE, + NM_SUPPLICANT_MANAGER_STATE_LAST +}; + + +#define NM_TYPE_SUPPLICANT_MANAGER (nm_supplicant_manager_get_type ()) +#define NM_SUPPLICANT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManager)) +#define NM_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass)) +#define NM_IS_SUPPLICANT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUPPLICANT_MANAGER)) +#define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER)) +#define NM_SUPPLICANT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass)) + +struct _NMSupplicantManager +{ + GObject parent; +}; + +typedef struct +{ + GObjectClass parent; + + /* class members */ + void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state); +} NMSupplicantManagerClass; + +GType nm_supplicant_manager_get_type (void); + +NMSupplicantManager * nm_supplicant_manager_get (void); + +guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr); + +NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr, + const char *ifname, + gboolean is_wireless); + +void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr, + NMSupplicantInterface * iface); + +const char *nm_supplicant_manager_state_to_string (guint32 state); + +#endif /* NM_SUPPLICANT_MANAGER_H */ diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.c b/src/supplicant-manager/nm-supplicant-settings-verify.c new file mode 100644 index 00000000..28334655 --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-settings-verify.c @@ -0,0 +1,238 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + */ + +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "nm-supplicant-settings-verify.h" + +struct Opt { + const char * key; + const OptType type; + const gint32 int_low; /* Inclusive */ + const gint32 int_high; /* Inclusive; max length for strings */ + const gboolean str_allowed_multiple; + const char ** str_allowed; +}; + + +static gboolean validate_type_int (const struct Opt * opt, + const char * value, + const guint32 len); + +static gboolean validate_type_bytes (const struct Opt * opt, + const char * value, + const guint32 len); + +static gboolean validate_type_keyword (const struct Opt * opt, + const char * value, + const guint32 len); + +typedef gboolean (*validate_func)(const struct Opt *, const char *, const guint32); + +struct validate_entry { + const OptType type; + const validate_func func; +}; + +static const struct validate_entry validate_table[] = { + { TYPE_INT, validate_type_int }, + { TYPE_BYTES, validate_type_bytes }, + { TYPE_KEYWORD, validate_type_keyword }, +}; + + +const char * pairwise_allowed[] = { "CCMP", "TKIP", "NONE", NULL }; +const char * group_allowed[] = { "CCMP", "TKIP", "WEP104", "WEP40", NULL }; +const char * proto_allowed[] = { "WPA", "RSN", NULL }; +const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE", + "NONE", NULL }; +const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL }; +const char * eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM", + "PSK", "FAST", NULL }; + +const char * phase1_allowed[] = {"peapver=0", "peapver=1", "peaplabel=1", + "peap_outer_success=0", "include_tls_length=1", + "sim_min_num_chal=3", NULL }; +const char * phase2_allowed[] = {"auth=PAP", "auth=CHAP", "auth=MSCHAP", + "auth=MSCHAPV2", "auth=GTC", "auth=OTP", + "auth=MD5", "auth=TLS", "autheap=MD5", + "autheap=MSCHAPV2", "autheap=OTP", + "autheap=GTC", "autheap=TLS", NULL }; + +static const struct Opt opt_table[] = { + { "ssid", TYPE_BYTES, 0, 32,FALSE, NULL }, + { "bssid", TYPE_KEYWORD, 0, 0, FALSE, NULL }, + { "scan_ssid", TYPE_INT, 0, 1, FALSE, NULL }, + { "mode", TYPE_INT, 0, 1, FALSE, NULL }, + { "frequency", TYPE_INT, 2412, 5825, FALSE, NULL }, + { "auth_alg", TYPE_KEYWORD, 0, 0, FALSE, auth_alg_allowed }, + { "psk", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "pairwise", TYPE_KEYWORD, 0, 0, FALSE, pairwise_allowed }, + { "group", TYPE_KEYWORD, 0, 0, FALSE, group_allowed }, + { "proto", TYPE_KEYWORD, 0, 0, FALSE, proto_allowed }, + { "key_mgmt", TYPE_KEYWORD, 0, 0, FALSE, key_mgmt_allowed }, + { "wep_key0", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "wep_key1", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "wep_key2", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "wep_key3", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "wep_tx_keyidx", TYPE_INT, 0, 3, FALSE, NULL }, + { "eapol_flags", TYPE_INT, 0, 3, FALSE, NULL }, + { "eap", TYPE_KEYWORD, 0, 0, FALSE, eap_allowed }, + { "identity", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "password", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "ca_path", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "ca_cert", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "client_cert", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "private_key", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "private_key_passwd", TYPE_BYTES, 0, 1024, FALSE, NULL }, + { "phase1", TYPE_KEYWORD, 0, 0, TRUE, phase1_allowed }, + { "phase2", TYPE_KEYWORD, 0, 0, TRUE, phase2_allowed }, + { "anonymous_identity", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "ca_path2", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "ca_cert2", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "client_cert2", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "private_key2", TYPE_BYTES, 0, 65536, FALSE, NULL }, + { "private_key2_passwd",TYPE_BYTES, 0, 1024, FALSE, NULL }, + { "pin", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "pcsc", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "nai", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "eappsk", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "pac_file", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "engine", TYPE_INT, 0, 1, FALSE, NULL }, + { "engine_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "key_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "fragment_size", TYPE_INT, 1, 2000, FALSE, NULL }, +}; + + +static gboolean +validate_type_int (const struct Opt * opt, + const char * value, + const guint32 len) +{ + long int intval; + + g_return_val_if_fail (opt != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + errno = 0; + intval = strtol (value, NULL, 10); + if (errno != 0) + return FALSE; + + /* strtol returns a long, but we are dealing with ints */ + if (intval > INT_MAX || intval < INT_MIN) + return FALSE; + if (intval > opt->int_high || intval < opt->int_low) + return FALSE; + + return TRUE; +} + +static gboolean +validate_type_bytes (const struct Opt * opt, + const char * value, + const guint32 len) +{ + guint32 check_len; + + g_return_val_if_fail (opt != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + check_len = opt->int_high ? opt->int_high : 255; + if (len > check_len) + return FALSE; + + return TRUE; +} + +static gboolean +validate_type_keyword (const struct Opt * opt, + const char * value, + const guint32 len) +{ + char ** allowed; + gchar ** candidates = NULL; + char ** candidate; + gboolean found = FALSE; + + g_return_val_if_fail (opt != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + /* Allow everything */ + if (!opt->str_allowed) + return TRUE; + + candidates = g_strsplit (value, " ", 0); + if (!candidates) + goto out; + + /* validate each space-separated word in 'value' */ + for (candidate = candidates; *candidate; candidate++) { + found = FALSE; + for (allowed = (char **) opt->str_allowed; *allowed; allowed++) { + if (strcmp (*candidate, *allowed) == 0) { + found = TRUE; + break; + } + } + if (!found) + break; + } + +out: + g_strfreev (candidates); + return found; +} + +OptType +nm_supplicant_settings_verify_setting (const char * key, + const char * value, + const guint32 len) +{ + OptType type = TYPE_INVALID; + int opt_count = sizeof (opt_table) / sizeof (opt_table[0]); + int val_count = sizeof (validate_table) / sizeof (validate_table[0]); + int i, j; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + for (i = 0; i < opt_count; i++) { + if (strcmp (opt_table[i].key, key) != 0) + continue; + + for (j = 0; j < val_count; j++) { + if (validate_table[j].type == opt_table[i].type) { + if ((*(validate_table[j].func))(&opt_table[i], value, len)) { + type = opt_table[i].type; + break; + } + } + } + } + + return type; +} + diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.h b/src/supplicant-manager/nm-supplicant-settings-verify.h new file mode 100644 index 00000000..0939ebdb --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-settings-verify.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + */ + +#ifndef NM_SUPPLICANT_SETTINGS_VERIFY_H +#define NM_SUPPLICANT_SETTINGS_VERIFY_H + +typedef enum OptType { + TYPE_INVALID = 0, + TYPE_INT, + TYPE_BYTES, + TYPE_KEYWORD, + TYPE_STRING +} OptType; + +OptType nm_supplicant_settings_verify_setting (const char * key, + const char * value, + const guint32 len); + + +#endif /* NM_SUPPLICANT_SETTINGS_VERIFY_H */ diff --git a/src/supplicant-manager/nm-supplicant-types.h b/src/supplicant-manager/nm-supplicant-types.h new file mode 100644 index 00000000..16e4a6ba --- /dev/null +++ b/src/supplicant-manager/nm-supplicant-types.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2008 Red Hat, Inc. + */ + +#ifndef NM_SUPPLICANT_TYPES_H +#define NM_SUPPLICANT_TYPES_H + +typedef struct _NMSupplicantManager NMSupplicantManager; +typedef struct _NMSupplicantInterface NMSupplicantInterface; +typedef struct _NMSupplicantConfig NMSupplicantConfig; + +#endif /* NM_SUPPLICANT_TYPES_H */ diff --git a/src/supplicant-manager/tests/Makefile.am b/src/supplicant-manager/tests/Makefile.am new file mode 100644 index 00000000..b5e4db61 --- /dev/null +++ b/src/supplicant-manager/tests/Makefile.am @@ -0,0 +1,27 @@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/supplicant-manager + +noinst_PROGRAMS = test-supplicant-config + +test_supplicant_config_SOURCES = \ + test-supplicant-config.c + +test_supplicant_config_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_supplicant_config_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/supplicant-manager/libsupplicant-manager.la \ + $(DBUS_LIBS) + +if WITH_TESTS + +check-local: test-supplicant-config + $(abs_builddir)/test-supplicant-config + +endif + diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in new file mode 100644 index 00000000..f919b8b8 --- /dev/null +++ b/src/supplicant-manager/tests/Makefile.in @@ -0,0 +1,579 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-supplicant-config$(EXEEXT) +subdir = src/supplicant-manager/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)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_supplicant_config_OBJECTS = \ + test_supplicant_config-test-supplicant-config.$(OBJEXT) +test_supplicant_config_OBJECTS = $(am_test_supplicant_config_OBJECTS) +am__DEPENDENCIES_1 = +test_supplicant_config_DEPENDENCIES = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/supplicant-manager/libsupplicant-manager.la \ + $(am__DEPENDENCIES_1) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(test_supplicant_config_SOURCES) +DIST_SOURCES = $(test_supplicant_config_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +IPTABLES_PATH = @IPTABLES_PATH@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBM = @LIBM@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +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@ +RANLIB = @RANLIB@ +RESOLVCONF_PATH = @RESOLVCONF_PATH@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_BASE_DIR = @UDEV_BASE_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/supplicant-manager + +test_supplicant_config_SOURCES = \ + test-supplicant-config.c + +test_supplicant_config_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_supplicant_config_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/supplicant-manager/libsupplicant-manager.la \ + $(DBUS_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/supplicant-manager/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/supplicant-manager/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test-supplicant-config$(EXEEXT): $(test_supplicant_config_OBJECTS) $(test_supplicant_config_DEPENDENCIES) + @rm -f test-supplicant-config$(EXEEXT) + $(LINK) $(test_supplicant_config_OBJECTS) $(test_supplicant_config_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_supplicant_config-test-supplicant-config.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test_supplicant_config-test-supplicant-config.o: test-supplicant-config.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_supplicant_config-test-supplicant-config.o -MD -MP -MF $(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o test_supplicant_config-test-supplicant-config.o `test -f 'test-supplicant-config.c' || echo '$(srcdir)/'`test-supplicant-config.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo $(DEPDIR)/test_supplicant_config-test-supplicant-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-supplicant-config.c' object='test_supplicant_config-test-supplicant-config.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_supplicant_config-test-supplicant-config.o `test -f 'test-supplicant-config.c' || echo '$(srcdir)/'`test-supplicant-config.c + +test_supplicant_config-test-supplicant-config.obj: test-supplicant-config.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_supplicant_config-test-supplicant-config.obj -MD -MP -MF $(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o test_supplicant_config-test-supplicant-config.obj `if test -f 'test-supplicant-config.c'; then $(CYGPATH_W) 'test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/test-supplicant-config.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo $(DEPDIR)/test_supplicant_config-test-supplicant-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-supplicant-config.c' object='test_supplicant_config-test-supplicant-config.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_supplicant_config-test-supplicant-config.obj `if test -f 'test-supplicant-config.c'; then $(CYGPATH_W) 'test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/test-supplicant-config.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@WITH_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +@WITH_TESTS_TRUE@check-local: test-supplicant-config +@WITH_TESTS_TRUE@ $(abs_builddir)/test-supplicant-config + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c new file mode 100644 index 00000000..d0868b5f --- /dev/null +++ b/src/supplicant-manager/tests/test-supplicant-config.c @@ -0,0 +1,518 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2009 Red Hat, Inc. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <netinet/ether.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <dbus/dbus-glib.h> + +#include <nm-utils.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> +#include <nm-setting-ip4-config.h> +#include <nm-setting-8021x.h> + +#include "nm-test-helpers.h" + +#include "nm-supplicant-config.h" +#include "nm-supplicant-settings-verify.h" + +static gboolean +validate_opt (const char *detail, + GHashTable *hash, + const char *key, + OptType val_type, + gconstpointer expected, + size_t expected_len) +{ + GValue *value; + gint int_val; + GByteArray *array; + const char *s; + const unsigned char *expected_array = expected; + int result; + + ASSERT (hash != NULL, detail, "hash was NULL"); + + value = g_hash_table_lookup (hash, key); + ASSERT (value != NULL, + detail, "option '%s' expected but not found in config hash."); + + switch (val_type) { + case TYPE_INT: + ASSERT (G_VALUE_HOLDS_INT (value), + detail, "config hash item '%s' was not TYPE_INT.", key); + int_val = g_value_get_int (value); + ASSERT (int_val == GPOINTER_TO_INT (expected), + detail, "unexpected config hash item '%s' value %d (expected %d)", + key, int_val, GPOINTER_TO_INT (expected)); + break; + case TYPE_BYTES: + ASSERT (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY), + detail, "config hash item '%s' was not TYPE_BYTES.", key); + array = g_value_get_boxed (value); + ASSERT (array->len == expected_len, + detail, "unexpected config hash item '%s' length %d (expected %d)", + key, array->len, expected_len); + result = memcmp (array->data, expected_array, expected_len); + ASSERT (result == 0, detail, "unexpected config hash item '%s' value", key); + break; + case TYPE_KEYWORD: + case TYPE_STRING: + ASSERT (G_VALUE_HOLDS_STRING (value), + detail, "config hash item '%s' was not TYPE_STRING or TYPE_KEYWORD.", key); + if (expected_len == -1) + expected_len = strlen ((const char *) expected); + s = g_value_get_string (value); + ASSERT (s != NULL, detail, "unexpected NULL config hash string item '%s'.", key); + ASSERT (strlen (s) == expected_len, + detail, "unexpected config hash string item '%s' length %d (expected %d)", + key, strlen (s), expected_len); + result = strcmp (s, (const char *) expected); + ASSERT (result == 0, + detail, "unexpected config hash string item '%s' value '%s' (expected '%s')", + key, s, (const char *) expected); + break; + default: + g_warning ("unknown supplicant config hash item '%s' option type %d", + key, val_type); + return FALSE; + } + + return TRUE; +} + +static void +test_wifi_open (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingIP4Config *s_ip4; + NMSupplicantConfig *config; + GHashTable *hash; + char *uuid; + gboolean success; + GError *error = NULL; + GByteArray *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + GByteArray *bssid; + const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + const char *bssid_str = "11:22:33:44:55:66"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wifi-open", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wifi-open", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Wifi Open", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + "wifi-open", "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + bssid = g_byte_array_sized_new (sizeof (bssid_data)); + g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_BAND, "bg", + NULL); + + g_byte_array_free (ssid, TRUE); + g_byte_array_free (bssid, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wifi-open", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wifi-open", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + config = nm_supplicant_config_new (); + ASSERT (config != NULL, + "wifi-open", "failed to create new supplicant config"); + + success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); + ASSERT (success == TRUE, + "wifi-open", "failed to add wireless setting to supplicant config."); + + success = nm_supplicant_config_add_no_security (config); + ASSERT (success == TRUE, + "wifi-open", "failed to add wireless security to supplicant config."); + + hash = nm_supplicant_config_get_hash (config); + ASSERT (hash != NULL, + "wifi-open", "failed to hash supplicant config options."); + + validate_opt ("wifi-open", hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1); + validate_opt ("wifi-open", hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data)); + validate_opt ("wifi-open", hash, "bssid", TYPE_KEYWORD, bssid_str, -1); + validate_opt ("wifi-open", hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1); + + g_object_unref (connection); +} + +static void +test_wifi_wep_key (const char *detail, + NMWepKeyType wep_type, + const char *key_data, + const unsigned char *expected, + size_t expected_size) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSupplicantConfig *config; + GHashTable *hash; + char *uuid; + gboolean success; + GError *error = NULL; + GByteArray *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + GByteArray *bssid; + const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + const char *bssid_str = "11:22:33:44:55:66"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + detail, "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Wifi WEP Key", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + bssid = g_byte_array_sized_new (sizeof (bssid_data)); + g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_BAND, "bg", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + g_byte_array_free (bssid, TRUE); + + /* Wifi Security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, wep_type, + NULL); + nm_setting_wireless_security_set_wep_key (s_wsec, 0, key_data); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + config = nm_supplicant_config_new (); + ASSERT (config != NULL, + detail, "failed to create new supplicant config"); + + success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); + ASSERT (success == TRUE, + detail, "failed to add wireless setting to supplicant config."); + + success = nm_supplicant_config_add_setting_wireless_security (config, + s_wsec, + NULL, + "376aced7-b28c-46be-9a62-fcdf072571da"); + ASSERT (success == TRUE, + detail, "failed to add wireless security to supplicant config."); + + hash = nm_supplicant_config_get_hash (config); + ASSERT (hash != NULL, + detail, "failed to hash supplicant config options."); + + validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1); + validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data)); + validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1); + validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1); + validate_opt (detail, hash, "wep_tx_keyidx", TYPE_INT, GINT_TO_POINTER (0), -1); + validate_opt (detail, hash, "wep_key0", TYPE_BYTES, expected, expected_size); + + g_object_unref (connection); +} + +static void +test_wifi_wep (void) +{ + const char *key1 = "12345"; + const unsigned char key1_expected[] = { 0x31, 0x32, 0x33, 0x34, 0x35 }; + const char *key2 = "ascii test$$$"; + const unsigned char key2_expected[] = { 0x61, 0x73, 0x63, 0x69, 0x69, 0x20, 0x74, 0x65, 0x73, 0x74, 0x24, 0x24, 0x24 }; + const char *key3 = "abcdef1234"; + const unsigned char key3_expected[] = { 0xab, 0xcd, 0xef, 0x12, 0x34 }; + const char *key4 = "96aec785c6392675f87f592972"; + const unsigned char key4_expected[] = { 0x96, 0xae, 0xc7, 0x85, 0xc6, 0x39, 0x26, 0x75, 0xf8, 0x7f, 0x59, 0x29, 0x72 }; + const char *key5 = "r34lly l33t w3p p4ssphr4s3 for t3st1ng"; + const unsigned char key5_expected[] = { 0xce, 0x68, 0x8b, 0x35, 0xf6, 0x0a, 0x2b, 0xbf, 0xc9, 0x8f, 0xed, 0x10, 0xda }; + + test_wifi_wep_key ("wifi-wep-ascii-40", NM_WEP_KEY_TYPE_KEY, key1, key1_expected, sizeof (key1_expected)); + test_wifi_wep_key ("wifi-wep-ascii-104", NM_WEP_KEY_TYPE_KEY, key2, key2_expected, sizeof (key2_expected)); + test_wifi_wep_key ("wifi-wep-hex-40", NM_WEP_KEY_TYPE_KEY, key3, key3_expected, sizeof (key3_expected)); + test_wifi_wep_key ("wifi-wep-hex-104", NM_WEP_KEY_TYPE_KEY, key4, key4_expected, sizeof (key4_expected)); + test_wifi_wep_key ("wifi-wep-passphrase-104", NM_WEP_KEY_TYPE_PASSPHRASE, key5, key5_expected, sizeof (key5_expected)); + + test_wifi_wep_key ("wifi-wep-old-hex-104", NM_WEP_KEY_TYPE_UNKNOWN, key4, key4_expected, sizeof (key4_expected)); +} + +static void +test_wifi_wpa_psk (const char *detail, + OptType key_type, + const char *key_data, + const unsigned char *expected, + size_t expected_size) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIP4Config *s_ip4; + NMSupplicantConfig *config; + GHashTable *hash; + char *uuid; + gboolean success; + GError *error = NULL; + GByteArray *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + GByteArray *bssid; + const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + const char *bssid_str = "11:22:33:44:55:66"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + detail, "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Wifi WEP Key", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + ASSERT (s_wifi != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (ssid_data)); + g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + bssid = g_byte_array_sized_new (sizeof (bssid_data)); + g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_BAND, "bg", + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + + g_byte_array_free (ssid, TRUE); + g_byte_array_free (bssid, TRUE); + + /* Wifi Security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, key_data, + NULL); + + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + detail, "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + config = nm_supplicant_config_new (); + ASSERT (config != NULL, + detail, "failed to create new supplicant config"); + + success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); + ASSERT (success == TRUE, + detail, "failed to add wireless setting to supplicant config."); + + success = nm_supplicant_config_add_setting_wireless_security (config, + s_wsec, + NULL, + "376aced7-b28c-46be-9a62-fcdf072571da"); + ASSERT (success == TRUE, + detail, "failed to add wireless security to supplicant config."); + + hash = nm_supplicant_config_get_hash (config); + ASSERT (hash != NULL, + detail, "failed to hash supplicant config options."); + + validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1); + validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data)); + validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1); + validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "WPA-PSK", -1); + validate_opt (detail, hash, "proto", TYPE_KEYWORD, "WPA RSN", -1); + validate_opt (detail, hash, "pairwise", TYPE_KEYWORD, "TKIP CCMP", -1); + validate_opt (detail, hash, "group", TYPE_KEYWORD, "TKIP CCMP", -1); + validate_opt (detail, hash, "psk", key_type, expected, expected_size); + + g_object_unref (connection); +} + +static void +test_wifi_wpa_psk_types (void) +{ + const char *key1 = "d4721e911461d3cdef9793858e977fcda091779243abb7316c2f11605a160893"; + const unsigned char key1_expected[] = { 0xd4, 0x72, 0x1e, 0x91, 0x14, 0x61, 0xd3, 0xcd, + 0xef, 0x97, 0x93, 0x85, 0x8e, 0x97, 0x7f, 0xcd, + 0xa0, 0x91, 0x77, 0x92, 0x43, 0xab, 0xb7, 0x31, + 0x6c, 0x2f, 0x11, 0x60, 0x5a, 0x16, 0x08, 0x93 }; + const char *key2 = "r34lly l33t wp4 p4ssphr4s3 for t3st1ng"; + + test_wifi_wpa_psk ("wifi-wpa-psk-hex", TYPE_BYTES, key1, key1_expected, sizeof (key1_expected)); + test_wifi_wpa_psk ("wifi-wep-psk-passphrase", TYPE_STRING, key2, (gconstpointer) key2, strlen (key2)); +} + +int main (int argc, char **argv) +{ + GError *error = NULL; + DBusGConnection *bus; + char *base; + + g_type_init (); + bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + + if (!nm_utils_init (&error)) + FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + + /* The tests */ + test_wifi_open (); + test_wifi_wep (); + test_wifi_wpa_psk_types (); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + |