免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1019 | 回复: 0
打印 上一主题 下一主题

CVS 版本控制环境配置指南 - 第一部分 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-06 09:33 |只看该作者 |倒序浏览

                                                CVS 版本控制环境配置指南 - 第一部分
[color="#000000"]CVS Configuration HOWTO
CVS 版本控制环境配置指南
Stephen Suen
Copyright © 2005 Stephen Suen. All rights reserved.
CVS 是应用最为广泛的版本控制系统。有大量的有关如何使用 CVS 的参考资料,也有很多关于 CVS 的安装和配置的零散信息,并且如此多的开源团体在使用 CVS 作为他们的版本控制系统。但如何配置 CVS 环境,以满足多种访问方式以及访问控制需求,为用户提供安全可靠且便捷的版本控制服务,这方面的完整参考资料并不多见。本文则侧重这方面的内容,提供了关于 CVS 访问控制,访问方式以及常用第三方集成工具的详细信息。
本文的最新版本将发布在
程序员咖啡馆
网站上(建设中)。欢迎订阅我们的
邮件组
,以获得关于本文的正式发布及更新信息。全文在保证完整性,且保留全部版权声明(包括上述链接)的前提下可以在任意媒体转载——须保留此标注。
目录
前言
1. 关于本文
2. 读者对象
3. 关于范例
1. 概述
2. 安装
2.1. 从源代码安装
2.2. 从二进制安装(仅对 Solaris 用户)
3. 资源库
3.1. 创建资源库
3.2. 文件系统权限
3.2.1. 资源库所有者
3.2.2. 资源库根目录权限
3.2.3. 管理目录权限
3.2.4. 项目目录权限
4. 资源库访问方式
4.1. 资源库名称
4.2. 本地访问方式
5. 通过 SSH 访问
5.1. SSH 简介
5.2. SSH 服务器
5.3. 从 Unix 客户端访问 CVS
5.3.1. 公共密钥认证
6. 基于密码认证的服务器
6.1. 设置基于密码认证的服务器
6.2. 密码文件
6.3. 只读资源库访问
6.4. 匿名访问
7. CVSWeb
7.1. 需求
7.2. 安装
7.2.1. 安装 Perl(仅对 Solaris 用户)
7.2.2. 安装 Perl 模块
7.2.3. 安装 RCS 工具
7.2.4. 安装 CvsGraph(可选)
7.2.5. 安装 Enscript(可选)
7.2.6. 安装 CVSWeb
7.2.7. 配置 CVSWeb
8. ViewCVS
8.1. 需求
8.2. 安装
8.2.1. 安装 Python
8.2.2. 安装 RCS 和 Diffutils
8.2.3. 安装 ViewCVS
8.2.4. 配置 ViewCVS
参考文献
前言
目录
1. 关于本文
2. 读者对象
3. 关于范例
[color="#000000"]1. 关于本文
本文的主要内容侧重于 CVS 的配置和管理,包括访问控制,访问方式配置以及常用的第三方集成工具的配置。主要目的在于帮助 CVS 的管理员根据其所在组织对版本控制的需求,提出与之相适应的管理方案,并根据本文提供的“一站式”的参考信息,快速完成部署和配置。
本文不是 CVS 的使用指南。有大量的资源介绍如何使用 CVS
的丰富功能及其对应的命令,尤其是其官方参考手册,包含有非常完整的使用参考。本文在介绍相关配置和管理任务时,可能适当地对涉及的命令及其它内容加以简
单说明。但读者必须清楚,这些介绍当然不完整,其目的仅仅为了方便读者,使其偶然碰到不是十分熟悉的命令时,也不必非要查阅手册才能继续。
本文介绍的 CVS 的配置和管理都是基于 Solaris 操作系统的,同时也适用于其它 Unix 或者 Linux 操作系统。我们也建议应该尽可能地在这样的操作系统中配置 CVS(当然, CVS 的用户完全可以从 Windows 客户端访问 CVS 的资源库。)。所以,如果读者正在寻找如何在 Windows 的环境中配置这样的环境,本文就不是合适的参考资料,而只能作为辅助性的参考了。
[color="#000000"]2. 读者对象
本文的读者应熟悉日常的 Unix 管理任务,比如设置文件系统权限,管理系统用户信息,以及安装新的软件包等。读者还应该熟悉编译工具的使用,以及如何从源程序构建应用等。最后,毫无疑问,读者必须具有基本的 CVS 的使用知识和经验。
[color="#000000"]3. 关于范例
首先,本文所讲述的所有配置和管理任务的范例,均是针对 Solaris 操作系统的。所有列出的操作例子均适合于 Solaris 操作系统并经过验证。显然,绝大部分的内容都应该比较容易在其它 Unix 或者 Linux 环境中以类似地方式加以实施。当然,也有很多情况下,读者需要根据自身的实际环境,参考相应的其它信息来源才能实施。
本文所介绍的全部软件工具,都是基于写作时该软件工具的最新版本的。它们的版本更新,可能导致这里的内容不再适合。所以,作为良好的习惯,读者在获得这些软件的源程序或者二进制形式后,应阅读其中的信息文件,比如 README,RELEASE 或者 INSTALL 等等,之后再参考本文完成相应的配置和管理任务。
由于 Solaris 的编译工具不是免费的,所以正如本文所基于的操作系统环境一样,很多读者的 Solaris 系统中,需要安装 GNU 的 GCC 工具,以便构建本文述及的很多软件。读者应马上确认自己的操作系统中是否已经安装了编译工具,并确保它们正确配置,可以正常地进行编译和构建。
章 1. 概述
本文是 CVS 的配置和管理指南。在随后的章节中,将分别介绍 CVS 的安装;如何创建资源库,以及如何配置合理的的资源库访问权限;如何配置对资源库的远程访问,包括通过 SSH 的安全访问方式,基于密码认证的服务器访问方式,以及通过 Web 访问资源库。
在介绍这些配置和管理任务的过程中,主要涉及的当然是 CVS 本身。在配置资源库安全访问方式时,将介绍有关 SSH 的相关内容。在介绍通过 Web 访问资源库时,将介绍两个主要的第三方工具,包括 CVSweb 和 ViewCVS。此外,还包括另外一些常用工具,包括 CvsGraph 和 Enscript 等。
章 2. 安装
目录
2.1. 从源代码安装
2.2. 从二进制安装(仅对 Solaris 用户)
在大部分主流 Unix 和 Linux 操作系统中都预装有 CVS,可能在 /usr/bin 或者 /usr/local/bin 目录中。所以通常你可以跳过这个章节,直接进入后面的配置过程。下面示例中的命令可以检查 CVS 的版本:
$ cvs --version
Concurrent Versions System (CVS) 1.11.20 (client/server)
...
$
如果你的操作系统中没有安装 CVS 或者你热衷于使用最新版本的软件,可以参考这里的说明安装 CVS 的最新版本。
[color="#000000"]2.1. 从源代码安装
从 CVS 的官方网站
[color="#0000ff"]www.cvshome.org
可以找到它的最新版本。尽管有展现其特性的最新版本可供下载,配置将实际投入使用的版本控制环境时,建议读者应该安装其稳定版本,当前为 1.11.20。
下载的文件为源代码的压缩包,所以安装过程需要你的系统中有适当的解压缩和展开工具。同时还需要有适当的编译器(我们使用的是 GNU 的 GCC)。首先,参考下面的示例展开压缩文件:
$ gzip -dc cvs-1.11.20.tar.gz | tar xf -
$ cd cvs-1.11.20
在展开后的目录中,读者应仔细阅读文件 README 和 INSTALL 中包含的信息,尤其是你想订制构建或者安装过程时。对于大多数典型用户,这里讲述的基本过程通常就够了。
首先运行“configure”以创建所需的构建工程文件。此时,应确保你的编译器(我们使用 GCC)包含在 $PATH 环境变量中:
$ which gcc
/opt/sfw/gcc-3/bin/gcc
$ ./configure
默认的配置过程将设置安装的目标目录为 /usr/local。如果希望改变目标目录,可以指定 --prefix 选项。如下所示:
$ ./configure --prefix=/usr/cvs-1.11.20
如果配置过程成功结束,没有报告任何错误,就可以准备构建了。构建过程很简单,如下所示:
$ make
构建成功后,执行下面的命令将二进制程序及其文档安装到目标目录,即可完成安装过程。和很多其它软件的安装一样,这个过程通常需要 root 身份。这是由于安装的目标目录往往有权限限制。比如我们例子中,安装的目标目录为 /usr/local,而该目录只允许 root 用户写:
# make install
[color="#000000"]2.2. 从二进制安装(仅对 Solaris 用户)
如果你是 Solaris 用户,那么你可以不必从源代码安装。由 Sun 支持的网站
[color="#0000ff"]www.sunfreeware.com
为我们提供了很多软件的安装包,可以非常方便的通过 Solaris 的 pkgadd(1M) 软件包安装工具安装。在该站点上,所有软件按照平台类型和操作系统的版本加以组织。当然,这里提供的软件往往与其官方网站发布的最新版本有一定的延迟。目前最新的 CVS 版本为 1.11.19。找到适合你的环境的 CVS 安装包下载到本地。
下面的例子简要说明了其安装过程:
# gzip -d cvs-1.11.19-sol10-sparc-local.gz
# pkgadd -d cvs-1.11.19-sol10-sparc-local
章 3. 资源库
目录
3.1. 创建资源库
3.2. 文件系统权限
3.2.1. 资源库所有者
3.2.2. 资源库根目录权限
3.2.3. 管理目录权限
3.2.4. 项目目录权限
一旦 CVS 的可执行程序(cvs)安装到你的系统中,你就可以立即将其作为客户端访问远程主机上的资源库(repository)。如果想在你自己的主机上提供版本控制服务,就需要创建本地的资源库。
[color="#000000"]3.1. 创建资源库
CVS 的资源库由特殊的的管理目录 CVSROOT/ 和用户的项目目录组成。管理目录中保存着所有 CVS 的管理和配置文件。而用户项目目录则保存着用户的项目文件及相应的子目录。一般情况下,除了少数几个管理文件之外,无需也不应该直接访问资源库中保存的任何文件。对资源库的访问都应通过调用 CVS 的相应子命令完成(在不引起混淆的情况下,我们将直接称之为 CVS 命令)。比如利用命令从资源库检出(checkout)文件,经修改后,重新提交(commit)回资源库。创建资源库也是通过 CVS 的命令完成的。
CVS 命令的格式如下:
cvs [cvs_options] cvs_command [command_options] [command_args]
其中,cvs_options 被称为全局选项;cvs_command 为 CVS 命令;选项 command_options 为命令选项。全局选项影响所有的 CVS 命令,而命令选项则作用于指定的 CVS 命令。
有时,我们可能希望为不同组织或者出于其它目的,在同一主机上维护着相互独立的多个资源库的实例。这非常简单,只需要分别创建每个资源库并加以适当配置即可。CVS 可以轻易地管理所有这些资源库。这里以及本文后续的所有说明,均假设我们要为 javaplus.org 这个组织创建并配置服务于开源目的的资源库。在此基础上,创建更多的资源库的过程均类似于这个过程,只是需要根据不同的需求进行相应的配置而已。
假设我们所有的资源库都将创建在 /cvshome 目录中,而 /cvshome/javaplus 为将要创建的资源库实例所在的目录,则创建该资源库实例的命令如下:
# cvs -d /cvshome/javaplus init
其中,选项 -d /cvshome/javaplus 指定了资源库所在的目录(当然,你必须有该目录的写权限)。init 是 CVS 的命令,用于初始化,也就是创建新的资源库。我们在这里以及后面将要讲到的大部分管理和配置任务都将以 root 用户身份进行。因此,请先成为 root 用户。
提示: 如果需要在同一主机上维护多个资源库,将这些资源库组织在在同一路径下,通常有利于集中管理和维护。比如类似日常备份这种工作将更容易实施。
上述命令如果成功,将安静的返回。我们可以看看实际创建的资源库:
# ls /cvshome/javaplus
CVSROOT
# ls /cvshome/javaplus/CVSROOT
Emptydir        config          editinfo,v      modules,v       taginfo
checkoutlist    config,v        history         notify          taginfo,v
checkoutlist,v  cvswrappers     loginfo         notify,v        val-tags
commitinfo      cvswrappers,v   loginfo,v       rcsinfo         verifymsg
commitinfo,v    editinfo        modules         rcsinfo,v       verifymsg,v
在这个新建的资源库中只有一个 CVSROOT/ 子目录,即我们前面所讲的管理目录。这个管理目录中包含着初始的配置和管理文件(那些没有后缀的文件)。大部分的配置和管理文件都有一个对应的以“,v”作为后缀的历史文件。这意味着这些配置和管理文件像其它用户文件一样,也在版本控制之下。管理员可以检出这些文件,经修改后提交到资源库的管理目录。CVS 一方面在历史文件中保存所有修订信息,一方面将重建实际的配置和管理文件,以反映管理员的更新。有些管理文件,我们将在随后的配置任务中用到并加以说明。不过,我们这里的目标是指导如何一步步地建立 CVS 环境,关于这些管理文件的完整手册,请参考 [Cederqvist-1.11.20] 中的 Appendix A Guide to CVS commands 一节。
[color="#000000"]3.2. 文件系统权限
CVS 可以用于个人目的的版本控制工作,但其最主要的目标还是支持多用户协作,而绝大多数组织要求只有具有相应授权的用户才可以访问资源库中的特定资源,因此 CVS 管理员的重要任务之一是管理资源库的访问控制。
CVS 的访问控制基本上依赖于操作系统自身的文件系统访问控制,这意味着管理任务通常包括创建适当的系统用户和用户组,设置文件和目录的所有者及其组,设置文件和目录的访问权限等。本节将以传统的 Unix 和 Linux 文件系统访问权限为例,说明如何配置一个灵活可靠的 CVS 访问控制策略。
延续我们之前的 javaplus 例子,我们先来看看配置了文件系统访问权限之后的资源库根目录。随后,我们将针对该策略的不同方面分别加以讲解。
# ls -al /cvshome/javaplus
total 6
drwxrwsr-x   3 cvsowner cvsjppm      512 Apr 19 19:08 .
drwxr-xr-x   3 cvsowner root         512 Apr 19 19:08 ..
drwxrwsr-x   3 cvsowner cvsjpadm    1024 Apr 19 19:08 CVSROOT
[color="#000000"]3.2.1. 资源库所有者
在我们的文件系统访问控制策略中,权限主要是通过文件的组加以管理的。唯一需要特别创建的系统用户是作为资源库的所有者之用的。当然,由于所有者并
不直接影响我们的权限管理,你的访问控制策略中也可以不必创建这个特殊用户,而是使用其他任何对你来说有意义的用户作为资源库的所有者。不过,由于我们通
常赋予所有者以写权限,因此创建一个专门的用户服务于该目的可以使配置更直白,也更安全。为此,我们创建了一个系统用户,并将其命名为 cvsowner,参见下面的例子:
# grep cvs /etc/passwd
cvsowner:x:2401:1:CVS Owner Account:/cvshome:/bin/false
以 Solaris 为例,创建这个用户的命令如下:
# useradd -u 2401 -d /cvshome -s /bin/false -c "CVS Owner Account" cvsowner
需要注意的是,我们不需要 cvsowner 登录系统,因此指定了 /bin/false 作为其外壳程序,以禁止该账户登录系统。此外,例子中我们指定了 /cvshome 即所有的资源库的主目录作为该账户的主目录,便于实施针对 CVS 资源库的磁盘配额管理等任务。
提示: 选择 2401 作为该账户的 UID 并没有什么实际的特殊意义,只不过 2401 是 CVS 基于密码认证的服务器访问方式所建立的服务器的默认监听端口。我们将在后面说明如何建立这样的访问方式,以支持对资源库的只读匿名访问。
创建了该账户之后,我们将资源库的所有者设置为 cvsowner:
# chown -R cvsowner /cvshome
# ls -al /cvshome
total 6
drwxr-xr-x   3 cvsowner root         512 Apr 19 19:08 .
drwxr-xr-x  27 root     root        1024 Apr 26 00:30 ..
drwxrwxr-x   3 cvsowner root         512 Apr 19 19:08 javaplus
我们的配置中,目录 /cvshome 作为资源库的主目录,其中将包含多个资源库的实例。因此,我们在该目录层次上设置所有者。如果你的配置无需多资源库支持,应直接在资源库层次上设置。
[color="#000000"]3.2.2. 资源库根目录权限
设置了资源库的所有者之后,我们来讨论每个特定资源库实例的根目录权限。初始的资源库中只有一个 CVSROOT/ 子目录,我们将在下一节说明该管理目录的权限管理策略。
注意: 资源库的根目录,环境变量 $CVSROOT 和 CVSROOT/ 目录这些说法经常引起混淆。资源库的根目录即我们在创建新的资源库时,由 -d 选项指定的路径所对应的目录;而 CVSROOT/ 目录是根目录中的一个特殊的子目录,其中包含着 CVS 的管理文件。本文将始终分别用中文的“资源库根目录”以及字面形式的目录名称 CVSROOT/ 分别指代这两者。环境变量 $CVSROOT 除了定义了资源库的根目录的路径之外,还包含访问方式等信息。
所有将置于 CVS
的版本控制之下的用户项目都将保存为资源库根目录中的子目录,我们将其称之为“项目目录”。显然,对于大多数组织而言,在资源库的根目录中建立这样的顶层
项目目录通常需要特殊的授权,应该只有少数用户具有这样的权限。为此,我们需要建立一个特殊的系统用户组,所有被允许创建新项目的用户都将必须属于这个
组。
在 Solaris 中,建立这个组的命令可以是:
# groupadd -g 2402 cvsjppm
在为这个组及其它后续管理任务中将要创建的组命名时,我们采用了统一的命名规范。以 cvsjppm 为例,统一的前缀 cvs 将有助于组的检索等日常管理任务。由于我们的配置中存在多个资源库实例,所以我们使用缩写 jp 标识这个特定的资源库实例。最后的 pm 则为项目管理员(project manager)的缩写。如果不需要多资源库支持,可以省略资源库标识以提供更大的命名空间。
创建用户组之后,我们将资源库的根目录的组设置为这个新的用户组,同时设定权限如下:
# cd /cvshome
# chgrp cvsjppm javaplus
# chmod g+ws javaplus
# ls -al javaplus
total 6
drwxrwsr-x   3 cvsowner cvsjppm      512 Apr 19 19:08 .
drwxr-xr-x   3 cvsowner root         512 Apr 19 19:08 ..
drwxrwxr-x   3 cvsowner root        1024 Apr 19 19:08 CVSROOT
其中,我们除了赋予组应有的写权限之外,还同时设置了执行时设置组 ID 标志(set group ID on execution),即 SGID 标志。这样,在该目录中创建的文件和子目录得以自动继承父目录的组而不是当前进程的组。由于用户执行的 CVS 命令将以该用户执行命令时的有效组 ID 运行,设置该标志将避免用户更新资源库时,无意间造成其中的文件和目录组 ID 被修改,导致其他用户无法正常访问资源库。
[color="#000000"]3.2.3. 管理目录权限
现在我们来讨论资源库的管理目录,即 CVSROOT/ 子目录的权限设置问题。
提示: 事实上,CVS 不需要任何 CVSROOT/ 子目录中的管理和配置文件,就可以正常地以默认方式工作。
与其它正常的用户项目文件一样,CVSROOT/ 子目录中的大部分配置和管理文件可以通过 CVS 命令被检出,加以修改并提交回资源库。正如我们前面看到的,管理目录中既保存着这些文件的 RCS 格式的历史文件(以“,v”为后缀的文件),也保存着对应的普通文本格式的拷贝。当我们提交修改时,CVS 更新相应的历史文件,同时创建对应的普通文本格式的拷贝。我们会在其命令的输出中看到这样的信息:
cvs commit: Rebuilding admnistrative file database.
某些管理文件允许在用户执行 CVS 命令时自动运行用户所定义的命令(这些定制的命令有时被称为“插件”)。因此,具有对这些文件的写权限,实际上就可能运行任何程序。毫无疑问,必须严格限制对 CVSROOT/ 目录的写访问。为此,我们再创建一个特殊的用户组,只有属于该组的用户才有权限更新 CVSROOT/ 目录中的文件。参见下面的例子:
# groupadd -g 2401 cvsjpadm
# cd /cvshome/javaplus
# chgrp -R cvsjpadm CVSROOT
# find CVSROOT -type d -exec chmod g+ws {} \;
# ls -al
total 6
drwxrwsr-x   3 cvsowner cvsjppm      512 Apr 19 19:08 .
drwxr-xr-x   3 cvsowner root         512 Apr 19 19:08 ..
drwxrwsr-x   3 cvsowner cvsjpadm    1024 Apr 19 19:08 CVSROOT
在这个配置中,用户组 cvsjpadm 作为该资源库的管理员(administrator)组,并且具有对该目录的写权限。同时还设置了目录的 SGID 标志,以确保新文件自动继承适当的权限设置。由于 CVSROOT/ 目录中的文件包含资源库中用户项目文件的管理性信息,所有使用 CVS 命令访问资源库的用户都需要读取其中的文件。因此,应允许所有 CVS 用户具有对 CVSROOT/ 目录的读权限。此外,该目录中的绝大多数文件(马上我们将看到特例)被自动创建为只读文件(-r--r--r--),不要修改这些文件的权限设置。
CVS 使用了读写锁文件(lock
file)以防止对资源库文件的并发读写操作。默认配置下,对于需要锁定的目录,一些具有特定模式名称的文件和目录将创建在该目录中以标明该目录被锁定。
由于这个原因,即使用户仅仅希望检出该目录或者其中的文件,无意做任何更新,也必须具有对该目录的写权限。我们当然不能允许广泛的写权限,为了支持对资源
库中目录(也包括 CVSROOT/ 目录)的只读访问,我们将在后面说明如何配置基于密码认证的服务器访问方式的匿名只读访问支持。
注意: CVS 的锁是基于目录的,每个锁将锁定目标目录及其中包含的文件。此外,目标目录中两个服务于 CVS 内部目的的特殊子目录 Attic/ 和 CVS/ 也将同时被锁定。但是同一个锁并不锁定目标目录中的其它子目录。有关 CVS 锁机制的细节,参见 [Jennifer-03] 中 6.4.2 Locks 一节的详细说明。
前面讲到,在 CVSROOT/ 目录中的绝大部分文件是只读的,但是存在两个特例,分别是 CVSROOT/history 以及 CVSROOT/val-tags。其中,文件 CVSROOT/history 中保存着 CVS 命令每次被调用时的日志信息。这些信息可以通过 CVS 的 history 命令加以访问。文件 CVSROOT/val-tags 则用于缓存所有可用的标签(tag)名称以提高检索效率。不仅当用户创建新的标签时该文件将更新,检索同样可能引起这个文件的更新。因此,即使是资源库的只读用户,也必须具有对该文件的写权限。
提示: 如果想取消命令的日志特性,简单地删除文件 CVSROOT/history 即可。
利用 CVS 的 init 命令创建的资源库中,上述两个文件的权限均被设置为可读写(-rw-rw-rw-)。你可以如下面的例子所示确认权限被正确地设置:
# chmod 666 history val-tags
# ls -l history val-tags
-rw-rw-rw-   1 cvsowner root           0 Apr 19 19:08 history
-rw-rw-rw-   1 cvsowner root           0 Apr 19 19:08 val-tags
至此,资源库的文件系统权限就基本配置好了。尽管这里的说明不可能适合所有人,但你可以根据这里的信息和建议,配置适合你自身需求的策略。
[color="#000000"]3.2.4. 项目目录权限
所有的用户项目将保存为资源库中的子目录(及其中的文件和子目录),本文中称之为“项目目录”。管理目录 CVSROOT/
的权限管理方式,同样适用于项目目录的管理。为此,具有项目管理权限的用户(可能需要系统管理员的配合)需要在资源库的根目录中创建项目对应的子目录;建
立对应的系统组和项目组成员所需用户帐户;分配项目组成员到对应的系统组中;仿照管理目录的访问权限设置方式,设置项目目录的访问权限。详细的过程不再赘
述,下面是一个典型的例子:
# ls -l /cvshome/javaplus
total 8
drwxrwsr-x   2 cvsowner cvsjpbp      512 May 17 16:40 blogsplus
drwxr-sr-x   2 cvsowner cvsjpbp      512 Apr 25 13:02 blogsplus-web
drwxrwsr-x   3 cvsowner cvsjpadm    1024 Jun  9 16:04 CVSROOT
drwxrwsr-x   2 cvsowner cvsjpeaf     512 May 20 17:09 eaf
#
作为个人比较喜欢的一个实践方法,资源库中的项目目录的命名可以采用 $project[-$module] 的命名规范(参考自 Apache 的实践方法)。其中 $project 为项目的名称,$module 为可选的项目模块或者子项目名称。比如例子中的 blogsplus/ 为项目 blogsplus 的项目目录,而 blogsplus-web/ 则是 blogsplus 项目中被称为 web 模块(实际上是 blogsplus 项目的官方 Web 站点)的子项目目录。当然,项目目录的命名和管理也可以根据组织自身的实践采用其它的的命名规范及相应的管理方法。
章 4. 资源库访问方式
目录
4.1. 资源库名称
4.2. 本地访问方式
创建并配置了初始的资源库之后,就可以利用 CVS 作为客户端访问资源库了。CVS 支持通过多种访问方式访问资源库,包括本地资源库和远程资源库。在说明如何配置这些访问方式之前,我们先简单介绍一下它们。
[color="#000000"]4.1. 资源库名称
实际上,我们之前已经用到了所谓的资源库名称。由 CVS 的 -d 选项或者环境变量 $CVSROOT 指定的地址就被称为资源库名称,有时又称为资源库路径。除了这两种方式可以指定资源库名称外,我们还应该知道,当我们检出资源库的内容到我们的工作目录时,在工作目录中使用 CVS 的命令是不必指定资源库路径的。这是因为 CVS 在检出时,在工作目录中自动创建了一个特殊的 CVS/ 子目录,其中含有 CVS 所需的工作目录以及对应的资源库的信息。
资源库名称的完整格式如下所示:
[:method:][[[user][:password]@]hostname[:[port]]]path
其中 method 即访问方式,包括:
local
访问本地主机。
ext, server
通过 rsh 或其它类似的外部程序(比如 SSH)访问远程主机。
fork
像访问远程主机一样访问本地主机,主要用于调试或者错误诊断。
gserver, kserver
通过 GSSAPI 或者 Kerberos 连接访问远程主机。
pserver
基于密码认证的客户端/服务器访问方式。
如果 method 没有指定,且资源库名称中含有字符“:”,则默认为 ext 或者 server 访问方式。关于全部这些访问方式的完整说明,请参考 [Cederqvist-1.11.20] 中 2.9 Remote repositories 一节。我们将只介绍其中最常用的 local,ext 和 pserver 访问方式。后面两种是我们的重点,将在独立的章节加以介绍。这里将简单说说本地访问方式。
[color="#000000"]4.2. 本地访问方式
本地访问方式用于访问位于本地主机上的资源库。当路径名称中不含有字符“:”时,可以省略访问方法,而直接指定路径即可。这意味着在 Windows 系统中,如果资源库名称中需要包含驱动器符号,则必须指定 local 访问方法。比如下面是一个本地资源库名称的例子:
:local:e:\cvs\cvsroot
对于典型的协作开发环境中的大多数用户而言,资源库通常位于某个集中管理的远程主机中。本地访问可以用于偶然在资源库所在的主机本地执行 CVS 命令。比如,我们创建资源库时使用的 init 命令通常以本地访问方式执行。
本地访问方法的另一个值得推荐的用途是在你的本地主机上实现服务于个人目的的版本控制,来管理自己私人的文件。
章 5. 通过 SSH 访问
目录
5.1. SSH 简介
5.2. SSH 服务器
5.3. 从 Unix 客户端访问 CVS
对于远程主机上的资源库,最常见的访问方式为通过 rsh 或者类似的外部程序(比如我们将要说明的 SSH)进行访问,或者通过基于密码认证的服务器访问方式。本节说明如何通过 SSH 安全地访问 CVS 的远程资源库(也就是 ext 访问方式)。这种访问方式通常用于为称为提交者(committer)的用户,即需要通过提交等命令对资源库进行更新的用户,提供对资源库可写的访问支持。
[color="#000000"]5.1. SSH 简介
rsh 协议用于通过网络运行远程主机的程序。CVS 的访问方式 ext 和 server 都用于通过 rsh 或类似程序访问远程主机之上的资源库。不同点在于 server 方式使用内部的 rsh 客户端,只有少数特殊版本的 CVS 支持这种访问方式。而我们使用的 ext 方式则指定外部的 rsh 程序作为客户端。默认情况下,CVS 使用 rsh 命令,也可以通过环境变量 $CVS_RSH 指定将调用的其它可以访问远程服务器的类似程序。指定的程序必须能够不做任何修改的在本地和服务器之间传输数据。比如某些 Windows 系统之上的 rsh 程序不适合这一任务,因为它们会自动在不同操作系统间转换换行符。rsh 的问题在于其安全性。由于它无法为通过网络传输的数据提供保护,这就使得不怀好意的人可以轻易地利用这一点获取,或者篡改你通过网络传输的数据,用于不正当的目的。
SSH 是目前广泛使用的替代 rsh 的方案。SSH 指的是安全的外壳(secure shell),不过这只是因为受 rsh 名称的启发。事实上,SSH 并不是如同 Unix 的 Bourne 或者 C 那样的外壳程序。它不是命令解释器,而是一个协议,用于以和 rsh 相同的方式创建一个通道,以运行远程主机上的外壳程序。与 rsh 的不同之处在于,SSH 提供在本地和远程之间提供了端到端的加密通道,所有被传输的数据均被基于可靠的算法进行了有效的加密。
作为协议,SSH 具有经典的客户端/服务器架构。服务器端的 SSH 服务器程序,负责接受来自客户端的连接,并处理其请求。用户则使用 SSH 的相应客户端程序,连接服务器,并向服务器提出请求。比如登录,发送文件或者执行命令。
对 SSH 本身的详细讨论,已经超出了本文的范围。为了让初次接触 SSH 的 CVS 用户也能快速起步,本文在说明如何通过 SSH 访问资源库时,尽可能地对相关的 SSH 的基本使用加以说明。对于服务器端和 Unix 客户端,我们的示例是基于 Solaris 操作系统的,不过,因为 Solaris 中的 SSH 实现是基于广泛采用的 OpenSSH 的实现,所以应该可以比较容易地应用于其它环境。如果你的操作系统环境不同,或者希望了解更多 SSH 的有用信息,请参考 [Daniel-01]。
[color="#000000"]5.2. SSH 服务器
流行的 Unix 操作系统默认情况下都安装配置了的 SSH 的实现。例如 Solaris 中的 SSH 就是基于最广泛使用的 OpenSSH 的实现。对于 OpenSSH 以及其它主流的 SSH 实现,服务器端主要包括守护程序 sshd 及其配置管理文件。可以按照如下示例检查服务器中是否已经运行了该服务器程序:
# ps -ef | grep sshd
    root   349     1   0   Apr 22 ?           0:00 /usr/lib/ssh/sshd
