mirror of
https://github.com/bolkedebruin/rdpgw.git
synced 2026-05-14 12:19:59 +00:00
Restrict the rdpgw-auth socket to its own UID by default (#190)
The auth daemon's gRPC socket was world-writable and accepted any local UID that could connect to it. On a multi-tenant host any user on the box could speak the gRPC API and run an arbitrary username/ password through PAM -- effectively an unauthenticated PAM oracle. Create the socket with mode 0660 (Umask(0117)) and gate Accept on SO_PEERCRED: only the daemon's own UID is allowed by default, plus any operator-supplied --allow-uid / --allow-gid. Privilege-separated deployments (rdpgw and rdpgw-auth as different users) need to list the gateway's UID, or share a group; the existing path otherwise would have been permissive. The peer-credentials check is Linux-only; the non-Linux build keeps the listener as-is and logs a warning, since rdpgw-auth itself requires libpam and is effectively Linux-only in practice.
This commit is contained in:
@@ -24,7 +24,9 @@ const (
|
||||
var opts struct {
|
||||
ServiceName string `short:"n" long:"name" default:"rdpgw" description:"the PAM service name to use"`
|
||||
SocketAddr string `short:"s" long:"socket" default:"/tmp/rdpgw-auth.sock" description:"the location of the socket"`
|
||||
ConfigFile string `short:"c" long:"conf" default:"rdpgw-auth.yaml" description:"users config file for NTLM (yaml)"`
|
||||
ConfigFile string `short:"c" long:"conf" default:"rdpgw-auth.yaml" description:"users config file for NTLM (yaml)"`
|
||||
AllowUID []int `long:"allow-uid" description:"additional UIDs allowed to connect to the socket; the daemon's own UID is always allowed (repeatable)"`
|
||||
AllowGID []int `long:"allow-gid" description:"GIDs allowed to connect to the socket (repeatable)"`
|
||||
}
|
||||
|
||||
type AuthServiceImpl struct {
|
||||
@@ -127,12 +129,19 @@ func main() {
|
||||
}
|
||||
cleanup()
|
||||
|
||||
oldUmask := syscall.Umask(0)
|
||||
oldUmask := syscall.Umask(0117)
|
||||
listener, err := net.Listen(protocol, opts.SocketAddr)
|
||||
syscall.Umask(oldUmask)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// The daemon's own UID is always permitted; additional callers must
|
||||
// be enumerated by the operator. This stops any local user on a
|
||||
// shared host from speaking gRPC against the PAM oracle.
|
||||
allowedUIDs := append([]int{os.Getuid()}, opts.AllowUID...)
|
||||
listener = newGatedListener(listener, allowedUIDs, opts.AllowGID)
|
||||
|
||||
server := grpc.NewServer()
|
||||
db := database.NewConfig(conf.Users)
|
||||
service := NewAuthService(opts.ServiceName, db)
|
||||
|
||||
Reference in New Issue
Block a user