Skip to content

Commit 93e29b5

Browse files
committed
[confignet] Allow setting security descriptors for npipes
1 parent efde8a2 commit 93e29b5

7 files changed

Lines changed: 85 additions & 4 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp)
7+
component: pkg/config/confignet
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add `dialer.security_descriptor` to set an SDDL security descriptor on Windows named pipe (npipe) listeners
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [15211]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: [user, api]

config/confignet/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ leverage network configuration to set connection and transport information.
1616
"npipe" (Windows named pipes, Windows-only).
1717
- `dialer`: Dialer configuration
1818
- `timeout`: Dialer timeout is the maximum amount of time a dial will wait for a connect to complete. The default is no timeout.
19+
- `security_descriptor`: A [Security Descriptor Definition Language (SDDL)](https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language)
20+
string applied when creating a Windows named pipe listener. Ignored for any
21+
transport other than `npipe` and for client-side dials. When empty, Windows
22+
applies its [default named pipe DACL](https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights),
23+
which is roughly equivalent to
24+
`D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;WD)(A;;0x12019b;;;AN)` — full
25+
control for `LocalSystem` (`SY`) and `Administrators` (`BA`), and read plus
26+
limited write for `Everyone` (`WD`) and `Anonymous Logon` (`AN`).
1927

2028
Note that for TCP receivers only the `endpoint` configuration setting is
2129
required.

config/confignet/config.schema.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ $defs:
1616
description: DialerConfig contains options for connecting to an address.
1717
type: object
1818
properties:
19+
security_descriptor:
20+
description: SecurityDescriptor is a Security Descriptor Definition Language (SDDL) string used when creating a Windows named pipe listener. It is ignored for any transport other than "npipe" and for client-side dials. When empty, Windows applies its default named pipe DACL, which is roughly equivalent to "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;WD)(A;;0x12019b;;;AN)" — full control for LocalSystem (SY) and Administrators (BA), and read plus limited write for Everyone (WD) and Anonymous Logon (AN). See https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights and https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language
21+
type: string
1922
timeout:
2023
description: Timeout is the maximum amount of time a dial will wait for a connect to complete. The default is no timeout.
2124
type: string

config/confignet/confignet.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ type DialerConfig struct {
6363
// Timeout is the maximum amount of time a dial will wait for
6464
// a connect to complete. The default is no timeout.
6565
Timeout time.Duration `mapstructure:"timeout,omitempty"`
66+
// SecurityDescriptor is a Security Descriptor Definition Language (SDDL)
67+
// string used when creating a Windows named pipe listener. It is ignored
68+
// for any transport other than "npipe" and for client-side dials. When
69+
// empty, Windows applies its default named pipe DACL, which is roughly
70+
// equivalent to "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;WD)(A;;0x12019b;;;AN)"
71+
// — full control for LocalSystem (SY) and Administrators (BA), and
72+
// read plus limited write for Everyone (WD) and Anonymous Logon (AN).
73+
// See:
74+
// - https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights
75+
// - https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language
76+
SecurityDescriptor string `mapstructure:"security_descriptor,omitempty"`
6677
// prevent unkeyed literal initialization
6778
_ struct{}
6879
}
@@ -111,7 +122,7 @@ func (na *AddrConfig) Dial(ctx context.Context) (net.Conn, error) {
111122
// Listen equivalent with net.ListenConfig's Listen for this address.
112123
func (na *AddrConfig) Listen(ctx context.Context) (net.Listener, error) {
113124
if na.Transport == TransportTypeNpipe {
114-
return listenNpipe(na.Endpoint)
125+
return listenNpipe(na.Endpoint, na.DialerConfig.SecurityDescriptor)
115126
}
116127
lc := net.ListenConfig{}
117128
return lc.Listen(ctx, string(na.Transport), na.Endpoint)

config/confignet/npipe_others.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ func dialNpipe(_ context.Context, _ string, _ time.Duration) (net.Conn, error) {
1818
return nil, errNpipeUnsupported
1919
}
2020

21-
func listenNpipe(_ string) (net.Listener, error) {
21+
func listenNpipe(_, _ string) (net.Listener, error) {
2222
return nil, errNpipeUnsupported
2323
}

config/confignet/npipe_windows.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ func dialNpipe(ctx context.Context, endpoint string, timeout time.Duration) (net
2222
return winio.DialPipeContext(ctx, endpoint)
2323
}
2424

25-
func listenNpipe(endpoint string) (net.Listener, error) {
26-
return winio.ListenPipe(endpoint, nil)
25+
func listenNpipe(endpoint, securityDescriptor string) (net.Listener, error) {
26+
var cfg *winio.PipeConfig
27+
if securityDescriptor != "" {
28+
cfg = &winio.PipeConfig{SecurityDescriptor: securityDescriptor}
29+
}
30+
return winio.ListenPipe(endpoint, cfg)
2731
}

config/confignet/npipe_windows_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,33 @@ func TestNpipeListenAndDial(t *testing.T) {
5252
assert.NoError(t, conn.Close())
5353
<-done
5454
}
55+
56+
func TestNpipeListenSecurityDescriptor(t *testing.T) {
57+
tests := []struct {
58+
name string
59+
securityDescriptor string
60+
wantErr bool
61+
}{
62+
{name: "default", securityDescriptor: "", wantErr: false},
63+
{name: "owner local system, allow everyone read/write", securityDescriptor: "O:SYG:SYD:(A;;GRGW;;;WD)", wantErr: false},
64+
{name: "invalid SDDL", securityDescriptor: "not-a-valid-sddl", wantErr: true},
65+
}
66+
for _, tt := range tests {
67+
t.Run(tt.name, func(t *testing.T) {
68+
nas := &AddrConfig{
69+
Endpoint: `\\.\pipe\otel-test-confignet-sd`,
70+
Transport: TransportTypeNpipe,
71+
DialerConfig: DialerConfig{
72+
SecurityDescriptor: tt.securityDescriptor,
73+
},
74+
}
75+
ln, err := nas.Listen(t.Context())
76+
if tt.wantErr {
77+
require.Error(t, err)
78+
return
79+
}
80+
require.NoError(t, err)
81+
assert.NoError(t, ln.Close())
82+
})
83+
}
84+
}

0 commit comments

Comments
 (0)