分类: LINUX
2010-12-08 10:22:28
Rlogin的第一次发布是在4.2BSD中,当时它仅能实现Unix主机之间的远程登录。这就使得Rlogin比Telnet简单。由于客户进程和服务器进程的操作系统预先都知道对方的操作系统类型,所以就不需要选项协商机制。在过去的几年中,Rlogin也派生出几种非Unix环境的版本。
RFC1282[Kantor1991]
具体说明了Rlogin协议。类似于选路信息协议(RIP)的RFC,它是Rlogin用了许多年后才发布的。[Stevens1990]的第15章介绍
了远程登录的客户进程及服务器进程端的编程,并且给出了Rlogin的客户进程及服务器进程的完整源代码。[Comer和Stevens1993]的第
25章和第26章给出了Telnet的客户进程的实现细节和源代码。
应用进程的启动
Rlogin的客户进程和服务器进程使用一个TCP连接。当普通的TCP连接建立完毕之后,客户进程和服务器进程之间将发生下面所述的动作。
1)
客户进程给服务器进程发送4个字符串:(a)一个字节的0;(b)用户登录进客户进程主机的登录名,以一个字节的0结束;(c)登录服务器进程端主机的登
录名,以一个字节的0结束;(d)用户终端类型名,紧跟一个正斜杠“/”,然后是终端速率,以一个字节的0结束。在这里需要两个登录名字,这是因为用户登
录客户和服务器的名称有可能不一样。由于大多满屏应用程序需要知道终端类型,所以终端类型也必须发送到服务器进程。发送终端速率的原因是因为有些应用随着
速率的改变,它的操作也有所变化。例如vi编辑器,当速率比较小的时候,它的工作窗口也变小。所以它不能永远保持同样大小的窗口。
2)服务器进程返回一个字节的0。
3)
服务器进程可以选择是否要求用户输入口令。这个步骤的数据交互没有什么非凡的协议,而被当作是普通的数据进行传输。服务器进程给客户进程发送一个字符串
(显示在客户进程的屏幕上),通常是passWord:。假如在一定的限定时间内(通常是60秒)客户进程没有输入口令,服务器进程将关闭该连接。通常可
以在服务器进程的主目录(homeDirectory)下生成一个文件(通常叫.rhosts),该文件的某些行记录了一个主机名和用户名。假如从该文件
中已经记录的主机上用已经记录的用户名进行登录,服务器进程将不提示我们输入口令。但是很多关于安全性的文献,如[Curry1992],强烈建议不要采
用这种方法,因为这存在安全漏洞。假如提示输入口令,那么我们输入的口令将以明文的形式发送到服务器进程。我们所键入的每个字符都是以明文的格式传输的。
所以某人只要能够截取网络上的原始传输的分组,他就可以截获用户口令。针对这个问题,新版本的Rlogin客户程序,例如
4.4BSD版本的客户程序,第一次采用了Kerberos安全模型。Kerberos安全模型可以避免用户口令以明文的形式在网络上传输。当然,这要求服务器进程也支持Kerberos
([Curry1992]具体描述了Kerberos安全模型)。4)服务器进程通常要给客户进程发送请求,询问终端的窗口大小(将在后面解释)。客户进程每次给服务器进程发送一个字节的内容,并且接收服务器进程的所有返回信息。
同样我们也采用了Nagle算法(在19.4节中曾经介绍),该算法可以保证在速率较低的网络上,若干输入字节以单个TCP报文段传输。操作其实很简单:用户键入的所有东西被发送到服务器,服务器发送给客户的任何信息返回到用户的屏幕上。
另外,服务器和客户之间还可以互相发送命令。在介绍这些命令之前,先介绍需要用到这些命令。
流量控制
默认情况下,流量控制是由Rlogin的客户进程完成的。客户进程能够识别用户键入的STOP和START的ASCII字符(ControlS和ControlQ),并且终止或启动终端的输出。
假
如不是这样,每次我们为终止终端输出而键入的Control_S字符将沿网络传输到服务器进程,这时服务器进程将停止往网络上写数据。但是在写操作终止之
前,服务器进程可能已经往网络上写了一窗口的输出数据。也就是说,在输出停止之前,成千上万的数据字节还将在屏幕上显示。图26-3显示了这个情况。
客户的中断键
当我们为中断服务器正在运行的进程而键入一个中断字符时(通常是DELETE或
Control_C),会发生和流量控制相同的问题。这个情况和图26-3所示的类似,在一条TCP连接的管道上,从服务器进程向客户进程正在发送大量的
数据,而客户进程同时在向服务器进程传输中断字符。而我们的本意是要中断字符尽快终止某个进程,使屏幕上不再有任何响应输出。
在流量控制和中断键这两种情况中,流量控制机制很少终止客户进程到服务器进程的数据流。这个方向仅仅包含我们键入的字符。所以对于从客户输出到服务器的非凡输入字符(Control_S和中断字符)不需要采用TCP的紧急方式(urgentmode)。
窗口大小的改变
假如是窗口风格的显示方式,当应用程序在运行的时候,我们还可以动态地改变窗口的大小。一些应用程序(典型的如那些操作整个窗口的应用程序,如全屏编辑器)需要知道窗口大小的变化。目前大多数Unix系统提供这种功能,可以告诉应用程序关于窗口大小的变化。
对于远程登录这种情况,窗口大小的变化发生在客户端,而运行在服务器端的应用程序需要知道窗口大小变化。所以Rlogin的客户需要采用某些方法来通知服务器窗口大小变化的情况以及新窗口的大小。
服务器到客户的命令
现
在我们介绍通过TCP连接,Rlogin服务器进程可以发送给客户进程的4条命令。问题是只有一条TCP连接可供使用,所以服务器进程必须给这些命令字节
做标记,使得客户进程可以从数据流中识别出这些是命令,而不是显示在终端上。所以我们将使用TCP的紧急方式(在20.8节中曾经介绍)。
当
服务器要给客户发送命令时,服务器就进入紧急方式,并且把命令放在紧急数据的最后一个字节中。当客户进程收到这个紧急方式通知时,它从连接上读取数据并且
保存起来,直到读到命令字节(即紧急数据的最后一个字节)。这时候客户进程根据读到的命令,再决定对于所读到并保存起来的数据是显示在终端上还是丢弃它。
采用TCP紧急方式发送这些命令的一个原因是第一个命令(“清仓输出(flushoutput)”)需要立即发送给客户,即使服务器到客户的数据流被窗口
流量控制所终止。这种情况下,即服务器到客户的输出被流量控制所终止的情况是经常发生的,这是因为运行在服务器的进程的输出速率通常大于客户终端的显示速
率。另一方面,客户到服务器的数据流很少被流量控制所终止,因为这个方向的数据流仅仅包含用户所键入的字符。
客户到服务器的命令
对于客户到服务器的命令,只定义了一条命令,那就是:将当前窗口大小发送给服务器。当客户的窗口大小发生变化时,客户并不立即向服务器报告,除非收到了服务器发来的0x80命令(图26-4中有介绍)。
同样,由于只存在一条TCP连接,客户必须对在连接上传输的该命令字节进行标注,使得服务器可以从数据流中识别出命令,而不是把它发送到上层的应用程序中去。处理的方法就是在两个字节的0xff后面紧跟着发送两个非凡的标志字节。
对
于窗口大小命令,两个标志字节是ASCII码的字符‘s’。之后是4个16bit长的数据(按网络字节顺序),分别是:行数(例如,25),每列的字符数
(例如,80),X方向的像素数量,Y方向的像素数量。通常情况下,后两个16bit是0,因为在Rlogin服务器进程调用的应用程序中,通常是以字符
为单位来度量屏幕的,而不是像素点。
上面我们介绍的从客户进程到服务器进程的命令采用带内信令(in-bandsignaling),这
是因为命令字节和其他的普通数据一起传输。选择0xff字节来表示这个带内信令的原因是:一般用户的操作不会产生0xff这个字节。所以说Rlogin是
不完备的,假如我们采用某种方法,使得通过键盘就可以产生两个连续的0xff字节,而且正好在这之前是两个ASCII的‘s’字符,那么下面的8个字节就
会被误认为是窗口大小了。
图26-4中介绍的是从服务器到客户的Rlogin命令,由于大多数的API采用的技术叫做“带外数据
(out-of-banddata)”,所以我们就称它为带外信令(out-of-bandsignaling)。但是回忆一下在20.8节中对TCP紧
急方式的讨论,在那里我们说紧急方式数据不是带外数据,命令字节是按照普通数据流进行传输的,非凡之处是采用了紧急指针。
既然带内信令被
用来传输从客户到服务器的命令,那么服务器进程必须检查从客户进程收到的每个字节,看看是否有两个连续的0xff字节。但是对于采用带外信令的、从服务器
传输到到客户的命令,客户进程不需要检查收到的每个字节,除非服务器进程进入了紧急方式。即使在紧急方式下,客户进程也仅仅需要留意紧急指针所指向的字
节。而且由于从客户进程到服务器的数据流量和相反方向的数据流量之比是1:20,这就暗示带内信令适合于数据量比较小的情况(从客户到服务器),而带外信
令适合于数据量比较大的情况(从服务器到客户)。
客户的转义符
通常情况下,我们向Rlogin客户进程键入的信息将传输到服务器进程。但是有些时候,我们并不需要把键入的信息传输到服务器,而是要和Rlogin客户进程直接通信。方法是在一行的开头键入代字符(tilde)“~”,紧跟着是下列4个字符之一:
1)以一个句号结束客户进程。
2)以文件结束符(通常是Control_D)结束客户进程。
3)以任务控制挂起符(通常是Control_Z)挂起客户进程。
4)
以任务控制延迟挂起符(通常是Control_Y)来挂起仅仅是客户进程的输入。这时,不管客户运行什么程序,键入的任何信息将由该程序进行解释,但是从
服务器发送到客户的信息还是输出到终端上。这非常适合当我们需要在服务器上运行一个长时间程序的场合,我们既想知道该程序的输出结果,同时还想在客户上运
行其他程序。只有当客户进程的Unix系统支持任务控制时,后两个命令才有效。