% Login.c -- Prompting for username and password with ndialog % Jessica L. Parsons % Wed Jan 16 10:07:54 PST 2008 #Login.c This code can be called by a login program to get a username and password. It expects that the world has been prepared by an `init_dialog()` before it's called, and it leaves it up to the caller to call `end_dialog()` when it wants to. /* * cc -c getuser.o getuser.c */ #include #include #include #include #define ESIZE 20 static char user[ESIZE]; static char pass[ESIZE]; static struct passwd *pw; static int retries; /* * pwcallback() is a local function that authenticates the user after they * enter a password. */ static int pwcallback(void* obj, void* display) { char *ency; if ((pw = getpwnam(user)) != 0) { if (pw->pw_passwd[0] == 0 && pass[0] == 0) { /* no password, so don't even check */ return -1; } ency = crypt(pass, pw->pw_passwd); memset(pass, 0, ESIZE); if (strcmp(ency, pw->pw_passwd) == 0) { /* password matched; we can leave now */ return -1; } } /* complain bitterly and return */ Error("login incorrect"); return (--retries >= 0) ? 0 : -1; } /* pwcallback */ /* * getuser() asks for a username and password. If it's given a valid username * and password, it returns a pwent for that user, otherwise it spits up a * `login incorrect' error box and asks again, up to login_attempts times. * After that, it returns 0 and leaves the proper punishment up to the caller. */ struct passwd * getuser(int login_attempts) { int rc; void *u_obj, *p_obj, *cancel, *chain; /* allocate the display fields */ u_obj = newString( 0,0, ESIZE, ESIZE, user, 0, "Username", 0, 0); p_obj = newPWString(0,3, ESIZE, ESIZE, pass, 0, "Password", pwcallback, 0); cancel= newCancelButton(0, "Forget it", 0, 0); retries = login_attempts; /* build them into a ObjChain */ chain = ObjChain(ObjChain(u_obj, p_obj), cancel); /* get the user input and clean up */ rc = MENU(chain, -1, -1, 0, "Enter your username and password", 0); deleteObjChain(chain); /* and return the user info if there is any */ return (rc == MENU_OK) ? pw : 0; } /* getuser */