Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4036762
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: LINUX

2011-01-20 10:36:00

实现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

#include

#include

#include

#include

#include

 

#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;

}

 

阅读(8353) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~