|
Motif password prompt and launcher This is based off some Motif sample code for a password dialog (the link is on my links page somewhere). I just added some bits that will check the password against root's (it doesn't have to be root's) and then setuid to 0 and launch an xterm. ie. Its basically a graphical su command (NB: You'll need to make the executable setuid). Security is undoubtedly poor but at least the source is pretty short. The code below is obviously for Solaris, but you could easily mod it to work on linux. Also google for 'x11 ssh askpass'. This is a pure xlib program for prompting for a password. You could easily hack it to add in the setuid stuff (hint: acceptAction is the routine that ends up with the password. Just get it to call switch_user from the code below. You also need to do an XFlush(app->dpy) in the cleanUp routine).
/*
Simple password dialog to launch root process
based on sample Motif code by Dan Heller and Paula Ferguson
compile using something like:
gcc -I/usr/openwin/include -L/usr/openwin/lib -lcrypt -lXm -lXt \
-lX11 -o d4 d4.c
* Written by Dan Heller and Paula Ferguson.
* Copyright 1994, O'Reilly & Associates, Inc.
* Permission to use, copy, and modify this program without
* restriction is hereby granted, as long as this copyright
* notice appears in each copy of the program source code.
* This program is freely distributable without licensing fees and
* is provided without guarantee or warrantee expressed or implied.
* This program is -not- in the public domain.
*/
/* password.c -- prompt for a password. All input looks like
* a series of *'s. Store the actual data typed by the user in
* an internal variable. Don't allow paste operations. Handle
* backspacing by deleting all text from insertion point to the
* end of text.
*/
#include <stdlib.h>
#include <shadow.h>
#include <unistd.h>
#include <string.h>
#include <Xm/Text.h>
#include <Xm/LabelG.h>
#include <Xm/RowColumn.h>
void check_passwd();
char *passwd; /* store user-typed passwd here. */
void switch_user(char *s) {
struct spwd *spwd;
char *epasswd;
char *disp;
char cmdline[256];
int x;
spwd = getspnam("root");
if (spwd!=NULL) {
epasswd = (char *) crypt(s,spwd->sp_pwdp);
if (strcmp(epasswd,spwd->sp_pwdp)==0) {
printf("match\n");
//Zap the password
for (x=0;s[x]!=0;x++)
s[x]=0;
disp = getenv("DISPLAY");
if (disp!=NULL) {
printf("disp %s\n",disp);
snprintf(cmdline,255,"HOME=/ /usr/openwin/bin/xterm -ls -display %s"
,disp);
setuid(0);
system(cmdline);
}
}
} else
printf("bad\n");
}
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, text_w, rowcol;
XtAppContext app;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
rowcol = XtVaCreateWidget ("rowcol",
xmRowColumnWidgetClass, toplevel,
XmNorientation, XmHORIZONTAL,
NULL);
XtVaCreateManagedWidget ("Password:",
xmLabelGadgetClass, rowcol, NULL);
text_w = XtVaCreateManagedWidget ("text_w",
xmTextWidgetClass, rowcol, NULL);
XtAddCallback(text_w, XmNmodifyVerifyCallback, check_passwd, NULL);
XtAddCallback(text_w, XmNactivateCallback, check_passwd, NULL);
XtManageChild (rowcol);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* check_passwd() -- handle the input of a password. */
void
check_passwd(text_w, client_data, call_data)
Widget text_w;
XtPointer client_data;
XtPointer call_data;
{
char *c_new;
char duppass[100];
int len;
XmTextVerifyCallbackStruct *cbs =
(XmTextVerifyCallbackStruct *) call_data;
if (cbs->reason == XmCR_ACTIVATE) {
//printf ("Password: %s\n", passwd);
strcpy(duppass,passwd);
XtFree(passwd);
XtUnmanageChild(text_w);
XtDestroyWidget(text_w);
switch_user(duppass);
exit(1);
}
if (cbs->startPos < cbs->currInsert) { /* backspace */
cbs->endPos = strlen (passwd); /* delete from here to end */
passwd[cbs->startPos] = 0; /* backspace--terminate */
return;
}
if (cbs->text->length > 1) {
cbs->doit = False; /* don't allow "paste" operations */
return; /* make the user *type* the password! */
}
c_new = XtMalloc (cbs->endPos + 2); /* new char + NULL terminator */
if (passwd) {
strcpy (c_new, passwd);
XtFree (passwd);
} else
c_new[0] = (char) NULL;
passwd = c_new;
strncat (passwd, cbs->text->ptr, cbs->text->length);
passwd[cbs->endPos + cbs->text->length] = 0;
for (len = 0; len < cbs->text->length; len++)
cbs->text->ptr[len] = '*';
}
pablo , 2004-02-10 22:13:25 |