免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4865 | 回复: 6
打印 上一主题 下一主题

Linux下Terminal的密码输入 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-02 17:52 |只看该作者 |倒序浏览
呵,在我的blog上写着玩的,因为在做之前搜了一下chinaunix(习惯性动作),没搜到,所以就贴上来了,别见笑啊,有不对的请指正,谢谢!

最近由于一个程序安全的需要,在运行程序时需要用户输入用户名密码。哎,一直没做过在程序运行时的权限认证,以前都是通过对机器系统级的用户权限控制达到权限管理的需求(事实这也是我觉得最实用,简单的一种)。OK,不做是不可能的,有时候被迫接受别人的思想,自己的思想无法体现也是非常痛苦的啊,题外话,呵呵。切入正题。

谁规定的输入密码时不能显示出来?背着点人不就行了嘛,还要给技术找麻烦,要知道做技术多辛苦啊,又累!算了,顺应大众习惯吧。本来Linux下有系统提供的getpass()函数,可由于写的时候太早了(我猜的呵呵,当时可能就这需求),只支持8位字符,同时有安全隐患(溢出!),obsolate了,可怜的孩子啊。那总该有个替换的吧?例如像getpass_new()这种的函数,K~找了半天,没找到啊!郁闷。没办法,想办法吧。查了点资料,最多的是用ncurses库里的getch(),可我的是Terminal啊,盗版SecureCRT,用不成。还有两种就差不多了,都是通过termios来控制低层。一种是通过最最最强大的函数:ioctl(),用数据struct termio设置TCGETA、TCSETA。最讨厌用ioctl了!本来这函数挺简单,可我觉得就是做OS开发的人在偷懒!你要控制IO的哪部分,怎么控制,都得自己去找参数,找数据结构,郁闷。嘿,终于轮到主角出场了,我觉得这个才是正道啊!猜对了,这就是termios.h里藏着的:

  1. int tcgetattr (int __fd, struct termios *__termios_p);
  2. int tcsetattr (int __fd, int __optional_actions,
  3.               __const struct termios *__termios_p);
复制代码

哎,找了半天,终于找到让我一见钟情的她了~
这个其实也是对文件(UNIX概念的文件)进行设置,应该也是调用ioctl吧?猜的,没看源码:)但起码感觉它是专门做这个的呀,看人家多专一!

查了一下,还好,tcsetattr的optional actions只有三个选择,一目了然了,当然是用Flush action(TCSAFLUSH)了。万事俱备啊!于是_fd用0(stdin),输出当然要用stderr了,action用TCSAFLUSH, termios_p只需要设置个c_lflag,和~ECHO做个&就OK了。呵,终于搞定了。源码奉上:



  1. #include <termios.h>

  2. void UserIf::Echoff(int f)
  3. {
  4.   struct termios sg;        
  5.   tcgetattr(f, &sg);             /* get settings */
  6.   sg.c_lflag &= ~ECHO;     /* turn echo off */
  7.   tcsetattr(f,TCSAFLUSH,&sg); /* set settings */
  8. }

  9. void UserIf::Echon(int f)
  10. {
  11.   struct termios sg;
  12.   tcgetattr(f, &sg);    /* get settings */
  13.   sg.c_lflag |= ECHO;  /* turn echo on */
  14.   tcsetattr(f,TCSAFLUSH,&sg); /* set settings */
  15. }

  16. string UserIf::getPassword(string prompt, int n)
  17. {
  18. char c;                   // for read()
  19. int i;                      // number of  input
  20. char *w;                // warning on retry
  21. int f;                      // file descripto
  22. char *p = new char(n+2);
  23. string ret;
  24. f = 0;  // Read from stdin
  25. // get password
  26. w = ""; //warning
  27. do
  28. {
  29.    fputs(w, stderr);
  30.    fputs(prompt.c_str(), stderr);
  31.    fflush(stderr);
  32.    i = 0;
  33.    Echoff(f);
  34.    do {                    /* read line, keeping n */
  35.      read(f, &c, 1);
  36.      if (i < n)
  37.      p[i++] = c;
  38.    } while (c != '\n');
  39.    Echon(f);
  40.    putc('\n', stderr);
  41.    fflush(stderr);
  42.    w = "(line too long)\n";
  43. } while (p[i-1] != '\n');
  44. p[i-1] = 0; //!!!notice
  45. ret = string(p);
  46. delete p;
  47. return ret;
  48. } /* end function getPassword */
复制代码


写得有点乱,本来想用std的stream来做的,可除了最基本的功能都不太熟悉,还是改用了c 的文件操作模式。

哎,做技术真是苦,一个小功能浪费了半天的时间,不过还是有点成就感的,探索的过程也很美:P

[ 本帖最后由 liangtf 于 2006-6-2 17:56 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-06-02 17:55 |只看该作者
支持员创,ps:不死3兄弟真锰啊

论坛徽章:
0
3 [报告]
发表于 2006-06-02 17:57 |只看该作者
HOHO,讨厌另一个让人睡觉恶魔,最邪恶,所以没选他:P

论坛徽章:
0
4 [报告]
发表于 2006-06-03 00:57 |只看该作者
一不小心进了精华,多谢版主!
写的时候特别随便,像是流水帐一样记在blog上了,不好意思

论坛徽章:
0
5 [报告]
发表于 2006-06-03 04:52 |只看该作者
Undead
I like!

论坛徽章:
0
6 [报告]
发表于 2006-06-03 09:47 |只看该作者
xd是高手,我讨厌不死

论坛徽章:
0
7 [报告]
发表于 2006-06-05 08:16 |只看该作者
thanks liangtf ~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP