linux第三方串口,[原创]Linux下的第三方登录认证实现

本文的动机来自于一个项目,即:实现linux下的刷卡登录系统。因为使用ubuntu的缘故,接到项目时的第一感觉就是改写GDM。在GDM代码差不多看完以后,发现GDM认证采用了PAM机制。这种将认证交由第三方模块实现的做法,使开发者只要实现自己的认证模块,无需更改GDM本身的代码,大大降低了系统耦合。相比较于Windows xp的Gina以及vista下的provider,第三方认证机制虽然简洁优雅,但是文档方面还有所欠缺。故现将Linux PAM、GDM等相关资料整理出来,以便来者。

本文的测试开发环境:ubuntu9.04,虚拟机 virtualbox 3.2,GDM版本2.20.7,PAM版本1.0.1。将分别介绍GDM,PAM,然后简要说明gtk+以及linux下的串口读写。

1、GDM

GDM全称Gnome Display Manage,即Gnome显示管理器。狭义的理解可以把它看作一个登录管理器,但是gdm做的远比登录验证要多,如:gdm启动Xserver,管理基于XDMCP的远程连接,允许用户重启、关机等。

GDM有一个主进程。主守护进程异步运行,不会挂起。守护进程会启动很多slave进程,每一个slave进程代表一个Xserver,以及其中涉及的会话,slave进程可以挂起。我们看到的登录对话界面是一个greeter程序,由salve进程fork出来。主进程是root权限,slave进程是gdm用户权限,由slave进程fork出来的登录界面进程只能与slave进程通信,转发slave进程的问题给user,将user的回答给slave,这个设计可以保证安全性。即使用户利用gtk+的漏洞取得了一个shell,所能造成的破坏仅限于gdm本身。

下面简要分析一下gdm的启动流程,关于配置文件的分析等,可以参考gdm的官方文档,GNOME Display Manager Reference Manual。(http://library.gnome.org/admin/gdm/stable/security.html.en)

3.2节这段话直接说明了如何实现gdm下的第三方认证,动手前官方文档还是要认真看一遍。

If you wish to make GDM work with other types of authentication mechanisms (such as a fingerprint or SmartCard reader), then you should implement this by using a PAM service module for the desired authentication type rather than by trying to modify the GDM code directly. Refer to the PAM documentation on your system.

(如果你想让GDM配合其他类型的认证机制,如:指纹、智能卡等,你可以通过编写pam的service模块的方式,而不是试图直接修改GDM源码)

与用户认证有关的的代码启动顺序如下:

gdm.c       main()->gdm_start_first_unborn_local()->

display.c   gdm_display_manage (GdmDisplay *d)->void gdm_slave_start (GdmDisplay *d)->

slave.c     gdm_slave_run (GdmDisplay *display)->gdm_slave_greeter ()

上述是gdm的调用关系,gdm_slave_greeter ()最终fork出了greeter程序,即前台我们看到的登录对话界面。gdm_slave_run (GdmDisplay *display)在fork完greeter后,调用gdm_slave_wait_for_login ()函数,这个函数中初始化pam库,调用

verify-pam.c中  gdm_verify_user ()实现用户验证;主要包括:与前台greeter交互,取得用户名和密码,调用pam验证函数,验证是否能够登录。与前台交互采用管道,将标准输入输出绑定到管道上,注意所有的通信发起者都是slave进程,greeter只负责应答。

gdm_verify_user ()中pam相关的部分,遵循的是pam的规则,首先初始化pam库,指定pam对话函数gdm_verify_pam_conv()。在调用pam的验证函数pam_authenticate()时,pam将会使用此对话函数与前台greeter程序交互。也就是说使用pam,需要给pam提供一个与前台交互的函数。作为通用库的pam并不需要知道前台代码的逻辑,当pam验证用户的时候发现信息不足,就会调用交互函数。交互函数将用户输入存入约定的变量,pam取得后验证,返回认证的结果:通过或者不通过。

2、PAM

pam是由sun,对不起,现在应该叫oracle了,首先在solaris中实现的。

系统管理员通过PAM配置文件来制定认证策略,即指定什么服务该采用什么样的认证方法;应用程序开发者通过在服务程序中使用PAM API而实现对认证方法的调用;而PAM服务模块(service module)的开发者则利用PAM SPI(Service Module API)来编写认证模块(主 要是 引出一些函数pam_sm_xxxx( )供libpam调用),将不同的认证机制(比如传统的UNIX认证方 法、Kerberos等)加入到系统中;PAM核 心库(libpam)则读取配置文件,以此为根据将服务程序和相应的认证方法联系起来。

这个机制很好,很符合逻辑,很好的满足了第三方认证的需求:程序调用标准api,需要什么验证,由配置文件决定;怎么认证,则由第三方的认证提供者决定,比如指纹认证,编写一个符合规范的pam***.so即可。

Pam服务端的开发方法可以参照这个文档:

http://download.oracle.com/docs/cd/E19253-01/819-7056/ch3pam-01/index.html

转眼间,sun就变成了oracle,唉 。。。

3、gtk+和串口读写以及部署

auth需要实现两个函数

pam_sm_authenticate(pam_handle_t *pamh, int flags,

int argc, const char **argv)

pam_sm_setcred(pam_handle_t *pamh, int flags,

int argc, const char **argv)

pam_sm_authenticate中实现,在gdm用户名密码验证之前,跳一个窗口,提示刷卡;后台一个进程读串口,检测到刷卡事件给给前台窗口发信息,验证。pam_sm_setcred直接返回PAM_SUCCESS即可。

编译出来的pam_rfid.so拷贝到 /lib/security下

在gdm的pam配置文件中加一行即可:(/etc/pam.d/gdm)

auth    requisite       pam_rfid.so

4、enjoy

Eric Yang

2011.06.30

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值