【问题标题】:Better alternative for getpass functiongetpass 函数的更好替代方案
【发布时间】:2015-09-04 10:46:56
【问题描述】:

今天我正在编写一些东西,在某些时候我需要 getpass 函数,一切都很好,至少在我使用 --std=c11 之前我得到了:

错误:函数“getpass”的隐式声明 [-Werror=implicit-function-declaration]|

在网上我发现这个功能已经过时了。:

The getpass() function is not threadsafe because it manipulates global signal state.

The getpass() function is scheduled to be withdrawn from a future version of the X/Open CAE Specification.

所以我不能使用它,至少如果我用 --std=c11 编译的话。

我试过的程序是这样的:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>

    int main(void){
        char checkPasswd[BUFSIZ] = "iajsdiajsda32121312asda:ubuntu";
        char *checkName = "michi";

        char name[25];
        char *passwd;
        char *delimiter;

        printf("Login Name:\t");
        scanf("%24s" ,name);

        delimiter = strchr(checkPasswd, ':');
        delimiter[0] = '\0';
        delimiter++;

        passwd = getpass("Give a passwd:\t");

        if(strcmp(name,checkName) == 0){
             if(strcmp(passwd,delimiter) == 0){
                printf("Logged In\n\n");
             }else{
                printf("\t\t\tWrong Password\n");
                exit(1);
             }
        }else{
            printf("\t\t\tWrong Name\n");
            exit(1);
        }

        printf("\t\t\tWelcome %s\n\n", name);
        return 0;
    }

我在这里读到了一些东西 ==>> Getting a password in C without using getpass (3)? 也有一些答案,但我想知道在我尝试在那里找到的之前是否有简单的方法,类似于:

passwd = getpass("Give a passwd:\t");

或者我必须自己创建它?

这个程序不能满足我的需要:

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int main(void){
    struct termios oflags, nflags;
    char password[64];

    tcgetattr(fileno(stdin), &oflags);
    nflags = oflags;
    nflags.c_lflag &= ~ECHO;
    nflags.c_lflag |= ECHONL;

    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    printf("password: ");
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    printf("you typed '%s'\n", password);

    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    return 0;
}

所以问题是,我必须自己写还是有替代功能?

【问题讨论】:

  • 你从哪里得到#include &lt;fildes.h&gt;?它不在链接问题的已接受答案中。
  • @olaf 我只是在我的问题中建议了这个链接,我需要别的东西,否则我必须自己写。
  • @olaf 感谢您结束我的问题并向我展示了一些对我没有帮助的东西。您没有阅读我的问题。
  • 0) 我做得很好。 1)我没有关闭,只是投票。至少一个人显然同意。 2)您没有澄清为什么接受的答案对您不起作用。正如@ecatmur 所说,您没有遵循它,但甚至没有说明原因。

标签: c


【解决方案1】:

如果您的终端支持这些转义码,这将隐藏您输入的密码内容。

#include <stdio.h>

void UserPW ( char *pw, size_t pwsize) {
    int i = 0;
    int ch = 0;

    printf ( "\033[8m");//conceal typing
    while ( 1) {
        ch = getchar();
        if ( ch == '\r' || ch == '\n' || ch == EOF) {//get characters until CR or NL
            break;
        }
        if ( i < pwsize - 1) {//do not save pw longer than space in pw
            pw[i] = ch;       //longer pw can be entered but excess is ignored
            pw[i + 1] = '\0';
        }
        i++;
    }
    printf ( "\033[0A");//move cursor up one line
    printf ( "\033[21C");//move cursor 21 places
    while ( i) {
        printf ( "*");//overwrite password on screen. this is still concealed
        i--;
    }
    printf ( "\033[28m");//reveal typing
}

int main ( ) {
    char password[20];

    printf ( "Enter your password: ");
    fflush ( stdout);//prompt does not have '\n' so make sure it prints
    UserPW ( password, sizeof ( password));//password array and size
    printf ( "\nentered [%s]\n", password);//instead of printing you would verify the entered password
    return 0;
}

【讨论】:

  • 所以答案是,是的,我必须自己实现它。谢谢你的作品。
【解决方案2】:

让我在你自己的文章中给出几个 cmets:

getpass() 只能读取 8 个字符,所以不要使用它。

应以允许检测用户输入的字符是否多于预期的方式编写自己的代码。

filedes.h 不存在且不需要。

密码通常从 /dev/tty 或 stderr 读取。

如果您没有捕捉到重要信号,代码可能会使 tty 处于不可用状态。

查看 UNIX 源代码以获得有效的实现:

http://sourceforge.net/p/schillix-on/schillix-on/ci/default/tree/usr/src/lib/libc/port/stdio/getpass.c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 2018-04-15
    • 2011-10-26
    相关资源
    最近更新 更多