mirror of
https://github.com/rwinkhart/rcw.git
synced 2026-09-05 16:47:24 -04:00
Only respond to RPC calls from the same user as the daemon process
This commit is contained in:
+7
-4
@@ -75,7 +75,8 @@ func (h *RCWService) GetPass(request string, reply *string) error {
|
|||||||
// handleConn verifies the identity of the client.
|
// handleConn verifies the identity of the client.
|
||||||
// It uses the file descriptor of the connection to get the PID of the client,
|
// It uses the file descriptor of the connection to get the PID of the client,
|
||||||
// which is then used to get the path of the client's executable and calculate its hash.
|
// which is then used to get the path of the client's executable and calculate its hash.
|
||||||
// The passphrase is only returned if the client's executable hash matches the daemon's hash.
|
// The passphrase is only returned if the client's executable hash matches the daemon's hash
|
||||||
|
// and if the request is coming from the same user.
|
||||||
// This ensures that only the binary the daemon is embedded in can retrieve the passphrase.
|
// This ensures that only the binary the daemon is embedded in can retrieve the passphrase.
|
||||||
func handleConn(conn net.Conn) {
|
func handleConn(conn net.Conn) {
|
||||||
// ensure access to the underlying file descriptor
|
// ensure access to the underlying file descriptor
|
||||||
@@ -94,6 +95,7 @@ func handleConn(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var callingPID int32
|
var callingPID int32
|
||||||
|
var callingUID int
|
||||||
_ = rawConn.Control(func(fd uintptr) {
|
_ = rawConn.Control(func(fd uintptr) {
|
||||||
// use syscall.GetsockoptUcred to fetch credentials
|
// use syscall.GetsockoptUcred to fetch credentials
|
||||||
ucred, err := syscall.GetsockoptUcred(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
|
ucred, err := syscall.GetsockoptUcred(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
|
||||||
@@ -102,18 +104,19 @@ func handleConn(conn net.Conn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
callingPID = ucred.Pid
|
callingPID = ucred.Pid
|
||||||
|
callingUID = int(ucred.Uid)
|
||||||
})
|
})
|
||||||
|
|
||||||
// check if the RPC call is coming from an identical binary
|
// check if the RPC call is coming from an identical binary and from the same user
|
||||||
callingBinPath := pidToPath(callingPID)
|
callingBinPath := pidToPath(callingPID)
|
||||||
if bytes.Equal(getFileHash(callingBinPath), daemonHash) {
|
if callingUID == os.Getuid() && bytes.Equal(getFileHash(callingBinPath), daemonHash) {
|
||||||
// valid client; hand off the connection to the RPC server
|
// valid client; hand off the connection to the RPC server
|
||||||
rpc.ServeConn(conn)
|
rpc.ServeConn(conn)
|
||||||
} else {
|
} else {
|
||||||
// invalid client; close the connection w/o a response,
|
// invalid client; close the connection w/o a response,
|
||||||
// log the client's path, and kill the daemon
|
// log the client's path, and kill the daemon
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Printf("Request received from invalid client: %s", callingBinPath) // TODO log to file
|
log.Printf("Request received from invalid client: PID(%d), UID(%d), Path(%s)", callingPID, callingUID, callingBinPath) // TODO log to file
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user