mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-02 02:38:51 -04:00
60 lines
1.8 KiB
Go
60 lines
1.8 KiB
Go
//go:build windows
|
|
|
|
package daemonaddr
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
|
|
"github.com/Microsoft/go-winio"
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.org/x/sys/windows"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/ipcauth"
|
|
)
|
|
|
|
// dialPipePaths connects to the first path that answers with a pipe server this
|
|
// client may trust, and returns the last error when none does.
|
|
func dialPipePaths(ctx context.Context, paths []string) (net.Conn, error) {
|
|
var lastErr error
|
|
for _, path := range paths {
|
|
conn, err := dialPipe(ctx, path)
|
|
if err != nil {
|
|
log.Debugf("dial daemon pipe %s: %v", path, err)
|
|
lastErr = err
|
|
continue
|
|
}
|
|
|
|
// A pipe in the protected namespace could only have been created by an
|
|
// administrator or LocalSystem, so its name is the guarantee. Any other
|
|
// name has to be checked, because any local user can create one.
|
|
if !IsProtectedPipePath(path) {
|
|
if err := ipcauth.PipeServerTrusted(conn); err != nil {
|
|
if closeErr := conn.Close(); closeErr != nil {
|
|
log.Debugf("close untrusted pipe %s: %v", path, closeErr)
|
|
}
|
|
lastErr = fmt.Errorf("%s: %w", path, err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
return conn, nil
|
|
}
|
|
|
|
if lastErr == nil {
|
|
lastErr = errors.New("no daemon pipe to connect to")
|
|
}
|
|
return nil, lastErr
|
|
}
|
|
|
|
// dialPipe connects to the daemon control pipe at SECURITY_IDENTIFICATION.
|
|
// winio's plain DialPipe connects at SECURITY_ANONYMOUS, under which the daemon
|
|
// cannot read the caller's token at all. Identification lets the daemon read the
|
|
// caller's SID and groups without granting it the ability to act as the caller.
|
|
func dialPipe(ctx context.Context, path string) (net.Conn, error) {
|
|
access := uint32(windows.GENERIC_READ | windows.GENERIC_WRITE)
|
|
return winio.DialPipeAccessImpLevel(ctx, path, access, winio.PipeImpLevelIdentification)
|
|
}
|