- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 Windows API CreateNamedPipe
创建一个双工命名管道,以用于我的 shell 扩展和我的主桌面应用程序之间的 IPC。
对于 Vista 及更高版本,您可以传递一个标志来阻止远程连接 (PIPE_REJECT_REMOTE_CLIENTS
)。据我了解,这意味着管道只能在同一台机器上连接。有谁知道如何在早期版本的 Windows 中获得相同的功能?我尝试使用以下代码创建一个 SECURITY_ATTRIBUTES
对象,但我不能完全确定它是否正常工作:
static bool GetLocalMachineOnlySecurityAttributes (SECURITY_ATTRIBUTES& sa)
{
PSID plocalsid = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_LOCAL_SID_AUTHORITY;
if(!::AllocateAndInitializeSid (&SIDAuthWorld, 1, SECURITY_LOCAL_RID, 0, 0, 0, 0, 0, 0, 0, &plocalsid))
return false;
EXPLICIT_ACCESS ea = {0};
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = reinterpret_cast<LPWSTR>(plocalsid);
PACL acl = NULL;
if(!::SetEntriesInAcl (1, &ea, NULL, &acl))
return false;
//PSECURITY_DESCRIPTOR sd = reinterpret_cast<PSECURITY_DESCRIPTOR>(::LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
static SECURITY_DESCRIPTOR sd = {0};
if(!::InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
return false;
if(!::SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE))
return false;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
return true;
}
如果有人可以告诉我我做的事情是否正确,或者我可以在某个地方寻找关于 SECURITY_ATTRIBUTES
的明确解释,我将不胜感激。
最佳答案
您确实可以通过为管道创建适当的自主访问控制列表 (DACL) 来阻止远程连接。
您的代码正在尝试但未能做到这一点,第一个原因在于这一行:
if(!::SetEntriesInAcl (1, &ea, NULL, &acl))
SetEntriesInAcl 返回一个 DWORD 代码,而不是一个 BOOL:成功时返回的代码是 ERROR_SUCCESS
,其值为 0L,因此您的函数总是在此时退出,使 SECURITY_ATTRIBUTES 结构为空。
您的代码还会泄漏内存,因为它无法释放由某些 API 创建的缓冲区,包括 SetEntriesInAcl
。我建议你使用 the example in MSDN作为确保您进行所有必要清理的指南。
更多地转向您的代码策略,您目前正在尝试使用允许本地安全组的所有访问的单个访问控制条目 (ACE) 来解决您的问题。由于 DACL 的工作方式,这不是正确的方法……您应该拒绝远程访问——即将其列入黑名单——而不是尝试将本地访问列入白名单。这至少有两个原因:
因此,您的代码需要修改,以便构建包含以下 ACE 的 DACL:
首先是阻止对管道的远程访问,因为远程访问协议(protocol)创建的所有登录 token ,包括基于 SMB 的远程命名管道协议(protocol),自动包含 NETWORK USERS 组的组成员身份(以及-已知 SID S-1-5-2)。此拒绝 ACE 必须位于 DACL 中的允许 ACE 之前。
您没有说您的应用程序中的哪个是管道服务器,哪个是客户端。也许这并不重要,如果两者都在交互式用户的 session 中运行:在这种情况下,您可以只使用一个允许 ACE,它授予对用户 session 的 SID 的所有访问权限。
如果没有关于您的安全要求的更多详细信息,就很难规定您应该如何设置服务器和客户端 ACE。但是,几乎可以肯定,您会希望限制访问权限 FILE_CREATE_PIPE_INSTANCE,以便只有管道服务器拥有它。
关于c++ - 没有 PIPE_REJECT_REMOTE_CLIENTS 的 CreateNamedPipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11004775/
我正在尝试使用 Windows API CreateNamedPipe 创建一个双工命名管道,以用于我的 shell 扩展和我的主桌面应用程序之间的 IPC。 对于 Vista 及更高版本,您可以传递
我是一名优秀的程序员,十分优秀!