linux 密码回显

一,绪论

1.课题背景

Linux下有系统提供的getpass()函数,可由于写的时候太早了,只支持8位字符,同时有安全隐患(溢出!)Linux出于对密码的保密,输入的字符是不会显示到屏幕上的。在登陆函数和密码修改函数内都没有提供密码回显提示,但是此设计对于一般的桌面级应用的初级用户带来了一定的麻烦,而且,没有任何密码遗忘提示功能,一旦遗忘,只能重设,作为用户定制功能,如何在linux c下实现密码回显和提示功能的登录和密码修改模块

2.参考资料

Linux编程技术详解   杜华 编著 人民邮电出版社

http://www.fanqiang.com

http://csdn.net/

二,实现过程

1.首先,我编写了在windows c下的密码回显的代码

程序1.c代码如下:

#include <stdio.h> 

#include <conio.h> 

#define TRUE 1 

#define FALSE 0 

#define MIN_INPUT 0x20 

#define MAX_INPUT 0x7e 

/* 

所有功能有此函数实现: 

* pszPw : 保存密码的缓冲 

* iMaxSize :最大的密码长度,该长度必须小于缓冲区大小。 

返回值为TRUE为成功获取密码。总是返回TRUE 

*/ 

int GetPassword(unsigned char* pszPw,int iMaxSize) 

unsigned char ch; 

int i=0; 

int bIsEcho=TRUE; 

//while( ! kbhit() && i<iMaxSize ) 

while( ( ch = (unsigned char)getch() ) && i < iMaxSize ) 

//ch = (unsigned char)getch(); 

bIsEcho=TRUE; 

if ( ch == 13) 

pszPw[i++]=0; 

break; 

else if ( ch >= MIN_INPUT && ch <= MAX_INPUT) /*所有可打印字符*/ 

pszPw[i++]=ch; 

else if ( ch == 8 && i> 0 ) /*退格键*/ 

pszPw[i--] = 0; 

bIsEcho = FALSE; 

putchar( ch ); 

putchar( ' ' ); 

putchar( ch ); 

else 

bIsEcho = FALSE; 

If(bIsEcho) 

putchar('*'); 

pszPw[i]=0; 

return TRUE; 

int main(void) 

int iMaxSize=80; 

unsigned char pw[99]; 

if ( GetPassword(pw,iMaxSize) == TRUE )

printf("/npassword=%s",pw); 

}  

Else

printf("/nCan not get the password!"); 

}

经过在虚拟机下的编译,该程序却无法执行,估计原因应该是没有相应的c库,所以开始查阅资料

2..使用curses

curses库是由柏克莱大学的Bill JoyKen Arnold所开发的。当时开发curses库的目的是为了解决程序对于不同终端的兼容性。curses库用于处理Linux/UNIX上的光标移动及屏幕显示问题。考虑到curses库的复杂性,这里只是简单地介绍一下curses库的使用。需要这方面详细信息可以查阅相关资料。

使用curses库中的函数前,需要进行必要的初始化工作。程序需要使用initscr函数来开启curses模式,在结束前调用endwin函数来关闭curses模式。代码如下:

#include <curses.h>

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

{

    initscr();

    endwin();

}

在实际使用中,出于方便的目的,往往把一些初始化的动作放置在初始化函数中,以方便调用。具体代码如下:

void initial()

{

    initscr();

    cbreak();

    nl();

    noecho()

    intrflush(stdscr,FALSE);

    keypad(stdscr,TRUE);

    refresh();

}

代码中使用到了一些curses库的函数,含义如下。

l cbreak():调用cbreak函数后,除了“Del”“Ctrl”键外,接受其他所有字符输入。

l nl()/nonl():输出时,换行是否作为回车字符。nl函数将换行作为回车符,而nonl数相反。

l noecho()/echo():关闭/打开输入回显功能。

l intrflush(WINDOW *win, bool bf)win为标准输出。当bftrue时输入Break,可以加快中断的响应。但是,有可能会造成屏幕输出信息的混乱。

