summaryrefslogtreecommitdiffhomepage
path: root/ipc/winpipe/pipe.go
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/winpipe/pipe.go')
-rw-r--r--ipc/winpipe/pipe.go22
1 files changed, 19 insertions, 3 deletions
diff --git a/ipc/winpipe/pipe.go b/ipc/winpipe/pipe.go
index 1e99a93..39ccfa4 100644
--- a/ipc/winpipe/pipe.go
+++ b/ipc/winpipe/pipe.go
@@ -211,7 +211,7 @@ func tryDialPipe(ctx context.Context, path *string) (syscall.Handle, error) {
// DialPipe connects to a named pipe by path, timing out if the connection
// takes longer than the specified duration. If timeout is nil, then we use
// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
-func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
+func DialPipe(path string, timeout *time.Duration, expectedOwner *syscall.SID) (net.Conn, error) {
var absTimeout time.Time
if timeout != nil {
absTimeout = time.Now().Add(*timeout)
@@ -219,7 +219,7 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
absTimeout = time.Now().Add(time.Second * 2)
}
ctx, _ := context.WithDeadline(context.Background(), absTimeout)
- conn, err := DialPipeContext(ctx, path)
+ conn, err := DialPipeContext(ctx, path, expectedOwner)
if err == context.DeadlineExceeded {
return nil, ErrTimeout
}
@@ -228,7 +228,7 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
// cancellation or timeout.
-func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
+func DialPipeContext(ctx context.Context, path string, expectedOwner *syscall.SID) (net.Conn, error) {
var err error
var h syscall.Handle
h, err = tryDialPipe(ctx, &path)
@@ -236,9 +236,25 @@ func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
return nil, err
}
+ if expectedOwner != nil {
+ var realOwner *syscall.SID
+ var realSd uintptr
+ err = getSecurityInfo(h, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &realOwner, nil, nil, nil, &realSd)
+ if err != nil {
+ syscall.Close(h)
+ return nil, err
+ }
+ defer localFree(realSd)
+ if !equalSid(realOwner, expectedOwner) {
+ syscall.Close(h)
+ return nil, syscall.ERROR_ACCESS_DENIED
+ }
+ }
+
var flags uint32
err = getNamedPipeInfo(h, &flags, nil, nil, nil)
if err != nil {
+ syscall.Close(h)
return nil, err
}