作为学校计算机实验室的预备任务,我们被要求编写一个模拟UNIX中登录过程的c程序。程序应该从终端读取用户名和密码,将其与本地文件中的散列值进行比较,该文件应该类似于/ etc / passwd。
这就是我所拥有的:
/*
* Program mylogin.c
*
* This program prompts the user for a login name and password
*
*/
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <string.h>
/* define some error constants */
#define NOUSER -1
/* define max size of a username */
#define USERNAME_SIZE 32
#define PASSWORD_SIZE 32
#define HASH_SIZE 32
#define FAILED_LIMIT 5
#define AGE_LIMIT 10
int read_username(char *username)
{
printf("login: ");
fgets(username,USERNAME_SIZE,stdin);
/* remove the CR included by getline() */
username[strlen(username)-1]='\0';
return(0);
}
int read_password(char *password)
{
printf("password: ");
fgets(password,PASSWORD_SIZE,stdin);
//getpass(password);
/* remove the CR included by getline() */
password[strlen(password)-1]='\0';
return(0);
}
int user_exists(const char *username)
{
struct pwdb_passwd *pw_entry;
pw_entry=getpwnam(username);
return((pw_entry)!=NULL);
}
int main(int argc,char **argv)
{
char username[USERNAME_SIZE];
char* password;
/* write "login:" and read user input */
read_username(username);
read_password(password);
if (!user_exists(username))
{
printf("Unknown user or authentication\n");
main(argc, argv);
}
struct pwdb_passwd *pw_entry = getpwnam(username);
char* hashed_password = crypt(password,pw_entry->pw_passwd);
if(strcmp(hashed_password, pw_entry->pw_passwd)==0)
{
if((pw_entry->pw_failed)<FAILED_LIMIT)
{
printf("User authenticated successfully\n");
pw_entry->pw_age++;
pw_entry->pw_failed = 0;
pwdb_update_user(pw_entry);
}else{
printf("User account locked\n");
main(argc, argv);
}
}
else
{
printf("Unknown user or authentication\n");
pw_entry->pw_failed++;
if(pw_entry->pw_failed>5){
printf("Too many failed attempts. Username now locked\n");
}
pwdb_update_user(pw_entry);
main(argc, argv);
}
return(0);
}
struct pwdb_passwd在已经编写的文件pwdb_lib.c和pwdb_lib.h中定义。
编译程序时,我遇到了一些错误。例如,在第73行,我得到:“错误:取消引用指向不完整类型的指针”
我不明白为什么。它似乎不喜欢pw_entry->pw_passwd
和类似的东西。更重要的是,在使用Code :: Blocks(使用gcc)在Windows下编译时,与使用gcc的Ubuntu下编译时会出现不同的错误。我发现这很奇怪。我怀疑它可能是因为我导入pwd.h并且它只存在于Linux而不是Windows上。这可能是对的吗?我尝试创建自己的pwd.h文件并将其保存在同一目录中,但它仍然无法正常工作。转移到ubuntu计算机,我不会从pwd.h的东西中得到错误,而是得到错误:“取消引用指向不完整类型的指针”
我的代码出了什么问题?
我还怀疑user_exists函数中存在内存泄漏,但我不确定它是否会影响整个程序。
答案 0 :(得分:1)
即使已经编写pwdb_lib.c
,您也需要将其包含在源文件中。
添加
#include "pwdb_lib.h"
到您的来源并确保您编译/链接pwdb_lib.c
通过#include
此文件,您可以让源文件了解其中的定义,而无需为其提供实现。最后,当您使用pwdb_lib.c
编译程序时(或链接其目标文件,如果这就是您正在做的事情),您可以让包含这些定义的任何来源知道它们的实现位置(因此,给它们能够使用它们。)
答案 1 :(得分:1)
如果标题名为pwdb_lib.h
,那么为什么您的程序不会#include
?它似乎包含一个不同的标题(pwd.h
),它是什么?
如果声明丢失,您所得到的错误就是您所期望的错误。