diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.cvsignore | 5 | ||||
-rw-r--r-- | src/Makefile.am | 37 | ||||
-rw-r--r-- | src/Makefile.in | 621 | ||||
-rw-r--r-- | src/dummy-strings.c | 6 | ||||
-rw-r--r-- | src/krb5-auth-applet.c | 265 | ||||
-rw-r--r-- | src/krb5-auth-applet.h | 68 | ||||
-rw-r--r-- | src/krb5-auth-dbus.c | 78 | ||||
-rw-r--r-- | src/krb5-auth-dbus.h | 28 | ||||
-rw-r--r-- | src/krb5-auth-dialog.c | 650 | ||||
-rw-r--r-- | src/krb5-auth-dialog.glade | 2 | ||||
-rw-r--r-- | src/krb5-auth-dialog.h | 30 | ||||
-rw-r--r-- | src/krb5-auth-dialog.schemas.in | 39 | ||||
-rw-r--r-- | src/krb5-auth-gconf.c | 206 | ||||
-rw-r--r-- | src/krb5-auth-gconf.h | 28 | ||||
-rw-r--r-- | src/krb5-auth-notify.c | 57 | ||||
-rw-r--r-- | src/krb5-auth-notify.h | 32 |
16 files changed, 1292 insertions, 860 deletions
diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 0000000..b18d7e7 --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +krb5-auth-dialog +krb5-auth-dialog.1 +krb5-auth-dialog.desktop diff --git a/src/Makefile.am b/src/Makefile.am index 282e938..d165710 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,6 @@ -INCLUDES = \ - -DGLADEDIR=\""$(datadir)/krb5-auth-dialog/"\" +INCLUDES = \ + -DGLADEDIR=\""$(gladedir)/"\" \ + -DLOCALE_DIR=\""$(localedir)/"\" bin_PROGRAMS = krb5-auth-dialog man_MANS = krb5-auth-dialog.1 @@ -11,9 +12,29 @@ autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) krb5_auth_dialog_SOURCES = \ krb5-auth-dialog.c \ + krb5-auth-dialog.h \ + krb5-auth-applet.c \ + krb5-auth-applet.h \ + krb5-auth-gconf.c \ + krb5-auth-gconf.h \ + krb5-auth-notify.c \ + krb5-auth-notify.h \ + krb5-auth-dbus.c \ + krb5-auth-dbus.h \ dummy-strings.c -krb5_auth_dialog_LDADD = @NETWORK_MANAGER_LIBS@ @KRB5_LIBS@ @GNOME_LIBS@ +krb5_auth_dialog_LDADD = \ + ../gtksecentry/libgtksecentry.a \ + ../secmem/libsecmem.a \ + @NETWORK_MANAGER_LIBS@ \ + @KRB5_LIBS@ \ + @LIBNOTIFY_LIBS@ \ + @DBUS_LIBS@ \ + @GCONF_LIBS@ \ + @GLADE_LIBS@ \ + @GTK_LIBS@ + +AM_CPPFLAGS = -I $(top_srcdir)/gtksecentry/ -I $(top_srcdir)/secmem/ gladedir = $(datadir)/krb5-auth-dialog glade_DATA = \ @@ -22,6 +43,16 @@ glade_DATA = \ EXTRA_DIST = \ $(glade_DATA) \ $(autostart_in_files) \ + $(schema_SOURCES) \ krb5-auth-dialog.1.in +schemadir = $(sysconfdir)/gconf/schemas +schema_SOURCES = $(PACKAGE).schemas.in +schema_DATA = $(PACKAGE).schemas + DISTCLEANFILES = krb5-auth-dialog.desktop +CLEANFILES = $(schema_DATA) + +%.schemas: $(srcdir)/%.schemas.in + sed -e "s,::PACKAGE::,$(PACKAGE)," -e "s,::MINIMUM_LIFETIME::,$(minimum_lifetime)," < $< > $@ + diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index 630ddd3..0000000 --- a/src/Makefile.in +++ /dev/null @@ -1,621 +0,0 @@ -# Makefile.in generated by automake 1.7.9 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_triplet = @host@ -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ENABLE_NETWORK_MANAGER_FALSE = @ENABLE_NETWORK_MANAGER_FALSE@ -ENABLE_NETWORK_MANAGER_TRUE = @ENABLE_NETWORK_MANAGER_TRUE@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GMOFILES = @GMOFILES@ -GMSGFMT = @GMSGFMT@ -GNOME_CFLAGS = @GNOME_CFLAGS@ -GNOME_LIBS = @GNOME_LIBS@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ -INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ -INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_ICONV = @INTLTOOL_ICONV@ -INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@ -INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@ -INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@ -INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ -INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ -INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ -INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ -INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ -INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ -INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ -INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@ -INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@ -INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@ -INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ -KRB5_CFLAGS = @KRB5_CFLAGS@ -KRB5_CONFIG = @KRB5_CONFIG@ -KRB5_LIBS = @KRB5_LIBS@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ -MAKEINFO = @MAKEINFO@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -MSGFMT = @MSGFMT@ -NETWORK_MANAGER_CFLAGS = @NETWORK_MANAGER_CFLAGS@ -NETWORK_MANAGER_LIBS = @NETWORK_MANAGER_LIBS@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -POFILES = @POFILES@ -POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -YACC = @YACC@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -check_interval = @check_interval@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -minimum_lifetime = @minimum_lifetime@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -INCLUDES = \ - -DGLADEDIR=\""$(datadir)/krb5-auth-dialog/"\" - - -bin_PROGRAMS = krb5-auth-dialog -man_MANS = krb5-auth-dialog.1 - -autostartdir = $(sysconfdir)/xdg/autostart -autostart_in_files = krb5-auth-dialog.desktop.in -autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) - -krb5_auth_dialog_SOURCES = \ - krb5-auth-dialog.c \ - dummy-strings.c - - -krb5_auth_dialog_LDADD = @NETWORK_MANAGER_LIBS@ @KRB5_LIBS@ @GNOME_LIBS@ - -gladedir = $(datadir)/krb5-auth-dialog -glade_DATA = \ - krb5-auth-dialog.glade - - -EXTRA_DIST = \ - $(glade_DATA) \ - $(autostart_in_files) \ - krb5-auth-dialog.1.in - - -DISTCLEANFILES = krb5-auth-dialog.desktop -subdir = src -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = krb5-auth-dialog.1 -bin_PROGRAMS = krb5-auth-dialog$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) - -am_krb5_auth_dialog_OBJECTS = krb5-auth-dialog.$(OBJEXT) \ - dummy-strings.$(OBJEXT) -krb5_auth_dialog_OBJECTS = $(am_krb5_auth_dialog_OBJECTS) -krb5_auth_dialog_DEPENDENCIES = -krb5_auth_dialog_LDFLAGS = - -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dummy-strings.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/krb5-auth-dialog.Po -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ - $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -DIST_SOURCES = $(krb5_auth_dialog_SOURCES) - -NROFF = nroff -MANS = $(man_MANS) -DATA = $(autostart_DATA) $(glade_DATA) - -DIST_COMMON = $(srcdir)/Makefile.in Makefile.am krb5-auth-dialog.1.in -SOURCES = $(krb5_auth_dialog_SOURCES) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile -Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -krb5-auth-dialog.1: $(top_builddir)/config.status krb5-auth-dialog.1.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - || test -f $$p1 \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ - rm -f $(DESTDIR)$(bindir)/$$f; \ - done - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -krb5-auth-dialog$(EXEEXT): $(krb5_auth_dialog_OBJECTS) $(krb5_auth_dialog_DEPENDENCIES) - @rm -f krb5-auth-dialog$(EXEEXT) - $(LINK) $(krb5_auth_dialog_LDFLAGS) $(krb5_auth_dialog_OBJECTS) $(krb5_auth_dialog_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy-strings.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5-auth-dialog.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ -@am__fastdepCC_TRUE@ fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< - -.c.obj: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ -@am__fastdepCC_TRUE@ fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` - -.c.lo: -@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ -@am__fastdepCC_TRUE@ fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -man1dir = $(mandir)/man1 -install-man1: $(man1_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(man1dir) - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 1*) ;; \ - *) ext='1' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ - done -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 1*) ;; \ - *) ext='1' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ - rm -f $(DESTDIR)$(man1dir)/$$inst; \ - done -autostartDATA_INSTALL = $(INSTALL_DATA) -install-autostartDATA: $(autostart_DATA) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(autostartdir) - @list='$(autostart_DATA)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(autostartDATA_INSTALL) $$d$$p $(DESTDIR)$(autostartdir)/$$f"; \ - $(autostartDATA_INSTALL) $$d$$p $(DESTDIR)$(autostartdir)/$$f; \ - done - -uninstall-autostartDATA: - @$(NORMAL_UNINSTALL) - @list='$(autostart_DATA)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " rm -f $(DESTDIR)$(autostartdir)/$$f"; \ - rm -f $(DESTDIR)$(autostartdir)/$$f; \ - done -gladeDATA_INSTALL = $(INSTALL_DATA) -install-gladeDATA: $(glade_DATA) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(gladedir) - @list='$(glade_DATA)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " $(gladeDATA_INSTALL) $$d$$p $(DESTDIR)$(gladedir)/$$f"; \ - $(gladeDATA_INSTALL) $$d$$p $(DESTDIR)$(gladedir)/$$f; \ - done - -uninstall-gladeDATA: - @$(NORMAL_UNINSTALL) - @list='$(glade_DATA)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ - echo " rm -f $(DESTDIR)$(gladedir)/$$f"; \ - rm -f $(DESTDIR)$(gladedir)/$$f; \ - done - -ETAGS = etags -ETAGSFLAGS = - -CTAGS = ctags -CTAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(autostartdir) $(DESTDIR)$(gladedir) -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f $(CONFIG_CLEAN_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: install-autostartDATA install-gladeDATA install-man - -install-exec-am: install-binPROGRAMS - -install-info: install-info-am - -install-man: install-man1 - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-autostartDATA uninstall-binPROGRAMS \ - uninstall-gladeDATA uninstall-info-am uninstall-man - -uninstall-man: uninstall-man1 - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am info info-am install install-am install-autostartDATA \ - install-binPROGRAMS install-data install-data-am install-exec \ - install-exec-am install-gladeDATA install-info install-info-am \ - install-man install-man1 install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-autostartDATA \ - uninstall-binPROGRAMS uninstall-gladeDATA uninstall-info-am \ - uninstall-man uninstall-man1 - -@INTLTOOL_DESKTOP_RULE@ -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/dummy-strings.c b/src/dummy-strings.c index adc8ea4..e107293 100644 --- a/src/dummy-strings.c +++ b/src/dummy-strings.c @@ -132,7 +132,7 @@ realm %s. %s."), /* kpasswd_strings.et:kpws:KPW_STR_CANT_OPEN_ADMIN_SERVER */ N_("while releasing permanent lock"), /* import_err.et:imp:IMPORT_RENAME_UNLOCK */ N_("while closing databases"), /* import_err.et:imp:IMPORT_RENAME_CLOSE */ N_("while retrieving configuration parameters"), /* import_err.et:imp:IMPORT_GET_PARAMS */ - N_("$Id: dummy-strings.c,v 1.2 2005/10/31 21:55:46 caillon Exp $"), /* kdc5_err.et:kdc5:KDC5_RCSID */ + N_("$Id$"), /* kdc5_err.et:kdc5:KDC5_RCSID */ N_("No server port found"), /* kdc5_err.et:kdc5:KDC5_NOPORT */ N_("Network not initialized"), /* kdc5_err.et:kdc5:KDC5_NONET */ N_("Short write while sending response"), /* kdc5_err.et:kdc5:KDC5_IO_RESPONSE */ @@ -385,7 +385,7 @@ realm %s. %s."), /* kpasswd_strings.et:kpws:KPW_STR_CANT_OPEN_ADMIN_SERVER */ N_("Bad magic number for passwd_phrase_element"), /* kv5m_err.et:kv5m:KV5M_PASSWD_PHRASE_ELEMENT */ N_("Bad magic number for GSSAPI OID"), /* kv5m_err.et:kv5m:KV5M_GSS_OID */ N_("Bad magic number for GSSAPI QUEUE"), /* kv5m_err.et:kv5m:KV5M_GSS_QUEUE */ - N_("$Id: dummy-strings.c,v 1.2 2005/10/31 21:55:46 caillon Exp $"), /* kdb5_err.et:kdb5:KRB5_KDB_RCSID */ + N_("$Id$"), /* kdb5_err.et:kdb5:KRB5_KDB_RCSID */ N_("Entry already exists in database"), /* kdb5_err.et:kdb5:KRB5_KDB_INUSE */ N_("Database store error"), /* kdb5_err.et:kdb5:KRB5_KDB_UK_SERROR */ N_("Database read error"), /* kdb5_err.et:kdb5:KRB5_KDB_UK_RERROR */ @@ -512,7 +512,7 @@ security administrator."), /* chpass_util_strings.et:ovku:CHPASS_UTIL_PASSWORD_T N_("New password was used previously. Please choose a different password."), /* chpass_util_strings.et:ovku:CHPASS_UTIL_PASSWORD_REUSE */ N_("while trying to change password."), /* chpass_util_strings.et:ovku:CHPASS_UTIL_WHILE_TRYING_TO_CHANGE */ N_("while reading new password."), /* chpass_util_strings.et:ovku:CHPASS_UTIL_WHILE_READING_PASSWORD */ - N_("$Header: /cvs/gnome/krb5-auth-dialog/src/dummy-strings.c,v 1.2 2005/10/31 21:55:46 caillon Exp $"), /* kadm_err.et:kadm:KADM_RCSID */ + N_("$Header$"), /* kadm_err.et:kadm:KADM_RCSID */ N_("Cannot fetch local realm"), /* kadm_err.et:kadm:KADM_NO_REALM */ N_("Unable to fetch credentials"), /* kadm_err.et:kadm:KADM_NO_CRED */ N_("Bad key supplied"), /* kadm_err.et:kadm:KADM_BAD_KEY */ diff --git a/src/krb5-auth-applet.c b/src/krb5-auth-applet.c new file mode 100644 index 0000000..8799ae1 --- /dev/null +++ b/src/krb5-auth-applet.c @@ -0,0 +1,265 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 <glib/gi18n.h> + +#include "krb5-auth-applet.h" +#include "krb5-auth-dialog.h" +#ifdef HAVE_LIBNOTIFY +#include "krb5-auth-notify.h" +#endif + + +/* update the tray icon's tooltip and icon */ +int +ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry) +{ + gchar* expiry_text; + int interval = expiry - time(0); + static gboolean expiry_notified = FALSE; + + if (interval > 0) { + int hours, minutes; + if (interval >= 3600) { + hours = interval / 3600; + minutes = (interval % 3600) / 60; + expiry_text = g_strdup_printf (_("Your credentials expire in %.2d:%.2dh"), hours, minutes); + } else { + minutes = interval / 60; + expiry_text = g_strdup_printf (ngettext( + "Your credentials expire in %d minute", + "Your credentials expire in %d minutes", + minutes), minutes); + } + gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[1]); +#ifdef HAVE_LIBNOTIFY + if (expiry_notified) { + ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL, + _("Network credentials valid"), + _("Your Kerberos credentials have been refreshed."), NULL); + expiry_notified = FALSE; + } +#endif + } else { + expiry_text = g_strdup (_("Your credentials have expired")); + gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[0]); +#ifdef HAVE_LIBNOTIFY + if (!expiry_notified) { + ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL, + _("Network credentials expired"), + _("Your Kerberos credentails have expired."), NULL); + expiry_notified = TRUE; + } +#endif + } + + gtk_status_icon_set_tooltip(applet->tray_icon, expiry_text); + g_free(expiry_text); + return 0; +} + + +static void +ka_menu_add_separator_item (GtkWidget* menu) +{ + GtkWidget* menu_item; + + menu_item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + gtk_widget_show (menu_item); +} + + +/* Free all resources and quit */ +static void +ka_quit_applet (GtkMenuItem* menuitem, gpointer user_data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) user_data; + + g_free(applet->principal); + g_free(applet); + gtk_main_quit(); +} + + +static void +ka_about_dialog (GtkMenuItem* menuitem, gpointer user_data) +{ + gchar* authors[] = { "Christopher Aillon <caillon@redhat.com>", + "Colin Walters <walters@verbum.org>", + "Guido Günther <agx@sigxpcu.org>", + NULL }; + gtk_show_about_dialog (NULL, + "authors", authors, + "version", VERSION, + "copyright", "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n2008 Guido Günther", + NULL); +} + + +/* The tray icon's context menu */ +static GtkWidget* +ka_create_context_menu (Krb5AuthApplet* applet) +{ + GtkWidget* menu; + GtkWidget* menu_item; + GtkWidget* image; + + menu = gtk_menu_new (); + + /* kdestroy */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("Remove Credentials _Cache")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_destroy_cache), 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); + + ka_menu_add_separator_item(menu); + + /* About item */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("_About")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_about_dialog), applet); + image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, 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); + + ka_menu_add_separator_item(menu); + + /* Quit */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Quit")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_quit_applet), applet); + image = gtk_image_new_from_stock (GTK_STOCK_QUIT, 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); + + gtk_widget_show_all (menu); + + return menu; +} + + +static void +ka_tray_icon_on_menu (GtkStatusIcon* status_icon, guint button, + guint activate_time, gpointer user_data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) user_data; + + KA_DEBUG("Trayicon right clicked: %d", applet->pw_prompt_secs); + gtk_menu_popup (GTK_MENU (applet->context_menu), NULL, NULL, + gtk_status_icon_position_menu, applet->tray_icon, + button, activate_time); +} + + +static gboolean +ka_tray_icon_on_click (GtkStatusIcon* status_icon, gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; + g_return_val_if_fail (applet != NULL, FALSE); + + KA_DEBUG("Trayicon clicked: %d", applet->pw_prompt_secs); + ka_grab_credentials (applet); + return TRUE; +} + + +gboolean +ka_show_tray_icon (Krb5AuthApplet* applet) +{ + g_return_val_if_fail (applet != NULL, FALSE); + g_return_val_if_fail (applet->tray_icon != NULL, FALSE); + + gtk_status_icon_set_visible (applet->tray_icon, applet->show_trayicon); + return TRUE; +} + + +static GtkStatusIcon* +ka_create_tray_icon (Krb5AuthApplet* applet) +{ + GtkStatusIcon* tray_icon; + + tray_icon = gtk_status_icon_new(); + g_signal_connect(G_OBJECT(tray_icon), "activate", + G_CALLBACK(ka_tray_icon_on_click), applet); + g_signal_connect(G_OBJECT(tray_icon), + "popup-menu", + G_CALLBACK(ka_tray_icon_on_menu), applet); + gtk_status_icon_set_from_icon_name (tray_icon, applet->icons[0]); + gtk_status_icon_set_tooltip (tray_icon, PACKAGE); + return tray_icon; +} + + +static void +ka_err_dialog (const char* err) +{ + GtkWidget* dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + err); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + + +int +ka_setup_icons (Krb5AuthApplet* applet) +{ + applet->icons[0] = "krb-no-valid-ticket"; + applet->icons[1] = "krb-valid-ticket"; + return TRUE; +} + + +/* create the tray icon applet */ +Krb5AuthApplet* +ka_create_applet() +{ + const char* err; + Krb5AuthApplet* applet = g_malloc0(sizeof(Krb5AuthApplet)); + + if(!(ka_setup_icons(applet))) { + err = _("Failure to setup icons"); + goto out; + } + + if(!(applet->tray_icon = ka_create_tray_icon(applet))) { + err = _("Failure to create tray icon"); + goto out; + } + // FIXME: handle with signal + ka_show_tray_icon (applet); + + if(!(applet->context_menu = ka_create_context_menu(applet))) { + err = _("Failure to create context menu"); + goto out; + } + + return applet; +out: + ka_err_dialog(err); + g_free(applet); + return NULL; +} + diff --git a/src/krb5-auth-applet.h b/src/krb5-auth-applet.h new file mode 100644 index 0000000..0cf29d9 --- /dev/null +++ b/src/krb5-auth-applet.h @@ -0,0 +1,68 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 KRB5_AUTH_APPLET_H +#define KRB5_AUTH_APPLET_H + +#include <glib.h> +#include <glib/gprintf.h> +#include <gtk/gtk.h> +#include <glade/glade.h> +#ifdef HAVE_LIBNOTIFY +#include <libnotify/notify.h> +#endif /* HAVE_LIBNOTIFY */ +#include <krb5.h> + +#include "config.h" + +typedef struct { + GtkStatusIcon* tray_icon; /* the tray icon */ + GtkWidget* context_menu; /* the tray icon's context menu */ + const char* icons[2]; /* for expired and valid tickts */ + gboolean show_trayicon; /* show the trayicon */ + + /* The password dialog */ + GtkWidget* pw_dialog; /* the password dialog itself */ + GladeXML* pw_xml; /* the dialog's glade xml */ + GtkWidget* pw_wrong_label; /* the wrong password/timeout label */ + int pw_prompt_secs; /* when to start prompting for a password */ + gboolean pw_dialog_persist; /* don't hide the dialog when creds are still valid */ + +#ifdef HAVE_LIBNOTIFY + NotifyNotification* notification;/* notification messages */ +#endif /* HAVE_LIBNOTIFY */ + char* principal; /* the principal to request */ +} Krb5AuthApplet; + +Krb5AuthApplet* ka_create_applet(); +/* update tooltip and icon */ +int ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry); +/* show or hide the tray icon */ +gboolean ka_show_tray_icon(Krb5AuthApplet* applet); + +#ifdef ENABLE_DEBUG +#define KA_DEBUG(fmt,...) \ + g_printf ("DEBUG: %s: " fmt "\n", __func__, __VA_ARGS__) +#else +#define KA_DEBUG(fmt,...) \ + do { } while (0) +#endif /* !ENABLE_DEBUG */ + +#endif diff --git a/src/krb5-auth-dbus.c b/src/krb5-auth-dbus.c new file mode 100644 index 0000000..f658c8d --- /dev/null +++ b/src/krb5-auth-dbus.c @@ -0,0 +1,78 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 <dbus/dbus-glib.h> +#include "krb5-auth-applet.h" +#include "krb5-auth-dbus.h" + +gboolean +ka_dbus_connect(unsigned int* status) +{ + guint request_name_reply; + unsigned int flags; + DBusGConnection *session; + DBusGProxy *bus_proxy; + GError* error = NULL; + + /* Connect to the session bus so we get exit-on-disconnect semantics. */ + session = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (session == NULL) { + g_error ("couldn't connect to session bus: %s", (error) ? error->message : "(null)"); + *status = 1; + return FALSE; + } + flags = DBUS_NAME_FLAG_DO_NOT_QUEUE; + bus_proxy = dbus_g_proxy_new_for_name (session, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + if (!dbus_g_proxy_call (bus_proxy, + "RequestName", + &error, + G_TYPE_STRING, + "org.gnome.KrbAuthDialog", + G_TYPE_UINT, + flags, + G_TYPE_INVALID, + G_TYPE_UINT, + &request_name_reply, + G_TYPE_INVALID)) { + g_warning ("Failed to invoke RequestName: %s", + error->message); + } + g_clear_error (&error); + g_object_unref (bus_proxy); + + if (request_name_reply == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER + || request_name_reply == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) + ; + else if (request_name_reply == DBUS_REQUEST_NAME_REPLY_EXISTS + || request_name_reply == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { + *status = 0; + return FALSE; + } else { + g_assert_not_reached(); + } + return TRUE; +} + diff --git a/src/krb5-auth-dbus.h b/src/krb5-auth-dbus.h new file mode 100644 index 0000000..6ef0bf0 --- /dev/null +++ b/src/krb5-auth-dbus.h @@ -0,0 +1,28 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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. + * + */ + +#ifndef KRB5_AUTH_DBUS_H +#define KRB5_AUTH_DBUS_H + +#include <glib.h> + +gboolean ka_dbus_connect(unsigned int* status); + +#endif /* KRB5_AUTH_DBUS_H */ diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c index 81f4f38..de5d9c9 100644 --- a/src/krb5-auth-dialog.c +++ b/src/krb5-auth-dialog.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004,2005 Red Hat, Inc. + * Copyright (C) 2004,2005,2006 Red Hat, Inc. * Authored by Christopher Aillon <caillon@redhat.com> * * This program is free software; you can redistribute it and/or modify @@ -20,43 +20,160 @@ #include "config.h" -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <gnome.h> #include <stdlib.h> #include <time.h> #include <krb5.h> #include <stdio.h> #include <sys/wait.h> #include <string.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <glade/glade.h> + +#include "gtksecentry.h" +#include "secmem-util.h" +#include "memory.h" +#include "krb5-auth-dialog.h" +#include "krb5-auth-applet.h" +#include "krb5-auth-gconf.h" +#include "krb5-auth-dbus.h" #ifdef ENABLE_NETWORK_MANAGER #include <libnm_glib.h> #endif -static GladeXML *xml = NULL; 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_password; static gboolean always_run; -static gint creds_expiry; -static int renew_credentials (); +static int grab_credentials (Krb5AuthApplet* applet, gboolean renewable); static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds); +/* 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 gboolean +credentials_expiring_real (Krb5AuthApplet* applet, gboolean *renewable) +{ + krb5_creds my_creds; + krb5_timestamp now; + gboolean retval = FALSE; + *renewable = FALSE; + + if (!get_tgt_from_ccache (kcontext, &my_creds)) { + creds_expiry = 0; + retval = TRUE; + goto out; + } + + 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 + applet->pw_prompt_secs > my_creds.times.endtime)) + retval = TRUE; + + /* If our creds are expiring, determine whether they are renewable */ + if (retval && get_cred_renewable(&my_creds) && my_creds.times.renew_till > now) { + *renewable = TRUE; + } + + krb5_free_cred_contents (kcontext, &my_creds); + +out: + ka_update_status(applet, creds_expiry); + return retval; +} + + static gchar* minutes_to_expiry_text (int minutes) { gchar *expiry_text; gchar *tmp; - if (minutes > 0) + if (minutes > 0) { expiry_text = g_strdup_printf (ngettext("Your credentials expire in %d minute", "Your credentials expire in %d minutes", minutes), minutes); - else - { + } else { expiry_text = g_strdup (_("Your credentials have expired")); tmp = g_strdup_printf ("<span foreground=\"red\">%s</span>", expiry_text); g_free (expiry_text); @@ -66,18 +183,22 @@ static gchar* minutes_to_expiry_text (int minutes) return expiry_text; } + static gboolean -krb5_auth_dialog_wrong_label_update_expiry (gpointer data) +krb5_auth_dialog_wrong_label_update_expiry (GtkWidget* label) { - GtkWidget *label = GTK_WIDGET(data); int minutes_left; + krb5_timestamp now; gchar *expiry_text; gchar *expiry_markup; - g_return_val_if_fail (label != NULL, FALSE); + g_return_val_if_fail (label!= NULL, FALSE); - minutes_left = (creds_expiry - time(0)) / 60; + if (krb5_timeofday(kcontext, &now) != 0) { + return TRUE; + } + minutes_left = (creds_expiry - now) / 60; expiry_text = minutes_to_expiry_text (minutes_left); expiry_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", expiry_text); @@ -88,23 +209,45 @@ krb5_auth_dialog_wrong_label_update_expiry (gpointer data) return TRUE; } + +/* Check for things we have to do while the password dialog is open */ +static gboolean +krb5_auth_dialog_do_updates(gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*)data; + gboolean refreshable; + + g_return_val_if_fail (applet != 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, &refreshable)) { + KA_DEBUG("PW Dialog persist is %d", applet->pw_dialog_persist); + if (!applet->pw_dialog_persist) + gtk_widget_hide(applet->pw_dialog); + } + + /* Update the expiry information in the dialog */ + krb5_auth_dialog_wrong_label_update_expiry (applet->pw_wrong_label); + return TRUE; +} + + static void -krb5_auth_dialog_setup (GtkWidget *dialog, +krb5_auth_dialog_setup (Krb5AuthApplet *applet, const gchar *krb5prompt, gboolean hide_password) { GtkWidget *entry; GtkWidget *label; - GtkWidget *wrong_label; gchar *wrong_text; gchar *wrong_markup; gchar *prompt; int pw4len; - if (krb5prompt == NULL) + + if (krb5prompt == NULL) { prompt = g_strdup (_("Please enter your Kerberos password.")); - else - { + } else { /* Kerberos's prompts are a mess, and basically impossible to * translate. There's basically no way short of doing a lot of * string parsing to translate them. The most common prompt is @@ -112,72 +255,69 @@ krb5_auth_dialog_setup (GtkWidget *dialog, * cannot do any of the fancier strings (like challenges), * though. */ pw4len = strlen ("Password for "); - if (strncmp (krb5prompt, "Password for ", pw4len) == 0) - { + if (strncmp (krb5prompt, "Password for ", pw4len) == 0) { gchar *uid = (gchar *) (krb5prompt + pw4len); prompt = g_strdup_printf (_("Please enter the password for '%s'"), uid); - } - else + } else { prompt = g_strdup (krb5prompt); + } } /* Clear the password entry field */ - entry = glade_xml_get_widget (xml, "krb5_entry"); - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_entry_set_visibility (GTK_ENTRY (entry), !hide_password); + entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry"); + gtk_secure_entry_set_text (GTK_SECURE_ENTRY (entry), ""); /* Use the prompt label that krb5 provides us */ - label = glade_xml_get_widget (xml, "krb5_message_label"); + label = glade_xml_get_widget (applet->pw_xml, "krb5_message_label"); gtk_label_set_text (GTK_LABEL (label), prompt); /* Add our extra message hints, if any */ - wrong_label = glade_xml_get_widget (xml, "krb5_wrong_label"); wrong_text = NULL; - if (wrong_label) - { - if (invalid_password) + if (applet->pw_wrong_label) { + if (invalid_password) { wrong_text = g_strdup (_("The password you entered is invalid")); - else - { - int minutes_left = (creds_expiry - time(0)) / 60; - + } else { + krb5_timestamp now; + int minutes_left; + + if (krb5_timeofday(kcontext, &now) == 0) + minutes_left = (creds_expiry - now) / 60; + else + minutes_left = 0; wrong_text = minutes_to_expiry_text (minutes_left); } } - if (wrong_text) - { + if (wrong_text) { wrong_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", wrong_text); - gtk_label_set_markup (GTK_LABEL (wrong_label), wrong_markup); + gtk_label_set_markup (GTK_LABEL (applet->pw_wrong_label), wrong_markup); g_free(wrong_text); g_free(wrong_markup); + } else { + gtk_label_set_text (GTK_LABEL (applet->pw_wrong_label), ""); } - else - gtk_label_set_text (GTK_LABEL (wrong_label), ""); - g_free (prompt); } + static krb5_error_code -krb5_gtk_prompter (krb5_context ctx, - void *data, - const char *name, - const char *banner, - int num_prompts, - krb5_prompt prompts[]) +auth_dialog_prompter (krb5_context ctx, + void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) { - GtkWidget *dialog; - GtkWidget *wrong_label; + Krb5AuthApplet* applet = (Krb5AuthApplet*)data; krb5_error_code errcode; int i; errcode = KRB5_LIBOS_CANTREADPWD; + canceled = FALSE; + canceled_creds_expiry = 0; - dialog = glade_xml_get_widget (xml, "krb5_dialog"); - - for (i = 0; i < num_prompts; i++) - { + for (i = 0; i < num_prompts; i++) { const gchar *password = NULL; int password_len = 0; int response; @@ -187,25 +327,27 @@ krb5_gtk_prompter (krb5_context ctx, errcode = KRB5_LIBOS_CANTREADPWD; - entry = glade_xml_get_widget(xml, "krb5_entry"); - krb5_auth_dialog_setup (dialog, (gchar *) prompts[i].prompt, prompts[i].hidden); + krb5_auth_dialog_setup (applet, (gchar *) prompts[i].prompt, prompts[i].hidden); + entry = glade_xml_get_widget(applet->pw_xml, "krb5_entry"); + gtk_widget_grab_focus(entry); - wrong_label = glade_xml_get_widget (xml, "krb5_wrong_label"); - source_id = g_timeout_add (5000, (GSourceFunc)krb5_auth_dialog_wrong_label_update_expiry, - wrong_label); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); + source_id = g_timeout_add_seconds (5, (GSourceFunc)krb5_auth_dialog_do_updates, applet); + response = gtk_dialog_run (GTK_DIALOG (applet->pw_dialog)); switch (response) { case GTK_RESPONSE_OK: - password = gtk_entry_get_text (GTK_ENTRY (entry)); + password = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry)); password_len = strlen (password); errcode = 0; break; case GTK_RESPONSE_CANCEL: + canceled = TRUE; + break; + case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: break; default: + g_warning ("Unknown Response: %d", response); g_assert_not_reached (); } @@ -216,7 +358,7 @@ krb5_gtk_prompter (krb5_context ctx, } /* Reset this, so we know the next time we get a TRUE value, it is accurate. */ - gtk_widget_hide (dialog); + gtk_widget_hide (applet->pw_dialog); invalid_password = FALSE; return errcode; @@ -252,101 +394,38 @@ network_state_cb (libnm_glib_ctx *context, } #endif -static gboolean -credentials_expiring_real (void) -{ - krb5_creds my_creds; - gboolean retval = FALSE; - - if (!get_tgt_from_ccache (kcontext, &my_creds)) { - creds_expiry = 0; - return TRUE; - } - - 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 (time(NULL) + MINUTES_BEFORE_PROMPTING * 60 > my_creds.times.endtime) - retval = TRUE; - - krb5_free_cred_contents(kcontext, &my_creds); - - return retval; -} static gboolean credentials_expiring (gpointer *data) { - if (credentials_expiring_real () && is_online) - renew_credentials (); - + int retval; + gboolean give_up; + gboolean renewable; + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; + + KA_DEBUG("Checking expiry: %d", applet->pw_prompt_secs); + if (credentials_expiring_real (applet, &renewable) && is_online) { + give_up = canceled && (creds_expiry == canceled_creds_expiry); + if (!give_up) { + do { + retval = grab_credentials (applet, renewable); + give_up = canceled && + (creds_expiry == canceled_creds_expiry); + } while ((retval != 0) && + (retval != KRB5_REALM_CANT_RESOLVE) && + (retval != KRB5_KDC_UNREACH) && + invalid_password && + !give_up); + } + } + ka_update_status(applet, creds_expiry); return TRUE; } -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_FORWARDABLE) -static int -get_cred_forwardable(krb5_creds *creds) -{ - return creds->ticket_flags & TKT_FLG_FORWARDABLE; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_FORWARDABLE) -static int -get_cred_forwardable(krb5_creds *creds) -{ - return creds->flags.b.forwardable; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_FORWARDABLE) -static int -get_cred_forwardable(krb5_creds *creds) -{ - return creds->flags & KDC_OPT_FORWARDABLE; -} -#endif - -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_RENEWABLE) -static int -get_cred_renewable(krb5_creds *creds) -{ - return creds->ticket_flags & TKT_FLG_RENEWABLE; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_RENEWABLE) -static int -get_cred_renewable(krb5_creds *creds) -{ - return creds->flags.b.renewable; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_RENEWABLE) -static int -get_cred_renewable(krb5_creds *creds) -{ - return creds->flags & KDC_OPT_RENEWABLE; -} -#endif - -#if defined(HAVE_KRB5_CREDS_TICKET_FLAGS) && defined(TKT_FLG_PROXIABLE) -static int -get_cred_proxiable(krb5_creds *creds) -{ - return creds->ticket_flags & TKT_FLG_PROXIABLE; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS_B_PROXIABLE) -static int -get_cred_proxiable(krb5_creds *creds) -{ - return creds->flags.b.proxiable; -} -#elif defined(HAVE_KRB5_CREDS_FLAGS) && defined(KDC_OPT_PROXIABLE) -static int -get_cred_proxiable(krb5_creds *creds) -{ - return creds->flags & KDC_OPT_PROXIABLE; -} -#endif static void -set_options_using_creds(krb5_context context, +set_options_using_creds(const Krb5AuthApplet* applet, + krb5_context context, krb5_creds *creds, krb5_get_init_creds_opt *opts) { @@ -365,7 +444,7 @@ set_options_using_creds(krb5_context context, renew_lifetime); } if (creds->times.endtime > - creds->times.starttime + MINUTES_BEFORE_PROMPTING * 60) { + creds->times.starttime + applet->pw_prompt_secs) { krb5_get_init_creds_opt_set_tkt_life(opts, creds->times.endtime - creds->times.starttime); @@ -375,92 +454,84 @@ set_options_using_creds(krb5_context context, } static int -renew_credentials (void) +grab_credentials (Krb5AuthApplet* applet, gboolean renewable) { krb5_error_code retval; krb5_creds my_creds; krb5_ccache ccache; krb5_get_init_creds_opt opts; + memset(&my_creds, 0, sizeof(my_creds)); + if (kprincipal == NULL) { - retval = krb5_parse_name(kcontext, g_get_user_name (), + retval = krb5_parse_name(kcontext, applet->principal, &kprincipal); if (retval) { return retval; } } - krb5_get_init_creds_opt_init(&opts); - if (get_tgt_from_ccache (kcontext, &my_creds)) - { - set_options_using_creds(kcontext, &my_creds, &opts); + retval = krb5_cc_default (kcontext, &ccache); + if (retval) + return retval; + + krb5_get_init_creds_opt_init (&opts); + if (get_tgt_from_ccache (kcontext, &my_creds)) { + set_options_using_creds (applet, kcontext, &my_creds, &opts); creds_expiry = my_creds.times.endtime; - krb5_free_cred_contents(kcontext, &my_creds); + + if (renewable) { + retval = get_renewed_creds (kcontext, &my_creds, kprincipal, ccache, NULL); + + /* If we succeeded in renewing the credentials, we store it. */ + if (retval == 0) { + goto store; + } + /* Else, try to get new credentials, so just fall through */ + } + krb5_free_cred_contents (kcontext, &my_creds); } else { creds_expiry = 0; } retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal, - NULL, krb5_gtk_prompter, 0, - 0, NULL, &opts); - if (retval) - { + NULL, auth_dialog_prompter, applet, + 0, NULL, &opts); + if (canceled) { + canceled_creds_expiry = creds_expiry; + } + if (retval) { switch (retval) { case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KRB_AP_ERR_BAD_INTEGRITY: /* Invalid password, try again. */ invalid_password = TRUE; - return renew_credentials(); + goto out; default: break; } - return retval; + goto out; } - retval = krb5_cc_default(kcontext, &ccache); - if (retval) - return retval; - +store: retval = krb5_cc_initialize(kcontext, ccache, kprincipal); - if (retval) + if (retval) { goto out; + } retval = krb5_cc_store_cred(kcontext, ccache, &my_creds); - if (retval) + if (retval) { goto out; + } creds_expiry = my_creds.times.endtime; - out: + krb5_free_cred_contents (kcontext, &my_creds); krb5_cc_close (kcontext, ccache); return retval; } -#if defined(HAVE_KRB5_PRINCIPAL_REALM_AS_STRING) -static size_t -get_principal_realm_length(krb5_principal p) -{ - return strlen(p->realm); -} -static const char * -get_principal_realm_data(krb5_principal p) -{ - return p->realm; -} -#elif defined(HAVE_KRB5_PRINCIPAL_REALM_AS_DATA) -static size_t -get_principal_realm_length(krb5_principal p) -{ - return p->realm.length; -} -static const char * -get_principal_realm_data(krb5_principal p) -{ - return p->realm.data; -} -#endif - static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds) { @@ -471,11 +542,9 @@ get_tgt_from_ccache (krb5_context context, krb5_creds *creds) memset(&ccache, 0, sizeof(ccache)); ret = FALSE; - if (krb5_cc_default(context, &ccache) == 0) - { + if (krb5_cc_default(context, &ccache) == 0) { memset(&principal, 0, sizeof(principal)); - if (krb5_cc_get_principal(context, ccache, &principal) == 0) - { + if (krb5_cc_get_principal(context, ccache, &principal) == 0) { memset(&tgt_principal, 0, sizeof(tgt_principal)); if (krb5_build_principal_ext(context, &tgt_principal, get_principal_realm_length(principal), @@ -492,8 +561,7 @@ get_tgt_from_ccache (krb5_context context, krb5_creds *creds) if (krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, - creds) == 0) - { + creds) == 0) { ret = TRUE; } else { memset(creds, 0, sizeof(*creds)); @@ -515,8 +583,9 @@ using_krb5() krb5_creds creds; err = krb5_init_context(&kcontext); - if (err) + if (err) { return TRUE; + } have_tgt = get_tgt_from_ccache(kcontext, &creds); if (have_tgt) { @@ -527,50 +596,170 @@ using_krb5() return have_tgt; } + +void +ka_destroy_cache (GtkMenuItem *menuitem, gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; + krb5_ccache ccache; + const char* cache; + krb5_error_code ret; + gboolean renewable; + + cache = krb5_cc_default_name(kcontext); + ret = krb5_cc_resolve(kcontext, cache, &ccache); + ret = krb5_cc_destroy (kcontext, ccache); + + credentials_expiring_real(applet, &renewable); +} + + +static void +ka_error_dialog(int err) +{ + const char* msg = error_message(err); + GtkWidget *dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("Couldn't acquire kerberos ticket: '%s'"), msg); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + + +/* this is done on leftclick, update the tooltip immediately */ +void +ka_grab_credentials (Krb5AuthApplet* applet) +{ + int retval; + gboolean renewable, retry; + + applet->pw_dialog_persist = TRUE; + do { + retry = TRUE; + retval = grab_credentials (applet, FALSE); + switch (retval) { + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + retry = TRUE; + break; + case 0: /* success */ + case KRB5_LIBOS_CANTREADPWD: /* canceled */ + retry = FALSE; + break; + case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: + default: + ka_error_dialog(retval); + retry = FALSE; + break; + } + } while(retry); + + applet->pw_dialog_persist = FALSE; + credentials_expiring_real(applet, &renewable); +} + + +static GtkWidget* +ka_create_gtk_secure_entry (GladeXML *xml, gchar *func_name, gchar *name, + gchar *s1, gchar *s2, gint i1, gint i2, + gpointer user_data) +{ + GtkWidget* entry = NULL; + + if (!strcmp(name, "krb5_entry")) { + entry = gtk_secure_entry_new (); + gtk_secure_entry_set_activates_default(GTK_SECURE_ENTRY(entry), TRUE); + gtk_widget_show (entry); + } else { + g_warning("Don't know anything about widget %s", name); + } + return entry; +} + + +static void +ka_secmem_init () +{ + /* 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"); +} + + int main (int argc, char *argv[]) { - GtkWidget *dialog; - GnomeClient *client; - int run_auto = 0, run_always = 0; - struct poptOption options[] = { - {"auto", 'a', 0, &run_auto, 0, - "Only run if an initialized ccache is found (default)", NULL}, - {"always", 'A', 0, &run_always, 0, - "Always run", NULL}, - {NULL}, + Krb5AuthApplet *applet; + GOptionContext *context; + GError *error = NULL; + + guint status = 0; + gboolean run_auto = FALSE, run_always = 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 (default)", NULL}, + {"always", 'A', 0, G_OPTION_ARG_NONE, &run_always, + "Always run", NULL}, + { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; #ifdef ENABLE_NETWORK_MANAGER libnm_glib_ctx *nm_context; guint32 nm_callback_id; #endif + 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_error_free (error); + return 1; + } + textdomain(PACKAGE); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + bindtextdomain(PACKAGE, LOCALE_DIR); + ka_secmem_init(); - gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_POPT_TABLE, options, - GNOME_PARAM_NONE); - - client = gnome_master_client (); - gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY); + if(!ka_dbus_connect (&status)) + exit(status); - if (run_always && !run_auto) - always_run++; - if (using_krb5 () || always_run) - { - g_signal_connect (G_OBJECT (client), "die", - G_CALLBACK (gtk_main_quit), NULL); + if (run_always && !run_auto) { + always_run = TRUE; + } + if (using_krb5 () || always_run) { + applet = ka_create_applet(); + if (!applet) + return 1; + if (!ka_gconf_init(applet, argc, argv)) + return 1; + + /* setup the pw dialog */ + glade_set_custom_handler (&ka_create_gtk_secure_entry, NULL); + applet->pw_xml = glade_xml_new (GLADEDIR "krb5-auth-dialog.glade", NULL, NULL); + applet->pw_wrong_label = glade_xml_get_widget (applet->pw_xml, "krb5_wrong_label"); + applet->pw_dialog = glade_xml_get_widget (applet->pw_xml, "krb5_dialog"); g_set_application_name (_("Network Authentication")); + gtk_window_set_default_icon_name(applet->icons[1]); #ifdef ENABLE_NETWORK_MANAGER nm_context = libnm_glib_init (); - if (!nm_context) + if (!nm_context) { g_warning ("Could not initialize libnm_glib"); - else - { + } else { nm_callback_id = libnm_glib_register_callback (nm_context, network_state_cb, &is_online, NULL); - if (nm_callback_id == 0) - { + if (nm_callback_id == 0) { libnm_glib_shutdown (nm_context); nm_context = NULL; @@ -579,12 +768,9 @@ main (int argc, char *argv[]) } #endif /* ENABLE_NETWORK_MANAGER */ - xml = glade_xml_new (GLADEDIR "krb5-auth-dialog.glade", NULL, NULL); - dialog = glade_xml_get_widget (xml, "krb5_dialog"); - - if (credentials_expiring (NULL)) - g_timeout_add (CREDENTIAL_CHECK_INTERVAL * 1000, (GSourceFunc)credentials_expiring, NULL); - + if (credentials_expiring ((gpointer)applet)) { + g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, (GSourceFunc)credentials_expiring, applet); + } gtk_main (); } diff --git a/src/krb5-auth-dialog.glade b/src/krb5-auth-dialog.glade index ef4ff7c..e115849 100644 --- a/src/krb5-auth-dialog.glade +++ b/src/krb5-auth-dialog.glade @@ -178,7 +178,7 @@ </child> <child> - <widget class="GtkEntry" id="krb5_entry"> + <widget class="Custom" id="krb5_entry"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="editable">True</property> diff --git a/src/krb5-auth-dialog.h b/src/krb5-auth-dialog.h new file mode 100644 index 0000000..841b983 --- /dev/null +++ b/src/krb5-auth-dialog.h @@ -0,0 +1,30 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 KRB5_AUTH_DIALOG +#define KRB5_AUTH_DIALOG + +#include "krb5-auth-applet.h" + +void ka_destroy_cache (GtkMenuItem *menuitem, gpointer user_data); +void ka_grab_credentials(Krb5AuthApplet* applet); + +#endif + diff --git a/src/krb5-auth-dialog.schemas.in b/src/krb5-auth-dialog.schemas.in new file mode 100644 index 0000000..e715d26 --- /dev/null +++ b/src/krb5-auth-dialog.schemas.in @@ -0,0 +1,39 @@ +<gconfschemafile> + <schemalist> + <schema> + <key>/schemas/apps/::PACKAGE::/show_trayicon</key> + <applyto>/apps/::PACKAGE::/show_trayicon</applyto> + <owner>::PACKAGE::</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Display trayicon</short> + <long>Display the trayicon in the panel</long> + </locale> + </schema> + + <schema> + <key>/schemas/apps/::PACKAGE::/prompt_minutes</key> + <applyto>/apps/::PACKAGE::/prompt_minutes</applyto> + <owner>::PACKAGE::</owner> + <type>int</type> + <default>::MINIMUM_LIFETIME::</default> + <locale name="C"> + <short>Minutes before ticket expires</short> + <long>How many minutes before the ticket expires should + prompting for the new password start</long> + </locale> + </schema> + + <schema> + <key>/schemas/apps/::PACKAGE::/principal</key> + <applyto>/apps/::PACKAGE::/principal</applyto> + <type>string</type> + <default></default> + <locale name="C"> + <short>default principal</short> + <long>principal to use when no ticket cache is present</long> + </locale> + </schema> + </schemalist> +</gconfschemafile> diff --git a/src/krb5-auth-gconf.c b/src/krb5-auth-gconf.c new file mode 100644 index 0000000..2d47cea --- /dev/null +++ b/src/krb5-auth-gconf.c @@ -0,0 +1,206 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 <gconf/gconf-client.h> + +#include "krb5-auth-applet.h" +#include "krb5-auth-gconf.h" + +#define KA_GCONF_PATH "/apps/" PACKAGE +#define KA_GCONF_KEY_PRINCIPAL KA_GCONF_PATH "/principal" +#define KA_GCONF_KEY_PROMPT_MINS KA_GCONF_PATH "/prompt_minutes" +#define KA_GCONF_KEY_SHOW_TRAYICON KA_GCONF_PATH "/show_trayicon" + +static gboolean +ka_gconf_get_string(GConfClient* client, + const char* key, + char** value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (*value == NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) { + if (gc_value->type == GCONF_VALUE_STRING) { + *value = g_strdup (gconf_value_get_string (gc_value)); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_get_int(GConfClient* client, + const char* key, + int* value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) + { + if (gc_value->type == GCONF_VALUE_INT) { + *value = gconf_value_get_int (gc_value); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_get_bool(GConfClient* client, + const char* key, + gboolean* value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) + { + if (gc_value->type == GCONF_VALUE_BOOL) { + *value = gconf_value_get_bool (gc_value); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_set_principal(GConfClient* client, Krb5AuthApplet* applet) +{ + g_free(applet->principal); + applet->principal = NULL; + if(!ka_gconf_get_string(client, KA_GCONF_KEY_PRINCIPAL, &applet->principal)) { + applet->principal = g_strdup(g_get_user_name()); + } + KA_DEBUG("Setting principal to %s", applet->principal); + // FIXME: need to send set-principal signal + return TRUE; +} + + +static gboolean +ka_gconf_set_prompt_mins(GConfClient* client, Krb5AuthApplet* applet) +{ + if(!ka_gconf_get_int(client, KA_GCONF_KEY_PROMPT_MINS, &applet->pw_prompt_secs)) { + applet->pw_prompt_secs = MINUTES_BEFORE_PROMPTING; + } + applet->pw_prompt_secs *= 60; + KA_DEBUG("Setting prompting timer to %d seconds", applet->pw_prompt_secs); + return TRUE; +} + + +static gboolean +ka_gconf_set_show_trayicon(GConfClient* client, Krb5AuthApplet* applet) +{ + if(!ka_gconf_get_bool(client, KA_GCONF_KEY_SHOW_TRAYICON, &applet->show_trayicon)) { + applet->show_trayicon = TRUE; + } + KA_DEBUG("Show trayicon: %s", (applet->show_trayicon ? "yes" : "no" )); + // FIXME: send show trayicon signal + ka_show_tray_icon(applet); + return TRUE; +} + + +static void +ka_gconf_key_changed_callback (GConfClient* client, + guint cnxn_id, + GConfEntry* entry, + gpointer user_data) +{ + const char* key; + + Krb5AuthApplet* applet = (Krb5AuthApplet*)user_data; + key = gconf_entry_get_key (entry); + if (!key) + return; + KA_DEBUG("Key %s changed", key); + + if (g_strcmp0(key, KA_GCONF_KEY_PRINCIPAL) == 0) { + ka_gconf_set_principal(client, applet); + } else if (g_strcmp0(key, KA_GCONF_KEY_PROMPT_MINS) == 0) { + ka_gconf_set_prompt_mins(client, applet); + } else if (g_strcmp0(key, KA_GCONF_KEY_SHOW_TRAYICON) == 0) { + ka_gconf_set_show_trayicon(client, applet); + } else + g_warning("Received notification for unknown gconf key %s", key); + return; +} + + +gboolean +ka_gconf_init (Krb5AuthApplet* applet, int argc, char* argv[]) +{ + GError *error = NULL; + GConfClient* client; + gboolean success = FALSE; + + client = gconf_client_get_default(); + gconf_client_add_dir(client, KA_GCONF_PATH, GCONF_CLIENT_PRELOAD_ONELEVEL, &error); + if (error) + goto out; + + gconf_client_notify_add(client, KA_GCONF_PATH, + ka_gconf_key_changed_callback, applet, NULL, &error); + if (error) + goto out; + + /* setup defaults */ + ka_gconf_set_principal(client, applet); + ka_gconf_set_prompt_mins(client, applet); + ka_gconf_set_show_trayicon(client, applet); + + success = TRUE; +out: + if(error) { + g_print (error->message); + g_error_free (error); + } + return success; +} diff --git a/src/krb5-auth-gconf.h b/src/krb5-auth-gconf.h new file mode 100644 index 0000000..7c2f8ce --- /dev/null +++ b/src/krb5-auth-gconf.h @@ -0,0 +1,28 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 KRB5_AUTH_GCONF_H +#define KRB5_AUTH_GCONF_H + +#include "krb5-auth-applet.h" + +gboolean ka_gconf_init (Krb5AuthApplet* applet, int argc, char* argv[]); + +#endif diff --git a/src/krb5-auth-notify.c b/src/krb5-auth-notify.c new file mode 100644 index 0000000..042ae00 --- /dev/null +++ b/src/krb5-auth-notify.c @@ -0,0 +1,57 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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" + +#ifdef HAVE_LIBNOTIFY + +#include "krb5-auth-applet.h" +#include "krb5-auth-notify.h" + +void +ka_send_event_notification (Krb5AuthApplet *applet, + NotifyUrgency urgency, + const char *summary, + const char *message, + const char *icon) +{ + const char *notify_icon; + + g_return_if_fail (applet != NULL); + g_return_if_fail (summary != NULL); + g_return_if_fail (message != NULL); + + if (!notify_is_initted ()) + notify_init (PACKAGE); + + if (applet->notification != NULL) { + notify_notification_close (applet->notification, NULL); + g_object_unref (applet->notification); + } + + notify_icon = icon ? icon : "gtk-dialog-authentication"; + + applet->notification = \ + notify_notification_new_with_status_icon(summary, message, notify_icon, applet->tray_icon); + + notify_notification_set_urgency (applet->notification, urgency); + notify_notification_show (applet->notification, NULL); +} + +#endif /* HAVE_LIBNOTIFY */ diff --git a/src/krb5-auth-notify.h b/src/krb5-auth-notify.h new file mode 100644 index 0000000..cc2c111 --- /dev/null +++ b/src/krb5-auth-notify.h @@ -0,0 +1,32 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther <agx@sigxcpu.org> + * + * 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 KRB5_AUTH_NOTIFY_H +#define KRB5_AUTH_NOTIFY_H + +#include <libnotify/notify.h> + +void ka_send_event_notification (Krb5AuthApplet *applet, + NotifyUrgency urgency, + const char *summary, + const char *message, + const char *icon); +#endif + |