kov changed libgksu/tags/2.0.8/, libgksu/tags/2.0.8/ChangeLog, libgksu/tags/2.0.8/ChangeLog, libgksu/tags/2.0.8/libgksu/libgksu.c, libgksu/tags/2.0.8/libgksu/libgksu.c
Gustavo Noronha
kov at alioth.debian.org
Wed Mar 4 18:39:37 UTC 2009
Mensagem de log:
releasing 2.0.8
-----
Copied: libgksu/tags/2.0.8 (from rev 840, libgksu/trunk)
Deleted: libgksu/tags/2.0.8/ChangeLog
===================================================================
--- libgksu/trunk/ChangeLog 2009-02-23 02:20:27 UTC (rev 840)
+++ libgksu/tags/2.0.8/ChangeLog 2009-03-04 18:39:36 UTC (rev 844)
@@ -1,1528 +0,0 @@
-2009-02-22 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c: - added threads protection for the gdk
- fadeout/fadein animation, so that callers will not have X errors
- when trying to use gdk functions in parallel with us
- See http://bugzilla.gnome.org/show_bug.cgi?id=549760.
-
-2009-02-22 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac, libgksu/libgksu.{c,h}, libgksu/gksu-run-helper.c:
- - accepted patch by Joshua Kwan <jkwan at vmware.com> to
- return the same status code as the child
-
-2009-02-03 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added th to ALL_LINGUAS
-
-2008-08-29 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c: patch by Daniel Richard G. <skunk at iSKUNK.ORG>
- to allow changing the location of the lockfile, so that libgksu
- will work on AFS/NFS mounted home directories
-
-2008-06-20 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-run-helper.c: accepted patch by Michael Vogt, from
- Ubuntu, to fix very long commands not fitting in the helper's
- statically-sized buffer (Debian bug #486087, launchpad #173757)
-
- * libgksu/libgksu.c (sudo_full): accepted patch by Michael Vogt,
- from Ubuntu, to fix sudo having problems resolving network
- addresses breaking gksu (Debian bug #486083, launchpad #237325)
-
-2008-05-27 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.7
-
- * libgksu/libgksu.c (gksu_sudo_full): accepted patch by Ben
- Hutchings <ben at decadent.org.uk> to also disable nonblocking I/O
- when no password is asked (Debian bug #463709)
-
- * configure.ac: - remove \n from the test code used to test for
- the presence of the -version-script linker option; that was
- causing the test to fail
-
-2008-05-16 Gustavo Noronha Silva <Gustavo Noronha Silva <kov at alfaiati.net>>
-
- * Release 2.0.6
-
-2008-01-02 Guilherme de S. Pastore <gpastore at debian.org>
-
- * libgksu/libgksu.c (gksu_sudo_full): fix typo introduced with the latest
- changes ("aways").
-
-2007-12-31 Gustavo Noronha Silva <kov at cenoura>
-
- * libgksu/libgksu.c:
- - format parameters were wrong for the case in which you
- ask gksu to run a given command as a given user (other than
- root); thanks to Uwe Kleine-König <ukleinek at informatik.uni-freiburg.de>
- for pointing out; Debian bug #449180
-
- * libgksu/libgksu.c:
- - accepted patch from Ubuntu by Michael Vogt to add a new
- property for GksuContext: always_ask_password; the patch
- suffered minor aditions by me to also implement the functionality
- to the su backend and document the limitations (Debian bug #453423)
-
- * libgksuui/gksuui-dialog.c:
- - accepted patch from Ubuntu by Michael Vogt that fixes
- the capslock notification so that it doesn't change the
- size of the window (Debian bug #453426)
-
-2007-06-22 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - accepted patch from Ubuntu, by Michael Vogt, that
- fixes the way gksu waits for the child process to
- finish; see:
- https://bugs.launchpad.net/ubuntu/+source/libgksu/+bug/121581
-
-2007-06-10 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.5
-
- * libgksu/libgksu.c:
- - also complete launch notification when cancel is
- pressed in the dialog; (Addressing Debian Bug #426495)
-
-2007-06-09 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - reworked the way gksu_su{,do}_full relays the child's
- output, making it sleep rather than wakeup every
- few microseconds (Addressing Debian Bug #425679)
-
-2007-05-11 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added sv and zh_CN.po to ALL_LINGUAS
-
-2007-03-28 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added ko to ALL_LINGUAS
-
-2007-03-06 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - always try to create the keyring when setting the password;
- if the keyring exists this is a no-op, so no problems
- (Addressing Debian Bug #412681)
-
- * libgksu/libgksu.c:
- - improved debugging for getting the password from the
- GNOME Keyring; and do not show the password anymore when
- debugging
-
-2007-03-04 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - accepted patch by Michael Vogt to handle the
- better quoted strings given by gksu
-
-2007-02-04 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.4
-
-2007-01-22 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.[ch]:
- - accepted patch by "Gian Mario Tagliaretti"
- <g.tagliaretti at gmail.com> to turn GksuContext into
- a boxed type, so that it can be used in a saner way
- in bindings
-
-2007-01-05 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - accepted patch by ÐиÑалий ÐÑенко <betalb at gmail.com>
- which makes libgksu only replace the 'password typing' character
- when '*' is the default one
-
-2006-12-07 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - make sure DESKTOP_STARTUP_ID is set in the environment correctly
-
-2006-10-31 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - remove a trailing \n if it exists in the password we get from
- the GNOME Keyring (Addresses Debian Bug #395462)
-
-2006-10-23 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.3
-
- * libgksu/libgksu.c:
- - make sure the dialog is _destroyed_ instead of just being
- hidden, after some action has been taken in the dialog that
- asks for the password
- - returns WRONGAUTOPASS instead of WRONGPASS when wrong password
- is the one we got from the gnome keyring
- - store the password in the GNOME Keyring without the \n
- (Addresses Debian Bug #394895)
-
-2006-10-22 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.2
-
- * libgksu/libgksu.c:
- - make sure we notice ECHO disabled, and remove some uneeded waits
- which will probably speedup using su with password, but probably
- slow down su without password; this should avoid deadlocks when
- su delays setting ECHO off.
-
-2006-10-15 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksuui/gksuui-dialog.c:
- - try to always have focus, by traping the focus-out-event;
- should address Debian bug #391804
-
-2006-10-08 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 2.0.1
-
- * libgksu/libgksu.c:
- - use some brute force reading when using sudo, to be able
- to handle stuff like the sudo lecture and pam modules debugging
-
-2006-10-01 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - if xauth is an empty string when using the su backend,
- then try to get it again by striping the hostname part
- of the display string; this is needed for ssh X forwarding
-
-2006-09-23 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - version set to 2.0.0; releasing libgksu 2, at last!
-
-2006-09-07 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - have gksu ignore lines coming from the process 'till it is able
- to find the gksu: waiting line; this is done observing some
- time and size constraints, though, so we won't end up in an infinite
- loop; this addresses #17139; libpam-mount should now work happily with
- debug on
- - also make su's child session leader, like sudo's, so that when the
- program you ran launches another, closing the first will not destroy
- the second
-
-2006-09-02 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added it to ALL_LINGUAS
-
-2006-08-19 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added lt to ALL_LINGUAS
-
- * libgksu/libgksu.c:
- - add gettext call in the prompt in su_ask_password, so that
- the prompt is translated
-
-2006-08-15 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - accepted patch by Michael Vogt to fix the detection of
- sudo password failure by making the fd block while expecting
- the line right after the password is sent to sudo
-
-2006-08-06 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.8
-
- * libgksu/libgksu.c:
- - bring the rest of the startup notification code from the
- application
-
-2006-07-19 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.7
-
- * libgksuui/gksuui-dialog.{c,h}:
- - gksuui_dialog_init is not called after the properties
- are set, so post-pone creating the gnome-keyring UI
- when they are; also fixes a logic error
-
-2006-07-16 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.6
-
- * libgksuui/gksuui-dialog.c, libgksu/libgksu.c:
- - add a new object property to GksuuiDialog, and pass
- the sudo_mode boolean to it on object instanciation,
- so that the sudo window will not have the gnome_keyring
- stuff, again
-
- * libgksu/libgksu.c[gksu_sudo_full]:
- - use select in the read side of the parent_pipe, so that
- the sudo prompt will not show up after the non-blocking
- read is done (addresses Debian bug #377746)
- - do not remove the hostname/socket part of the DISPLAY
- (addresses Debian bug #349652)
-
-2006-07-12 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.5
-
- * libgksu/libgksu.{c,h}:
- - add accessor methods for the startup notification launcher
- context
-
-2006-07-10 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - increment version to 1.9.5
-
- * libgksu/libgksu.{c,h}, libgksuui/gksu-dialog.{c,h}:
- - implement a new 'alert' label, to allow applications showing
- messages like 'wrong password, try again'
-
-2006-07-05 Gustavo Noronha Silva <kov at debian.org>
-
- * gksu.png, gksu-properties/{Makefile.am,gksu-properties.desktop.in,
- gksu-properties.c}:
- - added an icon, and a desktop file so that the capplet will show in
- the preferences menu for the desktop
-
-2006-07-03 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - remove \n from the check of the command name, since gtop
- does not give a \n-terminated string; thanks to
- Benoît Dejean <benoit at placenet.org> for pointing this out
-
-2006-06-29 Gustavo Noronha Silva <kov at debian.org>
-
- * gksu-properties/*:
- - start a simple capplet to configure the gksu gconf
- preferences
-
- * libgksu/defines.h:
- - small adaption so it can better be used by gksu-properties
-
-2006-06-26 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.4
-
- * libgksu/libgksu.c:
- - correctly derreference the error pointer when checking
- if something was returned by ask_pass
-
-2006-06-25 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.9.3
-
- * libgksu/libgksu.c:
- - use TRUE for success and FALSE for failure, to match glib's
- spawn API - well, it's a development release =D
-
- * libgksu/libgksu.c:
- - handle canceling the dialog correctly; added a new
- error to the enum
-
- * configure.ac, libgksu/libgksu.c:
- - accepted patch by Benoît Dejean <benoit at placenet.org>
- to get the process name in a platform independent way
-
-2006-05-01 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added fr to ALL_LINGUAS
-
- * configure.ac, libgksu/Makefile.am:
- - only use the version script if the system we're
- building on supports it; thanks to Daniel Macks
- for the patch
-
- * libgksu/libgksu.c:
- - check fread's return value before using strlen
- and setting a \0 in the xauth string, to prevent
- problems when xauth returns nothing (#7698)
- - handle locales which mess with the 'su:' layout
-
- * Release 1.9.2
-
- * configure.ac:
- - fixed gettext domain define
-
-2006-04-30 Gustavo Noronha Silva <kov at debian.org>
-
- * docs/*:
- - updated documentation
-
- * libgksu/Makefile.am:
- - increased minor version of the library, since some
- symbols were added
-
- * libgksuui/Makefile.am:
- - do not build a static version of the lib only;
- I need a shared version with PIC symbols built so
- that libgksu will be able to be fully PIC
-
- * libgksu/libgksu.c:
- - provide an API for simply getting the password
- - standardize the get methods that return string to
- return NULL if they were not set, and updated
- "docstrings" to fit;
- - removed translatable marks for strings that are
- errors printed to stderr
- - made some strings look better or more HIG compliant
-
- * libgksuui/libgksu.{c,h}, libgksuui/gksuui-dialog.c:
- - accepted changes from the Ubuntu people to make the dialog
- and messages be more beatiful; also provide an API that
- enables specifying a descriptional name for the command, that
- is used automatically in the message
-
- * libgksuui/gksuui-dialog.c:
- - do not center the label that is used to display
- the message
-
-2006-04-24 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - use the internal context->sudo_mode to tell the
- ask_pass function if we're on su or sudo mode
-
- * libgksu/libgksu.{c.h}:
- - implemented the message setting and getting
- functions, and use the message that is given
- when creating the dialog
-
- * Release 1.9.1
-
-2006-04-23 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu2.pc.in:
- - add gnome-keyring-1 and gconf-2.0 as dependencies
-
- * Release 1.9.0
-
- * libgksu/test-gksu.c:
- - display message before testing gksu_sudo_full, so we
- get a better picture of where stuff is happening
- - add a test to the new gksu_run{,_full} API
-
- * libgksu.c:
- - use non-blocking read when looking for the sudo prompt,
- so that we won't get blocked if there is none; also,
- make sure the window is displayed
- - (su) track that gnome keyring was used to enhance the pass_not_needed
- display logic; display it parallel to running the command, to match
- gksu_sudo_full behavior
- - only print the password when on debug mode
- - init sn_context with NULL, so non-SN-supporting users will
- not segfault when we check for the value
-
- * libgksu/libgksu.{c,h}:
- - new API gksu_run{,_full}, that is a generic way of using
- gksu functionality, leaving the choice of su or sudo backend
- to the gconf setting
-
-2006-04-16 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - used suggestion by Benoît Dejean <benoit at placenet.org>
- to avoid buffer overflows on the debug code
-
- * libgksu/libgksu.c:
- - patch from Michael Vogt to fix corner condition which
- happens when fgets returns badly with a specific app
-
-2006-04-15 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c, libgksu/gksu-run-helper.c:
- - check for xauth at /usr/bin (Xorg 7.0) and /usr/X11R6/bin
- (Xorg 6.9 and XFree86) [merged from trunk]
-
-2006-03-12 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksuui/gksuui-dialog.c:
- - added UI for the gnome-keyring support in the main widget
-
- * libgksu/libgksu.c:
- - Preliminary support for gnome-keyring imported from the
- gksu app code; it now removes the password from the
- keyring in case it tries with it and fails
-
-2006-03-02 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added dependency on libstartup-notification-1.0 to
- PKG_CHECK_MODULES; startup notification support has
- been added!
-
- * libgksu/test-gksu.c:
- - use the new location for xterm (FHS-compliant)
-
- * libgksu/libgksu.c:
- - integrated patch by Michael Vogt to support startup notfication
- - added accessor methods for the GksuContext structure, I want it
- to be opaque
-
- * libgksu/Makefile.am, libgksu/libgksu2.pc.in:
- - misc fixes to build system
-
-2006-01-24 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksuui/gksuui-dialog.{c,h}:
- - applied patch by Michael Vogt to report that capslock is enabled
- with small modifications
-
-2006-01-07 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c, docs/*:
- - revamp documentation; gtk-doc-style comments added to
- functions and some fixes to return values were made to
- match the docs
-
- * configure.ac, Makefile.am, others:
- - revamping the i18n infra-structure; mainly removing
- local intl/ copy and updating files
- - do not use local copies of m4 files in a m4/ directory
-
- * configure.ac:
- - do not create pkg-config files for libgksuui; it won't
- be installed anymore
-
- * Make libgksuui a sub, static library for libgksu only.
- - removed gksu-convenience stuff, that is not going to
- be used anymore
-
-2005-12-11 Gustavo Noronha Silva <kov at debian.org>
-
- * Major design overhaul
- - incorporating libgksuui
- - no longer try to be UI independent; use GTK+ mercylessly
- - incorporating gconf schema and settings handling
- - massive API review, removal of most public functions;
- GksuContext is no longer a GObject-based object, no longer
- has many accessor functions for its data fields and is
- needed for the _full versions of the main API functions
- right now; this allows saner handling of password prompting
- and housekeeping
-
- * gksu.schemas.in:
- - remove always-ask-password for now, it will probably be
- replaced by something else when gnome-keyring is integrated
-
- * intltoolized, modified some stuff for the package
- renaming to work
-
- * libgksu/libgksu.c:
- - integrated 'prompt before grab' support; also make the
- foce-grab configuration effective
-
- * renaming files:
- - libgksu/gksu-context.{c,h} -> libgksu/libgksu.{c,h}
-
-2005-11-23 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.7
-
-2005-11-17 Gustavo Noronha Silva <kov at debian.org>
-
- Following 4 fixes were done with information and help
- provided by Benoît Dejean <benoit at placenet.org>; thanks!
-
- * libgksu/gksu-context.c:
- - change debug message for the case in which we can't find
- a password prompt
-
- * libgksu/gksu-context.c:
- - do not free the user component of the context struct
- twice
-
- * libgksu/gksu-context.c:
- - init buffer with {0} so that debuging information will
- not show crappy stuff for it
-
- * libgksu/gksu-context.c:
- - check if pass_not_needed is there before calling
- it on gksu_context_sudo_run_full
-
-2005-10-25 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.6
-
-2005-10-02 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - fix logic problem when checking if what was read does not
- start with "gksu" or "su" - thanks to Guilherme de S. Pastore
- for spotting the problematic range of code (Debian bug #331124)
-
-2005-09-29 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.5
-
- * libgksu/gksu-context.c:
- - fixed some memory leaks which were added by lack of
- caution on my part =/
-
-2005-09-28 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.4
-
- * relibtoolized with libtool --automake -c -f
- (Debian's libtool 1.5.20-1)
-
- * configure.ac: bump version to 1.3.4
-
- * libgksu/gksu-context.c:
- - apply the same solution to handling error return
- checking to the su backend
-
-2005-09-21 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - handle 'not in sudoers' message (Ubuntu's #14922)
-
-2005-09-18 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - applied a patch to use /proc information to find out the
- name of the current child process to check if it was sudo
- who returned a failure code or the app we called on Linux
- systems; patch and modifications done to it were made by
- Michael Vogt and his advice, respectively (Ubuntu's #7517)
-
-2005-09-12 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - treat the command line to remove the quotes that may have
- been added by gksu's multi-argument processing code
-
-2005-08-20 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.{c,h}:
- - improve error reporting for sudo; tries to detect if sudo
- reported that the user cannot run the command for that user
-
-2005-08-02 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.3
-
- * libgksu/Makefile.am:
- - undo soname change because I stepped back from breaking the ABI
-
- * libgksu/gksu-context.{c,h}:
- - leave ask_and_run as deprecated functions to let software which
- used it at some point in development keep building and running
-
- * libgksu/gksu-context.{c,h}:
- - replaced ask_and_run with run_full for both su and sudo; the
- new API function which accepts another callback function that
- allows the user application to do something if a password was
- not needed like, for example, warning the user
-
-2005-08-01 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c, libgksu/Makefile.am, configure.ac:
- - revert inclusion of gnome-keyring support, which should
- actually go into the app, not the lib
-
-2005-07-21 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/Makefile.am:
- - increased minor version number because of the adition
- to the API
-
- * libgksu/gksu-context.{c,h}, libgksu/test-gksu.c:
- - implemented the gksu_context_ask_and_run counterpart
- for sudo
-
-2005-07-14 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.2 - The "Helsinki" Release!
-
- * libgksu/Makefile.am:
- - increase library minor version because API was added without
- breaking ABI (yet! =D)
-
- * libgksu/gksu-context.c:
- - wrap the keyring callback in the ENABLE_GNOME_KEYRING
- ifdef
-
- * libgksu/gksu-context.c, docs/libgksu1.2-sections.txt:
- - make sure every public API function is documented
-
- * libgksu/gksu-context.c:
- - small fixes and improvements to some info and error messages
-
- * libgksu/gksu-context.c:
- - handle the droping of the \n echoed after password was given
- if a password needed to be given, so we have wheel trust and
- other situations in which you don't need a password handled
- correctly
-
-2005-07-13 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - kill su in try_su_run instead of simply sending a "\n" if it
- asks for password, so we improve speed and avoid dead locks
-
- * libgksu/gksu-context.c:
- - after-password conversation with helper improved quite a bit
- and made simpler; should fix some problems with gksu-run:
- strings coming out eventually and prevent some cases of dead
- locks
-
- * libgksu/gksu-context.c:
- - accepted patch by Aurelien Jacobs <aurel at gnuage.org> that
- moves the keyring_create_item_cb outside of the function
- which calls it, so gksu will not segfault on AMD64, which
- does not permit execution of the stack; this addresses
- Debian bugs #318031, #307975 and #314369.
-
-2005-07-12 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - also use the ECHO trick for try_su_run
-
- * libgksu/gksu-context.c:
- - OK, so the call to usleep must be inside the while loop so
- gksu won't be eating CPU time
-
-2005-07-11 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/test-gksu.c:
- - fixed su_ask_pass declaration to include the GError** argument
-
- * libgksu/gksu-context.c:
- - init buf on gksu_context_ask_and_run with \0's so we don't get
- random weird stuff at the first time we read something to it
-
- * libgksu/gksu-context.c:
- - better checking of whether a prompt is waiting for a password
- or not to figure out if a password is needed or not; this enhances
- the 'only ask for password if really needed' approach and is one
- more step on addressing Debian's #246652; this required some
- tweaking to the logic used in conversation with gksu-run-helper.
-
- * libgksu/gksu-context.c:
- - Fixed wording on xauth warning message so it will not use first
- person; this addresses Debian bug #309563.
-
-2005-07-09 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - kill sudo when trying validation and wait a bit before
- wait()'ing, so gksu gets blocked for less time
-
-2005-06-29 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.{c,h}:
- - modified the password-asking function to receive a GError**
- so we have the possibility of creating a 'problem reporting'
- interface for it
- - also, check the return value of the function and bail out
- if it is FALSE
-
-2005-06-28 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - make a gksu_context_ask_and_run that receives a function
- pointer to request password if needed (so you don't have
- to fill context->password beforehand)
- * libgksu/test-gksu.c:
- - also test the new API function
-
-2005-06-18 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.1
-
- * libgksu/test-gksu.c:
- - s/strings.h/string.h/
-
- * libgksu/gksu-context.c:
- - call try_su_run before the gnome-keyring test; this solves
- lots of issues I was work-arounding before
-
- * libgksu/gksu-context.c:
- - fixed password checking to correct number of chars to compare
- and close fdpty after the comparison so su will not be blocked
- trying to write to the terminal
-
- * libgksu/gksu-context.c:
- - avoid using the keyring if su will simply work without
- a password or if the password is not there at the time
- it needs to be saved
- - nullify the password when entering try_need_password
- and if su will run without it (it may have been reset
- by try_gnome_keyring)
-
- * libgksu/gksu-context.c:
- - implemented a new test to simply try to run su and
- see what happens to check if we need a password
- - the above involved some changes to the _run method
- so it won't simply bail out if a password is not
- supplied and will also be more careful while discarting
- su output, which will simply not exist in some cases
-
-2005-06-16 Gustavo Noronha Silva <kov at debian.org>
-
- * ligbksu/gksu-context.c:
- - only save the password in the GNOME keyring if try_need_password
- has been called
-
-2005-06-15 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/test-gksu.c:
- - use the new API function for testing if a sudo password
- is needed
- - accept --su and --sudo arguments to try only su or sudo
- respectively
-
- * libgksu/gksu-context.{c,h}:
- - added a gksu_context_sudo_try_need_password to
- pre-check if we need a password; this uses sudo -v
- for now but will incorporate other ways of doing the
- check soon
-
-2005-06-14 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added ro to ALL_LINGUAS
-
-2005-06-13 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.3.0
-
-2005-06-09 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac, libgksu/Makefile.am:
- - changes based on the patch by Szilard Novaki to provide a
- --enable-gnome-keyring option to configure, disabled by
- default
- - new development version (1.3.0), API/ABI will not really be
- guaranteed to be that stable from now on 'till 1.4
-
- * docs/libgksu1.2-sections.txt:
- - updated so that the new public API function will appear
- in the documentation
-
- * libgksu/gksu-context.{c,h}:
- - added new public API function gksu_context_try_need_pass
- to check if we need to request a password
- (API version went up to 0:1:0, keeping compatibility)
- - implemented a method of getting a password from and saving
- it to the gnome-keyring, based on a patch provided to
- gksu by Szilard Novaki <novaki at agmen-software.com>
-
-2005-06-01 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added eu to ALL_LINGUAS
-
-2005-05-14 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added sk and nl to ALL_LINGUAS
-
-2005-05-13 Miroslav Kure <kurem at debian.cz>
-
- * configure.ac:
- - added cs to ALL_LINGUAS
-
-2005-05-12 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added pl to ALL_LINGUAS
-
-2005-05-07 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - accepted patch by Michael Vogt <mvogt at acm.org> to make the
- process which uses libgksu the session leader
-
-2005-04-27 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added hu to ALL_LINGUAS
-
- * configure.ac:
- - renamed no_NB to nb on ALL_LINGUAS
-
-2005-04-05 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.6
-
- * libgksu/gksu-context.c:
- - use other tatic to grab xauth cookie to make XDM and
- remote users happy. Should address Debian bugs #280914
- and #245092.
-
- * libgksu/gksu-context.c:
- - applied patch from Michael Vogt to have correct perms
- on the .Xauthority file that is created for sudo
-
- * libgksu/gksu-context.c:
- - some code cleanup and minor glitches were fixed
-
- * libgksu/gksu-run-helper.c:
- - changes to set XAUTHORITY in a more sane way and
- call the real command separately
-
-2004-10-17 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.5a
-
- * libgksu/gksu-context.c:
- - (gksu_context_sudo_run): added some more debugging stuff
- and fixed aditional space when checking if GNOME_SUDO_PASS
- was received, now sudo functionality works again.
- - (gksu_context_sudo_run): find out if password failed
-
-2004-10-16 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.5
-
- * libgksu/gksu-context.c:
- - (gksu_context_run): ignore first line when reading the
- output of gksu-run-helper - this should fix Debian bug
- #272133
- - (gksu_context_sudo_run): fixed the command building
- so that -H will only be used if context->keep_env is
- set - fixes Debian bug #276720
-
-2004-10-14 Gustavo Noronha Silva <kov at debian.org>
-
- * ChangeLog:
- - converted to UTF-8
-
- * libgksu/gksu-context.c:
- - prepare_xauth was modified to always get what comes after
- the ':' character, even if context->ssh_fwd is not set,
- thus making this variable unused for now... this probably
- fixed Debian bug #273819
-
- * configure.ac:
- - added no_NB to ALL_LINGUAS
-
-2004-09-07 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.4
-
- * libgksu/gksu-context.c:
- - applied patch by Martin Pitt <martin.pitt at canonical.com>
- to fix buffer overflows
-
-2004-08-15 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.3
-
- * configure.ac:
- - added ca to ALL_LINGUAS
-
-2004-06-24 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.2
-
- * libgksu/gksu-context.h:
- - added missing G_END_DECLS to fix C++ pre-processing
- (Debian bug #255607)
-
-2004-05-29 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.1
-
-2004-05-27 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.ver, libgksu/Makefile.am:
- - build the library with versioned symbols (thanks
- to Steve Langasek's [vorlon's] talk on "Escaping
- the dependency hell" at Debian Conference 4
-
-2004-05-18 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.2.0!
-
- * libgksu/gksu-context.c:
- - fixed string about Xauthority file already existing
- when being created for the target user
-
- * docs/libgksu-sections.txt:
- - removed the macros and the get_type function,
- added gksu_context_free
-
- * libgksu/gksu-context.{c,h}:
- - document GksuContext and gksu_context_free
-
-2004-05-05 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.1.5
-
- * libgksu/gksu-context.{c,h}:
- - new error for xauth stuff problems
- - now gksu looks at the XAUTHORITY environment
- variable to get the source from which to copy
- the Xauthorization file.
-
-2004-04-11 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - more select->sleep to fix bugs in linux 2.6
-
-2004-03-28 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/test-gksu.c:
- - changed the command that is called from ls to
- xterm
-
- * libgksu/gksu-context.c:
- - remove the password displaying debug stuff
- (it is not safe ;))
- - add an usleep to wait 200 usecs on each loop
- on the while that prints messages... it seems
- like linux 2.6's select() does not want to
- wait =)
-
-2004-03-27 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-context.c:
- - added some wait time before sending the
- password to su - the password was not
- being sent correctly without this.
-
-2004-03-21 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu.h, gksu-context.h:
- - changed double quotes to <> in gksu.h,
- fixed double inclusion of glib.h and
- self-inclusion on gksu-context.h, thanks
- to Max Reinhold Jahnke for the later fix
-
-2004-03-19 Gustavo Noronha Silva <kov at debian.org>
-
- * COPYING, libgksu/*:
- - change license to LGPL version 2
-
-2004-03-08 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-main*, libgksu/gksu-context*:
- - moved -main stuff to -context, made the _run
- stuff be methods of the GksuContext object
- also wrote a get_type function to the enum
- to help bindings
-
- * libgksu/gksu-context.{h,c}:
- - removed title, message and icon related methods
- as they are now to be used with the gksuui-dialog
- widget available in libgksuui
- - fixed problems with the naming of the GObject-related
- macros, so for example TYPE_GKSU_CONTEXT becomes
- GKSU_TYPE_CONTEXT -> I had misunderstood the docs and
- this seems to confuse the python binding generator
-
-2004-03-07 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/*:
- - loads of reorganization and code fixing to have
- it support the new build system, etc
-
- * separating libgksu into its own source package
-
-2004-03-05 gettextize <bug-gnu-gettext at gnu.org>
-
- * Makefile.am (SUBDIRS): Add intl.
- (DIST_SUBDIRS): Add intl.
- * configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
-
-2004-03-05 gettextize <bug-gnu-gettext at gnu.org>
-
- * Makefile.am (SUBDIRS): Add m4.
- (DIST_SUBDIRS): Add m4.
- (EXTRA_DIST): New variable.
- * configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
- (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1.
-
-2004-02-03 Gustavo Noronha Silva <kov at debian.org> [1.1.1]
-
- * configure.ac:
- - polished a bit
-
- * libgksu/gksu-private.c:
- - fixed wrong error checking (duh)
-
- * libgksu/gksu-context.[ch]:
- - new implementation of GksuContext, based on
- the GObject glib facility
-
- * libgksu/libgksu.c, gksu/gksu.c:
- - port to the new GObject-based GksuContext
-
-2004-02-02 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/gksu-private.c, libgksu-gksu-private.h:
- - added a gksu_init_check function to init
- gtk
-
- * libgksu/libgksu.c, libgksu/gksu.h:
- - added printf-like format support for title and
- message setters
- - call gksu_init_check on all the three main functions
- to make sure gtk will be inited
-
-2004-01-29 Gustavo Noronha Silva <kov at debian.org>
-
- * gksu/gksu.c:
- - ported to the new API
-
- * libgksu/libgksu.c, libgksu/gksu-private.c:
- - more well-defined separation between exported
- and not export symbols (now even using the
- visibility __attribute__)
- - new API, based on contexts, preparation for
- 1.2
-
- * gksu/gksuexec.c:
- - accepted patch from Jorgen Viksell <jorgen.viksell at telia.com>
- to have gksuexec show a combo listing all the users on the
- system, thanks!
-
-2004-01-20 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.0.3
-
- * libgksu/libgksu.c:
- - fixed _gksu_conf->dir allocation for gksu_sudo_run
- to work
-
- * libgksu/libgksu.c:
- - added aditional error checking code to the xauth
- exec to avoid a segfault when it returns nothing
- patch by Doug Holland <meldroc at frii.com>
-
-2004-01-18 Gustavo Noronha Silva <kov at debian.org>
-
- * gksu/gksu.c, Makefile.am:
- - added support to sudo, when called as 'gksudo'
- - create the symlink on install
-
-2004-01-17 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.0.2
-
-2004-01-16 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c, libgksu/gksu.h:
- - improved error checking
- - improved error reporting on sudo related stuff
- - added gksu_sudo_run, with sudo support
-
- * remove the common directory and library, integrate
- the relevant parts into libgksu and gksu separately
-
- * libgksu/libgksu.c, common/gksutils.c:
- - incorporated code from gnome-sudo with some
- modifications to have gksu handle sudo, too
- untested, probably unstable code, needs testing
- to be exposed
-
- * libgksu/Makefile.am:
- - build the library with -fPIC, to allow prelinking
-
- * configure.ac:
- - added da to ALL_LINGUAS
-
-2004-01-15 Gustavo Noronha Silva <kov at debian.org>
-
- * libgksu/libgksu.c:
- - Fixed problems with gksu closing the application
- when canceled
- - gtk_init_check instead of gtk_init, to avoid failures
- killing the "parent" application
-
-2004-01-14 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.0.1
-
- * Major update on the documentation stuff
-
- * Small corrections to the locale handling code
-
-2003-12-19 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 1.0.0
-
- * introducing libgksu! I believe the code is stable
- enough for a 1.0 release -- althought the change to
- a library might be a big move, the code has not
- being changed a lot... let's see if the Debian
- unstable trial proves me wrong.
-
-2003-11-18 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.18
-
- * src/gui.c:
- - does not quit when grab fails, warns and continues...
-
- * po/de.po:
- - small fix, thanks to Michael Vogt <mvogt at acm.org>
-
- * src/gksu-run-helper.c:
- - fix bashism
-
-2003-11-14 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.17
-
- * autogen.sh:
- - use automake 1.7, instead of 1.6
-
- * configure.ac, po/pl.po:
- - added polish translation, thanks to Emil <emil5 at go2.pl>
-
- * src/gksu-run-helper.c:
- - added, to help fix the stupid security bug
-
- * src/gksu.{c,h}, src/su.c, src/xauth.c:
- - modified to use the gksu-run-helper, which will
- fix the security bug in which the Xauth token
- appears on a ps auxwww
-
-2003-08-28 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.16
-
-2003-08-26 Gustavo Noronha Silva <kov at debian.org>
-
- * src/xauth.c:
- - take care to take the MIT-MAGIC-COOKIE-1 from
- xauth list, XDM auth strings were biting gksu
-
-2003-08-08 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.15
-
-2003-08-06 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac:
- - added 'de' (German) to ALL_LINGUAS
-
- * gksu.desktop, gksuexec.desktop:
- - added German translation, thanks to:
- Sebastian Heinlein <sebastian.heinlein at campus.lmu.de>
-
-2003-07-29 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.14
-
- * src/su.c:
- - shows a nicer dialog with 'Wrong password.'
- instead of simply 'Child exited with error
- 1' thingy if su returns 'Authentication failure'
-
- * src/su.c:
- - use >& to redirect instead of 2>&1 to make
- non-bash shells happy (Closes: #203386,
- #203387)
-
-2003-07-24 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.13
-
- * README:
- - some explanations added
-
- * src/gui.c, src/su.c:
- - some modifications on the default label that's
- presented explaining why it wants the password,
- and in the label behavior, in general
-
- * src/gksu.c, src/xauth.c:
- - added --ssh-fwd option, which uses just the :x.x
- part of display when working with xauth, for gksu
- to work on ssh X11 forwarding
- (Closes Debian bug: #202532)
-
-2003-07-23 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.12
-
-2003-07-22 Gustavo Noronha Silva <kov at debian.org>
-
- * src/xauth.c:
- - added output about xauth token, file, directory and
- display, for debuging purposes (when --debug is enabled)
- - fixed clean_dir to remove the directory if it is empty
- before clean_dir is called
-
- * src/su.c:
- - do not show xauth's output, unless --debug is given
- - get rid of bashism when calling xauth by using the
- env command
-
- * src/gksu.c:
- - added a --debug option, to ask for more verbose
- output
-
-2003-07-14 Gustavo Noronha Silva <kov at debian.org>
-
- * man/gksu.1:
- - fixed --icon position
-
-2003-06-14 gettextize <bug-gnu-gettext at gnu.org>
-
- * Makefile.am (ACLOCAL_AMFLAGS): New variable.
- * configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
- (AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
-
-2003-06-14 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.11
-
- * Applied patch from Ãlvaro Peña <apg at esware.com>
- to HIG-ify gksu a bit more
-
-2003-05-24 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.10
-
- * src/su.c:
- - Why the hell do I want gksu to automaticaly go to
- background? Changed that, I guess that'll help
- lots of scripts.
-
-2003-05-10 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.9
-
- * src/gksuexec.c:
- - fixed the way the command is passed as argument
- to gksu to fix running programs with arguments (duh)
-
-2003-05-08 Gustavo Noronha Silva <kov at debian.org>
-
- * src/su.c:
- - fixed bug which did not allow gksu to run programs
- with arguments like, say, 'emacs /etc/mozpluggerrc' =)
-
-2003-05-06 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac: added es.po to ALL_LINGUAS
-
-2003-05-02 Gustavo Noronha Silva <kov at debian.org>
-
- * configure.ac: added ru.po to ALL_LINGUAS
-
-2003-04-05 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.8
-
- * src/xauth.c:
- - initialize 'xauth' to avoid problems with junk
- thanks to Alex Stewart <am2stewa at uwaterloo.ca>
-
- * src/gui.c:
- - wait a bit longer before checking for the effectiveness of
- the keyboard/mouse grab
-
-2003-03-29 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.7
-
- * src/gksu.c, src/xauth.c:
- - remove references to sudo, at least for now
-
- * src/sudo.{c,h}:
- - removed, no longer provide sudo functionality, it
- doesn't work as well as it should
-
-2003-03-28 Gustavo Noronha Silva <kov at debian.org>
-
- * src/su.c:
- - use xauth information to make the magic work
-
- * src/xauth.c:
- - implement prepare_xauth_su to handle Xauth in a safer way,
- by using the 'xauth' program instead of a world readable
- .Xauthorization file
- - move the old way of doing things to the prepare_xauth_sudo
- function... sudo is a difficult piece of software to handle
-
- * src/gksu.c:
- - moved as much xauth specific stuff as I could to xauth.c
-
-2003-02-01 Allan Douglas <allan_douglas at gmx.net>
-
- * src/sudo.c:
- - cleanups
-
-2003-01-31 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.1
-
- * AUTHORS:
- - added Allan Douglas
-
-2003-01-31 Allan Douglas <allan_douglas at gmx.net>
-
- * src/su.c:
- - fixed the "missing output" bug
-
-2003-01-30 Allan Douglas <allan_douglas at gmx.net>
-
- * configure.ac:
- - removed yacc dependency
-
- * src/su.c:
- - cleanups
-
-2003-01-30 Gustavo Noronha Silva <kov at debian.org>
-
- * src/su.c, src/sudo.c:
- - fixed some stuff pointed by my friend "o_0" =P
-
- * src/gksuexec.c:
- - has an 'advanced' dialog to select options
- 'login_shell' and '--preserv-env' for gksu
-
-2003-01-30 Gustavo Noronha Silva <kov at debian.org>
-
- * src/gksuexec.c:
- - has an 'advanced' dialog to select options
- 'login_shell' and '--preserv-env' for gksu
-
-2003-01-29 Gustavo Noronha Silva <kov at debian.org>
-
- * man/gksu.1:
- - added reference for gksuexec command
- - updated with the help of the 'help2man' command
-
- * man/gksuexec.1: (new)
- - wrote manpage to the new command
-
- * man/Makefile.am: (new)
- - install manpages
-
- * src/gksu.c:
- - fixed small and harmless segfault when free'ing
- conf.title
- - accept -i, --icon to set window's icon
- - print-pass' message no longer assumes root user
-
- * src/gui.c:
- - use gksu's icon at the window, instead of the
- question mark
- - use conf.icon to set gksu window's icon
-
-2003-01-29 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.9.0
-
- * src/gksuexec.c:
- - a new program, a dialog to ask for other informations
- as a wrapper to gksu's command line
-
- * src/util.{c,h}, src/gui.{c,h}:
- - moved gk_dialog from gui to util to make it easier
- for gksuexec to use it
-
- * gksuexec.desktop:
- - new icon for GNOME, to run gksuexec
-
-2003-01-28 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.8.5
-
- * src/su.c:
- - does not ask for password when the real uid
- is 0 (see http://bugs.debian.org/178675)
-
- * src/gksu.c:
- - minor aesthetical fixes
-
-2003-01-22 Gustavo Noronha Silva <kov at debian.org>
-
- * Release 0.8.4
-
-2003-01-14 Gustavo Noronha Silva <kov at debian.org>
-
- * src/Makefile.am:
- - define DATA_DIR
- - add optimization on compilation
-
- * src/gui.c:
- - set default windows icon (requires Gtk+2.2)
-
- * gksu.png:
- - new icon, from art.gnome.org, Authorization.png
-
- * gksu.png -> gksu-terminal.png:
- - renamed icon for gnome's desktop icon
-
-2003-01-14 Gustavo Noronha Silva <kov at debian.org>
-
- * 0.8.3 Release
-
- * clean up to the build system, using autoconf
- 2.50 and automake-1.6
-
- * man/gksu.1:
- - fixed WHATIS entry
-
- * gksu.desktop, gksu.png:
- - icon for GNOME's System menu, to open a terminal
- as the root user
-
-2003-01-14 Gustavo Noronha Silva <kov at debian.org>
-
- * 0.8.2 Release
- - changed configure.in
-
- * src/gksu.c:
- - make reset environment the default, changed:
- reset-env, r to preserv-env, k
- - make not login shell the default, again, it
- will make the Xauth stuff break... duh
-
- * src/su.c, src/sudo.c:
- - yes, yes, auto-background again =P
-
- * src/gui.c:
- - cleans the Xauth directory in case the dialog is
- canceled or closed
- - changed buttons' positions to reflect the changes
- that happened to GNOME2
-
- * src/gksu.c:
- - made title more i18n friendly, fixed some small
- memory leaks
-
- * po/pt_BR.po:
- - updated translation
-
-2003-01-12 Gustavo Noronha Silva <kov at debian.org>
-
- * src/gksu.c:
- - make login shell by default
-
- * src/su.c, src/sudo.c:
- - no grandchild, no auto-background anymore
- - fixes on outputing things
-
-2002-08-13 gettextize <bug-gnu-gettext at gnu.org>
-
- * Makefile.am (SUBDIRS): Add m4.
- (SUBDIRS): Remove intl.
- (ACLOCAL_AMFLAGS): New variable.
- (EXTRA_DIST): New variable.
-
- * configure.in (AC_OUTPUT): Add m4/Makefile.
-
-2002-02-18 Gustavo Noronha Silva <kov at debian.org>
-
- * gksu: initial version.
-
Copied: libgksu/tags/2.0.8/ChangeLog (from rev 843, libgksu/trunk/ChangeLog)
===================================================================
--- libgksu/tags/2.0.8/ChangeLog (rev 0)
+++ libgksu/tags/2.0.8/ChangeLog 2009-03-04 18:39:36 UTC (rev 844)
@@ -0,0 +1,1532 @@
+2009-02-22 Gustavo Noronha Silva <kov at alface>
+
+ * Release 2.0.8
+
+2009-02-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c: - added threads protection for the gdk
+ fadeout/fadein animation, so that callers will not have X errors
+ when trying to use gdk functions in parallel with us
+ See http://bugzilla.gnome.org/show_bug.cgi?id=549760.
+
+2009-02-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac, libgksu/libgksu.{c,h}, libgksu/gksu-run-helper.c:
+ - accepted patch by Joshua Kwan <jkwan at vmware.com> to
+ return the same status code as the child
+
+2009-02-03 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added th to ALL_LINGUAS
+
+2008-08-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c: patch by Daniel Richard G. <skunk at iSKUNK.ORG>
+ to allow changing the location of the lockfile, so that libgksu
+ will work on AFS/NFS mounted home directories
+
+2008-06-20 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-run-helper.c: accepted patch by Michael Vogt, from
+ Ubuntu, to fix very long commands not fitting in the helper's
+ statically-sized buffer (Debian bug #486087, launchpad #173757)
+
+ * libgksu/libgksu.c (sudo_full): accepted patch by Michael Vogt,
+ from Ubuntu, to fix sudo having problems resolving network
+ addresses breaking gksu (Debian bug #486083, launchpad #237325)
+
+2008-05-27 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.7
+
+ * libgksu/libgksu.c (gksu_sudo_full): accepted patch by Ben
+ Hutchings <ben at decadent.org.uk> to also disable nonblocking I/O
+ when no password is asked (Debian bug #463709)
+
+ * configure.ac: - remove \n from the test code used to test for
+ the presence of the -version-script linker option; that was
+ causing the test to fail
+
+2008-05-16 Gustavo Noronha Silva <Gustavo Noronha Silva <kov at alfaiati.net>>
+
+ * Release 2.0.6
+
+2008-01-02 Guilherme de S. Pastore <gpastore at debian.org>
+
+ * libgksu/libgksu.c (gksu_sudo_full): fix typo introduced with the latest
+ changes ("aways").
+
+2007-12-31 Gustavo Noronha Silva <kov at cenoura>
+
+ * libgksu/libgksu.c:
+ - format parameters were wrong for the case in which you
+ ask gksu to run a given command as a given user (other than
+ root); thanks to Uwe Kleine-König <ukleinek at informatik.uni-freiburg.de>
+ for pointing out; Debian bug #449180
+
+ * libgksu/libgksu.c:
+ - accepted patch from Ubuntu by Michael Vogt to add a new
+ property for GksuContext: always_ask_password; the patch
+ suffered minor aditions by me to also implement the functionality
+ to the su backend and document the limitations (Debian bug #453423)
+
+ * libgksuui/gksuui-dialog.c:
+ - accepted patch from Ubuntu by Michael Vogt that fixes
+ the capslock notification so that it doesn't change the
+ size of the window (Debian bug #453426)
+
+2007-06-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - accepted patch from Ubuntu, by Michael Vogt, that
+ fixes the way gksu waits for the child process to
+ finish; see:
+ https://bugs.launchpad.net/ubuntu/+source/libgksu/+bug/121581
+
+2007-06-10 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.5
+
+ * libgksu/libgksu.c:
+ - also complete launch notification when cancel is
+ pressed in the dialog; (Addressing Debian Bug #426495)
+
+2007-06-09 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - reworked the way gksu_su{,do}_full relays the child's
+ output, making it sleep rather than wakeup every
+ few microseconds (Addressing Debian Bug #425679)
+
+2007-05-11 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added sv and zh_CN.po to ALL_LINGUAS
+
+2007-03-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added ko to ALL_LINGUAS
+
+2007-03-06 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - always try to create the keyring when setting the password;
+ if the keyring exists this is a no-op, so no problems
+ (Addressing Debian Bug #412681)
+
+ * libgksu/libgksu.c:
+ - improved debugging for getting the password from the
+ GNOME Keyring; and do not show the password anymore when
+ debugging
+
+2007-03-04 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - accepted patch by Michael Vogt to handle the
+ better quoted strings given by gksu
+
+2007-02-04 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.4
+
+2007-01-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.[ch]:
+ - accepted patch by "Gian Mario Tagliaretti"
+ <g.tagliaretti at gmail.com> to turn GksuContext into
+ a boxed type, so that it can be used in a saner way
+ in bindings
+
+2007-01-05 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - accepted patch by ÐиÑалий ÐÑенко <betalb at gmail.com>
+ which makes libgksu only replace the 'password typing' character
+ when '*' is the default one
+
+2006-12-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - make sure DESKTOP_STARTUP_ID is set in the environment correctly
+
+2006-10-31 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - remove a trailing \n if it exists in the password we get from
+ the GNOME Keyring (Addresses Debian Bug #395462)
+
+2006-10-23 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.3
+
+ * libgksu/libgksu.c:
+ - make sure the dialog is _destroyed_ instead of just being
+ hidden, after some action has been taken in the dialog that
+ asks for the password
+ - returns WRONGAUTOPASS instead of WRONGPASS when wrong password
+ is the one we got from the gnome keyring
+ - store the password in the GNOME Keyring without the \n
+ (Addresses Debian Bug #394895)
+
+2006-10-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.2
+
+ * libgksu/libgksu.c:
+ - make sure we notice ECHO disabled, and remove some uneeded waits
+ which will probably speedup using su with password, but probably
+ slow down su without password; this should avoid deadlocks when
+ su delays setting ECHO off.
+
+2006-10-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksuui/gksuui-dialog.c:
+ - try to always have focus, by traping the focus-out-event;
+ should address Debian bug #391804
+
+2006-10-08 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 2.0.1
+
+ * libgksu/libgksu.c:
+ - use some brute force reading when using sudo, to be able
+ to handle stuff like the sudo lecture and pam modules debugging
+
+2006-10-01 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - if xauth is an empty string when using the su backend,
+ then try to get it again by striping the hostname part
+ of the display string; this is needed for ssh X forwarding
+
+2006-09-23 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - version set to 2.0.0; releasing libgksu 2, at last!
+
+2006-09-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - have gksu ignore lines coming from the process 'till it is able
+ to find the gksu: waiting line; this is done observing some
+ time and size constraints, though, so we won't end up in an infinite
+ loop; this addresses #17139; libpam-mount should now work happily with
+ debug on
+ - also make su's child session leader, like sudo's, so that when the
+ program you ran launches another, closing the first will not destroy
+ the second
+
+2006-09-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added it to ALL_LINGUAS
+
+2006-08-19 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added lt to ALL_LINGUAS
+
+ * libgksu/libgksu.c:
+ - add gettext call in the prompt in su_ask_password, so that
+ the prompt is translated
+
+2006-08-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - accepted patch by Michael Vogt to fix the detection of
+ sudo password failure by making the fd block while expecting
+ the line right after the password is sent to sudo
+
+2006-08-06 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.8
+
+ * libgksu/libgksu.c:
+ - bring the rest of the startup notification code from the
+ application
+
+2006-07-19 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.7
+
+ * libgksuui/gksuui-dialog.{c,h}:
+ - gksuui_dialog_init is not called after the properties
+ are set, so post-pone creating the gnome-keyring UI
+ when they are; also fixes a logic error
+
+2006-07-16 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.6
+
+ * libgksuui/gksuui-dialog.c, libgksu/libgksu.c:
+ - add a new object property to GksuuiDialog, and pass
+ the sudo_mode boolean to it on object instanciation,
+ so that the sudo window will not have the gnome_keyring
+ stuff, again
+
+ * libgksu/libgksu.c[gksu_sudo_full]:
+ - use select in the read side of the parent_pipe, so that
+ the sudo prompt will not show up after the non-blocking
+ read is done (addresses Debian bug #377746)
+ - do not remove the hostname/socket part of the DISPLAY
+ (addresses Debian bug #349652)
+
+2006-07-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.5
+
+ * libgksu/libgksu.{c,h}:
+ - add accessor methods for the startup notification launcher
+ context
+
+2006-07-10 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - increment version to 1.9.5
+
+ * libgksu/libgksu.{c,h}, libgksuui/gksu-dialog.{c,h}:
+ - implement a new 'alert' label, to allow applications showing
+ messages like 'wrong password, try again'
+
+2006-07-05 Gustavo Noronha Silva <kov at debian.org>
+
+ * gksu.png, gksu-properties/{Makefile.am,gksu-properties.desktop.in,
+ gksu-properties.c}:
+ - added an icon, and a desktop file so that the capplet will show in
+ the preferences menu for the desktop
+
+2006-07-03 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - remove \n from the check of the command name, since gtop
+ does not give a \n-terminated string; thanks to
+ Benoît Dejean <benoit at placenet.org> for pointing this out
+
+2006-06-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * gksu-properties/*:
+ - start a simple capplet to configure the gksu gconf
+ preferences
+
+ * libgksu/defines.h:
+ - small adaption so it can better be used by gksu-properties
+
+2006-06-26 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.4
+
+ * libgksu/libgksu.c:
+ - correctly derreference the error pointer when checking
+ if something was returned by ask_pass
+
+2006-06-25 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.9.3
+
+ * libgksu/libgksu.c:
+ - use TRUE for success and FALSE for failure, to match glib's
+ spawn API - well, it's a development release =D
+
+ * libgksu/libgksu.c:
+ - handle canceling the dialog correctly; added a new
+ error to the enum
+
+ * configure.ac, libgksu/libgksu.c:
+ - accepted patch by Benoît Dejean <benoit at placenet.org>
+ to get the process name in a platform independent way
+
+2006-05-01 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added fr to ALL_LINGUAS
+
+ * configure.ac, libgksu/Makefile.am:
+ - only use the version script if the system we're
+ building on supports it; thanks to Daniel Macks
+ for the patch
+
+ * libgksu/libgksu.c:
+ - check fread's return value before using strlen
+ and setting a \0 in the xauth string, to prevent
+ problems when xauth returns nothing (#7698)
+ - handle locales which mess with the 'su:' layout
+
+ * Release 1.9.2
+
+ * configure.ac:
+ - fixed gettext domain define
+
+2006-04-30 Gustavo Noronha Silva <kov at debian.org>
+
+ * docs/*:
+ - updated documentation
+
+ * libgksu/Makefile.am:
+ - increased minor version of the library, since some
+ symbols were added
+
+ * libgksuui/Makefile.am:
+ - do not build a static version of the lib only;
+ I need a shared version with PIC symbols built so
+ that libgksu will be able to be fully PIC
+
+ * libgksu/libgksu.c:
+ - provide an API for simply getting the password
+ - standardize the get methods that return string to
+ return NULL if they were not set, and updated
+ "docstrings" to fit;
+ - removed translatable marks for strings that are
+ errors printed to stderr
+ - made some strings look better or more HIG compliant
+
+ * libgksuui/libgksu.{c,h}, libgksuui/gksuui-dialog.c:
+ - accepted changes from the Ubuntu people to make the dialog
+ and messages be more beatiful; also provide an API that
+ enables specifying a descriptional name for the command, that
+ is used automatically in the message
+
+ * libgksuui/gksuui-dialog.c:
+ - do not center the label that is used to display
+ the message
+
+2006-04-24 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - use the internal context->sudo_mode to tell the
+ ask_pass function if we're on su or sudo mode
+
+ * libgksu/libgksu.{c.h}:
+ - implemented the message setting and getting
+ functions, and use the message that is given
+ when creating the dialog
+
+ * Release 1.9.1
+
+2006-04-23 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu2.pc.in:
+ - add gnome-keyring-1 and gconf-2.0 as dependencies
+
+ * Release 1.9.0
+
+ * libgksu/test-gksu.c:
+ - display message before testing gksu_sudo_full, so we
+ get a better picture of where stuff is happening
+ - add a test to the new gksu_run{,_full} API
+
+ * libgksu.c:
+ - use non-blocking read when looking for the sudo prompt,
+ so that we won't get blocked if there is none; also,
+ make sure the window is displayed
+ - (su) track that gnome keyring was used to enhance the pass_not_needed
+ display logic; display it parallel to running the command, to match
+ gksu_sudo_full behavior
+ - only print the password when on debug mode
+ - init sn_context with NULL, so non-SN-supporting users will
+ not segfault when we check for the value
+
+ * libgksu/libgksu.{c,h}:
+ - new API gksu_run{,_full}, that is a generic way of using
+ gksu functionality, leaving the choice of su or sudo backend
+ to the gconf setting
+
+2006-04-16 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - used suggestion by Benoît Dejean <benoit at placenet.org>
+ to avoid buffer overflows on the debug code
+
+ * libgksu/libgksu.c:
+ - patch from Michael Vogt to fix corner condition which
+ happens when fgets returns badly with a specific app
+
+2006-04-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c, libgksu/gksu-run-helper.c:
+ - check for xauth at /usr/bin (Xorg 7.0) and /usr/X11R6/bin
+ (Xorg 6.9 and XFree86) [merged from trunk]
+
+2006-03-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksuui/gksuui-dialog.c:
+ - added UI for the gnome-keyring support in the main widget
+
+ * libgksu/libgksu.c:
+ - Preliminary support for gnome-keyring imported from the
+ gksu app code; it now removes the password from the
+ keyring in case it tries with it and fails
+
+2006-03-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added dependency on libstartup-notification-1.0 to
+ PKG_CHECK_MODULES; startup notification support has
+ been added!
+
+ * libgksu/test-gksu.c:
+ - use the new location for xterm (FHS-compliant)
+
+ * libgksu/libgksu.c:
+ - integrated patch by Michael Vogt to support startup notfication
+ - added accessor methods for the GksuContext structure, I want it
+ to be opaque
+
+ * libgksu/Makefile.am, libgksu/libgksu2.pc.in:
+ - misc fixes to build system
+
+2006-01-24 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksuui/gksuui-dialog.{c,h}:
+ - applied patch by Michael Vogt to report that capslock is enabled
+ with small modifications
+
+2006-01-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c, docs/*:
+ - revamp documentation; gtk-doc-style comments added to
+ functions and some fixes to return values were made to
+ match the docs
+
+ * configure.ac, Makefile.am, others:
+ - revamping the i18n infra-structure; mainly removing
+ local intl/ copy and updating files
+ - do not use local copies of m4 files in a m4/ directory
+
+ * configure.ac:
+ - do not create pkg-config files for libgksuui; it won't
+ be installed anymore
+
+ * Make libgksuui a sub, static library for libgksu only.
+ - removed gksu-convenience stuff, that is not going to
+ be used anymore
+
+2005-12-11 Gustavo Noronha Silva <kov at debian.org>
+
+ * Major design overhaul
+ - incorporating libgksuui
+ - no longer try to be UI independent; use GTK+ mercylessly
+ - incorporating gconf schema and settings handling
+ - massive API review, removal of most public functions;
+ GksuContext is no longer a GObject-based object, no longer
+ has many accessor functions for its data fields and is
+ needed for the _full versions of the main API functions
+ right now; this allows saner handling of password prompting
+ and housekeeping
+
+ * gksu.schemas.in:
+ - remove always-ask-password for now, it will probably be
+ replaced by something else when gnome-keyring is integrated
+
+ * intltoolized, modified some stuff for the package
+ renaming to work
+
+ * libgksu/libgksu.c:
+ - integrated 'prompt before grab' support; also make the
+ foce-grab configuration effective
+
+ * renaming files:
+ - libgksu/gksu-context.{c,h} -> libgksu/libgksu.{c,h}
+
+2005-11-23 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.7
+
+2005-11-17 Gustavo Noronha Silva <kov at debian.org>
+
+ Following 4 fixes were done with information and help
+ provided by Benoît Dejean <benoit at placenet.org>; thanks!
+
+ * libgksu/gksu-context.c:
+ - change debug message for the case in which we can't find
+ a password prompt
+
+ * libgksu/gksu-context.c:
+ - do not free the user component of the context struct
+ twice
+
+ * libgksu/gksu-context.c:
+ - init buffer with {0} so that debuging information will
+ not show crappy stuff for it
+
+ * libgksu/gksu-context.c:
+ - check if pass_not_needed is there before calling
+ it on gksu_context_sudo_run_full
+
+2005-10-25 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.6
+
+2005-10-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - fix logic problem when checking if what was read does not
+ start with "gksu" or "su" - thanks to Guilherme de S. Pastore
+ for spotting the problematic range of code (Debian bug #331124)
+
+2005-09-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.5
+
+ * libgksu/gksu-context.c:
+ - fixed some memory leaks which were added by lack of
+ caution on my part =/
+
+2005-09-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.4
+
+ * relibtoolized with libtool --automake -c -f
+ (Debian's libtool 1.5.20-1)
+
+ * configure.ac: bump version to 1.3.4
+
+ * libgksu/gksu-context.c:
+ - apply the same solution to handling error return
+ checking to the su backend
+
+2005-09-21 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - handle 'not in sudoers' message (Ubuntu's #14922)
+
+2005-09-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - applied a patch to use /proc information to find out the
+ name of the current child process to check if it was sudo
+ who returned a failure code or the app we called on Linux
+ systems; patch and modifications done to it were made by
+ Michael Vogt and his advice, respectively (Ubuntu's #7517)
+
+2005-09-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - treat the command line to remove the quotes that may have
+ been added by gksu's multi-argument processing code
+
+2005-08-20 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.{c,h}:
+ - improve error reporting for sudo; tries to detect if sudo
+ reported that the user cannot run the command for that user
+
+2005-08-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.3
+
+ * libgksu/Makefile.am:
+ - undo soname change because I stepped back from breaking the ABI
+
+ * libgksu/gksu-context.{c,h}:
+ - leave ask_and_run as deprecated functions to let software which
+ used it at some point in development keep building and running
+
+ * libgksu/gksu-context.{c,h}:
+ - replaced ask_and_run with run_full for both su and sudo; the
+ new API function which accepts another callback function that
+ allows the user application to do something if a password was
+ not needed like, for example, warning the user
+
+2005-08-01 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c, libgksu/Makefile.am, configure.ac:
+ - revert inclusion of gnome-keyring support, which should
+ actually go into the app, not the lib
+
+2005-07-21 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/Makefile.am:
+ - increased minor version number because of the adition
+ to the API
+
+ * libgksu/gksu-context.{c,h}, libgksu/test-gksu.c:
+ - implemented the gksu_context_ask_and_run counterpart
+ for sudo
+
+2005-07-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.2 - The "Helsinki" Release!
+
+ * libgksu/Makefile.am:
+ - increase library minor version because API was added without
+ breaking ABI (yet! =D)
+
+ * libgksu/gksu-context.c:
+ - wrap the keyring callback in the ENABLE_GNOME_KEYRING
+ ifdef
+
+ * libgksu/gksu-context.c, docs/libgksu1.2-sections.txt:
+ - make sure every public API function is documented
+
+ * libgksu/gksu-context.c:
+ - small fixes and improvements to some info and error messages
+
+ * libgksu/gksu-context.c:
+ - handle the droping of the \n echoed after password was given
+ if a password needed to be given, so we have wheel trust and
+ other situations in which you don't need a password handled
+ correctly
+
+2005-07-13 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - kill su in try_su_run instead of simply sending a "\n" if it
+ asks for password, so we improve speed and avoid dead locks
+
+ * libgksu/gksu-context.c:
+ - after-password conversation with helper improved quite a bit
+ and made simpler; should fix some problems with gksu-run:
+ strings coming out eventually and prevent some cases of dead
+ locks
+
+ * libgksu/gksu-context.c:
+ - accepted patch by Aurelien Jacobs <aurel at gnuage.org> that
+ moves the keyring_create_item_cb outside of the function
+ which calls it, so gksu will not segfault on AMD64, which
+ does not permit execution of the stack; this addresses
+ Debian bugs #318031, #307975 and #314369.
+
+2005-07-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - also use the ECHO trick for try_su_run
+
+ * libgksu/gksu-context.c:
+ - OK, so the call to usleep must be inside the while loop so
+ gksu won't be eating CPU time
+
+2005-07-11 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/test-gksu.c:
+ - fixed su_ask_pass declaration to include the GError** argument
+
+ * libgksu/gksu-context.c:
+ - init buf on gksu_context_ask_and_run with \0's so we don't get
+ random weird stuff at the first time we read something to it
+
+ * libgksu/gksu-context.c:
+ - better checking of whether a prompt is waiting for a password
+ or not to figure out if a password is needed or not; this enhances
+ the 'only ask for password if really needed' approach and is one
+ more step on addressing Debian's #246652; this required some
+ tweaking to the logic used in conversation with gksu-run-helper.
+
+ * libgksu/gksu-context.c:
+ - Fixed wording on xauth warning message so it will not use first
+ person; this addresses Debian bug #309563.
+
+2005-07-09 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - kill sudo when trying validation and wait a bit before
+ wait()'ing, so gksu gets blocked for less time
+
+2005-06-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.{c,h}:
+ - modified the password-asking function to receive a GError**
+ so we have the possibility of creating a 'problem reporting'
+ interface for it
+ - also, check the return value of the function and bail out
+ if it is FALSE
+
+2005-06-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - make a gksu_context_ask_and_run that receives a function
+ pointer to request password if needed (so you don't have
+ to fill context->password beforehand)
+ * libgksu/test-gksu.c:
+ - also test the new API function
+
+2005-06-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.1
+
+ * libgksu/test-gksu.c:
+ - s/strings.h/string.h/
+
+ * libgksu/gksu-context.c:
+ - call try_su_run before the gnome-keyring test; this solves
+ lots of issues I was work-arounding before
+
+ * libgksu/gksu-context.c:
+ - fixed password checking to correct number of chars to compare
+ and close fdpty after the comparison so su will not be blocked
+ trying to write to the terminal
+
+ * libgksu/gksu-context.c:
+ - avoid using the keyring if su will simply work without
+ a password or if the password is not there at the time
+ it needs to be saved
+ - nullify the password when entering try_need_password
+ and if su will run without it (it may have been reset
+ by try_gnome_keyring)
+
+ * libgksu/gksu-context.c:
+ - implemented a new test to simply try to run su and
+ see what happens to check if we need a password
+ - the above involved some changes to the _run method
+ so it won't simply bail out if a password is not
+ supplied and will also be more careful while discarting
+ su output, which will simply not exist in some cases
+
+2005-06-16 Gustavo Noronha Silva <kov at debian.org>
+
+ * ligbksu/gksu-context.c:
+ - only save the password in the GNOME keyring if try_need_password
+ has been called
+
+2005-06-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/test-gksu.c:
+ - use the new API function for testing if a sudo password
+ is needed
+ - accept --su and --sudo arguments to try only su or sudo
+ respectively
+
+ * libgksu/gksu-context.{c,h}:
+ - added a gksu_context_sudo_try_need_password to
+ pre-check if we need a password; this uses sudo -v
+ for now but will incorporate other ways of doing the
+ check soon
+
+2005-06-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added ro to ALL_LINGUAS
+
+2005-06-13 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.3.0
+
+2005-06-09 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac, libgksu/Makefile.am:
+ - changes based on the patch by Szilard Novaki to provide a
+ --enable-gnome-keyring option to configure, disabled by
+ default
+ - new development version (1.3.0), API/ABI will not really be
+ guaranteed to be that stable from now on 'till 1.4
+
+ * docs/libgksu1.2-sections.txt:
+ - updated so that the new public API function will appear
+ in the documentation
+
+ * libgksu/gksu-context.{c,h}:
+ - added new public API function gksu_context_try_need_pass
+ to check if we need to request a password
+ (API version went up to 0:1:0, keeping compatibility)
+ - implemented a method of getting a password from and saving
+ it to the gnome-keyring, based on a patch provided to
+ gksu by Szilard Novaki <novaki at agmen-software.com>
+
+2005-06-01 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added eu to ALL_LINGUAS
+
+2005-05-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added sk and nl to ALL_LINGUAS
+
+2005-05-13 Miroslav Kure <kurem at debian.cz>
+
+ * configure.ac:
+ - added cs to ALL_LINGUAS
+
+2005-05-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added pl to ALL_LINGUAS
+
+2005-05-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - accepted patch by Michael Vogt <mvogt at acm.org> to make the
+ process which uses libgksu the session leader
+
+2005-04-27 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added hu to ALL_LINGUAS
+
+ * configure.ac:
+ - renamed no_NB to nb on ALL_LINGUAS
+
+2005-04-05 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.6
+
+ * libgksu/gksu-context.c:
+ - use other tatic to grab xauth cookie to make XDM and
+ remote users happy. Should address Debian bugs #280914
+ and #245092.
+
+ * libgksu/gksu-context.c:
+ - applied patch from Michael Vogt to have correct perms
+ on the .Xauthority file that is created for sudo
+
+ * libgksu/gksu-context.c:
+ - some code cleanup and minor glitches were fixed
+
+ * libgksu/gksu-run-helper.c:
+ - changes to set XAUTHORITY in a more sane way and
+ call the real command separately
+
+2004-10-17 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.5a
+
+ * libgksu/gksu-context.c:
+ - (gksu_context_sudo_run): added some more debugging stuff
+ and fixed aditional space when checking if GNOME_SUDO_PASS
+ was received, now sudo functionality works again.
+ - (gksu_context_sudo_run): find out if password failed
+
+2004-10-16 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.5
+
+ * libgksu/gksu-context.c:
+ - (gksu_context_run): ignore first line when reading the
+ output of gksu-run-helper - this should fix Debian bug
+ #272133
+ - (gksu_context_sudo_run): fixed the command building
+ so that -H will only be used if context->keep_env is
+ set - fixes Debian bug #276720
+
+2004-10-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * ChangeLog:
+ - converted to UTF-8
+
+ * libgksu/gksu-context.c:
+ - prepare_xauth was modified to always get what comes after
+ the ':' character, even if context->ssh_fwd is not set,
+ thus making this variable unused for now... this probably
+ fixed Debian bug #273819
+
+ * configure.ac:
+ - added no_NB to ALL_LINGUAS
+
+2004-09-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.4
+
+ * libgksu/gksu-context.c:
+ - applied patch by Martin Pitt <martin.pitt at canonical.com>
+ to fix buffer overflows
+
+2004-08-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.3
+
+ * configure.ac:
+ - added ca to ALL_LINGUAS
+
+2004-06-24 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.2
+
+ * libgksu/gksu-context.h:
+ - added missing G_END_DECLS to fix C++ pre-processing
+ (Debian bug #255607)
+
+2004-05-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.1
+
+2004-05-27 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.ver, libgksu/Makefile.am:
+ - build the library with versioned symbols (thanks
+ to Steve Langasek's [vorlon's] talk on "Escaping
+ the dependency hell" at Debian Conference 4
+
+2004-05-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.2.0!
+
+ * libgksu/gksu-context.c:
+ - fixed string about Xauthority file already existing
+ when being created for the target user
+
+ * docs/libgksu-sections.txt:
+ - removed the macros and the get_type function,
+ added gksu_context_free
+
+ * libgksu/gksu-context.{c,h}:
+ - document GksuContext and gksu_context_free
+
+2004-05-05 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.1.5
+
+ * libgksu/gksu-context.{c,h}:
+ - new error for xauth stuff problems
+ - now gksu looks at the XAUTHORITY environment
+ variable to get the source from which to copy
+ the Xauthorization file.
+
+2004-04-11 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - more select->sleep to fix bugs in linux 2.6
+
+2004-03-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/test-gksu.c:
+ - changed the command that is called from ls to
+ xterm
+
+ * libgksu/gksu-context.c:
+ - remove the password displaying debug stuff
+ (it is not safe ;))
+ - add an usleep to wait 200 usecs on each loop
+ on the while that prints messages... it seems
+ like linux 2.6's select() does not want to
+ wait =)
+
+2004-03-27 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-context.c:
+ - added some wait time before sending the
+ password to su - the password was not
+ being sent correctly without this.
+
+2004-03-21 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu.h, gksu-context.h:
+ - changed double quotes to <> in gksu.h,
+ fixed double inclusion of glib.h and
+ self-inclusion on gksu-context.h, thanks
+ to Max Reinhold Jahnke for the later fix
+
+2004-03-19 Gustavo Noronha Silva <kov at debian.org>
+
+ * COPYING, libgksu/*:
+ - change license to LGPL version 2
+
+2004-03-08 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-main*, libgksu/gksu-context*:
+ - moved -main stuff to -context, made the _run
+ stuff be methods of the GksuContext object
+ also wrote a get_type function to the enum
+ to help bindings
+
+ * libgksu/gksu-context.{h,c}:
+ - removed title, message and icon related methods
+ as they are now to be used with the gksuui-dialog
+ widget available in libgksuui
+ - fixed problems with the naming of the GObject-related
+ macros, so for example TYPE_GKSU_CONTEXT becomes
+ GKSU_TYPE_CONTEXT -> I had misunderstood the docs and
+ this seems to confuse the python binding generator
+
+2004-03-07 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/*:
+ - loads of reorganization and code fixing to have
+ it support the new build system, etc
+
+ * separating libgksu into its own source package
+
+2004-03-05 gettextize <bug-gnu-gettext at gnu.org>
+
+ * Makefile.am (SUBDIRS): Add intl.
+ (DIST_SUBDIRS): Add intl.
+ * configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
+
+2004-03-05 gettextize <bug-gnu-gettext at gnu.org>
+
+ * Makefile.am (SUBDIRS): Add m4.
+ (DIST_SUBDIRS): Add m4.
+ (EXTRA_DIST): New variable.
+ * configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
+ (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1.
+
+2004-02-03 Gustavo Noronha Silva <kov at debian.org> [1.1.1]
+
+ * configure.ac:
+ - polished a bit
+
+ * libgksu/gksu-private.c:
+ - fixed wrong error checking (duh)
+
+ * libgksu/gksu-context.[ch]:
+ - new implementation of GksuContext, based on
+ the GObject glib facility
+
+ * libgksu/libgksu.c, gksu/gksu.c:
+ - port to the new GObject-based GksuContext
+
+2004-02-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/gksu-private.c, libgksu-gksu-private.h:
+ - added a gksu_init_check function to init
+ gtk
+
+ * libgksu/libgksu.c, libgksu/gksu.h:
+ - added printf-like format support for title and
+ message setters
+ - call gksu_init_check on all the three main functions
+ to make sure gtk will be inited
+
+2004-01-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * gksu/gksu.c:
+ - ported to the new API
+
+ * libgksu/libgksu.c, libgksu/gksu-private.c:
+ - more well-defined separation between exported
+ and not export symbols (now even using the
+ visibility __attribute__)
+ - new API, based on contexts, preparation for
+ 1.2
+
+ * gksu/gksuexec.c:
+ - accepted patch from Jorgen Viksell <jorgen.viksell at telia.com>
+ to have gksuexec show a combo listing all the users on the
+ system, thanks!
+
+2004-01-20 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.0.3
+
+ * libgksu/libgksu.c:
+ - fixed _gksu_conf->dir allocation for gksu_sudo_run
+ to work
+
+ * libgksu/libgksu.c:
+ - added aditional error checking code to the xauth
+ exec to avoid a segfault when it returns nothing
+ patch by Doug Holland <meldroc at frii.com>
+
+2004-01-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * gksu/gksu.c, Makefile.am:
+ - added support to sudo, when called as 'gksudo'
+ - create the symlink on install
+
+2004-01-17 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.0.2
+
+2004-01-16 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c, libgksu/gksu.h:
+ - improved error checking
+ - improved error reporting on sudo related stuff
+ - added gksu_sudo_run, with sudo support
+
+ * remove the common directory and library, integrate
+ the relevant parts into libgksu and gksu separately
+
+ * libgksu/libgksu.c, common/gksutils.c:
+ - incorporated code from gnome-sudo with some
+ modifications to have gksu handle sudo, too
+ untested, probably unstable code, needs testing
+ to be exposed
+
+ * libgksu/Makefile.am:
+ - build the library with -fPIC, to allow prelinking
+
+ * configure.ac:
+ - added da to ALL_LINGUAS
+
+2004-01-15 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - Fixed problems with gksu closing the application
+ when canceled
+ - gtk_init_check instead of gtk_init, to avoid failures
+ killing the "parent" application
+
+2004-01-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.0.1
+
+ * Major update on the documentation stuff
+
+ * Small corrections to the locale handling code
+
+2003-12-19 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 1.0.0
+
+ * introducing libgksu! I believe the code is stable
+ enough for a 1.0 release -- althought the change to
+ a library might be a big move, the code has not
+ being changed a lot... let's see if the Debian
+ unstable trial proves me wrong.
+
+2003-11-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.18
+
+ * src/gui.c:
+ - does not quit when grab fails, warns and continues...
+
+ * po/de.po:
+ - small fix, thanks to Michael Vogt <mvogt at acm.org>
+
+ * src/gksu-run-helper.c:
+ - fix bashism
+
+2003-11-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.17
+
+ * autogen.sh:
+ - use automake 1.7, instead of 1.6
+
+ * configure.ac, po/pl.po:
+ - added polish translation, thanks to Emil <emil5 at go2.pl>
+
+ * src/gksu-run-helper.c:
+ - added, to help fix the stupid security bug
+
+ * src/gksu.{c,h}, src/su.c, src/xauth.c:
+ - modified to use the gksu-run-helper, which will
+ fix the security bug in which the Xauth token
+ appears on a ps auxwww
+
+2003-08-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.16
+
+2003-08-26 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/xauth.c:
+ - take care to take the MIT-MAGIC-COOKIE-1 from
+ xauth list, XDM auth strings were biting gksu
+
+2003-08-08 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.15
+
+2003-08-06 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac:
+ - added 'de' (German) to ALL_LINGUAS
+
+ * gksu.desktop, gksuexec.desktop:
+ - added German translation, thanks to:
+ Sebastian Heinlein <sebastian.heinlein at campus.lmu.de>
+
+2003-07-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.14
+
+ * src/su.c:
+ - shows a nicer dialog with 'Wrong password.'
+ instead of simply 'Child exited with error
+ 1' thingy if su returns 'Authentication failure'
+
+ * src/su.c:
+ - use >& to redirect instead of 2>&1 to make
+ non-bash shells happy (Closes: #203386,
+ #203387)
+
+2003-07-24 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.13
+
+ * README:
+ - some explanations added
+
+ * src/gui.c, src/su.c:
+ - some modifications on the default label that's
+ presented explaining why it wants the password,
+ and in the label behavior, in general
+
+ * src/gksu.c, src/xauth.c:
+ - added --ssh-fwd option, which uses just the :x.x
+ part of display when working with xauth, for gksu
+ to work on ssh X11 forwarding
+ (Closes Debian bug: #202532)
+
+2003-07-23 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.12
+
+2003-07-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/xauth.c:
+ - added output about xauth token, file, directory and
+ display, for debuging purposes (when --debug is enabled)
+ - fixed clean_dir to remove the directory if it is empty
+ before clean_dir is called
+
+ * src/su.c:
+ - do not show xauth's output, unless --debug is given
+ - get rid of bashism when calling xauth by using the
+ env command
+
+ * src/gksu.c:
+ - added a --debug option, to ask for more verbose
+ output
+
+2003-07-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * man/gksu.1:
+ - fixed --icon position
+
+2003-06-14 gettextize <bug-gnu-gettext at gnu.org>
+
+ * Makefile.am (ACLOCAL_AMFLAGS): New variable.
+ * configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
+ (AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
+
+2003-06-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.11
+
+ * Applied patch from Ãlvaro Peña <apg at esware.com>
+ to HIG-ify gksu a bit more
+
+2003-05-24 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.10
+
+ * src/su.c:
+ - Why the hell do I want gksu to automaticaly go to
+ background? Changed that, I guess that'll help
+ lots of scripts.
+
+2003-05-10 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.9
+
+ * src/gksuexec.c:
+ - fixed the way the command is passed as argument
+ to gksu to fix running programs with arguments (duh)
+
+2003-05-08 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/su.c:
+ - fixed bug which did not allow gksu to run programs
+ with arguments like, say, 'emacs /etc/mozpluggerrc' =)
+
+2003-05-06 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac: added es.po to ALL_LINGUAS
+
+2003-05-02 Gustavo Noronha Silva <kov at debian.org>
+
+ * configure.ac: added ru.po to ALL_LINGUAS
+
+2003-04-05 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.8
+
+ * src/xauth.c:
+ - initialize 'xauth' to avoid problems with junk
+ thanks to Alex Stewart <am2stewa at uwaterloo.ca>
+
+ * src/gui.c:
+ - wait a bit longer before checking for the effectiveness of
+ the keyboard/mouse grab
+
+2003-03-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.7
+
+ * src/gksu.c, src/xauth.c:
+ - remove references to sudo, at least for now
+
+ * src/sudo.{c,h}:
+ - removed, no longer provide sudo functionality, it
+ doesn't work as well as it should
+
+2003-03-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/su.c:
+ - use xauth information to make the magic work
+
+ * src/xauth.c:
+ - implement prepare_xauth_su to handle Xauth in a safer way,
+ by using the 'xauth' program instead of a world readable
+ .Xauthorization file
+ - move the old way of doing things to the prepare_xauth_sudo
+ function... sudo is a difficult piece of software to handle
+
+ * src/gksu.c:
+ - moved as much xauth specific stuff as I could to xauth.c
+
+2003-02-01 Allan Douglas <allan_douglas at gmx.net>
+
+ * src/sudo.c:
+ - cleanups
+
+2003-01-31 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.1
+
+ * AUTHORS:
+ - added Allan Douglas
+
+2003-01-31 Allan Douglas <allan_douglas at gmx.net>
+
+ * src/su.c:
+ - fixed the "missing output" bug
+
+2003-01-30 Allan Douglas <allan_douglas at gmx.net>
+
+ * configure.ac:
+ - removed yacc dependency
+
+ * src/su.c:
+ - cleanups
+
+2003-01-30 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/su.c, src/sudo.c:
+ - fixed some stuff pointed by my friend "o_0" =P
+
+ * src/gksuexec.c:
+ - has an 'advanced' dialog to select options
+ 'login_shell' and '--preserv-env' for gksu
+
+2003-01-30 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/gksuexec.c:
+ - has an 'advanced' dialog to select options
+ 'login_shell' and '--preserv-env' for gksu
+
+2003-01-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * man/gksu.1:
+ - added reference for gksuexec command
+ - updated with the help of the 'help2man' command
+
+ * man/gksuexec.1: (new)
+ - wrote manpage to the new command
+
+ * man/Makefile.am: (new)
+ - install manpages
+
+ * src/gksu.c:
+ - fixed small and harmless segfault when free'ing
+ conf.title
+ - accept -i, --icon to set window's icon
+ - print-pass' message no longer assumes root user
+
+ * src/gui.c:
+ - use gksu's icon at the window, instead of the
+ question mark
+ - use conf.icon to set gksu window's icon
+
+2003-01-29 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.9.0
+
+ * src/gksuexec.c:
+ - a new program, a dialog to ask for other informations
+ as a wrapper to gksu's command line
+
+ * src/util.{c,h}, src/gui.{c,h}:
+ - moved gk_dialog from gui to util to make it easier
+ for gksuexec to use it
+
+ * gksuexec.desktop:
+ - new icon for GNOME, to run gksuexec
+
+2003-01-28 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.8.5
+
+ * src/su.c:
+ - does not ask for password when the real uid
+ is 0 (see http://bugs.debian.org/178675)
+
+ * src/gksu.c:
+ - minor aesthetical fixes
+
+2003-01-22 Gustavo Noronha Silva <kov at debian.org>
+
+ * Release 0.8.4
+
+2003-01-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/Makefile.am:
+ - define DATA_DIR
+ - add optimization on compilation
+
+ * src/gui.c:
+ - set default windows icon (requires Gtk+2.2)
+
+ * gksu.png:
+ - new icon, from art.gnome.org, Authorization.png
+
+ * gksu.png -> gksu-terminal.png:
+ - renamed icon for gnome's desktop icon
+
+2003-01-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * 0.8.3 Release
+
+ * clean up to the build system, using autoconf
+ 2.50 and automake-1.6
+
+ * man/gksu.1:
+ - fixed WHATIS entry
+
+ * gksu.desktop, gksu.png:
+ - icon for GNOME's System menu, to open a terminal
+ as the root user
+
+2003-01-14 Gustavo Noronha Silva <kov at debian.org>
+
+ * 0.8.2 Release
+ - changed configure.in
+
+ * src/gksu.c:
+ - make reset environment the default, changed:
+ reset-env, r to preserv-env, k
+ - make not login shell the default, again, it
+ will make the Xauth stuff break... duh
+
+ * src/su.c, src/sudo.c:
+ - yes, yes, auto-background again =P
+
+ * src/gui.c:
+ - cleans the Xauth directory in case the dialog is
+ canceled or closed
+ - changed buttons' positions to reflect the changes
+ that happened to GNOME2
+
+ * src/gksu.c:
+ - made title more i18n friendly, fixed some small
+ memory leaks
+
+ * po/pt_BR.po:
+ - updated translation
+
+2003-01-12 Gustavo Noronha Silva <kov at debian.org>
+
+ * src/gksu.c:
+ - make login shell by default
+
+ * src/su.c, src/sudo.c:
+ - no grandchild, no auto-background anymore
+ - fixes on outputing things
+
+2002-08-13 gettextize <bug-gnu-gettext at gnu.org>
+
+ * Makefile.am (SUBDIRS): Add m4.
+ (SUBDIRS): Remove intl.
+ (ACLOCAL_AMFLAGS): New variable.
+ (EXTRA_DIST): New variable.
+
+ * configure.in (AC_OUTPUT): Add m4/Makefile.
+
+2002-02-18 Gustavo Noronha Silva <kov at debian.org>
+
+ * gksu: initial version.
+
Deleted: libgksu/tags/2.0.8/libgksu/libgksu.c
===================================================================
--- libgksu/trunk/libgksu/libgksu.c 2009-02-23 02:20:27 UTC (rev 840)
+++ libgksu/tags/2.0.8/libgksu/libgksu.c 2009-03-04 18:39:36 UTC (rev 844)
@@ -1,3087 +0,0 @@
-/*
- * Gksu -- a library providing access to su functionality
- * Copyright (C) 2004 Gustavo Noronha Silva
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <pty.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <errno.h>
-
-#include <glibtop.h>
-#include <glibtop/procstate.h>
-
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
-#define SN_API_NOT_YET_FROZEN
-#include <libsn/sn.h>
-
-#include <gtk/gtk.h>
-#include <locale.h>
-
-#include <gconf/gconf-client.h>
-#include <gnome-keyring.h>
-
-#include "defines.h"
-#include "../config.h"
-
-#include "libgksu.h"
-#include "../libgksuui/gksuui-dialog.h"
-
-static void
-gksu_context_launch_complete (GksuContext *context);
-
-GType
-gksu_error_get_type (void)
-{
- static GType etype = 0;
- if (etype == 0) {
- static const GEnumValue values[] = {
- { GKSU_ERROR_HELPER, "GKSU_ERROR_HELPER", "helper" },
- { GKSU_ERROR_NOCOMMAND, "GKSU_ERROR_NOCOMMAND", "nocommand" },
- { GKSU_ERROR_NOPASSWORD, "GKSU_ERROR_NOPASSWORD", "nopassword" },
- { GKSU_ERROR_FORK, "GKSU_ERROR_FORK", "fork" },
- { GKSU_ERROR_EXEC, "GKSU_ERROR_EXEC", "exec" },
- { GKSU_ERROR_PIPE, "GKSU_ERROR_PIPE", "pipe" },
- { GKSU_ERROR_PIPEREAD, "GKSU_ERROR_PIPEREAD", "piperead" },
- { GKSU_ERROR_WRONGPASS, "GKSU_ERROR_WRONGPASS", "wrongpass" },
- { GKSU_ERROR_CHILDFAILED, "GKSU_ERROR_CHILDFAILED", "childfailed" },
- { GKSU_ERROR_CANCELED, "GKSU_ERROR_CANCELED", "canceled" },
- { GKSU_ERROR_WRONGAUTOPASS, "GKSU_ERROR_WRONGAUTOPASS", "wrongautopass" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static ("GksuError", values);
- }
- return etype;
-}
-
-static pid_t
-test_lock(const char* fname)
-{
- int FD = open(fname, 0);
- if(FD < 0) {
- if(errno == ENOENT) {
- // File does not exist
- return 0;
- } else {
- perror("open");
- return(-1);
- }
- }
- struct flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- if (fcntl(FD, F_GETLK, &fl) < 0) {
- g_critical("fcntl error");
- close(FD);
- return(-1);
- }
- close(FD);
- // lock is available
- if(fl.l_type == F_UNLCK)
- return(0);
- // file is locked by another process
- return (fl.l_pid);
-}
-
-static int
-get_lock(const char *File)
-{
- int FD = open(File,O_RDWR | O_CREAT | O_TRUNC,0640);
- if (FD < 0)
- {
- // Read only .. cant have locking problems there.
- if (errno == EROFS)
- {
- g_warning(_("Not using locking for read only lock file %s"),File);
- return dup(0); // Need something for the caller to close
- }
-
- // Feh.. We do this to distinguish the lock vs open case..
- errno = EPERM;
- return -1;
- }
- fcntl(FD,F_SETFD, FD_CLOEXEC);
-
- // Aquire a write lock
- struct flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- if (fcntl(FD,F_SETLK,&fl) == -1)
- {
- if (errno == ENOLCK)
- {
- g_warning(_("Not using locking for nfs mounted lock file %s"), File);
- unlink(File);
- close(FD);
- return dup(0); // Need something for the caller to close
- }
-
- int Tmp = errno;
- close(FD);
- errno = Tmp;
- return -1;
- }
-
- return FD;
-}
-
-/*
- * code 'stolen' from gnome-session's logout.c
- *
- * Written by Owen Taylor <otaylor at redhat.com>
- * Copyright (C) Red Hat
- */
-typedef struct {
- GdkScreen *screen;
- int monitor;
- GdkRectangle area;
- int rowstride;
- GdkWindow *root_window;
- GdkWindow *draw_window;
- GdkPixbuf *start_pb, *end_pb, *frame;
- guchar *start_p, *end_p, *frame_p;
- GTimeVal start_time;
- GdkGC *gc;
-} FadeoutData;
-
-FadeoutData *fade_data = NULL;
-static GList *fadeout_windows = NULL;
-
-#define FADE_DURATION 500.0
-
-int
-gsm_screen_get_width (GdkScreen *screen,
- int monitor)
-{
- GdkRectangle geometry;
-
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
- return geometry.width;
-}
-
-int
-gsm_screen_get_height (GdkScreen *screen,
- int monitor)
-{
- GdkRectangle geometry;
-
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
- return geometry.height;
-}
-
-int
-gsm_screen_get_x (GdkScreen *screen,
- int monitor)
-{
- GdkRectangle geometry;
-
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
- return geometry.x;
-}
-
-int
-gsm_screen_get_y (GdkScreen *screen,
- int monitor)
-{
- GdkRectangle geometry;
-
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
- return geometry.y;
-}
-
-static void
-get_current_frame (FadeoutData *fadeout,
- double sat)
-{
- guchar *sp, *ep, *fp;
- int i, j, width, offset;
-
- width = fadeout->area.width * 3;
- offset = 0;
-
- for (i = 0; i < fadeout->area.height; i++)
- {
- sp = fadeout->start_p + offset;
- ep = fadeout->end_p + offset;
- fp = fadeout->frame_p + offset;
-
- for (j = 0; j < width; j += 3)
- {
- guchar r = abs (*(sp++) - ep[0]);
- guchar g = abs (*(sp++) - ep[1]);
- guchar b = abs (*(sp++) - ep[2]);
-
- *(fp++) = *(ep++) + r * sat;
- *(fp++) = *(ep++) + g * sat;
- *(fp++) = *(ep++) + b * sat;
- }
-
- offset += fadeout->rowstride;
- }
-}
-
-static void
-darken_pixbuf (GdkPixbuf *pb)
-{
- int width, height, rowstride;
- int i, j;
- guchar *p, *pixels;
-
- width = gdk_pixbuf_get_width (pb) * 3;
- height = gdk_pixbuf_get_height (pb);
- rowstride = gdk_pixbuf_get_rowstride (pb);
- pixels = gdk_pixbuf_get_pixels (pb);
-
- for (i = 0; i < height; i++)
- {
- p = pixels + (i * rowstride);
- for (j = 0; j < width; j++)
- p [j] >>= 1;
- }
-}
-
-static gboolean
-fadeout_callback (FadeoutData *fadeout)
-{
- GTimeVal current_time;
- double elapsed, percent;
-
- g_get_current_time (¤t_time);
- elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
- (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
-
- if (elapsed < 0)
- {
- g_warning ("System clock seemed to go backwards?");
- elapsed = G_MAXDOUBLE;
- }
-
- if (elapsed > FADE_DURATION)
- {
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->end_pb,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
-
- return FALSE;
- }
-
- percent = elapsed / FADE_DURATION;
-
- get_current_frame (fadeout, 1.0 - percent);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
-
- gdk_flush ();
-
- return TRUE;
-}
-
-static void
-hide_fadeout_windows (void)
-{
- GList *l;
-
- for (l = fadeout_windows; l; l = l->next)
- {
- gdk_window_hide (GDK_WINDOW (l->data));
- g_object_unref (l->data);
- }
-
- g_list_free (fadeout_windows);
- fadeout_windows = NULL;
-}
-
-static gboolean
-fadein_callback (FadeoutData *fadeout)
-{
- GTimeVal current_time;
- double elapsed, percent;
-
- g_get_current_time (¤t_time);
- elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
- (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
-
- if (elapsed < 0)
- {
- g_warning ("System clock seemed to go backwards?");
- elapsed = G_MAXDOUBLE;
- }
-
- if (elapsed > FADE_DURATION)
- {
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->end_pb,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
-
- g_object_unref (fadeout->gc);
- g_object_unref (fadeout->start_pb);
- g_object_unref (fadeout->end_pb);
- g_object_unref (fadeout->frame);
-
- g_free (fadeout);
-
- hide_fadeout_windows ();
-
- return FALSE;
- }
-
- percent = elapsed / FADE_DURATION;
-
- get_current_frame (fadeout, percent);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
-
- gdk_flush ();
-
- return TRUE;
-}
-
-static void
-fadeout_screen (GdkScreen *screen,
- int monitor)
-{
- GdkWindowAttr attr;
- int attr_mask;
- GdkGCValues values;
- FadeoutData *fadeout;
-
- fadeout = g_new (FadeoutData, 1);
-
- fadeout->screen = screen;
- fadeout->monitor = monitor;
-
- fadeout->area.x = gsm_screen_get_x (screen, monitor);
- fadeout->area.y = gsm_screen_get_y (screen, monitor);
- fadeout->area.width = gsm_screen_get_width (screen, monitor);
- fadeout->area.height = gsm_screen_get_height (screen, monitor);
-
- fadeout->root_window = gdk_screen_get_root_window (screen);
- attr.window_type = GDK_WINDOW_CHILD;
- attr.x = fadeout->area.x;
- attr.y = fadeout->area.y;
- attr.width = fadeout->area.width;
- attr.height = fadeout->area.height;
- attr.wclass = GDK_INPUT_OUTPUT;
- attr.visual = gdk_screen_get_system_visual (fadeout->screen);
- attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
- attr.override_redirect = TRUE;
- attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_NOREDIR;
-
- fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
- fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
-
- fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
- fadeout->root_window,
- NULL,
- fadeout->area.x,
- fadeout->area.y,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height);
-
- fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
- darken_pixbuf (fadeout->end_pb);
-
- fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
- fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
-
- fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
- fadeout->end_p = gdk_pixbuf_get_pixels (fadeout->end_pb);
- fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
-
- values.subwindow_mode = GDK_INCLUDE_INFERIORS;
-
- fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
-
- gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
- gdk_window_show (fadeout->draw_window);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
-
- g_get_current_time (&fadeout->start_time);
- g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
-
- fade_data = fadeout;
-}
-
-/* End of 'stolen' code */
-
-#define GRAB_TRIES 16
-#define GRAB_WAIT 250 /* milliseconds */
-
-typedef enum
- {
- FAILED_GRAB_MOUSE,
- FAILED_GRAB_KEYBOARD
- } FailedGrabWhat;
-
-void
-report_failed_grab (FailedGrabWhat what)
-{
- GtkWidget *dialog;
-
- dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
- "message-type", GTK_MESSAGE_WARNING,
- "buttons", GTK_BUTTONS_CLOSE,
- NULL);
-
- switch (what)
- {
- case FAILED_GRAB_MOUSE:
- gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
- _("<b><big>Could not grab your mouse.</big></b>"
- "\n\n"
- "A malicious client may be eavesdropping "
- "on your session or you may have just clicked "
- "a menu or some application just decided to get "
- "focus."
- "\n\n"
- "Try again."));
-
- break;
- case FAILED_GRAB_KEYBOARD:
- gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
- _("<b><big>Could not grab your keyboard.</big></b>"
- "\n\n"
- "A malicious client may be eavesdropping "
- "on your session or you may have just clicked "
- "a menu or some application just decided to get "
- "focus."
- "\n\n"
- "Try again."));
- break;
- }
-
- gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
- gtk_dialog_run (GTK_DIALOG(dialog));
- gtk_widget_destroy (dialog);
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
-}
-
-int
-grab_keyboard_and_mouse (GtkWidget *dialog)
-{
- GdkGrabStatus status;
- gint grab_tries = 0;
- gint lock = -1;
- pid_t pid;
-
- gchar *fname = g_strdup (getenv ("GKSU_LOCK_FILE"));
- if (fname == NULL)
- fname = g_strdup_printf ("%s/.gksu.lock", getenv ("HOME"));
-
- pid = test_lock (fname);
-
- if (pid != 0)
- {
- g_warning ("Lock taken by pid: %i. Exiting.", pid);
- exit (0);
- }
-
- lock = get_lock(fname);
- if( lock < 0)
- g_warning ("Unable to create lock file.");
- g_free (fname);
-
- gdk_threads_enter ();
- fadeout_screen (gdk_screen_get_default (), 0);
- gtk_widget_show_all (dialog);
-
- /* reset cursor */
- gdk_window_set_cursor(dialog->window, gdk_cursor_new(GDK_LEFT_PTR));
-
- for(;;)
- {
- status = gdk_pointer_grab ((GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
- NULL, GDK_CURRENT_TIME);
- if (status == GDK_GRAB_SUCCESS)
- break;
- usleep (GRAB_WAIT * 1000);
- if (++grab_tries > GRAB_TRIES)
- {
- gtk_widget_hide (dialog);
- g_get_current_time (&fade_data->start_time);
- while (fadein_callback (fade_data) != FALSE);
- report_failed_grab (FAILED_GRAB_MOUSE);
- exit (1);
- break;
- }
- }
-
- for(;;)
- {
- status = gdk_keyboard_grab ((GTK_WIDGET(dialog))->window,
- FALSE, GDK_CURRENT_TIME);
- if (status == GDK_GRAB_SUCCESS)
- break;
-
- usleep(GRAB_WAIT * 1000);
-
- if (++grab_tries > GRAB_TRIES)
- {
- gtk_widget_hide (dialog);
- g_get_current_time (&fade_data->start_time);
- while (fadein_callback (fade_data) != FALSE);
- report_failed_grab (FAILED_GRAB_KEYBOARD);
- exit (1);
- break;
- }
- }
-
- /* we "raise" the window because there is a race here for
- * focus-follow-mouse and auto-raise WMs that may put the window
- * in the background and confuse users
- */
- gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- return lock;
-}
-
-void
-ungrab_keyboard_and_mouse (int lock)
-{
- /* Ungrab */
- gdk_pointer_ungrab(GDK_CURRENT_TIME);
- gdk_keyboard_ungrab(GDK_CURRENT_TIME);
- gdk_flush();
-
- g_get_current_time (&fade_data->start_time);
- while (fadein_callback (fade_data) != FALSE);
- gdk_threads_leave();
-
- close(lock);
-}
-
-static gchar*
-get_gnome_keyring_password (GksuContext *context)
-{
- GnomeKeyringAttributeList *attributes;
- GnomeKeyringAttribute attribute;
- GnomeKeyringResult result;
- GList *list;
-
- attributes = gnome_keyring_attribute_list_new ();
-
- attribute.name = g_strdup ("user");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup (gksu_context_get_user (context));
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("type");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("local");
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("creator");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("gksu");
- g_array_append_val (attributes, attribute);
-
- list = g_list_alloc();
-
- result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- attributes,
- &list);
- gnome_keyring_attribute_list_free (attributes);
- if (
- (result == GNOME_KEYRING_RESULT_OK) &&
- (g_list_length(list) >= 1)
- )
- {
- GnomeKeyringFound *found = list->data;
- gint password_length = strlen (found->secret);
- gchar *password;
-
- password = g_locale_from_utf8 (found->secret,
- password_length,
- NULL, NULL, NULL);
- password_length = strlen (password);
-
- if (password[password_length-1] == '\n')
- password[password_length-1] = '\0';
- return password;
- }
-
- return NULL;
-}
-
-static void
-keyring_create_item_cb (GnomeKeyringResult result,
- guint32 id, gpointer keyring_loop)
-{
- g_main_loop_quit (keyring_loop);
-}
-
-static void
-set_gnome_keyring_password (GksuContext *context, gchar *password)
-{
- GConfClient *gconf_client;
- gboolean save_to_keyring;
-
- gconf_client = context->gconf_client;
- save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
-
- if (password && save_to_keyring)
- {
- static GMainLoop *keyring_loop = NULL;
- GnomeKeyringAttributeList *attributes;
- GnomeKeyringAttribute attribute;
- GnomeKeyringResult result;
-
- gchar *keyring_name;
- gchar *key_name;
-
- attributes = gnome_keyring_attribute_list_new ();
-
- attribute.name = g_strdup ("user");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup (gksu_context_get_user (context));
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("type");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("local");
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("creator");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("gksu");
- g_array_append_val (attributes, attribute);
-
- key_name = g_strdup_printf ("Local password for user %s",
- gksu_context_get_user (context));
-
- keyring_loop = g_main_loop_new (NULL, FALSE);
-
- keyring_name = gconf_client_get_string (gconf_client, BASE_PATH"save-keyring", NULL);
- if (keyring_name == NULL)
- keyring_name = g_strdup ("session");
-
- /* make sure the keyring exists; if an error occurs, use
- the session keyring */
- result = gnome_keyring_create_sync(keyring_name, NULL);
- if ((result != GNOME_KEYRING_RESULT_OK) &&
- (result != GNOME_KEYRING_RESULT_ALREADY_EXISTS))
- keyring_name = g_strdup ("session");
-
- gnome_keyring_item_create (keyring_name,
- GNOME_KEYRING_ITEM_GENERIC_SECRET,
- key_name,
- attributes,
- password,
- TRUE,
- keyring_create_item_cb,
- keyring_loop, NULL);
- gnome_keyring_attribute_list_free (attributes);
- g_free (keyring_name);
- g_main_loop_run (keyring_loop);
- }
-}
-
-static void
-unset_gnome_keyring_password (GksuContext *context)
-{
- GConfClient *gconf_client;
- gboolean save_to_keyring;
-
- GnomeKeyringAttributeList *attributes;
- GnomeKeyringAttribute attribute;
- GnomeKeyringResult result;
- GList *list;
-
- gconf_client = context->gconf_client;
- save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
-
- if (save_to_keyring)
- {
- attributes = gnome_keyring_attribute_list_new ();
-
- attribute.name = g_strdup ("user");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup (gksu_context_get_user (context));
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("type");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("local");
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("creator");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("gksu");
- g_array_append_val (attributes, attribute);
-
- list = g_list_alloc();
-
- result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- attributes,
- &list);
- gnome_keyring_attribute_list_free (attributes);
- if (
- (result == GNOME_KEYRING_RESULT_OK) &&
- (g_list_length(list) == 1)
- )
- {
- GnomeKeyringFound *found = list->data;
-
- gnome_keyring_item_delete_sync (found->keyring,
- found->item_id);
- }
- }
-}
-
-void
-get_configuration_options (GksuContext *context)
-{
- GConfClient *gconf_client = context->gconf_client;
- gboolean force_grab;
-
- context->grab = !gconf_client_get_bool (gconf_client, BASE_PATH "disable-grab",
- NULL);
- force_grab = gconf_client_get_bool (gconf_client, BASE_PATH "force-grab",
- NULL);
- if (force_grab)
- context->grab = TRUE;
-
- context->sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
- NULL);
-}
-
-/**
- * su_ask_password:
- * @context: a #GksuContext
- * @prompt: the prompt that should be used instead of "Password: "
- * @data: data that is passed by gksu_*_full
- * @error: a pointer to pointer #GError that will be filled with
- * data if an error happens.
- *
- * This is a convenience function to create a #GksuuiDialog and
- * request the password.
- *
- * Returns: a newly allocated gchar containing the password
- * or NULL if an error happens or the user cancels the action
- */
-static gchar*
-su_ask_password (GksuContext *context, gchar *prompt,
- gpointer data, GError **error)
-{
- GtkWidget *dialog = NULL;
- gchar *msg;
- gchar *password = NULL, *tmp = NULL;
- int retvalue = 0;
- int lock = 0;
- GQuark gksu_quark;
-
- gksu_quark = g_quark_from_string (PACKAGE);
-
- if (context->grab)
- dialog = g_object_new (GKSUUI_TYPE_DIALOG,
- "type", GTK_WINDOW_POPUP,
- "sudo-mode", context->sudo_mode,
- NULL);
- else
- dialog = gksuui_dialog_new (context->sudo_mode);
-
- if (prompt)
- gksuui_dialog_set_prompt (GKSUUI_DIALOG(dialog), _(prompt));
-
- if (context->message)
- gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), context->message);
- else
- {
- gchar *command = NULL;
- if (context->description)
- command = context->description;
- else
- command = context->command;
-
- if (context->sudo_mode)
- {
- if (!strcmp(context->user, "root"))
- msg = g_strdup_printf (_("<b><big>Enter your password to perform"
- " administrative tasks</big></b>\n\n"
- "The application '%s' lets you "
- "modify essential parts of your "
- "system."),
- command);
- else
- msg = g_strdup_printf (_("<b><big>Enter your password to run "
- "the application '%s' as user %s"
- "</big></b>"),
- command, context->user);
- }
- else
- {
- if (strcmp(gksu_context_get_user (context), "root") == 0)
- msg = g_strdup_printf (_("<b><big>Enter the administrative password"
- "</big></b>\n\n"
- "The application '%s' lets you "
- "modify essential parts of your "
- "system."),
- command);
- else
- msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
- "the application '%s'"
- "</big></b>"),
- context->user, command);
- }
-
- gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
- g_free (msg);
- }
-
- if (context->alert)
- gksuui_dialog_set_alert (GKSUUI_DIALOG(dialog), context->alert);
-
- if (context->grab)
- lock = grab_keyboard_and_mouse (dialog);
- retvalue = gtk_dialog_run (GTK_DIALOG(dialog));
- gtk_widget_hide (dialog);
- if (context->grab)
- ungrab_keyboard_and_mouse (lock);
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- if (retvalue != GTK_RESPONSE_OK)
- {
- switch (retvalue)
- {
- case GTK_RESPONSE_CANCEL:
- case GTK_RESPONSE_DELETE_EVENT:
- g_set_error (error, gksu_quark,
- GKSU_ERROR_CANCELED,
- _("Password prompt canceled."));
- if (context->sn_context)
- gksu_context_launch_complete (context);
- }
-
- gtk_widget_destroy (dialog);
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- return NULL;
- }
-
- tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog));
- password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL);
- g_free (tmp);
-
- gtk_widget_destroy (dialog);
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- return password;
-}
-
-static void
-cb_toggled_cb (GtkWidget *button, gpointer data)
-{
- GConfClient *gconf_client;
- gchar *key;
- gboolean toggled;
- gchar *key_name;
-
- g_return_if_fail (data != NULL);
-
- key_name = (gchar*)data;
-
- gconf_client = gconf_client_get_default ();
- toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
-
- key = g_strdup_printf (BASE_PATH "%s", key_name);
-
- if (!strcmp (key_name, "display-no-pass-info"))
- {
- /* the meaning of the key is the exact opposite of the meaning
- of the answer - when the check button is checked the key must
- be off
- */
- gconf_client_set_bool (gconf_client, key, !toggled, NULL);
- }
- else
- gconf_client_set_bool (gconf_client, key, toggled, NULL);
-
- g_object_unref (gconf_client);
-
- g_free (key);
-}
-
-void
-no_pass (GksuContext *context, gpointer data)
-{
- GtkWidget *dialog;
- GtkWidget *alignment;
- GtkWidget *check_button;
-
- gchar *command = NULL;
-
- if (context->description)
- command = context->description;
- else
- command = context->command;
-
- dialog = gtk_message_dialog_new_with_markup (NULL, 0,
- GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
- _("<b><big>Granted permissions without asking "
- "for password</big></b>"
- "\n\n"
- "The '%s' program was started with "
- "the privileges of the %s user without "
- "the need to ask for a password, due to "
- "your system's authentication mechanism "
- "setup."
- "\n\n"
- "It is possible that you are being allowed "
- "to run specific programs as user %s "
- "without the need for a password, or that "
- "the password is cached."
- "\n\n"
- "This is not a problem report; it's "
- "simply a notification to make sure "
- "you are aware of this."),
- command,
- context->user,
- context->user);
-
- alignment = gtk_alignment_new (0.5, 0.5, 0.6, 1);
- gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), alignment, TRUE, TRUE, 2);
-
- check_button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again"));
- g_signal_connect (G_OBJECT(check_button), "toggled",
- G_CALLBACK(cb_toggled_cb), "display-no-pass-info");
- gtk_container_add (GTK_CONTAINER(alignment), check_button);
-
- gtk_widget_show_all (dialog);
- gtk_dialog_run (GTK_DIALOG(dialog));
- gtk_widget_destroy (GTK_WIDGET(dialog));
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-}
-
-static void
-gksu_prompt_grab (GksuContext *context)
-{
- GtkWidget *d;
-
- d = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("<b>Would you like your screen to be \"grabbed\"\n"
- "while you enter the password?</b>"
- "\n\n"
- "This means all applications will be paused to avoid\n"
- "the eavesdropping of your password by a a malicious\n"
- "application while you type it."));
-
- if (gtk_dialog_run (GTK_DIALOG(d)) == GTK_RESPONSE_NO)
- context->grab = FALSE;
- else
- context->grab = TRUE;
-
- gtk_widget_destroy (d);
-}
-
-static void
-nullify_password (gchar *pass)
-{
- if (pass)
- {
- memset(pass, 0, strlen(pass));
- g_free (pass);
- }
- pass = NULL;
-}
-
-static gchar *
-get_process_name (pid_t pid)
-{
- static gboolean init;
- glibtop_proc_state buf;
-
- if (!init) {
- glibtop_init();
- init = TRUE;
- }
-
- glibtop_get_proc_state (&buf, pid);
- return strdup(buf.cmd);
-}
-
-static gchar *
-get_xauth_token (GksuContext *context, gchar *display)
-{
- gchar *xauth_bin = NULL;
- FILE *xauth_output;
- gchar *tmp = NULL;
- gchar *xauth = g_new0 (gchar, 256);
-
- /* find out where the xauth binary is located */
- if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
- xauth_bin = "/usr/bin/xauth";
- else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
- xauth_bin = "/usr/X11R6/bin/xauth";
- else
- {
- fprintf (stderr,
- "Failed to obtain xauth key: xauth binary not found "
- "at usual locations");
-
- return NULL;
- }
-
- /* get the authorization token */
- tmp = g_strdup_printf ("%s list %s | "
- "head -1 | awk '{ print $3 }'",
- xauth_bin,
- display);
- if ((xauth_output = popen (tmp, "r")) == NULL)
- {
- fprintf (stderr,
- "Failed to obtain xauth key: %s",
- strerror(errno));
- return NULL;
- }
- fread (xauth, sizeof(char), 255, xauth_output);
- pclose (xauth_output);
- g_free (tmp);
-
- if (context->debug)
- {
- fprintf(stderr,
- "xauth: -%s-\n"
- "display: -%s-\n",
- xauth, display);
- }
-
- return xauth;
-}
-
-/**
- * prepare_xauth:
- *
- * Sets up the variables with values for the $DISPLAY
- * environment variable and xauth-related stuff. Also
- * creates a temporary directory to hold a .Xauthority
- *
- * Returns: TRUE if it suceeds, FALSE if it fails.
- */
-static int
-prepare_xauth (GksuContext *context)
-{
- gchar *display = NULL;
- gchar *xauth = NULL;
-
- display = g_strdup (getenv ("DISPLAY"));
- xauth = get_xauth_token (context, display);
- if (xauth == NULL)
- {
- g_free (display);
- return FALSE;
- }
-
- /* If xauth is the empty string, then try striping the
- * hostname part of the DISPLAY string for getting the
- * auth token; this is needed for ssh-forwarded usage
- */
- if (!strcmp ("", xauth))
- {
- gchar *cut_display = NULL;
-
- g_free (xauth);
- cut_display = g_strdup (g_strrstr (display, ":"));
- xauth = get_xauth_token (context, cut_display);
-
- g_free (display);
- display = cut_display;
- }
-
- context->xauth = xauth;
- context->display = display;
-
- if (context->debug)
- {
- fprintf(stderr,
- "final xauth: -%s-\n"
- "final display: -%s-\n",
- context->xauth, context->display);
- }
-
- return TRUE;
-}
-
-/* Write all of buf, even if write(2) is interrupted. */
-static ssize_t
-full_write (int d, const char *buf, size_t nbytes)
-{
- ssize_t r, w = 0;
-
- /* Loop until nbytes of buf have been written. */
- while (w < nbytes) {
- /* Keep trying until write succeeds without interruption. */
- do {
- r = write(d, buf + w, nbytes - w);
- } while (r < 0 && errno == EINTR);
-
- if (r < 0) {
- return -1;
- }
-
- w += r;
- }
-
- return w;
-}
-
-static gboolean
-copy (const char *fn, const char *dir)
-{
- int in, out;
- int r;
- char *newfn;
- char buf[BUFSIZ] = "";
-
- newfn = g_strdup_printf("%s/.Xauthority", dir);
-
- out = open(newfn, O_WRONLY | O_CREAT | O_EXCL, 0600);
- if (out == -1)
- {
- if (errno == EEXIST)
- fprintf (stderr,
- "Impossible to create the .Xauthority file: a file "
- "already exists. This might be a security issue; "
- "please investigate.");
- else
- fprintf (stderr,
- "Error copying '%s' to '%s': %s",
- fn, dir, strerror(errno));
-
- return FALSE;
- }
-
- in = open(fn, O_RDONLY);
- if (in == -1)
- {
- fprintf (stderr,
- "Error copying '%s' to '%s': %s",
- fn, dir, strerror(errno));
- return FALSE;
- }
-
- while ((r = read(in, buf, BUFSIZ)) > 0)
- {
- if (full_write(out, buf, r) == -1)
- {
- fprintf (stderr,
- "Error copying '%s' to '%s': %s",
- fn, dir, strerror(errno));
- return FALSE;
- }
- }
-
- if (r == -1)
- {
- fprintf (stderr,
- "Error copying '%s' to '%s': %s",
- fn, dir, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-sudo_prepare_xauth (GksuContext *context)
-{
- gchar template[] = "/tmp/" PACKAGE "-XXXXXX";
- gboolean error_copying = FALSE;
- gchar *xauth = NULL;
-
- context->dir = g_strdup (mkdtemp(template));
- if (!context->dir)
- {
- fprintf (stderr, strerror(errno));
- return FALSE;
- }
-
- xauth = g_strdup(g_getenv ("XAUTHORITY"));
- if (xauth == NULL)
- xauth = g_strdup_printf ("%s/.Xauthority", g_get_home_dir());
-
- error_copying = !copy (xauth, context->dir);
- g_free (xauth);
-
- if (error_copying)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-sudo_reset_xauth (GksuContext *context, gchar *xauth,
- gchar *xauth_env)
-{
- /* reset the env var as it was before or clean it */
- if (xauth_env)
- setenv ("XAUTHORITY", xauth_env, TRUE);
- else
- unsetenv ("XAUTHORITY");
-
- if (context->debug)
- fprintf (stderr, "xauth: %s\nxauth_env: %s\ndir: %s\n",
- xauth, xauth_env, context->dir);
-
- unlink (xauth);
- rmdir (context->dir);
-
- g_free (xauth);
-}
-
-static void
-startup_notification_initialize (GksuContext *context)
-{
- SnDisplay *sn_display;
- sn_display = sn_display_new (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
- NULL, NULL);
- context->sn_context = sn_launcher_context_new (sn_display, gdk_screen_get_number (gdk_display_get_default_screen (gdk_display_get_default ())));
- sn_launcher_context_set_description (context->sn_context, _("Granting Rights"));
- sn_launcher_context_set_name (context->sn_context, g_get_prgname ());
-}
-
-/**
- * gksu_context_new
- *
- * This function should be used when creating a new #GksuContext to
- * pass to gksu_su_full or gksu_sudo_full. The #GksuContext must be
- * freed with gksu_context_free.
- *
- * Returns: a newly allocated #GksuContext
- */
-GksuContext*
-gksu_context_new ()
-{
- GksuContext *context;
-
- context = g_new (GksuContext, 1);
-
- context->xauth = NULL;
- context->dir = NULL;
- context->display = NULL;
-
- context->gconf_client = gconf_client_get_default ();
-
- context->sudo_mode = FALSE;
-
- context->user = g_strdup ("root");
- context->command = NULL;
-
- context->login_shell = FALSE;
- context->keep_env = FALSE;
-
- context->description = NULL;
- context->message = NULL;
- context->alert = NULL;
- context->grab = TRUE;
- context->always_ask_password = FALSE;
-
- context->debug = FALSE;
-
- context->sn_context = NULL;
- context->sn_id = NULL;
-
- context->ref_count = 1;
-
- get_configuration_options (context);
- startup_notification_initialize (context);
-
- return context;
-}
-
-/**
- * gksu_context_set_user:
- * @context: the #GksuContext you want to modify
- * @username: the target username
- *
- * Sets up what user the command will be run as. The default
- * is root, but you can run the command as any user.
- *
- */
-void
-gksu_context_set_user (GksuContext *context, gchar *username)
-{
- g_assert (username != NULL);
-
- if (context->user)
- g_free (context->user);
- context->user = g_strdup (username);
-}
-
-/**
- * gksu_context_get_user:
- * @context: the #GksuContext from which to grab the information
- *
- * Gets the user the command will be run as, as set
- * by gksu_context_set_user.
- *
- * Returns: a string with the user or NULL if not set.
- */
-const gchar*
-gksu_context_get_user (GksuContext *context)
-{
- return context->user;
-}
-
-/**
- * gksu_context_set_command:
- * @context: the #GksuContext you want to modify
- * @command: the command that shall be ran
- *
- * Sets up what command will run with the target user.
- *
- */
-void
-gksu_context_set_command (GksuContext *context, gchar *command)
-{
- g_assert (command != NULL);
-
- if (context->command)
- g_free (context->command);
- context->command = g_strdup (command);
-
- /* startup notification */
- sn_launcher_context_set_binary_name (context->sn_context,
- command);
-}
-
-/**
- * gksu_context_get_command:
- * @context: the #GksuContext from which to grab the information
- *
- * Gets the command that will be run, as set by
- * gksu_context_set_command.
- *
- * Returns: a string with the command or NULL if not set.
- */
-const gchar*
-gksu_context_get_command (GksuContext *context)
-{
- return context->command;
-}
-
-/**
- * gksu_context_set_login_shell:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Should the shell in which the command will be run be
- * a login shell?
- */
-void
-gksu_context_set_login_shell (GksuContext *context, gboolean value)
-{
- context->login_shell = value;
-}
-
-/**
- * gksu_context_get_login_shell:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the shell created by the underlying su process
- * will be a login shell.
- *
- * Returns: TRUE if the shell will be a login shell, FALSE otherwise.
- */
-gboolean
-gksu_context_get_login_shell (GksuContext *context)
-{
- return context->login_shell;
-}
-
-/**
- * gksu_context_set_keep_env:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Should the environment be kept as it is? Defaults to
- * TRUE. Notice that setting this to FALSE may cause the
- * X authorization stuff to fail.
- */
-void
-gksu_context_set_keep_env (GksuContext *context, gboolean value)
-{
- context->keep_env = value;
-}
-
-/**
- * gksu_context_get_keep_env:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the environment in which the program will be
- * run will be reset.
- *
- * Returns: TRUE if the environment is going to be kept,
- * FALSE otherwise.
- */
-gboolean
-gksu_context_get_keep_env (GksuContext *context)
-{
- return context->keep_env;
-}
-
-/**
- * gksu_context_set_description:
- * @context: the #GksuContext you want to modify
- * @description: a string to set the description for
- *
- * Set the nice name for the action that is being run that the window
- * that asks for the password will have. This is only meant to be
- * used if the default window is used, of course.
- */
-void
-gksu_context_set_description (GksuContext *context, gchar *description)
-{
- if (context->description)
- g_free (context->description);
- context->description = g_strdup (description);
-}
-
-/**
- * gksu_context_get_description:
- * @context: the #GksuContext you want to get the description from.
- *
- * Get the description that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the description or NULL if not set.
- */
-gchar*
-gksu_context_get_description (GksuContext *context)
-{
- return context->description;
-}
-
-/**
- * gksu_context_set_message:
- * @context: the #GksuContext you want to modify
- * @message: a string to set the message for
- *
- * Set the message that the window that asks for the password will have.
- * This is only meant to be used if the default window is used, of course.
- */
-void
-gksu_context_set_message (GksuContext *context, gchar *message)
-{
- if (context->message)
- g_free (context->message);
- context->message = g_strdup (message);
-}
-
-/**
- * gksu_context_get_message:
- * @context: the #GksuContext you want to get the message from.
- *
- * Get the message that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the message or NULL if not set.
- */
-gchar*
-gksu_context_get_message (GksuContext *context)
-{
- return context->message;
-}
-
-/**
- * gksu_context_set_alert:
- * @context: the #GksuContext you want to modify
- * @alert: a string to set the alert for
- *
- * Set the alert that the window that asks for the password will have.
- * This is only meant to be used if the default window is used, of course.
- * This alert should be used to display messages such as 'incorrect password',
- * for instance.
- */
-void
-gksu_context_set_alert (GksuContext *context, gchar *alert)
-{
- if (context->alert)
- g_free (context->alert);
- context->alert = g_strdup (alert);
-}
-
-/**
- * gksu_context_get_alert:
- * @context: the #GksuContext you want to get the alert from.
- *
- * Get the alert that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the alert or NULL if not set.
- */
-gchar*
-gksu_context_get_alert (GksuContext *context)
-{
- return context->alert;
-}
-
-/**
- * gksu_context_set_debug:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if debuging information should be printed.
- */
-void
-gksu_context_set_grab (GksuContext *context, gboolean value)
-{
- context->grab = value;
-}
-
-/**
- * gksu_context_get_grab:
- * @context: the #GksuContext you want to ask whether a grab will be done.
- *
- * Returns TRUE if gksu has been asked to do a grab on keyboard and mouse
- * when asking for the password.
- *
- * Returns: TRUE if yes, FALSE otherwise.
- */
-gboolean
-gksu_context_get_grab (GksuContext *context)
-{
- return context->grab;
-}
-
-/**
- * gksu_context_set_always_ask_password:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if gksu should always ask for a password. Notice that this
- * will only work when passwords are cached, as done by gnome-keyring
- * for gksu's su mode and by sudo for gksu's sudo mode, but will have no
- * effect if su or sudo are set up to not require the password at all.
- */
-void
-gksu_context_set_always_ask_password (GksuContext *context, gboolean value)
-{
- context->always_ask_password = value;
-}
-
-/**
- * gksu_context_get_always_ask_password:
- * @context: the #GksuContext you want to ask whether a grab will be done.
- *
- * Returns TRUE if gksu has been asked to always ask for a password
- * (even if sudo or gnome-keyring have cached it)
- *
- * Returns: TRUE if yes, FALSE otherwise.
- */
-gboolean
-gksu_context_get_always_ask_password (GksuContext *context)
-{
- return context->always_ask_password;
-}
-
-
-/**
- * gksu_context_set_launcher_context:
- * @context: the #GksuContext you want to set the sn context in
- * @sn_context: the #SnLauncherContext you want to set
- *
- * Tell libgksu to use the given #SnLauncherContext for startup notification.
- * Currently the library will use this to set DESKTOP_STARTUP_ID in the
- * environment of the child and to issue initiate and complete events.
- * Notice that you don't need to use this function unless you want to
- * override gksu's default behavior on startup notification, since the
- * library will create its own context.
- *
- * Returns: the #SnLauncherContext which is set, or NULL if none was set
- */
-void
-gksu_context_set_launcher_context (GksuContext *context,
- SnLauncherContext *sn_context)
-{
- if (context->sn_context)
- sn_launcher_context_unref (context->sn_context);
- context->sn_context = sn_context;
-}
-
-/**
- * gksu_context_get_launcher_context:
- * @context: the #GksuContext you want to get the sn context from
- *
- * Gets the current startup notification launcher context
- *
- * Returns: the #SnLauncherContext which is set, or NULL if none was set
- */
-SnLauncherContext*
-gksu_context_get_launcher_context (GksuContext *context)
-{
- return context->sn_context;
-}
-
-/**
- * gksu_context_set_launcher_id:
- * @context: the #GksuContext you want to set the sn id in
- * @sn_context: the sn_id you want to set, as a #gchar
- */
-void
-gksu_context_set_launcher_id (GksuContext *context,
- gchar *sn_id)
-{
- if (context->sn_id)
- g_free (context->sn_id);
- context->sn_id = g_strdup(sn_id);
-}
-
-/**
- * gksu_context_launch_initiate:
- * @context: the #GksuContext you want to initiate the launch for
- *
- * Initiates the launch, as far as Startup Notification is concerned;
- * This will only be used internally, usually.
- */
-static void
-gksu_context_launch_initiate (GksuContext *context)
-{
- gchar *sid = NULL;
- guint32 launch_time = gdk_x11_display_get_user_time ((GdkDisplay*)GDK_DISPLAY());
- static gboolean initiated = FALSE;
-
- if (!initiated)
- initiated = TRUE;
- else
- return;
-
- sn_launcher_context_initiate (context->sn_context,
- g_get_prgname (),
- gksu_context_get_command (context),
- launch_time);
-
- sid = g_strdup_printf ("%s", sn_launcher_context_get_startup_id (context->sn_context));
- gksu_context_set_launcher_id (context, sid);
-
- if (context->debug)
- fprintf (stderr, "STARTUP_ID: %s\n", sid);
- setenv ("DESKTOP_STARTUP_ID", sid, TRUE);
- g_free(sid);
-}
-
-/**
- * gksu_context_launch_complete:
- * @context: the #GksuContext you want to complete the launch for
- *
- * Completes the launch, as far as Startup Notification is concerned;
- * This will only be used internally, usually.
- */
-static void
-gksu_context_launch_complete (GksuContext *context)
-{
- sn_launcher_context_complete(context->sn_context);
-}
-
-/**
- * gksu_context_set_debug:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if debuging information should be printed.
- */
-void
-gksu_context_set_debug (GksuContext *context, gboolean value)
-{
- context->debug = value;
-}
-
-/**
- * gksu_context_get_debug:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the library is configured to print debuging
- * information.
- *
- * Returns: TRUE if it is, FALSE otherwise.
- */
-gboolean
-gksu_context_get_debug (GksuContext *context)
-{
- return context->debug;
-}
-
-/**
- * gksu_context_free
- * @context: the #GksuContext to be freed.
- *
- * Frees the given #GksuContext.
- */
-void
-gksu_context_free (GksuContext *context)
-{
- g_free (context->xauth);
- g_free (context->dir);
- g_free (context->display);
-
- g_object_unref (context->gconf_client);
-
- g_free (context->description);
- g_free (context->message);
-
- g_free (context->user);
- g_free (context->command);
-
- g_free (context);
-}
-
-/**
- * gksu_context_ref
- * @context: A #GksuContext struct.
- *
- * Increments the reference count of the given #GksuContext.
- */
-GksuContext*
-gksu_context_ref (GksuContext *context)
-{
- context->ref_count++;
- return context;
-}
-
-/**
- * gksu_context_unref
- * @context: A #GksuContext struct.
- *
- * Decrements the reference count of the given #GksuContext struct,
- * freeing it if the reference count falls to zero.
- */
-void
-gksu_context_unref (GksuContext *context)
-{
- if (--context->ref_count == 0)
- {
- gksu_context_free (context);
- }
-}
-
-GType
-gksu_context_get_type (void)
-{
- static GType type_gksu_context = 0;
-
- if (!type_gksu_context)
- type_gksu_context = g_boxed_type_register_static
- ("GksuContext",
- (GBoxedCopyFunc) gksu_context_ref,
- (GBoxedFreeFunc) gksu_context_unref);
-
- return type_gksu_context;
-}
-
-
-/**
- * gksu_su_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_su_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument. You should
- * check the documentation for gksu_su_fuller for information about
- * the arguments.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_su_full (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- GError **error)
-{
- return gksu_su_fuller(context,
- ask_pass, ask_pass_data,
- pass_not_needed, pass_not_needed_data,
- NULL, error);
-}
-
-
-/**
- * gksu_su_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This could be considered one of the main functions in GKSu.
- * it is responsible for doing the 'user changing' magic calling
- * the #GksuAskPassFunc function to request a password if needed.
- * and the #GksuPassNotNeededFunc function if a password won't be
- * needed, so the application has the oportunity of warning the user
- * what it's doing.
- *
- * This function uses su as backend.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_su_fuller (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- gint8 *exit_status,
- GError **error)
-{
- GQuark gksu_quark;
- int i = 0;
-
- gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
-
- int fdpty;
- pid_t pid;
-
- context->sudo_mode = FALSE;
-
- gksu_quark = g_quark_from_string (PACKAGE);
-
- if (!context->command)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
- _("gksu_run needs a command to be run, "
- "none was provided."));
- return FALSE;
- }
-
- if (!context->user)
- context->user = g_strdup ("root");
-
- if (!g_file_test (auxcommand, G_FILE_TEST_IS_EXECUTABLE))
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_HELPER,
- _("The gksu-run-helper command was not found or "
- "is not executable."));
- return FALSE;
- }
-
- if (!prepare_xauth (context))
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
- _("Unable to copy the user's Xauthorization file."));
- return FALSE;
- }
-
- if (context->sn_context)
- gksu_context_launch_initiate (context);
-
- pid = forkpty(&fdpty, NULL, NULL, NULL);
- if (pid == 0)
- {
- gchar **cmd = g_malloc (sizeof(gchar*)*7);
-
- setsid(); // make us session leader
- cmd[i] = g_strdup ("/bin/su"); i++;
- if (context->login_shell)
- {
- cmd[i] = g_strdup ("-"); i++;
- }
- cmd[i] = g_strdup (context->user); i++;
- if (context->keep_env)
- {
- cmd[i] = g_strdup ("-p"); i++;
- }
- cmd[i] = g_strdup ("-c"); i++;
-
- /* needs to get X authorization prior to running the program */
- cmd[i] = g_strdup_printf ("%s \"%s\"", auxcommand,
- context->command); i++;
-
- cmd[i] = NULL;
-
- /* executes the command */
- if (execv (cmd[0], cmd) == -1)
- {
- fprintf (stderr,
- "Unable to run /bin/su: %s",
- strerror(errno));
- }
-
- for (i = 0 ; cmd[i] != NULL ; i++)
- g_free (cmd[i]);
- g_free(cmd);
- }
- else if (pid == -1)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
- _("Failed to fork new process: %s"),
- strerror(errno));
- return FALSE;
- }
- else
- {
- fd_set rfds;
-
- struct timeval tv;
-
- struct passwd *pwd = NULL;
- gint target_uid = -1;
- gint my_uid = 0;
-
- gchar buf[256] = {0};
- gint status;
-
- gchar *password = NULL;
- gchar *cmdline = NULL;
- gboolean password_needed = FALSE;
- gboolean used_gnome_keyring = FALSE;
-
- my_uid = getuid();
- pwd = getpwnam (context->user);
- if (pwd)
- target_uid = pwd->pw_uid;
-
- if (ask_pass == NULL)
- {
- ask_pass = su_ask_password;
- }
-
- if (pass_not_needed == NULL)
- {
- pass_not_needed = no_pass;
- }
-
- /* no need to ask for password if we're already root */
- if (my_uid != target_uid && my_uid)
- {
- gint count;
- struct termios tio;
-
- read (fdpty, buf, 255);
- if (context->debug)
- fprintf (stderr, "gksu_context_run: buf: -%s-\n", buf);
-
- /* make sure we notice that ECHO is turned off, if it gets
- turned off */
- tcgetattr (fdpty, &tio);
- for (count = 0; (tio.c_lflag & ECHO) && count < 15; count++)
- {
- usleep (1000);
- tcgetattr (fdpty, &tio);
- }
-
- if (!(tio.c_lflag & ECHO))
- {
- gboolean prompt_grab;
- prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
- NULL);
-
- if (prompt_grab)
- gksu_prompt_grab (context);
-
- /* try to get the password from the GNOME Keyring first, but
- * only if we have not been requested to always ask for the
- * password
- */
- if (!context->always_ask_password)
- password = get_gnome_keyring_password (context);
- if (password == NULL)
- {
- password = ask_pass (context, buf, ask_pass_data, error);
- if (context->debug)
- {
- fprintf (stderr, "no password on keyring\n");
- if (password == NULL)
- fprintf (stderr, "no password from ask_pass!\n");
- }
- }
- else
- {
- if (context->debug)
- fprintf (stderr, "password from keyring found\n");
- used_gnome_keyring = TRUE;
- }
- if (password == NULL || (error && (*error)))
- {
- if (context->debug)
- fprintf (stderr, "gksu_su_full: problem getting password - getting out\n");
- if (context->debug && error)
- fprintf (stderr, "error: %s\n", (*error)->message);
- nullify_password (password);
- return TRUE;
- }
-
- write (fdpty, password, strlen(password) + 1);
- write (fdpty, "\n", 1);
- password_needed = TRUE;
- }
- }
-
- if (context->debug)
- fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
- if (strncmp (buf, "gksu", 4) && strncmp (buf, "su", 2))
- {
- /* drop the \n echoed on password entry if su did request
- a password */
- if (password_needed)
- read (fdpty, buf, 255);
- if (context->debug)
- fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
- read (fdpty, buf, 255);
- if (context->debug)
- fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
- }
-
- FD_ZERO (&rfds);
- FD_SET (fdpty, &rfds);
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- int loop_count = 0;
- while (TRUE)
- {
- int retval = 0;
-
- if (!strncmp (buf, "su", 2))
- {
- gchar **strings;
-
- if (password)
- {
- nullify_password (password);
- unset_gnome_keyring_password (context);
- }
-
- strings = g_strsplit (buf, ":", 2);
- if (strings[1] && !strncmp (strings[1], " Authentication failure", 23))
- {
- if (used_gnome_keyring)
- g_set_error (error, gksu_quark,
- GKSU_ERROR_WRONGAUTOPASS,
- _("Wrong password got from keyring."));
- else
- g_set_error (error, gksu_quark,
- GKSU_ERROR_WRONGPASS,
- _("Wrong password."));
- }
- g_strfreev (strings);
-
- if (context->debug)
- fprintf (stderr, "DEBUG (auth_failed) buf: -%s-\n", buf);
-
- break;
- }
- else if (!strncmp (buf, "gksu: waiting", 13))
- {
- gchar *line;
-
- if (password)
- {
- set_gnome_keyring_password (context, password);
- nullify_password (password);
- }
-
- if (context->debug)
- fprintf (stderr, "DEBUG (gksu: waiting) buf: -%s-\n", buf);
-
- line = g_strdup_printf ("gksu-run: %s\n", context->display);
- write (fdpty, line, strlen(line));
- g_free (line);
-
- line = g_strdup_printf ("gksu-run: %s\n", context->sn_id);
- write (fdpty, line, strlen(line));
- g_free (line);
-
- line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
- write (fdpty, line, strlen(line));
- g_free (line);
-
- tcdrain (fdpty);
-
- bzero (buf, 256);
- read (fdpty, buf, 255);
-
- break;
- }
-
- retval = select (fdpty + 1, &rfds, NULL, NULL, &tv);
- if ((loop_count > 50) || (!retval))
- {
- gchar *emsg = NULL;
- gchar *converted_str = NULL;
- GError *converr = NULL;
-
- if (password)
- nullify_password (password);
-
- converted_str = g_locale_to_utf8 (buf, -1, NULL, NULL, &converr);
- if (converr)
- {
- g_warning (_("Failed to communicate with "
- "gksu-run-helper.\n\n"
- "Received:\n"
- " %s\n"
- "While expecting:\n"
- " %s"), buf, "gksu: waiting");
- emsg = g_strdup_printf (_("Failed to communicate with "
- "gksu-run-helper.\n\n"
- "Received bad string "
- "while expecting:\n"
- " %s"), "gksu: waiting");
- g_error_free (converr);
- }
- else
- emsg = g_strdup_printf (_("Failed to communicate with "
- "gksu-run-helper.\n\n"
- "Received:\n"
- " %s\n"
- "While expecting:\n"
- " %s"), converted_str, "gksu: waiting");
- g_free (converted_str);
-
- g_set_error (error, gksu_quark, GKSU_ERROR_HELPER, emsg);
- g_free (emsg);
-
- if (context->debug)
- fprintf (stderr, "DEBUG (failed!) buf: -%s-\n", buf);
-
- return FALSE;
- }
- else if (retval == -1)
- {
- if (context->debug)
- fprintf (stderr, "DEBUG (select failed!) buf: %s\n", buf);
- return FALSE;
- }
-
- read (fdpty, buf, 255);
- if (context->debug)
- fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
- loop_count++;
- }
-
- if (!password_needed || used_gnome_keyring)
- {
- gboolean should_display;
-
- should_display = gconf_client_get_bool (context->gconf_client,
- BASE_PATH "display-no-pass-info", NULL);
-
- /* configuration tells us to show this message */
- if (should_display)
- {
- if (context->debug)
- fprintf (stderr, "Calling pass_not_needed window...\n");
- pass_not_needed (context, pass_not_needed_data);
- /* make sure it is displayed */
- while (gtk_events_pending ())
- gtk_main_iteration ();
- }
- }
-
- cmdline = g_strdup("bin/su");
- /* wait for the child process to end or become something other
- than su */
- pid_t pid_exited;
- while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
- (g_str_has_suffix(cmdline, "bin/su")))
- {
- if (cmdline)
- g_free (cmdline);
- cmdline = get_process_name (pid);
- usleep(100000);
- }
-
- if (context->sn_context)
- gksu_context_launch_complete (context);
-
- bzero(buf, 256);
- while (read (fdpty, buf, 255) > 0)
- {
- fprintf (stderr, "%s", buf);
- bzero(buf, 256);
- }
-
- if (pid_exited != pid)
- waitpid(pid, &status, 0);
-
- if (exit_status)
- {
- if (WIFEXITED(status)) {
- *exit_status = WEXITSTATUS(status);
- } else if (WIFSIGNALED(status)) {
- *exit_status = -1;
- }
- }
-
- if (WEXITSTATUS(status))
- {
- if(cmdline)
- {
- /* su already exec()ed something else, don't report
- * exit status errors in that case
- */
- if (!g_str_has_suffix (cmdline, "su"))
- {
- g_free (cmdline);
- return FALSE;
- }
- g_free (cmdline);
- }
-
- if (error == NULL)
- g_set_error (error, gksu_quark,
- GKSU_ERROR_CHILDFAILED,
- _("su terminated with %d status"),
- WEXITSTATUS(status));
- }
- }
-
- if (error)
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * gksu_su
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_su_run_full. It will call it
- * without giving the callback functions, which leads to the standard
- * ones being called. A simple #GksuContext is created to hold the
- * user name and the command.
- *
- * Returns: TRUE if all went well, FALSE if an error happend.
- */
-gboolean
-gksu_su (gchar *command_line, GError **error)
-{
- GksuContext *context = gksu_context_new ();
- gboolean retval;
-
- context->command = g_strdup (command_line);
- context->user = g_strdup ("root");
- retval = gksu_su_full (context,
- NULL, NULL,
- NULL, NULL,
- error);
- gksu_context_free (context);
- return retval;
-}
-
-static void
-read_line (int fd, gchar *buffer, int n)
-{
- gint counter = 0;
- gchar tmp[2] = {0};
-
- for (; counter < (n - 1); counter++)
- {
- read (fd, tmp, 1);
- if (tmp[0] == '\n')
- break;
- buffer[counter] = tmp[0];
- }
- buffer[counter+1] = '\0';
-}
-
-/**
- * gksu_sudo_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_sudo_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument. You should
- * check the documentation for gksu_sudo_fuller for information about
- * the arguments.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_sudo_full (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- GError **error)
-{
- return gksu_sudo_fuller(context,
- ask_pass, ask_pass_data,
- pass_not_needed, pass_not_needed_data,
- NULL, error);
-}
-
-/**
- * gksu_sudo_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- *
- * This could be considered one of the main functions in GKSu.
- * it is responsible for doing the 'user changing' magic calling
- * the #GksuAskPassFunc function to request a password if needed.
- * and the #GksuPassNotNeededFunc function if a password won't be
- * needed, so the application has the oportunity of warning the user
- * what it's doing.
- *
- * This function uses the sudo backend.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_sudo_fuller (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- gint8 *exit_status,
- GError **error)
-{
- char **cmd;
- char buffer[256] = {0};
- int argcount = 8;
- int i, j;
-
- GQuark gksu_quark;
-
- gchar *xauth = NULL,
- *xauth_env = NULL;
-
- pid_t pid;
- int status;
- FILE *infile, *outfile;
- int parent_pipe[2]; /* For talking to the parent */
- int child_pipe[2]; /* For talking to the child */
-
- context->sudo_mode = TRUE;
-
- gksu_quark = g_quark_from_string (PACKAGE);
-
- if (!context->command)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
- _("gksu_sudo_run needs a command to be run, "
- "none was provided."));
- return FALSE;
- }
-
- if (!context->user)
- context->user = g_strdup ("root");
-
- if (ask_pass == NULL)
- {
- if (context->debug)
- fprintf (stderr, "No ask_pass set, using default!\n");
- ask_pass = su_ask_password;
- }
- if (pass_not_needed == NULL)
- {
- pass_not_needed = no_pass;
- }
-
- if (context->always_ask_password)
- {
- gint exit_status;
- g_spawn_command_line_sync("/usr/bin/sudo -K", NULL, NULL, &exit_status, NULL);
- }
-
-
- /*
- FIXME: need to set GError in a more detailed way
- */
- if (!sudo_prepare_xauth (context))
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
- _("Unable to copy the user's Xauthorization file."));
- return FALSE;
- }
-
- /* sets XAUTHORITY */
- xauth = g_strdup_printf ("%s/.Xauthority", context->dir);
- xauth_env = getenv ("XAUTHORITY");
- setenv ("XAUTHORITY", xauth, TRUE);
- if (context->debug)
- fprintf (stderr, "xauth: %s\n", xauth);
-
- /* set startup id */
- if (context->sn_context)
- gksu_context_launch_initiate (context);
-
- cmd = g_new (gchar *, argcount + 1);
-
- argcount = 0;
-
- /* sudo binary */
- cmd[argcount] = g_strdup("/usr/bin/sudo");
- argcount++;
-
- if (!context->keep_env)
- {
- /* Make sudo set $HOME */
- cmd[argcount] = g_strdup("-H");
- argcount++;
- }
-
- /* Make sudo read from stdin */
- cmd[argcount] = g_strdup("-S");
- argcount++;
-
- /* Make sudo use next arg as prompt */
- cmd[argcount] = g_strdup("-p");
- argcount++;
-
- /* prompt */
- cmd[argcount] = g_strdup("GNOME_SUDO_PASS");
- argcount++;
-
- /* Make sudo use the selected user */
- cmd[argcount] = g_strdup("-u");
- argcount++;
-
- /* user */
- cmd[argcount] = g_strdup(context->user);
- argcount++;
-
- /* sudo does not understand this if we do not use -H
- weird.
- */
- if (!context->keep_env)
- {
- /* Make sudo stop processing options */
- cmd[argcount] = g_strdup("--");
- argcount++;
- }
-
- {
- gchar *tmp_arg = g_malloc (sizeof(gchar)*1);
- gboolean inside_quotes = FALSE;
-
- tmp_arg[0] = '\0';
-
- for (i = j = 0; ; i++)
- {
- if ((context->command[i] == '\'') && (context->command[i-1] != '\\'))
- {
- i = i + 1;
- inside_quotes = !inside_quotes;
- }
-
- if ((context->command[i] == ' ' && inside_quotes == FALSE)
- || context->command[i] == '\0')
- {
- tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
- tmp_arg[j] = '\0';
- cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
- cmd[argcount] = g_strdup (tmp_arg);
-
- g_free (tmp_arg);
-
- argcount = argcount + 1;
- j = 0;
-
- if (context->command[i] == '\0')
- break;
-
- tmp_arg = g_malloc (sizeof(gchar)*1);
- tmp_arg[0] = '\0';
- }
- else
- {
- if (context->command[i] == '\\' && context->command[i+1] != '\\')
- i = i + 1;
- tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
- tmp_arg[j] = context->command[i];
- j = j + 1;
- }
- }
- }
- cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
- cmd[argcount] = NULL;
-
- if (context->debug)
- {
- for (i = 0; cmd[i] != NULL; i++)
- fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
- }
-
- if ((pipe(parent_pipe)) == -1)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
- _("Error creating pipe: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
-
- if ((pipe(child_pipe)) == -1)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
- _("Error creating pipe: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
-
- pid = fork();
- if (pid == -1)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
- _("Failed to fork new process: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
- else if (pid == 0)
- {
- // Child
- setsid(); // make us session leader
- close(child_pipe[1]);
- dup2(child_pipe[0], STDIN_FILENO);
- dup2(parent_pipe[1], STDERR_FILENO);
-
- execv(cmd[0], cmd);
-
- g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
- _("Failed to exec new process: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
- else
- {
- gint counter = 0;
- gchar *cmdline = NULL;
-
- // Parent
- close(parent_pipe[1]);
-
- infile = fdopen(parent_pipe[0], "r");
- if (!infile)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
- _("Error opening pipe: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
-
- outfile = fdopen(child_pipe[1], "w");
- if (!outfile)
- {
- g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
- _("Error opening pipe: %s"),
- strerror(errno));
- sudo_reset_xauth (context, xauth, xauth_env);
- return FALSE;
- }
-
- /*
- we are expecting to receive a GNOME_SUDO_PASS
- if we don't there are two possibilities: an error
- or a password is not needed
- */
- fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
-
- { /* no matter if we can read, since we're using
- O_NONBLOCK; this is just to avoid the prompt
- showing up after the read */
- fd_set rfds;
- struct timeval tv;
-
- FD_ZERO(&rfds);
- FD_SET(parent_pipe[0], &rfds);
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-
- select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
- }
-
- /* Try hard to find the prompt; it may happen that we're
- * seeing sudo's lecture, or that some pam module is spitting
- * debugging stuff at the screen
- */
- for (counter = 0; counter < 50; counter++)
- {
- if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
- break;
-
- read_line (parent_pipe[0], buffer, 256);
-
- if (context->debug)
- fprintf (stderr, "buffer: -%s-\n", buffer);
-
- usleep(1000);
- }
-
- if (context->debug)
- fprintf (stderr, "brute force GNOME_SUDO_PASS ended...\n");
-
- if (strncmp(buffer, "GNOME_SUDO_PASS", 15) == 0)
- {
- gchar *password = NULL;
- gboolean prompt_grab;
-
- if (context->debug)
- fprintf (stderr, "Yeah, we're in...\n");
-
- prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
- NULL);
- if (prompt_grab)
- gksu_prompt_grab (context);
-
- password = ask_pass (context, _("Password: "),
- ask_pass_data, error);
- if (password == NULL || (*error))
- {
- nullify_password (password);
- return FALSE;
- }
-
- usleep (1000);
-
- fprintf (outfile, "%s\n", password);
- fclose (outfile);
-
- nullify_password (password);
-
- /* turn NONBLOCK off */
- fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
- /* ignore the first newline that comes right after sudo receives
- the password */
- fgets (buffer, 255, infile);
- /* this is the status we are interessted in */
- fgets (buffer, 255, infile);
- }
- else
- {
- gboolean should_display;
- if (context->debug)
- fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
-
- /* turn NONBLOCK off, also if have no prompt */
- fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
-
- should_display = gconf_client_get_bool (context->gconf_client,
- BASE_PATH "display-no-pass-info", NULL);
-
- /* configuration tells us to show this message */
- if (should_display)
- {
- if (context->debug)
- fprintf (stderr, "Calling pass_not_needed window...\n");
- pass_not_needed (context, pass_not_needed_data);
- /* make sure it is displayed */
- while (gtk_events_pending ())
- gtk_main_iteration ();
- }
-
- fprintf (stderr, "%s", buffer);
- }
-
- if (!strcmp (buffer, "Sorry, try again.\n"))
- g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
- _("Wrong password."));
- else if (!strncmp (buffer, "Sorry, user ", 12))
- g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
- _("The underlying authorization mechanism (sudo) "
- "does not allow you to run this program. Contact "
- "the system administrator."));
- else
- {
- gchar *haystack = buffer;
- gchar *needle;
-
- needle = g_strstr_len (haystack, strlen (haystack), " ");
- if (needle && (needle + 1))
- {
- needle += 1;
- if (!strncmp (needle, "is not in", 9))
- g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
- _("The underlying authorization mechanism (sudo) "
- "does not allow you to run this program. Contact "
- "the system administrator."));
- }
- }
-
- cmdline = g_strdup("sudo");
- /* wait for the child process to end or become something other
- than sudo */
- pid_t pid_exited;
- while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
- (g_str_has_suffix(cmdline, "sudo")))
- {
- if (cmdline)
- g_free (cmdline);
- cmdline = get_process_name (pid);
- usleep(100000);
- }
-
- if (context->sn_context)
- gksu_context_launch_complete (context);
-
- while (read (parent_pipe[0], buffer, 255) > 0)
- {
- fprintf (stderr, "%s", buffer);
- bzero(buffer, 256);
- }
-
- /* if the process is still active waitpid() on it */
- if (pid_exited != pid)
- waitpid(pid, &status, 0);
- sudo_reset_xauth (context, xauth, xauth_env);
-
- if (exit_status)
- {
- if (WIFEXITED(status)) {
- *exit_status = WEXITSTATUS(status);
- } else if (WIFSIGNALED(status)) {
- *exit_status = -1;
- }
- }
-
- if (WEXITSTATUS(status))
- {
- if(cmdline)
- {
- /* sudo already exec()ed something else, don't report
- * exit status errors in that case
- */
- if (!g_str_has_suffix (cmdline, "sudo"))
- {
- g_free (cmdline);
- return FALSE;
- }
- g_free (cmdline);
- }
- if (error == NULL)
- g_set_error (error, gksu_quark,
- GKSU_ERROR_CHILDFAILED,
- _("sudo terminated with %d status"),
- WEXITSTATUS(status));
- }
- }
-
- /* if error is set we have found an error condition */
- if (error)
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * gksu_sudo
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_sudo_run_full. It will call it
- * without giving the callback functions, which leads to the standard
- * ones being called. A simple #GksuContext is created to hold the
- * user name and the command.
- *
- * Returns: TRUE if all went well, FALSE if an error happend.
- */
-gboolean
-gksu_sudo (gchar *command_line,
- GError **error)
-{
- GksuContext *context = gksu_context_new ();
- gboolean retval;
-
- context->command = g_strdup (command_line);
- context->user = g_strdup ("root");
- retval = gksu_sudo_full (context,
- NULL, NULL,
- NULL, NULL,
- error);
- gksu_context_free (context);
-
- return retval;
-}
-
-/**
- * gksu_run_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_run_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_run_full (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- GError **error)
-{
- return gksu_run_fuller(context,
- ask_pass, ask_pass_data,
- pass_not_needed, pass_not_needed_data,
- NULL, error);
-}
-
-/**
- * gksu_run_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This function is a wrapper for gksu_sudo_full/gksu_su_full. It will
- * call one of them, depending on the GConf key that defines whether
- * the default behavior for gksu is su or sudo mode. This is the
- * recommended way of using the library functionality.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_run_fuller (GksuContext *context,
- GksuAskPassFunc ask_pass,
- gpointer ask_pass_data,
- GksuPassNotNeededFunc pass_not_needed,
- gpointer pass_not_needed_data,
- gint8 *exit_status,
- GError **error)
-{
- GConfClient *gconf_client;
- gboolean sudo_mode;
-
- gconf_client = gconf_client_get_default ();
- sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
- NULL);
- g_object_unref (gconf_client);
-
- if (sudo_mode)
- return gksu_sudo_fuller (context, ask_pass, ask_pass_data,
- pass_not_needed, pass_not_needed_data,
- exit_status, error);
-
- return gksu_su_fuller (context, ask_pass, ask_pass_data,
- pass_not_needed, pass_not_needed_data,
- exit_status, error);
-}
-
-/**
- * gksu_run
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_sudo/gksu_su. It will call one
- * of them, depending on the GConf key that defines whether the default
- * behavior for gksu is su or sudo mode. This is the recommended way of
- * using the library functionality.
- *
- * Returns: FALSE if all went well, TRUE if an error happend.
- */
-gboolean
-gksu_run (gchar *command_line,
- GError **error)
-{
- GConfClient *gconf_client;
- gboolean sudo_mode;
-
- gconf_client = gconf_client_get_default ();
- sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
- NULL);
- g_object_unref (gconf_client);
-
- if (sudo_mode)
- return gksu_sudo (command_line, error);
-
- return gksu_su (command_line, error);
-}
-
-/**
- * gksu_ask_password_full:
- * @context: a #GksuContext
- * @prompt: a prompt different from Password:
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This function uses the gksu infra-structure to request for a
- * password, but instead of passing it to su or sudo to run a command
- * it simply returns the password.
- *
- * Returns: a newly allocated string with the password;
- */
-gchar*
-gksu_ask_password_full (GksuContext *context, gchar *prompt,
- GError **error)
-{
- gchar *ret_value = su_ask_password (context, _(prompt), NULL, error);
- if (context->sn_context)
- gksu_context_launch_complete (context);
- return ret_value;
-}
-
-/**
- * gksu_ask_password
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function uses the gksu infra-structure to request for a
- * password, but instead of passing it to su or sudo to run a command
- * it simply returns the password. This is just a convenience wrapper
- * for gksu_ask_password_full.
- *
- * Returns: a newly allocated string with the password;
- */
-gchar*
-gksu_ask_password (GError **error)
-{
- GksuContext *context = gksu_context_new ();
- gchar* retval;
-
- context->user = g_strdup ("root");
- retval = gksu_ask_password_full (context, NULL, error);
- gksu_context_free (context);
-
- return retval;
-}
Copied: libgksu/tags/2.0.8/libgksu/libgksu.c (from rev 842, libgksu/trunk/libgksu/libgksu.c)
===================================================================
--- libgksu/tags/2.0.8/libgksu/libgksu.c (rev 0)
+++ libgksu/tags/2.0.8/libgksu/libgksu.c 2009-03-04 18:39:36 UTC (rev 844)
@@ -0,0 +1,3087 @@
+/*
+ * Gksu -- a library providing access to su functionality
+ * Copyright (C) 2004-2009 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pty.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include <glibtop.h>
+#include <glibtop/procstate.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#define SN_API_NOT_YET_FROZEN
+#include <libsn/sn.h>
+
+#include <gtk/gtk.h>
+#include <locale.h>
+
+#include <gconf/gconf-client.h>
+#include <gnome-keyring.h>
+
+#include "defines.h"
+#include "../config.h"
+
+#include "libgksu.h"
+#include "../libgksuui/gksuui-dialog.h"
+
+static void
+gksu_context_launch_complete (GksuContext *context);
+
+GType
+gksu_error_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { GKSU_ERROR_HELPER, "GKSU_ERROR_HELPER", "helper" },
+ { GKSU_ERROR_NOCOMMAND, "GKSU_ERROR_NOCOMMAND", "nocommand" },
+ { GKSU_ERROR_NOPASSWORD, "GKSU_ERROR_NOPASSWORD", "nopassword" },
+ { GKSU_ERROR_FORK, "GKSU_ERROR_FORK", "fork" },
+ { GKSU_ERROR_EXEC, "GKSU_ERROR_EXEC", "exec" },
+ { GKSU_ERROR_PIPE, "GKSU_ERROR_PIPE", "pipe" },
+ { GKSU_ERROR_PIPEREAD, "GKSU_ERROR_PIPEREAD", "piperead" },
+ { GKSU_ERROR_WRONGPASS, "GKSU_ERROR_WRONGPASS", "wrongpass" },
+ { GKSU_ERROR_CHILDFAILED, "GKSU_ERROR_CHILDFAILED", "childfailed" },
+ { GKSU_ERROR_CANCELED, "GKSU_ERROR_CANCELED", "canceled" },
+ { GKSU_ERROR_WRONGAUTOPASS, "GKSU_ERROR_WRONGAUTOPASS", "wrongautopass" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("GksuError", values);
+ }
+ return etype;
+}
+
+static pid_t
+test_lock(const char* fname)
+{
+ int FD = open(fname, 0);
+ if(FD < 0) {
+ if(errno == ENOENT) {
+ // File does not exist
+ return 0;
+ } else {
+ perror("open");
+ return(-1);
+ }
+ }
+ struct flock fl;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ if (fcntl(FD, F_GETLK, &fl) < 0) {
+ g_critical("fcntl error");
+ close(FD);
+ return(-1);
+ }
+ close(FD);
+ // lock is available
+ if(fl.l_type == F_UNLCK)
+ return(0);
+ // file is locked by another process
+ return (fl.l_pid);
+}
+
+static int
+get_lock(const char *File)
+{
+ int FD = open(File,O_RDWR | O_CREAT | O_TRUNC,0640);
+ if (FD < 0)
+ {
+ // Read only .. cant have locking problems there.
+ if (errno == EROFS)
+ {
+ g_warning(_("Not using locking for read only lock file %s"),File);
+ return dup(0); // Need something for the caller to close
+ }
+
+ // Feh.. We do this to distinguish the lock vs open case..
+ errno = EPERM;
+ return -1;
+ }
+ fcntl(FD,F_SETFD, FD_CLOEXEC);
+
+ // Aquire a write lock
+ struct flock fl;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ if (fcntl(FD,F_SETLK,&fl) == -1)
+ {
+ if (errno == ENOLCK)
+ {
+ g_warning(_("Not using locking for nfs mounted lock file %s"), File);
+ unlink(File);
+ close(FD);
+ return dup(0); // Need something for the caller to close
+ }
+
+ int Tmp = errno;
+ close(FD);
+ errno = Tmp;
+ return -1;
+ }
+
+ return FD;
+}
+
+/*
+ * code 'stolen' from gnome-session's logout.c
+ *
+ * Written by Owen Taylor <otaylor at redhat.com>
+ * Copyright (C) Red Hat
+ */
+typedef struct {
+ GdkScreen *screen;
+ int monitor;
+ GdkRectangle area;
+ int rowstride;
+ GdkWindow *root_window;
+ GdkWindow *draw_window;
+ GdkPixbuf *start_pb, *end_pb, *frame;
+ guchar *start_p, *end_p, *frame_p;
+ GTimeVal start_time;
+ GdkGC *gc;
+} FadeoutData;
+
+FadeoutData *fade_data = NULL;
+static GList *fadeout_windows = NULL;
+
+#define FADE_DURATION 500.0
+
+int
+gsm_screen_get_width (GdkScreen *screen,
+ int monitor)
+{
+ GdkRectangle geometry;
+
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+ return geometry.width;
+}
+
+int
+gsm_screen_get_height (GdkScreen *screen,
+ int monitor)
+{
+ GdkRectangle geometry;
+
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+ return geometry.height;
+}
+
+int
+gsm_screen_get_x (GdkScreen *screen,
+ int monitor)
+{
+ GdkRectangle geometry;
+
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+ return geometry.x;
+}
+
+int
+gsm_screen_get_y (GdkScreen *screen,
+ int monitor)
+{
+ GdkRectangle geometry;
+
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+ return geometry.y;
+}
+
+static void
+get_current_frame (FadeoutData *fadeout,
+ double sat)
+{
+ guchar *sp, *ep, *fp;
+ int i, j, width, offset;
+
+ width = fadeout->area.width * 3;
+ offset = 0;
+
+ for (i = 0; i < fadeout->area.height; i++)
+ {
+ sp = fadeout->start_p + offset;
+ ep = fadeout->end_p + offset;
+ fp = fadeout->frame_p + offset;
+
+ for (j = 0; j < width; j += 3)
+ {
+ guchar r = abs (*(sp++) - ep[0]);
+ guchar g = abs (*(sp++) - ep[1]);
+ guchar b = abs (*(sp++) - ep[2]);
+
+ *(fp++) = *(ep++) + r * sat;
+ *(fp++) = *(ep++) + g * sat;
+ *(fp++) = *(ep++) + b * sat;
+ }
+
+ offset += fadeout->rowstride;
+ }
+}
+
+static void
+darken_pixbuf (GdkPixbuf *pb)
+{
+ int width, height, rowstride;
+ int i, j;
+ guchar *p, *pixels;
+
+ width = gdk_pixbuf_get_width (pb) * 3;
+ height = gdk_pixbuf_get_height (pb);
+ rowstride = gdk_pixbuf_get_rowstride (pb);
+ pixels = gdk_pixbuf_get_pixels (pb);
+
+ for (i = 0; i < height; i++)
+ {
+ p = pixels + (i * rowstride);
+ for (j = 0; j < width; j++)
+ p [j] >>= 1;
+ }
+}
+
+static gboolean
+fadeout_callback (FadeoutData *fadeout)
+{
+ GTimeVal current_time;
+ double elapsed, percent;
+
+ g_get_current_time (¤t_time);
+ elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
+ (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
+
+ if (elapsed < 0)
+ {
+ g_warning ("System clock seemed to go backwards?");
+ elapsed = G_MAXDOUBLE;
+ }
+
+ if (elapsed > FADE_DURATION)
+ {
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->end_pb,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ return FALSE;
+ }
+
+ percent = elapsed / FADE_DURATION;
+
+ get_current_frame (fadeout, 1.0 - percent);
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ gdk_flush ();
+
+ return TRUE;
+}
+
+static void
+hide_fadeout_windows (void)
+{
+ GList *l;
+
+ for (l = fadeout_windows; l; l = l->next)
+ {
+ gdk_window_hide (GDK_WINDOW (l->data));
+ g_object_unref (l->data);
+ }
+
+ g_list_free (fadeout_windows);
+ fadeout_windows = NULL;
+}
+
+static gboolean
+fadein_callback (FadeoutData *fadeout)
+{
+ GTimeVal current_time;
+ double elapsed, percent;
+
+ g_get_current_time (¤t_time);
+ elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
+ (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
+
+ if (elapsed < 0)
+ {
+ g_warning ("System clock seemed to go backwards?");
+ elapsed = G_MAXDOUBLE;
+ }
+
+ if (elapsed > FADE_DURATION)
+ {
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->end_pb,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ g_object_unref (fadeout->gc);
+ g_object_unref (fadeout->start_pb);
+ g_object_unref (fadeout->end_pb);
+ g_object_unref (fadeout->frame);
+
+ g_free (fadeout);
+
+ hide_fadeout_windows ();
+
+ return FALSE;
+ }
+
+ percent = elapsed / FADE_DURATION;
+
+ get_current_frame (fadeout, percent);
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ gdk_flush ();
+
+ return TRUE;
+}
+
+static void
+fadeout_screen (GdkScreen *screen,
+ int monitor)
+{
+ GdkWindowAttr attr;
+ int attr_mask;
+ GdkGCValues values;
+ FadeoutData *fadeout;
+
+ fadeout = g_new (FadeoutData, 1);
+
+ fadeout->screen = screen;
+ fadeout->monitor = monitor;
+
+ fadeout->area.x = gsm_screen_get_x (screen, monitor);
+ fadeout->area.y = gsm_screen_get_y (screen, monitor);
+ fadeout->area.width = gsm_screen_get_width (screen, monitor);
+ fadeout->area.height = gsm_screen_get_height (screen, monitor);
+
+ fadeout->root_window = gdk_screen_get_root_window (screen);
+ attr.window_type = GDK_WINDOW_CHILD;
+ attr.x = fadeout->area.x;
+ attr.y = fadeout->area.y;
+ attr.width = fadeout->area.width;
+ attr.height = fadeout->area.height;
+ attr.wclass = GDK_INPUT_OUTPUT;
+ attr.visual = gdk_screen_get_system_visual (fadeout->screen);
+ attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
+ attr.override_redirect = TRUE;
+ attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_NOREDIR;
+
+ fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
+ fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
+
+ fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
+ fadeout->root_window,
+ NULL,
+ fadeout->area.x,
+ fadeout->area.y,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height);
+
+ fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
+ darken_pixbuf (fadeout->end_pb);
+
+ fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
+ fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
+
+ fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
+ fadeout->end_p = gdk_pixbuf_get_pixels (fadeout->end_pb);
+ fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
+
+ values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+
+ fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+
+ gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
+ gdk_window_show (fadeout->draw_window);
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ g_get_current_time (&fadeout->start_time);
+ g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
+
+ fade_data = fadeout;
+}
+
+/* End of 'stolen' code */
+
+#define GRAB_TRIES 16
+#define GRAB_WAIT 250 /* milliseconds */
+
+typedef enum
+ {
+ FAILED_GRAB_MOUSE,
+ FAILED_GRAB_KEYBOARD
+ } FailedGrabWhat;
+
+void
+report_failed_grab (FailedGrabWhat what)
+{
+ GtkWidget *dialog;
+
+ dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
+ "message-type", GTK_MESSAGE_WARNING,
+ "buttons", GTK_BUTTONS_CLOSE,
+ NULL);
+
+ switch (what)
+ {
+ case FAILED_GRAB_MOUSE:
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
+ _("<b><big>Could not grab your mouse.</big></b>"
+ "\n\n"
+ "A malicious client may be eavesdropping "
+ "on your session or you may have just clicked "
+ "a menu or some application just decided to get "
+ "focus."
+ "\n\n"
+ "Try again."));
+
+ break;
+ case FAILED_GRAB_KEYBOARD:
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
+ _("<b><big>Could not grab your keyboard.</big></b>"
+ "\n\n"
+ "A malicious client may be eavesdropping "
+ "on your session or you may have just clicked "
+ "a menu or some application just decided to get "
+ "focus."
+ "\n\n"
+ "Try again."));
+ break;
+ }
+
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+ gtk_dialog_run (GTK_DIALOG(dialog));
+ gtk_widget_destroy (dialog);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+}
+
+int
+grab_keyboard_and_mouse (GtkWidget *dialog)
+{
+ GdkGrabStatus status;
+ gint grab_tries = 0;
+ gint lock = -1;
+ pid_t pid;
+
+ gchar *fname = g_strdup (getenv ("GKSU_LOCK_FILE"));
+ if (fname == NULL)
+ fname = g_strdup_printf ("%s/.gksu.lock", getenv ("HOME"));
+
+ pid = test_lock (fname);
+
+ if (pid != 0)
+ {
+ g_warning ("Lock taken by pid: %i. Exiting.", pid);
+ exit (0);
+ }
+
+ lock = get_lock(fname);
+ if( lock < 0)
+ g_warning ("Unable to create lock file.");
+ g_free (fname);
+
+ gdk_threads_enter ();
+ fadeout_screen (gdk_screen_get_default (), 0);
+ gtk_widget_show_all (dialog);
+
+ /* reset cursor */
+ gdk_window_set_cursor(dialog->window, gdk_cursor_new(GDK_LEFT_PTR));
+
+ for(;;)
+ {
+ status = gdk_pointer_grab ((GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
+ NULL, GDK_CURRENT_TIME);
+ if (status == GDK_GRAB_SUCCESS)
+ break;
+ usleep (GRAB_WAIT * 1000);
+ if (++grab_tries > GRAB_TRIES)
+ {
+ gtk_widget_hide (dialog);
+ g_get_current_time (&fade_data->start_time);
+ while (fadein_callback (fade_data) != FALSE);
+ report_failed_grab (FAILED_GRAB_MOUSE);
+ exit (1);
+ break;
+ }
+ }
+
+ for(;;)
+ {
+ status = gdk_keyboard_grab ((GTK_WIDGET(dialog))->window,
+ FALSE, GDK_CURRENT_TIME);
+ if (status == GDK_GRAB_SUCCESS)
+ break;
+
+ usleep(GRAB_WAIT * 1000);
+
+ if (++grab_tries > GRAB_TRIES)
+ {
+ gtk_widget_hide (dialog);
+ g_get_current_time (&fade_data->start_time);
+ while (fadein_callback (fade_data) != FALSE);
+ report_failed_grab (FAILED_GRAB_KEYBOARD);
+ exit (1);
+ break;
+ }
+ }
+
+ /* we "raise" the window because there is a race here for
+ * focus-follow-mouse and auto-raise WMs that may put the window
+ * in the background and confuse users
+ */
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ return lock;
+}
+
+void
+ungrab_keyboard_and_mouse (int lock)
+{
+ /* Ungrab */
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+ gdk_flush();
+
+ g_get_current_time (&fade_data->start_time);
+ while (fadein_callback (fade_data) != FALSE);
+ gdk_threads_leave();
+
+ close(lock);
+}
+
+static gchar*
+get_gnome_keyring_password (GksuContext *context)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+ GnomeKeyringResult result;
+ GList *list;
+
+ attributes = gnome_keyring_attribute_list_new ();
+
+ attribute.name = g_strdup ("user");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (gksu_context_get_user (context));
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("type");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("local");
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("creator");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("gksu");
+ g_array_append_val (attributes, attribute);
+
+ list = g_list_alloc();
+
+ result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ attributes,
+ &list);
+ gnome_keyring_attribute_list_free (attributes);
+ if (
+ (result == GNOME_KEYRING_RESULT_OK) &&
+ (g_list_length(list) >= 1)
+ )
+ {
+ GnomeKeyringFound *found = list->data;
+ gint password_length = strlen (found->secret);
+ gchar *password;
+
+ password = g_locale_from_utf8 (found->secret,
+ password_length,
+ NULL, NULL, NULL);
+ password_length = strlen (password);
+
+ if (password[password_length-1] == '\n')
+ password[password_length-1] = '\0';
+ return password;
+ }
+
+ return NULL;
+}
+
+static void
+keyring_create_item_cb (GnomeKeyringResult result,
+ guint32 id, gpointer keyring_loop)
+{
+ g_main_loop_quit (keyring_loop);
+}
+
+static void
+set_gnome_keyring_password (GksuContext *context, gchar *password)
+{
+ GConfClient *gconf_client;
+ gboolean save_to_keyring;
+
+ gconf_client = context->gconf_client;
+ save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
+
+ if (password && save_to_keyring)
+ {
+ static GMainLoop *keyring_loop = NULL;
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+ GnomeKeyringResult result;
+
+ gchar *keyring_name;
+ gchar *key_name;
+
+ attributes = gnome_keyring_attribute_list_new ();
+
+ attribute.name = g_strdup ("user");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (gksu_context_get_user (context));
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("type");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("local");
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("creator");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("gksu");
+ g_array_append_val (attributes, attribute);
+
+ key_name = g_strdup_printf ("Local password for user %s",
+ gksu_context_get_user (context));
+
+ keyring_loop = g_main_loop_new (NULL, FALSE);
+
+ keyring_name = gconf_client_get_string (gconf_client, BASE_PATH"save-keyring", NULL);
+ if (keyring_name == NULL)
+ keyring_name = g_strdup ("session");
+
+ /* make sure the keyring exists; if an error occurs, use
+ the session keyring */
+ result = gnome_keyring_create_sync(keyring_name, NULL);
+ if ((result != GNOME_KEYRING_RESULT_OK) &&
+ (result != GNOME_KEYRING_RESULT_ALREADY_EXISTS))
+ keyring_name = g_strdup ("session");
+
+ gnome_keyring_item_create (keyring_name,
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ key_name,
+ attributes,
+ password,
+ TRUE,
+ keyring_create_item_cb,
+ keyring_loop, NULL);
+ gnome_keyring_attribute_list_free (attributes);
+ g_free (keyring_name);
+ g_main_loop_run (keyring_loop);
+ }
+}
+
+static void
+unset_gnome_keyring_password (GksuContext *context)
+{
+ GConfClient *gconf_client;
+ gboolean save_to_keyring;
+
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+ GnomeKeyringResult result;
+ GList *list;
+
+ gconf_client = context->gconf_client;
+ save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
+
+ if (save_to_keyring)
+ {
+ attributes = gnome_keyring_attribute_list_new ();
+
+ attribute.name = g_strdup ("user");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (gksu_context_get_user (context));
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("type");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("local");
+ g_array_append_val (attributes, attribute);
+
+ attribute.name = g_strdup ("creator");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup ("gksu");
+ g_array_append_val (attributes, attribute);
+
+ list = g_list_alloc();
+
+ result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ attributes,
+ &list);
+ gnome_keyring_attribute_list_free (attributes);
+ if (
+ (result == GNOME_KEYRING_RESULT_OK) &&
+ (g_list_length(list) == 1)
+ )
+ {
+ GnomeKeyringFound *found = list->data;
+
+ gnome_keyring_item_delete_sync (found->keyring,
+ found->item_id);
+ }
+ }
+}
+
+void
+get_configuration_options (GksuContext *context)
+{
+ GConfClient *gconf_client = context->gconf_client;
+ gboolean force_grab;
+
+ context->grab = !gconf_client_get_bool (gconf_client, BASE_PATH "disable-grab",
+ NULL);
+ force_grab = gconf_client_get_bool (gconf_client, BASE_PATH "force-grab",
+ NULL);
+ if (force_grab)
+ context->grab = TRUE;
+
+ context->sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+ NULL);
+}
+
+/**
+ * su_ask_password:
+ * @context: a #GksuContext
+ * @prompt: the prompt that should be used instead of "Password: "
+ * @data: data that is passed by gksu_*_full
+ * @error: a pointer to pointer #GError that will be filled with
+ * data if an error happens.
+ *
+ * This is a convenience function to create a #GksuuiDialog and
+ * request the password.
+ *
+ * Returns: a newly allocated gchar containing the password
+ * or NULL if an error happens or the user cancels the action
+ */
+static gchar*
+su_ask_password (GksuContext *context, gchar *prompt,
+ gpointer data, GError **error)
+{
+ GtkWidget *dialog = NULL;
+ gchar *msg;
+ gchar *password = NULL, *tmp = NULL;
+ int retvalue = 0;
+ int lock = 0;
+ GQuark gksu_quark;
+
+ gksu_quark = g_quark_from_string (PACKAGE);
+
+ if (context->grab)
+ dialog = g_object_new (GKSUUI_TYPE_DIALOG,
+ "type", GTK_WINDOW_POPUP,
+ "sudo-mode", context->sudo_mode,
+ NULL);
+ else
+ dialog = gksuui_dialog_new (context->sudo_mode);
+
+ if (prompt)
+ gksuui_dialog_set_prompt (GKSUUI_DIALOG(dialog), _(prompt));
+
+ if (context->message)
+ gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), context->message);
+ else
+ {
+ gchar *command = NULL;
+ if (context->description)
+ command = context->description;
+ else
+ command = context->command;
+
+ if (context->sudo_mode)
+ {
+ if (!strcmp(context->user, "root"))
+ msg = g_strdup_printf (_("<b><big>Enter your password to perform"
+ " administrative tasks</big></b>\n\n"
+ "The application '%s' lets you "
+ "modify essential parts of your "
+ "system."),
+ command);
+ else
+ msg = g_strdup_printf (_("<b><big>Enter your password to run "
+ "the application '%s' as user %s"
+ "</big></b>"),
+ command, context->user);
+ }
+ else
+ {
+ if (strcmp(gksu_context_get_user (context), "root") == 0)
+ msg = g_strdup_printf (_("<b><big>Enter the administrative password"
+ "</big></b>\n\n"
+ "The application '%s' lets you "
+ "modify essential parts of your "
+ "system."),
+ command);
+ else
+ msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
+ "the application '%s'"
+ "</big></b>"),
+ context->user, command);
+ }
+
+ gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
+ g_free (msg);
+ }
+
+ if (context->alert)
+ gksuui_dialog_set_alert (GKSUUI_DIALOG(dialog), context->alert);
+
+ if (context->grab)
+ lock = grab_keyboard_and_mouse (dialog);
+ retvalue = gtk_dialog_run (GTK_DIALOG(dialog));
+ gtk_widget_hide (dialog);
+ if (context->grab)
+ ungrab_keyboard_and_mouse (lock);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ if (retvalue != GTK_RESPONSE_OK)
+ {
+ switch (retvalue)
+ {
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT:
+ g_set_error (error, gksu_quark,
+ GKSU_ERROR_CANCELED,
+ _("Password prompt canceled."));
+ if (context->sn_context)
+ gksu_context_launch_complete (context);
+ }
+
+ gtk_widget_destroy (dialog);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ return NULL;
+ }
+
+ tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog));
+ password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL);
+ g_free (tmp);
+
+ gtk_widget_destroy (dialog);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ return password;
+}
+
+static void
+cb_toggled_cb (GtkWidget *button, gpointer data)
+{
+ GConfClient *gconf_client;
+ gchar *key;
+ gboolean toggled;
+ gchar *key_name;
+
+ g_return_if_fail (data != NULL);
+
+ key_name = (gchar*)data;
+
+ gconf_client = gconf_client_get_default ();
+ toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
+
+ key = g_strdup_printf (BASE_PATH "%s", key_name);
+
+ if (!strcmp (key_name, "display-no-pass-info"))
+ {
+ /* the meaning of the key is the exact opposite of the meaning
+ of the answer - when the check button is checked the key must
+ be off
+ */
+ gconf_client_set_bool (gconf_client, key, !toggled, NULL);
+ }
+ else
+ gconf_client_set_bool (gconf_client, key, toggled, NULL);
+
+ g_object_unref (gconf_client);
+
+ g_free (key);
+}
+
+void
+no_pass (GksuContext *context, gpointer data)
+{
+ GtkWidget *dialog;
+ GtkWidget *alignment;
+ GtkWidget *check_button;
+
+ gchar *command = NULL;
+
+ if (context->description)
+ command = context->description;
+ else
+ command = context->command;
+
+ dialog = gtk_message_dialog_new_with_markup (NULL, 0,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+ _("<b><big>Granted permissions without asking "
+ "for password</big></b>"
+ "\n\n"
+ "The '%s' program was started with "
+ "the privileges of the %s user without "
+ "the need to ask for a password, due to "
+ "your system's authentication mechanism "
+ "setup."
+ "\n\n"
+ "It is possible that you are being allowed "
+ "to run specific programs as user %s "
+ "without the need for a password, or that "
+ "the password is cached."
+ "\n\n"
+ "This is not a problem report; it's "
+ "simply a notification to make sure "
+ "you are aware of this."),
+ command,
+ context->user,
+ context->user);
+
+ alignment = gtk_alignment_new (0.5, 0.5, 0.6, 1);
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), alignment, TRUE, TRUE, 2);
+
+ check_button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again"));
+ g_signal_connect (G_OBJECT(check_button), "toggled",
+ G_CALLBACK(cb_toggled_cb), "display-no-pass-info");
+ gtk_container_add (GTK_CONTAINER(alignment), check_button);
+
+ gtk_widget_show_all (dialog);
+ gtk_dialog_run (GTK_DIALOG(dialog));
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static void
+gksu_prompt_grab (GksuContext *context)
+{
+ GtkWidget *d;
+
+ d = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO,
+ _("<b>Would you like your screen to be \"grabbed\"\n"
+ "while you enter the password?</b>"
+ "\n\n"
+ "This means all applications will be paused to avoid\n"
+ "the eavesdropping of your password by a a malicious\n"
+ "application while you type it."));
+
+ if (gtk_dialog_run (GTK_DIALOG(d)) == GTK_RESPONSE_NO)
+ context->grab = FALSE;
+ else
+ context->grab = TRUE;
+
+ gtk_widget_destroy (d);
+}
+
+static void
+nullify_password (gchar *pass)
+{
+ if (pass)
+ {
+ memset(pass, 0, strlen(pass));
+ g_free (pass);
+ }
+ pass = NULL;
+}
+
+static gchar *
+get_process_name (pid_t pid)
+{
+ static gboolean init;
+ glibtop_proc_state buf;
+
+ if (!init) {
+ glibtop_init();
+ init = TRUE;
+ }
+
+ glibtop_get_proc_state (&buf, pid);
+ return strdup(buf.cmd);
+}
+
+static gchar *
+get_xauth_token (GksuContext *context, gchar *display)
+{
+ gchar *xauth_bin = NULL;
+ FILE *xauth_output;
+ gchar *tmp = NULL;
+ gchar *xauth = g_new0 (gchar, 256);
+
+ /* find out where the xauth binary is located */
+ if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+ xauth_bin = "/usr/bin/xauth";
+ else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+ xauth_bin = "/usr/X11R6/bin/xauth";
+ else
+ {
+ fprintf (stderr,
+ "Failed to obtain xauth key: xauth binary not found "
+ "at usual locations");
+
+ return NULL;
+ }
+
+ /* get the authorization token */
+ tmp = g_strdup_printf ("%s list %s | "
+ "head -1 | awk '{ print $3 }'",
+ xauth_bin,
+ display);
+ if ((xauth_output = popen (tmp, "r")) == NULL)
+ {
+ fprintf (stderr,
+ "Failed to obtain xauth key: %s",
+ strerror(errno));
+ return NULL;
+ }
+ fread (xauth, sizeof(char), 255, xauth_output);
+ pclose (xauth_output);
+ g_free (tmp);
+
+ if (context->debug)
+ {
+ fprintf(stderr,
+ "xauth: -%s-\n"
+ "display: -%s-\n",
+ xauth, display);
+ }
+
+ return xauth;
+}
+
+/**
+ * prepare_xauth:
+ *
+ * Sets up the variables with values for the $DISPLAY
+ * environment variable and xauth-related stuff. Also
+ * creates a temporary directory to hold a .Xauthority
+ *
+ * Returns: TRUE if it suceeds, FALSE if it fails.
+ */
+static int
+prepare_xauth (GksuContext *context)
+{
+ gchar *display = NULL;
+ gchar *xauth = NULL;
+
+ display = g_strdup (getenv ("DISPLAY"));
+ xauth = get_xauth_token (context, display);
+ if (xauth == NULL)
+ {
+ g_free (display);
+ return FALSE;
+ }
+
+ /* If xauth is the empty string, then try striping the
+ * hostname part of the DISPLAY string for getting the
+ * auth token; this is needed for ssh-forwarded usage
+ */
+ if (!strcmp ("", xauth))
+ {
+ gchar *cut_display = NULL;
+
+ g_free (xauth);
+ cut_display = g_strdup (g_strrstr (display, ":"));
+ xauth = get_xauth_token (context, cut_display);
+
+ g_free (display);
+ display = cut_display;
+ }
+
+ context->xauth = xauth;
+ context->display = display;
+
+ if (context->debug)
+ {
+ fprintf(stderr,
+ "final xauth: -%s-\n"
+ "final display: -%s-\n",
+ context->xauth, context->display);
+ }
+
+ return TRUE;
+}
+
+/* Write all of buf, even if write(2) is interrupted. */
+static ssize_t
+full_write (int d, const char *buf, size_t nbytes)
+{
+ ssize_t r, w = 0;
+
+ /* Loop until nbytes of buf have been written. */
+ while (w < nbytes) {
+ /* Keep trying until write succeeds without interruption. */
+ do {
+ r = write(d, buf + w, nbytes - w);
+ } while (r < 0 && errno == EINTR);
+
+ if (r < 0) {
+ return -1;
+ }
+
+ w += r;
+ }
+
+ return w;
+}
+
+static gboolean
+copy (const char *fn, const char *dir)
+{
+ int in, out;
+ int r;
+ char *newfn;
+ char buf[BUFSIZ] = "";
+
+ newfn = g_strdup_printf("%s/.Xauthority", dir);
+
+ out = open(newfn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (out == -1)
+ {
+ if (errno == EEXIST)
+ fprintf (stderr,
+ "Impossible to create the .Xauthority file: a file "
+ "already exists. This might be a security issue; "
+ "please investigate.");
+ else
+ fprintf (stderr,
+ "Error copying '%s' to '%s': %s",
+ fn, dir, strerror(errno));
+
+ return FALSE;
+ }
+
+ in = open(fn, O_RDONLY);
+ if (in == -1)
+ {
+ fprintf (stderr,
+ "Error copying '%s' to '%s': %s",
+ fn, dir, strerror(errno));
+ return FALSE;
+ }
+
+ while ((r = read(in, buf, BUFSIZ)) > 0)
+ {
+ if (full_write(out, buf, r) == -1)
+ {
+ fprintf (stderr,
+ "Error copying '%s' to '%s': %s",
+ fn, dir, strerror(errno));
+ return FALSE;
+ }
+ }
+
+ if (r == -1)
+ {
+ fprintf (stderr,
+ "Error copying '%s' to '%s': %s",
+ fn, dir, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+sudo_prepare_xauth (GksuContext *context)
+{
+ gchar template[] = "/tmp/" PACKAGE "-XXXXXX";
+ gboolean error_copying = FALSE;
+ gchar *xauth = NULL;
+
+ context->dir = g_strdup (mkdtemp(template));
+ if (!context->dir)
+ {
+ fprintf (stderr, strerror(errno));
+ return FALSE;
+ }
+
+ xauth = g_strdup(g_getenv ("XAUTHORITY"));
+ if (xauth == NULL)
+ xauth = g_strdup_printf ("%s/.Xauthority", g_get_home_dir());
+
+ error_copying = !copy (xauth, context->dir);
+ g_free (xauth);
+
+ if (error_copying)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+sudo_reset_xauth (GksuContext *context, gchar *xauth,
+ gchar *xauth_env)
+{
+ /* reset the env var as it was before or clean it */
+ if (xauth_env)
+ setenv ("XAUTHORITY", xauth_env, TRUE);
+ else
+ unsetenv ("XAUTHORITY");
+
+ if (context->debug)
+ fprintf (stderr, "xauth: %s\nxauth_env: %s\ndir: %s\n",
+ xauth, xauth_env, context->dir);
+
+ unlink (xauth);
+ rmdir (context->dir);
+
+ g_free (xauth);
+}
+
+static void
+startup_notification_initialize (GksuContext *context)
+{
+ SnDisplay *sn_display;
+ sn_display = sn_display_new (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+ NULL, NULL);
+ context->sn_context = sn_launcher_context_new (sn_display, gdk_screen_get_number (gdk_display_get_default_screen (gdk_display_get_default ())));
+ sn_launcher_context_set_description (context->sn_context, _("Granting Rights"));
+ sn_launcher_context_set_name (context->sn_context, g_get_prgname ());
+}
+
+/**
+ * gksu_context_new
+ *
+ * This function should be used when creating a new #GksuContext to
+ * pass to gksu_su_full or gksu_sudo_full. The #GksuContext must be
+ * freed with gksu_context_free.
+ *
+ * Returns: a newly allocated #GksuContext
+ */
+GksuContext*
+gksu_context_new ()
+{
+ GksuContext *context;
+
+ context = g_new (GksuContext, 1);
+
+ context->xauth = NULL;
+ context->dir = NULL;
+ context->display = NULL;
+
+ context->gconf_client = gconf_client_get_default ();
+
+ context->sudo_mode = FALSE;
+
+ context->user = g_strdup ("root");
+ context->command = NULL;
+
+ context->login_shell = FALSE;
+ context->keep_env = FALSE;
+
+ context->description = NULL;
+ context->message = NULL;
+ context->alert = NULL;
+ context->grab = TRUE;
+ context->always_ask_password = FALSE;
+
+ context->debug = FALSE;
+
+ context->sn_context = NULL;
+ context->sn_id = NULL;
+
+ context->ref_count = 1;
+
+ get_configuration_options (context);
+ startup_notification_initialize (context);
+
+ return context;
+}
+
+/**
+ * gksu_context_set_user:
+ * @context: the #GksuContext you want to modify
+ * @username: the target username
+ *
+ * Sets up what user the command will be run as. The default
+ * is root, but you can run the command as any user.
+ *
+ */
+void
+gksu_context_set_user (GksuContext *context, gchar *username)
+{
+ g_assert (username != NULL);
+
+ if (context->user)
+ g_free (context->user);
+ context->user = g_strdup (username);
+}
+
+/**
+ * gksu_context_get_user:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Gets the user the command will be run as, as set
+ * by gksu_context_set_user.
+ *
+ * Returns: a string with the user or NULL if not set.
+ */
+const gchar*
+gksu_context_get_user (GksuContext *context)
+{
+ return context->user;
+}
+
+/**
+ * gksu_context_set_command:
+ * @context: the #GksuContext you want to modify
+ * @command: the command that shall be ran
+ *
+ * Sets up what command will run with the target user.
+ *
+ */
+void
+gksu_context_set_command (GksuContext *context, gchar *command)
+{
+ g_assert (command != NULL);
+
+ if (context->command)
+ g_free (context->command);
+ context->command = g_strdup (command);
+
+ /* startup notification */
+ sn_launcher_context_set_binary_name (context->sn_context,
+ command);
+}
+
+/**
+ * gksu_context_get_command:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Gets the command that will be run, as set by
+ * gksu_context_set_command.
+ *
+ * Returns: a string with the command or NULL if not set.
+ */
+const gchar*
+gksu_context_get_command (GksuContext *context)
+{
+ return context->command;
+}
+
+/**
+ * gksu_context_set_login_shell:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Should the shell in which the command will be run be
+ * a login shell?
+ */
+void
+gksu_context_set_login_shell (GksuContext *context, gboolean value)
+{
+ context->login_shell = value;
+}
+
+/**
+ * gksu_context_get_login_shell:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the shell created by the underlying su process
+ * will be a login shell.
+ *
+ * Returns: TRUE if the shell will be a login shell, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_login_shell (GksuContext *context)
+{
+ return context->login_shell;
+}
+
+/**
+ * gksu_context_set_keep_env:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Should the environment be kept as it is? Defaults to
+ * TRUE. Notice that setting this to FALSE may cause the
+ * X authorization stuff to fail.
+ */
+void
+gksu_context_set_keep_env (GksuContext *context, gboolean value)
+{
+ context->keep_env = value;
+}
+
+/**
+ * gksu_context_get_keep_env:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the environment in which the program will be
+ * run will be reset.
+ *
+ * Returns: TRUE if the environment is going to be kept,
+ * FALSE otherwise.
+ */
+gboolean
+gksu_context_get_keep_env (GksuContext *context)
+{
+ return context->keep_env;
+}
+
+/**
+ * gksu_context_set_description:
+ * @context: the #GksuContext you want to modify
+ * @description: a string to set the description for
+ *
+ * Set the nice name for the action that is being run that the window
+ * that asks for the password will have. This is only meant to be
+ * used if the default window is used, of course.
+ */
+void
+gksu_context_set_description (GksuContext *context, gchar *description)
+{
+ if (context->description)
+ g_free (context->description);
+ context->description = g_strdup (description);
+}
+
+/**
+ * gksu_context_get_description:
+ * @context: the #GksuContext you want to get the description from.
+ *
+ * Get the description that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the description or NULL if not set.
+ */
+gchar*
+gksu_context_get_description (GksuContext *context)
+{
+ return context->description;
+}
+
+/**
+ * gksu_context_set_message:
+ * @context: the #GksuContext you want to modify
+ * @message: a string to set the message for
+ *
+ * Set the message that the window that asks for the password will have.
+ * This is only meant to be used if the default window is used, of course.
+ */
+void
+gksu_context_set_message (GksuContext *context, gchar *message)
+{
+ if (context->message)
+ g_free (context->message);
+ context->message = g_strdup (message);
+}
+
+/**
+ * gksu_context_get_message:
+ * @context: the #GksuContext you want to get the message from.
+ *
+ * Get the message that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the message or NULL if not set.
+ */
+gchar*
+gksu_context_get_message (GksuContext *context)
+{
+ return context->message;
+}
+
+/**
+ * gksu_context_set_alert:
+ * @context: the #GksuContext you want to modify
+ * @alert: a string to set the alert for
+ *
+ * Set the alert that the window that asks for the password will have.
+ * This is only meant to be used if the default window is used, of course.
+ * This alert should be used to display messages such as 'incorrect password',
+ * for instance.
+ */
+void
+gksu_context_set_alert (GksuContext *context, gchar *alert)
+{
+ if (context->alert)
+ g_free (context->alert);
+ context->alert = g_strdup (alert);
+}
+
+/**
+ * gksu_context_get_alert:
+ * @context: the #GksuContext you want to get the alert from.
+ *
+ * Get the alert that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the alert or NULL if not set.
+ */
+gchar*
+gksu_context_get_alert (GksuContext *context)
+{
+ return context->alert;
+}
+
+/**
+ * gksu_context_set_debug:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if debuging information should be printed.
+ */
+void
+gksu_context_set_grab (GksuContext *context, gboolean value)
+{
+ context->grab = value;
+}
+
+/**
+ * gksu_context_get_grab:
+ * @context: the #GksuContext you want to ask whether a grab will be done.
+ *
+ * Returns TRUE if gksu has been asked to do a grab on keyboard and mouse
+ * when asking for the password.
+ *
+ * Returns: TRUE if yes, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_grab (GksuContext *context)
+{
+ return context->grab;
+}
+
+/**
+ * gksu_context_set_always_ask_password:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if gksu should always ask for a password. Notice that this
+ * will only work when passwords are cached, as done by gnome-keyring
+ * for gksu's su mode and by sudo for gksu's sudo mode, but will have no
+ * effect if su or sudo are set up to not require the password at all.
+ */
+void
+gksu_context_set_always_ask_password (GksuContext *context, gboolean value)
+{
+ context->always_ask_password = value;
+}
+
+/**
+ * gksu_context_get_always_ask_password:
+ * @context: the #GksuContext you want to ask whether a grab will be done.
+ *
+ * Returns TRUE if gksu has been asked to always ask for a password
+ * (even if sudo or gnome-keyring have cached it)
+ *
+ * Returns: TRUE if yes, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_always_ask_password (GksuContext *context)
+{
+ return context->always_ask_password;
+}
+
+
+/**
+ * gksu_context_set_launcher_context:
+ * @context: the #GksuContext you want to set the sn context in
+ * @sn_context: the #SnLauncherContext you want to set
+ *
+ * Tell libgksu to use the given #SnLauncherContext for startup notification.
+ * Currently the library will use this to set DESKTOP_STARTUP_ID in the
+ * environment of the child and to issue initiate and complete events.
+ * Notice that you don't need to use this function unless you want to
+ * override gksu's default behavior on startup notification, since the
+ * library will create its own context.
+ *
+ * Returns: the #SnLauncherContext which is set, or NULL if none was set
+ */
+void
+gksu_context_set_launcher_context (GksuContext *context,
+ SnLauncherContext *sn_context)
+{
+ if (context->sn_context)
+ sn_launcher_context_unref (context->sn_context);
+ context->sn_context = sn_context;
+}
+
+/**
+ * gksu_context_get_launcher_context:
+ * @context: the #GksuContext you want to get the sn context from
+ *
+ * Gets the current startup notification launcher context
+ *
+ * Returns: the #SnLauncherContext which is set, or NULL if none was set
+ */
+SnLauncherContext*
+gksu_context_get_launcher_context (GksuContext *context)
+{
+ return context->sn_context;
+}
+
+/**
+ * gksu_context_set_launcher_id:
+ * @context: the #GksuContext you want to set the sn id in
+ * @sn_context: the sn_id you want to set, as a #gchar
+ */
+void
+gksu_context_set_launcher_id (GksuContext *context,
+ gchar *sn_id)
+{
+ if (context->sn_id)
+ g_free (context->sn_id);
+ context->sn_id = g_strdup(sn_id);
+}
+
+/**
+ * gksu_context_launch_initiate:
+ * @context: the #GksuContext you want to initiate the launch for
+ *
+ * Initiates the launch, as far as Startup Notification is concerned;
+ * This will only be used internally, usually.
+ */
+static void
+gksu_context_launch_initiate (GksuContext *context)
+{
+ gchar *sid = NULL;
+ guint32 launch_time = gdk_x11_display_get_user_time ((GdkDisplay*)GDK_DISPLAY());
+ static gboolean initiated = FALSE;
+
+ if (!initiated)
+ initiated = TRUE;
+ else
+ return;
+
+ sn_launcher_context_initiate (context->sn_context,
+ g_get_prgname (),
+ gksu_context_get_command (context),
+ launch_time);
+
+ sid = g_strdup_printf ("%s", sn_launcher_context_get_startup_id (context->sn_context));
+ gksu_context_set_launcher_id (context, sid);
+
+ if (context->debug)
+ fprintf (stderr, "STARTUP_ID: %s\n", sid);
+ setenv ("DESKTOP_STARTUP_ID", sid, TRUE);
+ g_free(sid);
+}
+
+/**
+ * gksu_context_launch_complete:
+ * @context: the #GksuContext you want to complete the launch for
+ *
+ * Completes the launch, as far as Startup Notification is concerned;
+ * This will only be used internally, usually.
+ */
+static void
+gksu_context_launch_complete (GksuContext *context)
+{
+ sn_launcher_context_complete(context->sn_context);
+}
+
+/**
+ * gksu_context_set_debug:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if debuging information should be printed.
+ */
+void
+gksu_context_set_debug (GksuContext *context, gboolean value)
+{
+ context->debug = value;
+}
+
+/**
+ * gksu_context_get_debug:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the library is configured to print debuging
+ * information.
+ *
+ * Returns: TRUE if it is, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_debug (GksuContext *context)
+{
+ return context->debug;
+}
+
+/**
+ * gksu_context_free
+ * @context: the #GksuContext to be freed.
+ *
+ * Frees the given #GksuContext.
+ */
+void
+gksu_context_free (GksuContext *context)
+{
+ g_free (context->xauth);
+ g_free (context->dir);
+ g_free (context->display);
+
+ g_object_unref (context->gconf_client);
+
+ g_free (context->description);
+ g_free (context->message);
+
+ g_free (context->user);
+ g_free (context->command);
+
+ g_free (context);
+}
+
+/**
+ * gksu_context_ref
+ * @context: A #GksuContext struct.
+ *
+ * Increments the reference count of the given #GksuContext.
+ */
+GksuContext*
+gksu_context_ref (GksuContext *context)
+{
+ context->ref_count++;
+ return context;
+}
+
+/**
+ * gksu_context_unref
+ * @context: A #GksuContext struct.
+ *
+ * Decrements the reference count of the given #GksuContext struct,
+ * freeing it if the reference count falls to zero.
+ */
+void
+gksu_context_unref (GksuContext *context)
+{
+ if (--context->ref_count == 0)
+ {
+ gksu_context_free (context);
+ }
+}
+
+GType
+gksu_context_get_type (void)
+{
+ static GType type_gksu_context = 0;
+
+ if (!type_gksu_context)
+ type_gksu_context = g_boxed_type_register_static
+ ("GksuContext",
+ (GBoxedCopyFunc) gksu_context_ref,
+ (GBoxedFreeFunc) gksu_context_unref);
+
+ return type_gksu_context;
+}
+
+
+/**
+ * gksu_su_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_su_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument. You should
+ * check the documentation for gksu_su_fuller for information about
+ * the arguments.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_su_full (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ GError **error)
+{
+ return gksu_su_fuller(context,
+ ask_pass, ask_pass_data,
+ pass_not_needed, pass_not_needed_data,
+ NULL, error);
+}
+
+
+/**
+ * gksu_su_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This could be considered one of the main functions in GKSu.
+ * it is responsible for doing the 'user changing' magic calling
+ * the #GksuAskPassFunc function to request a password if needed.
+ * and the #GksuPassNotNeededFunc function if a password won't be
+ * needed, so the application has the oportunity of warning the user
+ * what it's doing.
+ *
+ * This function uses su as backend.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_su_fuller (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ gint8 *exit_status,
+ GError **error)
+{
+ GQuark gksu_quark;
+ int i = 0;
+
+ gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
+
+ int fdpty;
+ pid_t pid;
+
+ context->sudo_mode = FALSE;
+
+ gksu_quark = g_quark_from_string (PACKAGE);
+
+ if (!context->command)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
+ _("gksu_run needs a command to be run, "
+ "none was provided."));
+ return FALSE;
+ }
+
+ if (!context->user)
+ context->user = g_strdup ("root");
+
+ if (!g_file_test (auxcommand, G_FILE_TEST_IS_EXECUTABLE))
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_HELPER,
+ _("The gksu-run-helper command was not found or "
+ "is not executable."));
+ return FALSE;
+ }
+
+ if (!prepare_xauth (context))
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
+ _("Unable to copy the user's Xauthorization file."));
+ return FALSE;
+ }
+
+ if (context->sn_context)
+ gksu_context_launch_initiate (context);
+
+ pid = forkpty(&fdpty, NULL, NULL, NULL);
+ if (pid == 0)
+ {
+ gchar **cmd = g_malloc (sizeof(gchar*)*7);
+
+ setsid(); // make us session leader
+ cmd[i] = g_strdup ("/bin/su"); i++;
+ if (context->login_shell)
+ {
+ cmd[i] = g_strdup ("-"); i++;
+ }
+ cmd[i] = g_strdup (context->user); i++;
+ if (context->keep_env)
+ {
+ cmd[i] = g_strdup ("-p"); i++;
+ }
+ cmd[i] = g_strdup ("-c"); i++;
+
+ /* needs to get X authorization prior to running the program */
+ cmd[i] = g_strdup_printf ("%s \"%s\"", auxcommand,
+ context->command); i++;
+
+ cmd[i] = NULL;
+
+ /* executes the command */
+ if (execv (cmd[0], cmd) == -1)
+ {
+ fprintf (stderr,
+ "Unable to run /bin/su: %s",
+ strerror(errno));
+ }
+
+ for (i = 0 ; cmd[i] != NULL ; i++)
+ g_free (cmd[i]);
+ g_free(cmd);
+ }
+ else if (pid == -1)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
+ _("Failed to fork new process: %s"),
+ strerror(errno));
+ return FALSE;
+ }
+ else
+ {
+ fd_set rfds;
+
+ struct timeval tv;
+
+ struct passwd *pwd = NULL;
+ gint target_uid = -1;
+ gint my_uid = 0;
+
+ gchar buf[256] = {0};
+ gint status;
+
+ gchar *password = NULL;
+ gchar *cmdline = NULL;
+ gboolean password_needed = FALSE;
+ gboolean used_gnome_keyring = FALSE;
+
+ my_uid = getuid();
+ pwd = getpwnam (context->user);
+ if (pwd)
+ target_uid = pwd->pw_uid;
+
+ if (ask_pass == NULL)
+ {
+ ask_pass = su_ask_password;
+ }
+
+ if (pass_not_needed == NULL)
+ {
+ pass_not_needed = no_pass;
+ }
+
+ /* no need to ask for password if we're already root */
+ if (my_uid != target_uid && my_uid)
+ {
+ gint count;
+ struct termios tio;
+
+ read (fdpty, buf, 255);
+ if (context->debug)
+ fprintf (stderr, "gksu_context_run: buf: -%s-\n", buf);
+
+ /* make sure we notice that ECHO is turned off, if it gets
+ turned off */
+ tcgetattr (fdpty, &tio);
+ for (count = 0; (tio.c_lflag & ECHO) && count < 15; count++)
+ {
+ usleep (1000);
+ tcgetattr (fdpty, &tio);
+ }
+
+ if (!(tio.c_lflag & ECHO))
+ {
+ gboolean prompt_grab;
+ prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
+ NULL);
+
+ if (prompt_grab)
+ gksu_prompt_grab (context);
+
+ /* try to get the password from the GNOME Keyring first, but
+ * only if we have not been requested to always ask for the
+ * password
+ */
+ if (!context->always_ask_password)
+ password = get_gnome_keyring_password (context);
+ if (password == NULL)
+ {
+ password = ask_pass (context, buf, ask_pass_data, error);
+ if (context->debug)
+ {
+ fprintf (stderr, "no password on keyring\n");
+ if (password == NULL)
+ fprintf (stderr, "no password from ask_pass!\n");
+ }
+ }
+ else
+ {
+ if (context->debug)
+ fprintf (stderr, "password from keyring found\n");
+ used_gnome_keyring = TRUE;
+ }
+ if (password == NULL || (error && (*error)))
+ {
+ if (context->debug)
+ fprintf (stderr, "gksu_su_full: problem getting password - getting out\n");
+ if (context->debug && error)
+ fprintf (stderr, "error: %s\n", (*error)->message);
+ nullify_password (password);
+ return TRUE;
+ }
+
+ write (fdpty, password, strlen(password) + 1);
+ write (fdpty, "\n", 1);
+ password_needed = TRUE;
+ }
+ }
+
+ if (context->debug)
+ fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
+ if (strncmp (buf, "gksu", 4) && strncmp (buf, "su", 2))
+ {
+ /* drop the \n echoed on password entry if su did request
+ a password */
+ if (password_needed)
+ read (fdpty, buf, 255);
+ if (context->debug)
+ fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
+ read (fdpty, buf, 255);
+ if (context->debug)
+ fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
+ }
+
+ FD_ZERO (&rfds);
+ FD_SET (fdpty, &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ int loop_count = 0;
+ while (TRUE)
+ {
+ int retval = 0;
+
+ if (!strncmp (buf, "su", 2))
+ {
+ gchar **strings;
+
+ if (password)
+ {
+ nullify_password (password);
+ unset_gnome_keyring_password (context);
+ }
+
+ strings = g_strsplit (buf, ":", 2);
+ if (strings[1] && !strncmp (strings[1], " Authentication failure", 23))
+ {
+ if (used_gnome_keyring)
+ g_set_error (error, gksu_quark,
+ GKSU_ERROR_WRONGAUTOPASS,
+ _("Wrong password got from keyring."));
+ else
+ g_set_error (error, gksu_quark,
+ GKSU_ERROR_WRONGPASS,
+ _("Wrong password."));
+ }
+ g_strfreev (strings);
+
+ if (context->debug)
+ fprintf (stderr, "DEBUG (auth_failed) buf: -%s-\n", buf);
+
+ break;
+ }
+ else if (!strncmp (buf, "gksu: waiting", 13))
+ {
+ gchar *line;
+
+ if (password)
+ {
+ set_gnome_keyring_password (context, password);
+ nullify_password (password);
+ }
+
+ if (context->debug)
+ fprintf (stderr, "DEBUG (gksu: waiting) buf: -%s-\n", buf);
+
+ line = g_strdup_printf ("gksu-run: %s\n", context->display);
+ write (fdpty, line, strlen(line));
+ g_free (line);
+
+ line = g_strdup_printf ("gksu-run: %s\n", context->sn_id);
+ write (fdpty, line, strlen(line));
+ g_free (line);
+
+ line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
+ write (fdpty, line, strlen(line));
+ g_free (line);
+
+ tcdrain (fdpty);
+
+ bzero (buf, 256);
+ read (fdpty, buf, 255);
+
+ break;
+ }
+
+ retval = select (fdpty + 1, &rfds, NULL, NULL, &tv);
+ if ((loop_count > 50) || (!retval))
+ {
+ gchar *emsg = NULL;
+ gchar *converted_str = NULL;
+ GError *converr = NULL;
+
+ if (password)
+ nullify_password (password);
+
+ converted_str = g_locale_to_utf8 (buf, -1, NULL, NULL, &converr);
+ if (converr)
+ {
+ g_warning (_("Failed to communicate with "
+ "gksu-run-helper.\n\n"
+ "Received:\n"
+ " %s\n"
+ "While expecting:\n"
+ " %s"), buf, "gksu: waiting");
+ emsg = g_strdup_printf (_("Failed to communicate with "
+ "gksu-run-helper.\n\n"
+ "Received bad string "
+ "while expecting:\n"
+ " %s"), "gksu: waiting");
+ g_error_free (converr);
+ }
+ else
+ emsg = g_strdup_printf (_("Failed to communicate with "
+ "gksu-run-helper.\n\n"
+ "Received:\n"
+ " %s\n"
+ "While expecting:\n"
+ " %s"), converted_str, "gksu: waiting");
+ g_free (converted_str);
+
+ g_set_error (error, gksu_quark, GKSU_ERROR_HELPER, emsg);
+ g_free (emsg);
+
+ if (context->debug)
+ fprintf (stderr, "DEBUG (failed!) buf: -%s-\n", buf);
+
+ return FALSE;
+ }
+ else if (retval == -1)
+ {
+ if (context->debug)
+ fprintf (stderr, "DEBUG (select failed!) buf: %s\n", buf);
+ return FALSE;
+ }
+
+ read (fdpty, buf, 255);
+ if (context->debug)
+ fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
+ loop_count++;
+ }
+
+ if (!password_needed || used_gnome_keyring)
+ {
+ gboolean should_display;
+
+ should_display = gconf_client_get_bool (context->gconf_client,
+ BASE_PATH "display-no-pass-info", NULL);
+
+ /* configuration tells us to show this message */
+ if (should_display)
+ {
+ if (context->debug)
+ fprintf (stderr, "Calling pass_not_needed window...\n");
+ pass_not_needed (context, pass_not_needed_data);
+ /* make sure it is displayed */
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ }
+ }
+
+ cmdline = g_strdup("bin/su");
+ /* wait for the child process to end or become something other
+ than su */
+ pid_t pid_exited;
+ while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
+ (g_str_has_suffix(cmdline, "bin/su")))
+ {
+ if (cmdline)
+ g_free (cmdline);
+ cmdline = get_process_name (pid);
+ usleep(100000);
+ }
+
+ if (context->sn_context)
+ gksu_context_launch_complete (context);
+
+ bzero(buf, 256);
+ while (read (fdpty, buf, 255) > 0)
+ {
+ fprintf (stderr, "%s", buf);
+ bzero(buf, 256);
+ }
+
+ if (pid_exited != pid)
+ waitpid(pid, &status, 0);
+
+ if (exit_status)
+ {
+ if (WIFEXITED(status)) {
+ *exit_status = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ *exit_status = -1;
+ }
+ }
+
+ if (WEXITSTATUS(status))
+ {
+ if(cmdline)
+ {
+ /* su already exec()ed something else, don't report
+ * exit status errors in that case
+ */
+ if (!g_str_has_suffix (cmdline, "su"))
+ {
+ g_free (cmdline);
+ return FALSE;
+ }
+ g_free (cmdline);
+ }
+
+ if (error == NULL)
+ g_set_error (error, gksu_quark,
+ GKSU_ERROR_CHILDFAILED,
+ _("su terminated with %d status"),
+ WEXITSTATUS(status));
+ }
+ }
+
+ if (error)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * gksu_su
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_su_run_full. It will call it
+ * without giving the callback functions, which leads to the standard
+ * ones being called. A simple #GksuContext is created to hold the
+ * user name and the command.
+ *
+ * Returns: TRUE if all went well, FALSE if an error happend.
+ */
+gboolean
+gksu_su (gchar *command_line, GError **error)
+{
+ GksuContext *context = gksu_context_new ();
+ gboolean retval;
+
+ context->command = g_strdup (command_line);
+ context->user = g_strdup ("root");
+ retval = gksu_su_full (context,
+ NULL, NULL,
+ NULL, NULL,
+ error);
+ gksu_context_free (context);
+ return retval;
+}
+
+static void
+read_line (int fd, gchar *buffer, int n)
+{
+ gint counter = 0;
+ gchar tmp[2] = {0};
+
+ for (; counter < (n - 1); counter++)
+ {
+ read (fd, tmp, 1);
+ if (tmp[0] == '\n')
+ break;
+ buffer[counter] = tmp[0];
+ }
+ buffer[counter+1] = '\0';
+}
+
+/**
+ * gksu_sudo_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_sudo_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument. You should
+ * check the documentation for gksu_sudo_fuller for information about
+ * the arguments.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_sudo_full (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ GError **error)
+{
+ return gksu_sudo_fuller(context,
+ ask_pass, ask_pass_data,
+ pass_not_needed, pass_not_needed_data,
+ NULL, error);
+}
+
+/**
+ * gksu_sudo_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ *
+ * This could be considered one of the main functions in GKSu.
+ * it is responsible for doing the 'user changing' magic calling
+ * the #GksuAskPassFunc function to request a password if needed.
+ * and the #GksuPassNotNeededFunc function if a password won't be
+ * needed, so the application has the oportunity of warning the user
+ * what it's doing.
+ *
+ * This function uses the sudo backend.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_sudo_fuller (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ gint8 *exit_status,
+ GError **error)
+{
+ char **cmd;
+ char buffer[256] = {0};
+ int argcount = 8;
+ int i, j;
+
+ GQuark gksu_quark;
+
+ gchar *xauth = NULL,
+ *xauth_env = NULL;
+
+ pid_t pid;
+ int status;
+ FILE *infile, *outfile;
+ int parent_pipe[2]; /* For talking to the parent */
+ int child_pipe[2]; /* For talking to the child */
+
+ context->sudo_mode = TRUE;
+
+ gksu_quark = g_quark_from_string (PACKAGE);
+
+ if (!context->command)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
+ _("gksu_sudo_run needs a command to be run, "
+ "none was provided."));
+ return FALSE;
+ }
+
+ if (!context->user)
+ context->user = g_strdup ("root");
+
+ if (ask_pass == NULL)
+ {
+ if (context->debug)
+ fprintf (stderr, "No ask_pass set, using default!\n");
+ ask_pass = su_ask_password;
+ }
+ if (pass_not_needed == NULL)
+ {
+ pass_not_needed = no_pass;
+ }
+
+ if (context->always_ask_password)
+ {
+ gint exit_status;
+ g_spawn_command_line_sync("/usr/bin/sudo -K", NULL, NULL, &exit_status, NULL);
+ }
+
+
+ /*
+ FIXME: need to set GError in a more detailed way
+ */
+ if (!sudo_prepare_xauth (context))
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
+ _("Unable to copy the user's Xauthorization file."));
+ return FALSE;
+ }
+
+ /* sets XAUTHORITY */
+ xauth = g_strdup_printf ("%s/.Xauthority", context->dir);
+ xauth_env = getenv ("XAUTHORITY");
+ setenv ("XAUTHORITY", xauth, TRUE);
+ if (context->debug)
+ fprintf (stderr, "xauth: %s\n", xauth);
+
+ /* set startup id */
+ if (context->sn_context)
+ gksu_context_launch_initiate (context);
+
+ cmd = g_new (gchar *, argcount + 1);
+
+ argcount = 0;
+
+ /* sudo binary */
+ cmd[argcount] = g_strdup("/usr/bin/sudo");
+ argcount++;
+
+ if (!context->keep_env)
+ {
+ /* Make sudo set $HOME */
+ cmd[argcount] = g_strdup("-H");
+ argcount++;
+ }
+
+ /* Make sudo read from stdin */
+ cmd[argcount] = g_strdup("-S");
+ argcount++;
+
+ /* Make sudo use next arg as prompt */
+ cmd[argcount] = g_strdup("-p");
+ argcount++;
+
+ /* prompt */
+ cmd[argcount] = g_strdup("GNOME_SUDO_PASS");
+ argcount++;
+
+ /* Make sudo use the selected user */
+ cmd[argcount] = g_strdup("-u");
+ argcount++;
+
+ /* user */
+ cmd[argcount] = g_strdup(context->user);
+ argcount++;
+
+ /* sudo does not understand this if we do not use -H
+ weird.
+ */
+ if (!context->keep_env)
+ {
+ /* Make sudo stop processing options */
+ cmd[argcount] = g_strdup("--");
+ argcount++;
+ }
+
+ {
+ gchar *tmp_arg = g_malloc (sizeof(gchar)*1);
+ gboolean inside_quotes = FALSE;
+
+ tmp_arg[0] = '\0';
+
+ for (i = j = 0; ; i++)
+ {
+ if ((context->command[i] == '\'') && (context->command[i-1] != '\\'))
+ {
+ i = i + 1;
+ inside_quotes = !inside_quotes;
+ }
+
+ if ((context->command[i] == ' ' && inside_quotes == FALSE)
+ || context->command[i] == '\0')
+ {
+ tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
+ tmp_arg[j] = '\0';
+ cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
+ cmd[argcount] = g_strdup (tmp_arg);
+
+ g_free (tmp_arg);
+
+ argcount = argcount + 1;
+ j = 0;
+
+ if (context->command[i] == '\0')
+ break;
+
+ tmp_arg = g_malloc (sizeof(gchar)*1);
+ tmp_arg[0] = '\0';
+ }
+ else
+ {
+ if (context->command[i] == '\\' && context->command[i+1] != '\\')
+ i = i + 1;
+ tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
+ tmp_arg[j] = context->command[i];
+ j = j + 1;
+ }
+ }
+ }
+ cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
+ cmd[argcount] = NULL;
+
+ if (context->debug)
+ {
+ for (i = 0; cmd[i] != NULL; i++)
+ fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
+ }
+
+ if ((pipe(parent_pipe)) == -1)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+ _("Error creating pipe: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+
+ if ((pipe(child_pipe)) == -1)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+ _("Error creating pipe: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+
+ pid = fork();
+ if (pid == -1)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
+ _("Failed to fork new process: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+ else if (pid == 0)
+ {
+ // Child
+ setsid(); // make us session leader
+ close(child_pipe[1]);
+ dup2(child_pipe[0], STDIN_FILENO);
+ dup2(parent_pipe[1], STDERR_FILENO);
+
+ execv(cmd[0], cmd);
+
+ g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
+ _("Failed to exec new process: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+ else
+ {
+ gint counter = 0;
+ gchar *cmdline = NULL;
+
+ // Parent
+ close(parent_pipe[1]);
+
+ infile = fdopen(parent_pipe[0], "r");
+ if (!infile)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+ _("Error opening pipe: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+
+ outfile = fdopen(child_pipe[1], "w");
+ if (!outfile)
+ {
+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+ _("Error opening pipe: %s"),
+ strerror(errno));
+ sudo_reset_xauth (context, xauth, xauth_env);
+ return FALSE;
+ }
+
+ /*
+ we are expecting to receive a GNOME_SUDO_PASS
+ if we don't there are two possibilities: an error
+ or a password is not needed
+ */
+ fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
+
+ { /* no matter if we can read, since we're using
+ O_NONBLOCK; this is just to avoid the prompt
+ showing up after the read */
+ fd_set rfds;
+ struct timeval tv;
+
+ FD_ZERO(&rfds);
+ FD_SET(parent_pipe[0], &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
+ }
+
+ /* Try hard to find the prompt; it may happen that we're
+ * seeing sudo's lecture, or that some pam module is spitting
+ * debugging stuff at the screen
+ */
+ for (counter = 0; counter < 50; counter++)
+ {
+ if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
+ break;
+
+ read_line (parent_pipe[0], buffer, 256);
+
+ if (context->debug)
+ fprintf (stderr, "buffer: -%s-\n", buffer);
+
+ usleep(1000);
+ }
+
+ if (context->debug)
+ fprintf (stderr, "brute force GNOME_SUDO_PASS ended...\n");
+
+ if (strncmp(buffer, "GNOME_SUDO_PASS", 15) == 0)
+ {
+ gchar *password = NULL;
+ gboolean prompt_grab;
+
+ if (context->debug)
+ fprintf (stderr, "Yeah, we're in...\n");
+
+ prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
+ NULL);
+ if (prompt_grab)
+ gksu_prompt_grab (context);
+
+ password = ask_pass (context, _("Password: "),
+ ask_pass_data, error);
+ if (password == NULL || (*error))
+ {
+ nullify_password (password);
+ return FALSE;
+ }
+
+ usleep (1000);
+
+ fprintf (outfile, "%s\n", password);
+ fclose (outfile);
+
+ nullify_password (password);
+
+ /* turn NONBLOCK off */
+ fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
+ /* ignore the first newline that comes right after sudo receives
+ the password */
+ fgets (buffer, 255, infile);
+ /* this is the status we are interessted in */
+ fgets (buffer, 255, infile);
+ }
+ else
+ {
+ gboolean should_display;
+ if (context->debug)
+ fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
+
+ /* turn NONBLOCK off, also if have no prompt */
+ fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
+
+ should_display = gconf_client_get_bool (context->gconf_client,
+ BASE_PATH "display-no-pass-info", NULL);
+
+ /* configuration tells us to show this message */
+ if (should_display)
+ {
+ if (context->debug)
+ fprintf (stderr, "Calling pass_not_needed window...\n");
+ pass_not_needed (context, pass_not_needed_data);
+ /* make sure it is displayed */
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ }
+
+ fprintf (stderr, "%s", buffer);
+ }
+
+ if (!strcmp (buffer, "Sorry, try again.\n"))
+ g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
+ _("Wrong password."));
+ else if (!strncmp (buffer, "Sorry, user ", 12))
+ g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
+ _("The underlying authorization mechanism (sudo) "
+ "does not allow you to run this program. Contact "
+ "the system administrator."));
+ else
+ {
+ gchar *haystack = buffer;
+ gchar *needle;
+
+ needle = g_strstr_len (haystack, strlen (haystack), " ");
+ if (needle && (needle + 1))
+ {
+ needle += 1;
+ if (!strncmp (needle, "is not in", 9))
+ g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
+ _("The underlying authorization mechanism (sudo) "
+ "does not allow you to run this program. Contact "
+ "the system administrator."));
+ }
+ }
+
+ cmdline = g_strdup("sudo");
+ /* wait for the child process to end or become something other
+ than sudo */
+ pid_t pid_exited;
+ while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
+ (g_str_has_suffix(cmdline, "sudo")))
+ {
+ if (cmdline)
+ g_free (cmdline);
+ cmdline = get_process_name (pid);
+ usleep(100000);
+ }
+
+ if (context->sn_context)
+ gksu_context_launch_complete (context);
+
+ while (read (parent_pipe[0], buffer, 255) > 0)
+ {
+ fprintf (stderr, "%s", buffer);
+ bzero(buffer, 256);
+ }
+
+ /* if the process is still active waitpid() on it */
+ if (pid_exited != pid)
+ waitpid(pid, &status, 0);
+ sudo_reset_xauth (context, xauth, xauth_env);
+
+ if (exit_status)
+ {
+ if (WIFEXITED(status)) {
+ *exit_status = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ *exit_status = -1;
+ }
+ }
+
+ if (WEXITSTATUS(status))
+ {
+ if(cmdline)
+ {
+ /* sudo already exec()ed something else, don't report
+ * exit status errors in that case
+ */
+ if (!g_str_has_suffix (cmdline, "sudo"))
+ {
+ g_free (cmdline);
+ return FALSE;
+ }
+ g_free (cmdline);
+ }
+ if (error == NULL)
+ g_set_error (error, gksu_quark,
+ GKSU_ERROR_CHILDFAILED,
+ _("sudo terminated with %d status"),
+ WEXITSTATUS(status));
+ }
+ }
+
+ /* if error is set we have found an error condition */
+ if (error)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * gksu_sudo
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_sudo_run_full. It will call it
+ * without giving the callback functions, which leads to the standard
+ * ones being called. A simple #GksuContext is created to hold the
+ * user name and the command.
+ *
+ * Returns: TRUE if all went well, FALSE if an error happend.
+ */
+gboolean
+gksu_sudo (gchar *command_line,
+ GError **error)
+{
+ GksuContext *context = gksu_context_new ();
+ gboolean retval;
+
+ context->command = g_strdup (command_line);
+ context->user = g_strdup ("root");
+ retval = gksu_sudo_full (context,
+ NULL, NULL,
+ NULL, NULL,
+ error);
+ gksu_context_free (context);
+
+ return retval;
+}
+
+/**
+ * gksu_run_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_run_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_run_full (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ GError **error)
+{
+ return gksu_run_fuller(context,
+ ask_pass, ask_pass_data,
+ pass_not_needed, pass_not_needed_data,
+ NULL, error);
+}
+
+/**
+ * gksu_run_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This function is a wrapper for gksu_sudo_full/gksu_su_full. It will
+ * call one of them, depending on the GConf key that defines whether
+ * the default behavior for gksu is su or sudo mode. This is the
+ * recommended way of using the library functionality.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_run_fuller (GksuContext *context,
+ GksuAskPassFunc ask_pass,
+ gpointer ask_pass_data,
+ GksuPassNotNeededFunc pass_not_needed,
+ gpointer pass_not_needed_data,
+ gint8 *exit_status,
+ GError **error)
+{
+ GConfClient *gconf_client;
+ gboolean sudo_mode;
+
+ gconf_client = gconf_client_get_default ();
+ sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+ NULL);
+ g_object_unref (gconf_client);
+
+ if (sudo_mode)
+ return gksu_sudo_fuller (context, ask_pass, ask_pass_data,
+ pass_not_needed, pass_not_needed_data,
+ exit_status, error);
+
+ return gksu_su_fuller (context, ask_pass, ask_pass_data,
+ pass_not_needed, pass_not_needed_data,
+ exit_status, error);
+}
+
+/**
+ * gksu_run
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_sudo/gksu_su. It will call one
+ * of them, depending on the GConf key that defines whether the default
+ * behavior for gksu is su or sudo mode. This is the recommended way of
+ * using the library functionality.
+ *
+ * Returns: FALSE if all went well, TRUE if an error happend.
+ */
+gboolean
+gksu_run (gchar *command_line,
+ GError **error)
+{
+ GConfClient *gconf_client;
+ gboolean sudo_mode;
+
+ gconf_client = gconf_client_get_default ();
+ sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+ NULL);
+ g_object_unref (gconf_client);
+
+ if (sudo_mode)
+ return gksu_sudo (command_line, error);
+
+ return gksu_su (command_line, error);
+}
+
+/**
+ * gksu_ask_password_full:
+ * @context: a #GksuContext
+ * @prompt: a prompt different from Password:
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This function uses the gksu infra-structure to request for a
+ * password, but instead of passing it to su or sudo to run a command
+ * it simply returns the password.
+ *
+ * Returns: a newly allocated string with the password;
+ */
+gchar*
+gksu_ask_password_full (GksuContext *context, gchar *prompt,
+ GError **error)
+{
+ gchar *ret_value = su_ask_password (context, _(prompt), NULL, error);
+ if (context->sn_context)
+ gksu_context_launch_complete (context);
+ return ret_value;
+}
+
+/**
+ * gksu_ask_password
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function uses the gksu infra-structure to request for a
+ * password, but instead of passing it to su or sudo to run a command
+ * it simply returns the password. This is just a convenience wrapper
+ * for gksu_ask_password_full.
+ *
+ * Returns: a newly allocated string with the password;
+ */
+gchar*
+gksu_ask_password (GError **error)
+{
+ GksuContext *context = gksu_context_new ();
+ gchar* retval;
+
+ context->user = g_strdup ("root");
+ retval = gksu_ask_password_full (context, NULL, error);
+ gksu_context_free (context);
+
+ return retval;
+}
More information about the gksu-commits
mailing list