学校のコンピューター室の準備作業として、UNIX でログイン プロセスをシミュレートする ac プログラムを作成するよう求められました。プログラムは端末からユーザー名とパスワードを読み取り、/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);
}
構造体 pwdb_passwd は、ファイル pwdb_lib.c および pwdb_lib.h で定義されており、既に書き込まれています。
プログラムをコンパイルすると、いくつかのエラーが発生します。たとえば、73 行目で、「エラー: 不完全な型へのポインターを逆参照しています」というメッセージが表示されます。
理由がわかりません。それは好きではないようですpw_entry->pw_passwd
。さらに言えば、Windows で Code::Blocks (gcc を使用) を使用してコンパイルすると、Ubuntu で gcc を使用する場合とは異なるエラーが発生します。これはかなり奇妙だと思います。pwd.h をインポートし、Windows ではなく Linux にのみ存在することが原因である可能性があると思われます。これは正しいでしょうか?独自の pwd.h ファイルを作成して同じディレクトリに保存しようとしましたが、それでも機能しませんでした。ubuntu コンピューターに移行すると、pwd.h からエラーが発生しませんが、代わりに「不完全な型へのポインターを逆参照しています」というエラーが発生します。
コードの何が問題になっていますか?
また、user_exists 関数でのメモリ リークも疑われますが、プログラム全体に影響があるかどうかはわかりません。