摘要
- RFC 1509 把
gss_cred_id_t定义为调用者看不见内部结构的原子引用,实际凭据保留在 GSS-API 或底层机制中;句柄数值本身不含安全相关信息。 - 规范明确允许相同数值在不同调用者那里指向不同凭据。句柄的意义必须连同进程或 UID 范围、实现状态、机制、主体、用途和有效期一起重建。
- 真正跨网络传递的是机制生成的认证令牌,不是本地句柄。认证完成后,应用授权、消息交付和业务结果仍需各自回执。
被复制的只是数值
设想进程甲持有一个 gss_cred_id_t,其机器表示看起来像整数 7。进程乙也拿到整数 7。两者调用同一个 GSS-API 函数时,是否必然使用同一份凭据?
RFC 1509 的答案是否定的。这个 1993 年 9 月发布的 C 语言绑定允许实现把句柄做成指针或算术值,却明确说句柄是相对于调用者解释的。完全相同的原子值交给不同调用者,可以指向不同凭据。
因此,复制数值没有完成对象迁移。另一个进程可能没有对应表项,可能在自己的表项中找到另一主体的凭据,也可能依据不同机制解释引用。只有当本地实现认可调用者范围并能从自己的状态中解析该值时,句柄才成为可用引用。
这种设计不是接口缺陷。它是抽象的边界:应用获得一种调用接口,而不是获得底层凭据元素。
凭据留在服务内部
RFC 1509 信息页 记录作者 John Wray、最初的 Proposed Standard 状态以及后来被 RFC 2744 取代的关系。绑定描述四个阶段:取得凭据;与对端建立共同安全上下文;在消息上使用完整性或保密服务;通信会话结束时删除上下文。
这里至少有七种不同对象:调用进程、本地凭据句柄、句柄背后的凭据材料、凭据可声明的主体、与对端共同建立的上下文、承载协议交换的连接,以及应用最终允许或拒绝的操作。
通信会话还可以跨越多个连接,同一关联也能同时存在多个安全上下文。连接不是上下文,句柄不是上下文内部状态,认证主体也不是应用权限。
如果日志只记录“句柄 7”,它没有保存哪一个调用者、哪一代本地状态、哪一种机制或哪一个主体。它记住了语法,却丢失了权威来源。
句柄范围是一条隐含关系
RFC 1509 要求实现说明句柄和凭据的作用范围。句柄可能只对取得它的进程有效,也可能传给子进程,或允许共享某种本地身份(例如同一 UID)的进程使用。最后一个可达句柄消失后,凭据才可能被删除。
为什么标准没有选择唯一答案?RFC 1508 把这项责任留给系统机制和操作系统:本地安全层必须限制谁能够取得并使用某个主体的凭据。RFC 1508 信息页 则保留了通用接口、语言绑定与后续版本之间的谱系。
使用凭据就是能够声明相应主体的身份。能否把这种能力交给另一个进程,不只是数据格式问题,而是本地授权问题。通用 API 可以统一函数边界,却不能替操作系统决定进程间的信任。
RFC 1511 从 Common Authentication Technology 工作组的历史目标解释这层分工:把安全实现细节与调用协议集成安全数据的工作分开。RFC 1511 信息页 将 RFC 1508、RFC 1509、Kerberos V5 和 DASS 放在同一组工作中。可移植性来自机制隐藏,不来自句柄全局化。
“没有凭据”反而会触发选择
GSS_C_NO_CREDENTIAL 的名字很容易诱导错误判断。应用没有传入显式凭据句柄,并不一定意味着匿名、空身份或没有权威。它是在请求本地实现选择默认凭据。
RFC 1509 把默认凭据如何建立、作用于哪些调用者留给实现。RFC 2078 在吸收实现经验后的 Version 2 中进一步说明默认主体解析及其授权检查;解析可能成功,也可能因为调用者无权取得凭据而失败。RFC 2078 信息页 保留这次版本替换关系。
所以零值或特殊常量不是“什么都没发生”。它启动了一个环境选择。审计必须记录调用者 PID、UID、服务账号或容器边界,本地实现与重启代次,默认规则,实际选中的机制、主体、用途和寿命。
默认值带来便利,也让权威更容易藏在调用代码之外。代码看似没有选择身份,本地代理却已经替它选择。
本地上下文句柄没有跨过网络
gss_ctx_id_t 同样可能相对于调用者解释。相同原子值在不同进程中可以代表不同安全上下文。上下文包含双方共同状态与密码学材料;RFC 1509 没有提供“再取一个现有上下文句柄”的普通操作。
跨越网络的是另一种对象:认证令牌。机制在一端生成受密码学保护、对调用应用不透明的位串,由应用自己的协议负责把它带给对端机制。令牌与本地句柄可能都“看不懂”,却有不同的移动规则和风险。
后续 C 绑定没有靠复制句柄解决跨进程迁移。RFC 2744 新增显式 export/import 路径:导出会让源进程中的上下文失活,生成供另一进程导入的进程间令牌,并要求同一上下文只能有一个活动实例。令牌可能包含密钥等敏感材料,必须受到保护,只交给可信进程。RFC 2744 信息页 记录它取代 RFC 1509。
这条演进本身就是证据。真正迁移上下文需要受控状态转换、敏感载荷与唯一活动实例约束;复制整数不具备这些语义。
可打印名字只是显示投影
RFC 1509 还把可打印名字和内部名字分开。字符串形式可能随配置或用户偏好变化;导入时要配合对象标识符说明命名空间。名字是否相等,应由 gss_compare_names 判断,而不是直接比较字符串。
RFC 2743 及其信息页 保留通用 Version 2 Update 1 的概念边界。RFC 2744 更明确地说,内部名字再次显示时,不必复现最初字符串,甚至不保证返回同一个命名空间标识符。
这使一条常见审计记录变得可疑:屏幕上的名字不是凭据本体,也不自动是应用账号。要把它用于归责,必须保存名字类型、机制、规范化或导入过程以及实际授权映射。
通道绑定只完成一个特定连接
RFC 1509 的 channel bindings 把发起方地址类型与地址、接受方地址类型与地址、应用数据拼接起来,由机制在建立上下文时签入。如果两端材料不一致,上下文可能无法建立。规范也提醒某些机制可能把绑定数据放进令牌,因此不应把机密内容直接用作绑定材料。
绑定成功只能证明这次机制交换接受了双方提交的那组材料。它不能证明地址的法律所有者、应用操作的授权、消息最终送达或业务效果。调用者仍须检查请求和返回的安全属性、主状态与机制专用状态,再由应用做独立授权。
RFC 2744 的安全考虑也没有把 GSS-API 描述成保证器:安全属性依赖底层机制和调用者是否正确检查返回值。RFC 1509 的 Datatracker 页面 只能证明文档状态,不能证明任何具名实现、部署、漏洞或当前产品行为。
薄接口为何反而要求厚回执
Heng Lu 的 Running-Code Primacy 强调,共同规范的价值必须在真实执行与结果中验证。Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption 要求把共同层保持在必要范围,让未来选择留在本地。On Reality Layers, Symbolic Power, and Why Clarity Feels So Hostile 则要求不要让符号吞掉背后的对象、决定与效果。
RFC 1509 的 C 绑定正是一层薄接口。句柄保持不透明,使应用无需理解每个机制;本地系统继续控制凭据;对端令牌承担网络交换;应用保留业务授权。共同接口没有把这些角色合成一个“安全令牌”。
本组来源只证明规范文字与演进谱系。它们不证明某个实现采用哪种句柄范围,也不证明真实系统的默认身份、漏洞、互操作或部署结果。
历史教训因此非常具体:句柄可以是一次 API 调用的正确输入,却不能脱离调用者和解析状态,独自成为身份、权威或结果证据。
来源
- RFC 1509 信息页
- RFC 1509:GSS-API C 绑定
- RFC 1509 Datatracker 页面
- RFC 1508 信息页
- RFC 1508:Generic Security Service Application Program Interface
- RFC 1511 信息页
- RFC 1511:Common Authentication Technology Overview
- RFC 2078 信息页
- RFC 2078:GSS-API Version 2
- RFC 2743 信息页
- RFC 2743:GSS-API Version 2, Update 1
- RFC 2744 信息页
- RFC 2744:GSS-API Version 2 C 绑定
- Heng Lu:Running-Code Primacy
- Heng Lu:Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
- Heng Lu:On Reality Layers, Symbolic Power, and Why Clarity Feels So Hostile
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
