Skip to content

Commit 986a33c

Browse files
committed
Limit Windows Named Pipe access to logon session
1 parent 1a10bf7 commit 986a33c

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed

src/main/java/org/scalasbt/ipcsocket/Win32NamedPipeServerSocket.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.sun.jna.platform.win32.WinError;
2222
import com.sun.jna.platform.win32.WinNT;
2323
import com.sun.jna.platform.win32.WinNT.HANDLE;
24+
import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES;
2425
import com.sun.jna.ptr.IntByReference;
2526

2627
import java.io.IOException;
@@ -89,6 +90,7 @@ public Win32NamedPipeServerSocket(
8990
this.path = path;
9091
}
9192
String lockPath = this.path + "_lock";
93+
SECURITY_ATTRIBUTES sa = Win32SecurityLibrary.createSecurityWithLogonDacl(WinNT.FILE_GENERIC_READ);
9294
lockHandle = API.CreateNamedPipe(
9395
lockPath,
9496
Win32NamedPipeLibrary.FILE_FLAG_FIRST_PIPE_INSTANCE | Win32NamedPipeLibrary.PIPE_ACCESS_DUPLEX,
@@ -97,7 +99,7 @@ public Win32NamedPipeServerSocket(
9799
BUFFER_SIZE,
98100
BUFFER_SIZE,
99101
0,
100-
null);
102+
sa);
101103
if (lockHandle == Win32NamedPipeLibrary.INVALID_HANDLE_VALUE) {
102104
throw new IOException(String.format("Could not create lock for %s, error %d", lockPath, API.GetLastError()));
103105
} else {
@@ -113,6 +115,7 @@ public void bind(SocketAddress endpoint) throws IOException {
113115
}
114116

115117
public Socket accept() throws IOException {
118+
SECURITY_ATTRIBUTES sa = Win32SecurityLibrary.createSecurityWithLogonDacl(WinNT.FILE_ALL_ACCESS);
116119
HANDLE handle = API.CreateNamedPipe(
117120
path,
118121
Win32NamedPipeLibrary.PIPE_ACCESS_DUPLEX | WinNT.FILE_FLAG_OVERLAPPED,
@@ -121,7 +124,7 @@ public Socket accept() throws IOException {
121124
BUFFER_SIZE,
122125
BUFFER_SIZE,
123126
0,
124-
null);
127+
sa);
125128
if (handle == Win32NamedPipeLibrary.INVALID_HANDLE_VALUE) {
126129
throw new IOException(String.format("Could not create named pipe, error %d", API.GetLastError()));
127130
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package org.scalasbt.ipcsocket;
2+
3+
import com.sun.jna.platform.win32.WinNT;
4+
import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR;
5+
import com.sun.jna.platform.win32.WinNT.PSID;
6+
import com.sun.jna.platform.win32.WinNT.PSIDByReference;
7+
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
8+
import com.sun.jna.platform.win32.WinNT.HANDLE;
9+
import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES;
10+
import com.sun.jna.platform.win32.WinNT.ACL;
11+
import com.sun.jna.platform.win32.WinNT.ACCESS_ALLOWED_ACE;
12+
import com.sun.jna.platform.win32.WinDef.DWORD;
13+
import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES;
14+
import com.sun.jna.platform.win32.Advapi32;
15+
import com.sun.jna.platform.win32.Advapi32Util;
16+
import com.sun.jna.platform.win32.Kernel32;
17+
import com.sun.jna.platform.win32.Kernel32Util;
18+
import com.sun.jna.platform.win32.W32Errors;
19+
import com.sun.jna.ptr.IntByReference;
20+
import com.sun.jna.Native;
21+
22+
public class Win32SecurityLibrary {
23+
private static final long SE_GROUP_LOGON_ID = 0xC0000000L;
24+
25+
public static SECURITY_ATTRIBUTES createSecurityWithLogonDacl(int accessMask) {
26+
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
27+
Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION);
28+
Native.getLastError();
29+
30+
ACL pAcl;
31+
int cbAcl = 0;
32+
PSIDByReference psid = new PSIDByReference();
33+
getLogonSID(psid);
34+
int sidLength = Advapi32.INSTANCE.GetLengthSid(psid.getValue());
35+
cbAcl = Native.getNativeSize(ACL.class, null);
36+
cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null);
37+
cbAcl += (sidLength - DWORD.SIZE);
38+
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
39+
pAcl = new ACL(cbAcl);
40+
Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION);
41+
Native.getLastError();
42+
Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, accessMask, psid.getValue());
43+
Native.getLastError();
44+
Advapi32.INSTANCE.SetSecurityDescriptorDacl(sd, true, pAcl, false);
45+
Native.getLastError();
46+
47+
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
48+
sa.dwLength = new DWORD(sd.size());
49+
sa.lpSecurityDescriptor = sd.getPointer();
50+
sa.bInheritHandle = false;
51+
52+
return sa;
53+
}
54+
55+
public static void getOwnerSID(PSIDByReference psid) {
56+
HANDLEByReference phToken = new HANDLEByReference();
57+
try {
58+
Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_QUERY, phToken);
59+
Native.getLastError();
60+
IntByReference tokenInformationLength = new IntByReference();
61+
Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
62+
WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, null, 0, tokenInformationLength);
63+
WinNT.TOKEN_OWNER owner = new WinNT.TOKEN_OWNER(tokenInformationLength.getValue());
64+
Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
65+
WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, owner,
66+
tokenInformationLength.getValue(), tokenInformationLength);
67+
Native.getLastError();
68+
psid.setValue(owner.Owner);
69+
} finally {
70+
Kernel32Util.closeHandleRef(phToken);
71+
}
72+
}
73+
74+
public static void getLogonSID(PSIDByReference psid) {
75+
HANDLEByReference phToken = new HANDLEByReference();
76+
try {
77+
Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_QUERY, phToken);
78+
Native.getLastError();
79+
IntByReference tokenInformationLength = new IntByReference();
80+
Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
81+
WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, null, 0, tokenInformationLength);
82+
WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(tokenInformationLength.getValue());
83+
Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
84+
WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, groups,
85+
tokenInformationLength.getValue(), tokenInformationLength);
86+
Native.getLastError();
87+
88+
for (SID_AND_ATTRIBUTES sidAndAttribute: groups.getGroups()) {
89+
if ((sidAndAttribute.Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) {
90+
psid.setValue(sidAndAttribute.Sid);
91+
return;
92+
}
93+
}
94+
throw new RuntimeException("LogonSID was not found.");
95+
} finally {
96+
Kernel32Util.closeHandleRef(phToken);
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)