initial version of the basic x11 proxy
This commit is contained in:
116
auth.go
Normal file
116
auth.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"net"
|
||||
)
|
||||
|
||||
func resolveDisplay(display string) (ConnType, string) {
|
||||
var dispNum int
|
||||
var err error
|
||||
|
||||
if strings.HasPrefix(display, ":") {
|
||||
dispNum, err = strconv.Atoi(strings.Split(display[1:], ".")[0])
|
||||
} else {
|
||||
parts := strings.Split(display, ":")
|
||||
dispNum, err = strconv.Atoi(strings.Split(parts[1], ".")[0])
|
||||
}
|
||||
if err != nil {
|
||||
dispNum = 0
|
||||
}
|
||||
|
||||
unixPath := path.Join("/tmp/.X11-unix", fmt.Sprintf("X%d", dispNum))
|
||||
if _, err := os.Stat(unixPath); err == nil {
|
||||
return Unix, unixPath
|
||||
}
|
||||
|
||||
tcpAddr := fmt.Sprintf("127.0.0.1:%d", 6000+dispNum)
|
||||
conn, err := net.Dial("tcp", tcpAddr)
|
||||
if err == nil {
|
||||
conn.Close()
|
||||
return TCP, tcpAddr
|
||||
}
|
||||
|
||||
return Unix, unixPath
|
||||
}
|
||||
|
||||
func getXAuthCookie(display string) ([]byte, error) {
|
||||
out, err := exec.Command("xauth", "list").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dispNum string
|
||||
if strings.HasPrefix(display, ":") {
|
||||
dispNum = strings.Split(display[1:], ".")[0]
|
||||
} else {
|
||||
parts := strings.Split(display, ":")
|
||||
dispNum = strings.Split(parts[1], ".")[0]
|
||||
}
|
||||
|
||||
lines := strings.Split(string(out), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 3 && fields[1] == "MIT-MAGIC-COOKIE-1" {
|
||||
entry := fields[0]
|
||||
if strings.Contains(entry, ":"+dispNum) {
|
||||
fmt.Printf("Using XAuth cookie from entry: %s\n", entry)
|
||||
return parseHexCookie(fields[2]), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no matching cookie found for display %s", display)
|
||||
}
|
||||
|
||||
|
||||
func parseHexCookie(hexStr string) []byte {
|
||||
var cookie []byte
|
||||
for i := 0; i < len(hexStr); i += 2 {
|
||||
var val byte
|
||||
fmt.Sscanf(hexStr[i:i+2], "%02x", &val)
|
||||
cookie = append(cookie, val)
|
||||
}
|
||||
return cookie
|
||||
}
|
||||
|
||||
func PatchAuth(data []byte, cookie []byte) []byte {
|
||||
isLittleEndian := data[0] == 'l'
|
||||
|
||||
var authProtoLen, authDataLen int
|
||||
if isLittleEndian {
|
||||
authProtoLen = int(data[7])<<8 | int(data[6])
|
||||
authDataLen = int(data[9])<<8 | int(data[8])
|
||||
} else {
|
||||
authProtoLen = int(data[6])<<8 | int(data[7])
|
||||
authDataLen = int(data[8])<<8 | int(data[9])
|
||||
}
|
||||
|
||||
headerLen := 12
|
||||
authProtoPad := (authProtoLen + 3) & ^3
|
||||
authDataPad := (authDataLen + 3) & ^3
|
||||
authDataStart := headerLen + authProtoPad
|
||||
|
||||
// Replace cookie and update length
|
||||
patched := make([]byte, headerLen+authProtoPad+authDataPad)
|
||||
copy(patched, data[:headerLen+authProtoPad])
|
||||
copy(patched[authDataStart:], cookie)
|
||||
|
||||
// Update authDataLen to match cookie length
|
||||
cookieLen := len(cookie)
|
||||
if isLittleEndian {
|
||||
patched[8] = byte(cookieLen)
|
||||
patched[9] = byte(cookieLen >> 8)
|
||||
} else {
|
||||
patched[8] = byte(cookieLen >> 8)
|
||||
patched[9] = byte(cookieLen)
|
||||
}
|
||||
|
||||
return patched
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user