linux用户登录验证程序

实现linux登录验证的程序,要考虑两个部分,第一是用户名、密码的输入;第二是用户、密码的验证,关于第二部分的机制已经在http://blog168.chinaunix.net/space.php?uid=20196318&do=blog&id=94771中讲到。

而第一部分的难点则在于如何在输入密码时不回显输入的字符,这就需要更改终端的属性,涉及终端IO的编程,主要用到tcgetattrsetattr两个函数,通过取消终端的ECHO标记,即可禁用终端回显,在密码输入处理之后,要记得恢复终端原来的属性,避免影响到其它的进程。

 

终端IO处理大致过程如下:

struct termios ts, ots;

/* 禁用终端回显 */

ts.c_lflag &= ~ECHO;

ts.c_lflag |= ECHONL;

tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);

 

 /* 在这里插入输入密码的代码 */

 

 /* 恢复终端原来的属性 */

tcsetattr(STDIN_FILENO, TCSANOW, &ots);

 

实例:(为方便coding,输入与认证一同处理,使用gets存在缓冲区溢出的隐患,应使用getlinegets,使用时要注意去掉末尾的换行符)

 

#include <stdio.h>

#include <stdlib.h>

#include <termios.h>

#include <unistd.h>

#include <shadow.h>

#include <string.h>

 

#define AUTH_SIZE 1024

 

int main(int argc, char* argv[])

{

         struct termios ts, ots;

         char userbuf[AUTH_SIZE];

         char passbuf[AUTH_SIZE];

 

         tcgetattr(STDIN_FILENO, &ts);

         ots = ts;

 

         printf("Login:");

         fflush(stdout);

         gets(userbuf);

 

         /* 禁用终端回显 */

         ts.c_lflag &= ~ECHO;

         ts.c_lflag |= ECHONL;

         tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);

 

         printf("Password:");

         fflush(stdout);

         gets(passbuf);

 

         struct spwd *sp = getspnam(userbuf);

         if(sp == NULL) {

                   printf("set sp error\n");

         }

 

         /* 验证用户名、密码的正确性 */

         if(!strcmp(sp->sp_pwdp, (char*)crypt(passbuf, sp->sp_pwdp))) {

                   printf("correct\n");

         }

         else {

                   printf("user or password error\n");

         }

         /* 恢复终端原来的属性 */

         tcsetattr(STDIN_FILENO, TCSANOW, &ots);

         return 0;

}

 

 

 
posted @ 2013-04-19 14:09  ydzhang  阅读(682)  评论(0编辑  收藏  举报