模拟密码登陆过程
知识点:
1.当查看手册发现头文件上面有宏定义的要在文件程序的最上方加上该宏定义。
2用到的函数:
getpwnam(name);//根据用户输入的name来查找passwd表,看是否有该用户
getspnam(name)//通过用户名在shadow中找到该用户的密钥,返回的是结构体指针
crypt(pas.sp->sp_pwdp)//通过crypt函数校验密码,用输入的密码和密钥用相同的算法进行加密,返回新密钥
3.步骤
3.1 用户输入帐号和密码,用两个数组进行保存;
3.2 调用getpwnam()函数判断passwd表中是否存在该用户(存在则继续,否则退出)
3.3 调用getspnam(name)函数,根据name在shadow表中找到存放该数据的表象,并返回结构体指针
3.4 调用crypt(新密码,密钥)函数对用户输入的密码按照和3.3求得 的密钥相同的算法加密,返回新密钥;
3.5 将3.4求得的密钥与原密钥通过strcmp(s1,s2)函数进行比较,形同则密码正确,用户可以进入。否则报错。
4.示例代码如下
#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <shadow.h>
#include <unistd.h>
#define SIZE 4096
int main(void)
{
char *t,name[SIZE],pas[SIZE];
system("clear");
//read user name and passwd from stdin
printf("login:");
fgets(name,SIZE,stdin);
t=strchr(name,'\n');
if(t) *t='\0';//del '\n'
system("stty -echo");
printf("passwd:");
fgets(pas,SIZE,stdin);
t=strchr(pas,'\n');
if(t) *t='\0';//del '\n'
system("stty echo");
putchar('\n');
//check user and passwd
struct passwd *pw;
pw=getpwnam(name);
if(pw==NULL)
{
fprintf(stderr,"user not exist or passwd error!\n");
return 1;
}
//读出密钥 shadow sp->sp_pwdp
struct spwd *sp;
sp=getspnam(name);
if(sp==NULL)
{
fprintf(stderr,"error!!!!!\n");
return 2;
}
//通过crypt函数校验密码:用输入的密码与密钥用相同的算法进行加密,返回新的密钥
char *ret;
//Link with -lcrypt
ret=crypt(pas,sp->sp_pwdp);
if(ret==NULL)
{
fprintf(stderr,"error!!!!!\n");
return 3;
}
//
if(strcmp(ret,sp->sp_pwdp)==0)
{
printf("login success.\n");
}
else
{
fprintf(stderr,"user not exist or passwd error!\n");
}
return 0;
}