RPC学习

说到RPC,不得不说下IPC,也就是进程间调用,如何在两个进程之间传输数据的问题。

两个进程可以是独立进程各自互不影响各自有自己的内存空间。

也可是是父子之类的进程。

IPC有如下方式

1.共享内存

2.信号量

3.消息队列

4.pipe-(又分匿名,有名)

pipe在windows中被看作文件对象,访问方式和文件一样。其安全性在于创建的时候指定安全的ACL

 远程访问pipe的时候由于pipe被当作对象,可以经由SMB协议访问该文件。

SMB访问的时候可以提供用户认证,pipe本身没有用户鉴别功能,借助于SMB达到认证之后靠ACL来授权

那么RPC又是个什么东西。

RPC服务器需要注册接口,定义底层是什么传输协议,客户端是如何区分不同RPC服务器和某个节点上有哪些RPC服务呢,是如何调用的呢。

答案是类似域名工作一样。

RPC server注册一个UUID跑到endpoint maper上,client查询endpoint maper查到特定UUID和其服务,安装规定格式传输参数,等待答复并解包。服务器端获取参数,并回复结果。

底层协议可以是如下:

  • ncacn_ip_tcp needs a TCP port number, e.g. 9999
  • ncacn_np needs a Named Pipe name, e .g. “\pipe\FRPC-NP”
  • ncalrpc needs an ALPC port name, e.g. “\RPC Control\FRPC-LRPC”

RPC也和pipe一样达到进程间通信的目的。但是又不同,RPC会指定数据的格式和返回方式。

而pipe可以理解为文件,可以读写任意格式的数据。

所以RPC可以建立在name pipe之上。将name pipe作为一个数据媒介来使用。

如下图:RPC当然也可以之间基于HTTP,将数据依靠HTTP传输。或者直接基于更底层的TCP/IP也是可以的。

基于named pipe的RPC调用如下:

那么这个binding是什么东西呢

当客户端连接到服务器的时候,如果啥也不指定,那么就是匿名访问或者未授权的访问。

服务器端无法知道是谁在访问。

可以有以下方式实现授权访问:

1.服务器端注册RPC interface的时候设置一个标记说明访问限制,例如可以设置标记

RPC_IF_ALLOW_LOCAL_ONLY

只允许本地访问。

2.服务器端注册RPC interface的时候设置一个回调函数,例如可以写一个回调函数用于基于IP来授权访问。

3.同1一样,不过标记设置为RPC_IF_ALLOW_SECURE_ONL.

同时服务器端和客户端都需要设置认证信息

服务器端:

RPC_STATUS rpcStatus = RpcServerRegisterAuthInfo(
    pszSpn,             // Server principal name
    RPC_C_AUTHN_WINNT,	// using NTLM as authentication service provider
    NULL,               // Use default key function, which  is ignored for NTLM SSP
    NULL                // No arg for key function
);
客户端:
RPC_STATUS status = RpcBindingSetAuthInfoEx(
    hExplicitBinding,		// the client's binding handle
    pszHostSPN,			// the server's service principale name (SPN)
    RPC_C_AUTHN_LEVEL_PKT,	// authentication level PKT
    RPC_C_AUTHN_WINNT,		// using NTLM as authentication service provider
    NULL,			// use current thread credentials
    RPC_C_AUTHZ_NAME,		// authorization based on the provided SPN
    &secQos			// Quality of Service structure
);
client端的secQos可以指定用户扮演的程度

对于安全问题。RPC是什么机制呢?

原文地址:https://www.cnblogs.com/jjkv3/p/15691380.html