让 Dropbear 更好地支持 PAM

2009/10/22 | 14:45 | 分类:Linux与开源 | 标签: | 695次阅读

  Dropbear 是一套来自澳大利亚的 *nix SSH 工具集,以体积微小著称,因此在嵌入式环境被广泛中使用。Dropbear 支持 Linux PAM,但直到目前最新的 0.52 版本,它对 PAM 的支持仍极其有限,只能做基本的身份认证(auth、account),不支持会话与密码管理(session、password)。在使用时,我发现即使是 Dropbear 已实现的 PAM 特性也存在一些不大不小的问题,需要自己动手解决。不过作者在 configure 的帮助中已经说明了现在只是“Try to include PAM support”,并且在与 PAM 相关的源代码注释中多次告知用户可以在什么地方 add、edit、hack 一些代码来满足自己特定的需求。我在编译部署 Dropbear 时,为了正常使用 PAM 认证,做了如下工作(基于 0.52 版本):
  1.开启 PAM 支持
  不要以为 configure 时加入 --enable-pam 参数就开启了 PAM 支持,仔细看 configure 输出的最后一句:Now edit options.h to choose features。我们需要自行修改 options.h,定义 ENABLE_SVR_PAM_AUTH 宏,同时将与其冲突的 ENABLE_SVR_PASSWORD_AUTH 宏注释掉,这样 PAM 相关的代码才会被启用。
  2.修正每次 PAM 会话(conversation)之后立即销毁密码的 bug
  svr-authpam.c 中的 pamConvFunc 函数实现了将客户端消息传递给服务端 PAM 的会话。为安全起见,第 119 行使用 m_burn 函数将用完的消息中的密码销毁(使用 0x66 字符覆盖)。但我们知道,在一次 pam_authenticate 调用中有可能配置了多个 PAM(pam_unix.so、pam_ldap.so……)陆续调用应用程序提供的会话函数来取用户名、密码,如果在第一次会话之后立即销毁密码,后续的会话就无法正常工作了。因此,需要等待所有 PAM 会话结束之后再销毁密码。我们可以注释掉 119 行;而 pam_authenticate 之后销毁密码的工作在 svr_auth_pam 函数中已经实现,不用新增。
  3.去除 PAM 会话函数只识别“password:”提示符为密码消息的限制
  svr-authpam.c 的第 101 行限制了密码消息的提示符为“password:”,但一些 PAM 有可能使用其它自定义的提示符,这使得 Dropbear 拒绝传送密码。事实上像 OpenSSH 等软件只是通过消息的类型为 PAM_PROMPT_ECHO_OFF 来认定其内容为密码,而不在意提示符是什么。因此,我们可以去除此处对提示符的判断,让使用自定义提示符的 PAM 也能与之兼容。
  4.解决 PAM 和基于 NSS 的用户映射无法同时工作的问题
  有的应用系统结合使用 PAM 以及 GNU C Library 提供的 NSS 特性实现应用级的用户到本地系统用户的映射。在这类系统中,用户提供给 PAM 的应用级用户名在 NSS 中被映射为本地系统级用户名,用户只持有应用级的密码而不用知道本地系统级的密码。login、OpenSSH、vsftp 等程序对此种需求的支持良好,但 Dropbear 的实现却是首先调用 getpwnam 获得本地系统级用户名(已经由 NSS 映射过的),再用这个用户名去调用 PAM 认证,这就使得 PAM 得到的是“本地系统级用户名+应用级密码”的组件,自然验证失败。我们可以修改 Dropbear 的实现,在 svr-authpam.c 的 recv_msg_userauth_request 函数中保存客户端输入的用户名,在 svr-authpam.c 的 svr_auth_pam 函数中读取前面保存的用户名,而不要使用 NSS 输出在 ses.authstate.pw_name 的本地用户名。
  所有修改如下,如果你也需要在 Dropbear 中支持 PAM 认证,可以直接打上这些 patch。我有空向 Dropbear 的作者反馈一下吧。

  1. dropbear-0.52$ cat options.h.diff
  2. 152c152
  3. < #define ENABLE_SVR_PASSWORD_AUTH
  4. ---
  5. > /*#define ENABLE_SVR_PASSWORD_AUTH*/
  6. 154c154
  7. < /*#define ENABLE_SVR_PAM_AUTH*/
  8. ---
  9. > #define ENABLE_SVR_PAM_AUTH
  1. dropbear-0.52$ cat svr-auth.c.diff
  2. 36a37,38
  3. > char client_login_username[256];
  4. >
  5. 142a145,146
  6. >     strncpy(client_login_username, username, 256);
  7. >
  1. dropbear-0.52$ cat svr-authpam.c.diff
  2. 41a42,43
  3. > extern char client_login_username[256];
  4. >
  5. 101c103
  6. <             if (!(strcmp(compare_message, "password:") == 0)) {
  7. ---
  8. >             if (/*!(strcmp(compare_message, "password:") == 0)*/ 0) {
  9. 119c121
  10. <             m_burn(userDatap->passwd, strlen(userDatap->passwd));
  11. ---
  12. >             /*m_burn(userDatap->passwd, strlen(userDatap->passwd));*/
  13. 198c200
  14. <     userData.user = ses.authstate.pw_name;
  15. ---
  16. >     userData.user = m_strdup(client_login_username);
  17. 247a250,252
  18. >     if (userData.user != NULL) {
  19. >         m_free(userData.user);
  20. >     }

从磁盘映像中挂载或提取指定的 LVM 逻辑卷

2009/10/19 | 13:40 | 分类:Linux与开源 | 标签: | 800次阅读

  前面提到了如何从磁盘映像中挂载或提取指定分区,现在我们再看看如何从含有 LVM 分区的映像中挂载或提取指定的逻辑卷(LV)。由于 LVM 分区内部有自己的盘区(PE)分配方法,因此逻辑卷在映像中并不一定是物理连续的,不能通过找到其偏移地址直接挂载。不过只要本地系统安装了 LVM 支持,就可以使用 LVM 自带的实用工具完成硬盘映像中逻辑卷的挂载。
  首先查看一下本地系统已经挂载过的物理卷(PV)、卷组(VG)和逻辑卷。我们看到,系统已经安装并激活了 VolGroup01 卷组。事实上 VolGroup01 中的 LogVol00 是本地系统的根分区,LogVol01 是交换分区。

  1. [root@centos CentOS]# pvscan
  2.   PV /dev/sda2   VG VolGroup01   lvm2 [136.00 GB / 0    free]
  3.   Total: 1 [136.00 GB] / in use: 1 [136.00 GB] / in no VG: 0 [0   ]
  4. [root@centos CentOS]# vgscan
  5.   Reading all physical volumes.  This may take a while...
  6.   Found volume group "VolGroup01" using metadata type lvm2
  7. [root@centos CentOS]# lvscan
  8.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  9.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  实验使用的 centos5-2-gnome.img 是一个安装了 CentOS 并通过 LVM 管理磁盘的映像文件。使用 fdisk 命令查看其分区结构,其中 centos5-2-gnome.img2 是 LVM 分区,fdisk 不能提供 LVM 的详细信息。

  1. [root@centos CentOS]# fdisk -l -u centos5-2-gnome.img
  2. last_lba(): I don't know how to handle files with mode 81a4
  3. You must set cylinders.
  4. You can do this from the extra functions menu.
  5.  
  6. Disk centos5-2-gnome.img: 0 MB, 0 bytes
  7. 255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
  8. Units = sectors of 1 * 512 = 512 bytes
  9.  
  10.               Device Boot      Start         End      Blocks   Id  System
  11. centos5-2-gnome.img1   *          63      208844      104391   83  Linux
  12. centos5-2-gnome.img2          208845     8385929     4088542+  8e  Linux LVM

  使用 Linux 的 loop 设备控制命令——losetup:首先用 -f 参数查找一个空闲的 loop 节点;然后通过 -o 参数指定 LVM 分区在映像中的偏移量(参考 fdisk 的输出),将其挂载在空闲的 loop 节点上;最后使用 -a 参数确认挂载成功。

  1. [root@centos CentOS]# losetup -f
  2. /dev/loop4
  3. [root@centos CentOS]# losetup -o $((208845*512)) /dev/loop4 centos5-2-gnome.img
  4. [root@centos CentOS]# losetup -a
  5. ...
  6. /dev/loop4: [fd00]:26706086 (centos5-2-gnome.img), offset 106928640

  再一次查看系统中存在的 LVM 设施。我们看到,映像中的 VolGroup00 卷组已被扫描到,其中有 LogVol00、LogVol01 两个未激活的分区。

  1. [root@centos CentOS]# pvscan
  2.   PV /dev/loop4   VG VolGroup00   lvm2 [3.88 GB / 0    free]
  3.   PV /dev/sda2    VG VolGroup01   lvm2 [136.00 GB / 0    free]
  4.   Total: 2 [139.88 GB] / in use: 2 [139.88 GB] / in no VG: 0 [0   ]
  5. [root@centos CentOS]# vgscan
  6.   Reading all physical volumes.  This may take a while...
  7.   Found volume group "VolGroup00" using metadata type lvm2
  8.   Found volume group "VolGroup01" using metadata type lvm2
  9. [root@centos CentOS]# lvscan
  10.   inactive          '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  11.   inactive          '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  12.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  13.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  这个例子中,映像中的卷组与本地已挂载的卷组名称不同,不会出现歧义。但如果映像中的卷组恰与本地已挂载的卷组重名,则可以使用 vgrename 命令修改映像中的卷组名称。

  1. [root@centos CentOS]# vgrename --help
  2.   vgrename: Rename a volume group
  3.  
  4. vgrename
  5.         [-A|--autobackup y|n]
  6.         [-d|--debug]
  7.         [-h|--help]
  8.         [-t|--test]
  9.         [-v|--verbose]
  10.         [--version]
  11.         OldVolumeGroupPath NewVolumeGroupPath |
  12.         OldVolumeGroupName NewVolumeGroupName

  使用 vgchange 命令激活 VolGroup00 卷组,再次查看逻辑卷的状态,LogVol00、LogVol01 已经可用。

  1. [root@centos CentOS]# vgchange -ay VolGroup00
  2.   2 logical volume(s) in volume group "VolGroup00" now active
  3. [root@centos CentOS]# lvscan
  4.   ACTIVE            '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  5.   ACTIVE            '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  6.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  7.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  现在便可以使用 lvscan 输出的逻辑卷设备文件名来挂载对应的文件系统了。

  1. [root@centos CentOS]# mount /dev/VolGroup00/LogVol00 ./part/
  2. [root@centos CentOS]# ls ./part/
  3. bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
  4. net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
  5. [root@centos CentOS]# umount ./part/

  如果要提取其中的分区,也可以直接对逻辑卷设备文件或 /dev/mapper/ 下对应的设备文件操作。

  1. [root@centos CentOS]# dd if=/dev/VolGroup00/LogVol00 of=LogVol00.img
  2. 6094848+0 records in
  3. 6094848+0 records out
  4. 3120562176 bytes (3.1 GB) copied, 113.93 seconds, 27.4 MB/s

  试挂载提取出来的分区。

  1. [root@centos CentOS]# mount -o loop LogVol00.img ./part/
  2. [root@centos CentOS]# ls ./part/
  3. bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
  4. net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
  5. [root@centos CentOS]# umount ./part/

  卸载文件系统之后,别忘了卸载卷组和 loop 节点。

  1. [root@centos CentOS]# vgchange -an VolGroup00
  2.   0 logical volume(s) in volume group "VolGroup00" now active
  3. [root@centos CentOS]# losetup -d /dev/loop4

Create your private bit.ly and twitpic

2009/10/15 | 23:45 | 分类:Web与移动平台 | 标签: | 510次阅读

As you know that some web 2.0 services, such as twitter web clients, URL shorteners, and picture hosting services cannot be accessed steadily in Mainland China. Perhaps you know how to break through the “wall”, but as information promulgators, we would better make our resources accessible for masses without special network skills or the lazy ones. A few months ago, I wrote Imagoxy, a picasa proxy for my blog readers. And these days a private URL shortener and a private picture hosting service are built for my twitter followers.

I chose a free PHP hosting service with advertisements to host these web applications. For one thing, I do not want my paid host be punished for being related to them accidentally, while free spaces are easily replaceable. For another, advertisements are only appended to htmls, and yet URL forwarding and picture files are not affected.

There are lots of free URL shortener scripts based on PHP and MySQL. I prefer TightURL, which is relatively simpler than the others, since web pages with rich features such as AJAX may go wrong for appended advertisements. Apache's RewriteEngine should be enabled to make the short URL more graceful. And you can also modify “tighturl.*.tmpl” to make it more friendly to users and external caller scripts. Like most of public URL shorteners, TightURL can be dragged into browser's bookmarks for convenience.

I had not found a free and simple enough PHP application to host pictures for twitter. So I wrote a tiny script for myself. It saves uploaded picture and send a tweet via twitter API (with shortened URL). I employed PHP Twitter to call twitter API for its simplicity. The script is accessible from my cellphone, so I can upload the taken photos instantly. I will release the script after more security measure taken.

More services can be deployed on free / advertisement web hosting sites. However, these sites are also usually banned by the “wall”. You should backup your data periodically and be ready to migrate at all times. The only unaltered entrance for your twitter followers is your domain name – unless you have too much influence infuriating somebody.

At last, my private services' domain name is “Jian.me”. It originates from my given name. It's interesting that “Jian” can be thought as “简” or “减” for URL shortener using.

我的肖像又一次被“误用”了……

2009/10/13 | 00:41 | 分类:生活空间 | 标签: | 698次阅读

  上一次是 2007 年 2 月,参考这里
  这一次很“荣幸”,是在 ZDNet“最受欢迎的 50 大中国技术博客”页面:
我的肖像又一次被“误用”了……
  第 27 名,林昊同志,用的是我林健的肖像。两个名字可以说是一字之差,也可以说是 50% 的误差。这是 ZDNet 编辑粗心搞错了呢,还是林昊朋友在故意开玩笑?这个网页左下角的广告正好说明了我的感觉:好囧呀。
  看了看这个名单,还不错,第 13 名高昂、第 21 名刘未鹏、第 44 名简朝阳都是我们《我是一只 IT 小小鸟》的作者,把我的照片混在里面还不至于太离谱。正巧林昊也是一位博文视点的作者,他的《OSGi 原理与最佳实践》我有机会要找来看看,服务框架方面的东西还是挺有意思的。这个博客名单里面还有几位我曾谋过面的 IT 达人,以及 RSS 订阅列表中的对象,看来我还是挺 IN 的呵。
  期待我的博客哪天真的上个什么(非负面的)排行榜吧,哈哈!


  Update (2009-10-13 12:34):与 ZDNet 沟通后,他们已经修正,换上了原版帅哥林昊。


  P.S. 同学报告,还有转载文章也照抄了我的肖像——
我的肖像又一次被“误用”了……

纪念陈志行教授

2009/10/12 | 21:06 | 分类:生活空间 | 标签: | 416次阅读

  今天是中国电脑围棋的先行者、中山大学化学系陈志行教授逝世一周年的日子。

纪念陈志行教授
陈志行、徐心和教授与北理工团队

  我认识陈老先生是在 2007 年重庆工学院举办的第二届中国机器博弈锦标赛上。作为中国计算机博弈界的元老,陈教授既是那次比赛的特邀嘉宾,也是重量级的参赛选手。为了鼓励新手,陈教授宣布自己只参加对弈而不计算成绩。在每局比赛中,陈教授总是同年轻的选手亲切地交流,点评他们程序的优劣、向他们传授围棋与编程两方面的经验。我当时参加的不是围棋项目,自己也不怎么懂围棋,但在旁边观战时却能够深切地感受到他条理的思路和无私的精神。陈教授对自己当时已处于肺癌晚期的事实毫不避讳,对于自己不能完成的事业仍怀有理性的规划,因此对年轻人也充满了殷切的期望。

纪念陈志行教授
手谈 v.s. 理治棋壮(围棋)

  陈志行教授研制的《手谈》软件在计算博弈界与围棋界可谓无人不晓,《手谈》在上世纪末、本世纪初的多项国际赛事中屡屡夺魁。可惜在盗版软件泛滥的大环境下,《手谈》的商业版本在国内并没有太大的营利,其主要市场在日本等周边国家,让发行商 KOEI 占尽了风头。陈教授 2000 年还出版过《电脑围棋小洞天》一书,讲述了他的电脑围棋生涯、经验和感悟,然而这毕竟属于一个小众领域,这本书的印量并不大,成为了业界同仁的经典收藏。

纪念陈志行教授
《手谈》(中文版)与《电脑围棋小洞天》

  “少年好学志于行”——这是陈志行教授名字的来历,也是他给予青年人的赠言。在陈教授逝世一周年的日子,让我们以此句自勉。

页面存档: 上页 1 2 3 4 5 6 7 8 ...44 45 46 下页