From 85df09c7a65dab7c54e1e35b0685f8677355710c Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 26 Sep 2011 22:20:52 +0200 Subject: New upstream version 3.2.0 --- src/Makefile.am | 10 +- src/Makefile.in | 79 +-- src/ka-applet-priv.h | 4 +- src/ka-applet.c | 260 +++++---- src/ka-dbus.c | 45 +- src/ka-dialog.c | 1138 --------------------------------------- src/ka-dialog.h | 32 -- src/ka-kerberos.c | 1114 ++++++++++++++++++++++++++++++++++++++ src/ka-kerberos.h | 35 ++ src/ka-main-window.c | 193 +++++++ src/ka-main-window.h | 42 ++ src/ka-preferences.c | 689 ++++++++++++++++++++++++ src/ka-preferences.h | 21 + src/ka-pwdialog.c | 2 +- src/ka-tickets.c | 116 ---- src/ka-tickets.h | 39 -- src/ka-tools.c | 28 + src/ka-tools.h | 1 + src/krb5-auth-dialog.desktop.in | 1 - src/krb5-auth-dialog.ui | 998 +++++++++++++++++++++++++++++++--- 20 files changed, 3296 insertions(+), 1551 deletions(-) delete mode 100644 src/ka-dialog.c delete mode 100644 src/ka-dialog.h create mode 100644 src/ka-kerberos.c create mode 100644 src/ka-kerberos.h create mode 100644 src/ka-main-window.c create mode 100644 src/ka-main-window.h create mode 100644 src/ka-preferences.c create mode 100644 src/ka-preferences.h delete mode 100644 src/ka-tickets.c delete mode 100644 src/ka-tickets.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 65d2a92..9c22dcf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,8 +25,8 @@ $(service_DATA): $(service_in_files) Makefile sed -e "s|\@BINDIR\@|$(bindir)|" $< > $@ krb5_auth_dialog_SOURCES = \ - ka-dialog.c \ - ka-dialog.h \ + ka-kerberos.c \ + ka-kerberos.h \ ka-applet.c \ ka-applet-priv.h \ ka-applet.h \ @@ -40,12 +40,14 @@ krb5_auth_dialog_SOURCES = \ ka-dbus.h \ ka-tools.c \ ka-tools.h \ - ka-tickets.c \ - ka-tickets.h \ + ka-main-window.c \ + ka-main-window.h \ ka-plugin.c \ ka-plugin.h \ ka-plugin-loader.c \ ka-plugin-loader.h \ + ka-preferences.c \ + ka-preferences.h \ ka-closures.h \ ka-closures.c \ ka-entry-buffer.h \ diff --git a/src/Makefile.in b/src/Makefile.in index b67314b..f4a24be 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -54,16 +54,17 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(servicedir)" PROGRAMS = $(bin_PROGRAMS) am__objects_1 = -am_krb5_auth_dialog_OBJECTS = krb5_auth_dialog-ka-dialog.$(OBJEXT) \ +am_krb5_auth_dialog_OBJECTS = krb5_auth_dialog-ka-kerberos.$(OBJEXT) \ krb5_auth_dialog-ka-applet.$(OBJEXT) \ krb5_auth_dialog-ka-pwdialog.$(OBJEXT) \ krb5_auth_dialog-ka-gconf.$(OBJEXT) \ krb5_auth_dialog-ka-gconf-tools.$(OBJEXT) \ krb5_auth_dialog-ka-dbus.$(OBJEXT) \ krb5_auth_dialog-ka-tools.$(OBJEXT) \ - krb5_auth_dialog-ka-tickets.$(OBJEXT) \ + krb5_auth_dialog-ka-main-window.$(OBJEXT) \ krb5_auth_dialog-ka-plugin.$(OBJEXT) \ krb5_auth_dialog-ka-plugin-loader.$(OBJEXT) \ + krb5_auth_dialog-ka-preferences.$(OBJEXT) \ krb5_auth_dialog-ka-closures.$(OBJEXT) \ krb5_auth_dialog-ka-entry-buffer.$(OBJEXT) \ krb5_auth_dialog-dummy-strings.$(OBJEXT) $(am__objects_1) @@ -155,8 +156,6 @@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMPILER_FLAGS = @COMPILER_FLAGS@ -CONTROL_CENTER_CFLAGS = @CONTROL_CENTER_CFLAGS@ -CONTROL_CENTER_LIBS = @CONTROL_CENTER_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -244,7 +243,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_LIBS = @PAM_LIBS@ -PANELS_DIR = @PANELS_DIR@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ @@ -336,8 +334,8 @@ servicedir = $(datadir)/dbus-1/services service_in_files = org.gnome.KrbAuthDialog.service.in service_DATA = $(service_in_files:.service.in=.service) krb5_auth_dialog_SOURCES = \ - ka-dialog.c \ - ka-dialog.h \ + ka-kerberos.c \ + ka-kerberos.h \ ka-applet.c \ ka-applet-priv.h \ ka-applet.h \ @@ -351,12 +349,14 @@ krb5_auth_dialog_SOURCES = \ ka-dbus.h \ ka-tools.c \ ka-tools.h \ - ka-tickets.c \ - ka-tickets.h \ + ka-main-window.c \ + ka-main-window.h \ ka-plugin.c \ ka-plugin.h \ ka-plugin-loader.c \ ka-plugin-loader.h \ + ka-preferences.c \ + ka-preferences.h \ ka-closures.h \ ka-closures.c \ ka-entry-buffer.h \ @@ -512,14 +512,15 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-applet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-closures.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-dbus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-dialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-entry-buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-gconf-tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-gconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-kerberos.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-main-window.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-plugin-loader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-plugin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-preferences.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-pwdialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-tickets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth_dialog-ka-tools.Po@am__quote@ .c.o: @@ -546,21 +547,21 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< -krb5_auth_dialog-ka-dialog.o: ka-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-dialog.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-dialog.Tpo -c -o krb5_auth_dialog-ka-dialog.o `test -f 'ka-dialog.c' || echo '$(srcdir)/'`ka-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-dialog.Tpo $(DEPDIR)/krb5_auth_dialog-ka-dialog.Po +krb5_auth_dialog-ka-kerberos.o: ka-kerberos.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-kerberos.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Tpo -c -o krb5_auth_dialog-ka-kerberos.o `test -f 'ka-kerberos.c' || echo '$(srcdir)/'`ka-kerberos.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Tpo $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-dialog.c' object='krb5_auth_dialog-ka-dialog.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-kerberos.c' object='krb5_auth_dialog-ka-kerberos.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-dialog.o `test -f 'ka-dialog.c' || echo '$(srcdir)/'`ka-dialog.c +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-kerberos.o `test -f 'ka-kerberos.c' || echo '$(srcdir)/'`ka-kerberos.c -krb5_auth_dialog-ka-dialog.obj: ka-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-dialog.obj -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-dialog.Tpo -c -o krb5_auth_dialog-ka-dialog.obj `if test -f 'ka-dialog.c'; then $(CYGPATH_W) 'ka-dialog.c'; else $(CYGPATH_W) '$(srcdir)/ka-dialog.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-dialog.Tpo $(DEPDIR)/krb5_auth_dialog-ka-dialog.Po +krb5_auth_dialog-ka-kerberos.obj: ka-kerberos.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-kerberos.obj -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Tpo -c -o krb5_auth_dialog-ka-kerberos.obj `if test -f 'ka-kerberos.c'; then $(CYGPATH_W) 'ka-kerberos.c'; else $(CYGPATH_W) '$(srcdir)/ka-kerberos.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Tpo $(DEPDIR)/krb5_auth_dialog-ka-kerberos.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-dialog.c' object='krb5_auth_dialog-ka-dialog.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-kerberos.c' object='krb5_auth_dialog-ka-kerberos.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-dialog.obj `if test -f 'ka-dialog.c'; then $(CYGPATH_W) 'ka-dialog.c'; else $(CYGPATH_W) '$(srcdir)/ka-dialog.c'; fi` +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-kerberos.obj `if test -f 'ka-kerberos.c'; then $(CYGPATH_W) 'ka-kerberos.c'; else $(CYGPATH_W) '$(srcdir)/ka-kerberos.c'; fi` krb5_auth_dialog-ka-applet.o: ka-applet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-applet.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-applet.Tpo -c -o krb5_auth_dialog-ka-applet.o `test -f 'ka-applet.c' || echo '$(srcdir)/'`ka-applet.c @@ -658,21 +659,21 @@ krb5_auth_dialog-ka-tools.obj: ka-tools.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-tools.obj `if test -f 'ka-tools.c'; then $(CYGPATH_W) 'ka-tools.c'; else $(CYGPATH_W) '$(srcdir)/ka-tools.c'; fi` -krb5_auth_dialog-ka-tickets.o: ka-tickets.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-tickets.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-tickets.Tpo -c -o krb5_auth_dialog-ka-tickets.o `test -f 'ka-tickets.c' || echo '$(srcdir)/'`ka-tickets.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-tickets.Tpo $(DEPDIR)/krb5_auth_dialog-ka-tickets.Po +krb5_auth_dialog-ka-main-window.o: ka-main-window.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-main-window.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-main-window.Tpo -c -o krb5_auth_dialog-ka-main-window.o `test -f 'ka-main-window.c' || echo '$(srcdir)/'`ka-main-window.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-main-window.Tpo $(DEPDIR)/krb5_auth_dialog-ka-main-window.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-tickets.c' object='krb5_auth_dialog-ka-tickets.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-main-window.c' object='krb5_auth_dialog-ka-main-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-tickets.o `test -f 'ka-tickets.c' || echo '$(srcdir)/'`ka-tickets.c +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-main-window.o `test -f 'ka-main-window.c' || echo '$(srcdir)/'`ka-main-window.c -krb5_auth_dialog-ka-tickets.obj: ka-tickets.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-tickets.obj -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-tickets.Tpo -c -o krb5_auth_dialog-ka-tickets.obj `if test -f 'ka-tickets.c'; then $(CYGPATH_W) 'ka-tickets.c'; else $(CYGPATH_W) '$(srcdir)/ka-tickets.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-tickets.Tpo $(DEPDIR)/krb5_auth_dialog-ka-tickets.Po +krb5_auth_dialog-ka-main-window.obj: ka-main-window.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-main-window.obj -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-main-window.Tpo -c -o krb5_auth_dialog-ka-main-window.obj `if test -f 'ka-main-window.c'; then $(CYGPATH_W) 'ka-main-window.c'; else $(CYGPATH_W) '$(srcdir)/ka-main-window.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-main-window.Tpo $(DEPDIR)/krb5_auth_dialog-ka-main-window.Po @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-tickets.c' object='krb5_auth_dialog-ka-tickets.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-main-window.c' object='krb5_auth_dialog-ka-main-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-tickets.obj `if test -f 'ka-tickets.c'; then $(CYGPATH_W) 'ka-tickets.c'; else $(CYGPATH_W) '$(srcdir)/ka-tickets.c'; fi` +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-main-window.obj `if test -f 'ka-main-window.c'; then $(CYGPATH_W) 'ka-main-window.c'; else $(CYGPATH_W) '$(srcdir)/ka-main-window.c'; fi` krb5_auth_dialog-ka-plugin.o: ka-plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-plugin.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-plugin.Tpo -c -o krb5_auth_dialog-ka-plugin.o `test -f 'ka-plugin.c' || echo '$(srcdir)/'`ka-plugin.c @@ -706,6 +707,22 @@ krb5_auth_dialog-ka-plugin-loader.obj: ka-plugin-loader.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-plugin-loader.obj `if test -f 'ka-plugin-loader.c'; then $(CYGPATH_W) 'ka-plugin-loader.c'; else $(CYGPATH_W) '$(srcdir)/ka-plugin-loader.c'; fi` +krb5_auth_dialog-ka-preferences.o: ka-preferences.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-preferences.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-preferences.Tpo -c -o krb5_auth_dialog-ka-preferences.o `test -f 'ka-preferences.c' || echo '$(srcdir)/'`ka-preferences.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-preferences.Tpo $(DEPDIR)/krb5_auth_dialog-ka-preferences.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-preferences.c' object='krb5_auth_dialog-ka-preferences.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-preferences.o `test -f 'ka-preferences.c' || echo '$(srcdir)/'`ka-preferences.c + +krb5_auth_dialog-ka-preferences.obj: ka-preferences.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-preferences.obj -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-preferences.Tpo -c -o krb5_auth_dialog-ka-preferences.obj `if test -f 'ka-preferences.c'; then $(CYGPATH_W) 'ka-preferences.c'; else $(CYGPATH_W) '$(srcdir)/ka-preferences.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-preferences.Tpo $(DEPDIR)/krb5_auth_dialog-ka-preferences.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ka-preferences.c' object='krb5_auth_dialog-ka-preferences.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -c -o krb5_auth_dialog-ka-preferences.obj `if test -f 'ka-preferences.c'; then $(CYGPATH_W) 'ka-preferences.c'; else $(CYGPATH_W) '$(srcdir)/ka-preferences.c'; fi` + krb5_auth_dialog-ka-closures.o: ka-closures.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(krb5_auth_dialog_CPPFLAGS) $(CPPFLAGS) $(krb5_auth_dialog_CFLAGS) $(CFLAGS) -MT krb5_auth_dialog-ka-closures.o -MD -MP -MF $(DEPDIR)/krb5_auth_dialog-ka-closures.Tpo -c -o krb5_auth_dialog-ka-closures.o `test -f 'ka-closures.c' || echo '$(srcdir)/'`ka-closures.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/krb5_auth_dialog-ka-closures.Tpo $(DEPDIR)/krb5_auth_dialog-ka-closures.Po diff --git a/src/ka-applet-priv.h b/src/ka-applet-priv.h index bd55996..d571230 100644 --- a/src/ka-applet-priv.h +++ b/src/ka-applet-priv.h @@ -34,11 +34,13 @@ G_BEGIN_DECLS #define KA_NAME _("Kerberos Authentication") + /* signals emitted by KaApplet */ - typedef enum { +typedef enum { KA_SIGNAL_ACQUIRED_TGT, /* New TGT acquired */ KA_SIGNAL_RENEWED_TGT, /* TGT got renewed */ KA_SIGNAL_EXPIRED_TGT, /* TGT expired or ticket cache got destroyed */ + KA_CCACHE_CHANGED, /* The credential cache changed */ KA_SIGNAL_COUNT } KaAppletSignalNumber; diff --git a/src/ka-applet.c b/src/ka-applet.c index 441ed94..f1fffbf 100644 --- a/src/ka-applet.c +++ b/src/ka-applet.c @@ -23,12 +23,14 @@ #include #include "ka-applet-priv.h" -#include "ka-dialog.h" +#include "ka-dbus.h" +#include "ka-kerberos.h" #include "ka-gconf-tools.h" #include "ka-gconf.h" #include "ka-tools.h" -#include "ka-tickets.h" +#include "ka-main-window.h" #include "ka-plugin-loader.h" +#include "ka-preferences.h" #include "ka-closures.h" #include @@ -56,22 +58,23 @@ const gchar *ka_signal_names[KA_SIGNAL_COUNT] = { "krb-tgt-acquired", "krb-tgt-renewed", "krb-tgt-expired", + "krb-ccache-changed", }; struct _KaApplet { - GObject parent; + GtkApplication parent; KaAppletPrivate *priv; }; struct _KaAppletClass { - GObjectClass parent; + GtkApplicationClass parent; guint signals[KA_SIGNAL_COUNT]; }; -G_DEFINE_TYPE (KaApplet, ka_applet, G_TYPE_OBJECT); +G_DEFINE_TYPE (KaApplet, ka_applet, GTK_TYPE_APPLICATION); struct _KaAppletPrivate { GtkBuilder *uixml; @@ -84,6 +87,11 @@ struct _KaAppletPrivate { int pw_prompt_secs; /* when to start sending notifications */ KaPluginLoader *loader; /* Plugin loader */ + /* command line handling */ + gboolean startup_ccache; /* ccache found on startup */ + gboolean auto_run; /* only start with valid ccache */ + + /* GConf optins */ NotifyNotification *notification; /* notification messages */ char *krb_msg; /* Additional banner delivered by Kerberos */ const char *notify_gconf_key; /* disable notification gconf key */ @@ -98,7 +106,96 @@ struct _KaAppletPrivate { GConfClient *gconf; /* gconf client */ }; + static void ka_close_notification (KaApplet *self); +static gboolean is_initialized; + +static void +ka_applet_activate (GApplication *application G_GNUC_UNUSED) +{ + if (is_initialized) { + KA_DEBUG ("Main window activated"); + ka_main_window_show (); + } else + is_initialized = TRUE; +} + + +static int +ka_applet_command_line (GApplication *application, + GApplicationCommandLine *cmdline G_GNUC_UNUSED) +{ + KaApplet *self = KA_APPLET(application); + KA_DEBUG ("Evaluating command line"); + + if (!self->priv->startup_ccache && + self->priv->auto_run) + ka_applet_destroy (self); + else + ka_applet_activate (application); + return 0; +} + + + +static gint +ka_applet_local_command_line (GApplication *application, + gchar ***argv, + gint *exit_status) +{ + KaApplet *self = KA_APPLET(application); + GOptionContext *context; + GError *error = NULL; + + gint argc = g_strv_length (*argv); + gboolean auto_run = FALSE; + + const char *help_msg = + "Run '" PACKAGE + " --help' to see a full list of available command line options"; + const GOptionEntry options[] = { + {"auto", 'a', 0, G_OPTION_ARG_NONE, &auto_run, + "Only run if an initialized ccache is found", NULL}, + {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL} + }; + + KA_DEBUG ("Parsing local command line"); + + context = g_option_context_new ("- Kerberos 5 credential checking"); + g_option_context_add_main_entries (context, options, NULL); + g_option_context_add_group (context, gtk_get_option_group (TRUE)); + g_option_context_parse (context, &argc, argv, &error); + + if (error) { + g_print ("%s\n%s\n", error->message, help_msg); + g_clear_error (&error); + *exit_status = 1; + } else { + self->priv->auto_run = auto_run; + *exit_status = 0; + } + + g_option_context_free (context); + return FALSE; +} + +static void +ka_applet_startup (GApplication *application) +{ + KaApplet *self = KA_APPLET (application); + GtkWindow *main_window; + + KA_DEBUG ("Primary application"); + + self->priv->startup_ccache = ka_kerberos_init (self); + if (!ka_dbus_connect (self)) { + ka_applet_destroy (self); + } + + main_window = ka_main_window_create (self, self->priv->uixml); + gtk_application_add_window (GTK_APPLICATION(self), main_window); + ka_preferences_window_create (self, self->priv->uixml); +} static void ka_applet_set_property (GObject *object, @@ -266,6 +363,11 @@ ka_applet_class_init (KaAppletClass *klass) object_class->finalize = ka_applet_finalize; g_type_class_add_private (klass, sizeof (KaAppletPrivate)); + G_APPLICATION_CLASS (klass)->local_command_line = \ + ka_applet_local_command_line; + G_APPLICATION_CLASS (klass)->command_line = ka_applet_command_line; + G_APPLICATION_CLASS (klass)->startup = ka_applet_startup; + object_class->set_property = ka_applet_set_property; object_class->get_property = ka_applet_get_property; @@ -318,8 +420,7 @@ ka_applet_class_init (KaAppletClass *klass) G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (object_class, KA_PROP_TGT_RENEWABLE, pspec); - - for (i = 0; i < KA_SIGNAL_COUNT; i++) { + for (i=0; i < KA_SIGNAL_COUNT-1; i++) { guint signalId; signalId = g_signal_new (ka_signal_names[i], G_OBJECT_CLASS_TYPE (klass), @@ -329,13 +430,21 @@ ka_applet_class_init (KaAppletClass *klass) G_TYPE_STRING, G_TYPE_UINT); klass->signals[i] = signalId; } + klass->signals[KA_CCACHE_CHANGED] = g_signal_new ( + ka_signal_names[KA_CCACHE_CHANGED], + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static KaApplet * ka_applet_new (void) { - return g_object_new (KA_TYPE_APPLET, NULL); + return g_object_new (KA_TYPE_APPLET, + "application-id", "org.gnome.KrbAuthDialog", + NULL); } @@ -456,8 +565,8 @@ ka_notify_ticket_action_cb (NotifyNotification *notification G_GNUC_UNUSED, KA_DEBUG ("Removing ccache"); ka_destroy_ccache (self); } else if (strcmp (action, "ka-list-tickets") == 0) { - KA_DEBUG ("Listing tickets"); - ka_tickets_dialog_run (); + KA_DEBUG ("Showing main window"); + ka_main_window_show (); } else { g_warning ("unkonwn action for callback"); } @@ -680,37 +789,10 @@ ka_applet_menu_add_separator_item (GtkWidget *menu) gtk_widget_show (menu_item); } -static void -ka_applet_cb_preferences (GtkWidget *menuitem G_GNUC_UNUSED, - gpointer user_data G_GNUC_UNUSED) -{ - GError *error = NULL; - - g_spawn_command_line_async (BIN_DIR - G_DIR_SEPARATOR_S - "gnome-control-center ka-panel", &error); - if (error) { - GtkWidget *message_dialog; - - message_dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("There was an error launching the preferences dialog: %s"), - error->message); - gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE); - - g_signal_connect (message_dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show (message_dialog); - g_clear_error (&error); - } -} - /* Free all resources and quit */ static void -ka_applet_cb_quit (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data) +ka_applet_quit_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data) { KaApplet *applet = KA_APPLET (user_data); @@ -719,36 +801,7 @@ ka_applet_cb_quit (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data) static void -ka_applet_cb_about_dialog (GtkMenuItem *menuitem G_GNUC_UNUSED, - gpointer user_data G_GNUC_UNUSED) -{ - const gchar *authors[] = { - "Christopher Aillon ", - "Jonathan Blandford ", - "Colin Walters ", - "Guido Günther ", - NULL - }; - - gtk_show_about_dialog (NULL, - "authors", authors, - "version", VERSION, - "logo-icon-name", "krb-valid-ticket", - "copyright", - "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n" - "2008-2011 Guido Günther", - "website-label", PACKAGE " website", - "website", - "https://honk.sigxcpu.org/piki/projects/krb5-auth-dialog/", - "license", "GNU General Public License Version 2", - /* Translators: add the translators of your language here */ - "translator-credits", _("translator-credits"), - NULL); -} - - -static void -ka_applet_cb_show_help (GtkMenuItem *menuitem G_GNUC_UNUSED, +ka_applet_show_help_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data) { KaApplet *applet = KA_APPLET (user_data); @@ -759,7 +812,7 @@ ka_applet_cb_show_help (GtkMenuItem *menuitem G_GNUC_UNUSED, static void -ka_applet_cb_destroy_ccache (GtkMenuItem *menuitem G_GNUC_UNUSED, +ka_applet_destroy_ccache_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data) { KaApplet *applet = KA_APPLET (user_data); @@ -768,10 +821,10 @@ ka_applet_cb_destroy_ccache (GtkMenuItem *menuitem G_GNUC_UNUSED, } static void -ka_applet_cb_show_tickets (GtkMenuItem *menuitem G_GNUC_UNUSED, +ka_applet_show_tickets_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED) { - ka_tickets_dialog_run (); + ka_main_window_show (); } @@ -789,7 +842,7 @@ ka_applet_create_context_menu (KaApplet *applet) menu_item = gtk_image_menu_item_new_with_mnemonic (_("Remove Credentials _Cache")); g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_destroy_ccache), applet); + G_CALLBACK (ka_applet_destroy_ccache_cb), applet); image = gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); @@ -799,26 +852,13 @@ ka_applet_create_context_menu (KaApplet *applet) /* Ticket dialog */ menu_item = gtk_image_menu_item_new_with_mnemonic (_("_List Tickets")); g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_show_tickets), applet); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - - /* Preferences */ - menu_item = - gtk_image_menu_item_new_from_stock (GTK_STOCK_PREFERENCES, NULL); - g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_preferences), applet); + G_CALLBACK (ka_applet_show_tickets_cb), applet); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - /* About item */ + /* Help item */ menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_HELP, NULL); g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_show_help), applet); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - - /* About item */ - menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_ABOUT, NULL); - g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_about_dialog), applet); + G_CALLBACK (ka_applet_show_help_cb), applet); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); ka_applet_menu_add_separator_item (menu); @@ -826,7 +866,7 @@ ka_applet_create_context_menu (KaApplet *applet) /* Quit */ menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, NULL); g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (ka_applet_cb_quit), applet); + G_CALLBACK (ka_applet_quit_cb), applet); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); gtk_widget_show_all (menu); @@ -984,12 +1024,21 @@ ka_ns_check_persistence (KaApplet *self) } -/* destroy the applet and quit */ +/* undo what was done on startup() */ void -ka_applet_destroy (KaApplet* applet) +ka_applet_destroy (KaApplet* self) { - g_object_unref (applet); - gtk_main_quit (); + GList *windows, *first; + + ka_dbus_disconnect (); + windows = gtk_application_get_windows (GTK_APPLICATION(self)); + if (windows) { + first = g_list_first (windows); + gtk_application_remove_window(GTK_APPLICATION (self), + GTK_WINDOW (first->data)); + } + + ka_kerberos_destroy (); } @@ -1020,19 +1069,42 @@ ka_applet_create () g_assert (error->message); g_error ("Failed to load UI XML: %s", error->message); } + gtk_builder_connect_signals (applet->priv->uixml, NULL); + applet->priv->pwdialog = ka_pwdialog_create (applet->priv->uixml); g_return_val_if_fail (applet->priv->pwdialog != NULL, NULL); applet->priv->gconf = ka_gconf_init (applet); g_return_val_if_fail (applet->priv->gconf != NULL, NULL); - ka_tickets_dialog_create (applet->priv->uixml); applet->priv->loader = ka_plugin_loader_create (applet); g_return_val_if_fail (applet->priv->loader != NULL, NULL); return applet; } +int +main (int argc, char *argv[]) +{ + KaApplet *applet; + int ret = 0; + + textdomain (PACKAGE); + bind_textdomain_codeset (PACKAGE, "UTF-8"); + bindtextdomain (PACKAGE, LOCALE_DIR); + + g_set_application_name (KA_NAME); + + gtk_init (&argc, &argv); + applet = ka_applet_create (); + if (!applet) + return 1; + + ret = g_application_run (G_APPLICATION(applet), argc, argv); + g_object_unref (applet); + return ret; +} + /* * vim:ts:sts=4:sw=4:et: */ diff --git a/src/ka-dbus.c b/src/ka-dbus.c index a79f85f..2b84adc 100644 --- a/src/ka-dbus.c +++ b/src/ka-dbus.c @@ -21,10 +21,9 @@ #include "config.h" #include "ka-applet-priv.h" -#include "ka-dialog.h" +#include "ka-kerberos.h" #include "ka-dbus.h" -static guint dbus_owner_id; static GDBusConnection *dbus_connection; static const char *dbus_object_path = "/org/gnome/KrbAuthDialog"; static const char *dbus_interface_name = "org.gnome.KrbAuthDialog"; @@ -156,7 +155,7 @@ ka_dbus_connect_signals(KaApplet *applet) { int i; - for (i = 0; i < KA_SIGNAL_COUNT; i++) { + for (i = 0; i < KA_SIGNAL_COUNT-1; i++) { g_signal_connect (applet, ka_signal_names[i], G_CALLBACK (ka_dbus_signal_cb), (gpointer)ka_signal_names[i]); @@ -171,18 +170,19 @@ static const GDBusInterfaceVTable interface_vtable = static void -ka_dbus_on_bus_acquired (GDBusConnection *connection, - const gchar *name G_GNUC_UNUSED, - gpointer user_data) +ka_dbus_on_get_bus_cb (GObject *source_object G_GNUC_UNUSED, + GAsyncResult *res, + gpointer user_data) { KaApplet *applet = user_data; guint id; + dbus_connection = g_bus_get_finish (res, NULL); introspection_data = g_dbus_node_info_new_for_xml ( ka_dbus_introspection_xml, NULL); - id = g_dbus_connection_register_object (connection, + id = g_dbus_connection_register_object (dbus_connection, "/org/gnome/KrbAuthDialog", introspection_data->interfaces[0], &interface_vtable, @@ -190,22 +190,8 @@ ka_dbus_on_bus_acquired (GDBusConnection *connection, NULL, /* user_data_free_func */ NULL); /* GError** */ if (!id) - g_error ("Failed to regiester DBus object"); + g_error ("Failed to register DBus object"); ka_dbus_connect_signals (applet); - - dbus_connection = connection; -} - - -static void -ka_dbus_on_name_lost (GDBusConnection *connection G_GNUC_UNUSED, - const gchar *name G_GNUC_UNUSED, - gpointer user_data) -{ - KaApplet *applet = user_data; - - g_warning ("Cannot acquire DBUS name"); - ka_applet_destroy (applet); } @@ -217,10 +203,6 @@ ka_dbus_disconnect () introspection_data = NULL; } - if (dbus_owner_id) { - g_bus_unown_name (dbus_owner_id); - dbus_owner_id = 0; - } dbus_connection = NULL; } @@ -230,17 +212,12 @@ ka_dbus_connect (KaApplet *applet) { g_return_val_if_fail (applet != 0, FALSE); - dbus_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, - "org.gnome.KrbAuthDialog", - G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, - ka_dbus_on_bus_acquired, - NULL, - ka_dbus_on_name_lost, - applet, - NULL); + g_bus_get (G_BUS_TYPE_SESSION, NULL, ka_dbus_on_get_bus_cb, + applet); return TRUE; } /* * vim:ts=4:sts=4:sw=4:et: */ + diff --git a/src/ka-dialog.c b/src/ka-dialog.c deleted file mode 100644 index fffd2fd..0000000 --- a/src/ka-dialog.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * Copyright (C) 2004,2005,2006 Red Hat, Inc. - * Authored by Christopher Aillon - * - * Copyright (C) 2008,2009,2010 Guido Guenther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "secmem-util.h" -#include "memory.h" - -#include "ka-dialog.h" -#include "ka-applet-priv.h" -#include "ka-pwdialog.h" -#include "ka-dbus.h" -#include "ka-tools.h" -#include "ka-tickets.h" - -#ifdef ENABLE_NETWORK_MANAGER -#include - -#if !defined(NM_CHECK_VERSION) -#define NM_CHECK_VERSION(x,y,z) 0 -#endif -#endif - -#ifdef HAVE_HX509_ERR_H -#include -#endif - -static krb5_context kcontext; -static krb5_principal kprincipal; -static krb5_timestamp creds_expiry; -static krb5_timestamp canceled_creds_expiry; -static gboolean canceled; -static gboolean invalid_auth; -static gboolean always_run; -static gboolean is_online = TRUE; - -static int grab_credentials (KaApplet *applet); -static int ka_renew_credentials (KaApplet *applet); -static gboolean ka_get_tgt_from_ccache (krb5_context context, - krb5_creds *creds); - -#ifdef ENABLE_NETWORK_MANAGER -NMClient *nm_client; -#endif - -/* YAY for different Kerberos implementations */ -static int -get_cred_forwardable (krb5_creds *creds) -{ -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_FORWARDABLE) - return creds->ticket_flags & TKT_FLG_FORWARDABLE; -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_FORWARDABLE) - return creds->flags.b.forwardable; -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_FORWARDABLE) - return creds->flags & KDC_OPT_FORWARDABLE; -#endif -} - -static int -get_cred_renewable (krb5_creds *creds) -{ -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_RENEWABLE) - return creds->ticket_flags & TKT_FLG_RENEWABLE; -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_RENEWABLE) - return creds->flags.b.renewable; -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_RENEWABLE) - return creds->flags & KDC_OPT_RENEWABLE; -#endif -} - -static krb5_error_code -get_renewed_creds (krb5_context context, - krb5_creds *creds, - krb5_principal client, - krb5_ccache ccache, char *in_tkt_service) -{ -#ifdef HAVE_KRB5_GET_RENEWED_CREDS - return krb5_get_renewed_creds (context, creds, client, ccache, - in_tkt_service); -#else - return 1; /* XXX is there something better to return? */ -#endif -} - -static int -get_cred_proxiable (krb5_creds *creds) -{ -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_PROXIABLE) - return creds->ticket_flags & TKT_FLG_PROXIABLE; -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_PROXIABLE) - return creds->flags.b.proxiable; -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_PROXIABLE) - return creds->flags & KDC_OPT_PROXIABLE; -#endif -} - -static size_t -get_principal_realm_length (krb5_principal p) -{ -#if defined(HAVE_KRB5_PRINCIPAL_REALM_AS_STRING) - return strlen (p->realm); -#elif defined(HAVE_KRB5_PRINCIPAL_REALM_AS_DATA) - return p->realm.length; -#endif -} - -static const char * -get_principal_realm_data (krb5_principal p) -{ -#if defined(HAVE_KRB5_PRINCIPAL_REALM_AS_STRING) - return p->realm; -#elif defined(HAVE_KRB5_PRINCIPAL_REALM_AS_DATA) - return p->realm.data; -#endif -} - -static void -ka_krb5_free_error_message (krb5_context context, const char *msg) -{ -#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE) - krb5_free_error_message (context, msg); -#elif defined(HAVE_KRB5_FREE_ERROR_STRING) - krb5_free_error_string (context, (char *) msg); -#else -# error No way to free error string. -#endif -} - -/* - * Returns a descriptive error message or kerberos related error - * returned pointer must be freed using g_free(). - */ -static char * -ka_get_error_message (krb5_context context, krb5_error_code err) -{ - char *msg = NULL; - -#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) - const char *krberr; - - krberr = krb5_get_error_message (context, err); - msg = g_strdup (krberr); - ka_krb5_free_error_message (context, krberr); -#else -# error No detailed error message information -#endif - if (msg == NULL) - msg = g_strdup (_("unknown error")); - return msg; -} - - -static void -ka_krb5_cc_clear_mcred (krb5_creds *mcred) -{ -#if defined HAVE_KRB5_CC_CLEAR_MCRED - krb5_cc_clear_mcred (mcred); -#else - memset (mcred, 0, sizeof (krb5_creds)); -#endif -} - - -/* ***************************************************************** */ -/* ***************************************************************** */ - -/* log a kerberos error messge */ -static void -ka_log_error_message (const char *prefix, krb5_context context, - krb5_error_code err) -{ - char *errmsg = ka_get_error_message (context, err); - - g_warning ("%s: %s", prefix, errmsg); - g_free (errmsg); -} - - -static gboolean -credentials_expiring_real (KaApplet *applet) -{ - krb5_creds my_creds; - krb5_timestamp now; - gboolean retval = FALSE; - - memset (&my_creds, 0, sizeof (my_creds)); - ka_applet_set_tgt_renewable (applet, FALSE); - if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) { - creds_expiry = 0; - retval = TRUE; - goto out; - } - - /* copy principal from cache if any */ - if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { - krb5_free_principal (kcontext, kprincipal); - krb5_copy_principal (kcontext, my_creds.client, &kprincipal); - } - creds_expiry = my_creds.times.endtime; - if ((krb5_timeofday (kcontext, &now) == 0) && - (now + ka_applet_get_pw_prompt_secs (applet) > - my_creds.times.endtime)) - retval = TRUE; - - /* If our creds are expiring, determine whether they are renewable. - * If the expiry is already at the renew_till time, don't consider - * credentials renewable */ - if (retval && get_cred_renewable (&my_creds) - && my_creds.times.renew_till > now - && my_creds.times.renew_till > creds_expiry) { - ka_applet_set_tgt_renewable (applet, TRUE); - } - - out: - krb5_free_cred_contents (kcontext, &my_creds); - ka_applet_update_status (applet, creds_expiry); - return retval; -} - - -/* time in seconds the tgt will be still valid */ -int -ka_tgt_valid_seconds () -{ - krb5_timestamp now; - - if (krb5_timeofday (kcontext, &now)) - return 0; - - return (creds_expiry - now); -} - - -/* return credential cache filename, strip "FILE:" prefix if necessary */ -static const char * -ka_ccache_filename (void) -{ - const gchar *name; - - name = krb5_cc_default_name (kcontext); - if (g_str_has_prefix (name, "FILE:")) - return strchr (name, ':') + 1; - else if (g_str_has_prefix (name, "SCC:")) - g_warning ("Cannot monitor sqlite based cache '%s'", name); - else - g_warning ("Unsupported cache type for '%s'", name); - return NULL; -} - - -static void -ka_format_time (time_t t, gchar *ts, size_t len) -{ - g_strlcpy (ts, ctime (&t) + 4, len); - ts[15] = 0; -} - - -/* fill in service tickets data */ -gboolean -ka_get_service_tickets (GtkListStore * tickets) -{ - krb5_cc_cursor cursor; - krb5_creds creds; - krb5_error_code ret; - GtkTreeIter iter; - krb5_ccache ccache; - char *name; - krb5_timestamp sec; - gchar start_time[128], end_time[128], end_time_markup[256]; - gboolean retval = FALSE; - - gtk_list_store_clear (tickets); - - krb5_timeofday (kcontext, &sec); - ret = krb5_cc_default (kcontext, &ccache); - g_return_val_if_fail (!ret, FALSE); - - ret = krb5_cc_start_seq_get (kcontext, ccache, &cursor); - if (ret) { - ka_log_error_message ("krb5_cc_start_seq_get", kcontext, ret); - - /* if the file doesn't exist, it's not an error if we can't - * parse it */ - if (!g_file_test (ka_ccache_filename (), G_FILE_TEST_EXISTS)) - gtk_list_store_append (tickets, &iter); - gtk_list_store_set (tickets, &iter, - PRINCIPAL_COLUMN, _("Your ticket cache is currently empty"), - START_TIME_COLUMN, 0, - END_TIME_COLUMN, 0, - FORWARDABLE_COLUMN, FALSE, - RENEWABLE_COLUMN, FALSE, - PROXIABLE_COLUMN, FALSE, -1); - retval = TRUE; - goto out; - } - - while ((ret = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { - gboolean renewable, proxiable, forwardable; - - if (creds.times.starttime) - ka_format_time (creds.times.starttime, start_time, - sizeof (start_time)); - else - ka_format_time (creds.times.authtime, start_time, - sizeof (start_time)); - - ka_format_time (creds.times.endtime, end_time, sizeof (end_time)); - if (creds.times.endtime > sec) - strcpy (end_time_markup, end_time); - else - g_snprintf (end_time_markup, sizeof (end_time_markup), - "%s (%s)", - end_time, _("Expired")); - - forwardable = get_cred_forwardable (&creds); - renewable = get_cred_renewable (&creds); - proxiable = get_cred_proxiable (&creds); - - ret = krb5_unparse_name (kcontext, creds.server, &name); - if (!ret) { - gtk_list_store_append (tickets, &iter); - gtk_list_store_set (tickets, &iter, - PRINCIPAL_COLUMN, name, - START_TIME_COLUMN, start_time, - END_TIME_COLUMN, end_time_markup, - FORWARDABLE_COLUMN, forwardable, - RENEWABLE_COLUMN, renewable, - PROXIABLE_COLUMN, proxiable, -1); - free (name); - } else - ka_log_error_message ("krb5_unparse_name", kcontext, ret); - krb5_free_cred_contents (kcontext, &creds); - } - if (ret != KRB5_CC_END) - ka_log_error_message ("krb5_cc_get_next", kcontext, ret); - - ret = krb5_cc_end_seq_get (kcontext, ccache, &cursor); - if (ret) - ka_log_error_message ("krb5_cc_end_seq_get", kcontext, ret); - - retval = TRUE; - out: - ret = krb5_cc_close (kcontext, ccache); - g_return_val_if_fail (!ret, FALSE); - - return retval; -} - - -/* Check for things we have to do while the password dialog is open */ -static gboolean -krb5_auth_dialog_do_updates (gpointer data) -{ - KaApplet *applet = KA_APPLET (data); - KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); - - g_return_val_if_fail (pwdialog != NULL, FALSE); - /* Update creds_expiry and close the applet if we got the creds by other means (e.g. kinit) */ - if (!credentials_expiring_real (applet)) - ka_pwdialog_hide (pwdialog, FALSE); - - /* Update the expiry information in the dialog */ - ka_pwdialog_status_update (pwdialog); - return TRUE; -} - - -static krb5_error_code -auth_dialog_prompter (krb5_context ctx G_GNUC_UNUSED, - void *data, - const char *name G_GNUC_UNUSED, - const char *banner G_GNUC_UNUSED, - int num_prompts, krb5_prompt prompts[]) -{ - KaApplet *applet = KA_APPLET (data); - KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); - krb5_error_code errcode; - int i; - - errcode = KRB5KRB_ERR_GENERIC; - canceled = FALSE; - canceled_creds_expiry = 0; - - if (banner && !num_prompts) - ka_applet_set_msg (applet, banner); - - for (i = 0; i < num_prompts; i++) { - const gchar *password = NULL; - int password_len = 0; - int response; - guint32 source_id; - - errcode = KRB5_LIBOS_CANTREADPWD; - - source_id = - g_timeout_add_seconds (5, - (GSourceFunc) krb5_auth_dialog_do_updates, - applet); - ka_pwdialog_setup (pwdialog, (gchar *) prompts[i].prompt, - invalid_auth); - response = ka_pwdialog_run (pwdialog); - switch (response) { - case GTK_RESPONSE_OK: - password = ka_pwdialog_get_password (pwdialog); - password_len = strlen (password); - break; - case GTK_RESPONSE_DELETE_EVENT: - case GTK_RESPONSE_CANCEL: - canceled = TRUE; - break; - case GTK_RESPONSE_NONE: - break; - default: - g_warning ("Unknown Response: %d", response); - g_assert_not_reached (); - } - g_source_remove (source_id); - - if (!password) - goto cleanup; - if (password_len + 1 > prompts[i].reply->length) { - g_warning ("Password too long %d/%d", password_len + 1, - prompts[i].reply->length); - goto cleanup; - } - - memcpy (prompts[i].reply->data, (char *) password, password_len + 1); - prompts[i].reply->length = password_len; - errcode = 0; - } - cleanup: - ka_pwdialog_hide (pwdialog, TRUE); - /* Reset this, so we know the next time we get a TRUE value, it is accurate. */ - invalid_auth = FALSE; - - return errcode; -} - - -#ifdef ENABLE_NETWORK_MANAGER -static void -ka_nm_client_state_changed_cb (NMClient * client, - GParamSpec *pspec G_GNUC_UNUSED, gpointer data) -{ - NMState state; - gboolean *online = (gboolean *) data; - - state = nm_client_get_state (client); - switch (state) { - case NM_STATE_UNKNOWN: - case NM_STATE_ASLEEP: - case NM_STATE_CONNECTING: - KA_DEBUG ("Network state: %d", state); - /* do nothing */ - break; -#if NM_CHECK_VERSION(0,8,992) - case NM_STATE_DISCONNECTING: -#endif - case NM_STATE_DISCONNECTED: - KA_DEBUG ("Network disconnected"); - *online = FALSE; - break; -#if NM_CHECK_VERSION(0,8,992) - case NM_STATE_CONNECTED_LOCAL: - case NM_STATE_CONNECTED_SITE: - case NM_STATE_CONNECTED_GLOBAL: -#else - case NM_STATE_CONNECTED: -#endif - KA_DEBUG ("Network connected"); - *online = TRUE; - break; - } -} -#endif - -/* credentials expiring timer */ -static gboolean -credentials_expiring (gpointer *data) -{ - KaApplet *applet = KA_APPLET (data); - - KA_DEBUG ("Checking expiry <%ds", ka_applet_get_pw_prompt_secs (applet)); - if (credentials_expiring_real (applet) && is_online) { - KA_DEBUG ("Expiry @ %ld", creds_expiry); - - if (!ka_renew_credentials (applet)) - KA_DEBUG ("Credentials renewed"); - } - ka_applet_update_status (applet, creds_expiry); - - return TRUE; -} - - -/* run once, then terminate the timer */ -static gboolean -credentials_expiring_once (gpointer *data) -{ - credentials_expiring (data); - return FALSE; -} - - -/* - * set ticket options by looking at krb5.conf and gconf - */ -static void -ka_set_ticket_options (KaApplet *applet, krb5_context context, - krb5_get_init_creds_opt * out, - const char *pk_userid G_GNUC_UNUSED, - const char *pk_anchors G_GNUC_UNUSED) -{ - gboolean flag; - -#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS - krb5_get_init_creds_opt_set_default_flags (context, PACKAGE, - krb5_principal_get_realm - (context, kprincipal), out); -#endif - g_object_get (applet, "tgt-forwardable", &flag, NULL); - if (flag) - krb5_get_init_creds_opt_set_forwardable (out, flag); - g_object_get (applet, "tgt-proxiable", &flag, NULL); - if (flag) - krb5_get_init_creds_opt_set_proxiable (out, flag); - g_object_get (applet, "tgt-renewable", &flag, NULL); - if (flag) { - krb5_deltat r = 3600 * 24 * 30; /* 1 month */ - - krb5_get_init_creds_opt_set_renew_life (out, r); - } -#if ENABLE_PKINIT && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PA - /* pkinit optins for MIT Kerberos */ - if (pk_userid && strlen (pk_userid)) { - KA_DEBUG ("pkinit with '%s'", pk_userid); - krb5_get_init_creds_opt_set_pa (context, out, - "X509_user_identity", pk_userid); - if (pk_anchors && strlen (pk_anchors)) { - KA_DEBUG ("pkinit anchors '%s'", pk_anchors); - krb5_get_init_creds_opt_set_pa (context, out, - "X509_anchors", pk_anchors); - } - } -#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PA */ -} - - -#if ENABLE_PKINIT && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT -static krb5_error_code -ka_auth_heimdal_pkinit (KaApplet *applet, krb5_creds *creds, - const char *pk_userid, const char *pk_anchors) -{ - krb5_get_init_creds_opt *opts = NULL; - krb5_error_code retval; - const char *pkinit_anchors = NULL; - - KA_DEBUG ("pkinit with '%s'", pk_userid); - if (pk_anchors && strlen (pk_anchors)) { - pkinit_anchors = pk_anchors; - KA_DEBUG ("pkinit anchors '%s'", pkinit_anchors); - } - - if ((retval = krb5_get_init_creds_opt_alloc (kcontext, &opts))) - goto out; - - ka_set_ticket_options (applet, kcontext, opts, NULL, NULL); - retval = krb5_get_init_creds_opt_set_pkinit (kcontext, opts, kprincipal, pk_userid, pkinit_anchors, NULL, NULL, 0, /* pk_use_enc_key */ - auth_dialog_prompter, applet, /* data */ - NULL); /* passwd */ - KA_DEBUG ("pkinit returned with %d", retval); - if (retval) - goto out; - - retval = krb5_get_init_creds_password (kcontext, creds, kprincipal, - NULL, auth_dialog_prompter, applet, - 0, NULL, opts); - out: - if (opts) - krb5_get_init_creds_opt_free (kcontext, opts); - return retval; -} -#endif /* ! ENABLE_PKINIT */ - -static krb5_error_code -ka_auth_password (KaApplet *applet, krb5_creds *creds, - const char *pk_userid, const char *pk_anchors) -{ - krb5_error_code retval; - krb5_get_init_creds_opt *opts = NULL; - - if ((retval = krb5_get_init_creds_opt_alloc (kcontext, &opts))) - goto out; - ka_set_ticket_options (applet, kcontext, opts, pk_userid, pk_anchors); - - retval = krb5_get_init_creds_password (kcontext, creds, kprincipal, - NULL, auth_dialog_prompter, applet, - 0, NULL, opts); - out: - if (opts) - krb5_get_init_creds_opt_free (kcontext, opts); - return retval; -} - -static krb5_error_code -ka_parse_name (KaApplet *applet, krb5_context krbcontext, - krb5_principal * kprinc) -{ - krb5_error_code ret; - gchar *principal = NULL; - - if (*kprinc != NULL) - krb5_free_principal (krbcontext, *kprinc); - - g_object_get (applet, "principal", &principal, NULL); - ret = krb5_parse_name (krbcontext, principal, kprinc); - - g_free (principal); - return ret; -} - - -/* - * return current principal in text form - * - * caller needs to free the returned result using g_free(); - */ -char * -ka_unparse_name () -{ - char *princ, *gprinc = NULL; - krb5_error_code err; - - if (!kprincipal) - goto out; - - if ((err = krb5_unparse_name (kcontext, kprincipal, &princ))) { - ka_log_error_message (__func__, kcontext, err); - goto out; - } - - gprinc = g_strdup (princ); - free (princ); - out: - return gprinc; -} - - -static void -ccache_changed_cb (GFileMonitor * monitor G_GNUC_UNUSED, - GFile * file, - GFile * other_file G_GNUC_UNUSED, - GFileMonitorEvent event_type, gpointer data) -{ - KaApplet *applet = KA_APPLET (data); - gchar *ccache_name = g_file_get_path (file); - - switch (event_type) { - case G_FILE_MONITOR_EVENT_DELETED: - case G_FILE_MONITOR_EVENT_CREATED: - case G_FILE_MONITOR_EVENT_CHANGED: - KA_DEBUG ("%s changed", ccache_name); - credentials_expiring ((gpointer) applet); - break; - default: - KA_DEBUG ("%s unhandled event: %d", ccache_name, event_type); - } - g_free (ccache_name); -} - - -static GFileMonitor * -monitor_ccache (KaApplet *applet) -{ - const gchar *ccache_name; - GFile *ccache; - GFileMonitor *monitor = NULL; - GError *err = NULL; - - ccache_name = ka_ccache_filename (); - g_return_val_if_fail (ccache_name != NULL, FALSE); - - ccache = g_file_new_for_path (ccache_name); - monitor = g_file_monitor_file (ccache, G_FILE_MONITOR_NONE, NULL, &err); - g_assert ((!monitor && err) || (monitor && !err)); - if (!monitor) { - /* cache disappeared? */ - if (err->code == G_FILE_ERROR_NOENT) - credentials_expiring ((gpointer) applet); - else - g_warning ("Failed to monitor %s: %s", ccache_name, err->message); - } else { - /* g_file_monitor_set_rate_limit(monitor, 10*1000); */ - g_signal_connect (monitor, "changed", G_CALLBACK (ccache_changed_cb), - applet); - KA_DEBUG ("Monitoring %s", ccache_name); - } - g_object_unref (ccache); - g_clear_error (&err); - return monitor; -} - - -/* grab credentials interactively */ -static int -grab_credentials (KaApplet *applet) -{ - krb5_error_code retval = KRB5_KDC_UNREACH; - krb5_creds my_creds; - krb5_ccache ccache; - gchar *pk_userid = NULL; - gchar *pk_anchors = NULL; - gchar *errmsg = NULL; - gboolean pw_auth = TRUE; - - memset (&my_creds, 0, sizeof (my_creds)); - - retval = ka_parse_name (applet, kcontext, &kprincipal); - if (retval) - goto out2; - - retval = krb5_cc_default (kcontext, &ccache); - if (retval) - goto out2; - - g_object_get (applet, "pk-userid", &pk_userid, - "pk-anchors", &pk_anchors, NULL); -#if ENABLE_PKINIT && HAVE_HX509_ERR_H && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT - /* pk_userid set: try pkinit */ - if (pk_userid && strlen (pk_userid)) { - retval = ka_auth_heimdal_pkinit (applet, &my_creds, - pk_userid, pk_anchors); - /* other error than: "no token found" - no need to try password auth: */ - if (retval != HX509_PKCS11_NO_TOKEN && retval != HX509_PKCS11_NO_SLOT) - pw_auth = FALSE; - } -#endif /* ENABLE_PKINIT */ - if (pw_auth) - retval = ka_auth_password (applet, &my_creds, pk_userid, pk_anchors); - - creds_expiry = my_creds.times.endtime; - if (canceled) - canceled_creds_expiry = creds_expiry; - if (retval) { - switch (retval) { - case KRB5KDC_ERR_PREAUTH_FAILED: - case KRB5KRB_AP_ERR_BAD_INTEGRITY: -#ifdef HAVE_HX509_ERR_H - case HX509_PKCS11_LOGIN: -#endif /* Invalid password/pin, try again. */ - invalid_auth = TRUE; - break; - default: - errmsg = ka_get_error_message (kcontext, retval); - KA_DEBUG ("Auth failed with %d: %s", retval, errmsg); - g_free (errmsg); - break; - } - goto out; - } - retval = krb5_cc_initialize (kcontext, ccache, kprincipal); - if (retval) - goto out; - - retval = krb5_cc_store_cred (kcontext, ccache, &my_creds); - if (retval) - goto out; - out: - krb5_free_cred_contents (kcontext, &my_creds); - krb5_cc_close (kcontext, ccache); - out2: - g_free (pk_userid); - return retval; -} - -/* try to renew the credentials noninteractively */ -static int -ka_renew_credentials (KaApplet *applet) -{ - krb5_error_code retval; - krb5_creds my_creds; - krb5_ccache ccache; - - memset (&my_creds, 0, sizeof (my_creds)); - if (kprincipal == NULL) { - retval = ka_parse_name (applet, kcontext, &kprincipal); - if (retval) - return retval; - } - - retval = krb5_cc_default (kcontext, &ccache); - if (retval) - return retval; - - retval = ka_get_tgt_from_ccache (kcontext, &my_creds); - if (!retval) { - krb5_free_cred_contents (kcontext, &my_creds); - krb5_cc_close (kcontext, ccache); - return -1; - } - - if (ka_applet_get_tgt_renewable (applet)) { - krb5_free_cred_contents (kcontext, &my_creds); - retval = - get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL); - if (retval) - goto out; - - retval = krb5_cc_initialize (kcontext, ccache, kprincipal); - if (retval) { - ka_log_error_message ("krb5_cc_initialize", kcontext, retval); - goto out; - } - retval = krb5_cc_store_cred (kcontext, ccache, &my_creds); - if (retval) { - ka_log_error_message ("krb5_cc_store_cred", kcontext, retval); - goto out; - } - ka_applet_signal_emit (applet, KA_SIGNAL_RENEWED_TGT, - my_creds.times.endtime); - } - out: - if (!retval) - creds_expiry = my_creds.times.endtime; - krb5_free_cred_contents (kcontext, &my_creds); - krb5_cc_close (kcontext, ccache); - return retval; -} - - -/* get principal associated with the default credentials cache - if found store - * it in *creds, return FALSE otwerwise */ -static gboolean -ka_get_tgt_from_ccache (krb5_context context, krb5_creds *creds) -{ - krb5_ccache ccache; - krb5_creds pattern; - krb5_principal principal; - gboolean ret = FALSE; - - ka_krb5_cc_clear_mcred (&pattern); - - if (krb5_cc_default (context, &ccache)) - return FALSE; - - if (krb5_cc_get_principal (context, ccache, &principal)) - goto out; - - if (krb5_build_principal_ext (context, &pattern.server, - get_principal_realm_length (principal), - get_principal_realm_data (principal), - KRB5_TGS_NAME_SIZE, - KRB5_TGS_NAME, - get_principal_realm_length (principal), - get_principal_realm_data (principal), 0)) { - goto out_free_princ; - } - pattern.client = principal; - if (!krb5_cc_retrieve_cred (context, ccache, 0, &pattern, creds)) - ret = TRUE; - - krb5_free_principal (context, pattern.server); - out_free_princ: - krb5_free_principal (context, principal); - out: - krb5_cc_close (context, ccache); - return ret; -} - -static gboolean -using_krb5 (void) -{ - krb5_error_code err; - gboolean have_tgt = FALSE; - krb5_creds creds; - - err = krb5_init_context (&kcontext); - if (err) - return FALSE; - - have_tgt = ka_get_tgt_from_ccache (kcontext, &creds); - if (have_tgt) { - krb5_copy_principal (kcontext, creds.client, &kprincipal); - krb5_free_cred_contents (kcontext, &creds); - } - return have_tgt; -} - - -gboolean -ka_destroy_ccache (KaApplet *applet) -{ - krb5_ccache ccache; - const char *cache; - krb5_error_code ret; - - cache = krb5_cc_default_name (kcontext); - ret = krb5_cc_resolve (kcontext, cache, &ccache); - ret = krb5_cc_destroy (kcontext, ccache); - - credentials_expiring_real (applet); - - if (ret) - return FALSE; - else - return TRUE; -} - - -/* - * check if we have valid credentials for the requested principal - if not, grab them - * principal: requested principal - if empty use default - */ -gboolean -ka_check_credentials (KaApplet *applet, const char *newprincipal) -{ - gboolean success = FALSE; - int retval; - char *principal; - - g_object_get (applet, "principal", &principal, NULL); - - if (strlen (newprincipal)) { - krb5_principal knewprinc; - - /* no ticket cache: is requested princ the one from our config? */ - if (!kprincipal && g_strcmp0 (principal, newprincipal)) { - KA_DEBUG ("Requested principal %s not %s", principal, - newprincipal); - goto out; - } - - /* ticket cache: check if the requested principal is the one we have */ - retval = krb5_parse_name (kcontext, newprincipal, &knewprinc); - if (retval) { - g_warning ("Cannot parse principal '%s'", newprincipal); - goto out; - } - if (kprincipal - && !krb5_principal_compare (kcontext, kprincipal, knewprinc)) { - KA_DEBUG ("Current Principal '%s' not '%s'", principal, - newprincipal); - krb5_free_principal (kcontext, knewprinc); - goto out; - } - krb5_free_principal (kcontext, knewprinc); - } - - if (credentials_expiring_real (applet)) { - if (!is_online) - success = FALSE; - else - success = ka_grab_credentials (applet); - } else - success = TRUE; - out: - g_free (principal); - return success; -} - - -/* initiate grabbing of credentials (e.g. on leftclick of tray icon) */ -gboolean -ka_grab_credentials (KaApplet *applet) -{ - int retval; - int success = FALSE; - KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); - - ka_pwdialog_set_persist (pwdialog, TRUE); - do { - retval = grab_credentials (applet); - if (invalid_auth) - continue; - if (canceled) - break; - if (retval) { - gchar *errmsg; - - errmsg = ka_get_error_message (kcontext, retval); - ka_pwdialog_error (pwdialog, errmsg); - g_free (errmsg); - break; - } else { - success = TRUE; - break; - } - } while (TRUE); - - ka_pwdialog_set_persist (pwdialog, FALSE); - credentials_expiring_real (applet); - - return success; -} - - -static void -ka_secmem_init (void) -{ - /* Initialize secure memory. 1 is too small, so the default size - will be used. */ - secmem_init (1); - secmem_set_flags (SECMEM_WARN); - drop_privs (); - - if (atexit (secmem_term)) - g_error ("Couln't register atexit handler"); -} - - -static void -ka_nm_shutdown (void) -{ -#ifdef ENABLE_NETWORK_MANAGER - if (nm_client) { - g_object_unref (nm_client); - nm_client = NULL; - } -#endif -} - - -static gboolean -ka_nm_init (void) -{ -#ifdef ENABLE_NETWORK_MANAGER - nm_client = nm_client_new (); - if (!nm_client) { - g_warning ("Could not initialize nm-client"); - } else { - g_signal_connect (nm_client, "notify::state", - G_CALLBACK (ka_nm_client_state_changed_cb), - &is_online); - /* Set initial state */ - ka_nm_client_state_changed_cb (nm_client, NULL, &is_online); - } -#endif /* ENABLE_NETWORK_MANAGER */ - return TRUE; -} - - -int -main (int argc, char *argv[]) -{ - KaApplet *applet; - GOptionContext *context; - GError *error = NULL; - - gboolean run_auto = FALSE; - - const char *help_msg = - "Run '" PACKAGE - " --help' to see a full list of available command line options"; - const GOptionEntry options[] = { - {"auto", 'a', 0, G_OPTION_ARG_NONE, &run_auto, - "Only run if an initialized ccache is found", NULL}, - {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL} - }; - GFileMonitor *monitor = NULL; - - context = g_option_context_new ("- Kerberos 5 credential checking"); - g_option_context_add_main_entries (context, options, NULL); - g_option_context_add_group (context, gtk_get_option_group (TRUE)); - g_option_context_parse (context, &argc, &argv, &error); - - if (error) { - g_print ("%s\n%s\n", error->message, help_msg); - g_clear_error (&error); - return 1; - } - g_option_context_free (context); - - textdomain (PACKAGE); - bind_textdomain_codeset (PACKAGE, "UTF-8"); - bindtextdomain (PACKAGE, LOCALE_DIR); - ka_secmem_init (); - - always_run = !run_auto; - if (using_krb5 () || always_run) { - g_set_application_name (KA_NAME); - - applet = ka_applet_create (); - if (!applet) - return 1; - - if (!ka_dbus_connect (applet)) { - ka_applet_destroy (applet); - return 1; - } - ka_nm_init (); - - g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, - (GSourceFunc) credentials_expiring, applet); - g_idle_add ((GSourceFunc) credentials_expiring_once, applet); - monitor = monitor_ccache (applet); - - gtk_main (); - } - ka_dbus_disconnect (); - ka_nm_shutdown (); - if (monitor) - g_object_unref (monitor); - return 0; -} - -/* - * vim:ts=4:sts=4:sw=4:et: - */ diff --git a/src/ka-dialog.h b/src/ka-dialog.h deleted file mode 100644 index c62acb3..0000000 --- a/src/ka-dialog.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Krb5 Auth Applet -- Acquire and release kerberos tickets - * - * (C) 2008 Guido Guenther - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef KA_DIALOG -#define KA_DIALOG - -#include "ka-applet-priv.h" - -gboolean ka_destroy_ccache (KaApplet* applet); -gboolean ka_grab_credentials(KaApplet* applet); -gboolean ka_check_credentials (KaApplet *applet, const char* principal); -gboolean ka_get_service_tickets(GtkListStore *tickets); -char* ka_unparse_name(void); -int ka_tgt_valid_seconds(void); -#endif diff --git a/src/ka-kerberos.c b/src/ka-kerberos.c new file mode 100644 index 0000000..e131286 --- /dev/null +++ b/src/ka-kerberos.c @@ -0,0 +1,1114 @@ +/* + * Copyright (C) 2004,2005,2006 Red Hat, Inc. + * Authored by Christopher Aillon + * + * Copyright (C) 2008,2009,2010,2011 Guido Guenther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "secmem-util.h" +#include "memory.h" + +#include "ka-kerberos.h" +#include "ka-applet-priv.h" +#include "ka-pwdialog.h" +#include "ka-tools.h" +#include "ka-main-window.h" + +#ifdef ENABLE_NETWORK_MANAGER +#include + +#if !defined(NM_CHECK_VERSION) +#define NM_CHECK_VERSION(x,y,z) 0 +#endif +#endif + +#ifdef HAVE_HX509_ERR_H +#include +#endif + +static krb5_context kcontext; +static krb5_principal kprincipal; +static krb5_timestamp creds_expiry; +static krb5_timestamp canceled_creds_expiry; +static gboolean canceled; +static gboolean invalid_auth; +static gboolean is_online = TRUE; +static gboolean kcontext_valid; +GFileMonitor *ccache_monitor; + +static int grab_credentials (KaApplet *applet); +static int ka_renew_credentials (KaApplet *applet); +static gboolean ka_get_tgt_from_ccache (krb5_context context, + krb5_creds *creds); + +#ifdef ENABLE_NETWORK_MANAGER +NMClient *nm_client; +#endif + +/* YAY for different Kerberos implementations */ +static int +get_cred_forwardable (krb5_creds *creds) +{ +#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_FORWARDABLE) + return creds->ticket_flags & TKT_FLG_FORWARDABLE; +#elif defined(HAVE_KRB5_CREDS_FLAGS_B_FORWARDABLE) + return creds->flags.b.forwardable; +#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_FORWARDABLE) + return creds->flags & KDC_OPT_FORWARDABLE; +#endif +} + +static int +get_cred_renewable (krb5_creds *creds) +{ +#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_RENEWABLE) + return creds->ticket_flags & TKT_FLG_RENEWABLE; +#elif defined(HAVE_KRB5_CREDS_FLAGS_B_RENEWABLE) + return creds->flags.b.renewable; +#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_RENEWABLE) + return creds->flags & KDC_OPT_RENEWABLE; +#endif +} + +static krb5_error_code +get_renewed_creds (krb5_context context, + krb5_creds *creds, + krb5_principal client, + krb5_ccache ccache, char *in_tkt_service) +{ +#ifdef HAVE_KRB5_GET_RENEWED_CREDS + return krb5_get_renewed_creds (context, creds, client, ccache, + in_tkt_service); +#else + return 1; /* XXX is there something better to return? */ +#endif +} + +static int +get_cred_proxiable (krb5_creds *creds) +{ +#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_PROXIABLE) + return creds->ticket_flags & TKT_FLG_PROXIABLE; +#elif defined(HAVE_KRB5_CREDS_FLAGS_B_PROXIABLE) + return creds->flags.b.proxiable; +#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_PROXIABLE) + return creds->flags & KDC_OPT_PROXIABLE; +#endif +} + +static size_t +get_principal_realm_length (krb5_principal p) +{ +#if defined(HAVE_KRB5_PRINCIPAL_REALM_AS_STRING) + return strlen (p->realm); +#elif defined(HAVE_KRB5_PRINCIPAL_REALM_AS_DATA) + return p->realm.length; +#endif +} + +static const char * +get_principal_realm_data (krb5_principal p) +{ +#if defined(HAVE_KRB5_PRINCIPAL_REALM_AS_STRING) + return p->realm; +#elif defined(HAVE_KRB5_PRINCIPAL_REALM_AS_DATA) + return p->realm.data; +#endif +} + +static void +ka_krb5_free_error_message (krb5_context context, const char *msg) +{ +#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE) + krb5_free_error_message (context, msg); +#elif defined(HAVE_KRB5_FREE_ERROR_STRING) + krb5_free_error_string (context, (char *) msg); +#else +# error No way to free error string. +#endif +} + +/* + * Returns a descriptive error message or kerberos related error + * returned pointer must be freed using g_free(). + */ +static char * +ka_get_error_message (krb5_context context, krb5_error_code err) +{ + char *msg = NULL; + +#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) + const char *krberr; + + krberr = krb5_get_error_message (context, err); + msg = g_strdup (krberr); + ka_krb5_free_error_message (context, krberr); +#else +# error No detailed error message information +#endif + if (msg == NULL) + msg = g_strdup (_("unknown error")); + return msg; +} + + +static void +ka_krb5_cc_clear_mcred (krb5_creds *mcred) +{ +#if defined HAVE_KRB5_CC_CLEAR_MCRED + krb5_cc_clear_mcred (mcred); +#else + memset (mcred, 0, sizeof (krb5_creds)); +#endif +} + + +/* ***************************************************************** */ +/* ***************************************************************** */ + +/* log a kerberos error messge */ +static void +ka_log_error_message (const char *prefix, krb5_context context, + krb5_error_code err) +{ + char *errmsg = ka_get_error_message (context, err); + + g_warning ("%s: %s", prefix, errmsg); + g_free (errmsg); +} + + +static gboolean +credentials_expiring_real (KaApplet *applet) +{ + krb5_creds my_creds; + krb5_timestamp now; + gboolean retval = FALSE; + + memset (&my_creds, 0, sizeof (my_creds)); + ka_applet_set_tgt_renewable (applet, FALSE); + if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) { + creds_expiry = 0; + retval = TRUE; + goto out; + } + + /* copy principal from cache if any */ + if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { + krb5_free_principal (kcontext, kprincipal); + krb5_copy_principal (kcontext, my_creds.client, &kprincipal); + } + creds_expiry = my_creds.times.endtime; + if ((krb5_timeofday (kcontext, &now) == 0) && + (now + ka_applet_get_pw_prompt_secs (applet) > + my_creds.times.endtime)) + retval = TRUE; + + /* If our creds are expiring, determine whether they are renewable. + * If the expiry is already at the renew_till time, don't consider + * credentials renewable */ + if (retval && get_cred_renewable (&my_creds) + && my_creds.times.renew_till > now + && my_creds.times.renew_till > creds_expiry) { + ka_applet_set_tgt_renewable (applet, TRUE); + } + + out: + krb5_free_cred_contents (kcontext, &my_creds); + ka_applet_update_status (applet, creds_expiry); + return retval; +} + + +/* time in seconds the tgt will be still valid */ +int +ka_tgt_valid_seconds () +{ + krb5_timestamp now; + + if (krb5_timeofday (kcontext, &now)) + return 0; + + return (creds_expiry - now); +} + + +/* return credential cache filename, strip "FILE:" prefix if necessary */ +static const char * +ka_ccache_filename (void) +{ + const gchar *name; + + name = krb5_cc_default_name (kcontext); + if (g_str_has_prefix (name, "FILE:")) + return strchr (name, ':') + 1; + else if (g_str_has_prefix (name, "SCC:")) + g_warning ("Cannot monitor sqlite based cache '%s'", name); + else + g_warning ("Unsupported cache type for '%s'", name); + return NULL; +} + + +static void +ka_format_time (time_t t, gchar *ts, size_t len) +{ + g_strlcpy (ts, ctime (&t) + 4, len); + ts[15] = 0; +} + + +/* fill in service tickets data */ +gboolean +ka_get_service_tickets (GtkListStore * tickets) +{ + krb5_cc_cursor cursor; + krb5_creds creds; + krb5_error_code ret; + GtkTreeIter iter; + krb5_ccache ccache; + char *name; + krb5_timestamp sec; + gchar start_time[128], end_time[128], end_time_markup[256]; + gboolean retval = FALSE; + + gtk_list_store_clear (tickets); + + krb5_timeofday (kcontext, &sec); + ret = krb5_cc_default (kcontext, &ccache); + g_return_val_if_fail (!ret, FALSE); + + ret = krb5_cc_start_seq_get (kcontext, ccache, &cursor); + if (ret) { + ka_log_error_message ("krb5_cc_start_seq_get", kcontext, ret); + + /* if the file doesn't exist, it's not an error if we can't + * parse it */ + if (!g_file_test (ka_ccache_filename (), G_FILE_TEST_EXISTS)) + gtk_list_store_append (tickets, &iter); + gtk_list_store_set (tickets, &iter, + PRINCIPAL_COLUMN, _("Your ticket cache is currently empty"), + FORWARDABLE_COLUMN, FALSE, + RENEWABLE_COLUMN, FALSE, + PROXIABLE_COLUMN, FALSE, -1); + retval = TRUE; + goto out; + } + + while ((ret = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { + gboolean renewable, proxiable, forwardable; + + if (creds.times.starttime) + ka_format_time (creds.times.starttime, start_time, + sizeof (start_time)); + else + ka_format_time (creds.times.authtime, start_time, + sizeof (start_time)); + + ka_format_time (creds.times.endtime, end_time, sizeof (end_time)); + if (creds.times.endtime > sec) + strcpy (end_time_markup, end_time); + else + g_snprintf (end_time_markup, sizeof (end_time_markup), + "%s (%s)", + end_time, _("Expired")); + + forwardable = get_cred_forwardable (&creds); + renewable = get_cred_renewable (&creds); + proxiable = get_cred_proxiable (&creds); + + ret = krb5_unparse_name (kcontext, creds.server, &name); + if (!ret) { + gtk_list_store_append (tickets, &iter); + gtk_list_store_set (tickets, &iter, + PRINCIPAL_COLUMN, name, + START_TIME_COLUMN, start_time, + END_TIME_COLUMN, end_time_markup, + FORWARDABLE_COLUMN, forwardable, + RENEWABLE_COLUMN, renewable, + PROXIABLE_COLUMN, proxiable, -1); + free (name); + } else + ka_log_error_message ("krb5_unparse_name", kcontext, ret); + krb5_free_cred_contents (kcontext, &creds); + } + if (ret != KRB5_CC_END) + ka_log_error_message ("krb5_cc_get_next", kcontext, ret); + + ret = krb5_cc_end_seq_get (kcontext, ccache, &cursor); + if (ret) + ka_log_error_message ("krb5_cc_end_seq_get", kcontext, ret); + + retval = TRUE; + out: + ret = krb5_cc_close (kcontext, ccache); + g_return_val_if_fail (!ret, FALSE); + + return retval; +} + + +/* Check for things we have to do while the password dialog is open */ +static gboolean +krb5_auth_dialog_do_updates (gpointer data) +{ + KaApplet *applet = KA_APPLET (data); + KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); + + g_return_val_if_fail (pwdialog != NULL, FALSE); + /* Update creds_expiry and close the applet if we got the creds by other means (e.g. kinit) */ + if (!credentials_expiring_real (applet)) + ka_pwdialog_hide (pwdialog, FALSE); + + /* Update the expiry information in the dialog */ + ka_pwdialog_status_update (pwdialog); + return TRUE; +} + + +static krb5_error_code +auth_dialog_prompter (krb5_context ctx G_GNUC_UNUSED, + void *data, + const char *name G_GNUC_UNUSED, + const char *banner G_GNUC_UNUSED, + int num_prompts, krb5_prompt prompts[]) +{ + KaApplet *applet = KA_APPLET (data); + KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); + krb5_error_code errcode; + int i; + + errcode = KRB5KRB_ERR_GENERIC; + canceled = FALSE; + canceled_creds_expiry = 0; + + if (banner && !num_prompts) + ka_applet_set_msg (applet, banner); + + for (i = 0; i < num_prompts; i++) { + const gchar *password = NULL; + int password_len = 0; + int response; + guint32 source_id; + + errcode = KRB5_LIBOS_CANTREADPWD; + + source_id = + g_timeout_add_seconds (5, + (GSourceFunc) krb5_auth_dialog_do_updates, + applet); + ka_pwdialog_setup (pwdialog, (gchar *) prompts[i].prompt, + invalid_auth); + response = ka_pwdialog_run (pwdialog); + switch (response) { + case GTK_RESPONSE_OK: + password = ka_pwdialog_get_password (pwdialog); + password_len = strlen (password); + break; + case GTK_RESPONSE_DELETE_EVENT: + case GTK_RESPONSE_CANCEL: + canceled = TRUE; + break; + case GTK_RESPONSE_NONE: + break; + default: + g_warning ("Unknown Response: %d", response); + g_assert_not_reached (); + } + g_source_remove (source_id); + + if (!password) + goto cleanup; + if (password_len + 1 > prompts[i].reply->length) { + g_warning ("Password too long %d/%d", password_len + 1, + prompts[i].reply->length); + goto cleanup; + } + + memcpy (prompts[i].reply->data, (char *) password, password_len + 1); + prompts[i].reply->length = password_len; + errcode = 0; + } + cleanup: + ka_pwdialog_hide (pwdialog, TRUE); + /* Reset this, so we know the next time we get a TRUE value, it is accurate. */ + invalid_auth = FALSE; + + return errcode; +} + + +#ifdef ENABLE_NETWORK_MANAGER +static void +ka_nm_client_state_changed_cb (NMClient * client, + GParamSpec *pspec G_GNUC_UNUSED, gpointer data) +{ + NMState state; + gboolean *online = (gboolean *) data; + + state = nm_client_get_state (client); + switch (state) { + case NM_STATE_UNKNOWN: + case NM_STATE_ASLEEP: + case NM_STATE_CONNECTING: + KA_DEBUG ("Network state: %d", state); + /* do nothing */ + break; +#if NM_CHECK_VERSION(0,8,992) + case NM_STATE_DISCONNECTING: +#endif + case NM_STATE_DISCONNECTED: + KA_DEBUG ("Network disconnected"); + *online = FALSE; + break; +#if NM_CHECK_VERSION(0,8,992) + case NM_STATE_CONNECTED_LOCAL: + case NM_STATE_CONNECTED_SITE: + case NM_STATE_CONNECTED_GLOBAL: +#else + case NM_STATE_CONNECTED: +#endif + KA_DEBUG ("Network connected"); + *online = TRUE; + break; + } +} +#endif + +/* credentials expiring timer */ +static gboolean +credentials_expiring (gpointer *data) +{ + KaApplet *applet = KA_APPLET (data); + + KA_DEBUG ("Checking expiry <%ds", ka_applet_get_pw_prompt_secs (applet)); + if (credentials_expiring_real (applet) && is_online) { + KA_DEBUG ("Expiry @ %ld", creds_expiry); + + if (!ka_renew_credentials (applet)) + KA_DEBUG ("Credentials renewed"); + } + ka_applet_update_status (applet, creds_expiry); + + return TRUE; +} + + +/* run once, then terminate the timer */ +static gboolean +credentials_expiring_once (gpointer *data) +{ + credentials_expiring (data); + return FALSE; +} + + +/* + * set ticket options by looking at krb5.conf and gconf + */ +static void +ka_set_ticket_options (KaApplet *applet, krb5_context context, + krb5_get_init_creds_opt * out, + const char *pk_userid G_GNUC_UNUSED, + const char *pk_anchors G_GNUC_UNUSED) +{ + gboolean flag; + +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS + krb5_get_init_creds_opt_set_default_flags (context, PACKAGE, + krb5_principal_get_realm + (context, kprincipal), out); +#endif + g_object_get (applet, "tgt-forwardable", &flag, NULL); + if (flag) + krb5_get_init_creds_opt_set_forwardable (out, flag); + g_object_get (applet, "tgt-proxiable", &flag, NULL); + if (flag) + krb5_get_init_creds_opt_set_proxiable (out, flag); + g_object_get (applet, "tgt-renewable", &flag, NULL); + if (flag) { + krb5_deltat r = 3600 * 24 * 30; /* 1 month */ + + krb5_get_init_creds_opt_set_renew_life (out, r); + } +#if ENABLE_PKINIT && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PA + /* pkinit optins for MIT Kerberos */ + if (pk_userid && strlen (pk_userid)) { + KA_DEBUG ("pkinit with '%s'", pk_userid); + krb5_get_init_creds_opt_set_pa (context, out, + "X509_user_identity", pk_userid); + if (pk_anchors && strlen (pk_anchors)) { + KA_DEBUG ("pkinit anchors '%s'", pk_anchors); + krb5_get_init_creds_opt_set_pa (context, out, + "X509_anchors", pk_anchors); + } + } +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PA */ +} + + +#if ENABLE_PKINIT && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT +static krb5_error_code +ka_auth_heimdal_pkinit (KaApplet *applet, krb5_creds *creds, + const char *pk_userid, const char *pk_anchors) +{ + krb5_get_init_creds_opt *opts = NULL; + krb5_error_code retval; + const char *pkinit_anchors = NULL; + + KA_DEBUG ("pkinit with '%s'", pk_userid); + if (pk_anchors && strlen (pk_anchors)) { + pkinit_anchors = pk_anchors; + KA_DEBUG ("pkinit anchors '%s'", pkinit_anchors); + } + + if ((retval = krb5_get_init_creds_opt_alloc (kcontext, &opts))) + goto out; + + ka_set_ticket_options (applet, kcontext, opts, NULL, NULL); + retval = krb5_get_init_creds_opt_set_pkinit (kcontext, opts, kprincipal, pk_userid, pkinit_anchors, NULL, NULL, 0, /* pk_use_enc_key */ + auth_dialog_prompter, applet, /* data */ + NULL); /* passwd */ + KA_DEBUG ("pkinit returned with %d", retval); + if (retval) + goto out; + + retval = krb5_get_init_creds_password (kcontext, creds, kprincipal, + NULL, auth_dialog_prompter, applet, + 0, NULL, opts); + out: + if (opts) + krb5_get_init_creds_opt_free (kcontext, opts); + return retval; +} +#endif /* ! ENABLE_PKINIT */ + +static krb5_error_code +ka_auth_password (KaApplet *applet, krb5_creds *creds, + const char *pk_userid, const char *pk_anchors) +{ + krb5_error_code retval; + krb5_get_init_creds_opt *opts = NULL; + + if ((retval = krb5_get_init_creds_opt_alloc (kcontext, &opts))) + goto out; + ka_set_ticket_options (applet, kcontext, opts, pk_userid, pk_anchors); + + retval = krb5_get_init_creds_password (kcontext, creds, kprincipal, + NULL, auth_dialog_prompter, applet, + 0, NULL, opts); + out: + if (opts) + krb5_get_init_creds_opt_free (kcontext, opts); + return retval; +} + +static krb5_error_code +ka_parse_name (KaApplet *applet, krb5_context krbcontext, + krb5_principal * kprinc) +{ + krb5_error_code ret; + gchar *principal = NULL; + + if (*kprinc != NULL) + krb5_free_principal (krbcontext, *kprinc); + + g_object_get (applet, "principal", &principal, NULL); + ret = krb5_parse_name (krbcontext, principal, kprinc); + + g_free (principal); + return ret; +} + + +/* + * return current principal in text form + * + * caller needs to free the returned result using g_free(); + */ +char * +ka_unparse_name () +{ + char *princ, *gprinc = NULL; + krb5_error_code err; + + if (!kprincipal) + goto out; + + if ((err = krb5_unparse_name (kcontext, kprincipal, &princ))) { + ka_log_error_message (__func__, kcontext, err); + goto out; + } + + gprinc = g_strdup (princ); + free (princ); + out: + return gprinc; +} + + +static void +ccache_changed_cb (GFileMonitor *monitor G_GNUC_UNUSED, + GFile *file, + GFile *other_file G_GNUC_UNUSED, + GFileMonitorEvent event_type, gpointer data) +{ + KaApplet *applet = KA_APPLET (data); + gchar *ccache_name = g_file_get_path (file); + + switch (event_type) { + case G_FILE_MONITOR_EVENT_DELETED: + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGED: + KA_DEBUG ("%s changed", ccache_name); + credentials_expiring ((gpointer) applet); + g_signal_emit_by_name(applet, "krb-ccache-changed"); + break; + default: + KA_DEBUG ("%s unhandled event: %d", ccache_name, event_type); + } + g_free (ccache_name); +} + + +static GFileMonitor * +monitor_ccache (KaApplet *applet) +{ + const gchar *ccache_name; + GFile *ccache; + GFileMonitor *monitor = NULL; + GError *err = NULL; + + ccache_name = ka_ccache_filename (); + g_return_val_if_fail (ccache_name != NULL, FALSE); + + ccache = g_file_new_for_path (ccache_name); + monitor = g_file_monitor_file (ccache, G_FILE_MONITOR_NONE, NULL, &err); + g_assert ((!monitor && err) || (monitor && !err)); + if (!monitor) { + /* cache disappeared? */ + if (err->code == G_FILE_ERROR_NOENT) + credentials_expiring ((gpointer) applet); + else + g_warning ("Failed to monitor %s: %s", ccache_name, err->message); + } else { + /* g_file_monitor_set_rate_limit(monitor, 10*1000); */ + g_signal_connect (monitor, "changed", G_CALLBACK (ccache_changed_cb), + applet); + KA_DEBUG ("Monitoring %s", ccache_name); + } + g_object_unref (ccache); + g_clear_error (&err); + return monitor; +} + + +/* grab credentials interactively */ +static int +grab_credentials (KaApplet *applet) +{ + krb5_error_code retval = KRB5_KDC_UNREACH; + krb5_creds my_creds; + krb5_ccache ccache; + gchar *pk_userid = NULL; + gchar *pk_anchors = NULL; + gchar *errmsg = NULL; + gboolean pw_auth = TRUE; + + memset (&my_creds, 0, sizeof (my_creds)); + + retval = ka_parse_name (applet, kcontext, &kprincipal); + if (retval) + goto out2; + + retval = krb5_cc_default (kcontext, &ccache); + if (retval) + goto out2; + + g_object_get (applet, "pk-userid", &pk_userid, + "pk-anchors", &pk_anchors, NULL); +#if ENABLE_PKINIT && HAVE_HX509_ERR_H && HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT + /* pk_userid set: try pkinit */ + if (pk_userid && strlen (pk_userid)) { + retval = ka_auth_heimdal_pkinit (applet, &my_creds, + pk_userid, pk_anchors); + /* other error than: "no token found" - no need to try password auth: */ + if (retval != HX509_PKCS11_NO_TOKEN && retval != HX509_PKCS11_NO_SLOT) + pw_auth = FALSE; + } +#endif /* ENABLE_PKINIT */ + if (pw_auth) + retval = ka_auth_password (applet, &my_creds, pk_userid, pk_anchors); + + creds_expiry = my_creds.times.endtime; + if (canceled) + canceled_creds_expiry = creds_expiry; + if (retval) { + switch (retval) { + case KRB5KDC_ERR_PREAUTH_FAILED: + case KRB5KRB_AP_ERR_BAD_INTEGRITY: +#ifdef HAVE_HX509_ERR_H + case HX509_PKCS11_LOGIN: +#endif /* Invalid password/pin, try again. */ + invalid_auth = TRUE; + break; + default: + errmsg = ka_get_error_message (kcontext, retval); + KA_DEBUG ("Auth failed with %d: %s", retval, errmsg); + g_free (errmsg); + break; + } + goto out; + } + retval = krb5_cc_initialize (kcontext, ccache, kprincipal); + if (retval) + goto out; + + retval = krb5_cc_store_cred (kcontext, ccache, &my_creds); + if (retval) + goto out; + out: + krb5_free_cred_contents (kcontext, &my_creds); + krb5_cc_close (kcontext, ccache); + out2: + g_free (pk_userid); + return retval; +} + +/* try to renew the credentials noninteractively */ +static int +ka_renew_credentials (KaApplet *applet) +{ + krb5_error_code retval; + krb5_creds my_creds; + krb5_ccache ccache; + + memset (&my_creds, 0, sizeof (my_creds)); + if (kprincipal == NULL) { + retval = ka_parse_name (applet, kcontext, &kprincipal); + if (retval) + return retval; + } + + retval = krb5_cc_default (kcontext, &ccache); + if (retval) + return retval; + + retval = ka_get_tgt_from_ccache (kcontext, &my_creds); + if (!retval) { + krb5_free_cred_contents (kcontext, &my_creds); + krb5_cc_close (kcontext, ccache); + return -1; + } + + if (ka_applet_get_tgt_renewable (applet)) { + krb5_free_cred_contents (kcontext, &my_creds); + retval = + get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL); + if (retval) + goto out; + + retval = krb5_cc_initialize (kcontext, ccache, kprincipal); + if (retval) { + ka_log_error_message ("krb5_cc_initialize", kcontext, retval); + goto out; + } + retval = krb5_cc_store_cred (kcontext, ccache, &my_creds); + if (retval) { + ka_log_error_message ("krb5_cc_store_cred", kcontext, retval); + goto out; + } + ka_applet_signal_emit (applet, KA_SIGNAL_RENEWED_TGT, + my_creds.times.endtime); + } + out: + if (!retval) + creds_expiry = my_creds.times.endtime; + krb5_free_cred_contents (kcontext, &my_creds); + krb5_cc_close (kcontext, ccache); + return retval; +} + + +/* get principal associated with the default credentials cache - if found store + * it in *creds, return FALSE otwerwise */ +static gboolean +ka_get_tgt_from_ccache (krb5_context context, krb5_creds *creds) +{ + krb5_ccache ccache; + krb5_creds pattern; + krb5_principal principal; + gboolean ret = FALSE; + + ka_krb5_cc_clear_mcred (&pattern); + + if (krb5_cc_default (context, &ccache)) + return FALSE; + + if (krb5_cc_get_principal (context, ccache, &principal)) + goto out; + + if (krb5_build_principal_ext (context, &pattern.server, + get_principal_realm_length (principal), + get_principal_realm_data (principal), + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME, + get_principal_realm_length (principal), + get_principal_realm_data (principal), 0)) { + goto out_free_princ; + } + pattern.client = principal; + if (!krb5_cc_retrieve_cred (context, ccache, 0, &pattern, creds)) + ret = TRUE; + + krb5_free_principal (context, pattern.server); + out_free_princ: + krb5_free_principal (context, principal); + out: + krb5_cc_close (context, ccache); + return ret; +} + +static gboolean +ka_krb5_context_init () +{ + krb5_error_code err; + gboolean have_tgt = FALSE; + krb5_creds creds; + + err = krb5_init_context (&kcontext); + if (err) + return FALSE; + else + kcontext_valid = TRUE; + + have_tgt = ka_get_tgt_from_ccache (kcontext, &creds); + if (have_tgt) { + krb5_copy_principal (kcontext, creds.client, &kprincipal); + krb5_free_cred_contents (kcontext, &creds); + } + return have_tgt; +} + + +static gboolean +ka_krb5_context_free () +{ + if (kcontext_valid) { + krb5_free_context (kcontext); + kcontext_valid = FALSE; + } + return TRUE; +} + + +gboolean +ka_destroy_ccache (KaApplet *applet) +{ + krb5_ccache ccache; + const char *cache; + krb5_error_code ret; + + cache = krb5_cc_default_name (kcontext); + ret = krb5_cc_resolve (kcontext, cache, &ccache); + ret = krb5_cc_destroy (kcontext, ccache); + + credentials_expiring_real (applet); + + if (ret) + return FALSE; + else + return TRUE; +} + + +/* + * check if we have valid credentials for the requested principal - if not, grab them + * principal: requested principal - if empty use default + */ +gboolean +ka_check_credentials (KaApplet *applet, const char *newprincipal) +{ + gboolean success = FALSE; + int retval; + char *principal; + + g_object_get (applet, "principal", &principal, NULL); + + if (strlen (newprincipal)) { + krb5_principal knewprinc; + + /* no ticket cache: is requested princ the one from our config? */ + if (!kprincipal && g_strcmp0 (principal, newprincipal)) { + KA_DEBUG ("Requested principal %s not %s", principal, + newprincipal); + goto out; + } + + /* ticket cache: check if the requested principal is the one we have */ + retval = krb5_parse_name (kcontext, newprincipal, &knewprinc); + if (retval) { + g_warning ("Cannot parse principal '%s'", newprincipal); + goto out; + } + if (kprincipal + && !krb5_principal_compare (kcontext, kprincipal, knewprinc)) { + KA_DEBUG ("Current Principal '%s' not '%s'", principal, + newprincipal); + krb5_free_principal (kcontext, knewprinc); + goto out; + } + krb5_free_principal (kcontext, knewprinc); + } + + if (credentials_expiring_real (applet)) { + if (!is_online) + success = FALSE; + else + success = ka_grab_credentials (applet); + } else + success = TRUE; + out: + g_free (principal); + return success; +} + + +/* initiate grabbing of credentials (e.g. on leftclick of tray icon) */ +gboolean +ka_grab_credentials (KaApplet *applet) +{ + int retval; + int success = FALSE; + KaPwDialog *pwdialog = ka_applet_get_pwdialog (applet); + + ka_pwdialog_set_persist (pwdialog, TRUE); + do { + retval = grab_credentials (applet); + if (invalid_auth) + continue; + if (canceled) + break; + if (retval) { + gchar *errmsg; + + errmsg = ka_get_error_message (kcontext, retval); + ka_pwdialog_error (pwdialog, errmsg); + g_free (errmsg); + break; + } else { + success = TRUE; + break; + } + } while (TRUE); + + ka_pwdialog_set_persist (pwdialog, FALSE); + credentials_expiring_real (applet); + + return success; +} + + +static void +ka_secmem_init (void) +{ + /* Initialize secure memory. 1 is too small, so the default size + will be used. */ + secmem_init (1); + secmem_set_flags (SECMEM_WARN); + drop_privs (); + + if (atexit (secmem_term)) + g_error ("Couln't register atexit handler"); +} + + +static void +ka_nm_shutdown (void) +{ +#ifdef ENABLE_NETWORK_MANAGER + if (nm_client) { + g_object_unref (nm_client); + nm_client = NULL; + } +#endif +} + + +static gboolean +ka_nm_init (void) +{ +#ifdef ENABLE_NETWORK_MANAGER + nm_client = nm_client_new (); + if (!nm_client) { + g_warning ("Could not initialize nm-client"); + } else { + g_signal_connect (nm_client, "notify::state", + G_CALLBACK (ka_nm_client_state_changed_cb), + &is_online); + /* Set initial state */ + ka_nm_client_state_changed_cb (nm_client, NULL, &is_online); + } +#endif /* ENABLE_NETWORK_MANAGER */ + return TRUE; +} + + +gboolean +ka_kerberos_init (KaApplet *applet) +{ + gboolean ret; + + ka_secmem_init (); + ret = ka_krb5_context_init (applet); + ka_nm_init (); + g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, + (GSourceFunc) credentials_expiring, applet); + g_idle_add ((GSourceFunc) credentials_expiring_once, applet); + ccache_monitor = monitor_ccache (applet); + return ret; +} + + +gboolean +ka_kerberos_destroy () +{ + ka_nm_shutdown (); + + if (ccache_monitor) + g_object_unref (ccache_monitor); + + ka_krb5_context_free (); + return TRUE; +} + +/* + * vim:ts=4:sts=4:sw=4:et: + */ diff --git a/src/ka-kerberos.h b/src/ka-kerberos.h new file mode 100644 index 0000000..504cc14 --- /dev/null +++ b/src/ka-kerberos.h @@ -0,0 +1,35 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef KA_DIALOG +#define KA_DIALOG + +#include "ka-applet-priv.h" + +gboolean ka_kerberos_init (KaApplet *applet); +gboolean ka_kerberos_destroy (void); + +gboolean ka_destroy_ccache (KaApplet* applet); +gboolean ka_grab_credentials(KaApplet* applet); +gboolean ka_check_credentials (KaApplet *applet, const char* principal); +gboolean ka_get_service_tickets(GtkListStore *tickets); +char* ka_unparse_name(void); +int ka_tgt_valid_seconds(void); +#endif diff --git a/src/ka-main-window.c b/src/ka-main-window.c new file mode 100644 index 0000000..b841b3e --- /dev/null +++ b/src/ka-main-window.c @@ -0,0 +1,193 @@ +/* -*- c-file-style: "linux"; c-basic-offset: 4; indent-tabs-mode: nil; -*- * + * + * Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2009,2011 Guido Guenther + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include +#include + +#include "ka-main-window.h" +#include "ka-kerberos.h" +#include "ka-tools.h" +#include "ka-preferences.h" + +static GtkListStore *tickets; +static GtkWindow *main_window; + +static void +ccache_changed_cb (KaApplet* applet G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + KA_DEBUG("Refreshing ticket list"); + ka_get_service_tickets (tickets); +} + +static void +menuitem_close_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + ka_main_window_hide(); +} + +static void +menuitem_preferences_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + ka_preferences_window_show (main_window); +} + +static void +menuitem_about_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + ka_show_about (); +} + +static void +menuitem_help_contents_cb (GtkMenuItem *menuitem G_GNUC_UNUSED, + gpointer user_data G_GNUC_UNUSED) +{ + ka_show_help (gtk_window_get_screen (main_window), NULL, NULL); +} + + +static void +ka_main_window_create_menu (KaApplet *applet, GtkBuilder *xml) +{ + GtkMenuItem *item; + +#define CONNECT_MENU(name) \ + item = GTK_MENU_ITEM (gtk_builder_get_object (xml, \ + "menuitem_" #name)); \ + g_signal_connect (item, \ + "activate", \ + G_CALLBACK(menuitem_ ##name## _cb), \ + applet) + + CONNECT_MENU(close); + CONNECT_MENU(preferences); + CONNECT_MENU(about); + CONNECT_MENU(help_contents); + +#undef CONNECT_MENU +} + + +GtkWindow * +ka_main_window_create (KaApplet *applet, GtkBuilder *xml) +{ + GtkCellRenderer *text_renderer, *toggle_renderer; + GtkTreeView *tickets_view; + + tickets = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + + main_window = + GTK_WINDOW (gtk_builder_get_object (xml, "krb5_main_window")); + tickets_view = + GTK_TREE_VIEW (gtk_builder_get_object (xml, "krb5_tickets_treeview")); + gtk_tree_view_set_model (GTK_TREE_VIEW (tickets_view), + GTK_TREE_MODEL (tickets)); + + text_renderer = gtk_cell_renderer_text_new (); + toggle_renderer = gtk_cell_renderer_toggle_new (); + + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + _("Principal"), + text_renderer, + "text", + PRINCIPAL_COLUMN, + NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + _("Start Time"), + text_renderer, + "text", + START_TIME_COLUMN, + NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + _("End Time"), + text_renderer, + "markup", + END_TIME_COLUMN, + NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + /* Translators: this is an abbreviation for forwardable */ + _("Fwd"), + toggle_renderer, + "active", + FORWARDABLE_COLUMN, + NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + /* Translators: this is an abbreviation for proxiable */ + _("Proxy"), + toggle_renderer, + "active", + PROXIABLE_COLUMN, + NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, + /* Translators: this is an abbreviation for renewable */ + _("Renew"), + toggle_renderer, + "active", + RENEWABLE_COLUMN, + NULL); + + g_signal_connect (applet, "krb-ccache-changed", + G_CALLBACK(ccache_changed_cb), + NULL); + + ka_main_window_create_menu(applet, xml); + return main_window; +} + +void +ka_main_window_show () +{ + if (ka_get_service_tickets (tickets)) { + gtk_window_present (main_window); + } else { + GtkWidget *message_dialog; + + message_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _ + ("Error displaying service ticket information")); + gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE); + + g_signal_connect (message_dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gtk_widget_show (message_dialog); + } +} + +void +ka_main_window_hide () +{ + KA_DEBUG("Hiding main window"); + gtk_widget_hide (GTK_WIDGET(main_window)); +} diff --git a/src/ka-main-window.h b/src/ka-main-window.h new file mode 100644 index 0000000..bc5b191 --- /dev/null +++ b/src/ka-main-window.h @@ -0,0 +1,42 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2009 Guido Guenther + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef KA_TICKETS_H +#define KA_TICKETS_H + +#include "ka-applet.h" + +enum ticket_columns { + PRINCIPAL_COLUMN, + START_TIME_COLUMN, + END_TIME_COLUMN, + FORWARDABLE_COLUMN, + RENEWABLE_COLUMN, + PROXIABLE_COLUMN, + N_COLUMNS +}; + + +GtkWindow *ka_main_window_create (KaApplet *applet, GtkBuilder *xml); +void ka_main_window_show (void); +void ka_main_window_hide (void); + + +#endif diff --git a/src/ka-preferences.c b/src/ka-preferences.c new file mode 100644 index 0000000..a80f6d9 --- /dev/null +++ b/src/ka-preferences.c @@ -0,0 +1,689 @@ +/* + * Copyright (C) 2011 Guido Guenther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" +#include "ka-preferences.h" + +#include "ka-gconf-tools.h" +#include "ka-tools.h" + +#include + +#define WID(b, w) (GtkWidget *) gtk_builder_get_object (b, w) + +#define PKINIT_SMARTCARD "PKCS11:" SC_PKCS11 +#define PKINIT_FILE "FILE:" + +#define N_LISTENERS 7 + +struct _KaPreferencesPrivate { + GtkBuilder *builder; + + GConfClient *client; + + GtkWidget *dialog; + GtkWidget *notebook; + GtkWidget *principal_entry; + GtkWidget *pkuserid_entry; + GtkWidget *pkuserid_button; + GtkWidget *smartcard_toggle; + GtkWidget *pkanchors_entry; + GtkWidget *pkanchors_button; + GtkWidget *forwardable_toggle; + GtkWidget *proxiable_toggle; + GtkWidget *renewable_toggle; + GtkWidget *prompt_mins_entry; + + guint listeners [N_LISTENERS]; + int n_listeners; +} prefs; + + +static void +ka_preferences_principal_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + const char *principal; + + if (!entry->value || entry->value->type != GCONF_VALUE_STRING) + return; + + principal = gconf_value_get_string (entry->value); + + if (!principal || !strlen(principal)) + gtk_entry_set_text (GTK_ENTRY (prefs.principal_entry), ""); + else { + const char *old_principal; + + old_principal = gtk_entry_get_text (GTK_ENTRY (prefs.principal_entry)); + if (!old_principal || (old_principal && strcmp (old_principal, principal))) + gtk_entry_set_text (GTK_ENTRY (prefs.principal_entry), principal); + } +} + +static void +ka_preferences_principal_changed (GtkEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + const char *principal; + + principal = gtk_entry_get_text (entry); + + if (!principal || !strlen(principal)) + gconf_client_unset (prefs.client, KA_GCONF_KEY_PRINCIPAL, NULL); + else + gconf_client_set_string (prefs.client, KA_GCONF_KEY_PRINCIPAL, principal, NULL); +} + + +static void +ka_preferences_setup_principal_entry () +{ + char *principal = NULL; + + prefs.principal_entry = WID (prefs.builder, "principal_entry"); + g_assert (prefs.principal_entry != NULL); + + if (!ka_gconf_get_string (prefs.client, KA_GCONF_KEY_PRINCIPAL, &principal)) + g_warning ("Getting principal failed"); + + if (principal && strlen(principal)) + gtk_entry_set_text (GTK_ENTRY (prefs.principal_entry), principal); + if (principal) + g_free (principal); + + g_signal_connect (prefs.principal_entry, "changed", + G_CALLBACK (ka_preferences_principal_changed), NULL); + + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_PRINCIPAL, NULL)) { + gtk_widget_set_sensitive (prefs.principal_entry, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_PRINCIPAL, + (GConfClientNotifyFunc) ka_preferences_principal_notify, + NULL, NULL, NULL); + prefs.n_listeners++; +} + + +static void +ka_preferences_pkuserid_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer *userdata G_GNUC_UNUSED) +{ + const char *pkuserid; + + if (!entry->value || entry->value->type != GCONF_VALUE_STRING) + return; + + pkuserid = gconf_value_get_string (entry->value); + + if (!pkuserid || !strlen(pkuserid)) + gtk_entry_set_text (GTK_ENTRY (prefs.pkuserid_entry), ""); + else { + const char *old_pkuserid; + + old_pkuserid = gtk_entry_get_text (GTK_ENTRY (prefs.pkuserid_entry)); + if (!old_pkuserid || (old_pkuserid && strcmp (old_pkuserid, pkuserid))) + gtk_entry_set_text (GTK_ENTRY (prefs.pkuserid_entry), pkuserid); + } +} + + +static void +ka_preferences_pkuserid_changed (GtkEntry *entry, + gpointer *user_data G_GNUC_UNUSED) +{ + const char *pkuserid; + + pkuserid = gtk_entry_get_text (entry); + + if (!pkuserid || !strlen(pkuserid)) + gconf_client_unset (prefs.client, KA_GCONF_KEY_PK_USERID, NULL); + else + gconf_client_set_string (prefs.client, KA_GCONF_KEY_PK_USERID, pkuserid, NULL); +} + + +static void +ka_preferences_setup_pkuserid_entry () +{ + char *pkuserid = NULL; + + prefs.pkuserid_entry = WID(prefs.builder, "pkuserid_entry"); + g_assert (prefs.pkuserid_entry != NULL); + + if (!ka_gconf_get_string (prefs.client, KA_GCONF_KEY_PK_USERID, &pkuserid)) + g_warning ("Getting pkuserid failed"); + + if (pkuserid && strlen(pkuserid)) + gtk_entry_set_text (GTK_ENTRY (prefs.pkuserid_entry), pkuserid); + if (pkuserid) + g_free (pkuserid); + + g_signal_connect (prefs.pkuserid_entry, "changed", + G_CALLBACK (ka_preferences_pkuserid_changed), NULL); + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_PK_USERID, NULL)) { + gtk_widget_set_sensitive (prefs.pkuserid_entry, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_PK_USERID, + (GConfClientNotifyFunc) ka_preferences_pkuserid_notify, + NULL, NULL, NULL); + prefs.n_listeners++; +} + + +static void +ka_preferences_pkanchors_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + const char *pkanchors; + + if (!entry->value || entry->value->type != GCONF_VALUE_STRING) + return; + + pkanchors = gconf_value_get_string (entry->value); + + if (!pkanchors || !strlen(pkanchors)) + gtk_entry_set_text (GTK_ENTRY (prefs.pkanchors_entry), ""); + else { + const char *old_pkanchors; + + old_pkanchors = gtk_entry_get_text (GTK_ENTRY (prefs.pkanchors_entry)); + if (!old_pkanchors || (old_pkanchors && strcmp (old_pkanchors, pkanchors))) + gtk_entry_set_text (GTK_ENTRY (prefs.pkanchors_entry), pkanchors); + } +} + + +static void +ka_preferences_pkanchors_changed (GtkEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + const char *pkanchors; + + pkanchors = gtk_entry_get_text (entry); + + if (!pkanchors || !strlen(pkanchors)) + gconf_client_unset (prefs.client, KA_GCONF_KEY_PK_ANCHORS, NULL); + else + gconf_client_set_string (prefs.client, KA_GCONF_KEY_PK_ANCHORS, + pkanchors, NULL); +} + + +static void +ka_preferences_setup_pkanchors_entry () +{ + char *pkanchors = NULL; + + prefs.pkanchors_entry = WID(prefs.builder, "pkanchors_entry"); + g_assert (prefs.pkanchors_entry != NULL); + + if (!ka_gconf_get_string (prefs.client, KA_GCONF_KEY_PK_ANCHORS, &pkanchors)) + g_warning ("Getting pkanchors failed"); + + if (pkanchors && strlen(pkanchors)) + gtk_entry_set_text (GTK_ENTRY (prefs.pkanchors_entry), pkanchors); + if (pkanchors) + g_free (pkanchors); + + g_signal_connect (prefs.pkanchors_entry, "changed", + G_CALLBACK (ka_preferences_pkanchors_changed), NULL); + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_PK_ANCHORS, NULL)) { + gtk_widget_set_sensitive (prefs.pkanchors_entry, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_PK_ANCHORS, + (GConfClientNotifyFunc) ka_preferences_pkanchors_notify, + NULL, NULL, NULL); + prefs.n_listeners++; +} + + +static void +ka_preferences_toggle_pkuserid_entry (gboolean state, gpointer userdata G_GNUC_UNUSED) +{ + gtk_widget_set_sensitive (prefs.pkuserid_entry, state); + gtk_widget_set_sensitive (prefs.pkuserid_button, state); +} + + +static void +ka_preferences_smartcard_toggled (GtkToggleButton *toggle, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean smartcard = gtk_toggle_button_get_active (toggle); + static gchar *old_path = NULL; + + if (smartcard) { + const char *path; + + path = gtk_entry_get_text (GTK_ENTRY(prefs.pkuserid_entry)); + if (g_strcmp0 (path, PKINIT_SMARTCARD)) { + g_free (old_path); + old_path = g_strdup (path); + } + ka_preferences_toggle_pkuserid_entry (FALSE, NULL); + gconf_client_set_string (prefs.client, KA_GCONF_KEY_PK_USERID, PKINIT_SMARTCARD, NULL); + } else { + ka_preferences_toggle_pkuserid_entry (TRUE, NULL); + if (old_path) + gconf_client_set_string (prefs.client, KA_GCONF_KEY_PK_USERID, old_path, NULL); + else + gconf_client_unset (prefs.client, KA_GCONF_KEY_PK_USERID, NULL); + } +} + + +static void +ka_preferences_setup_smartcard_toggle () +{ + char *pkuserid = NULL; + + prefs.smartcard_toggle = WID (prefs.builder, "smartcard_toggle"); + g_assert (prefs.smartcard_toggle != NULL); + + if (!ka_gconf_get_string (prefs.client, KA_GCONF_KEY_PK_USERID, &pkuserid)) + g_warning ("Getting pkanchors failed"); + + g_signal_connect (prefs.smartcard_toggle, "toggled", + G_CALLBACK (ka_preferences_smartcard_toggled), NULL); + + if (!g_strcmp0 (pkuserid, PKINIT_SMARTCARD)) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.smartcard_toggle), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.smartcard_toggle), FALSE); + + if (pkuserid) + g_free (pkuserid); +} + + +static void +ka_preferences_browse_certs (GtkEntry *entry) +{ + GtkWidget *filechooser; + GtkFileFilter *cert_filter, *all_filter; + gchar *filename = NULL; + const gchar *current; + gint ret; + + filechooser = gtk_file_chooser_dialog_new(_("Choose Certificate"), + GTK_WINDOW (prefs.dialog), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + current = gtk_entry_get_text (entry); + if (current && g_str_has_prefix (current, PKINIT_FILE) && + strlen(current) > strlen (PKINIT_FILE)) { + gtk_file_chooser_select_filename (GTK_FILE_CHOOSER(filechooser), + (const gchar*)¤t[strlen(PKINIT_FILE)]); + } + + cert_filter = g_object_ref_sink (gtk_file_filter_new ()); + gtk_file_filter_add_mime_type (cert_filter, "application/x-x509-ca-cert"); + gtk_file_filter_set_name (cert_filter, _("X509 Certificates")); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filechooser), cert_filter); + all_filter = g_object_ref_sink (gtk_file_filter_new ()); + gtk_file_filter_add_pattern (all_filter, "*"); + gtk_file_filter_set_name (all_filter, _("all files")); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filechooser), all_filter); + + ret = gtk_dialog_run (GTK_DIALOG(filechooser)); + if (ret == GTK_RESPONSE_ACCEPT) + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(filechooser)); + gtk_widget_destroy (GTK_WIDGET(filechooser)); + + if (filename) { + gchar *cert = g_strconcat( PKINIT_FILE, filename, NULL); + gtk_entry_set_text (entry, cert); + g_free (filename); + g_free (cert); + } + g_object_unref (cert_filter); + g_object_unref (all_filter); +} + +static void +ka_preferences_browse_pkuserids (GtkButton *button G_GNUC_UNUSED, + gpointer userdata G_GNUC_UNUSED) +{ + ka_preferences_browse_certs (GTK_ENTRY(prefs.pkuserid_entry)); +} + +static void +ka_preferences_browse_pkanchors(GtkButton *button G_GNUC_UNUSED, + gpointer userdata G_GNUC_UNUSED) +{ + ka_preferences_browse_certs (GTK_ENTRY(prefs.pkanchors_entry)); +} + +static void +ka_preferences_setup_pkuserid_button () +{ + prefs.pkuserid_button = WID (prefs.builder, "pkuserid_button"); + g_assert (prefs.pkuserid_button != NULL); + + g_signal_connect (prefs.pkuserid_button, "clicked", + G_CALLBACK (ka_preferences_browse_pkuserids), NULL); + +} + +static void +ka_preferences_setup_pkanchors_button () +{ + prefs.pkanchors_button = WID (prefs.builder, "pkanchors_button"); + g_assert (prefs.pkanchors_button != NULL); + + g_signal_connect (prefs.pkanchors_button, "clicked", + G_CALLBACK (ka_preferences_browse_pkanchors), NULL); + +} + + +static void +ka_preferences_forwardable_toggled (GtkToggleButton *toggle, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean forwardable; + + forwardable = gtk_toggle_button_get_active (toggle); + + gconf_client_set_bool (prefs.client, KA_GCONF_KEY_FORWARDABLE, forwardable, NULL); +} + + +static void +ka_preferences_forwardable_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean forwardable; + + if (!entry->value || entry->value->type != GCONF_VALUE_BOOL) + return; + + forwardable = gconf_value_get_bool (entry->value) != FALSE; + + if (forwardable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs.forwardable_toggle))) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.forwardable_toggle), forwardable); +} + + +static gboolean +ka_preferences_setup_forwardable_toggle () +{ + gboolean forwardable; + + prefs.forwardable_toggle = WID (prefs.builder, "forwardable_toggle"); + g_assert (prefs.forwardable_toggle != NULL); + + forwardable = gconf_client_get_bool (prefs.client, KA_GCONF_KEY_FORWARDABLE, NULL); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.forwardable_toggle), forwardable); + + g_signal_connect (prefs.forwardable_toggle, "toggled", + G_CALLBACK (ka_preferences_forwardable_toggled), NULL); + + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_FORWARDABLE, NULL)) { + gtk_widget_set_sensitive (prefs.forwardable_toggle, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_FORWARDABLE, + (GConfClientNotifyFunc) ka_preferences_forwardable_notify, + NULL, NULL, NULL); + prefs.n_listeners++; + return forwardable; +} + + +static void +ka_preferences_proxiable_toggled (GtkToggleButton *toggle, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean proxiable; + + proxiable = gtk_toggle_button_get_active (toggle); + + gconf_client_set_bool (prefs.client, KA_GCONF_KEY_PROXIABLE, proxiable, NULL); +} + + +static void +ka_preferences_proxiable_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean proxiable; + + if (!entry->value || entry->value->type != GCONF_VALUE_BOOL) + return; + + proxiable = gconf_value_get_bool (entry->value) != FALSE; + + if (proxiable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs.proxiable_toggle))) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.proxiable_toggle), proxiable); +} + + +static gboolean +ka_preferences_setup_proxiable_toggle () +{ + gboolean proxiable; + + prefs.proxiable_toggle = WID (prefs.builder, "proxiable_toggle"); + g_assert (prefs.proxiable_toggle != NULL); + + proxiable = gconf_client_get_bool (prefs.client, KA_GCONF_KEY_PROXIABLE, NULL); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.proxiable_toggle), proxiable); + + g_signal_connect (prefs.proxiable_toggle, "toggled", + G_CALLBACK (ka_preferences_proxiable_toggled), NULL); + + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_PROXIABLE, NULL)) { + gtk_widget_set_sensitive (prefs.proxiable_toggle, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_PROXIABLE, + (GConfClientNotifyFunc) ka_preferences_proxiable_notify, + NULL, NULL, NULL); + prefs.n_listeners++; + return proxiable; +} + + +static void +ka_preferences_renewable_toggled (GtkToggleButton *toggle, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean renewable; + + renewable = gtk_toggle_button_get_active (toggle); + + gconf_client_set_bool (prefs.client, KA_GCONF_KEY_RENEWABLE, renewable, NULL); +} + + +static void +ka_preferences_renewable_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + gboolean renewable; + + if (!entry->value || entry->value->type != GCONF_VALUE_BOOL) + return; + + renewable = gconf_value_get_bool (entry->value) != FALSE; + + if (renewable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs.renewable_toggle))) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.renewable_toggle), renewable); +} + + +static gboolean +ka_preferences_setup_renewable_toggle () +{ + gboolean renewable; + + prefs.renewable_toggle = WID (prefs.builder, "renewable_toggle"); + g_assert (prefs.renewable_toggle != NULL); + + renewable = gconf_client_get_bool (prefs.client, KA_GCONF_KEY_RENEWABLE, NULL); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs.renewable_toggle), renewable); + + g_signal_connect (prefs.renewable_toggle, "toggled", + G_CALLBACK (ka_preferences_renewable_toggled), NULL); + + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_RENEWABLE, NULL)) { + gtk_widget_set_sensitive (prefs.renewable_toggle, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_RENEWABLE, + (GConfClientNotifyFunc) ka_preferences_renewable_notify, + NULL, NULL, NULL); + prefs.n_listeners++; + return renewable; +} + + +static void +ka_preferences_prompt_mins_changed (GtkSpinButton *button, + gpointer userdata G_GNUC_UNUSED) +{ + gint prompt_mins; + + prompt_mins = gtk_spin_button_get_value_as_int (button); + gconf_client_set_int (prefs.client, KA_GCONF_KEY_PROMPT_MINS, prompt_mins, NULL); +} + + +static void +ka_preferences_prompt_mins_notify (GConfClient *client G_GNUC_UNUSED, + guint cnx_id G_GNUC_UNUSED, + GConfEntry *entry, + gpointer userdata G_GNUC_UNUSED) +{ + gint prompt_mins; + + if (!entry->value || entry->value->type != GCONF_VALUE_INT) + return; + + prompt_mins = gconf_value_get_int (entry->value); + + if (prompt_mins != gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (prefs.prompt_mins_entry))) + gtk_spin_button_set_value (GTK_SPIN_BUTTON (prefs.prompt_mins_entry), prompt_mins); +} + + +static gint +ka_preferences_setup_prompt_mins_entry () +{ + gint prompt_mins; + + prefs.prompt_mins_entry = WID (prefs.builder, "prompt_mins_entry"); + g_assert (prefs.prompt_mins_entry != NULL); + + prompt_mins = gconf_client_get_int (prefs.client, KA_GCONF_KEY_PROMPT_MINS, NULL); + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (prefs.prompt_mins_entry), prompt_mins); + + g_signal_connect (prefs.prompt_mins_entry, "value-changed", + G_CALLBACK (ka_preferences_prompt_mins_changed), NULL); + + if (!gconf_client_key_is_writable (prefs.client, KA_GCONF_KEY_PROMPT_MINS, NULL)) { + gtk_widget_set_sensitive (prefs.prompt_mins_entry, FALSE); + } + + prefs.listeners [prefs.n_listeners] = + gconf_client_notify_add (prefs.client, + KA_GCONF_KEY_PROMPT_MINS, + (GConfClientNotifyFunc) ka_preferences_prompt_mins_notify, + NULL, NULL, NULL); + prefs.n_listeners++; + return prompt_mins; +} + + +void +ka_preferences_window_create (KaApplet *applet G_GNUC_UNUSED, + GtkBuilder *xml) +{ + prefs.client = gconf_client_get_default (); + gconf_client_add_dir (prefs.client, KA_GCONF_PATH, + GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); + + prefs.builder = xml; + ka_preferences_setup_principal_entry (prefs); + ka_preferences_setup_pkuserid_entry (prefs); + ka_preferences_setup_pkuserid_button (prefs); + ka_preferences_setup_smartcard_toggle (prefs); + ka_preferences_setup_pkanchors_entry(prefs); + ka_preferences_setup_pkanchors_button (prefs); + ka_preferences_setup_forwardable_toggle (prefs); + ka_preferences_setup_proxiable_toggle (prefs); + ka_preferences_setup_renewable_toggle (prefs); + ka_preferences_setup_prompt_mins_entry (prefs); + + g_assert (prefs.n_listeners == N_LISTENERS); + + prefs.notebook = WID (xml, "ka_notebook"); + prefs.dialog = WID (xml, "krb5_preferences_dialog"); + +} + +void +ka_preferences_window_show (GtkWindow *main_window) +{ + if (main_window) + gtk_window_set_transient_for (GTK_WINDOW(prefs.dialog), main_window); + gtk_window_present (GTK_WINDOW(prefs.dialog)); + gtk_dialog_run (GTK_DIALOG (prefs.dialog)); + gtk_widget_hide (prefs.dialog); +} + +/* + * vim:ts:sts=4:sw=4:et: + */ diff --git a/src/ka-preferences.h b/src/ka-preferences.h new file mode 100644 index 0000000..7f8e9a2 --- /dev/null +++ b/src/ka-preferences.h @@ -0,0 +1,21 @@ +/* ka-preferences.h */ + +#ifndef KA_PREFERENCES_H +#define KA_PREFERENCES_H + +#include + +#include "ka-applet.h" + +G_BEGIN_DECLS + +void ka_preferences_window_create (KaApplet *applet, GtkBuilder *xml); +void ka_preferences_window_show (GtkWindow *main_window); + +G_END_DECLS + +#endif /* KA_PREFERENCES */ + +/* + * vim:ts:sts=4:sw=4:et: + */ diff --git a/src/ka-pwdialog.c b/src/ka-pwdialog.c index 49ed2e4..483873a 100644 --- a/src/ka-pwdialog.c +++ b/src/ka-pwdialog.c @@ -23,7 +23,7 @@ #include #include "ka-applet-priv.h" -#include "ka-dialog.h" +#include "ka-kerberos.h" #include "ka-pwdialog.h" #include "ka-entry-buffer.h" diff --git a/src/ka-tickets.c b/src/ka-tickets.c deleted file mode 100644 index ce01fce..0000000 --- a/src/ka-tickets.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Krb5 Auth Applet -- Acquire and release kerberos tickets - * - * (C) 2009 Guido Guenther - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "config.h" - -#include -#include - -#include "ka-tickets.h" -#include "ka-dialog.h" - -static GtkListStore *tickets; -static GtkWidget *tickets_dialog; - -GtkWidget * -ka_tickets_dialog_create (GtkBuilder *xml) -{ - GtkCellRenderer *text_renderer, *toggle_renderer; - GtkTreeView *tickets_view; - - tickets = gtk_list_store_new (N_COLUMNS, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); - - tickets_dialog = - GTK_WIDGET (gtk_builder_get_object (xml, "krb5_tickets_dialog")); - tickets_view = - GTK_TREE_VIEW (gtk_builder_get_object (xml, "krb5_tickets_treeview")); - gtk_tree_view_set_model (GTK_TREE_VIEW (tickets_view), - GTK_TREE_MODEL (tickets)); - - text_renderer = gtk_cell_renderer_text_new (); - toggle_renderer = gtk_cell_renderer_toggle_new (); - - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("Principal"), - text_renderer, - "text", - PRINCIPAL_COLUMN, - NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("Start Time"), - text_renderer, - "text", - START_TIME_COLUMN, - NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("End Time"), - text_renderer, - "markup", - END_TIME_COLUMN, - NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("Fwd"), - toggle_renderer, - "active", - FORWARDABLE_COLUMN, - NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("Proxy"), - toggle_renderer, - "active", - PROXIABLE_COLUMN, - NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tickets_view), -1, - _("Renew"), - toggle_renderer, - "active", - RENEWABLE_COLUMN, - NULL); - return tickets_dialog; -} - -void -ka_tickets_dialog_run () -{ - if (ka_get_service_tickets (tickets)) { - gtk_window_present (GTK_WINDOW (tickets_dialog)); - gtk_dialog_run (GTK_DIALOG (tickets_dialog)); - gtk_widget_hide (tickets_dialog); - } else { - GtkWidget *message_dialog; - - message_dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _ - ("Error displaying service ticket information")); - gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE); - - g_signal_connect (message_dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show (message_dialog); - } -} diff --git a/src/ka-tickets.h b/src/ka-tickets.h deleted file mode 100644 index 2a8aa3f..0000000 --- a/src/ka-tickets.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Krb5 Auth Applet -- Acquire and release kerberos tickets - * - * (C) 2009 Guido Guenther - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef KA_TICKETS_H -#define KA_TICKETS_H - -enum ticket_columns { - PRINCIPAL_COLUMN, - START_TIME_COLUMN, - END_TIME_COLUMN, - FORWARDABLE_COLUMN, - RENEWABLE_COLUMN, - PROXIABLE_COLUMN, - N_COLUMNS -}; - - -GtkWidget *ka_tickets_dialog_create (GtkBuilder *xml); -void ka_tickets_dialog_run (void); - - -#endif diff --git a/src/ka-tools.c b/src/ka-tools.c index 260d101..227324a 100644 --- a/src/ka-tools.c +++ b/src/ka-tools.c @@ -55,3 +55,31 @@ ka_show_help (GdkScreen* screen, const char* chapter, GtkWindow* window) } g_free (url); } + + +void +ka_show_about () +{ + const gchar *authors[] = { + "Christopher Aillon ", + "Jonathan Blandford ", + "Colin Walters ", + "Guido Günther ", + NULL + }; + + gtk_show_about_dialog (NULL, + "authors", authors, + "version", VERSION, + "logo-icon-name", "krb-valid-ticket", + "copyright", + "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n" + "2008-2011 Guido Günther", + "website-label", PACKAGE " website", + "website", + "https://honk.sigxcpu.org/piki/projects/krb5-auth-dialog/", + "license", "GNU General Public License Version 2", + /* Translators: add the translators of your language here */ + "translator-credits", _("translator-credits"), + NULL); +} diff --git a/src/ka-tools.h b/src/ka-tools.h index f97791b..4fef541 100644 --- a/src/ka-tools.h +++ b/src/ka-tools.h @@ -26,6 +26,7 @@ G_BEGIN_DECLS void ka_show_help (GdkScreen* screen, const char* section, GtkWindow* window); +void ka_show_about (void); G_END_DECLS diff --git a/src/krb5-auth-dialog.desktop.in b/src/krb5-auth-dialog.desktop.in index 5569646..6f02571 100644 --- a/src/krb5-auth-dialog.desktop.in +++ b/src/krb5-auth-dialog.desktop.in @@ -4,7 +4,6 @@ _Comment=Kerberos Network Authentication Dialog Exec=krb5-auth-dialog Terminal=false Type=Application -NoDisplay=true Icon=krb-valid-ticket X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=krb5-auth-dialog diff --git a/src/krb5-auth-dialog.ui b/src/krb5-auth-dialog.ui index f36f537..1da04d7 100644 --- a/src/krb5-auth-dialog.ui +++ b/src/krb5-auth-dialog.ui @@ -1,47 +1,106 @@ - + - + + 100 + 1 + 10 + + False 6 Kerberos Authentication False center-always dialog - + True + False + + + True + False + end + + + gtk-cancel + True + True + True + False + False + True + + + False + False + 0 + + + + + _Renew Ticket + True + True + True + True + False + False + True + + + False + False + 1 + + + + + False + True + end + 0 + + True + False 6 12 True + False 0 krb-valid-ticket 6 False + True 0 True + False 10 True + False 12 True + False True + False 0 True @@ -53,28 +112,35 @@ + True + True 0 True + False 3 True + False 3 + True + True 0 True + False 1 <span size="smaller"> </span> True @@ -87,6 +153,8 @@ + True + True 1 @@ -94,123 +162,933 @@ + True + True 1 + False + True 1 - - + + + + cancelbutton1 + krb5_renew_button + + + + False + Service Tickets + + + + True + False + + True - end + False - - gtk-cancel + True - True - True - False - True + False + False + _File + True + + + True + False + + + gtk-close + True + False + False + True + True + + + + - - False - False - 0 - - - _Renew Ticket + True - True - True - True - False + False + False + _Edit True + + + True + False + + + gtk-preferences + True + False + False + True + True + + + + + + + + + True + False + False + _Help + True + + + True + False + + + gtk-help + True + False + False + True + True + + + + + gtk-about + True + False + False + True + True + + + + - - False - False - 1 - False - end + True 0 + + + True + True + + + + + + True + True + 1 + + - - cancelbutton1 - krb5_renew_button - - + + False 5 - Service Tickets - False - normal + dialog - - True + + False vertical 2 - - - True - vertical + + + False + end - + + + + + gtk-close True True + True + False + True - 0 + False + True + 1 - 1 + False + True + end + 0 - - + + True - end + True - + + True + False + 12 + 18 + + + True + False + 12 + + + True + False + 0 + Kerberos User + + + + + + False + False + 0 + + + + + True + False + 12 + + + True + False + 0 + krb-valid-ticket + 6 + + + False + False + 0 + + + + + True + False + 6 + + + True + False + 0 + none + + + True + False + 5 + 12 + + + True + True + True + The name of your Kerberos account. Leave blank to use your current username. + The name of your Kerberos account. Leave blank to use your current username. + + True + True + + + + + + + True + False + Kerberos principal: + True + + + + + True + True + 0 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + True + 0 + + + + + True + False + 12 + + + True + False + 0 + Kerberos Ticket Options + + + + + + False + True + 0 + + + + + True + False + 12 + + + True + False + 0 + gtk-properties + 6 + + + False + False + 0 + + + + + True + False + 6 + + + True + False + 0 + Requested Kerberos tickets should be: + + + False + False + 0 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + forwardable + True + True + False + True + If checked, request forwardable tickets + If checked, request forwardable tickets + False + 0 + True + + + False + False + 1 + + + + + False + False + 1 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + renewable + True + True + False + True + If checked, request renewable tickets + If checked, request renewable tickets + False + 0 + True + + + False + False + 1 + + + + + True + True + 2 + + + + + True + False + + + True + False + + + + False + False + 0 + + + + + proxiable + True + True + False + True + If checked, request proxiable tickets + If checked, request proxiable tickets + False + 0 + True + + + False + False + 1 + + + + + True + True + 3 + + + + + True + True + 1 + + + + + True + True + 1 + + + + + False + True + 1 + + + + + + + True + False + Kerberos + + + False + - - gtk-close + True - True - True - True + False + start + 12 + 18 + + + True + False + 12 + + + True + False + 0 + Userid + + + + + + False + False + 0 + + + + + True + False + 12 + + + True + False + 0 + krb-valid-ticket + 6 + + + False + False + 0 + + + + + True + False + 6 + + + True + False + + + True + False + + + Use Smartcard + True + True + False + True + If checked, use a security token (Smartcard) to authenticate. + If checked, use a security token (Smartcard) to authenticate. + False + 0 + True + + + False + True + 0 + + + + + True + False + + + True + True + 1 + + + + + False + True + 0 + + + + + True + False + + + True + True + True + Certificate and private key used for authentication + Certificate and private key used for authentication + + True + True + + + True + True + 0 + + + + + _Browse... + True + True + True + False + True + + + False + True + 5 + 1 + + + + + False + True + 1 + + + + + True + True + 0 + + + + + True + True + 1 + + + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + 12 + + + True + False + 0 + X509 trust anchors + + + + + + False + False + 0 + + + + + True + False + + + True + True + True + Certificate used to verify digital signatures. + Certificate used to verify digital signatures. + + True + True + + + True + True + 0 + + + + + _Browse... + True + True + True + False + True + + + False + True + 5 + 1 + + + + + False + True + 1 + + + + + False + True + 2 + + + + + 1 + + + + + True + False + True + Configure the use of certificates and smartcards for your Kerberos network authentication. + Configure the use of certificates and smartcards for your Kerberos network authentication. + PKINIT - False - False 1 + False + + + + + True + False + 12 + 18 + + + True + False + 12 + + + True + False + 0 + Notifications + + + + + + False + False + 0 + + + + + True + False + 12 + + + True + False + 0 + krb-expiring-ticket + 6 + + + False + False + 0 + + + + + True + False + 6 + + + True + False + + + + False + False + 0 + + + + + True + False + Warn + + + False + False + 1 + + + + + True + True + True + Send notification about ticket expiry that many minutes before it finally expires + Send notification about ticket expiry that many minutes before it finally expires + + True + True + True + adjustment1 + + + False + False + 2 + + + + + True + False + minutes before ticket expiry + + + False + False + 3 + + + + + False + True + 1 + + + + + False + True + 1 + + + + + False + True + 0 + + + + + 2 + + + + + True + False + Notifications + + + 2 + False False - end - 0 + True + 1 - krb5_tickets_ok + button1 -- cgit