📄 rfc1057.txt
字号:
AUTH_ERROR = 1 /* Romote不能鉴定调用者 */
};
为什么鉴定失败:
enum auth_stat {
AUTH_BADCRED = 1, /* 坏信任书 (坏的签名) */
AUTH_REJECTEDCRED = 2, /* 客户必须重新调用 */
AUTH_BADVERF = 3, /* 错误校验(签名破坏) */
AUTH_REJECTEDVERF = 4, /* 验证口令期满或破坏 */
AUTH_TOOWEAK = 5 /* 安全原因拒绝 */
};
所有RPC信息以事物标志-XID开始,接着是两个区别域.联合的判别式是msg_type类型,
在信息的两种类型中进行交换.应答信息的xid总是和初始化调用信息相符.NB:xid域只是用
作客户匹配调用信息的应答或为服务器检测重传;服务器方不能把这个ID看作任何类型的系
列号.
struct rpc_msg {
unsigned int xid;
union switch (msg_type mtype) {
case CALL:
call_body cbody;
case REPLY:
reply_body rbody;
} body;
};
RPC调用内容:
在第二版的RPC协议说明中,rpcvers必须等于2.prog,vers和proc域指定了远程程序,
版本号,和远程程序调用的过程.这些域后是两个鉴定参数:cred(鉴定信任书)和verf(鉴定
校验),然后是远程过程参数,在特定的程序协议中规定.
struct call_body {
unsigned int rpcvers; /* 必须等于2 (2) */
unsigned int prog;
unsigned int vers;
unsigned int proc;
opaque_auth cred;
opaque_auth verf;
/* 过程指定参数从这开始 */
};
RPC调用应答内容:
union reply_body switch (reply_stat stat) {
case MSG_ACCEPTED:
accepted_reply areply;
case MSG_DENIED:
rejected_reply rreply;
} reply;
服务器接受的RPC调用应答:
即使调用被接受,也有可能存在错误.第一个域是服务器产生的用来使它对客户端
有效的鉴定校验域.紧接着是成员是枚举类型accept_stat的联合.该联合的 SUCCESS项是协
议规定的.PROG_UNAVAIL, PROC_UNAVAIL和GARBAGE_ARGS 为空.PROG_MISMATCH项指定服务
器支持的远程过程调用最低和最高版本号.
struct accepted_reply {
opaque_auth verf;
union switch (accept_stat stat) {
case SUCCESS:
opaque results[0];
/*
* 指定过程结果从这开始
*/
case PROG_MISMATCH:
struct {
unsigned int low;
unsigned int high;
} mismatch_info;
default:
/*
* Void. Cases include PROG_UNAVAIL, PROC_UNAVAIL,
* and GARBAGE_ARGS.
*/
void;
} reply_data;
};
被服务器端拒绝的RPC调用应答:
调用被拒绝的原因有两个:或是服务器没有运行RPC协议(RPC_MISMATCH)兼容版本,
或是服务器拒绝调用(AUTH_ERROR)鉴定.当RPC版本不符时,服务器返回RPC支持的最低和最
高版本号.当拒绝鉴定时,返回失败状态.
union rejected_reply switch (reject_stat stat) {
case RPC_MISMATCH:
struct {
unsigned int low;
unsigned int high;
} mismatch_info;
case AUTH_ERROR:
auth_stat stat;
};
9. 鉴定协议
如前面所述,鉴定参数是不透明的,但是对其它RPC协议开放.这个部分定义在 Sun运行
程序的一些内容.其它地方免费开发新的鉴定类型,内容号的委派和程序号的委派规则相同.
9.1 空鉴定
当客户端不知道自己的ID或服务器不关心客户端是谁是,必须进行调用.在这种情况下,
RPC信息的信任,校验和应答校验值(opaque_auth联合的判别式)似乎"AUTH_NULL".
opaque_auth
实体字节数没有定义.建议把它的长度设置为0.
9.2 Unix鉴定
当客户在UNIX系统中识别时,客户想在自身识别.RPC调用信息信任判别式值是
"AUTH_UNIX".信任不透明体内容为下:
struct auth_unix {
unsigned int stamp;
string machinename<255>;
unsigned int uid;
unsigned int gid;
unsigned int gids<16>;
};
"stamp"域是调用机器产生的任意ID."machinename"是调用机器名(象
"krypton")."uid"是调用者有效的用户ID."gid"是调用有效的组ID."gids"是调用者所在组
的记数数组.检验和信任应该为"AUHT_NULL"(上面定义).注意这些信任域在机器名,uid,gid
等特定域里是唯一的.域内名字的讨论不在这个文档范围.
从服务器收到的回答校验判别式的值应该是"AUTH_NULL"或"AUTH_SHORT"。当值为“AUTH
—NULL"时,回答校验字符串编码成不透明结构。现在这种新的不透明结构取代”AUTH_UNIX"
传送给服务器。服务器保持一个缓冲,对应短期不透明结构(到调用者的初始信任书。调用
者通过新的信任书能够保存网络带宽和服务器cpu周期。
服务器在任何时候都可能刷新短期不透明结构。如果如此发生,远程过程调用将由于认
证错误被拒绝。失败的原因为:"AUTH_REJECTEDCRED"。在此看来,客户想利用初始"AUTH_UNIX"
信任书。
9.3 DES 鉴定
UNIX鉴定主要有下面三个主要问题:
(1) 名字太UNIX导向
(2) 没有通用的地址,UID和GID空间。
(3) 有校验,因此认证书容易被伪造。
DES鉴定将解决这些问题。
9.3.1 命名
第一个问题就是用一个简短的字符串来表示客户端而不用操作系统指定的整数。这个字
符串称为“网络名字“或客户端网络名字。除了指定客户端,服务器端不允许用任何方式翻
译客户端名字内容。这样,netnames在因特网上对任何客户应该是唯一的。
需要操作系统执行DES认证来为用户产生保证调用远程服务器时唯一的netnames.OS已
经知道如何辨别它们系统的用户。扩展这个机制到网络是简单可行的。例如,一个sun unix
用户有一个用户ID为515将被分派网络名为:unix.515@sun.com.这个网络名包含三个部分
来保证其唯一。分析其,在因特网中有且仅有一个名字域为:“sun.com".在该域里头,有且
仅有一个unix用户有ID515。但是,要考虑的是,在该域里有可能使用另外一种操作系统的
用户,如VMS有相同的域名。所以为了保证这两个拥护能够由操作系统区别开来。一个用户
为unix.515@sun.com而另外一个为"vms.515@sun.com".
第一个域实际上是命名方式而不是操作系统名字。但是碰巧的是,命名方式和操作系统
之间存在一一对应关系。如果这个标准为世界所同意,第一个域是名字标准而不是操作系统
名字。
9.3.2 DES 鉴定校验
不祥UNIX鉴定,DES坚定有校验功能,这样服务器能够验证客户的认证书(反之也是)。
校验的内容主要是加密的时间戳。服务器解密该时间戳,如果这个时间值和实际时间靠近,
那么客户肯定已经正确加密。客户能够正确加密的唯一方式就是知道RPC任务的交谈密钥。
如果客户知道交谈密钥,它一定是实际客户。
交谈密钥是客户用DES加密产生的并在第一次RPC调用时传给服务器。交换密钥在第一
次事物中用公共密钥来加密。用DES鉴定的特殊的公共密钥是有192位的Diffie-Hellman
[3]。加密方式的详细内容在下面进行描述:
为了保证所有这些事物有效,客户端和服务器端应该具有相同的时间值,可以通过网络
时间协议。如果网络时间同步不能得到保证,那么客户端可以在开始传送前用简单时间要求
协议来确定服务器的时间。
服务器决定客户端时间戳是否有效的方式是有些复杂。对任何事物除了第一次,服务器
需要检查两件事:
1. 从相同客户端发来的时间戳应该比前一次的大
2.时间戳没有期满。
如果服务器的时间比客户端时间戳加上客户的窗口还晚,那么时间戳失效。窗口就是第一次
任务中客户穿给服务器的数量。可以认为是信任书的生存时间。
除了首次外,这里解释每样事情。在首次任务中,服务器只有检查没有过期的时间戳。
如果所有这些都可以成功,那么对客户端发送任意数据代替时间戳更有可能成功。作为附加
检查,客户端在第一次传送过程中发送加密部分,它必须等于窗口大小减一,否则服务器将
拒绝该信任书。
客户也必须检查从服务器端返回的校验来保证其合法性。服务器返回它从客户端收到的
时间戳减去一秒。如果客户端收到和这不同的数据,它将拒绝之。
9.3.3 别名和时钟同步
第一次传送之后,服务器DES认证子系统返回给客户端一个整数别名,这个整数别名是
在后来事物中代替网络名,加密DES密钥和窗口用的。别名是想服务器表中的一个索引,该
索引查找服务器表中所对应的网络名,解密DES密钥和窗口。
虽然开始时时钟是同步的,但是随后客户端和服务器端可能又失去同步。当不同步发生,
客户端RPC子系统必须获得“RPC_AUTHERROR"来重新获得同步。
即使客户保持和服务器同步,它也要获得"RPC_AUTHERROR"。其原因是服务器的别名表大小有
限,无论随时需要它都刷新输入。在这种情况下,客户端重新发送初始信任书,然后服务器
重新发配一个别名。如果服务器崩溃,那么全部别名表都刷新,这样所有客户端都得重新发
送它们色初始信任书。
9.3.4 DES信任协议说明书
两种信任书为:一种是客户端用它的全网络名,另外一种是用服务器发布给它的别名(无
符号整数)。在第一次传送中,客户端必须发送它的全名到服务器,然后服务器返回给客户端
别名。客户端将可以用该别名在后续的事物中和服务器传送。没有特别要求要用别名,但是
由于其表现良好而用它。
enum authdes_namekind {
ADN_FULLNAME = 0,
ADN_NICKNAME = 1
};
64位加密数据:
typedef opaque des_block[8];
网络用户名的最大长度:
const MAXNETNAMELEN = 255;
完整的用户名包括客户端网络名,加密的对话密钥和窗口。窗口实际上是信任书的生存
时间。如果该时间表示校验时间戳加上窗口已经过期,那么服务器将作废该请求并不同意之。
为了保证请求不重犯,除了首次传送服务器坚持认为时间戳大雨先前的那个。在首次传送中,
服务器检查窗口校验是否小于窗口。
struct authdes_fullname {
string name<MAXNETNAMELEN>; /* 客户端名 */
des_block key; /* PK 加密谈话密钥 */
opaque window[4]; /* 加密窗口 */
};
信任书或者是全名或者是别名:
union authdes_cred switch (authdes_namekind adc_namekind) {
case ADN_FULLNAME:
authdes_fullname adc_fullname;
case ADN_NICKNAME:
int adc_nickname;
};
时间戳把从1970年1月一日0时起的时间值编码:
struct timestamp {
unsigned int seconds; /* 秒值 */
unsigned int useconds; /* 微妙值 */
};
校验:客户变量
窗口校验只用在首次会话中。和一个信任书相关联,这些项在加密前封装在下面结构中:
struct {
adv_timestamp; -- one DES block
adc_fullname.window; -- one half DES block
adv_winverf; -- one half DES block
}
该结构用CBC模式和0输入向量来加密。所有其它时间戳用ECB模式加密。
struct authdes_verf_clnt {
des_block adv_timestamp; /* 加密时间戳*/
opaque adv_winverf[4]; /* 加密窗口校验 */
};
校验;服务器变量
服务器返回收到客户端的时间戳减去一秒。同时它也告知客户端在后续的事务中用别名
来传送。
struct authdes_verf_svr {
des_block adv_timeverf; /* 加密校验 */
int adv_nickname; /* 客户端的新别名 */
};
9.3.5 Diffie-Hellman 加密
在该主题中,有两个常量"BASE" 和 "MODULUS" [3]。Sun为DES认证协议选择的特别值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -