1 Solaris uses the gtk unlock dialog program originally written by |
|
2 Ximian & Wipro, in order to provide a dialog box that works with |
|
3 the GNOME accessibility framework. This was done as a fork of |
|
4 the original xscreensaver because the maintainer would not allow |
|
5 use of a toolkit in the lock dialog - he has since softened his |
|
6 stance a bit, but this has not been presented to him to see if it |
|
7 meets his requirements as spelled out at: |
|
8 http://www.jwz.org/xscreensaver/toolkits.html |
|
9 |
|
10 This patch also contains fixes for: |
|
11 |
|
12 15134570 SUNBT4782515 user is prompted to enter PIN or password when screen |
|
13 is locked |
|
14 15134983 SUNBT4783832 No date on xscreensaver-lock and warning on screen |
|
15 15179562 SUNBT4931584 xscreensaver-demo cores with GTK_MODULES=gail:atk-bridge |
|
16 15209082 SUNBT5039876 "User:" should not look like an input field |
|
17 15209083 SUNBT5039878 "Password:" field should be focused / have flashing caret |
|
18 15214348 SUNBT5059445 pam service name, screen kb and screen reader support |
|
19 15220008 SUNBT5077989 Bug 147580: password input dialogue obscures GOK |
|
20 15220010 SUNBT5077993 Bug 147639: Gok cant automatically UI grab screensaver |
|
21 preferences |
|
22 15220705 SUNBT5079870 147587: password field should set ATK_ROLE_PASSWORD_TEXT |
|
23 15221761 SUNBT5083155 Unable to unlock screen when running dual head |
|
24 magnification |
|
25 15231258 SUNBT6176524 passwdTimeoutEnable for disabled user (xscreensaver-lock) |
|
26 15231818 SUNBT6178584 Xscreensaver needs to use ROLE_PASSWORD_TEXT |
|
27 15233078 SUNBT6182506 Screensaver dialog isn't magnified properly |
|
28 15239418 SUNBT6203951 xscreensaver lockscreen translation errors for fr_FR |
|
29 15252945 SUNBT6237901 Ldap and Gnome xscreensaver authentication failure |
|
30 15265442 SUNBT6269444 snv_14 xscreensaver prints out gratuitous debug messages |
|
31 after authentication |
|
32 15280862 SUNBT6308859 xscreensaver: password lock dialog is not localized |
|
33 15295912 SUNBT6346056 xscreensaver should not enable input method |
|
34 15317555 SUNBT6395649 at-spi-registryd starts when screen is locked even when |
|
35 accessible device support is off |
|
36 15326852 SUNBT6417168 xscreensaver loops while trying to unlock a session for |
|
37 a user whose password was expired |
|
38 15346556 SUNBT6461887 GNOME screen lock does not prevent access to other |
|
39 applications via 'alt-tab' |
|
40 15352585 SUNBT6475285 xscreensaver core dumps in kill_job() after unlocking |
|
41 the screen |
|
42 15354012 SUNBT6478362 When the AT support is enabled, the input focus is |
|
43 located at password label |
|
44 15356879 SUNBT6484604 X should stop linking against -lcmd |
|
45 15375976 SUNBT6520014 possible mem. leak in xscreensaver's lock.c in s11/nv |
|
46 15387793 SUNBT6541240 Screen saver will lock user out of the system if they |
|
47 have no password set |
|
48 15405753 SUNBT6573182 after applying patch 120094-11(or later), xscreensaver |
|
49 core dump |
|
50 15427168 SUNBT6611183 xscreensaver needs to put Sun logos in files loaded at |
|
51 runtime |
|
52 15461985 SUNBT6670025 xscreensaver passwd dialog image missing in nv_85 |
|
53 15462355 SUNBT6670659 password dialog window remains on the screen even after |
|
54 screen is unlocked |
|
55 15463666 SUNBT6673036 prepare for Indiana unlock logos |
|
56 15500787 SUNBT6736157 Security problem when desktop a11y support is turned on |
|
57 15521700 SUNBT6769901 popup windows appearing through xscreensaver |
|
58 15553552 SUNBT6825374 xscreensaver issues under Xorg |
|
59 15561643 SUNBT6839026 Regression in screensaver may cause Performance |
|
60 Degradation and make locked screensaver unresponsive |
|
61 15565807 SUNBT6845751 xscreensaver-lock chews CPU when daemon dies while unlock |
|
62 dialog is up |
|
63 15568147 SUNBT6849124 xscreensaver leaves a dialog that cannot be moved/closed |
|
64 after password change warning |
|
65 15573881 SUNBT6857559 Nevada build was broken because of 6849124 |
|
66 --- |
|
67 config.h.in | 3 + |
|
68 configure.in | 23 +- |
|
69 driver/Makefile.in | 59 +++- |
|
70 driver/auth.h | 4 + |
|
71 driver/demo-Gtk.c | 18 + |
|
72 driver/dialog-data.h | 131 ++++++ |
|
73 driver/lock-Gtk.c | 955 +++++++++++++++++++++++++++++++++++++++++++ |
|
74 driver/lock.c | 1083 ++++++++++++++++++++++++++++++++++++++++++++----- |
|
75 driver/passwd-pam.c | 207 +++++++++- |
|
76 driver/passwd.c | 1 + |
|
77 driver/setuid.c | 5 +- |
|
78 driver/subprocs.c | 35 ++- |
|
79 driver/timers.c | 110 +++++- |
|
80 driver/types.h | 18 + |
|
81 driver/windows.c | 21 +- |
|
82 driver/xscreensaver.c | 131 ++++++- |
|
83 driver/xscreensaver.h | 6 + |
|
84 17 files changed, 2663 insertions(+), 147 deletions(-) |
|
85 create mode 100644 driver/dialog-data.h |
|
86 create mode 100644 driver/lock-Gtk.c |
|
87 |
|
88 diff --git a/config.h.in b/config.h.in |
|
89 --- a/config.h.in |
|
90 +++ b/config.h.in |
|
91 @@ -384,6 +384,9 @@ |
|
92 make use of this if it is available. */ |
|
93 #undef HAVE_XPM |
|
94 |
|
95 +/* Define this to build the external lock dialog */ |
|
96 +#undef HAVE_XSCREENSAVER_LOCK |
|
97 + |
|
98 /* Define this if you have the X Shared Memory Extension. */ |
|
99 #undef HAVE_XSHM_EXTENSION |
|
100 |
|
101 diff --git a/configure.in b/configure.in |
|
102 --- a/configure.in |
|
103 +++ b/configure.in |
|
104 @@ -2531,6 +2531,8 @@ if test "$with_gtk" = yes; then |
|
105 pkg_check_version libglade-2.0 1.99.0 |
|
106 pkg_check_version gdk-pixbuf-2.0 2.0.0 |
|
107 pkg_check_version gdk-pixbuf-xlib-2.0 2.0.0 |
|
108 + pkg_check_version gconf-2.0 2.6.1 |
|
109 + pkg_check_version libloginhelper-1.0 1.0 |
|
110 have_gtk="$ok" |
|
111 |
|
112 if test "$have_gtk" = no; then |
|
113 @@ -2546,6 +2548,9 @@ if test "$with_gtk" = yes; then |
|
114 fi |
|
115 |
|
116 if test "$have_gtk" = yes; then |
|
117 +#--- Begin SUNW addition |
|
118 + AC_DEFINE(HAVE_XSCREENSAVER_LOCK,[],[Define this to build the external lock dialog]) |
|
119 +#--- End SUNW addition |
|
120 AC_CACHE_CHECK([for Gtk includes], ac_cv_gtk_config_cflags, |
|
121 [ac_cv_gtk_config_cflags=`$pkg_config --cflags $pkgs`]) |
|
122 AC_CACHE_CHECK([for Gtk libs], ac_cv_gtk_config_libs, |
|
123 @@ -3642,6 +3647,16 @@ if test "$have_gtk" = yes; then |
|
124 ALL_DEMO_PROGRAMS="$PREFERRED_DEMO_PROGRAM $ALL_DEMO_PROGRAMS" |
|
125 fi |
|
126 |
|
127 +#--- Begin SUNW addition |
|
128 +PREFERRED_LOCK_PROGRAM= |
|
129 +ALL_LOCK_PROGRAMS= |
|
130 +LOCK_PROGRAM= |
|
131 +if test "$have_gtk" = yes; then |
|
132 + PREFERRED_LOCK_PROGRAM=xscreensaver-lock-Gtk |
|
133 + ALL_LOCK_PROGRAMS="$PREFERRED_LOCK_PROGRAM $ALL_LOCK_PROGRAMS" |
|
134 + LOCK_PROGRAM=xscreensaver-lock |
|
135 +fi |
|
136 +#--- End SUNW addition |
|
137 |
|
138 if test "$have_kerberos" = yes; then |
|
139 PASSWD_SRCS="$PASSWD_SRCS \$(KERBEROS_SRCS)" |
|
140 @@ -3781,6 +3796,11 @@ AC_SUBST(INCLUDES) |
|
141 |
|
142 AC_SUBST(PREFERRED_DEMO_PROGRAM) |
|
143 AC_SUBST(ALL_DEMO_PROGRAMS) |
|
144 +#--- Begin SUNW addition |
|
145 +AC_SUBST(PREFERRED_LOCK_PROGRAM) |
|
146 +AC_SUBST(ALL_LOCK_PROGRAMS) |
|
147 +AC_SUBST(LOCK_PROGRAM) |
|
148 +#--- End SUNW addition |
|
149 AC_SUBST(SAVER_LIBS) |
|
150 AC_SUBST(MOTIF_LIBS) |
|
151 AC_SUBST(GTK_LIBS) |
|
152 @@ -4260,7 +4280,8 @@ HACK_CONF_DIR=`echo "${HACK_CONF_DIR}" | sed 's@/$@@;s@//*@/@g'` |
|
153 |
|
154 |
|
155 # Sanity check the hackdir |
|
156 -for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command ; do |
|
157 +# SUNW addition: added xscreensaver-lock to list on next line |
|
158 +for bad_choice in xscreensaver xscreensaver-demo xscreensaver-command xscreensaver-lock ; do |
|
159 if test "${HACKDIR}" = "${bindir}/${bad_choice}" ; then |
|
160 echo "" |
|
161 AC_MSG_ERROR([\"--with-hackdir=${bindir}/${bad_choice}\" won't work. |
|
162 diff --git a/driver/Makefile.in b/driver/Makefile.in |
|
163 --- a/driver/Makefile.in |
|
164 +++ b/driver/Makefile.in |
|
165 @@ -29,6 +29,7 @@ GTK_APPDIR = $(GTK_DATADIR)/applications |
|
166 GTK_ICONDIR = $(GTK_DATADIR)/pixmaps |
|
167 GTK_GLADEDIR = $(prefix)/lib/xscreensaver/config |
|
168 HACK_CONF_DIR = @HACK_CONF_DIR@ |
|
169 +LOCK_DIR = $(libexecdir) |
|
170 |
|
171 CC = @CC@ |
|
172 OBJCC = @OBJCC@ |
|
173 @@ -42,6 +43,7 @@ SUBP_DEFS = $(DEFS) -DHACK_PATH='"@HACKDIR@"' \ |
|
174 GTK_DEFS = $(DEFS) -DDEFAULT_ICONDIR='"$(GTK_GLADEDIR)"' \ |
|
175 -DBINDIR='"$(bindir)"' |
|
176 CONF_DEFS = -DHACK_CONFIGURATION_PATH='"$(HACK_CONF_DIR)"' |
|
177 +LOCK_DEFS = $(DEFS) -DLOCKDIR=\"$(LOCK_DIR)\" |
|
178 |
|
179 LIBS = @LIBS@ |
|
180 INTL_LIBS = @INTLLIBS@ |
|
181 @@ -100,6 +102,8 @@ GTK_SRCS = demo-Gtk.c demo-Gtk-conf.c \ |
|
182 demo-Gtk-widgets.c demo-Gtk-support.c |
|
183 GTK_EXTRA_OBJS = demo-Gtk-widgets.o demo-Gtk-support.o |
|
184 GTK_OBJS = demo-Gtk.o demo-Gtk-conf.o @GTK_EXTRA_OBJS@ |
|
185 +GTK_LOCK_SRCS = lock-Gtk.c atoms.c remote.c |
|
186 +GTK_LOCK_OBJS = lock-Gtk.o atoms.o remote.o |
|
187 |
|
188 PWENT_SRCS = passwd-pwent.c |
|
189 PWENT_OBJS = passwd-pwent.o |
|
190 @@ -219,8 +223,8 @@ GETIMG_LIBS = $(LIBS) $(X_LIBS) $(XPM_LIBS) $(JPEG_LIBS) \ |
|
191 $(X_PRE_LIBS) -lXt -lX11 $(XMU_LIBS) -lXext $(X_EXTRA_LIBS) |
|
192 |
|
193 EXES = xscreensaver xscreensaver-command xscreensaver-demo \ |
|
194 - xscreensaver-getimage @EXES_OSX@ |
|
195 -EXES2 = @ALL_DEMO_PROGRAMS@ |
|
196 + xscreensaver-getimage @EXES_OSX@ @LOCK_PROGRAM@ |
|
197 +EXES2 = @ALL_DEMO_PROGRAMS@ @ALL_LOCK_PROGRAMS@ |
|
198 EXES_OSX = pdf2jpeg |
|
199 |
|
200 SCRIPTS_1 = xscreensaver-getimage-file xscreensaver-getimage-video \ |
|
201 @@ -250,7 +254,7 @@ VMSFILES = compile_axp.com compile_decc.com link_axp.com link_decc.com \ |
|
202 vms-getpwnam.c vms-pwd.h vms-hpwd.c vms-validate.c \ |
|
203 vms_axp.opt vms_axp_12.opt vms_decc.opt vms_decc_12.opt |
|
204 |
|
205 -TARFILES = $(EXTRAS) $(VMSFILES) $(SAVER_SRCS_1) \ |
|
206 +TARFILES = $(EXTRAS) $(VMSFILES) $(SAVER_SRCS_1) $(GTK_LOCK_SRCS) \ |
|
207 $(MOTIF_SRCS) $(GTK_SRCS) $(PWENT_SRCS) $(PWHELPER_SRCS) \ |
|
208 $(KERBEROS_SRCS) $(PAM_SRCS) $(LOCK_SRCS_1) $(DEMO_SRCS_1) \ |
|
209 $(CMD_SRCS) $(GETIMG_SRCS_1) $(PDF2JPEG_SRCS) $(HDRS) \ |
|
210 @@ -263,7 +267,7 @@ all: $(EXES) $(EXES2) |
|
211 tests: $(TEST_EXES) |
|
212 |
|
213 install: install-program install-ad install-scripts \ |
|
214 - install-gnome install-man install-xml install-pam |
|
215 + install-gnome install-man install-xml |
|
216 uninstall: uninstall-program uninstall-ad \ |
|
217 uninstall-gnome uninstall-man uninstall-xml |
|
218 |
|
219 @@ -275,6 +279,9 @@ install-program: $(EXES) |
|
220 @if [ ! -d $(install_prefix)$(bindir) ]; then \ |
|
221 $(INSTALL_DIRS) $(install_prefix)$(bindir) ; \ |
|
222 fi |
|
223 + @if [ -n "@LOCK_PROGRAM@" -a ! -d $(install_prefix)$(LOCK_DIR) ]; then \ |
|
224 + $(INSTALL_DIRS) $(install_prefix)$(LOCK_DIR) ; \ |
|
225 + fi |
|
226 @inst="$(INSTALL_PROGRAM)" ; \ |
|
227 if [ @NEED_SETUID@ = yes ]; then \ |
|
228 me=`PATH="$$PATH:/usr/ucb" whoami` ; \ |
|
229 @@ -303,6 +310,12 @@ install-program: $(EXES) |
|
230 echo $(INSTALL_PROGRAM) $$exe $(install_prefix)$(bindir)/$$exe ; \ |
|
231 $(INSTALL_PROGRAM) $$exe $(install_prefix)$(bindir)/$$exe ; \ |
|
232 done |
|
233 + @if [ -n "@LOCK_PROGRAM@" ]; then \ |
|
234 + echo $(INSTALL_PROGRAM) xscreensaver-lock \ |
|
235 + $(install_prefix)$(LOCK_DIR)/xscreensaver-lock ; \ |
|
236 + $(INSTALL_PROGRAM) xscreensaver-lock \ |
|
237 + $(install_prefix)$(LOCK_DIR)/xscreensaver-lock ; \ |
|
238 + fi |
|
239 |
|
240 install-ad: XScreenSaver.ad |
|
241 @if [ ! -d $(install_prefix)$(AD_DIR) ]; then \ |
|
242 @@ -738,7 +751,7 @@ $(SAVER_UTIL_OBJS): |
|
243 |
|
244 # How we build object files in this directory. |
|
245 .c.o: |
|
246 - $(CC) -c $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $< |
|
247 + $(CC) -c $(INCLUDES) $(DEFS) $(INTL_DEFS) $(CFLAGS) $(X_CFLAGS) $< |
|
248 |
|
249 .m.o: |
|
250 $(OBJCC) -c $(INCLUDES) $(DEFS) $(CFLAGS) $(X_CFLAGS) $< |
|
251 @@ -764,6 +777,16 @@ demo-Gtk-conf.o: demo-Gtk-conf.c |
|
252 $(CC) -c $(INCLUDES) $(CONF_DEFS) $(GTK_DEFS) $(CFLAGS) $(X_CFLAGS) \ |
|
253 $(srcdir)/demo-Gtk-conf.c |
|
254 |
|
255 +# lock takes an extra -D option. |
|
256 +lock.o: |
|
257 + $(CC) -c $(INCLUDES) $(LOCK_DEFS) $(CFLAGS) $(X_CFLAGS) \ |
|
258 + $(srcdir)/lock.c |
|
259 + |
|
260 +# lock-Gtk takes extra -D and -I options. |
|
261 +lock-Gtk.o: lock-Gtk.c |
|
262 + $(CC) -c $(INCLUDES) -I$(ICON_SRC) $(GTK_DEFS) \ |
|
263 + $(CFLAGS) $(X_CFLAGS) $(INTL_DEFS) \ |
|
264 + $(srcdir)/lock-Gtk.c |
|
265 |
|
266 # How we build the default app-defaults file into the program. |
|
267 # |
|
268 @@ -778,7 +801,8 @@ XScreenSaver_Xm_ad.h: XScreenSaver-Xm.ad |
|
269 # The executables linked in this directory. |
|
270 # |
|
271 xscreensaver: $(SAVER_OBJS) |
|
272 - $(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) |
|
273 + $(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) \ |
|
274 + -lgconf-2 -lgobject-2.0 |
|
275 |
|
276 xscreensaver-command: $(CMD_OBJS) |
|
277 $(CC) $(LDFLAGS) -o $@ $(CMD_OBJS) $(CMD_LIBS) |
|
278 @@ -794,6 +818,15 @@ xscreensaver-demo: @PREFERRED_DEMO_PROGRAM@ |
|
279 cp -p @PREFERRED_DEMO_PROGRAM@@EXEEXT@ $@@EXEEXT@ ; \ |
|
280 fi |
|
281 |
|
282 +xscreensaver-lock: @PREFERRED_LOCK_PROGRAM@ |
|
283 + $(INSTALL_PROGRAM) @PREFERRED_LOCK_PROGRAM@ $@ |
|
284 + |
|
285 +xscreensaver-lock-Gtk: $(GTK_LOCK_OBJS) |
|
286 + $(CC) $(LDFLAGS) -o $@ $(GTK_LOCK_OBJS) $(LIBS) $(X_LIBS) \ |
|
287 + $(GTK_LIBS) $(XML_LIBS) $(X_PRE_LIBS) -lXt -lX11 \ |
|
288 + $(XDPMS_LIBS) -lXext \ |
|
289 + $(X_EXTRA_LIBS) |
|
290 + |
|
291 xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS) |
|
292 $(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(MOTIF_OBJS) $(LIBS) $(X_LIBS) \ |
|
293 $(MOTIF_LIBS) $(INTL_LIBS) $(X_PRE_LIBS) -lXt -lX11 \ |
|
294 @@ -817,7 +850,7 @@ pdf2jpeg: $(PDF2JPEG_OBJS) |
|
295 |
|
296 |
|
297 TEST_PASSWD_OBJS = test-passwd.o $(LOCK_OBJS_1) $(PASSWD_OBJS) \ |
|
298 - subprocs.o setuid.o splash.o prefs.o mlstring.o exec.o \ |
|
299 + subprocs.o setuid.o splash.o prefs.o mlstring.o \ |
|
300 $(SAVER_UTIL_OBJS) |
|
301 test-passwd.o: XScreenSaver_ad.h |
|
302 |
|
303 @@ -907,8 +940,14 @@ dpms.o: $(srcdir)/types.h |
|
304 dpms.o: $(srcdir)/xscreensaver.h |
|
305 exec.o: ../config.h |
|
306 exec.o: $(srcdir)/exec.h |
|
307 +lock-Gtk.o: $(srcdir)/atoms.h |
|
308 +lock-Gtk.o: ../config.h |
|
309 +lock-Gtk.o: $(srcdir)/remote.h |
|
310 +lock-Gtk.o: $(UTILS_SRC)/xscreensaver-intl.h |
|
311 lock.o: $(srcdir)/auth.h |
|
312 lock.o: ../config.h |
|
313 +lock.o: $(srcdir)/dialog-data.h |
|
314 +lock.o: $(srcdir)/exec.h |
|
315 lock.o: $(srcdir)/mlstring.h |
|
316 lock.o: $(srcdir)/prefs.h |
|
317 lock.o: $(srcdir)/types.h |
|
318 @@ -917,6 +956,8 @@ lock.o: $(srcdir)/xscreensaver.h |
|
319 mlstring.o: $(srcdir)/mlstring.h |
|
320 passwd.o: $(srcdir)/auth.h |
|
321 passwd.o: ../config.h |
|
322 +passwd.o: $(srcdir)/dialog-data.h |
|
323 +passwd.o: $(srcdir)/mlstring.h |
|
324 passwd.o: $(srcdir)/prefs.h |
|
325 passwd.o: $(srcdir)/types.h |
|
326 passwd.o: $(srcdir)/xscreensaver.h |
|
327 @@ -984,6 +1025,8 @@ test-vp.o: ../config.h |
|
328 test-xdpms.o: ../config.h |
|
329 test-xinerama.o: ../config.h |
|
330 timers.o: ../config.h |
|
331 +timers.o: $(srcdir)/dialog-data.h |
|
332 +timers.o: $(srcdir)/mlstring.h |
|
333 timers.o: $(srcdir)/prefs.h |
|
334 timers.o: $(srcdir)/types.h |
|
335 timers.o: $(srcdir)/xscreensaver.h |
|
336 @@ -1011,6 +1054,8 @@ xscreensaver-getimage.o: $(UTILS_SRC)/yarandom.h |
|
337 xscreensaver.o: XScreenSaver_ad.h |
|
338 xscreensaver.o: $(srcdir)/auth.h |
|
339 xscreensaver.o: ../config.h |
|
340 +xscreensaver.o: $(srcdir)/dialog-data.h |
|
341 +xscreensaver.o: $(srcdir)/mlstring.h |
|
342 xscreensaver.o: $(srcdir)/prefs.h |
|
343 xscreensaver.o: $(srcdir)/types.h |
|
344 xscreensaver.o: $(UTILS_SRC)/resources.h |
|
345 diff --git a/driver/auth.h b/driver/auth.h |
|
346 --- a/driver/auth.h |
|
347 +++ b/driver/auth.h |
|
348 @@ -51,4 +51,8 @@ xss_authenticate(saver_info *si, Bool verbose_p); |
|
349 void |
|
350 auth_finished_cb (saver_info *si); |
|
351 |
|
352 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
353 +extern int write_to_child (saver_info* si, const char* cmd, const char *msg); |
|
354 +#endif |
|
355 + |
|
356 #endif |
|
357 diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c |
|
358 --- a/driver/demo-Gtk.c |
|
359 +++ b/driver/demo-Gtk.c |
|
360 @@ -98,6 +98,8 @@ |
|
361 # define G_MODULE_EXPORT /**/ |
|
362 #endif /* !HAVE_GTK2 */ |
|
363 |
|
364 +#include <gconf/gconf-client.h> |
|
365 + |
|
366 #if defined(DEFAULT_ICONDIR) && !defined(GLADE_DIR) |
|
367 # define GLADE_DIR DEFAULT_ICONDIR |
|
368 #endif |
|
369 @@ -5024,6 +5026,22 @@ main (int argc, char **argv) |
|
370 load_init_file (dpy, p); |
|
371 initialize_sort_map (s); |
|
372 |
|
373 + /* Bug 147639: Gok cant automatically UI grab screensaver preferences */ |
|
374 + { |
|
375 + GConfClient *client = gconf_client_get_default (); |
|
376 + |
|
377 +#define KEY "/desktop/gnome/interface/accessibility" |
|
378 + |
|
379 + /* check if accessibilty mode is enabled */ |
|
380 + if (gconf_client_get_bool (client, KEY, NULL)) |
|
381 + { |
|
382 + /* GTK Accessibility Module initialized */ |
|
383 + const char *modulesptr = g_getenv ("GTK_MODULES"); |
|
384 + if (!modulesptr || (modulesptr [0] == '\0')) |
|
385 + putenv ("GTK_MODULES=gail:atk-bridge"); |
|
386 + } |
|
387 + } |
|
388 + |
|
389 /* Now that Xt has been initialized, and the resources have been read, |
|
390 we can set our `progname' variable to something more in line with |
|
391 reality. |
|
392 diff --git a/driver/dialog-data.h b/driver/dialog-data.h |
|
393 new file mode 100644 |
|
394 --- /dev/null |
|
395 +++ b/driver/dialog-data.h |
|
396 @@ -0,0 +1,131 @@ |
|
397 +/* xscreensaver, Copyright (c) 1993-2008 Jamie Zawinski <[email protected]> |
|
398 + * |
|
399 + * Permission to use, copy, modify, distribute, and sell this software and its |
|
400 + * documentation for any purpose is hereby granted without fee, provided that |
|
401 + * the above copyright notice appear in all copies and that both that |
|
402 + * copyright notice and this permission notice appear in supporting |
|
403 + * documentation. No representations are made about the suitability of this |
|
404 + * software for any purpose. It is provided "as is" without express or |
|
405 + * implied warranty. |
|
406 + */ |
|
407 + |
|
408 +#ifndef __DIALOG_DATA_H__ |
|
409 +#define __DIALOG_DATA_H__ |
|
410 + |
|
411 +#include <stdio.h> |
|
412 +#include "types.h" |
|
413 +#include "mlstring.h" |
|
414 + |
|
415 +#define MAX_BYTES_PER_CHAR 8 /* UTF-8 uses no more than 3, I think */ |
|
416 +#define MAX_PASSWD_CHARS 128 /* Longest possible passphrase */ |
|
417 + |
|
418 +struct passwd_dialog_data { |
|
419 + |
|
420 + saver_screen_info *prompt_screen; |
|
421 + int previous_mouse_x, previous_mouse_y; |
|
422 + |
|
423 + /* "Characters" in the password may be a variable number of bytes long. |
|
424 + typed_passwd contains the raw bytes. |
|
425 + typed_passwd_char_size indicates the size in bytes of each character, |
|
426 + so that we can make backspace work. |
|
427 + */ |
|
428 + char typed_passwd [MAX_PASSWD_CHARS * MAX_BYTES_PER_CHAR]; |
|
429 + char typed_passwd_char_size [MAX_PASSWD_CHARS]; |
|
430 + |
|
431 + XtIntervalId timer; |
|
432 + int i_beam; |
|
433 + |
|
434 + float ratio; |
|
435 + Position x, y; |
|
436 + Dimension width; |
|
437 + Dimension height; |
|
438 + Dimension border_width; |
|
439 + |
|
440 + Bool echo_input; |
|
441 + Bool show_stars_p; /* "I regret that I have but one asterisk for my country." |
|
442 + -- Nathan Hale, 1776. */ |
|
443 + |
|
444 + char *heading_label; |
|
445 + char *body_label; |
|
446 + char *user_label; |
|
447 + mlstring *info_label; |
|
448 + /* The entry field shall only be displayed if prompt_label is not NULL */ |
|
449 + mlstring *prompt_label; |
|
450 + char *date_label; |
|
451 + char *passwd_string; |
|
452 + Bool passwd_changed_p; /* Whether the user entry field needs redrawing */ |
|
453 + Bool caps_p; /* Whether we saw a keypress with caps-lock on */ |
|
454 + char *unlock_label; |
|
455 + char *login_label; |
|
456 + char *uname_label; |
|
457 + |
|
458 + Bool show_uname_p; |
|
459 + |
|
460 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
461 + XFontStruct *heading_font; |
|
462 + XFontStruct *body_font; |
|
463 + XFontStruct *label_font; |
|
464 + XFontStruct *passwd_font; |
|
465 + XFontStruct *date_font; |
|
466 + XFontStruct *button_font; |
|
467 + XFontStruct *uname_font; |
|
468 + |
|
469 + Pixel foreground; |
|
470 + Pixel background; |
|
471 + Pixel border; |
|
472 + Pixel passwd_foreground; |
|
473 + Pixel passwd_background; |
|
474 + Pixel thermo_foreground; |
|
475 + Pixel thermo_background; |
|
476 + Pixel shadow_top; |
|
477 + Pixel shadow_bottom; |
|
478 + Pixel button_foreground; |
|
479 + Pixel button_background; |
|
480 + |
|
481 + Dimension preferred_logo_width, logo_width; |
|
482 + Dimension preferred_logo_height, logo_height; |
|
483 + Dimension thermo_width; |
|
484 + Dimension internal_border; |
|
485 + Dimension shadow_width; |
|
486 + |
|
487 + Dimension passwd_field_x, passwd_field_y; |
|
488 + Dimension passwd_field_width, passwd_field_height; |
|
489 + |
|
490 + Dimension unlock_button_x, unlock_button_y; |
|
491 + Dimension unlock_button_width, unlock_button_height; |
|
492 + |
|
493 + Dimension login_button_x, login_button_y; |
|
494 + Dimension login_button_width, login_button_height; |
|
495 + |
|
496 + Dimension thermo_field_x, thermo_field_y; |
|
497 + Dimension thermo_field_height; |
|
498 + |
|
499 + Pixmap logo_pixmap; |
|
500 + Pixmap logo_clipmask; |
|
501 + int logo_npixels; |
|
502 + unsigned long *logo_pixels; |
|
503 +#endif /* ! HAVE_XSCREENSAVER_LOCK */ |
|
504 + |
|
505 + Cursor passwd_cursor; |
|
506 + Bool unlock_button_down_p; |
|
507 + Bool login_button_down_p; |
|
508 + Bool login_button_p; |
|
509 + Bool login_button_enabled_p; |
|
510 + Bool button_state_changed_p; /* Refers to both buttons */ |
|
511 + |
|
512 + Pixmap save_under; |
|
513 + Pixmap user_entry_pixmap; |
|
514 + |
|
515 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
516 + /* extern passwd dialog stuff */ |
|
517 + XtInputId stdout_input_id; |
|
518 + int stdin_fd; /* child's stdin - parent writes to this */ |
|
519 + int stdout_fd; /* child's stdout - parent reads from this */ |
|
520 + FILE *stdin_file; /* child's stdin - parent writes to this */ |
|
521 + FILE *stdout_file; /* child's stdout - parent reads from this */ |
|
522 + Bool got_windowid; |
|
523 + Bool got_passwd; |
|
524 +#endif |
|
525 +}; |
|
526 + |
|
527 +#endif /* __DIALOG_DATA_H__ */ |
|
528 diff --git a/driver/lock-Gtk.c b/driver/lock-Gtk.c |
|
529 new file mode 100644 |
|
530 --- /dev/null |
|
531 +++ b/driver/lock-Gtk.c |
|
532 @@ -0,0 +1,955 @@ |
|
533 +/* lock-Gtk.c -- a GTK+ password dialog for xscreensaver |
|
534 + * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <[email protected]> |
|
535 + * |
|
536 + * Permission to use, copy, modify, distribute, and sell this software and its |
|
537 + * documentation for any purpose is hereby granted without fee, provided that |
|
538 + * the above copyright notice appear in all copies and that both that |
|
539 + * copyright notice and this permission notice appear in supporting |
|
540 + * documentation. No representations are made about the suitability of this |
|
541 + * software for any purpose. It is provided "as is" without express or |
|
542 + * implied warranty. |
|
543 + */ |
|
544 + |
|
545 +/* GTK+ locking code written by Jacob Berkman <[email protected]> for |
|
546 + * Sun Microsystems. |
|
547 + * |
|
548 + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. |
|
549 + * |
|
550 + * Permission is hereby granted, free of charge, to any person obtaining a |
|
551 + * copy of this software and associated documentation files (the "Software"), |
|
552 + * to deal in the Software without restriction, including without limitation |
|
553 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
554 + * and/or sell copies of the Software, and to permit persons to whom the |
|
555 + * Software is furnished to do so, subject to the following conditions: |
|
556 + * |
|
557 + * The above copyright notice and this permission notice (including the next |
|
558 + * paragraph) shall be included in all copies or substantial portions of the |
|
559 + * Software. |
|
560 + * |
|
561 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
562 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
563 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
564 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
565 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
566 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
567 + * DEALINGS IN THE SOFTWARE. |
|
568 + */ |
|
569 + |
|
570 +#ifdef HAVE_CONFIG_H |
|
571 +# include "config.h" |
|
572 +#endif |
|
573 + |
|
574 +#ifdef HAVE_GTK2 /* whole file */ |
|
575 + |
|
576 +#include <xscreensaver-intl.h> |
|
577 + |
|
578 +#include <unistd.h> |
|
579 +#include <errno.h> |
|
580 +#include <string.h> |
|
581 +#include <time.h> |
|
582 +#include <stdlib.h> |
|
583 +#include <stdio.h> |
|
584 +#include <fcntl.h> |
|
585 +#include <sys/types.h> |
|
586 +#include <sys/stat.h> |
|
587 + |
|
588 +#include <gtk/gtk.h> |
|
589 +#include <gdk/gdkx.h> |
|
590 + |
|
591 +/* AT-enabled */ |
|
592 +#include <stdio.h> |
|
593 +#include <ctype.h> |
|
594 +#include <X11/Xos.h> |
|
595 +#include <X11/Xlib.h> |
|
596 +#include <X11/Xatom.h> |
|
597 +#include <X11/Xutil.h> |
|
598 +#include <X11/Xmu/WinUtil.h> |
|
599 + |
|
600 +#include <gconf/gconf-client.h> |
|
601 +#include <libbonobo.h> |
|
602 +#include <login-helper/Accessibility_LoginHelper.h> |
|
603 +#include <atk/atkobject.h> |
|
604 + |
|
605 +#include "remote.h" |
|
606 +#include "atoms.h" |
|
607 + |
|
608 +#if GTK_CHECK_VERSION(2,14,0) |
|
609 +# define GET_WINDOW(w) gtk_widget_get_window (w) |
|
610 +#else |
|
611 +# define GET_WINDOW(w) ((w)->window) |
|
612 +#endif |
|
613 + |
|
614 +static Atom XA_UNLOCK_RATIO; |
|
615 + |
|
616 +typedef struct { |
|
617 + GtkWidget *dialog; |
|
618 + GtkWidget *user_prompt_label; |
|
619 + GtkWidget *user_input_entry; |
|
620 + GtkWidget *progress; |
|
621 + GtkWidget *button; |
|
622 + GtkWidget *msg_label; |
|
623 + GtkWidget *pam_message_label; |
|
624 +} PasswdDialog; |
|
625 + |
|
626 +/*Global info */ |
|
627 +#define MAXRAISEDWINS 2 |
|
628 + |
|
629 +char *progname = 0; |
|
630 +FILE *parent_file = NULL; /* child writes to parent on this */ |
|
631 + |
|
632 +#define FD_TO_PARENT 9 |
|
633 + |
|
634 +/* Send a command to the xscreensaver parent daemon |
|
635 + Arguments: |
|
636 + - msg - type of message - "input", "raise_wid", etc. |
|
637 + - data - data for message |
|
638 + - flush - whether to flush now or allow stdio to buffer |
|
639 + Message format sent to parent: |
|
640 + "msg\n" if no data, otherwise "msg=data\n" |
|
641 + |
|
642 + Can be used to flush previously buffered messages by calling |
|
643 + with NULL msg & data, and TRUE for flush. |
|
644 + */ |
|
645 +static int |
|
646 +write_to_parent (const char* msg, const char *data, gboolean flush) |
|
647 +{ |
|
648 + int len = 0; |
|
649 + |
|
650 + /* |
|
651 + fprintf (stderr, "-->Child write_to_parent() string to send is: %s=%s\n", |
|
652 + msg, data ? data : "(null)"); |
|
653 + fflush (stderr); |
|
654 + */ |
|
655 + |
|
656 + if (msg) |
|
657 + { |
|
658 + if (data) |
|
659 + len = fprintf (parent_file, "%s=%s\n", msg, data); |
|
660 + else |
|
661 + len = fprintf (parent_file, "%s\n", msg); |
|
662 + } |
|
663 + |
|
664 + if (flush) |
|
665 + fflush (parent_file); |
|
666 + |
|
667 + return len; |
|
668 +} |
|
669 + |
|
670 +/* Send parent a message with a window id as the data */ |
|
671 +static void |
|
672 +write_windowid (const char* msg, Window w) |
|
673 +{ |
|
674 + char s[16]; /* more than long enough to hold a 32-bit integer + '\0' */ |
|
675 + |
|
676 + snprintf(s, sizeof(s), "0x%lx", w); |
|
677 + write_to_parent(msg, s, FALSE); |
|
678 +} |
|
679 + |
|
680 +static GtkWidget * |
|
681 +load_unlock_logo_image (void) |
|
682 +{ |
|
683 + const char *logofile; |
|
684 + struct stat statbuf; |
|
685 + |
|
686 + logofile = DEFAULT_ICONDIR "/unlock-logo.png"; |
|
687 + |
|
688 + if (stat (logofile, &statbuf) != 0) |
|
689 + { |
|
690 + logofile = DEFAULT_ICONDIR "/logo-180.gif"; /* fallback */ |
|
691 + } |
|
692 + |
|
693 + return gtk_image_new_from_file (logofile); |
|
694 +} |
|
695 + |
|
696 +/* Create unlock dialog */ |
|
697 +static PasswdDialog * |
|
698 +make_dialog (gboolean center_pos) |
|
699 +{ |
|
700 + GtkWidget *dialog; |
|
701 + AtkObject *atk_dialog; |
|
702 + GtkWidget *frame1, *frame2; |
|
703 + GtkWidget *vbox; |
|
704 + GtkWidget *hbox1, *hbox2; |
|
705 + GtkWidget *bbox; |
|
706 + GtkWidget *vbox2; |
|
707 + GtkWidget *entry; |
|
708 + AtkObject *atk_entry; |
|
709 + GtkWidget *title_label, *msg_label, *prompt_label, |
|
710 + *user_label, *date_label, *pam_msg_label; |
|
711 + AtkObject *atk_title_label, *atk_prompt_label; |
|
712 + GtkWidget *button; |
|
713 + GtkWidget *image; |
|
714 + GtkWidget *progress; |
|
715 + char *version; |
|
716 + char *user; |
|
717 + char *host; |
|
718 + char *s; |
|
719 + gchar *format_string_locale, *format_string_utf8; |
|
720 + PasswdDialog *pwd; |
|
721 + |
|
722 + /* taken from lock.c */ |
|
723 + char buf[256]; |
|
724 + gchar *utf8_format; |
|
725 + time_t now = time (NULL); |
|
726 + struct tm* tm; |
|
727 + |
|
728 + server_xscreensaver_version (GDK_DISPLAY (), &version, &user, &host); |
|
729 + |
|
730 + if (!version) |
|
731 + { |
|
732 + fprintf (stderr, "%s: no xscreensaver running on display %s, exiting.\n", |
|
733 + progname, gdk_get_display ()); |
|
734 + exit (1); |
|
735 + } |
|
736 + |
|
737 + /* PUSH */ |
|
738 + gtk_widget_push_colormap (gdk_rgb_get_cmap ()); |
|
739 + |
|
740 + pwd = g_new0 (PasswdDialog, 1); |
|
741 + |
|
742 + dialog = gtk_window_new (GTK_WINDOW_POPUP); |
|
743 + pwd->dialog = dialog; |
|
744 + |
|
745 + /* |
|
746 + ** bugid: 5077989(P2)Bug 147580: password input dialogue obscures GOK |
|
747 + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); |
|
748 + bugid: 5002244: scr unlock dialog incompatible with MAG technique |
|
749 + ** 6182506: scr dialog is obscured by MAG window |
|
750 + */ |
|
751 + if (center_pos) |
|
752 + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); |
|
753 + else |
|
754 + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); |
|
755 + |
|
756 + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); /*mali99 irritating*/ |
|
757 + |
|
758 + /* AT-enabled dialog role = frame */ |
|
759 + atk_dialog = gtk_widget_get_accessible (dialog); |
|
760 + atk_object_set_description (atk_dialog, _("screen unlock dialog")); |
|
761 + |
|
762 + /* frame */ |
|
763 + frame1 = g_object_new (GTK_TYPE_FRAME, |
|
764 + "shadow", GTK_SHADOW_OUT, |
|
765 + NULL); |
|
766 + gtk_container_add (GTK_CONTAINER (dialog), frame1); |
|
767 + /* AT role = panel */ |
|
768 + |
|
769 + /* vbox */ |
|
770 + vbox = gtk_vbox_new (FALSE, 10); |
|
771 + gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); |
|
772 + gtk_container_add (GTK_CONTAINER (frame1), vbox); |
|
773 + /* AT role= filler(default) */ |
|
774 + |
|
775 + /* hbox */ |
|
776 + hbox1 = gtk_hbox_new (FALSE, 5); |
|
777 + gtk_box_pack_start (GTK_BOX (vbox), hbox1, |
|
778 + TRUE, TRUE, 0); |
|
779 + |
|
780 + /* image frame */ |
|
781 + frame2 = g_object_new (GTK_TYPE_FRAME, |
|
782 + "shadow", GTK_SHADOW_ETCHED_IN, |
|
783 + NULL); |
|
784 + gtk_box_pack_start (GTK_BOX (hbox1), frame2, |
|
785 + TRUE, TRUE, 0); |
|
786 + /* AT role= filler(default) */ |
|
787 + |
|
788 + /* image */ |
|
789 + image = load_unlock_logo_image (); |
|
790 + /* AT role = icon */ |
|
791 + gtk_container_add (GTK_CONTAINER (frame2), image); |
|
792 + |
|
793 + /* progress thingie */ |
|
794 + progress = g_object_new (GTK_TYPE_PROGRESS_BAR, |
|
795 + "orientation", GTK_PROGRESS_BOTTOM_TO_TOP, |
|
796 + "fraction", 1.0, |
|
797 + NULL); |
|
798 + gtk_box_pack_start (GTK_BOX (hbox1), progress, |
|
799 + FALSE, FALSE, 0); |
|
800 + pwd->progress = progress; |
|
801 + atk_object_set_description (gtk_widget_get_accessible (progress), |
|
802 + _("Percent of time you have left to unlock the screen.")); |
|
803 + |
|
804 + /* text fields */ |
|
805 + vbox2 = gtk_vbox_new (FALSE, 20); |
|
806 + gtk_box_pack_start (GTK_BOX (hbox1), vbox2, |
|
807 + TRUE, TRUE, 0); |
|
808 + /* AT role =filler */ |
|
809 + |
|
810 + s = g_markup_printf_escaped ("<span size=\"xx-large\"><b>%s </b></span>", |
|
811 + _("Screensaver")); |
|
812 + /* XScreenSaver foo label */ |
|
813 + title_label = g_object_new (GTK_TYPE_LABEL, |
|
814 + "use-markup", TRUE, |
|
815 + "label", s, |
|
816 + NULL); |
|
817 + g_free (s); |
|
818 + gtk_box_pack_start (GTK_BOX (vbox2), title_label, |
|
819 + FALSE, FALSE, 0); |
|
820 + /* AT role = label prog name */ |
|
821 + atk_title_label = gtk_widget_get_accessible (title_label); |
|
822 + atk_object_add_relationship (atk_title_label, ATK_RELATION_LABEL_FOR, |
|
823 + atk_dialog); |
|
824 + atk_object_add_relationship (atk_dialog, ATK_RELATION_LABELLED_BY, |
|
825 + atk_title_label); |
|
826 + |
|
827 + /* This display is locked. */ |
|
828 + msg_label = g_object_new (GTK_TYPE_LABEL, |
|
829 + "use-markup", TRUE, |
|
830 + "label", _("<b>This display is locked.</b>"), |
|
831 + NULL); |
|
832 + pwd->msg_label = msg_label; |
|
833 + gtk_box_pack_start (GTK_BOX (vbox2), msg_label, |
|
834 + FALSE, FALSE, 0); |
|
835 + |
|
836 + /* User information */ |
|
837 + s = g_strdup_printf (_("User: %s"), user ? user : ""); |
|
838 + user_label = g_object_new (GTK_TYPE_LABEL, |
|
839 + "label", s, |
|
840 + "use_underline", TRUE, |
|
841 + NULL); |
|
842 + g_free(s); |
|
843 + gtk_label_set_width_chars (GTK_LABEL (user_label), 35); |
|
844 + gtk_box_pack_start (GTK_BOX (vbox2), user_label, FALSE, FALSE, 0); |
|
845 + |
|
846 + /* User input */ |
|
847 + hbox2 = gtk_widget_new (GTK_TYPE_HBOX, |
|
848 + "border_width", 5, |
|
849 + "visible", TRUE, |
|
850 + "homogeneous", FALSE, |
|
851 + "spacing", 1, |
|
852 + NULL); |
|
853 + |
|
854 + /* PAM prompt */ |
|
855 + prompt_label = g_object_new (GTK_TYPE_LABEL, |
|
856 + /* blank space for prompt */ |
|
857 + "label", _(" "), |
|
858 + "use_underline", TRUE, |
|
859 + "use_markup", FALSE, |
|
860 + "justify", GTK_JUSTIFY_CENTER, |
|
861 + "wrap", FALSE, |
|
862 + "selectable", FALSE, |
|
863 + "xalign", 1.0, |
|
864 + "xpad", 0, |
|
865 + "ypad", 0, |
|
866 + "visible", FALSE, |
|
867 + NULL); |
|
868 + pwd->user_prompt_label = prompt_label; |
|
869 + |
|
870 + entry = g_object_new (GTK_TYPE_ENTRY, |
|
871 + "activates-default", TRUE, |
|
872 + "visible", TRUE, |
|
873 + "editable", TRUE, |
|
874 + "visibility", FALSE, |
|
875 + "can_focus", TRUE, |
|
876 + NULL); |
|
877 + pwd->user_input_entry = entry; |
|
878 + /* gtk_widget_grab_focus (entry); */ |
|
879 + atk_entry = gtk_widget_get_accessible (entry); |
|
880 + atk_object_set_role (atk_entry, ATK_ROLE_PASSWORD_TEXT); |
|
881 + |
|
882 + /* AT role = label for input widget */ |
|
883 + atk_prompt_label = gtk_widget_get_accessible (prompt_label); |
|
884 + atk_object_add_relationship (atk_prompt_label, ATK_RELATION_LABEL_FOR, |
|
885 + atk_entry); |
|
886 + atk_object_add_relationship (atk_entry, ATK_RELATION_LABELLED_BY, |
|
887 + atk_prompt_label); |
|
888 + |
|
889 + gtk_box_pack_start (GTK_BOX (hbox2), prompt_label, FALSE, FALSE, 0); |
|
890 + gtk_box_pack_end (GTK_BOX (hbox2), entry, TRUE, TRUE, 0); |
|
891 + gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0); |
|
892 + |
|
893 + pam_msg_label = g_object_new (GTK_TYPE_LABEL, |
|
894 + NULL); |
|
895 + pwd->pam_message_label = pam_msg_label; |
|
896 + |
|
897 + gtk_box_pack_start (GTK_BOX (vbox2), pam_msg_label, FALSE, FALSE, 0); |
|
898 + |
|
899 + /* date string */ |
|
900 + tm = localtime (&now); |
|
901 + memset (buf, 0, sizeof (buf)); |
|
902 + format_string_utf8 = _("%d-%b-%y (%a); %I:%M %p"); |
|
903 + format_string_locale = g_locale_from_utf8 (format_string_utf8, -1, |
|
904 + NULL, NULL, NULL); |
|
905 + strftime (buf, sizeof (buf) - 1, format_string_locale, tm); |
|
906 + g_free (format_string_locale); |
|
907 + |
|
908 + utf8_format = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); |
|
909 + s = g_markup_printf_escaped ("<small>%s</small>", utf8_format); |
|
910 + g_free (utf8_format); |
|
911 + |
|
912 + date_label = g_object_new (GTK_TYPE_LABEL, |
|
913 + "use-markup", TRUE, |
|
914 + "label", s, |
|
915 + NULL); |
|
916 + g_free (s); |
|
917 + gtk_box_pack_start (GTK_BOX (vbox2), date_label, |
|
918 + FALSE, FALSE, 0); |
|
919 + |
|
920 + /* button box */ |
|
921 + bbox = g_object_new (GTK_TYPE_HBUTTON_BOX, |
|
922 + "layout-style", GTK_BUTTONBOX_END, |
|
923 + "spacing", 10, |
|
924 + NULL); |
|
925 + |
|
926 + /* Ok button */ |
|
927 + button = gtk_button_new_from_stock (GTK_STOCK_OK); |
|
928 + pwd->button = button; |
|
929 + |
|
930 + gtk_box_pack_end (GTK_BOX (bbox), button, |
|
931 + FALSE, TRUE, 0); |
|
932 + |
|
933 + free (user); |
|
934 + free (version); |
|
935 + free (host); |
|
936 + |
|
937 + /* POP */ |
|
938 + gtk_widget_pop_colormap (); |
|
939 + |
|
940 + return pwd; |
|
941 +} |
|
942 + |
|
943 +/* Callback for when user has finished entering input, even though |
|
944 + we don't display an "OK" button for them to click on */ |
|
945 +static void |
|
946 +ok_clicked_cb (GtkWidget *button, PasswdDialog *pwd) |
|
947 +{ |
|
948 + const char *s; |
|
949 + |
|
950 + g_object_set (pwd->msg_label, "label", _("<b>Checking...</b>"), NULL); |
|
951 + |
|
952 + s = gtk_entry_get_text (GTK_ENTRY (pwd->user_input_entry)); |
|
953 + write_to_parent ("input", s, TRUE); |
|
954 + |
|
955 + /* Reset password field to blank, else passwd field shows old passwd *'s, |
|
956 + visible when passwd is expired, and pam is walking the user to change |
|
957 + old passwd. |
|
958 + */ |
|
959 + gtk_editable_delete_text (GTK_EDITABLE (pwd->user_input_entry), 0, -1); |
|
960 + gtk_widget_hide (pwd->user_input_entry); |
|
961 + gtk_widget_hide (pwd->user_prompt_label); |
|
962 +} |
|
963 + |
|
964 +static void |
|
965 +connect_signals (PasswdDialog *pwd) |
|
966 +{ |
|
967 + g_signal_connect (pwd->button, "clicked", |
|
968 + G_CALLBACK (ok_clicked_cb), |
|
969 + pwd); |
|
970 + |
|
971 + g_signal_connect (pwd->user_input_entry, "activate", |
|
972 + G_CALLBACK (ok_clicked_cb), |
|
973 + pwd); |
|
974 + |
|
975 + g_signal_connect (pwd->dialog, "delete-event", |
|
976 + G_CALLBACK (gtk_main_quit), |
|
977 + NULL); |
|
978 +} |
|
979 + |
|
980 +static GdkFilterReturn |
|
981 +dialog_filter_func (GdkXEvent *xevent, GdkEvent *gevent, gpointer data) |
|
982 +{ |
|
983 + PasswdDialog *pwd = data; |
|
984 + XEvent *event = xevent; |
|
985 + gdouble ratio; |
|
986 + |
|
987 + if ((event->xany.type != ClientMessage || |
|
988 + event->xclient.message_type != XA_UNLOCK_RATIO)) |
|
989 + return GDK_FILTER_CONTINUE; |
|
990 + |
|
991 + ratio = event->xclient.data.l[0] / (gdouble)100.0; |
|
992 + |
|
993 + /* CR 6176524 passwdTimeoutEnable for disabled user */ |
|
994 + if (event->xclient.data.l[1] == 0) |
|
995 + g_object_set (pwd->progress, "fraction", ratio, NULL); |
|
996 + |
|
997 + return GDK_FILTER_REMOVE; |
|
998 +} |
|
999 + |
|
1000 +static gboolean |
|
1001 +handle_input (GIOChannel *source, GIOCondition cond, gpointer data) |
|
1002 +{ |
|
1003 + PasswdDialog *pwd = data; |
|
1004 + GIOStatus status; |
|
1005 + char *str; |
|
1006 + char *label; |
|
1007 + char *hmsg = NULL; /* This is the heading of lock dialog..shows status */ |
|
1008 + |
|
1009 + if (cond & G_IO_HUP) /* daemon crashed/exited/was killed */ |
|
1010 + gtk_main_quit (); |
|
1011 + |
|
1012 + do |
|
1013 + { |
|
1014 + status = g_io_channel_read_line (source, &str, NULL, NULL, NULL); |
|
1015 + } |
|
1016 + while (status == G_IO_STATUS_AGAIN); |
|
1017 + |
|
1018 +/* debug only |
|
1019 + if (status == G_IO_STATUS_ERROR) |
|
1020 + g_message ("handle input() status_error %s\n",str); |
|
1021 + if (status == G_IO_STATUS_EOF) |
|
1022 + g_message ("handle input() status_eof %s\n",str); |
|
1023 + if (status == G_IO_STATUS_NORMAL) |
|
1024 + g_message ("handle input() status_normal %s\n",str); |
|
1025 + Most likely, the returned error msg of g_io_channel_read_line(), |
|
1026 + i.e str will not be translated into other locales ... |
|
1027 +*/ |
|
1028 + |
|
1029 + if (str) |
|
1030 + { |
|
1031 + /* strip trailing newline */ |
|
1032 + char *nl = strrchr(str, '\n'); |
|
1033 + if (nl) |
|
1034 + *nl = 0; |
|
1035 + |
|
1036 + /* |
|
1037 + fprintf (stderr,">>>>>Child..in handle_input..string is:%s\n",str); |
|
1038 + fflush (stderr); |
|
1039 + */ |
|
1040 + |
|
1041 + /* Handle commands from parent daemon */ |
|
1042 + |
|
1043 + if (((strncmp (str, "ul_", 3)) == 0)) |
|
1044 + { |
|
1045 + /* search for =, and if found, split into two strings there */ |
|
1046 + char *msgstr = strchr(str, '='); /* Data sent with command */ |
|
1047 + if (msgstr) |
|
1048 + *msgstr++ = 0; |
|
1049 + |
|
1050 + if ((strcmp (str, "ul_ok") == 0)) |
|
1051 + { |
|
1052 + hmsg = _("Authentication Successful!"); |
|
1053 + } |
|
1054 + else if ((strcmp (str, "ul_acct_ok") == 0)) |
|
1055 + { |
|
1056 + hmsg = _("PAM Account Management Also Successful!"); |
|
1057 + } |
|
1058 + else if ((strcmp (str, "ul_setcred_fail") == 0)) |
|
1059 + { |
|
1060 + hmsg = _("Just a Warning PAM Set Credential Failed!"); |
|
1061 + } |
|
1062 + else if ((strcmp (str, "ul_setcred_ok") == 0)) |
|
1063 + { |
|
1064 + hmsg = _("PAM Set Credential Also Successful!"); |
|
1065 + } |
|
1066 + else if ((strcmp (str, "ul_acct_fail") == 0)) |
|
1067 + { |
|
1068 + hmsg = _("Your Password has expired."); |
|
1069 + } |
|
1070 + else if ((strcmp (str, "ul_fail") == 0)) |
|
1071 + { |
|
1072 + hmsg = _("Sorry!"); |
|
1073 + } |
|
1074 + else if ((strcmp (str, "ul_read") == 0)) |
|
1075 + { |
|
1076 + hmsg = _("Waiting for user input!"); |
|
1077 + } |
|
1078 + else if ((strcmp (str, "ul_time") == 0)) |
|
1079 + { |
|
1080 + hmsg = _("Timed Out!"); |
|
1081 + } |
|
1082 + else if ((strcmp (str, "ul_null") == 0)) |
|
1083 + { |
|
1084 + hmsg = _("Still Checking!"); |
|
1085 + } |
|
1086 + else if ((strcmp (str, "ul_cancel") == 0)) |
|
1087 + { |
|
1088 + hmsg = _("Authentication Cancelled!"); |
|
1089 + } |
|
1090 + else if ((strcmp (str, "ul_pamprompt") == 0)) |
|
1091 + { |
|
1092 + gtk_label_set_text (GTK_LABEL (pwd->user_prompt_label), msgstr); |
|
1093 + gtk_widget_show (pwd->user_prompt_label); |
|
1094 + msgstr = NULL; /* clear message so we don't show it twice */ |
|
1095 + } |
|
1096 + else if ((strcmp (str, "ul_prompt_echo") == 0)) |
|
1097 + { |
|
1098 + if ((strcmp (msgstr, "true") == 0)) |
|
1099 + { |
|
1100 + gtk_entry_set_visibility |
|
1101 + (GTK_ENTRY (pwd->user_input_entry), TRUE); |
|
1102 + } |
|
1103 + else |
|
1104 + { |
|
1105 + if ((strcmp (msgstr, "stars") == 0)) |
|
1106 + /* reset to default display of "*" or bullet */ |
|
1107 + gtk_entry_unset_invisible_char |
|
1108 + (GTK_ENTRY (pwd->user_input_entry)); |
|
1109 + else |
|
1110 + /* set to no display */ |
|
1111 + gtk_entry_set_invisible_char |
|
1112 + (GTK_ENTRY (pwd->user_input_entry), 0); |
|
1113 + |
|
1114 + gtk_entry_set_visibility |
|
1115 + (GTK_ENTRY (pwd->user_input_entry), FALSE); |
|
1116 + } |
|
1117 + msgstr = NULL; /* clear message so we don't show it to user */ |
|
1118 + /* Show the entry field */ |
|
1119 + gtk_widget_show (pwd->user_input_entry); |
|
1120 + gtk_widget_grab_focus (pwd->user_input_entry); |
|
1121 + gdk_display_sync |
|
1122 + (gtk_widget_get_display (pwd->user_input_entry)); |
|
1123 + } |
|
1124 + else if ((strcmp (str, "ul_message") == 0)) |
|
1125 + { |
|
1126 + hmsg = NULL; /* only show msg */ |
|
1127 + } |
|
1128 + else |
|
1129 + { |
|
1130 + /* Should not be others, but if so just show it */ |
|
1131 + hmsg = str; |
|
1132 + } |
|
1133 + |
|
1134 + if (hmsg) |
|
1135 + { |
|
1136 + label = g_markup_printf_escaped ("<b>%s</b>", hmsg); |
|
1137 + g_object_set (pwd->msg_label, "label", label, NULL); |
|
1138 + g_free (label); |
|
1139 + } |
|
1140 + |
|
1141 + if (msgstr) |
|
1142 + { |
|
1143 + gtk_label_set_text (GTK_LABEL (pwd->pam_message_label), msgstr); |
|
1144 + } |
|
1145 + } |
|
1146 + else if ((strcmp (str, "cmd_exit") == 0)) |
|
1147 + { |
|
1148 + gtk_main_quit (); |
|
1149 + } |
|
1150 + else /* something came through that didn't start with ul_ */ |
|
1151 + { |
|
1152 + gtk_label_set_text (GTK_LABEL (pwd->pam_message_label), str); |
|
1153 + } |
|
1154 + |
|
1155 + g_free (str); |
|
1156 + } |
|
1157 + |
|
1158 + return (status != G_IO_STATUS_EOF); |
|
1159 +} |
|
1160 + |
|
1161 +int |
|
1162 +main (int argc, char *argv[]) |
|
1163 +{ |
|
1164 + GIOChannel *ioc; |
|
1165 + PasswdDialog *pwd; |
|
1166 + char *s; |
|
1167 + char *real_progname = argv[0]; |
|
1168 + GConfClient *client; |
|
1169 + const char *modulesptr = NULL; |
|
1170 + int i; |
|
1171 + |
|
1172 + gboolean at_enable = FALSE; /* accessibility mode enabled ? */ |
|
1173 + Bonobo_ServerInfoList *server_list = NULL; |
|
1174 + CORBA_Environment ev; |
|
1175 + Accessibility_LoginHelper helper; |
|
1176 + Accessibility_LoginHelper *helper_list = NULL; |
|
1177 + CORBA_boolean safe; |
|
1178 + gboolean center_position = TRUE; /* center dialog on screen? */ |
|
1179 + |
|
1180 +#ifdef ENABLE_NLS |
|
1181 + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); |
|
1182 + textdomain (GETTEXT_PACKAGE); |
|
1183 + |
|
1184 +#ifdef HAVE_GTK2 |
|
1185 + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); |
|
1186 +#else /* ! HAVE_GTK2 */ |
|
1187 + if (!setlocale (LC_ALL, "")) |
|
1188 + fprintf (stderr, "%s: locale not supported by C library\n", real_progname); |
|
1189 +#endif /* ! HAVE_GTK2 */ |
|
1190 +#endif /* ENABLE_NLS */ |
|
1191 + |
|
1192 + s = strrchr (real_progname, '/'); |
|
1193 + if (s) real_progname = s+1; |
|
1194 + progname = real_progname; |
|
1195 + |
|
1196 + parent_file = fdopen(FD_TO_PARENT, "w"); |
|
1197 + if (!parent_file) |
|
1198 + { |
|
1199 + fprintf (stderr, "%s: can't communicate with parent, exiting.\n", |
|
1200 + progname); |
|
1201 + exit (1); |
|
1202 + } |
|
1203 + |
|
1204 + gtk_init (&argc, &argv); |
|
1205 + |
|
1206 + /* Intern the atoms that xscreensaver_command() needs. |
|
1207 + */ |
|
1208 + { |
|
1209 + Display *dpy = gdk_x11_get_default_xdisplay(); |
|
1210 + |
|
1211 + const struct atom_request unlock_atoms[] = |
|
1212 + { |
|
1213 + { &XA_UNLOCK_RATIO, "UNLOCK_RATIO" }, |
|
1214 + { NULL, NULL } /* Must be last to terminate list */ |
|
1215 + }; |
|
1216 + |
|
1217 + const struct atom_request *atom_lists[3] = { NULL, NULL, NULL }; |
|
1218 + atom_lists[0] = remote_control_atoms; |
|
1219 + atom_lists[1] = unlock_atoms; |
|
1220 + request_atoms (dpy, atom_lists); |
|
1221 + } |
|
1222 + |
|
1223 + /* bugid 6346056(P1): |
|
1224 + ATOK pallet sometimes appears in screensave/lock-screen mode |
|
1225 + */ |
|
1226 + putenv ("GTK_IM_MODULE=gtk-im-context-simple"); |
|
1227 + |
|
1228 + |
|
1229 + /* accessibility mode enabled ? */ |
|
1230 + client = gconf_client_get_default (); |
|
1231 + at_enable = gconf_client_get_bool (client, |
|
1232 + "/desktop/gnome/interface/accessibility", |
|
1233 + NULL); |
|
1234 + if (at_enable) |
|
1235 + { |
|
1236 + |
|
1237 + /* GTK Accessibility Module initialized */ |
|
1238 + modulesptr = g_getenv ("GTK_MODULES"); |
|
1239 + if (!modulesptr || modulesptr [0] == '\0') |
|
1240 + putenv ("GTK_MODULES=gail:atk-bridge"); |
|
1241 + |
|
1242 + CORBA_exception_init (&ev); |
|
1243 + if (!bonobo_init (&argc, argv)) |
|
1244 + { |
|
1245 + g_error ("Can't initialize Bonobo"); |
|
1246 + } |
|
1247 + |
|
1248 + /* bonobo-activation query lists existing instances */ |
|
1249 + server_list = bonobo_activation_query ( |
|
1250 + "(repo_ids.has('IDL:Accessibility/LoginHelper:1.0')) AND _active", |
|
1251 + NULL, &ev); |
|
1252 + |
|
1253 + if (BONOBO_EX (&ev)) |
|
1254 + { |
|
1255 + bonobo_debug_shutdown (); |
|
1256 + g_error ("LoginHelper query failed : %s", |
|
1257 + bonobo_exception_get_text (&ev)); |
|
1258 + /* not reached (below) because g_error exits */ |
|
1259 + CORBA_exception_free (&ev); |
|
1260 + } |
|
1261 + |
|
1262 + /* |
|
1263 + * 6182506: unlock dialog can be obscured by the magnifier window |
|
1264 + * if it's always centered, so don't force that if any accessibility |
|
1265 + * helpers are present |
|
1266 + */ |
|
1267 + if (server_list && server_list->_length) |
|
1268 + center_position = FALSE; |
|
1269 + } /* accessibility enabled */ |
|
1270 + |
|
1271 + pwd = make_dialog (center_position); |
|
1272 + connect_signals (pwd); |
|
1273 + |
|
1274 + gtk_widget_show_all (pwd->dialog); |
|
1275 + gtk_window_present (GTK_WINDOW (pwd->dialog)); |
|
1276 + gtk_widget_map (pwd->dialog); |
|
1277 + |
|
1278 + gdk_display_sync (gtk_widget_get_display (pwd->dialog)); |
|
1279 + |
|
1280 + gdk_window_add_filter (GET_WINDOW (pwd->dialog), dialog_filter_func, pwd); |
|
1281 + write_windowid ("dialog_win", GDK_WINDOW_XID (GET_WINDOW (pwd->dialog))); |
|
1282 + |
|
1283 + if (server_list && server_list->_length) |
|
1284 + { |
|
1285 + /* debug only |
|
1286 + g_message ("%d LoginHelpers are running.", |
|
1287 + server_list ? server_list->_length : 0); |
|
1288 + */ |
|
1289 + |
|
1290 + helper_list = g_new0 (Accessibility_LoginHelper, server_list->_length); |
|
1291 + |
|
1292 + /* for each instance... */ |
|
1293 + for (i = 0; i < server_list->_length; i++) |
|
1294 + { |
|
1295 + Bonobo_Unknown server; |
|
1296 + Bonobo_ServerInfo info = server_list->_buffer[i]; |
|
1297 + |
|
1298 + server = bonobo_activation_activate_from_id ( |
|
1299 + info.iid, Bonobo_ACTIVATION_FLAG_EXISTING_ONLY, NULL, &ev); |
|
1300 + |
|
1301 + if (BONOBO_EX (&ev)) |
|
1302 + { |
|
1303 + g_warning ("Error activating server %d: %s", i, |
|
1304 + bonobo_exception_get_text (&ev)); |
|
1305 + CORBA_exception_free (&ev); |
|
1306 + continue; |
|
1307 + } |
|
1308 + else if (server == CORBA_OBJECT_NIL) |
|
1309 + { |
|
1310 + g_warning ("Activated server %d is NIL!", i); |
|
1311 + continue; |
|
1312 + } |
|
1313 + |
|
1314 + bonobo_activate (); |
|
1315 + |
|
1316 + helper = Bonobo_Unknown_queryInterface |
|
1317 + (server, "IDL:Accessibility/LoginHelper:1.0", &ev); |
|
1318 + |
|
1319 + if (BONOBO_EX (&ev)) |
|
1320 + { |
|
1321 + g_warning ("Error performing interface query: %s", |
|
1322 + bonobo_exception_get_text (&ev)); |
|
1323 + CORBA_exception_free (&ev); |
|
1324 + continue; |
|
1325 + } |
|
1326 + else if (helper == CORBA_OBJECT_NIL) |
|
1327 + { |
|
1328 + g_warning ("Activated an object which advertised LoginHelper but does not implement it!"); |
|
1329 + continue; |
|
1330 + } |
|
1331 + |
|
1332 + helper_list[i] = helper; |
|
1333 + bonobo_object_release_unref (server, &ev); |
|
1334 + |
|
1335 + if (helper && !BONOBO_EX (&ev)) |
|
1336 + { |
|
1337 + /* ask the helper to go into safe mode */ |
|
1338 + safe = Accessibility_LoginHelper_setSafe (helper, TRUE, &ev); |
|
1339 + if (BONOBO_EX (&ev)) |
|
1340 + { |
|
1341 + g_warning ("setSafe(TRUE) failed: %s", |
|
1342 + bonobo_exception_get_text (&ev)); |
|
1343 + CORBA_exception_free (&ev); |
|
1344 + } |
|
1345 + |
|
1346 + /* get the raise window list (if the program went into safe mode) */ |
|
1347 + if (safe) |
|
1348 + { |
|
1349 + int j; |
|
1350 + gboolean needs_windows_raised = FALSE; |
|
1351 + Accessibility_LoginHelper_DeviceReqList *list; |
|
1352 + |
|
1353 + g_debug ("safe"); |
|
1354 + |
|
1355 + /* does this helper need to have windows raised? */ |
|
1356 + list = Accessibility_LoginHelper_getDeviceReqs (helper, &ev); |
|
1357 + |
|
1358 + if (BONOBO_EX (&ev)) |
|
1359 + { |
|
1360 + g_warning ("Bonobo exception getting Device Requirements: %s", |
|
1361 + bonobo_exception_get_text (&ev)); |
|
1362 + CORBA_exception_free (&ev); |
|
1363 + } |
|
1364 + else |
|
1365 + { |
|
1366 + g_debug ("LoginHelper device requirements: "); |
|
1367 + if (list->_length == 0) |
|
1368 + g_debug (" - None."); |
|
1369 + |
|
1370 + for (j = 0; j < list->_length; j++) |
|
1371 + { |
|
1372 + switch (list->_buffer[j]) |
|
1373 + { |
|
1374 + case Accessibility_LoginHelper_GUI_EVENTS: |
|
1375 + g_debug (" - Needs access to the GUI event subsystem (e.g. Xserver)"); |
|
1376 + break; |
|
1377 + case Accessibility_LoginHelper_CORE_KEYBOARD: |
|
1378 + g_debug (" - Needs access to core keyboard device"); |
|
1379 + write_to_parent("ungrab_keyboard", "true", FALSE); |
|
1380 + break; |
|
1381 + case Accessibility_LoginHelper_CORE_POINTER: |
|
1382 + g_debug (" - Needs access to core pointer device"); |
|
1383 + write_to_parent("ungrab_pointer", "true", FALSE); |
|
1384 + break; |
|
1385 + case Accessibility_LoginHelper_EXT_INPUT: |
|
1386 + g_debug (" - Reads XInput extended input devices"); |
|
1387 + break; |
|
1388 + case Accessibility_LoginHelper_POST_WINDOWS: |
|
1389 + g_debug (" - Posts windows"); |
|
1390 + needs_windows_raised = TRUE; |
|
1391 + break; |
|
1392 + case Accessibility_LoginHelper_AUDIO_OUT: |
|
1393 + g_debug (" - Writes to audio device"); |
|
1394 + break; |
|
1395 + case Accessibility_LoginHelper_AUDIO_IN: |
|
1396 + g_debug (" - Reads from audio device"); |
|
1397 + break; |
|
1398 + case Accessibility_LoginHelper_LOCALHOST: |
|
1399 + g_debug (" - Needs LOCALHOST network connection"); |
|
1400 + break; |
|
1401 + case Accessibility_LoginHelper_SERIAL_OUT: |
|
1402 + g_debug (" - Needs to write to one or more serial ports"); |
|
1403 + break; |
|
1404 + default: |
|
1405 + break; |
|
1406 + } |
|
1407 + } |
|
1408 + CORBA_free (list); |
|
1409 + } |
|
1410 + |
|
1411 + if (needs_windows_raised) |
|
1412 + { |
|
1413 + Accessibility_LoginHelper_WindowList *windows |
|
1414 + = Accessibility_LoginHelper_getRaiseWindows |
|
1415 + (helper, &ev); |
|
1416 + |
|
1417 + if (BONOBO_EX (&ev)) |
|
1418 + { |
|
1419 + g_warning ("getRaiseWindows failed: %s", |
|
1420 + bonobo_exception_get_text (&ev)); |
|
1421 + CORBA_exception_free (&ev); |
|
1422 + } |
|
1423 + |
|
1424 + g_debug ("%d windows need raising", windows->_length); |
|
1425 + for (j = 0; j < windows->_length; j++) |
|
1426 + { |
|
1427 + Window wid = windows->_buffer[j].winID; |
|
1428 + g_debug ("Window ID = 0x%lx", wid); |
|
1429 + if (wid) |
|
1430 + write_windowid ("raise_win", wid); |
|
1431 + } |
|
1432 + } |
|
1433 + } |
|
1434 + else |
|
1435 + { |
|
1436 + g_warning ("LoginHelper %d did not go into safe mode", i); |
|
1437 + } |
|
1438 + } |
|
1439 + else |
|
1440 + { |
|
1441 + if (BONOBO_EX (&ev)) |
|
1442 + { |
|
1443 + g_warning ("Error activating %s: %s", |
|
1444 + info.iid, bonobo_exception_get_text (&ev)); |
|
1445 + CORBA_exception_free (&ev); |
|
1446 + } |
|
1447 + else |
|
1448 + { |
|
1449 + g_warning ("no active instance of %s found", info.iid); |
|
1450 + } |
|
1451 + } |
|
1452 + } |
|
1453 + } /* accessibility helpers active */ |
|
1454 + |
|
1455 + /* Flush dialog window ids & any messages about login helpers to parent */ |
|
1456 + write_to_parent(NULL, NULL, TRUE); |
|
1457 + |
|
1458 + gtk_widget_grab_focus (pwd->user_input_entry); |
|
1459 + |
|
1460 + ioc = g_io_channel_unix_new (0); |
|
1461 + g_io_add_watch (ioc, G_IO_IN | G_IO_HUP, handle_input, pwd); |
|
1462 + |
|
1463 + gtk_main (); |
|
1464 + |
|
1465 + /* Reset accessibility helpers back to non-safe mode now that we're done */ |
|
1466 + if (server_list) |
|
1467 + { |
|
1468 + for (i = 0; i < server_list->_length; i++) |
|
1469 + { |
|
1470 + helper = helper_list[i]; |
|
1471 + /* really no need to check the return value this time */ |
|
1472 + Accessibility_LoginHelper_setSafe (helper, FALSE, &ev); |
|
1473 + if (BONOBO_EX (&ev)) |
|
1474 + { |
|
1475 + g_warning ("setSafe(FALSE) failed: %s", |
|
1476 + bonobo_exception_get_text (&ev)); |
|
1477 + CORBA_exception_free (&ev); |
|
1478 + } |
|
1479 + CORBA_Object_release (helper, &ev); |
|
1480 + } |
|
1481 + CORBA_free (server_list); |
|
1482 + bonobo_debug_shutdown (); |
|
1483 + } |
|
1484 + |
|
1485 + return 0; |
|
1486 +} |
|
1487 +#endif /* HAVE_GTK2 */ |
|
1488 diff --git a/driver/lock.c b/driver/lock.c |
|
1489 --- a/driver/lock.c |
|
1490 +++ b/driver/lock.c |
|
1491 @@ -21,8 +21,13 @@ |
|
1492 #include <X11/Intrinsic.h> |
|
1493 #include <X11/cursorfont.h> |
|
1494 #include <X11/Xos.h> /* for time() */ |
|
1495 +#include <X11/Xatom.h> |
|
1496 #include <time.h> |
|
1497 #include <sys/time.h> |
|
1498 +#include <errno.h> |
|
1499 +#include <gconf/gconf-client.h> |
|
1500 +#include "exec.h" |
|
1501 +#include "dialog-data.h" |
|
1502 #include "xscreensaver.h" |
|
1503 #include "resources.h" |
|
1504 #include "mlstring.h" |
|
1505 @@ -83,126 +88,631 @@ vms_passwd_valid_p(char *pw, Bool verbose_p) |
|
1506 |
|
1507 typedef struct info_dialog_data info_dialog_data; |
|
1508 |
|
1509 +/* struct passwd_dialog_data moved to dialog-data.h */ |
|
1510 |
|
1511 -#define MAX_BYTES_PER_CHAR 8 /* UTF-8 uses no more than 3, I think */ |
|
1512 -#define MAX_PASSWD_CHARS 128 /* Longest possible passphrase */ |
|
1513 - |
|
1514 -struct passwd_dialog_data { |
|
1515 - |
|
1516 - saver_screen_info *prompt_screen; |
|
1517 - int previous_mouse_x, previous_mouse_y; |
|
1518 - |
|
1519 - /* "Characters" in the password may be a variable number of bytes long. |
|
1520 - typed_passwd contains the raw bytes. |
|
1521 - typed_passwd_char_size indicates the size in bytes of each character, |
|
1522 - so that we can make backspace work. |
|
1523 - */ |
|
1524 - char typed_passwd [MAX_PASSWD_CHARS * MAX_BYTES_PER_CHAR]; |
|
1525 - char typed_passwd_char_size [MAX_PASSWD_CHARS]; |
|
1526 - |
|
1527 - XtIntervalId timer; |
|
1528 - int i_beam; |
|
1529 - |
|
1530 - float ratio; |
|
1531 - Position x, y; |
|
1532 - Dimension width; |
|
1533 - Dimension height; |
|
1534 - Dimension border_width; |
|
1535 - |
|
1536 - Bool echo_input; |
|
1537 - Bool show_stars_p; /* "I regret that I have but one asterisk for my country." |
|
1538 - -- Nathan Hale, 1776. */ |
|
1539 - |
|
1540 - char *heading_label; |
|
1541 - char *body_label; |
|
1542 - char *user_label; |
|
1543 - mlstring *info_label; |
|
1544 - /* The entry field shall only be displayed if prompt_label is not NULL */ |
|
1545 - mlstring *prompt_label; |
|
1546 - char *date_label; |
|
1547 - char *passwd_string; |
|
1548 - Bool passwd_changed_p; /* Whether the user entry field needs redrawing */ |
|
1549 - Bool caps_p; /* Whether we saw a keypress with caps-lock on */ |
|
1550 - char *unlock_label; |
|
1551 - char *login_label; |
|
1552 - char *uname_label; |
|
1553 - |
|
1554 - Bool show_uname_p; |
|
1555 - |
|
1556 - XFontStruct *heading_font; |
|
1557 - XFontStruct *body_font; |
|
1558 - XFontStruct *label_font; |
|
1559 - XFontStruct *passwd_font; |
|
1560 - XFontStruct *date_font; |
|
1561 - XFontStruct *button_font; |
|
1562 - XFontStruct *uname_font; |
|
1563 - |
|
1564 - Pixel foreground; |
|
1565 - Pixel background; |
|
1566 - Pixel border; |
|
1567 - Pixel passwd_foreground; |
|
1568 - Pixel passwd_background; |
|
1569 - Pixel thermo_foreground; |
|
1570 - Pixel thermo_background; |
|
1571 - Pixel shadow_top; |
|
1572 - Pixel shadow_bottom; |
|
1573 - Pixel button_foreground; |
|
1574 - Pixel button_background; |
|
1575 - |
|
1576 - Dimension preferred_logo_width, logo_width; |
|
1577 - Dimension preferred_logo_height, logo_height; |
|
1578 - Dimension thermo_width; |
|
1579 - Dimension internal_border; |
|
1580 - Dimension shadow_width; |
|
1581 - |
|
1582 - Dimension passwd_field_x, passwd_field_y; |
|
1583 - Dimension passwd_field_width, passwd_field_height; |
|
1584 - |
|
1585 - Dimension unlock_button_x, unlock_button_y; |
|
1586 - Dimension unlock_button_width, unlock_button_height; |
|
1587 - |
|
1588 - Dimension login_button_x, login_button_y; |
|
1589 - Dimension login_button_width, login_button_height; |
|
1590 - |
|
1591 - Dimension thermo_field_x, thermo_field_y; |
|
1592 - Dimension thermo_field_height; |
|
1593 - |
|
1594 - Pixmap logo_pixmap; |
|
1595 - Pixmap logo_clipmask; |
|
1596 - int logo_npixels; |
|
1597 - unsigned long *logo_pixels; |
|
1598 - |
|
1599 - Cursor passwd_cursor; |
|
1600 - Bool unlock_button_down_p; |
|
1601 - Bool login_button_down_p; |
|
1602 - Bool login_button_p; |
|
1603 - Bool login_button_enabled_p; |
|
1604 - Bool button_state_changed_p; /* Refers to both buttons */ |
|
1605 - |
|
1606 - Pixmap save_under; |
|
1607 - Pixmap user_entry_pixmap; |
|
1608 -}; |
|
1609 - |
|
1610 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
1611 static void draw_passwd_window (saver_info *si); |
|
1612 +#endif |
|
1613 static void update_passwd_window (saver_info *si, const char *printed_passwd, |
|
1614 float ratio); |
|
1615 static void destroy_passwd_window (saver_info *si); |
|
1616 +static int ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error); |
|
1617 static void undo_vp_motion (saver_info *si); |
|
1618 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
1619 static void finished_typing_passwd (saver_info *si, passwd_dialog_data *pw); |
|
1620 +#endif |
|
1621 static void cleanup_passwd_window (saver_info *si); |
|
1622 static void restore_background (saver_info *si); |
|
1623 |
|
1624 extern void xss_authenticate(saver_info *si, Bool verbose_p); |
|
1625 |
|
1626 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
1627 + |
|
1628 +#define WIN_ALLOC_INCREMENT 8 /* allocate entries in the window lists in |
|
1629 + increments of 8 at a time for fewer |
|
1630 + reallocs and less chance of malloc error |
|
1631 + at the wrong time */ |
|
1632 +#define EXTRA_RAISE_WIN_SLOTS 4 /* Need to leave four extra slots free in |
|
1633 + raise_wins to allow calling XRestackWindows |
|
1634 + when a window pops up without having to |
|
1635 + realloc or copy to a new list. |
|
1636 + These slots would be used by: |
|
1637 + - passwd_dialog |
|
1638 + - stderr_overlay_window |
|
1639 + - xscreensaver virtual root |
|
1640 + - an interloper popup we need to hide |
|
1641 + */ |
|
1642 + |
|
1643 +extern Atom XA_UNLOCK_RATIO; |
|
1644 + |
|
1645 +Bool g_passwd_dialog_created = 0; |
|
1646 + |
|
1647 +GConfClient *client = NULL; |
|
1648 + |
|
1649 +static const char *switch_windows_gconf_key |
|
1650 + = "/apps/metacity/global_keybindings/switch_windows"; |
|
1651 +static char *global_switch_key = NULL; |
|
1652 + |
|
1653 +static const char *main_menu_gconf_key |
|
1654 + = "/apps/metacity/global_keybindings/panel_main_menu"; |
|
1655 +static char *global_menu_key = NULL; |
|
1656 + |
|
1657 +extern Bool safe_XDestroyWindow (Display *dpy, Window window); |
|
1658 +static Bool safe_XRestackWindows(Display *dpy, Window windows[], int nwindows); |
|
1659 +static Bool safe_XSendEvent(Display *dpy, Window w, Bool propagate, |
|
1660 + long event_mask, XEvent *event_send); |
|
1661 +static void passwd_animate_timer (XtPointer closure, XtIntervalId *id); |
|
1662 +extern void swallow_unlock_typeahead_events (saver_info *si, XEvent *e); |
|
1663 + |
|
1664 + |
|
1665 +static saver_screen_info * |
|
1666 +find_screen_for_window (saver_info *si, Window wid) |
|
1667 +{ |
|
1668 + saver_screen_info *ssi; |
|
1669 + Screen *screen; |
|
1670 + Window root, root_ret, parent_ret, *children = NULL; |
|
1671 + unsigned int nchildren = 0; |
|
1672 + int screen_no, status; |
|
1673 + |
|
1674 + status = XQueryTree (si->dpy, wid, &root_ret, &parent_ret, |
|
1675 + &children, &nchildren); |
|
1676 + |
|
1677 + if (status == 0) /* failed */ |
|
1678 + return NULL; |
|
1679 + |
|
1680 + XFree(children); |
|
1681 + children = NULL; |
|
1682 + |
|
1683 + for (screen_no = 0; screen_no < si->nscreens; screen_no++) |
|
1684 + { |
|
1685 + ssi = &si->screens[screen_no]; |
|
1686 + screen = ssi->screen; |
|
1687 + root = RootWindowOfScreen (screen); |
|
1688 + |
|
1689 + if (root == root_ret) |
|
1690 + return ssi; |
|
1691 + } |
|
1692 + |
|
1693 + return NULL; /* Didn't match the root on any screen we know of - PUNT! */ |
|
1694 +} |
|
1695 + |
|
1696 +/* |
|
1697 + 5083155 Unable to unlock screen when running dual-head MAG |
|
1698 + adding dual or multiple heads for magnifier support |
|
1699 + |
|
1700 + screen 0: loginhelp can pass the raisedWid of GOK or MAG or both |
|
1701 + found: return its parent Wid (child of root) |
|
1702 + not found: 0 |
|
1703 + |
|
1704 + other screen: MAG only if the target screen no > 0 is selected |
|
1705 + found: restack on that screen |
|
1706 + return 0 |
|
1707 + not-found : return 0 |
|
1708 + |
|
1709 + */ |
|
1710 + |
|
1711 +static Window |
|
1712 +check_raisedWid (saver_info *si, Window wid) |
|
1713 +{ |
|
1714 + saver_screen_info *ssi; |
|
1715 + Screen *screen; |
|
1716 + Window root, root_ret, parent_ret, *children = NULL; |
|
1717 + unsigned int nchildren = 0; |
|
1718 + int screen_no, status; |
|
1719 + |
|
1720 + status = XQueryTree (si->dpy, wid, &root_ret, &parent_ret, |
|
1721 + &children, &nchildren); |
|
1722 + |
|
1723 + if (status == 0) /* failed */ |
|
1724 + return 0; |
|
1725 + |
|
1726 + XFree(children); |
|
1727 + children = NULL; |
|
1728 + |
|
1729 + for (screen_no = 0; screen_no < si->nscreens; screen_no++) |
|
1730 + { |
|
1731 + ssi = &si->screens[screen_no]; |
|
1732 + screen = ssi->screen; |
|
1733 + root = RootWindowOfScreen (screen); |
|
1734 + |
|
1735 + if (root == root_ret) |
|
1736 + break; |
|
1737 + } |
|
1738 + |
|
1739 + if ( screen_no >= si->nscreens ) /* Didn't match the root on any screen */ |
|
1740 + return 0; /* we know of - PUNT! */ |
|
1741 + |
|
1742 + /* Climb the tree until we find an ancestor that's a child of root */ |
|
1743 + while ( root_ret != parent_ret ) |
|
1744 + { |
|
1745 + wid = parent_ret; |
|
1746 + |
|
1747 + status = XQueryTree (si->dpy, wid, &root_ret, &parent_ret, |
|
1748 + &children, &nchildren); |
|
1749 + |
|
1750 + if (status == 0) /* failed */ |
|
1751 + return 0; |
|
1752 + |
|
1753 + XFree(children); |
|
1754 + children = NULL; |
|
1755 + } |
|
1756 + |
|
1757 + if ( ssi != si->pw_data->prompt_screen ) |
|
1758 + { |
|
1759 + /* found in other screen (not the one with the unlock dialog), |
|
1760 + implies MAG target screen, invoke XRestackWindow() there |
|
1761 + */ |
|
1762 + Window screen_win[2] = { wid, ssi->screensaver_window }; |
|
1763 + safe_XRestackWindows(si->dpy, screen_win, 2); |
|
1764 + return 0; /* no need to do the restack on prompt screen */ |
|
1765 + } |
|
1766 + |
|
1767 + return wid; |
|
1768 +} |
|
1769 + |
|
1770 +/* Enforce window stacking order when a new window arrives. |
|
1771 + Only allow raising windows the unlock dialog has told us to raise |
|
1772 + (including itself). |
|
1773 + */ |
|
1774 +static void |
|
1775 +restack_my_windows (saver_info* si, saver_screen_info *ssi, Window newWin) |
|
1776 +{ |
|
1777 + int n = 0; |
|
1778 + Window short_stack[EXTRA_RAISE_WIN_SLOTS]; |
|
1779 + Window *restack_list; |
|
1780 + Bool allowed = False; |
|
1781 + |
|
1782 + /* If window is on another screen than the unlock dialog, |
|
1783 + or we have list of no windows to raise */ |
|
1784 + if ((si->raise_wins == NULL) || (ssi != si->pw_data->prompt_screen)) |
|
1785 + { |
|
1786 + restack_list = short_stack; |
|
1787 + } |
|
1788 + else |
|
1789 + { |
|
1790 + restack_list = si->raise_wins; |
|
1791 + for (n = 0; n < si->num_raise_wins; n++) |
|
1792 + { |
|
1793 + if (si->raise_wins[n] == newWin) |
|
1794 + allowed = True; |
|
1795 + } |
|
1796 + } |
|
1797 + |
|
1798 + if (si->passwd_dialog && (ssi == si->pw_data->prompt_screen)) |
|
1799 + { |
|
1800 + restack_list[n++] = si->passwd_dialog; |
|
1801 + if (si->passwd_dialog == newWin) |
|
1802 + allowed = True; |
|
1803 + } |
|
1804 + |
|
1805 + if (ssi->stderr_overlay_window) |
|
1806 + { |
|
1807 + restack_list[n++] = ssi->stderr_overlay_window; |
|
1808 + if (ssi->stderr_overlay_window == newWin) |
|
1809 + allowed = True; |
|
1810 + } |
|
1811 + |
|
1812 + if (ssi->screensaver_window) |
|
1813 + { |
|
1814 + restack_list[n++] = ssi->screensaver_window; |
|
1815 + if (ssi->screensaver_window == newWin) |
|
1816 + allowed = True; |
|
1817 + } |
|
1818 + |
|
1819 + /* If it's not in the allowed list, it goes behind |
|
1820 + the screensaver_window. */ |
|
1821 + if (newWin && !allowed) |
|
1822 + restack_list[n++] = newWin; |
|
1823 + |
|
1824 + if (n > 1) |
|
1825 + safe_XRestackWindows (si->dpy, restack_list, n); |
|
1826 +} |
|
1827 + |
|
1828 +/* Send a command to the xscreensaver-lock child process |
|
1829 + Arguments: |
|
1830 + - msg - message to send, such as ul_ok |
|
1831 + - data - additional data, such as string to display for this message, |
|
1832 + if any, otherwise NULL |
|
1833 + Message format sent to child: |
|
1834 + "msg\n" if no data, otherwise "msg=data\n" |
|
1835 + */ |
|
1836 +int |
|
1837 +write_to_child (saver_info* si, const char* msg, const char *data) |
|
1838 +{ |
|
1839 + if (msg == NULL) |
|
1840 + { |
|
1841 + fprintf (stderr, "Invalid null message written to child\n"); |
|
1842 + return -1; |
|
1843 + } |
|
1844 + |
|
1845 + if (si->external_passwd && g_passwd_dialog_created && |
|
1846 + si->pw_data->stdin_fd != -1) |
|
1847 + { |
|
1848 + int len; |
|
1849 + |
|
1850 + if (si->prefs.verbose_p) |
|
1851 + { |
|
1852 + fprintf (stderr, |
|
1853 + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" |
|
1854 + "HAVE_SCRSVR_LOCK writing to fd:%d message is:\n%s=%s\n" |
|
1855 + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n", |
|
1856 + si->pw_data->stdin_fd, msg, data ? data : "(null)"); |
|
1857 + } |
|
1858 + |
|
1859 + if (data) |
|
1860 + len = fprintf (si->pw_data->stdin_file, "%s=%s\n", msg, data); |
|
1861 + else |
|
1862 + len = fprintf (si->pw_data->stdin_file, "%s\n", msg); |
|
1863 + |
|
1864 + fflush (si->pw_data->stdin_file); |
|
1865 + return len; |
|
1866 + } |
|
1867 + |
|
1868 + return (0); /* if we didn't write anything return 0 */ |
|
1869 +} |
|
1870 + |
|
1871 +static int |
|
1872 +sane_dup2 (int fd1, int fd2) |
|
1873 +{ |
|
1874 + int ret; |
|
1875 + |
|
1876 + do |
|
1877 + { |
|
1878 + ret = dup2 (fd1, fd2); |
|
1879 + } |
|
1880 + while (ret < 0 && errno == EINTR); |
|
1881 + |
|
1882 + return ret; |
|
1883 +} |
|
1884 + |
|
1885 +static int |
|
1886 +close_and_invalidate (int *fd) |
|
1887 +{ |
|
1888 + int ret; |
|
1889 + |
|
1890 + ret = close (*fd); |
|
1891 + *fd = -1; |
|
1892 + |
|
1893 + return ret; |
|
1894 +} |
|
1895 + |
|
1896 +void |
|
1897 +handle_passwd_input (XtPointer xtdata, int *fd, XtInputId *id) |
|
1898 +{ |
|
1899 + saver_info *si = (saver_info *)xtdata; |
|
1900 + saver_preferences *p = &si->prefs; |
|
1901 + char buffer[1024]; |
|
1902 + char *msg, *data; |
|
1903 + passwd_dialog_data *pw = si->pw_data; |
|
1904 + |
|
1905 + if (p->verbose_p) |
|
1906 + fprintf (stderr, "passwd input handler() fd=%d\n", *fd); |
|
1907 + |
|
1908 + msg = fgets (buffer, sizeof (buffer), pw->stdout_file); |
|
1909 + if (!msg) /* child closed pipe */ |
|
1910 + { |
|
1911 + if (p->verbose_p) |
|
1912 + { |
|
1913 + fprintf (stderr, "done reading...\n"); |
|
1914 + fprintf (stderr, "removing input handler...\n"); |
|
1915 + } |
|
1916 + XtRemoveInput (*id); |
|
1917 + pw->stdout_input_id = 0; |
|
1918 + |
|
1919 + if (p->verbose_p) |
|
1920 + fprintf (stderr, "passwd input handler() returning...done reading\n"); |
|
1921 + |
|
1922 + return; |
|
1923 + } |
|
1924 + |
|
1925 + if (p->verbose_p) |
|
1926 + fprintf (stderr, "Child sent message: %s\n", msg); |
|
1927 + |
|
1928 + /* search for =, and if found, split msg & data into two strings there */ |
|
1929 + data = strchr(msg, '='); |
|
1930 + if (data) |
|
1931 + { |
|
1932 + char *nl; |
|
1933 + |
|
1934 + *data++ = 0; |
|
1935 + |
|
1936 + /* strip trailing newline */ |
|
1937 + nl = strchr (data, '\n'); |
|
1938 + if (nl) |
|
1939 + *nl = '\0'; |
|
1940 + } |
|
1941 + else |
|
1942 + { |
|
1943 + /* All the messages we currently expect require data! */ |
|
1944 + if (p->verbose_p) |
|
1945 + fprintf (stderr, "*** Invalid message: no data found, discarding\n"); |
|
1946 + |
|
1947 + return; |
|
1948 + } |
|
1949 + |
|
1950 + if ((strcmp(msg, "input") == 0)) /* User input */ |
|
1951 + { |
|
1952 + si->unlock_state = ul_finished; |
|
1953 + pw->got_passwd = TRUE; |
|
1954 + pw->passwd_string = strdup (data); |
|
1955 + memset (data, 0, strlen(data)); |
|
1956 + } |
|
1957 + else if ((strcmp(msg, "ungrab_keyboard") == 0)) |
|
1958 + { |
|
1959 + /* An accessibility helper needs to access the keyboard, so we have |
|
1960 + to release our grab - unfortunately this risks other apps acting |
|
1961 + on keys they shouldn't, so first we disable metacity keys that |
|
1962 + could allow getting back to the locked session windows, and hope |
|
1963 + we don't crash or die before restoring them later. |
|
1964 + |
|
1965 + Other window managers are likely to be risky to use in this case. |
|
1966 + */ |
|
1967 + |
|
1968 + if (client == NULL) |
|
1969 + client = gconf_client_get_default(); |
|
1970 + |
|
1971 + if (global_switch_key == NULL) |
|
1972 + { |
|
1973 + global_switch_key = |
|
1974 + gconf_client_get_string (client, switch_windows_gconf_key, NULL); |
|
1975 + |
|
1976 + if (global_switch_key && strncmp (global_switch_key, "dis", 3)) |
|
1977 + gconf_client_set_string (client, switch_windows_gconf_key, |
|
1978 + "disabled", NULL); |
|
1979 + } |
|
1980 + |
|
1981 + if (global_menu_key == NULL) |
|
1982 + { |
|
1983 + global_menu_key = |
|
1984 + gconf_client_get_string (client, main_menu_gconf_key, NULL); |
|
1985 + |
|
1986 + if (global_menu_key && strncmp(global_menu_key, "dis", 3)) |
|
1987 + gconf_client_set_string (client, main_menu_gconf_key, |
|
1988 + "disabled", NULL); |
|
1989 + } |
|
1990 + |
|
1991 + XUngrabKeyboard (si->dpy, CurrentTime); |
|
1992 + XFlush (si->dpy); |
|
1993 + } |
|
1994 + else if ((strcmp(msg, "ungrab_pointer") == 0)) |
|
1995 + { |
|
1996 + /* An accessibility helper needs to access the mouse, so we have |
|
1997 + to release our grab - this is simpler, since we don't worry about |
|
1998 + mouse gestures that may get through, though maybe we should... |
|
1999 + */ |
|
2000 + |
|
2001 + XUngrabPointer (si->dpy, CurrentTime); |
|
2002 + XFlush (si->dpy); |
|
2003 + } |
|
2004 + else /* Get a window id of an interesting window from the child */ |
|
2005 + { |
|
2006 + Window window = strtoul (data, NULL, 0); |
|
2007 + int status; |
|
2008 + |
|
2009 + if ((strcmp (msg, "dialog_win") == 0)) |
|
2010 + { |
|
2011 + /* The unlock dialog itself */ |
|
2012 + si->passwd_dialog = window; |
|
2013 + pw->got_windowid = True; |
|
2014 + |
|
2015 + move_mouse_grab (si, si->passwd_dialog, pw->passwd_cursor, |
|
2016 + pw->prompt_screen->number); |
|
2017 + undo_vp_motion (si); |
|
2018 + passwd_animate_timer ((XtPointer) si, 0); |
|
2019 + |
|
2020 + /* Flush queue of captured typeahead events */ |
|
2021 + if (si->typeahead_events && si->num_typeahead_events) |
|
2022 + { |
|
2023 + int i; |
|
2024 + |
|
2025 + for (i = 0; i < si->num_typeahead_events; i++) |
|
2026 + { |
|
2027 + si->typeahead_events[i].window = window; |
|
2028 + safe_XSendEvent (si->dpy, window, False, KeyPressMask, |
|
2029 + (XEvent *) &si->typeahead_events[i]); |
|
2030 + } |
|
2031 + si->num_typeahead_events = 0; |
|
2032 + } |
|
2033 + XGrabKeyboard (si->dpy, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); |
|
2034 + XGrabPointer (si->dpy, window, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); |
|
2035 + XFlush (si->dpy); |
|
2036 + XSetInputFocus (si->dpy, window, RevertToPointerRoot, CurrentTime); |
|
2037 + XSync (si->dpy, False); |
|
2038 + } |
|
2039 + else if ((strcmp (msg, "raise_win") == 0)) |
|
2040 + { |
|
2041 + /* Accessibility helpers that need to be raised above the |
|
2042 + full-screen blanking window hiding the user's desktop */ |
|
2043 + Window *newlist; |
|
2044 + Window overwin; |
|
2045 + |
|
2046 + if ( (si->num_raise_wins + EXTRA_RAISE_WIN_SLOTS) |
|
2047 + >= si->max_raise_wins) |
|
2048 + { |
|
2049 + int raise_alloc = si->max_raise_wins + WIN_ALLOC_INCREMENT; |
|
2050 + |
|
2051 + newlist = realloc(si->raise_wins, raise_alloc * sizeof(Window)); |
|
2052 + if (newlist == NULL) |
|
2053 + return; |
|
2054 + |
|
2055 + si->raise_wins = newlist; |
|
2056 + si->max_raise_wins = raise_alloc; |
|
2057 + } |
|
2058 + |
|
2059 + overwin = check_raisedWid (si, window); |
|
2060 + if (overwin) |
|
2061 + { |
|
2062 + XWindowAttributes attrs; |
|
2063 + status = XGetWindowAttributes (si->dpy, overwin, &attrs); |
|
2064 + |
|
2065 + if ( status && !attrs.override_redirect ) |
|
2066 + { |
|
2067 + unsigned long valuemask = CWOverrideRedirect; |
|
2068 + XSetWindowAttributes setwinattr; |
|
2069 + setwinattr.override_redirect = True; |
|
2070 + |
|
2071 + XChangeWindowAttributes (si->dpy, overwin, |
|
2072 + valuemask, &setwinattr); |
|
2073 + |
|
2074 + if (si->num_override_wins >= si->max_override_wins) |
|
2075 + { |
|
2076 + int over_alloc |
|
2077 + = si->max_override_wins + WIN_ALLOC_INCREMENT; |
|
2078 + |
|
2079 + newlist = realloc(si->override_wins, |
|
2080 + over_alloc * sizeof(Window)); |
|
2081 + if (newlist == NULL) |
|
2082 + return; |
|
2083 + |
|
2084 + si->override_wins = newlist; |
|
2085 + si->max_override_wins = over_alloc; |
|
2086 + } |
|
2087 + |
|
2088 + si->override_wins[si->num_override_wins++] = overwin; |
|
2089 + } |
|
2090 + XMapSubwindows(si->dpy, overwin); |
|
2091 + si->raise_wins[si->num_raise_wins++] = overwin; |
|
2092 + } |
|
2093 + else |
|
2094 + si->raise_wins[si->num_raise_wins++] = window; |
|
2095 + } /* "raise_win" */ |
|
2096 + |
|
2097 + restack_my_windows(si, si->pw_data->prompt_screen, 0); |
|
2098 + } |
|
2099 +} |
|
2100 + |
|
2101 +/* returns successful fork/exec */ |
|
2102 +Bool |
|
2103 +spawn_external_passwd_process (saver_info *si, passwd_dialog_data *pw) |
|
2104 +{ |
|
2105 + saver_preferences *p = &si->prefs; |
|
2106 + pid_t forked; |
|
2107 + const char *command = LOCKDIR "/xscreensaver-lock"; |
|
2108 + int stdin_pipe[2] = { -1, -1 }; |
|
2109 + int stdout_pipe[2] = { -1, -1 }; |
|
2110 + |
|
2111 + si->passwd_pid = 0; |
|
2112 + pw->stdin_fd = pw->stdout_fd = -1; |
|
2113 + pw->got_windowid = False; |
|
2114 + |
|
2115 + if (si->prefs.verbose_p) |
|
2116 + fprintf(stderr, "-->spawn_external_passwd()\n"); |
|
2117 + |
|
2118 + if (si->passwd_pid > 0) |
|
2119 + { |
|
2120 + if (si->prefs.verbose_p) |
|
2121 + fprintf (stderr,"pid %ld still exists. Killing it with SIGKILL\n", |
|
2122 + si->passwd_pid); |
|
2123 + kill_job (si, si->passwd_pid, SIGKILL); |
|
2124 + } |
|
2125 + si->passwd_pid = 0; |
|
2126 + |
|
2127 + if (pipe (stdin_pipe) < 0) |
|
2128 + { |
|
2129 + perror ("pipe(stdin_pipe) failed!"); |
|
2130 + return False; |
|
2131 + } |
|
2132 + |
|
2133 + if (pipe (stdout_pipe) < 0) |
|
2134 + { |
|
2135 + perror ("pipe(stdout_pipe) failed!"); |
|
2136 + close_and_invalidate (&stdin_pipe[0]); |
|
2137 + close_and_invalidate (&stdin_pipe[1]); |
|
2138 + return False; |
|
2139 + } |
|
2140 + switch ((int) (forked = fork ())) |
|
2141 + { |
|
2142 + case -1: |
|
2143 + fprintf (stderr, "%s: ", blurb ()); |
|
2144 + perror ("couldn't fork"); |
|
2145 + |
|
2146 + close_and_invalidate (&stdin_pipe[0]); |
|
2147 + close_and_invalidate (&stdin_pipe[1]); |
|
2148 + close_and_invalidate (&stdout_pipe[0]); |
|
2149 + close_and_invalidate (&stdout_pipe[1]); |
|
2150 + |
|
2151 + return False; |
|
2152 + |
|
2153 + case 0: |
|
2154 + close (ConnectionNumber (si->dpy)); /* close display fd */ |
|
2155 + /* limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); */ |
|
2156 + /* hack_subproc_environment (ssi); */ /* FIX $DISPLAY */ |
|
2157 + |
|
2158 + /* Inside Child Process */ |
|
2159 + if (p->verbose_p) |
|
2160 + fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n", |
|
2161 + blurb(), command, (unsigned long) getpid ()); |
|
2162 + |
|
2163 + close_and_invalidate (&stdin_pipe[1]); |
|
2164 + close_and_invalidate (&stdout_pipe[0]); |
|
2165 + |
|
2166 + sane_dup2 (stdin_pipe[0], 0); /* Listen to Parent from here */ |
|
2167 + sane_dup2 (stdout_pipe[1], 9); /* Talk to Parent from here */ |
|
2168 + |
|
2169 + /* Make sure we have relinquished setuid privs or lock dialog gtk |
|
2170 + * program will not run as libgtk is not setuid safe. |
|
2171 + */ |
|
2172 + hack_uid (si); |
|
2173 + |
|
2174 + exec_command (p->shell, command, 0); |
|
2175 + /* print_path_error (command); */ |
|
2176 + fprintf (stderr, "%s: couldn't exec: %s\n", |
|
2177 + blurb (), command); |
|
2178 + abort (); |
|
2179 + |
|
2180 + default: |
|
2181 + /* In Parent */ |
|
2182 + make_job(forked, 0, command); |
|
2183 + close_and_invalidate (&stdin_pipe[0]); |
|
2184 + close_and_invalidate (&stdout_pipe[1]); |
|
2185 + |
|
2186 + sane_dup2 (stdin_pipe[0], 0); /* Listen to Child from here */ |
|
2187 + sane_dup2 (stdout_pipe[1], 13); /* Talk to Child from here */ |
|
2188 + |
|
2189 + pw->stdin_fd = stdin_pipe[1]; /* Talk to child from here */ |
|
2190 + pw->stdout_fd = stdout_pipe[0]; /* Listen to Child from here */ |
|
2191 + si->passwd_pid = forked; |
|
2192 + |
|
2193 + /* Messages to child dialog are sent through this pipe/fd */ |
|
2194 + pw->stdin_file = fdopen (pw->stdin_fd, "w"); |
|
2195 + write_to_child (si, "Hello", NULL); /* Send a test message to Child */ |
|
2196 + |
|
2197 + /* Password from child dialog comes through this pipe/fd */ |
|
2198 + pw->stdout_file = fdopen (pw->stdout_fd, "r"); |
|
2199 + |
|
2200 + pw->stdout_input_id = XtAppAddInput (si->app, pw->stdout_fd, |
|
2201 + (XtPointer) XtInputReadMask, |
|
2202 + handle_passwd_input, si); |
|
2203 + |
|
2204 + /* Set global flag to indicate that lock dialog is visible */ |
|
2205 + g_passwd_dialog_created = True; |
|
2206 + return True; |
|
2207 + } |
|
2208 + |
|
2209 + /* shouldn't reach */ |
|
2210 + abort (); |
|
2211 + return False; |
|
2212 +} |
|
2213 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
2214 + |
|
2215 static int |
|
2216 new_passwd_window (saver_info *si) |
|
2217 { |
|
2218 passwd_dialog_data *pw; |
|
2219 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2220 Screen *screen; |
|
2221 Colormap cmap; |
|
2222 char *f; |
|
2223 +#endif |
|
2224 saver_screen_info *ssi = &si->screens [mouse_screen (si)]; |
|
2225 |
|
2226 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2227 + /* si->pw_data is globally allocated and never freed when HAVE_XSS_LOCK */ |
|
2228 + pw = si->pw_data; |
|
2229 + if (!spawn_external_passwd_process (si, pw)) |
|
2230 + return -1; |
|
2231 + si->external_passwd = True; |
|
2232 +#else |
|
2233 pw = (passwd_dialog_data *) calloc (1, sizeof(*pw)); |
|
2234 if (!pw) |
|
2235 return -1; |
|
2236 @@ -211,17 +721,21 @@ new_passwd_window (saver_info *si) |
|
2237 */ |
|
2238 pw->login_button_p = (si->prefs.new_login_command && |
|
2239 *si->prefs.new_login_command); |
|
2240 +#endif |
|
2241 |
|
2242 pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow); |
|
2243 |
|
2244 pw->prompt_screen = ssi; |
|
2245 |
|
2246 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2247 screen = pw->prompt_screen->screen; |
|
2248 cmap = DefaultColormapOfScreen (screen); |
|
2249 +#endif |
|
2250 |
|
2251 pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks", |
|
2252 "Boolean"); |
|
2253 |
|
2254 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2255 pw->heading_label = get_string_resource (si->dpy, "passwd.heading.label", |
|
2256 "Dialog.Label.Label"); |
|
2257 pw->body_label = get_string_resource (si->dpy, "passwd.body.label", |
|
2258 @@ -376,6 +890,7 @@ new_passwd_window (saver_info *si) |
|
2259 if (pw->shadow_width == 0) pw->shadow_width = 4; |
|
2260 if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width; |
|
2261 |
|
2262 +#endif /* ! HAVE_XSCREENSAVER_LOCK */ |
|
2263 |
|
2264 /* We need to remember the mouse position and restore it afterward, or |
|
2265 sometimes (perhaps only with Xinerama?) the mouse gets warped to |
|
2266 @@ -442,12 +957,16 @@ make_passwd_window (saver_info *si, |
|
2267 const char *prompt, |
|
2268 Bool echo) |
|
2269 { |
|
2270 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2271 XSetWindowAttributes attrs; |
|
2272 unsigned long attrmask = 0; |
|
2273 +#endif |
|
2274 passwd_dialog_data *pw; |
|
2275 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2276 Screen *screen; |
|
2277 Colormap cmap; |
|
2278 Dimension max_string_width_px; |
|
2279 +#endif |
|
2280 saver_screen_info *ssi = &si->screens [mouse_screen (si)]; |
|
2281 |
|
2282 cleanup_passwd_window (si); |
|
2283 @@ -455,7 +974,12 @@ make_passwd_window (saver_info *si, |
|
2284 if (! ssi) /* WTF? Trying to prompt while no screens connected? */ |
|
2285 return -1; |
|
2286 |
|
2287 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2288 + /* si->pw_data is globally allocated and never freed when HAVE_XSS_LOCK */ |
|
2289 + if (!si->pw_data->got_windowid) |
|
2290 +#else |
|
2291 if (!si->pw_data) |
|
2292 +#endif |
|
2293 if (new_passwd_window (si) < 0) |
|
2294 return -1; |
|
2295 |
|
2296 @@ -470,6 +994,29 @@ make_passwd_window (saver_info *si, |
|
2297 blurb(), pw->prompt_screen->number, |
|
2298 info_msg ? info_msg : ""); |
|
2299 |
|
2300 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2301 + /* Wipe the old password, so we get prompted to enter new password. */ |
|
2302 + if (pw->passwd_string) |
|
2303 + { |
|
2304 + memset(pw->passwd_string, 0, strlen (pw->passwd_string)); |
|
2305 + free (pw->passwd_string); |
|
2306 + pw->passwd_string = NULL; |
|
2307 + } |
|
2308 + |
|
2309 + if (info_msg) |
|
2310 + write_to_child (si, "ul_message", info_msg); |
|
2311 + if (prompt) |
|
2312 + { |
|
2313 + write_to_child (si, "ul_pamprompt", prompt); |
|
2314 + |
|
2315 + if (echo) |
|
2316 + write_to_child (si, "ul_prompt_echo", "true"); |
|
2317 + else if (pw->show_stars_p) |
|
2318 + write_to_child (si, "ul_prompt_echo", "stars"); |
|
2319 + else |
|
2320 + write_to_child (si, "ul_prompt_echo", "false"); |
|
2321 + } |
|
2322 +#else |
|
2323 screen = pw->prompt_screen->screen; |
|
2324 cmap = DefaultColormapOfScreen (screen); |
|
2325 |
|
2326 @@ -716,11 +1263,13 @@ make_passwd_window (saver_info *si, |
|
2327 if (cmap) |
|
2328 XInstallColormap (si->dpy, cmap); |
|
2329 draw_passwd_window (si); |
|
2330 +#endif /* ! HAVE_XSCREENSAVER_LOCK */ |
|
2331 |
|
2332 return 0; |
|
2333 } |
|
2334 |
|
2335 |
|
2336 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2337 static void |
|
2338 draw_passwd_window (saver_info *si) |
|
2339 { |
|
2340 @@ -1066,17 +1615,48 @@ draw_button(Display *dpy, |
|
2341 draw_shaded_rectangle(dpy, dialog, x, y, width, height, |
|
2342 shadow_width, shadow_light, shadow_dark); |
|
2343 } |
|
2344 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2345 |
|
2346 static void |
|
2347 update_passwd_window (saver_info *si, const char *printed_passwd, float ratio) |
|
2348 { |
|
2349 passwd_dialog_data *pw = si->pw_data; |
|
2350 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2351 XGCValues gcv; |
|
2352 GC gc1, gc2; |
|
2353 int x, y; |
|
2354 XRectangle rects[1]; |
|
2355 +#endif |
|
2356 |
|
2357 pw->ratio = ratio; |
|
2358 + |
|
2359 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2360 + /* Send countdown timer ratio to child lock dialog */ |
|
2361 + if (si->passwd_dialog) |
|
2362 + { |
|
2363 + XEvent event; |
|
2364 + |
|
2365 + event.xany.type = ClientMessage; |
|
2366 + event.xclient.display = si->dpy; |
|
2367 + event.xclient.window = si->passwd_dialog; |
|
2368 + event.xclient.message_type = XA_UNLOCK_RATIO; |
|
2369 + event.xclient.format = 32; |
|
2370 + memset (&event.xclient.data, 0, sizeof (event.xclient.data)); |
|
2371 + event.xclient.data.l[0] = (long)(pw->ratio * 100); |
|
2372 + event.xclient.data.l[1] = 0; |
|
2373 + event.xclient.data.l[2] = 0; |
|
2374 + |
|
2375 + if (!safe_XSendEvent (si->dpy, si->passwd_dialog, False, 0L, &event)) |
|
2376 + fprintf (stderr, "%s: error sending ratio to lock dialog\n", blurb ()); |
|
2377 + } |
|
2378 + else |
|
2379 + { |
|
2380 + if (si->prefs.verbose_p) |
|
2381 + fprintf (stderr, |
|
2382 + "-->update_passwd_window() lockdialog not created, returning!!\n"); |
|
2383 + return; |
|
2384 + } |
|
2385 +#else |
|
2386 gcv.foreground = pw->passwd_foreground; |
|
2387 gcv.font = pw->passwd_font->fid; |
|
2388 gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv); |
|
2389 @@ -1221,6 +1801,7 @@ update_passwd_window (saver_info *si, const char *printed_passwd, float ratio) |
|
2390 XFreeGC (si->dpy, gc1); |
|
2391 XFreeGC (si->dpy, gc2); |
|
2392 XSync (si->dpy, False); |
|
2393 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2394 } |
|
2395 |
|
2396 |
|
2397 @@ -1252,6 +1833,9 @@ cleanup_passwd_window (saver_info *si) |
|
2398 { |
|
2399 passwd_dialog_data *pw; |
|
2400 |
|
2401 + if (si->prefs.verbose_p) |
|
2402 + fprintf (stderr, "cleanup_passwd_window\n"); |
|
2403 + |
|
2404 if (!(pw = si->pw_data)) |
|
2405 return; |
|
2406 |
|
2407 @@ -1269,7 +1853,13 @@ cleanup_passwd_window (saver_info *si) |
|
2408 |
|
2409 memset (pw->typed_passwd, 0, sizeof(pw->typed_passwd)); |
|
2410 memset (pw->typed_passwd_char_size, 0, sizeof(pw->typed_passwd_char_size)); |
|
2411 - memset (pw->passwd_string, 0, strlen(pw->passwd_string)); |
|
2412 + if (pw->passwd_string) |
|
2413 + { |
|
2414 + memset (pw->passwd_string, 0, strlen(pw->passwd_string)); |
|
2415 + free (pw->passwd_string); |
|
2416 + pw->passwd_string = NULL; |
|
2417 + } |
|
2418 + |
|
2419 |
|
2420 if (pw->timer) |
|
2421 { |
|
2422 @@ -1292,8 +1882,10 @@ destroy_passwd_window (saver_info *si) |
|
2423 passwd_dialog_data *pw = si->pw_data; |
|
2424 saver_screen_info *ssi = pw->prompt_screen; |
|
2425 Colormap cmap = DefaultColormapOfScreen (ssi->screen); |
|
2426 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2427 Pixel black = BlackPixelOfScreen (ssi->screen); |
|
2428 Pixel white = WhitePixelOfScreen (ssi->screen); |
|
2429 +#endif |
|
2430 XEvent event; |
|
2431 |
|
2432 cleanup_passwd_window (si); |
|
2433 @@ -1309,6 +1901,81 @@ destroy_passwd_window (saver_info *si) |
|
2434 si->cached_passwd = NULL; |
|
2435 } |
|
2436 |
|
2437 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2438 + /* reset global flag to indicate passwd dialog is no longer there */ |
|
2439 + g_passwd_dialog_created = False; |
|
2440 + |
|
2441 + if (si->external_passwd) |
|
2442 + { |
|
2443 + /* kill the child etc. */ |
|
2444 + write_to_child (si, "cmd_exit", NULL); |
|
2445 + |
|
2446 + if (pw->stdin_file) |
|
2447 + fclose (pw->stdin_file); |
|
2448 + if (pw->stdin_fd != -1) |
|
2449 + close_and_invalidate (&pw->stdin_fd); |
|
2450 + if (pw->stdout_input_id) |
|
2451 + XtRemoveInput (pw->stdout_input_id); |
|
2452 + if (pw->stdout_file) |
|
2453 + fclose (pw->stdout_file); |
|
2454 + else if (pw->stdout_fd != -1) |
|
2455 + close_and_invalidate (&pw->stdout_fd); |
|
2456 + |
|
2457 + if (si->passwd_pid) |
|
2458 + { |
|
2459 + kill_job (si, si->passwd_pid, SIGTERM); |
|
2460 + si->passwd_pid = 0; |
|
2461 + } |
|
2462 + |
|
2463 + free (si->raise_wins); |
|
2464 + si->raise_wins = NULL; |
|
2465 + si->num_raise_wins = 0; |
|
2466 + si->max_raise_wins = 0; |
|
2467 + |
|
2468 + if (si->override_wins) |
|
2469 + { |
|
2470 + int n; |
|
2471 + |
|
2472 + unsigned long valuemask = CWOverrideRedirect; |
|
2473 + XSetWindowAttributes setwinattr; |
|
2474 + setwinattr.override_redirect = False; |
|
2475 + |
|
2476 + for (n = 0; n < si->num_override_wins; n++) |
|
2477 + { |
|
2478 + XChangeWindowAttributes (si->dpy, si->override_wins[n], |
|
2479 + valuemask, &setwinattr); |
|
2480 + } |
|
2481 + free(si->override_wins); |
|
2482 + si->override_wins = NULL; |
|
2483 + } |
|
2484 + si->num_override_wins = 0; |
|
2485 + si->max_override_wins = 0; |
|
2486 + |
|
2487 + si->pw_data->got_windowid = False; |
|
2488 + si->external_passwd = False; |
|
2489 + |
|
2490 + /* restore any metacity keys we temporarily disabled */ |
|
2491 + if (client) |
|
2492 + { |
|
2493 + if (global_switch_key) |
|
2494 + { |
|
2495 + gconf_client_set_string (client, switch_windows_gconf_key, |
|
2496 + global_switch_key, NULL); |
|
2497 + g_free(global_switch_key); |
|
2498 + global_switch_key = NULL; |
|
2499 + } |
|
2500 + |
|
2501 + if (global_menu_key) |
|
2502 + { |
|
2503 + gconf_client_set_string (client, main_menu_gconf_key, |
|
2504 + global_menu_key, NULL); |
|
2505 + g_free(global_menu_key); |
|
2506 + global_menu_key = NULL; |
|
2507 + } |
|
2508 + } |
|
2509 + } |
|
2510 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
2511 + |
|
2512 move_mouse_grab (si, RootWindowOfScreen (ssi->screen), |
|
2513 ssi->cursor, ssi->number); |
|
2514 |
|
2515 @@ -1343,7 +2010,14 @@ destroy_passwd_window (saver_info *si) |
|
2516 fprintf (stderr, "%s: %d: destroying password dialog.\n", |
|
2517 blurb(), pw->prompt_screen->number); |
|
2518 |
|
2519 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2520 + /* Ignore X error if window was already closed by the child, |
|
2521 + and make sure any VisibilityNotify events are removed |
|
2522 + from the event queue before we forget the window id. */ |
|
2523 + safe_XDestroyWindow (si->dpy, si->passwd_dialog); |
|
2524 +#else |
|
2525 XDestroyWindow (si->dpy, si->passwd_dialog); |
|
2526 +#endif |
|
2527 si->passwd_dialog = 0; |
|
2528 } |
|
2529 |
|
2530 @@ -1354,6 +2028,7 @@ destroy_passwd_window (saver_info *si) |
|
2531 pw->save_under = 0; |
|
2532 } |
|
2533 |
|
2534 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2535 if (pw->heading_label) free (pw->heading_label); |
|
2536 if (pw->body_label) free (pw->body_label); |
|
2537 if (pw->user_label) free (pw->user_label); |
|
2538 @@ -1404,6 +2079,7 @@ destroy_passwd_window (saver_info *si) |
|
2539 pw->logo_pixels = 0; |
|
2540 pw->logo_npixels = 0; |
|
2541 } |
|
2542 +#endif /* ! HAVE_XSCREENSAVER_LOCK */ |
|
2543 |
|
2544 if (pw->save_under) |
|
2545 XFreePixmap (si->dpy, pw->save_under); |
|
2546 @@ -1411,9 +2087,12 @@ destroy_passwd_window (saver_info *si) |
|
2547 if (cmap) |
|
2548 XInstallColormap (si->dpy, cmap); |
|
2549 |
|
2550 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2551 + /* si->pw_data is globally allocated and never freed when HAVE_XSS_LOCK */ |
|
2552 memset (pw, 0, sizeof(*pw)); |
|
2553 free (pw); |
|
2554 si->pw_data = 0; |
|
2555 +#endif |
|
2556 } |
|
2557 |
|
2558 |
|
2559 @@ -1426,6 +2105,49 @@ ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) |
|
2560 return 0; |
|
2561 } |
|
2562 |
|
2563 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2564 +/* Catch errors from XRestackWindows, since there's an inherent race |
|
2565 + condition in which other clients can destroy windows between when |
|
2566 + we get the notification event and when we send the RestackWindows |
|
2567 + response to it. */ |
|
2568 +static Bool |
|
2569 +safe_XRestackWindows(Display *dpy, Window windows[], int nwindows) |
|
2570 +{ |
|
2571 + XErrorHandler old_handler; |
|
2572 + XSync (dpy, False); |
|
2573 + error_handler_hit_p = False; |
|
2574 + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); |
|
2575 + |
|
2576 + XRestackWindows (dpy, windows, nwindows); |
|
2577 + |
|
2578 + XSync (dpy, False); |
|
2579 + XSetErrorHandler (old_handler); |
|
2580 + XSync (dpy, False); |
|
2581 + |
|
2582 + return (!error_handler_hit_p); |
|
2583 +} |
|
2584 + |
|
2585 +static Bool |
|
2586 +safe_XSendEvent(Display *dpy, Window w, Bool propagate, |
|
2587 + long event_mask, XEvent *event_send) |
|
2588 +{ |
|
2589 + Status status; |
|
2590 + XErrorHandler old_handler; |
|
2591 + XSync (dpy, False); |
|
2592 + error_handler_hit_p = False; |
|
2593 + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); |
|
2594 + |
|
2595 + status = XSendEvent (dpy, w, propagate, event_mask, event_send); |
|
2596 + |
|
2597 + XSync (dpy, False); |
|
2598 + XSetErrorHandler (old_handler); |
|
2599 + XSync (dpy, False); |
|
2600 + |
|
2601 + return (!error_handler_hit_p && status); |
|
2602 +} |
|
2603 + |
|
2604 +#endif |
|
2605 + |
|
2606 |
|
2607 #ifdef HAVE_XHPDISABLERESET |
|
2608 /* This function enables and disables the C-Sh-Reset hot-key, which |
|
2609 @@ -1627,6 +2349,17 @@ passwd_animate_timer (XtPointer closure, XtIntervalId *id) |
|
2610 |
|
2611 if (!pw) return; |
|
2612 |
|
2613 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2614 + /* We want to make sure dialog is up before we update countdown timer */ |
|
2615 + if (!si->passwd_dialog) |
|
2616 + { |
|
2617 + if (si->prefs.verbose_p) |
|
2618 + fprintf (stderr, |
|
2619 + "-->passwd_animate_timer() returning..no dialog yet\n"); |
|
2620 + return; |
|
2621 + } |
|
2622 +#endif |
|
2623 + |
|
2624 pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick)); |
|
2625 if (pw->ratio < 0) |
|
2626 { |
|
2627 @@ -1646,6 +2379,7 @@ passwd_animate_timer (XtPointer closure, XtIntervalId *id) |
|
2628 idle_timer ((XtPointer) si, 0); |
|
2629 } |
|
2630 |
|
2631 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2632 |
|
2633 static XComposeStatus *compose_status; |
|
2634 |
|
2635 @@ -1723,6 +2457,7 @@ finished_typing_passwd (saver_info *si, passwd_dialog_data *pw) |
|
2636 update_passwd_window (si, "", pw->ratio); |
|
2637 } |
|
2638 } |
|
2639 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2640 |
|
2641 static void |
|
2642 handle_passwd_key (saver_info *si, XKeyEvent *event) |
|
2643 @@ -1730,7 +2465,8 @@ handle_passwd_key (saver_info *si, XKeyEvent *event) |
|
2644 passwd_dialog_data *pw = si->pw_data; |
|
2645 unsigned char decoded [MAX_BYTES_PER_CHAR * 10]; /* leave some slack */ |
|
2646 KeySym keysym = 0; |
|
2647 - |
|
2648 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2649 + |
|
2650 /* XLookupString may return more than one character via XRebindKeysym; |
|
2651 and on some systems it returns multi-byte UTF-8 characters (contrary |
|
2652 to its documentation, which says it returns only Latin1.) |
|
2653 @@ -1764,11 +2500,40 @@ handle_passwd_key (saver_info *si, XKeyEvent *event) |
|
2654 |
|
2655 decoded[decoded_size] = 0; |
|
2656 pw->passwd_changed_p = True; |
|
2657 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2658 |
|
2659 /* Add 10% to the time remaining every time a key is pressed. */ |
|
2660 pw->ratio += 0.1; |
|
2661 if (pw->ratio > 1) pw->ratio = 1; |
|
2662 |
|
2663 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2664 + if (si->pw_data->got_windowid) |
|
2665 + { |
|
2666 + Bool status; |
|
2667 + |
|
2668 + if (si->prefs.verbose_p) |
|
2669 + fprintf (stderr, "event loop..gotwindowid..and keypress event...\n"); |
|
2670 + |
|
2671 + event->window = si->passwd_dialog; |
|
2672 + |
|
2673 + status = safe_XSendEvent (si->dpy, si->passwd_dialog, |
|
2674 + False, KeyPressMask, (XEvent *) event); |
|
2675 + |
|
2676 + if (si->prefs.verbose_p) |
|
2677 + { |
|
2678 + if (status) |
|
2679 + fprintf (stderr, "sent key...\n"); |
|
2680 + else |
|
2681 + fprintf (stderr, "error %d sending key...\n", status); |
|
2682 + } |
|
2683 + update_passwd_window (si, NULL, pw->ratio); |
|
2684 + } |
|
2685 + else |
|
2686 + { |
|
2687 + swallow_unlock_typeahead_events (si, (XEvent *) event); |
|
2688 + } |
|
2689 + |
|
2690 +#else /* !HAVE_XSCREENSAVER_LOCK */ |
|
2691 if (decoded_size == 1) /* Handle single-char commands */ |
|
2692 { |
|
2693 switch (*decoded) |
|
2694 @@ -1858,6 +2623,7 @@ handle_passwd_key (saver_info *si, XKeyEvent *event) |
|
2695 { |
|
2696 update_passwd_window (si, "", pw->ratio); |
|
2697 } |
|
2698 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2699 } |
|
2700 |
|
2701 |
|
2702 @@ -1880,7 +2646,9 @@ passwd_event_loop (saver_info *si) |
|
2703 |
|
2704 passwd_animate_timer ((XtPointer) si, 0); |
|
2705 |
|
2706 - while (si->unlock_state == ul_read) |
|
2707 + si->pw_data->got_passwd = FALSE; |
|
2708 + |
|
2709 + while (si->unlock_state == ul_read && si->pw_data->got_passwd == FALSE) |
|
2710 { |
|
2711 XtAppNextEvent (si->app, &event.x_event); |
|
2712 |
|
2713 @@ -1921,12 +2689,17 @@ passwd_event_loop (saver_info *si) |
|
2714 |
|
2715 if (event.x_event.xany.window == si->passwd_dialog && |
|
2716 event.x_event.xany.type == Expose) |
|
2717 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2718 + XtDispatchEvent (&event.x_event); |
|
2719 +#else |
|
2720 draw_passwd_window (si); |
|
2721 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2722 else if (event.x_event.xany.type == KeyPress) |
|
2723 { |
|
2724 handle_passwd_key (si, &event.x_event.xkey); |
|
2725 si->pw_data->caps_p = (event.x_event.xkey.state & LockMask); |
|
2726 } |
|
2727 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2728 else if (event.x_event.xany.type == ButtonPress || |
|
2729 event.x_event.xany.type == ButtonRelease) |
|
2730 { |
|
2731 @@ -1935,6 +2708,82 @@ passwd_event_loop (saver_info *si) |
|
2732 if (si->pw_data->login_button_p) |
|
2733 handle_login_button (si, &event.x_event); |
|
2734 } |
|
2735 +#endif /* !HAVE_XSCREENSAVER_LOCK */ |
|
2736 + |
|
2737 + /* |
|
2738 + 5077974 P1 "Bug 147583: Screen Lock unlocks because of GOK dwell movement in |
|
2739 + core pointer mode" |
|
2740 + |
|
2741 + ScreenLock did not unlock the screen, but WM's XRestackWindow() did. |
|
2742 + Once WM/metacity fixes the problem, the code can be removed. |
|
2743 + The problem: |
|
2744 + repositioning the Wids in the wrong positions when |
|
2745 + 1. the window type is changed from NORMAL to DOCK or vice versa |
|
2746 + 2. the Wid is managed |
|
2747 + within the X window stack with or without screen-lock in a mixed Wids |
|
2748 + there are two temp. get-around solutions: |
|
2749 + 1. non-managed GOK or MAG Wid |
|
2750 + or |
|
2751 + 2. screensaver picks up the WM's restacking task and fixes the prevous |
|
2752 + restacking problem. |
|
2753 + the cons: there is a flashing screen when corepointer is touching |
|
2754 + GOK or MAG and mouse is moved in a fast way |
|
2755 + when GOK or MAG window type is DOCK only. |
|
2756 + and it is not a good temp. get-around solution. |
|
2757 + This is the only choice if WM did not want to fix the problem now |
|
2758 + and AT group did not want to use non-managed Wids. |
|
2759 + Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed |
|
2760 + not to be used, and GOK cannot disable it |
|
2761 + */ |
|
2762 +/* |
|
2763 + bugid 6769901,6839026: popup windows appearing through xscreensaver |
|
2764 +*/ |
|
2765 + else if (((event.x_event.xany.type == UnmapNotify) |
|
2766 + || (event.x_event.xany.type == MapNotify) |
|
2767 + || (event.x_event.xany.type == VisibilityNotify) |
|
2768 + || (event.x_event.xany.type == ConfigureNotify) |
|
2769 + || (event.x_event.xany.type == PropertyNotify) |
|
2770 + || (event.x_event.xany.type == CreateNotify) |
|
2771 + || (event.x_event.xany.type == ReparentNotify)) |
|
2772 + && (si->passwd_dialog)) |
|
2773 + { |
|
2774 + /* Find the handle of popup window |
|
2775 + * Note: we can not get handle of popup window with |
|
2776 + * event.xany.window, thats why we have switch cases. |
|
2777 + */ |
|
2778 + Window wPopWin = 0; |
|
2779 + |
|
2780 + switch(event.x_event.xany.type) |
|
2781 + { |
|
2782 + case ConfigureNotify: |
|
2783 + wPopWin = event.x_event.xconfigure.window; |
|
2784 + break; |
|
2785 + case CreateNotify: |
|
2786 + wPopWin = event.x_event.xcreatewindow.window; |
|
2787 + break; |
|
2788 + case VisibilityNotify: |
|
2789 + wPopWin = event.x_event.xvisibility.window; |
|
2790 + break; |
|
2791 + default: |
|
2792 + break; |
|
2793 + } |
|
2794 + |
|
2795 + if (wPopWin) |
|
2796 + { |
|
2797 + saver_screen_info *ssi = find_screen_for_window (si, wPopWin); |
|
2798 + |
|
2799 + /* This if case is for safety, it prevent screensaver stuck in |
|
2800 + * loop of ConfigureNotify |
|
2801 + */ |
|
2802 + if ((wPopWin != si->passwd_dialog) && (ssi != NULL) && |
|
2803 + (wPopWin != ssi->screensaver_window) && |
|
2804 + (wPopWin != ssi->stderr_overlay_window)) |
|
2805 + { |
|
2806 + restack_my_windows(si, ssi, wPopWin); |
|
2807 + } |
|
2808 + } |
|
2809 + } |
|
2810 + /* the above new code for restacking under the condition */ |
|
2811 else |
|
2812 XtDispatchEvent (&event.x_event); |
|
2813 } |
|
2814 @@ -1960,8 +2809,13 @@ passwd_event_loop (saver_info *si) |
|
2815 |
|
2816 if (msg) |
|
2817 { |
|
2818 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2819 + write_to_child (si, "ul_message", msg); |
|
2820 + usleep (250000); /* 1/4 second */ |
|
2821 +#else |
|
2822 si->pw_data->i_beam = 0; |
|
2823 update_passwd_window (si, msg, 0.0); |
|
2824 +#endif |
|
2825 XSync (si->dpy, False); |
|
2826 |
|
2827 /* Swallow all pending KeyPress/KeyRelease events. */ |
|
2828 @@ -1977,6 +2831,10 @@ passwd_event_loop (saver_info *si) |
|
2829 static void |
|
2830 handle_typeahead (saver_info *si) |
|
2831 { |
|
2832 +/* HAVE_XSCREENSAVER_LOCK: typeahead events are flushed to the external |
|
2833 + dialog program in handle_passwd_input when we get the dialog_win notice |
|
2834 + that it has created the window */ |
|
2835 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2836 passwd_dialog_data *pw = si->pw_data; |
|
2837 int i; |
|
2838 if (!si->unlock_typeahead) |
|
2839 @@ -2004,6 +2862,7 @@ handle_typeahead (saver_info *si) |
|
2840 |
|
2841 free (si->unlock_typeahead); |
|
2842 si->unlock_typeahead = 0; |
|
2843 +#endif |
|
2844 } |
|
2845 |
|
2846 |
|
2847 @@ -2109,9 +2968,11 @@ gui_auth_conv(int num_msg, |
|
2848 free(prompt_trimmed); |
|
2849 } |
|
2850 |
|
2851 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2852 compose_status = calloc (1, sizeof (*compose_status)); |
|
2853 if (!compose_status) |
|
2854 goto fail; |
|
2855 +#endif |
|
2856 |
|
2857 si->unlock_state = ul_read; |
|
2858 |
|
2859 @@ -2121,7 +2982,14 @@ gui_auth_conv(int num_msg, |
|
2860 if (si->unlock_state == ul_cancel) |
|
2861 goto fail; |
|
2862 |
|
2863 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
2864 + if ((si->unlock_state != ul_time) && si->pw_data->passwd_string) |
|
2865 + responses[i].response = strdup (si->pw_data->passwd_string); |
|
2866 + else |
|
2867 + goto fail; |
|
2868 +#else |
|
2869 responses[i].response = strdup(si->pw_data->typed_passwd); |
|
2870 +#endif |
|
2871 |
|
2872 /* Cache the first response to a PROMPT_NOECHO to save prompting for |
|
2873 * each auth mechanism. */ |
|
2874 @@ -2129,8 +2997,10 @@ gui_auth_conv(int num_msg, |
|
2875 auth_msgs[i].type == AUTH_MSGTYPE_PROMPT_NOECHO) |
|
2876 si->cached_passwd = strdup(responses[i].response); |
|
2877 |
|
2878 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2879 free (compose_status); |
|
2880 compose_status = 0; |
|
2881 +#endif |
|
2882 } |
|
2883 |
|
2884 *resp = responses; |
|
2885 @@ -2138,9 +3008,11 @@ gui_auth_conv(int num_msg, |
|
2886 return (si->unlock_state == ul_finished) ? 0 : -1; |
|
2887 |
|
2888 fail: |
|
2889 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2890 if (compose_status) |
|
2891 free (compose_status); |
|
2892 compose_status = 0; |
|
2893 +#endif |
|
2894 |
|
2895 if (responses) |
|
2896 { |
|
2897 @@ -2196,11 +3068,14 @@ auth_finished_cb (saver_info *si) |
|
2898 if (XPending (si->dpy)) |
|
2899 { |
|
2900 XNextEvent (si->dpy, &event); |
|
2901 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
2902 if (event.xany.window == si->passwd_dialog && |
|
2903 event.xany.type == Expose) |
|
2904 draw_passwd_window (si); |
|
2905 - else if (event.xany.type == ButtonPress || |
|
2906 - event.xany.type == KeyPress) |
|
2907 + else |
|
2908 +#endif |
|
2909 + if (event.xany.type == ButtonPress || |
|
2910 + event.xany.type == KeyPress) |
|
2911 break; |
|
2912 XSync (si->dpy, False); |
|
2913 } |
|
2914 diff --git a/driver/passwd-pam.c b/driver/passwd-pam.c |
|
2915 --- a/driver/passwd-pam.c |
|
2916 +++ b/driver/passwd-pam.c |
|
2917 @@ -39,10 +39,16 @@ |
|
2918 #ifndef NO_LOCKING /* whole file */ |
|
2919 |
|
2920 #include <stdlib.h> |
|
2921 +#include <xscreensaver-intl.h> |
|
2922 + |
|
2923 #ifdef HAVE_UNISTD_H |
|
2924 # include <unistd.h> |
|
2925 #endif |
|
2926 |
|
2927 +#ifdef __sun |
|
2928 +# include <deflt.h> |
|
2929 +#endif |
|
2930 + |
|
2931 extern char *blurb(void); |
|
2932 |
|
2933 |
|
2934 @@ -58,6 +64,7 @@ extern char *blurb(void); |
|
2935 |
|
2936 #include <sys/stat.h> |
|
2937 |
|
2938 +#include "dialog-data.h" |
|
2939 #include "auth.h" |
|
2940 |
|
2941 extern sigset_t block_sigchld (void); |
|
2942 @@ -82,7 +89,10 @@ extern void unblock_sigchld (void); |
|
2943 #endif |
|
2944 |
|
2945 static int pam_conversation (int nmsgs, |
|
2946 - const struct pam_message **msg, |
|
2947 +#ifndef __sun |
|
2948 + const |
|
2949 +#endif |
|
2950 + struct pam_message **msg, |
|
2951 struct pam_response **resp, |
|
2952 void *closure); |
|
2953 |
|
2954 @@ -183,6 +193,11 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
2955 struct pam_conv pc; |
|
2956 sigset_t set; |
|
2957 struct timespec timeout; |
|
2958 + int pam_auth_status = 0; /* Specific for pam_authenticate() status*/ |
|
2959 + int acct_rc, setcred_rc, chauth_rc; |
|
2960 + int pam_flags = 0; |
|
2961 + |
|
2962 + uid_t euid = geteuid(); |
|
2963 |
|
2964 pc.conv = &pam_conversation; |
|
2965 pc.appdata_ptr = (void *) si; |
|
2966 @@ -191,6 +206,23 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
2967 `closure' argument to pc.conv always comes in as random garbage. */ |
|
2968 suns_pam_implementation_blows = (void *) si; |
|
2969 |
|
2970 +#ifdef __sun |
|
2971 + if (verbose_p) |
|
2972 + fprintf (stderr, "Before uid=%d euid=%d \n\n", getuid(), geteuid()); |
|
2973 + |
|
2974 + if (seteuid (0) != 0) |
|
2975 + { |
|
2976 + if (verbose_p) |
|
2977 + perror("Could not change euid to root, pam may not work!\n"); |
|
2978 + } |
|
2979 + |
|
2980 + if (verbose_p) |
|
2981 + { |
|
2982 + fprintf (stderr, "After seteuid(0) uid=%d euid=%d \n\n", |
|
2983 + getuid(), geteuid()); |
|
2984 + fprintf (stderr, "PAM is using SERVICE_NAME=\"%s\"\n\n", service); |
|
2985 + } |
|
2986 +#endif |
|
2987 |
|
2988 /* Initialize PAM. |
|
2989 */ |
|
2990 @@ -201,11 +233,35 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
2991 status, PAM_STRERROR (pamh, status)); |
|
2992 if (status != PAM_SUCCESS) goto DONE; |
|
2993 |
|
2994 +#ifdef __sun |
|
2995 + /* Check /etc/default/login to see if we should add |
|
2996 + PAM_DISALLOW_NULL_AUTHTOK to pam_flags */ |
|
2997 + if (defopen("/etc/default/login") == 0) { |
|
2998 + char *ptr; |
|
2999 + int flags = defcntl(DC_GETFLAGS, 0); |
|
3000 + |
|
3001 + TURNOFF(flags, DC_CASE); |
|
3002 + (void) defcntl(DC_SETFLAGS, flags); |
|
3003 + if ((ptr = defread("PASSREQ=")) != NULL && |
|
3004 + strcasecmp("YES", ptr) == 0) |
|
3005 + { |
|
3006 + pam_flags |= PAM_DISALLOW_NULL_AUTHTOK; |
|
3007 + } |
|
3008 + |
|
3009 + (void) defopen((char *)NULL); /* close current file */ |
|
3010 + } |
|
3011 +#endif |
|
3012 + |
|
3013 /* #### We should set PAM_TTY to the display we're using, but we |
|
3014 don't have that handy from here. So set it to :0.0, which is a |
|
3015 good guess (and has the bonus of counting as a "secure tty" as |
|
3016 far as PAM is concerned...) |
|
3017 */ |
|
3018 + |
|
3019 +/* From the pam trace and log file, it is found out that the |
|
3020 + Sun pam modules can drive itself. |
|
3021 +*/ |
|
3022 +#ifndef __sun |
|
3023 { |
|
3024 char *tty = strdup (":0.0"); |
|
3025 status = pam_set_item (pamh, PAM_TTY, tty); |
|
3026 @@ -214,6 +270,7 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
3027 blurb(), tty, status, PAM_STRERROR(pamh, status)); |
|
3028 free (tty); |
|
3029 } |
|
3030 +#endif |
|
3031 |
|
3032 /* Try to authenticate as the current user. |
|
3033 We must turn off our SIGCHLD handler for the duration of the call to |
|
3034 @@ -243,43 +300,102 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
3035 timeout.tv_sec = 0; |
|
3036 timeout.tv_nsec = 1; |
|
3037 set = block_sigchld(); |
|
3038 - status = pam_authenticate (pamh, 0); |
|
3039 + pam_auth_status = pam_authenticate (pamh, pam_flags); |
|
3040 # ifdef HAVE_SIGTIMEDWAIT |
|
3041 sigtimedwait (&set, NULL, &timeout); |
|
3042 /* #### What is the portable thing to do if we don't have it? */ |
|
3043 # endif /* HAVE_SIGTIMEDWAIT */ |
|
3044 unblock_sigchld(); |
|
3045 |
|
3046 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3047 + /* Send status message to unlock dialog */ |
|
3048 + if (pam_auth_status == PAM_SUCCESS) |
|
3049 + { |
|
3050 + if (verbose_p) |
|
3051 + write_to_child (si, "ul_ok", PAM_STRERROR (pamh, pam_auth_status)); |
|
3052 + } |
|
3053 + else if (si->unlock_state != ul_cancel && si->unlock_state != ul_time) |
|
3054 + { |
|
3055 + write_to_child (si, "ul_fail", PAM_STRERROR (pamh, pam_auth_status)); |
|
3056 + } |
|
3057 + if (verbose_p) |
|
3058 + sleep (1); |
|
3059 +#endif |
|
3060 + |
|
3061 + if (verbose_p) |
|
3062 + fprintf (stderr, "after calling pam_authenticate state is: %s\n", |
|
3063 + si->unlock_state == ul_success ? "ul_success" : "ul_fail"); |
|
3064 + |
|
3065 if (verbose_p) |
|
3066 fprintf (stderr, "%s: pam_authenticate (...) ==> %d (%s)\n", |
|
3067 - blurb(), status, PAM_STRERROR(pamh, status)); |
|
3068 + blurb(), pam_auth_status, PAM_STRERROR(pamh, pam_auth_status)); |
|
3069 |
|
3070 - if (status == PAM_SUCCESS) /* Win! */ |
|
3071 + if (pam_auth_status == PAM_SUCCESS) /* Win! */ |
|
3072 { |
|
3073 - int status2; |
|
3074 + /* perform PAM account validation procedures for login user only */ |
|
3075 + acct_rc = pam_acct_mgmt(pamh, pam_flags); |
|
3076 |
|
3077 - /* We don't actually care if the account modules fail or succeed, |
|
3078 - * but we need to run them anyway because certain pam modules |
|
3079 - * depend on side effects of the account modules getting run. |
|
3080 - */ |
|
3081 - status2 = pam_acct_mgmt (pamh, 0); |
|
3082 + /****************************************************************** |
|
3083 + ignore other cases for the time being |
|
3084 + PAM_USER_UNKNOWN, PAM_AUTH_ERR, PAM_ACCT_EXPIRED |
|
3085 + (password mgn service module) |
|
3086 + same as pam_setcred(), focus on auth. service module only |
|
3087 + *****************************************************************/ |
|
3088 |
|
3089 if (verbose_p) |
|
3090 fprintf (stderr, "%s: pam_acct_mgmt (...) ==> %d (%s)\n", |
|
3091 - blurb(), status2, PAM_STRERROR(pamh, status2)); |
|
3092 + blurb(), acct_rc, PAM_STRERROR(pamh, acct_rc)); |
|
3093 + |
|
3094 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3095 + /* Send status message to unlock dialog ***/ |
|
3096 + if (acct_rc == PAM_SUCCESS) |
|
3097 + { |
|
3098 + if (verbose_p) |
|
3099 + write_to_child (si, "ul_acct_ok", PAM_STRERROR(pamh, acct_rc)); |
|
3100 + } |
|
3101 + else |
|
3102 + write_to_child (si, "ul_acct_fail", PAM_STRERROR(pamh, acct_rc)); |
|
3103 + if (verbose_p) |
|
3104 + sleep (1); |
|
3105 +#endif |
|
3106 |
|
3107 /* HPUX for some reason likes to make PAM defines different from |
|
3108 * everyone else's. */ |
|
3109 #ifdef PAM_AUTHTOKEN_REQD |
|
3110 - if (status2 == PAM_AUTHTOKEN_REQD) |
|
3111 + if (acct_rc == PAM_AUTHTOKEN_REQD) |
|
3112 #else |
|
3113 - if (status2 == PAM_NEW_AUTHTOK_REQD) |
|
3114 + if (acct_rc == PAM_NEW_AUTHTOK_REQD) |
|
3115 #endif |
|
3116 { |
|
3117 - status2 = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); |
|
3118 + int i; |
|
3119 + for (i = 0; i < 3; i++) |
|
3120 + { |
|
3121 + chauth_rc = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); |
|
3122 + if (chauth_rc == PAM_AUTHTOK_ERR || |
|
3123 + chauth_rc == PAM_TRY_AGAIN ) |
|
3124 + { |
|
3125 + i = 0; |
|
3126 + si->unlock_state = ul_read; |
|
3127 + } |
|
3128 + else break; /* get out of the loop */ |
|
3129 + } |
|
3130 + |
|
3131 if (verbose_p) |
|
3132 fprintf (stderr, "%s: pam_chauthtok (...) ==> %d (%s)\n", |
|
3133 - blurb(), status2, PAM_STRERROR(pamh, status2)); |
|
3134 + blurb(), chauth_rc, PAM_STRERROR(pamh, chauth_rc)); |
|
3135 + |
|
3136 + if (chauth_rc != PAM_SUCCESS) |
|
3137 + { |
|
3138 + pam_auth_status = chauth_rc; |
|
3139 + goto DONE; |
|
3140 + } |
|
3141 + } |
|
3142 + else if (acct_rc != PAM_SUCCESS) |
|
3143 + { |
|
3144 + pam_auth_status = acct_rc; |
|
3145 + write_to_child (si, "pw_acct_fail", PAM_STRERROR(pamh, acct_rc)); |
|
3146 + sleep (3); |
|
3147 + goto DONE; |
|
3148 } |
|
3149 |
|
3150 /* Each time we successfully authenticate, refresh credentials, |
|
3151 @@ -291,24 +406,57 @@ pam_try_unlock(saver_info *si, Bool verbose_p, |
|
3152 says that the Linux PAM library ignores that one, and only refreshes |
|
3153 credentials when using PAM_REINITIALIZE_CRED. |
|
3154 */ |
|
3155 - status2 = pam_setcred (pamh, PAM_REINITIALIZE_CRED); |
|
3156 + setcred_rc = pam_setcred (pamh, PAM_REINITIALIZE_CRED); |
|
3157 if (verbose_p) |
|
3158 fprintf (stderr, "%s: pam_setcred (...) ==> %d (%s)\n", |
|
3159 - blurb(), status2, PAM_STRERROR(pamh, status2)); |
|
3160 + blurb(), setcred_rc, PAM_STRERROR(pamh, setcred_rc)); |
|
3161 + |
|
3162 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3163 + /* Send status message to unlock dialog ***/ |
|
3164 + if (setcred_rc == PAM_SUCCESS) |
|
3165 + { |
|
3166 + if (verbose_p) |
|
3167 + write_to_child (si, "ul_setcred_ok", PAM_STRERROR(pamh, setcred_rc)); |
|
3168 + } |
|
3169 + else |
|
3170 + write_to_child (si, "ul_setcred_fail", PAM_STRERROR(pamh, setcred_rc)); |
|
3171 + if (verbose_p) |
|
3172 + sleep (1); |
|
3173 +#endif |
|
3174 } |
|
3175 |
|
3176 DONE: |
|
3177 if (pamh) |
|
3178 { |
|
3179 - int status2 = pam_end (pamh, status); |
|
3180 - pamh = 0; |
|
3181 + int status2 = pam_end (pamh, pam_auth_status); |
|
3182 + pamh = NULL; |
|
3183 if (verbose_p) |
|
3184 fprintf (stderr, "%s: pam_end (...) ==> %d (%s)\n", |
|
3185 blurb(), status2, |
|
3186 (status2 == PAM_SUCCESS ? "Success" : "Failure")); |
|
3187 } |
|
3188 |
|
3189 - if (status == PAM_SUCCESS) |
|
3190 + if (seteuid (euid) != 0) |
|
3191 + { |
|
3192 + if (verbose_p) |
|
3193 + perror("Error pam could not revert euid to user running as euid root," |
|
3194 + " locking may not work now\n"); |
|
3195 + } |
|
3196 + |
|
3197 + if (verbose_p) |
|
3198 + fprintf (stderr, |
|
3199 + "<--end of pam_authenticate() returning ok_to_unblank = %d\n", |
|
3200 + (int) ((pam_auth_status == PAM_SUCCESS) ? True : False)); |
|
3201 + |
|
3202 + if (si->pw_data->passwd_string) |
|
3203 + { |
|
3204 + memset(si->pw_data->passwd_string, 0, |
|
3205 + strlen(si->pw_data->passwd_string)); |
|
3206 + free (si->pw_data->passwd_string); |
|
3207 + si->pw_data->passwd_string = NULL; |
|
3208 + } |
|
3209 + |
|
3210 + if (pam_auth_status == PAM_SUCCESS) |
|
3211 si->unlock_state = ul_success; /* yay */ |
|
3212 else if (si->unlock_state == ul_cancel || |
|
3213 si->unlock_state == ul_time) |
|
3214 @@ -334,6 +482,13 @@ pam_priv_init (int argc, char **argv, Bool verbose_p) |
|
3215 const char file2[] = "/etc/pam.conf"; |
|
3216 struct stat st; |
|
3217 |
|
3218 +#ifdef __sun |
|
3219 + if (! verbose_p) /* SUN addition: only print warnings in verbose mode */ |
|
3220 + { /* since they are rarely useful and mostly just */ |
|
3221 + return True; /* cause confusion when users see them. */ |
|
3222 + } |
|
3223 +#endif |
|
3224 + |
|
3225 # ifndef S_ISDIR |
|
3226 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) |
|
3227 # endif |
|
3228 @@ -360,6 +515,8 @@ pam_priv_init (int argc, char **argv, Bool verbose_p) |
|
3229 break; |
|
3230 } |
|
3231 fclose (f); |
|
3232 + |
|
3233 +#ifndef __sun /* disable the misleading message */ |
|
3234 if (!ok) |
|
3235 { |
|
3236 fprintf (stderr, |
|
3237 @@ -367,9 +524,11 @@ pam_priv_init (int argc, char **argv, Bool verbose_p) |
|
3238 "%s: password authentication via PAM is unlikely to work.\n", |
|
3239 blurb(), file2, PAM_SERVICE_NAME, blurb()); |
|
3240 } |
|
3241 +#endif |
|
3242 } |
|
3243 /* else warn about file2 existing but being unreadable? */ |
|
3244 } |
|
3245 +#ifndef __sun /* disable the misleading message */ |
|
3246 else |
|
3247 { |
|
3248 fprintf (stderr, |
|
3249 @@ -377,15 +536,19 @@ pam_priv_init (int argc, char **argv, Bool verbose_p) |
|
3250 "%s: password authentication via PAM is unlikely to work.\n", |
|
3251 blurb(), file2, file, blurb()); |
|
3252 } |
|
3253 +#endif |
|
3254 |
|
3255 /* Return true anyway, just in case. */ |
|
3256 return True; |
|
3257 } |
|
3258 |
|
3259 |
|
3260 -static int |
|
3261 +int |
|
3262 pam_conversation (int nmsgs, |
|
3263 - const struct pam_message **msg, |
|
3264 +#ifndef __sun |
|
3265 + const |
|
3266 +#endif |
|
3267 + struct pam_message **msg, |
|
3268 struct pam_response **resp, |
|
3269 void *vsaver_info) |
|
3270 { |
|
3271 diff --git a/driver/passwd.c b/driver/passwd.c |
|
3272 --- a/driver/passwd.c |
|
3273 +++ b/driver/passwd.c |
|
3274 @@ -35,6 +35,7 @@ |
|
3275 |
|
3276 #include <X11/Intrinsic.h> |
|
3277 |
|
3278 +#include "dialog-data.h" |
|
3279 #include "xscreensaver.h" |
|
3280 #include "auth.h" |
|
3281 |
|
3282 diff --git a/driver/setuid.c b/driver/setuid.c |
|
3283 --- a/driver/setuid.c |
|
3284 +++ b/driver/setuid.c |
|
3285 @@ -145,7 +145,10 @@ set_ids_by_number (uid_t uid, gid_t gid, char **message_ret) |
|
3286 gid_errno = errno ? errno : -1; |
|
3287 |
|
3288 errno = 0; |
|
3289 - if (setuid (uid) != 0) |
|
3290 +/*mali if (setuid (uid) != 0)**we need root privs back at pam_authenticate |
|
3291 + this is causing to loose root priv for good, not good **/ |
|
3292 + |
|
3293 + if (seteuid (uid) != 0) |
|
3294 uid_errno = errno ? errno : -1; |
|
3295 |
|
3296 if (uid_errno == 0 && gid_errno == 0 && sgs_errno == 0) |
|
3297 diff --git a/driver/subprocs.c b/driver/subprocs.c |
|
3298 --- a/driver/subprocs.c |
|
3299 +++ b/driver/subprocs.c |
|
3300 @@ -243,7 +243,11 @@ show_job_list (void) |
|
3301 |
|
3302 static void clean_job_list (void); |
|
3303 |
|
3304 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3305 +struct screenhack_job * |
|
3306 +#else |
|
3307 static struct screenhack_job * |
|
3308 +#endif |
|
3309 make_job (pid_t pid, int screen, const char *cmd) |
|
3310 { |
|
3311 struct screenhack_job *job = (struct screenhack_job *) malloc (sizeof(*job)); |
|
3312 @@ -407,7 +411,11 @@ unblock_sigchld (void) |
|
3313 block_sigchld_handler--; |
|
3314 } |
|
3315 |
|
3316 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3317 +int |
|
3318 +#else |
|
3319 static int |
|
3320 +#endif |
|
3321 kill_job (saver_info *si, pid_t pid, int signal) |
|
3322 { |
|
3323 saver_preferences *p = &si->prefs; |
|
3324 @@ -590,9 +598,14 @@ describe_dead_child (saver_info *si, pid_t kid, int wait_status) |
|
3325 mention them) if we've just killed the subprocess. But mention them |
|
3326 if they happen on their own. |
|
3327 */ |
|
3328 - if (!job || |
|
3329 - (exit_status != 0 && |
|
3330 - (p->verbose_p || job->status != job_killed))) |
|
3331 + |
|
3332 + if ((!job |
|
3333 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3334 + && kid != si->passwd_pid |
|
3335 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
3336 + ) || |
|
3337 + (exit_status != 0 && |
|
3338 + (p->verbose_p || (job && job->status != job_killed)))) |
|
3339 { |
|
3340 /* Don't call fprintf() from signal handlers, as it might malloc. |
|
3341 fprintf (stderr, |
|
3342 @@ -632,8 +645,12 @@ describe_dead_child (saver_info *si, pid_t kid, int wait_status) |
|
3343 else if (WIFSIGNALED (wait_status)) |
|
3344 { |
|
3345 if (p->verbose_p || |
|
3346 - !job || |
|
3347 - job->status != job_killed || |
|
3348 + (!job |
|
3349 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3350 + && kid != si->passwd_pid |
|
3351 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
3352 + ) || |
|
3353 + (job && job->status != job_killed) || |
|
3354 WTERMSIG (wait_status) != SIGTERM) |
|
3355 { |
|
3356 /* Don't call fprintf() from signal handlers, as it might malloc. |
|
3357 @@ -701,12 +718,20 @@ describe_dead_child (saver_info *si, pid_t kid, int wait_status) |
|
3358 /* Clear out the pid so that screenhack_running_p() knows it's dead. |
|
3359 */ |
|
3360 if (!job || job->status == job_dead) |
|
3361 + { |
|
3362 for (i = 0; i < si->nscreens; i++) |
|
3363 { |
|
3364 saver_screen_info *ssi = &si->screens[i]; |
|
3365 if (kid == ssi->pid) |
|
3366 ssi->pid = 0; |
|
3367 } |
|
3368 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3369 + if (kid == si->passwd_pid) |
|
3370 + { |
|
3371 + si->passwd_pid = 0; |
|
3372 + } |
|
3373 +#endif |
|
3374 + } |
|
3375 } |
|
3376 |
|
3377 #else /* VMS */ |
|
3378 diff --git a/driver/timers.c b/driver/timers.c |
|
3379 --- a/driver/timers.c |
|
3380 +++ b/driver/timers.c |
|
3381 @@ -47,6 +47,8 @@ |
|
3382 #endif /* HAVE_RANDR */ |
|
3383 |
|
3384 #include "xscreensaver.h" |
|
3385 +#include "types.h" |
|
3386 +#include "dialog-data.h" |
|
3387 |
|
3388 #undef ABS |
|
3389 #define ABS(x)((x)<0?-(x):(x)) |
|
3390 @@ -60,6 +62,11 @@ static Bool proc_interrupts_activity_p (saver_info *si); |
|
3391 #endif /* HAVE_PROC_INTERRUPTS */ |
|
3392 |
|
3393 static void check_for_clock_skew (saver_info *si); |
|
3394 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3395 +static void watchdog_timer (XtPointer closure, XtIntervalId *id); |
|
3396 +extern Bool g_passwd_dialog_created; |
|
3397 +extern Bool ok_to_unblank; |
|
3398 +#endif |
|
3399 |
|
3400 |
|
3401 void |
|
3402 @@ -255,7 +262,11 @@ cycle_timer (XtPointer closure, XtIntervalId *id) |
|
3403 crash. So, restart the thing once an hour. */ |
|
3404 how_long = 1000 * 60 * 60; |
|
3405 |
|
3406 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3407 + if (si->external_passwd) |
|
3408 +#else |
|
3409 if (si->dbox_up_p) |
|
3410 +#endif |
|
3411 { |
|
3412 if (p->verbose_p) |
|
3413 fprintf (stderr, "%s: dialog box up; delaying hack change.\n", |
|
3414 @@ -308,7 +319,28 @@ activate_lock_timer (XtPointer closure, XtIntervalId *id) |
|
3415 |
|
3416 if (p->verbose_p) |
|
3417 fprintf (stderr, "%s: timed out; activating lock.\n", blurb()); |
|
3418 - set_locked_p (si, True); |
|
3419 + |
|
3420 + if (si->locked_p) |
|
3421 + { |
|
3422 + if (p->verbose_p) |
|
3423 + fprintf (stderr, |
|
3424 + "-->activate_lock_timer returning because screen already locked\n"); |
|
3425 + return; |
|
3426 + } |
|
3427 + |
|
3428 + /* Make sure screen is blanked before posting dialog box */ |
|
3429 + if (si->screen_blanked_p) |
|
3430 + { |
|
3431 + set_locked_p (si, True); |
|
3432 + ok_to_unblank = unlock_p (si); |
|
3433 + if (ok_to_unblank == True) |
|
3434 + { |
|
3435 + set_locked_p(si,False); |
|
3436 + unblank_screen(si); |
|
3437 + } |
|
3438 + } |
|
3439 + else /* blanking of screen failed reset lock flag */ |
|
3440 + set_locked_p (si, False); |
|
3441 } |
|
3442 |
|
3443 |
|
3444 @@ -587,14 +619,30 @@ dispatch_event (saver_info *si, XEvent *event) |
|
3445 } |
|
3446 |
|
3447 |
|
3448 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3449 +void /* called from lock.c */ |
|
3450 +#else |
|
3451 static void |
|
3452 +#endif |
|
3453 swallow_unlock_typeahead_events (saver_info *si, XEvent *e) |
|
3454 { |
|
3455 XEvent event; |
|
3456 char buf [100]; |
|
3457 int i = 0; |
|
3458 |
|
3459 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3460 + if (!si->typeahead_events) |
|
3461 + { |
|
3462 + /* Allocate enough space for 10 keys to be queued - if we get more |
|
3463 + than that before the dialog is ready, it's most likely the user |
|
3464 + left something sitting on the keyboard, and won't want them. */ |
|
3465 + si->typeahead_events = calloc(10, sizeof(XKeyEvent)); |
|
3466 + if (si->typeahead_events == NULL) |
|
3467 + return; |
|
3468 + } |
|
3469 +#else |
|
3470 memset (buf, 0, sizeof(buf)); |
|
3471 +#endif |
|
3472 |
|
3473 event = *e; |
|
3474 |
|
3475 @@ -607,10 +655,12 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e) |
|
3476 if (size != 1) continue; |
|
3477 switch (*s) |
|
3478 { |
|
3479 +#ifndef HAVE_XSCREENSAVER_LOCK /* Let these be queued with the rest */ |
|
3480 case '\010': case '\177': /* Backspace */ |
|
3481 if (i > 0) i--; |
|
3482 break; |
|
3483 case '\025': case '\030': /* Erase line */ |
|
3484 +#endif |
|
3485 case '\012': case '\015': /* Enter */ |
|
3486 case '\033': /* ESC */ |
|
3487 i = 0; |
|
3488 @@ -620,7 +670,17 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e) |
|
3489 break; /* ignore space at beginning of line */ |
|
3490 /* else, fall through */ |
|
3491 default: |
|
3492 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3493 + /* Queue events to replay once dialog is ready */ |
|
3494 + if (si->num_typeahead_events < 10) |
|
3495 + memcpy (&si->typeahead_events[si->num_typeahead_events++], |
|
3496 + &event, sizeof(XKeyEvent)); |
|
3497 + else |
|
3498 + XBell (si->dpy, 0); |
|
3499 + i = 1; /* so that spaces are accepted after the beginning */ |
|
3500 +#else |
|
3501 buf [i++] = *s; |
|
3502 +#endif |
|
3503 break; |
|
3504 } |
|
3505 } |
|
3506 @@ -628,6 +688,7 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e) |
|
3507 } while (i < sizeof(buf)-1 && |
|
3508 XCheckMaskEvent (si->dpy, KeyPressMask, &event)); |
|
3509 |
|
3510 +#ifndef HAVE_XSCREENSAVER_LOCK |
|
3511 buf[i] = 0; |
|
3512 |
|
3513 if (si->unlock_typeahead) |
|
3514 @@ -642,6 +703,7 @@ swallow_unlock_typeahead_events (saver_info *si, XEvent *e) |
|
3515 si->unlock_typeahead = 0; |
|
3516 |
|
3517 memset (buf, 0, sizeof(buf)); |
|
3518 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
3519 } |
|
3520 |
|
3521 |
|
3522 @@ -824,6 +886,7 @@ sleep_until_idle (saver_info *si, Bool until_idle_p) |
|
3523 if (handle_clientmessage (si, &event.x_event, until_idle_p)) |
|
3524 { |
|
3525 why = "ClientMessage"; |
|
3526 + si->emergency_lock_p = True; |
|
3527 goto DONE; |
|
3528 } |
|
3529 break; |
|
3530 @@ -838,6 +901,47 @@ sleep_until_idle (saver_info *si, Bool until_idle_p) |
|
3531 } |
|
3532 break; |
|
3533 |
|
3534 + case VisibilityNotify: |
|
3535 + { |
|
3536 + int k; |
|
3537 + |
|
3538 + if (p->debug_p) |
|
3539 + { |
|
3540 + fprintf (stderr, |
|
3541 + "************************************\n" |
|
3542 + "-->sleep_until_idle() event:VisibilityNotify\n" |
|
3543 + "\t Window of VisibilityNotify:%x\n" |
|
3544 + "\t until_idle_p=%d g_passwd_dialog_created=%d\n", |
|
3545 + event.x_event.xvisibility.window, |
|
3546 + until_idle_p, g_passwd_dialog_created); |
|
3547 + fflush(stderr); |
|
3548 + } |
|
3549 + |
|
3550 + /* Don't raise root window when passwd dialog wants to come up */ |
|
3551 + if (g_passwd_dialog_created == 0 && !until_idle_p) |
|
3552 + { |
|
3553 + if (event.x_event.xvisibility.state != VisibilityUnobscured) |
|
3554 + { |
|
3555 + for (k = 0; k < si->nscreens; k++) |
|
3556 + { |
|
3557 + saver_screen_info *ssi = &si->screens[k]; |
|
3558 + XClearWindow (si->dpy, ssi->screensaver_window); |
|
3559 + clear_stderr (ssi); |
|
3560 + XMapRaised (si->dpy, ssi->screensaver_window); |
|
3561 + } |
|
3562 + if (p->debug_p) |
|
3563 + { |
|
3564 + fprintf (stderr, |
|
3565 + "A window is trying to popup.\n" |
|
3566 + "Raising saver root Window.\n" |
|
3567 + "************************************\n"); |
|
3568 + fflush(stderr); |
|
3569 + } |
|
3570 + } |
|
3571 + } |
|
3572 + break; |
|
3573 + } |
|
3574 + |
|
3575 case KeyPress: |
|
3576 case ButtonPress: |
|
3577 /* Ignore release events so that hitting ESC at the password dialog |
|
3578 @@ -1457,7 +1561,11 @@ watchdog_timer (XtPointer closure, XtIntervalId *id) |
|
3579 { |
|
3580 Bool running_p = screenhack_running_p (si); |
|
3581 |
|
3582 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3583 + if (si->external_passwd) |
|
3584 +#else |
|
3585 if (si->dbox_up_p) |
|
3586 +#endif |
|
3587 { |
|
3588 if (si->prefs.debug_p) |
|
3589 fprintf (stderr, "%s: dialog box is up: not raising screen.\n", |
|
3590 diff --git a/driver/types.h b/driver/types.h |
|
3591 --- a/driver/types.h |
|
3592 +++ b/driver/types.h |
|
3593 @@ -250,12 +250,30 @@ struct saver_info { |
|
3594 |
|
3595 int unlock_failures; /* Counts failed login attempts while the |
|
3596 screen is locked. */ |
|
3597 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3598 + Window *raise_wins; /* List of windows to raise above the */ |
|
3599 + int num_raise_wins; /* virtual root/hack display, such as */ |
|
3600 + int max_raise_wins; /* accessibility helpers */ |
|
3601 + |
|
3602 + Window *override_wins; /* Windows we had to unset the */ |
|
3603 + int num_override_wins; /* override_redirect attribute on and */ |
|
3604 + int max_override_wins; /* need to restore it on after unlock. */ |
|
3605 + |
|
3606 + |
|
3607 + pid_t passwd_pid; /* The pid of the password dialog child if we |
|
3608 + are running an external process for it. */ |
|
3609 + Bool external_passwd; |
|
3610 + |
|
3611 + XKeyEvent *typeahead_events; /* Like unlock_typeahead, but as raw events */ |
|
3612 + int num_typeahead_events; |
|
3613 +#else |
|
3614 |
|
3615 char *unlock_typeahead; /* If the screen is locked, and the user types |
|
3616 a character, we assume that it is the first |
|
3617 character of the password. It's stored here |
|
3618 for the password dialog to use to populate |
|
3619 itself. */ |
|
3620 +#endif /* HAVE_XSCREENSAVER_LOCK */ |
|
3621 |
|
3622 char *user; /* The user whose session is locked. */ |
|
3623 char *cached_passwd; /* Cached password, used to avoid multiple |
|
3624 diff --git a/driver/windows.c b/driver/windows.c |
|
3625 --- a/driver/windows.c |
|
3626 +++ b/driver/windows.c |
|
3627 @@ -1081,8 +1081,12 @@ safe_XConfigureWindow (Display *dpy, Window window, |
|
3628 return (!error_handler_hit_p); |
|
3629 } |
|
3630 |
|
3631 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3632 +Bool |
|
3633 +#else |
|
3634 /* This might not be necessary, but just in case. */ |
|
3635 static Bool |
|
3636 +#endif |
|
3637 safe_XDestroyWindow (Display *dpy, Window window) |
|
3638 { |
|
3639 XErrorHandler old_handler; |
|
3640 @@ -1096,6 +1100,14 @@ safe_XDestroyWindow (Display *dpy, Window window) |
|
3641 XSetErrorHandler (old_handler); |
|
3642 XSync (dpy, False); |
|
3643 |
|
3644 + /* clear any queued VisibilityNotify events so we don't cause XErrors |
|
3645 + later when we try to process them and find the windowid is invalid */ |
|
3646 + XEvent event; |
|
3647 + while (XCheckWindowEvent(dpy, window, VisibilityChangeMask, &event)) |
|
3648 + { |
|
3649 + /* discard event */ ; |
|
3650 + } |
|
3651 + |
|
3652 return (!error_handler_hit_p); |
|
3653 } |
|
3654 |
|
3655 @@ -1210,6 +1222,7 @@ initialize_screensaver_window_1 (saver_screen_info *ssi) |
|
3656 */ |
|
3657 attrs.event_mask = (KeyPressMask | KeyReleaseMask | |
|
3658 ButtonPressMask | ButtonReleaseMask | |
|
3659 + VisibilityChangeMask | |
|
3660 PointerMotionMask); |
|
3661 |
|
3662 attrs.backing_store = NotUseful; |
|
3663 @@ -1481,6 +1494,9 @@ raise_window (saver_info *si, |
|
3664 saver_preferences *p = &si->prefs; |
|
3665 int i; |
|
3666 |
|
3667 + if (p->verbose_p) |
|
3668 + fprintf(stderr,"-->raise_window()\n"); |
|
3669 + |
|
3670 if (si->demoing_p) |
|
3671 inhibit_fade = True; |
|
3672 |
|
3673 @@ -1695,6 +1711,9 @@ unblank_screen (saver_info *si) |
|
3674 Bool unfade_p = (si->fading_possible_p && p->unfade_p); |
|
3675 int i; |
|
3676 |
|
3677 + if (p->verbose_p) |
|
3678 + fprintf(stderr,"-->unblank_screen()\n"); |
|
3679 + |
|
3680 monitor_power_on (si, True); |
|
3681 reset_watchdog_timer (si, False); |
|
3682 |
|
3683 @@ -1983,7 +2002,7 @@ select_visual (saver_screen_info *ssi, const char *visual_name) |
|
3684 maybe_transfer_grabs (ssi, old_w, ssi->screensaver_window, ssi->number); |
|
3685 |
|
3686 /* Now we can destroy the old window without horking our grabs. */ |
|
3687 - XDestroyWindow (si->dpy, old_w); |
|
3688 + safe_XDestroyWindow (si->dpy, old_w); |
|
3689 |
|
3690 if (p->verbose_p) |
|
3691 fprintf (stderr, "%s: %d: destroyed old saver window 0x%lx.\n", |
|
3692 diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c |
|
3693 --- a/driver/xscreensaver.c |
|
3694 +++ b/driver/xscreensaver.c |
|
3695 @@ -156,6 +156,8 @@ |
|
3696 #include <X11/StringDefs.h> |
|
3697 #include <X11/Shell.h> |
|
3698 #include <X11/Xos.h> |
|
3699 +#include <gconf/gconf-client.h> |
|
3700 +#include <glib.h> |
|
3701 #include <time.h> |
|
3702 #include <sys/time.h> |
|
3703 #include <netdb.h> /* for gethostbyname() */ |
|
3704 @@ -217,6 +219,7 @@ |
|
3705 #endif /* HAVE_RANDR */ |
|
3706 |
|
3707 |
|
3708 +#include "dialog-data.h" |
|
3709 #include "xscreensaver.h" |
|
3710 #include "version.h" |
|
3711 #include "yarandom.h" |
|
3712 @@ -228,11 +231,28 @@ |
|
3713 |
|
3714 saver_info *global_si_kludge = 0; /* I hate C so much... */ |
|
3715 |
|
3716 +/* Globals */ |
|
3717 +Bool ok_to_unblank = False; |
|
3718 + |
|
3719 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3720 +/* Global storage for gtk passwd lock dialog |
|
3721 + * we assign this to si->pw_data and this is needed |
|
3722 + * to set user/passwd labels on gtk lock dialog by |
|
3723 + * pam conv function. |
|
3724 + */ |
|
3725 +passwd_dialog_data mygtkpwd; |
|
3726 +passwd_dialog_data *ptr_mygtkpwd = &mygtkpwd; |
|
3727 +#endif |
|
3728 + |
|
3729 char *progname = 0; |
|
3730 char *progclass = 0; |
|
3731 XrmDatabase db = 0; |
|
3732 |
|
3733 |
|
3734 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3735 +Atom XA_UNLOCK_RATIO; |
|
3736 +#endif |
|
3737 + |
|
3738 |
|
3739 static XrmOptionDescRec options [] = { |
|
3740 |
|
3741 @@ -630,6 +650,9 @@ connect_to_server (saver_info *si, int *argc, char **argv) |
|
3742 { &XA_XSETROOT_ID, "_XSETROOT_ID" }, |
|
3743 { &XA_ESETROOT_PMAP_ID, "ESETROOT_PMAP_ID" }, |
|
3744 { &XA_XROOTPMAP_ID, "_XROOTPMAP_ID" }, |
|
3745 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3746 + { &XA_UNLOCK_RATIO, "UNLOCK_RATIO" }, |
|
3747 +#endif |
|
3748 { NULL, NULL } /* Must be last to terminate list */ |
|
3749 }; |
|
3750 const struct atom_request *atom_lists[3] = { NULL, NULL, NULL }; |
|
3751 @@ -1105,8 +1128,36 @@ static void |
|
3752 main_loop (saver_info *si) |
|
3753 { |
|
3754 saver_preferences *p = &si->prefs; |
|
3755 - Bool ok_to_unblank; |
|
3756 + /* Bool ok_to_unblank; made this a global flag, gets set in timers.c */ |
|
3757 int i; |
|
3758 + const char *modulesptr = NULL; |
|
3759 + |
|
3760 +/* |
|
3761 +** CR4784055(P1)locked-screen dialog is inaccessible to Gnopernicus |
|
3762 +** voice for each type-in char in the password field of |
|
3763 +** pop-up dialog |
|
3764 +*/ |
|
3765 + |
|
3766 + /* BUG #6573182 |
|
3767 + ** g_type_init should be done before calling gconf_client routines |
|
3768 + ** so that xscreensaver does not dump core if gconf daemon is not running. |
|
3769 + */ |
|
3770 + g_type_init (); |
|
3771 + |
|
3772 + /* |
|
3773 + ** 6395649 at-spi-registryd starts when screen is locked even |
|
3774 + ** when accessible device support is off(SR) |
|
3775 + ** per AT core gp suggestion |
|
3776 + ** GTK_MODULES is set only if at support is enabled |
|
3777 + */ |
|
3778 + |
|
3779 + if (gconf_client_get_bool(gconf_client_get_default(), |
|
3780 + "/desktop/gnome/interface/accessibility", NULL)) |
|
3781 + { |
|
3782 + modulesptr = getenv ("GTK_MODULES"); |
|
3783 + if (!modulesptr || modulesptr [0] == '\0') |
|
3784 + putenv ("GTK_MODULES=gail:atk-bridge"); |
|
3785 + } |
|
3786 |
|
3787 while (1) |
|
3788 { |
|
3789 @@ -1137,6 +1188,17 @@ main_loop (saver_info *si) |
|
3790 fprintf (stderr, "%s: idle with blanking disabled at %s.\n", |
|
3791 blurb(), timestring()); |
|
3792 |
|
3793 + /* 6221109 Changing mode from disable to anything else, |
|
3794 + doesn't lock screen. |
|
3795 + |
|
3796 + This is Disable Screen Saver mode, in this mode we dont lock |
|
3797 + screen, but si->locked_p is already set to True, since someone |
|
3798 + tried to lock screen, reset it to False, else when we change |
|
3799 + mode from disable and try to lock screen, xscreensaver thinks |
|
3800 + screen is already locked and doesnt lock screen anymore. |
|
3801 + */ |
|
3802 + set_locked_p (si, False); |
|
3803 + |
|
3804 /* Go around the loop and wait for the next bout of idleness, |
|
3805 or for the init file to change, or for a remote command to |
|
3806 come in, or something. |
|
3807 @@ -1198,6 +1260,7 @@ main_loop (saver_info *si) |
|
3808 blurb()); |
|
3809 |
|
3810 schedule_wakeup_event (si, retry, p->debug_p); |
|
3811 + set_locked_p(si, False); |
|
3812 continue; |
|
3813 } |
|
3814 } |
|
3815 @@ -1263,7 +1326,17 @@ main_loop (saver_info *si) |
|
3816 p->lock_p && /* and locking is enabled */ |
|
3817 !si->locking_disabled_p && /* and locking is possible */ |
|
3818 lock_timeout == 0) /* and locking is not timer-deferred */ |
|
3819 - set_locked_p (si, True); /* then lock right now. */ |
|
3820 + { |
|
3821 + if (p->debug_p) |
|
3822 + fprintf(stderr, "going to lock screen B\n"); |
|
3823 + set_locked_p (si, True); /* then lock right now. */ |
|
3824 + ok_to_unblank = unlock_p(si); |
|
3825 + if (ok_to_unblank == True) |
|
3826 + { |
|
3827 + set_locked_p (si, False); |
|
3828 + goto DONE; |
|
3829 + } |
|
3830 + } |
|
3831 |
|
3832 /* locked_p might be true already because of the above, or because of |
|
3833 the LOCK ClientMessage. But if not, and if we're supposed to lock |
|
3834 @@ -1278,10 +1351,7 @@ main_loop (saver_info *si) |
|
3835 } |
|
3836 #endif /* !NO_LOCKING */ |
|
3837 |
|
3838 - |
|
3839 - ok_to_unblank = True; |
|
3840 do { |
|
3841 - |
|
3842 check_for_leaks ("blanked A"); |
|
3843 sleep_until_idle (si, False); /* until not idle */ |
|
3844 check_for_leaks ("blanked B"); |
|
3845 @@ -1291,6 +1361,13 @@ main_loop (saver_info *si) |
|
3846 #ifndef NO_LOCKING |
|
3847 /* Maybe unlock the screen. |
|
3848 */ |
|
3849 + if (si->demoing_p) goto DONE; /* in demoing mode and user wants out |
|
3850 + unblank screen */ |
|
3851 + |
|
3852 + /* This is when blank timeout has happened but lock timeout hasnt |
|
3853 + and user gets active. Simply get him out of the blank screen. */ |
|
3854 + if (si->screen_blanked_p && !si->locked_p) goto DONE; |
|
3855 + |
|
3856 if (si->locked_p) |
|
3857 { |
|
3858 saver_screen_info *ssi = si->default_screen; |
|
3859 @@ -1302,7 +1379,20 @@ main_loop (saver_info *si) |
|
3860 suspend_screenhack (&si->screens[i], True); /* suspend */ |
|
3861 XUndefineCursor (si->dpy, ssi->screensaver_window); |
|
3862 |
|
3863 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3864 + /* Prevents lock dialog posting on non blanked screen */ |
|
3865 + if (!si->screen_blanked_p) /* locked_p is true, so blank now */ |
|
3866 + blank_screen (si); |
|
3867 + if (si->screen_blanked_p) /* if blanking successful, call PAM */ |
|
3868 + { |
|
3869 + set_locked_p (si, True); |
|
3870 + ok_to_unblank = unlock_p(si); |
|
3871 + } |
|
3872 + else /* blanking failed, probably couldn't grab keyboard/mouse */ |
|
3873 + set_locked_p (si, False); |
|
3874 +#else |
|
3875 ok_to_unblank = unlock_p (si); |
|
3876 +#endif |
|
3877 |
|
3878 si->dbox_up_p = False; |
|
3879 XDefineCursor (si->dpy, ssi->screensaver_window, ssi->cursor); |
|
3880 @@ -1327,6 +1417,7 @@ main_loop (saver_info *si) |
|
3881 |
|
3882 } while (!ok_to_unblank); |
|
3883 |
|
3884 +DONE: |
|
3885 |
|
3886 if (p->verbose_p) |
|
3887 fprintf (stderr, "%s: unblanking screen at %s.\n", |
|
3888 @@ -1411,7 +1502,19 @@ main (int argc, char **argv) |
|
3889 textdomain (GETTEXT_PACKAGE); |
|
3890 #endif /* ENABLE_NLS */ |
|
3891 |
|
3892 +#if defined(ENABLE_NLS) && defined(HAVE_XSCREENSAVER_LOCK) |
|
3893 + /* Gtk unlock dialog needs to be sent UTF-8 text to display */ |
|
3894 + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); |
|
3895 +#endif |
|
3896 + |
|
3897 memset(si, 0, sizeof(*si)); |
|
3898 + |
|
3899 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3900 +/* Initialize and point si to pw_data i.e. the lock dialog struct */ |
|
3901 + memset(ptr_mygtkpwd, 0, sizeof(*ptr_mygtkpwd)); |
|
3902 + si->pw_data = ptr_mygtkpwd; |
|
3903 +#endif |
|
3904 + |
|
3905 global_si_kludge = si; /* I hate C so much... */ |
|
3906 |
|
3907 fix_fds(); |
|
3908 @@ -1421,7 +1524,9 @@ main (int argc, char **argv) |
|
3909 |
|
3910 save_argv (argc, argv); |
|
3911 set_version_string (si, &argc, argv); |
|
3912 +#ifndef HAVE_XSCREENSAVER_LOCK /* moved below for external lock */ |
|
3913 privileged_initialization (si, &argc, argv); |
|
3914 +#endif |
|
3915 hack_environment (si); |
|
3916 |
|
3917 spasswd = getpwuid(getuid()); |
|
3918 @@ -1444,6 +1549,10 @@ main (int argc, char **argv) |
|
3919 print_banner (si); |
|
3920 |
|
3921 load_init_file(si->dpy, p); /* must be before initialize_per_screen_info() */ |
|
3922 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3923 + privileged_initialization (si, &argc, argv); |
|
3924 +#endif |
|
3925 + |
|
3926 blurb_timestamp_p = p->timestamp_p; /* kludge */ |
|
3927 initialize_per_screen_info (si, shell); /* also sets si->fading_possible_p */ |
|
3928 |
|
3929 @@ -1695,8 +1804,12 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) |
|
3930 Atom type = 0; |
|
3931 Window window = event->xclient.window; |
|
3932 |
|
3933 + if (p->verbose_p) |
|
3934 + fprintf(stderr, "handle_clientmessage\n"); |
|
3935 + |
|
3936 /* Preferences might affect our handling of client messages. */ |
|
3937 maybe_reload_init_file (si); |
|
3938 + XSync (si->dpy, False); |
|
3939 |
|
3940 if (event->xclient.message_type != XA_SCREENSAVER || |
|
3941 event->xclient.format != 32) |
|
3942 @@ -1969,10 +2082,18 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) |
|
3943 : "locking."); |
|
3944 sprintf (buf, "LOCK ClientMessage received; %s", response); |
|
3945 clientmessage_response (si, window, False, buf, response); |
|
3946 + |
|
3947 + if (p->verbose_p) |
|
3948 + fprintf(stderr, "going to lock screen A\n"); |
|
3949 + |
|
3950 set_locked_p (si, True); |
|
3951 + si->emergency_lock_p = True; |
|
3952 si->selection_mode = 0; |
|
3953 si->demoing_p = False; |
|
3954 |
|
3955 + return True; /* dont set lock_id to 0, |
|
3956 + causes to go in lock in main_loop above */ |
|
3957 + |
|
3958 if (si->lock_id) /* we're doing it now, so lose the timeout */ |
|
3959 { |
|
3960 XtRemoveTimeOut (si->lock_id); |
|
3961 diff --git a/driver/xscreensaver.h b/driver/xscreensaver.h |
|
3962 --- a/driver/xscreensaver.h |
|
3963 +++ b/driver/xscreensaver.h |
|
3964 @@ -164,6 +164,12 @@ extern Bool select_visual (saver_screen_info *ssi, const char *visual_name); |
|
3965 extern void store_saver_status (saver_info *si); |
|
3966 extern const char *signal_name (int signal); |
|
3967 |
|
3968 +#ifdef HAVE_XSCREENSAVER_LOCK |
|
3969 +extern int kill_job (saver_info *si, pid_t pid, int signal); |
|
3970 +extern struct screenhack_job *make_job (pid_t pid, int screen, |
|
3971 + const char *cmd); |
|
3972 +#endif |
|
3973 + |
|
3974 /* ======================================================================= |
|
3975 subprocs diagnostics |
|
3976 ======================================================================= */ |
|