Linux的鉴别(Authentication)机制--PAM

来源:互联网 发布:蛋炒饭影评知乎 编辑:程序博客网 时间:2024/04/30 17:32
 

Linux的鉴别(Authentication)机制--PAM

             

转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

作者联系方式:李先静<xianjimli at hotmail dot com>

更新时间:2007-4-23

 

随着智能手机的日益普及,手机中储存的隐私信息越来越多,而手机的丢失率又居高不下,所以手机的安全性就显得更加重要了。为了保障数据的安全性,我们手机中的很多功能都需要鉴别(Authentication)之后才能使用。为了遵循标准的做法,不想自己搞一套鉴别(Authentication)机制,我花了一些时间去研究Linux-PAM。

 

有人说鉴别(Authentication)不就是对用户名和密码进行验证,以确认使用者的身份吗?没错,最简单的情况就是如此。但是,让用于单机的Login方法去代替于网络环境的 Kerberos方法,用户一定会觉得有很多不便。除此之外,事情也不那简单,比如对用户有效期的检查、对使用者的时间限制、对用户组的限制和对本地用户和远程用户的区分等等,处理方法都是不同的。由此可见,不同的场境需要不同的鉴别(Authentication)方法,或者需要多种鉴别(Authentication)方法的组合。

 

实际上,不仅有多种不同的鉴别(Authentication)方法存在,而且即使同一种方法也可能多种不同的表现形式。比如,同是普通用户名和密码验证方法,在Client/Server下,在Console下和在GUI下,它们的表现形式也不一样,这也是需要特别注意的。

 

不同的鉴别(Authentication)方法有自己的适用范围,把这些鉴别(Authentication)方法独立出来,供不同的应用程序使用,可以大大提高代码的复用率。而同一个应用程序,在不同环境,甚至在不同的时期,也可能会选择不同的鉴别(Authentication)方法。所以让鉴别(Authentication)方法的使用者和实现者分离开来,让它们各自独立发展,互不影响,显然是有利于软件维护的。这正是PAM(Pluggable Authentication Modules)的动机所在。

 

顾名思义,PAM就是基于插件式设计的一套鉴别(Authentication)方法框架和相应的模块实现代码。我们可以从以下几个方面来看PAM:

 

1.       PAM的使用者。

 

任何需要鉴别(Authentication)功能的软件都是可以是PAM的使用者。它调用PAM提供的统一的接口函数,去确认用户的身份,保证相关功能不会被非法使用。PAM的使用者只关心鉴别(Authentication)的结果,以决定让不让用户使用这个功能,而不关心鉴别(Authentication)方法。

 

PAM的使用者不关心鉴别(Authentication)方法,并不意味着所有PAM的使用者都不毫无区别,su的鉴别(Authentication)方法和FTP的鉴别(Authentication)方法肯定有所不同。如何区分它们呢,那就是靠配置文件,用不同的配置文件区分它们。

 

有时候,鉴别(Authentication)方法的实现模块需要向用户显示一些信息,比如鉴别(Authentication)失败,或者要求用户输入一些信息,比如用户名和密码。这都是与用户界面相关的,要根据PAM的使用者的要求,以不种的风格出现(Console或者GUI)。这可以在pam_start函数的pam_conv结构中传入一个回调函数,它由PAM使用者实现,由PAM的实现模块调用(有的提示语可以通过pam_set_item函数设置)

 

2.       系统管理员。

 

PAM的使用者需要指定一个配置文件,这只是为了与其它PAM的使用者区分开来,PAM的使用者并不关心配置文件的内容。配置文件的内容是系统管理员根据安全策略来决定的,比如,来自本机的root用户可以不输入密码,来自局域网内部的用户可以访问,而来自外网的用户禁止访问,或者全部使用用户名/密码方法鉴别,或者使用Kerberos方法鉴别。总之,这都是配置文件决定的。

 

系统管理员只修改配置文件,就可以使用不同的鉴别(Authentication)方法,而不需要修改源代码,不需要重新编译,这大大提高了鉴别(Authentication)的灵活性。

 

配置文件可以放在/etc/pam.d目录下,或者/etc/pam.conf文件中,下面是gdm的配置文件:

#%PAM-1.0

auth       required    pam_env.so

auth       include     system-auth

account    required    pam_nologin.so

account    include     system-auth

password   include     system-auth

session    optional    pam_keyinit.so force revoke

session    include     system-auth

session    required    pam_loginuid.so

session    optional    pam_console.so

 

如果没有指定配置文件,那么PAM就会用缺省的配置文件other,other的配置通常是禁止一切访问。

 

3.       PAM框架。

 

PAM框架采用了插件式设计和职责链模式。每种鉴别(Authentication)方法都是一个插件,要实现指定的插件接口函数。基于职责链模式,PAM框架可以把多种鉴别(Authentication)方法组合起来,以实现功能更强大的鉴别(Authentication)方法。

 

在配置文件中,用required、requisite、optional和sufficient等几个关键来决定职责链的执行/停止规则。

 

框架的实现代码在libpam目录里,pam_start函数里会读取配置文件,根据配置文件中描述的规则加载并组合插件,而pam_authenticate等函数则会调用_pam_dispatch去驱动职责链的执行。

 

4.       PAM鉴别(Authentication)方法的实现者。

 

每种PAM鉴别(Authentication)方法都是PAM框架的一个插件,PAM内置的鉴别(Authentication)插件可以静态编译到框架中去,也编译成共享库,由框架动态加载。插件要求实现下列接口(静态编译):

 

struct pam_module {

    const char *name;       /* Name of the module */

 

    /* These are function pointers to the module's key functions.  */

 

    int (*pam_sm_authenticate)(pam_handle_t *pamh, int flags,

                   int argc, const char **argv);

    int (*pam_sm_setcred)(pam_handle_t *pamh, int flags,

              int argc, const char **argv);

    int (*pam_sm_acct_mgmt)(pam_handle_t *pamh, int flags,

                int argc, const char **argv);

    int (*pam_sm_open_session)(pam_handle_t *pamh, int flags,

                   int argc, const char **argv);

    int (*pam_sm_close_session)(pam_handle_t *pamh, int flags,

                int argc, const char **argv);

    int (*pam_sm_chauthtok)(pam_handle_t *pamh, int flags,

                int argc, const char **argv);

};

 

这些函数基本上和PAM的API一一对应,插件并不要求实现以上全部函数,可以根据需要有选择的实现。插件之间可以用pam_putenv/pam_getenv通信,实现数据共享。

 

参考资料:

http://www.kernel.org/pub/linux/libs/pam/

http://www.ibm.com/developerworks/cn/linux/l-pam/index.html

 

~~end~~

原创粉丝点击