l keypadWINDOW *win, bool bf):win为标准输出。调用keypad函数后,将可以使用键盘上的一些特殊字符,如方向键,转化成curses.h中的特殊键。

lrefresh():重绘屏幕显示内容。在调用initscr函数后,第一次调用refresh函数会清除屏幕显示。

程序2.c给出了使用curses库实现密码输入、屏蔽输出结果的实例。具体代码如下:

//2.c使用curses实现密码输入

#include <stdio.h>

#include <stdlib.h>

#include <curses.h>

#include <unistd.h>

void init()

{

   initscr();

   cbreak();

   nl();

   noecho();

   intrflush(stdscr,FALSE);

   keypad(stdscr,TRUE);

   refresh();

}

int getpasswd(char* passwd, int size)

{

   int c;

   int n = 0;

   printw("Please Input password:");

   do{

      c = getch();

      if (c != '/n'){

         echochar('*');//printw("*");

         passwd[n++] = c;

        }

   }while(c != '/n' && n < (size - 1));

   passwd[n] = '/0';

   return n;

}

int main()

{

   char passwd[20];

   int n;

   init();

   n=getpasswd(passwd, sizeof(passwd));

   printw("/nYour passwd is:%s/n", passwd);

   printw("Press any key continue .../n");

   refresh();

   getchar();

   endwin();

   return 0;

}

使用gcc编译该程序,获得名为2的可执行程序。注意程序中使用了curses库,因此编译时要指明该库的名称。具体编译和执行情况如下:

[program@localhost charter6]$ gcc -o 2 2.c -lcurses

[program@localhost charter6]$ ./2

Please Input password:*******

Your passwd is:afdafds

Press any key continue ...

3.使用tcgetattr函数和tcsetattr函数

经查阅资料,还有种方法,可以不使用curses库解决密码输入的回显问题。程序3.c通过使用tcgetattr函数和tcsetattr函数同样达到了目的。具体代码如下:

#include <stdio.h>

#include <termios.h>

#include <unistd.h>

#include <errno.h>

#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)

//函数set_disp_mode用于控制是否开启输入回显功能

//如果option0,则关闭回显,为1则打开回显

int set_disp_mode(int fd,int option)

{

   int err;

   struct termios term;

   if(tcgetattr(fd,&term)==-1){

    perror("Cannot get the attribution of the terminal");

    return 1;

   }

   if(option)

       term.c_lflag|=ECHOFLAGS;

   else

       term.c_lflag &=~ECHOFLAGS;

   err=tcsetattr(fd,TCSAFLUSH,&term);

   if(err==-1 && err==EINTR){

       perror("Cannot set the attribution of the terminal");

       return 1;

   }

   return 0;

}

//函数getpasswd用于获得用户输入的密码,并将其存储在指定的字符数组中

int getpasswd(char* passwd, int size)

{

   int c;

   int n = 0;

   printf("Please Input password:");

   do{

      c=getchar();

      if (c != '/n'|c!='/r'){

         passwd[n++] = c;

      }

   }while(c != '/n' && c !='/r' && n < (size - 1));

   passwd[n] = '/0';

   return n;

}

int main()

{

   char passwd[20];

   //首先关闭输出回显,这样输入密码时就不会显示输入的字符信息

   set_disp_mode(STDIN_FILENO,0);

   //调用getpasswd函数获得用户输入的密码

   getpasswd(passwd, sizeof(passwd));

   printf("/nYour passwd is:%s/n", passwd);

   printf("Press any key continue .../n");

   set_disp_mode(STDIN_FILENO,1);

   getchar();

   return 0;

}

使用gcc编译3.c代码,获得名为3的可执行程序。执行该程序,得到如下的输出结果:

[program@localhost charter6]$ gcc -o 3 3.c

[program@localhost charter6]$ ./3

Please Input password:

Your passwd is:afdfasf

Press any key continue ...

[program@localhost charter6]$

三,结论

通过这个小小的程序,反映了LinuxC环境与windows下还是有一些区别的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值