[color="#000000"]5.3. 从 Unix 客户端访问 CVS
在 Unix 上,通过 SSH 访问 CVS 的资源库需要如下软件:

我们知道,对于 CVS 而言,唯一的程序 cvs 可以作为服务器端守护程序(用于 pserver 访问方式),也可以用作客户端。而对于 SSH 而言,流行的 Unix 系统中基本上都默认安装了该程序。对于 Solaris 或者 OpenSSH 及其它大部分 SSH 的实现而言,程序 ssh 及其配置文件就是我们需要的主要客户端软件。
注意: SSH 的实现中通常还包括其它客户端程序,比如用于安全的拷贝文件的 scp 以及用于生成和管理密钥的 ssh-keygen 等。
这里,我们先简要介绍一下 SSH 客户端的基本使用。首先我们来测试一下客户端程序是否安装就绪,以及能否正常地连接到远端的服务器。假设远端的服务器为 192.168.0.80,我们将使用 ssh 登录远端服务器,建立一个伪终端。参考下面的示例:
$ ssh -l stephen 192.168.0.80
Password:
Last login: Wed May 11 12:44:38 2005 from sol0
Sun Microsystems Inc.   SunOS 5.10      s10_55  May 2004
$
使用 SSH 登录远端系统,需要用户在远端的主机中拥有自己的系统帐户。在上面例子中,选项 -l 就是用于指定登录远端系统的用户帐户。随后的参数指定了远端主机的地址。
提示: 如果执行上面命令时,本地的用户帐户与将要登录的远端帐户相同,可以省略 -l 选项。
如果一切正常,ssh 将建立到远端系统的连接,并提示用户输入登录远端系统的用户帐户所需的密码。正确输入密码后,一个伪终端将被建立起来,用户可以象通过 telnet 一样使用远端系统。
如果用户是首次使用通过 SSH 连接这个远端系统,则情况会略有不同。参见下面的例子:
$ ssh 192.168.0.80 [color="#000000"](1)
The authenticity of host '192.168.0.80 (192.168.0.80)'can't be established.
RSA key fingerprintis d7:5d:ff:fa:06:63:b2:8e:c8:e3:49:d1:80:e9:ae:93.
Are you sure you want to continue connecting (yes/no)? yes [color="#000000"](2)
Warning: Permanently added '192.168.0.80' (RSA) to the list of known hosts. [color="#000000"](3)
Password: [color="#000000"](4)
Last login: Wed May 11 13:30:26 2005 from sol0
Sun Microsystems Inc.   SunOS 5.10      s10_55  May 2004
$
(1)
连接远端系统。因为本地帐户与登录远端系统使用的帐户相同,所以省略了 -l 参数。
(2)
提示首次连接指定的远端系统,远端系统真实性无法确认,要求用户确认是否继续连接。
(3)
警告用户指定的主机已经永久添加到已知主机的列表中。
(4)
输入登录远端系统所需的密码。
SSH 有一个特性,即“已知主机”特性(Known Hosts)。作为安全的连接方式,它不仅认证客户端,同时也对远端的服务器加以认证。每个 SSH 服务器都有一个被称为“主机密钥”(Host Key)的密钥,用以唯一标识该主机。当用户首次连接某个远端主机时,SSH
将检查本地的已知主机数据库,判断是否信任该远端主机。如果在数据库中没有找到远端主机的主机密钥,将提示用户用户远端主机的真实性无法确认。用户必须人
工干预,确认是否继续连接过程。一旦选择继续连接,则远端主机的密钥将自动添加到已知主机数据库中,此后的正常连接将不再提示主机真实性问题。在 Solaris 和 OpenSSH 实现中,对于特定的用户,该数据库位于 $HOME/.ssh/known_hosts 文件中。此外管理员可以在 /etc/ssh/ssh_known_hosts 文件中配置全局的已知主机数据库。
在上面描述的过程中,连接过程要求用户输入远端主机上的用户密码。这种用户认证的方式被称为密码认证。密码认证方式虽然应用起来比较简便,
但是密码从客户端通过网络传递到服务器。尽管传输过程比较安全,但是如果目标服务器已经被攻破,则密码在服务器端可能被轻易获得。如果需要更安全的认证方
式,可以使用下面介绍的公共密钥认证方式。
[color="#000000"]5.3.1. 公共密钥认证
公共密钥认证基于公共密钥加密系统对用户进行认证。公共密钥加密系统的加密和解密是分别通过一对不同的密钥完成的,并且从加密的密钥不可能导出解密
的密钥。认证的基本过程是,用户首先生成一个公共/私有密钥对,服务器知道公共密钥,而用户自己保有私有密钥。在服务器端用户的主目录中,文件 $HOME/.ssh/authorized_keys 中有允许登录的公共密钥的一个列表,用户需要将其密钥对中的公共密钥添加到这个列表中(允许用户使用多个密钥对)。当用户请求认证时,SSH 告诉服务器用户希望使用哪个密钥对进行认证,而服务器则检查密钥是否允许登录。如果发现匹配的公共密钥,则服务器向用户(实际上是程序 ssh
)发出一个口令(Challenge)。口令为一个随机生成的数字,由用户的公共密钥进行加密。这个口令只有用户保有的私有密钥才能解密。用户端收到口令
后,用私有密钥解密,经某种哈希运算处理后发送回服务器。服务器利用相同的哈希算法检查发回的口令是否正确。如果正确,则用户认证成功。整个过程中,用户
都不必向远端服务器暴露自己的私有密钥。
为了使用 SSH 的公共密钥认证,用户首先要生成自己的密钥对。对于 Solaris 而言,程序 ssh-keygen(1) 用于生成和管理这样的密码对。参见下面的示例:
$ ssh-keygen -t dsa [color="#000000"](1)
Generating public/private dsa key pair.
Enter file in which to save the key (/export/home/stephen/.ssh/id_dsa): [color="#000000"](2)
Enter passphrase (empty for no passphrase): [color="#000000"](3)
Enter same passphrase again: [color="#000000"](4)
Your identification has been saved in /export/home/stephen/.ssh/id_dsa.
Your public key has been saved in /export/home/stephen/.ssh/id_dsa.pub.
The key fingerprint is:
7a:dd:dd:0e:96:15:62:21:c2:ad:ee:7c:34:54:e3:fa stephen@sol0
(1)
生成新的密钥对。选项 -t dsa 指定使用 DSA 算法。
(2)
用户指定密钥对保存在什么文件中,回车接受默认值即可。
(3)
用户输入用于保护密钥的密语(Passphrase),直接回车表示不需要该密语。
(4)
用户重复输入用于保护密钥的密语。
生成的过程没什么神秘之处。命令行选项 -t dsa 指定基于 DSA 算法生成密钥,还可以通过 -t rsa 指定基于 RSA 算法生成密钥。ssh-keygen 生成密钥后,提示用户指定保存密钥的文件,一般来说,接受默认值即可。ssh-keygen 将在用户的主目录中创建 .ssh/ 子目录(如果不存在的话)保存密钥文件。稍微特别一点的地方在于要求用户输入的密语,该密语的目的在于保护用户的密钥,每次访问密钥时,都必须提供这个密语。这里有意使用了不同的词 passphrase 用于区别于用于登录系统帐户的用户密码 password,强调了密语允许并鼓励使用空格和标点等。
生成的密钥对分别保存在两个文件中,其中私有密钥只有用户自己可读。下面是生成的结果:
$ ls -l $HOME/.ssh
total 4
-rw-------   1 stephen  staff        668 May 12 11:34 id_dsa
-rw-r--r--   1 stephen  staff        602 May 12 11:34 id_dsa.pub
如同用户帐户和密码之间的关系一样,生成密钥后,还需要建立用户帐户和密钥之间的关联。建立这种关联的方式就是将自己的密钥对中的公钥安装到远端服务器中的自己的帐户中。在服务器上自己的主目录中创建文件 $HOME/.ssh/authorized_keys 并将自己的公共密钥,也就是上面示例中的文件 id_dsa.pub 中内容添加到该文件中。实际上,这个文件中可以包含一组公共密钥的列表,每个密钥占一行。
我们将使用 SSH 的另一个客户端程序,即 scp(1) 来安装我们的密钥到服务器端。改命令用于在网络间通过安全的通道复制文件。它使用 ssh 来传递数据,使用与 ssh 相同的认证方法并提供同等的安全性。典型的 scp 用法非常直白,我们还是在实际的示例中加以说明。我们的服务器还是 192.168.0.80,参见下面的安装过程:
$ cd $HOME/.ssh
$ scp id_dsa.pub stephen@192.168.0.80:.ssh/id_dsa.pub [color="#000000"](1)
Password: [color="#000000"](2)
id_dsa.pub           100% |*****************************|   602       00:00
$ ssh -l stephen 192.168.0.80 [color="#000000"](3)
Password: [color="#000000"](4)
Last login: Fri May 13 12:53:28 2005 from sol0
Sun Microsystems Inc.   SunOS 5.10      s10_55  May 2004
$ cd .ssh
$ cat id_dsa.pub >> authorized_keys [color="#000000"](5)
$ chmod 644 authorized_keys
$ ls -l authorized_keys
-rw-r--r--   1 stephen  staff        602 May 13 12:54 authorized_keys
$ rm id_dsa.pub
$ exit
Connection to 192.168.0.80 closed.
(1)
通过 scp 将本地的公共密钥文件拷贝到远端服务器上。
(2)
命令 scp 提示用户输入远端服务器的登录密码。
(3)
通过ssh 登录到远端服务器。
(5)
将密钥安装到主目录中。
远程文件复制程序 scp 的使用方法和基本的 Unix 文件复制程序 cp(1) 相似,都需要指定复制的源文件和目标文件。不过 scp 可以通过下面的方式指定远端主机之上的文件:
[[user@]host:]file
此外,在上面的例子中,我们还可以看到 scp 也象 ssh 一样提示用户输入登录远端系统的密码以便基于密码进行用户认证。成功认证后,文件将被复制到远端系统中。后面的过程就比较直白了。通过 ssh 登录远端服务器,从刚刚复制上来的公共密钥文件中析取内容,并安装到我们之前说明过的文件中。此时,公共密钥文件已经没有作用了,可以简单地将其删除即可。
ssh 是自动应用基于公共密钥的认证方式而无需特别的配置的。按照上面介绍的步骤,在服务器上安装了用户的密钥后,就可以基于公共密钥认证自动登录远端服务器了。现在我们再次利用 ssh 连接远端主机,可以发现不再需要输入用户密码了:
$ ssh -l stephen 192.168.0.80
Last login: Fri May 13 13:02:59 2005 from sol0
Sun Microsystems Inc.   SunOS 5.10      s10_55  May 2004
$
如果在生成密钥对时指定了密语,则登录时,ssh 会提示用户输入访问密钥所需的密语。参见下面的示例:
$ ssh 192.168.0.80
Enter passphrase for key '/export/home/stephen/.ssh/id_dsa':
Last login: Mon May 16 12:51:07 2005 from sol0
Sun Microsystems Inc.   SunOS 5.10      s10_55  May 2004
$
这里要求输入的密语不同于基于密码认证的登录过程中要求输入的密码。密语用于访问本地文件系统中保存的私有密钥,它不会象密码那样通过网络传递到远端系统中。
配置了 SSH 之后,我们就可以通过它来访问 CVS 的服务器了。这里,需要特殊配置的就只是环境变量 $CVS_RSH。该环境变量指定访问远端 CVS 资源库所需的外部程序,默认情况为 rsh,而我们将使用的则是 ssh。另外,环境变量 $CVSROOT 中访问方法要设置为 ext(当然,也可以省略访问方法)。参考下面的示例:
$ CVSROOT=:ext:stephen@192.168.0.80:/cvshome/javaplus
$ CVS_RSH=/usr/bin/ssh
$ export CVSROOT CVS_RSH
$ cd workdir
$ cvs co CVSROOT
cvs checkout: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
章 6. 基于密码认证的服务器
目录
6.1. 设置基于密码认证的服务器
6.2. 密码文件
6.3. 只读资源库访问
6.4. 匿名访问
基于密码认证的服务器,即 pserver 访问方式,是 CVS 提供的一种基于客户端/服务器模式的资源库访问方式。当客户端通过基于密码认证的服务器访问资源库时,它实际上是连接到资源库所在的服务器的一个特定端口,默认情况下为 2401。和其它很多 Unix 的服务一样,CVS 服务器本身在发生连接请求之前并不启动。Unix 的 inetd(1M) 程序负责监听指定的端口,当连接请求发生时,它将负责启动 CVS 的服务器,并建立其与客户端之间的连接。之后,客户端就可以通过这个连接访问指定的资源库,而且,在我们后面的示例中可以看到,CVS 允许通过其服务器连接多个资源库的实例。
基于密码认证的服务器访问模式通常用于对安全要求并不严苛的环境,尤其经常用于为公众提供对资源库的匿名只读访问支持。对于安全要求较高的情况,应通过前面介绍的外部访问方式(ext)。
[color="#000000"]6.1. 设置基于密码认证的服务器
设置基于密码认证的服务器,首先需要修改 inetd 的两个配置文件:/etc/services 和 /etc/inetd.conf。前者用于将端口号映射为服务名,后者指定 inetd 将启动的服务程序。
首先,在文件 /etc/services 中添加下面的行:
cvspserver        2401/tcp
然后,在文件 /etc/inetd.conf 中添加类似下面的行:
cvspserver        stream        tcp        nowait        root        /usr/local/bin/cvs        cvs \
        --allow-root=/cvshome/javaplus pserver
