linux查看智能卡命令,Linux PAM 模块建立“智能卡”登录(2)

具体的用法、约定有很多,不在这里解释了,可以 man 一下相应的函数或者看看 pam

的文档。

总体设计

认证过程与标准的 UNIX 认证差不多,只不过密码是存储在卡上的随机数,不是通过键

盘输入的就是了。

首先是认证标记:

typedef struct {

int magic;      /* 这里是'CARD',用来确认是不是一个有效的标记 */

int magic1;     /* 这里也是'CARD',但是如果有 PIN 的话,这个标记会一起被

加密 */

int id;   /* 一个随机数,只是个记号 */

char token[56]; /* 56个字节的随机数,充当密码使用 */

} token;

如果设定了 PIN的话,magic1、id和token[56]这三个域都要使用AES 加密存储,密钥

就是 PIN的 MD5值。

magic1、id和token[56]这几个加起来正好是64 个字节,也就是 AES blocksize的4

倍,这样就可以不要 padding 了;同时也是 SHA512 的输出的大小(下文会说到)。magic1

用来判断解密是否正确,PIN 不正确的话这里就不会是'CARD'。即使使用错误的PIN解密出

来的 magic1是'CARD',也不会通过接下来的测试。

存储在电脑上的"shadow"文件保存在/etc/cards,对每一个用户只储存这些项:用户名,

对应的认证标记种的 id,认证标记的 hash。hash 的算法作者采用的是重复 20000 次的

SHA512,hash的内容就是上一段说的那64个字节,这样可以省去第一次的特殊处理。

因为 SIM 卡中每一条电话号码记录是28 字节,每一条短信记录是 176 字节,所以认证

标记只能放到短信文件里(下文会说到)。

代码编写,PAM部分

#include

#include

#include

#include

#define _ gettext

#define PAM_SM_AUTH /* 要求有 pam_sm_authenticate的定义 */

#include

#include

#include

#include "common.h" /* 各种辅助函数, 会有相应的解释 */

#include "card.h" /* 智能卡的读写函数 */

#include "settings.h"

#define msg_error(args...) \

if(!(flags & PAM_SILENT)) { \

pam_prompt(pamh, PAM_ERROR_MSG, NULL, args); \

}

#define msg_info(args...) \

if(!(flags & PAM_SILENT)) { \

pam_prompt(pamh, PAM_TEXT_INFO, NULL, args); \

}

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,

const char **argv)

/*

这个就是认证的函数了,他的返回值决定了认证是成功还是失败

pamh: 应用程序由pam_start函数获得的句柄

flags: 标志位 具体请看PAM 的文档

argc/argv: 在配置文件中指定的参数

*/

{

int retval = PAM_AUTHINFO_UNAVAIL; /* 返回代码 */

token tok, *ptok; /* 认证标记 */

userinfo *uih = NULL, *u; /* 机器上存储的"shadow"文件 */

const char *desired_user = NULL, *rhost = NULL;

char hash[64];

setlocale(LC_ALL, ""); /* 这3 句是 L10N 相关的 */

bindtextdomain("pam_iccard", ".");

textdomain("pam_iccard");

parse_file("/etc/pam_iccard.conf", 0);

parse_args(argc, (char**)argv, 1);

if(on("silent")) {

flags |= PAM_SILENT;

}

if(PAM_SUCCESS == pam_get_item(pamh, PAM_RHOST, (const void **)&rhost)) {

if(rhost && strlen(rhost)) {

/* 不支持远程登录:

远程登录的时候(比如 ssh),认证的结果取决于那台机器上是否有智能

卡,这很显然不合理 */

msg_error(_("pam_iccard doesn't support remote login."));

retval = PAM_AUTH_ERR;

goto last;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值