在实际的配置文件中,上面的配置项应在一行,没有结尾的反斜杠。选项 --allow-root 指定了允许用户访问的资源库目录,可以重复指定多个 --allow-root 选项以指定多个资源库实例。如果用户端指定了这里列出的资源库目录之外的目录,连接将被禁止。CVS 命令 pserver 用于启动基于密码认证的服务器(CVS 不需要另外的程序作服务器,同一个程序既用作服务器,也用作客户端)。
注意: 很多 inetd 对命令行的参数和长度有限制。如果你有很多资源库目录需要指定,可以让 inetd 调用一个外壳程序,而在外壳程序中调用 cvs
配置好 inetd 之后,重起 inetd 以使新的配置有效:
# ps -ef | grep inetd
root   207     1   0 17:06:31 ?           0:00 /usr/sbin/inetd -s
# kill -HUP 207
现在就可以从客户端访问 CVS 的服务器了。如果需要,你可以按照下面的方式简单测试一下连接是否正常:
$ telnet 192.168.0.80 2401
Trying 192.168.0.80...
Connected to 192.168.0.80.
Escape character is '^]'.
cvs [pserver aborted]: bad auth protocol start:
Connection to 192.168.0.80 closed by foreign host.
$
telnet 连接到服务器之后,直接键入回车,应该可以看到类似上面的输出,说明 CVS 服务器已经准备好接受连接请求了。
[color="#000000"]6.2. 密码文件
CVS 的问题在于它的安全性很差。作为客户端,它用明文,或者说跟明文一样(经过简单的编码),来保存用户密码,并通过网络传递用户密码。为了稍微,只是稍微提高一点安全性,CVS 允许管理员使用一个特殊的密码文件,即 CVSROOT/passwd 为用户指定一个不同于其系统帐户密码的 CVS 密码,同时还可以指定不同于其系统帐户名称的专用于 CVS 的用户名。这种机制被称为“别名”(aliasing)机制。
文件 CVSROOT/passwd 在初始的管理目录中并不存在,管理员必须手工创建这个文件。它的格式有点类似于 Unix 操作系统的密码文件 /etc/passwd,以行为单位,冒号分隔不同的域,每一行指定一个用户。完整的格式如下:
USERNAME:[ENCRYPTED_PASSWORD[:SYSTEM_USERNAME]]
其中,USERNAME 指定 CVS 的用户名;可选的 SYSTEM_USERNAME 指定 CVS 用户名将映射成为的系统用户名。一旦认证成功,cvs 将以该用户身份运行。这就使得用户可以使用不同于其系统帐户的用户名作为其 CVS 用户名。而且,管理员还可以出于某些管理目的,将很多 CVS 用户映射到同一系统帐户。比如,有些管理员利用这一特性,创建不同的系统用户,并将 CVS 用户映射为特定的系统用户,配合文件系统权限设置,来控制对资源库不同部分的访问。但是这种基于系统用户而不是系统组的访问控制策略的局限性在于,一个 CVS 用户名只能映射为一个系统用户名。如果需要访问资源库的不同部分,就成了问题。用户名映射的另一个需要注意的特点是,如果没有指定系统用户名,则 CVS 的用户名必须与一个实际的系统用户相匹配。
注意: 不必担心系统用户名与 CVS 用户名不同时 CVS 的日志问题。CVS 使用 CVS 用户名而不是映射后的系统用户名记录日志等历史信息。
加密后的密码 ENCRYPTED_PASSWORD 指定用于 CVS 认证的密码。毫无疑问,这个密码应该不同于用户实际的系统密码。这里使用的加密方法和系统密码文件中使用的方法相同,所以,可以从系统密码文件中拷贝加密后的密码字符串出来。这种方法显然不太方便,下面提供了一个用 Perl 写的脚本工具可以用于生成密码的加密文本(该脚本摘自 [Moshe-03] 中的 Chapter 3 CVS Repository Administration 一节):
#!/usr/bin/perl
srand (time());
my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
my $plaintext = shift;
my $crypttext = crypt ($plaintext, $salt);
print "${crypttext}\n";
可以将这个文件保存在 /usr/local/bin/cryptout.pl 或其它合适的地方。该工具使用起来很简单:
$ ls -l /usr/local/bin/cryptout.pl
-rwxr-xr-x   1 root     root         265 Feb 17 11:17 /usr/local/bin/cryptout.pl
$ cryptout.pl "some password"
Rx/roEqHzSKUs
$
提示: 在文件 CVSROOT/passwd 中如果没有给出加密的密码,则意味可以使用任何密码,包括空密码进行认证,但 CVS 用户名之后的冒号还是必须有的。
下面是一个文件 CVSROOT/passwd 的例子:
stephen:aKNyh8VOAYAts
james:ldV9RIhccZUS.
ben:doZErS3CYiTlU
如果用户试图通过在文件 CVSROOT/passwd 中不存在的用户名进行认证,则默认情况下,CVS 将检查其用户名和密码是否在 /etc/passwd 中存在。如果发现匹配,则认证成功。你可能希望禁止这种特性,以避免用户密码通过网络传递,从而提高安全性。这就需要修改另一个重要的 CVS 配置文件 CVSROOT/config 中的 SystemAuth 选项了。
我们已经讲过,修改管理目录中的配置文件需要通过 CVS 进行(如果你不明白为什么 CVSROOT/passwd 没有遵守这一规则。别急,很快我们将说明这一点),也就是将 CVSROOT/ 检出到工作目录,进行所需的更新后,提交回资源库。一旦提交成功,CVS 将重建对应的管理文件。下面的例子演示了这一过程:
$ cvs -d /cvshome/javaplus checkout CVSROOT
cvs checkout: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
$ cd CVSROOT
$ vi config
进行所需的修改
$ cvs diff config
Index: config
===================================================================
RCS file: /cvshome/javaplus/CVSROOT/config,v
retrieving revision 1.1
diff -r1.1 config
2c2
SystemAuth=no
$ cvs ci -m "关闭 SystemAuth 选项" config
Checking in config;
/cvshome/javaplus/CVSROOT/config,v  
在上面的例子中,我们在本地的工作目录检出了 CVS 的管理目录;修改 CVSROOT/config 文件,将 SystemAuth 选项关闭;之后重新提交回资源库。最后的提交命令的输出说明 CVS 在接受提交结果后,不但更新了历史文件,同时重建了对应的管理文件。
对比我们之前处理 CVSROOT/passwd 文件的方式,会发现存在两种维护管理和配置文件的途径,即在资源库本地维护和通过 CVS 维护。绝大部分的管理和配置文件都需要通过 CVS 进行维护,这是因为资源库管理目录中,不仅有这些文件的正本拷贝,还有对应的保存有其全部修订信息的历史文件。直接修改这些文件,将导致二者之间不一致。但是,类似 CVSROOT/passwd 这样的文件,由于包含安全信息,我们通常不希望它可以被通过网络检出到用户的工作目录中。由于该文件没有对应的历史文件,所以,仔细观察前面的例子就会发现,该文件在检出管理目录时,没有像其它内建的文件一样被检出。
提示: 还有两个文件,包括 CVSROOT/history 和 CVSROOT/val-tags 也没有被检出。这是因为这两个文件由 CVS 自己维护而无需用户干预。
如果你出于某种理由,的确希望 CVSROOT/passwd 也可以和其它 CVS 内建的管理和配置文件一样通过 CVS 加以维护,也不是没有办法。文件 CVSROOT/checkoutlist 正是服务于这一目的。参见 [Cederqvist-1.11.20] 中 C.8 The checkoutlist file 一节的详细说明。不过出于安全考虑,我们强烈建议不要这样做。
[color="#000000"]6.3. 只读资源库访问
基于密码认证的服务器访问方式支持仅赋予用户对资源库的只读访问能力。
注意: 其它访问方式没有类似的只读访问支持,因为它们都需要用户登录到资源库所在的主机。而此时,用户当然可以做任何本地文件系统权限允许他做的事情。
除了某些管理文件(比如文件锁和历史文件)之外,只读用户只能实施那些不会改变资源库的 CVS 操作。有两种途径可以用来指定只读用户,既包含法和排除法。包含法是将用户列在一个特殊的管理文件 CVSROOT/readers 中。该文件以行为单位,每行可以列出一名用户。下面是一个 CVSROOT/readers 的例子(不要忘了最后一个用户名后面的换行):
tony
brian
matkin
排除法则是将具有写权限的用户列在另一个管理文件 CVSROOT/writers 中。这个文件的格式和 CVSROOT/readers 一样。这里有一点特别的是,只要该文件存在,则只有在这个文件中列出的用户才有写权限。比如,一个空的 CVSROOT/writers 文件将取消所有用户的写权限。
注意: 实践中,这两个文件经常配合 CVSROOT/passwd 使用。此时必须注意,这两个文件中列出的用户名都是 CVS 用户名,而不是映射后的系统用户名。
我们总结一下规则:如果用户名包含在文件 CVSROOT/readers 的列表中,则用户对资源库将只拥有读权限。如果用户名包含在文件 CVSROOT/writers 的列表中,则用户将拥有写权限,同时所有没有列在文件 CVSROOT/writers 的类别中的其他用户都将只拥有读权限。也就是说,只要文件 CVSROOT/writers 存在,所以没有列在其中的用户都将是只读用户。如果两个中文件都包含用户的用户名,则采用更谨慎的方式处理这种冲突,即仅赋予用户读权限。
不难理解,同样出于安全考虑,CVSROOT/readers 和 CVSROOT/writers 和 CVSROOT/passwd 一样,都在资源库本地维护。
[color="#000000"]6.4. 匿名访问
基于密码认证的服务器访问方式最常见的用途就是为用户提供匿名的只读访问支持。本节将说明如何利用上面讲到的这些管理文件配置匿名访问支持,同时读者也将可以把在本节中了解到的信息实践一遍。
首先创建用于一个用于匿名访问的系统用户。下面是一个典型的例子:
anoncvs:x:2402:10:Anonymous CVS Account:/cvshome:/bin/false
在这个例子中,anoncvs 将是用户用来访问资源库的用户名。指定的外壳程序 /bin/false 则禁止了该用户登录主机的能力。创建该用户后,我们需要在管理目录中创建相应的 CVSROOT/passwd 文件。在此之前,我们将使用之前给出的加密工具生成该用户的密码。假设目标设置为和用户名相同,参考下面的示例:
# cryptout.pl anoncvs
XVVBebSsg/J8.
即使你设置的密码和我们的例子相同,上面的输出也会和我们不一样。不用担心什么地方出了问题,这正是这种加密方法的好处。利用这个密码,我们创建 CVSROOT/passwd 如下:
anoncvs:XVVBebSsg/J8.:anoncvs
前面我们已经讲过,即便是用户只是想检出资源库的内容而无意更新资源库,由于锁定机制的原因,用户也必须具有对资源库的写权限。而我们的访问控制策略是基于系统组的,所以必须将系统用户 anoncvs 分配到对应的组中。参见下面的示例:
# grep cvs /etc/group
cvsjppm::2410:james,stephen,anoncvs
cvsjpadm::2411:james,stephen,anoncvs
cvsjpbp::2420:james,stephen,anoncvs
cvsjpeaf::2421:james,stephen,anoncvs
我们采用包含法设置用户的只读访问。为此,需要创建 CVSROOT/readers 文件,并将该用户添加到文件中。最后,因为 CVSROOT/passwd 和 CVSROOT/readers 文件比较敏感,所以我们需要加强对这两个文件的访问控制。参考下面的示例:
# ls -l passwd readers
-r--r-----   1 cvsowner cvsjpadm      22 Jun 11 17:11 passwd
-r--r-----   1 cvsowner cvsjpadm       8 Jun 11 17:38 readers
注意: 由于我们的访问控制策略是基于组的,所以上述几个管理文件必须允许组可读。否则 CVS 在检查用户是否具有相应权限时,由于无法读取这些管理文件而导致操作失败。
现在,我们已经为只读用户配置好了匿名访问支持。将准备好的用户名和密码公布给所有用户,他们就可以访问资源库了。下面的例子演示了匿名用户从远程访问资源库的一个场景:
$ cvs -d :pserver:anoncvs@192.168.0.80:/cvshome/javaplus login
Logging in to :pserver:anoncvs@192.168.0.80:2401/cvshome/javaplus
CVS password:
$ cvs -d :pserver:anoncvs@192.168.0.80:/cvshome/javaplus co CVSROOT
cvs checkout: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
$ cd CVSROOT
$ touch README
$ cvs add README
cvs [server aborted]: "add" requires write access to the repository
$
可以看到,用户可以登录资源库,检出所需的内容,但是试图对资源库更新时却失败了。
匿名访问支持为只读用户提供了方便的检出项目文件的方式。后面我们还将介绍服务于公众目的,基于 Web 的访问方式。这种方式对于那些缺少 CVS 客户端工具,或者只是想浏览资源库内容,偶尔下载几个文件的用户十分有用。
               
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/39518/showart_415308.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP