Skip to content

Commit eb80fba

Browse files
committed
Attempt to remove Xlib dependency.
1 parent edbaa8d commit eb80fba

6 files changed

Lines changed: 160 additions & 57 deletions

File tree

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,9 @@ __NOTE:__ If any issue starts to appear and you want to report it, ensure you do
246246
- go (>= 1.20)
247247
- gcc
248248
- pam-devel
249-
- libx11-devel (libx11)
250249

251250
### Dependencies
252251
- pam
253-
- libx11
254252
- xorg / xorg-server (optional)
255253
- xauth / xorg-xauth (required for xorg)
256254
- mcookie (required for xorg)
@@ -293,8 +291,5 @@ $ make build TAGS=tag1,tag2
293291
#### nopam
294292
This tag disables dependency on PAM. In Linux it switch to basic authentication with `shadow`.
295293

296-
#### noxlib
297-
This tag disables dependency on libx11, could be useful, if only Wayland desktop is expected to be used.
298-
299294
#### noutmp
300295
This tag disables dependency on UTMP/UTMPX. Its implementation is different by each libc/distro, this provides ability to build if incompatibility occurs.

src/emptty.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func printHelp() {
197197
// Gets current version
198198
func getVersion() string {
199199
tags := strings.Builder{}
200-
for _, tag := range []string{tagPam, tagUtmp, tagXlib} {
200+
for _, tag := range []string{tagPam, tagUtmp} {
201201
if tags.Len() > 0 {
202202
tags.WriteString(", ")
203203
}

src/session_xorg.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (x *xorgSession) startCarrier() {
6767
}
6868
logPrint("Started Xorg")
6969

70-
if err := openXDisplay(x.auth.usr().getenv(envDisplay)); err != nil {
70+
if err := openXDisplay(x.auth.usr().getenv(envDisplay), x.auth.usr().getenv(envXauthority)); err != nil {
7171
handleStrErr("Could not open X Display.")
7272
}
7373
}

src/x11.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package src
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"errors"
7+
"fmt"
8+
"net"
9+
"os"
10+
"path/filepath"
11+
"strings"
12+
"time"
13+
)
14+
15+
// Opens XDisplay via socket and tries to authenticate with Xauthority.
16+
func openXDisplay(dispName, xauthorityPath string) error {
17+
displayNum, socketPath, err := resolveDisplay(dispName)
18+
if err != nil {
19+
return err
20+
}
21+
22+
authName, authData, err := readXAuthority(displayNum, xauthorityPath)
23+
if err != nil {
24+
return fmt.Errorf("xauthority: %w", err)
25+
}
26+
27+
for i := 0; i < 50; i++ {
28+
conn, err := net.DialTimeout("unix", socketPath, 200*time.Millisecond)
29+
if err == nil {
30+
err = performHandshake(conn, authName, authData)
31+
if err == nil {
32+
return nil
33+
} else {
34+
conn.Close()
35+
}
36+
}
37+
time.Sleep(50 * time.Millisecond)
38+
}
39+
40+
return errors.New("could not open authenticated X display")
41+
}
42+
43+
// Gets display number and its socket path from display name.
44+
func resolveDisplay(display string) (string, string, error) {
45+
if !strings.HasPrefix(display, ":") {
46+
return "", "", errors.New("only local displays supported")
47+
}
48+
num := strings.Split(display[1:], ".")[0]
49+
socketPath := filepath.Join("/tmp/.X11-unix", "X"+num)
50+
return num, socketPath, nil
51+
}
52+
53+
// Reads and parses XAuthority file on defined path.
54+
func readXAuthority(displayNum, xauthorityPath string) (string, []byte, error) {
55+
data, err := os.ReadFile(xauthorityPath)
56+
if err != nil {
57+
return "", nil, err
58+
}
59+
60+
r := bytes.NewReader(data)
61+
62+
for r.Len() > 0 {
63+
var family uint16
64+
if err := binary.Read(r, binary.BigEndian, &family); err != nil {
65+
return "", nil, err
66+
}
67+
68+
addr, err := readString(r)
69+
if err != nil {
70+
return "", nil, err
71+
}
72+
_ = addr
73+
74+
display, err := readString(r)
75+
if err != nil {
76+
return "", nil, err
77+
}
78+
79+
name, err := readString(r)
80+
if err != nil {
81+
return "", nil, err
82+
}
83+
84+
authData, err := readString(r)
85+
if err != nil {
86+
return "", nil, err
87+
}
88+
89+
if family == 256 &&
90+
display == displayNum &&
91+
name == "MIT-MAGIC-COOKIE-1" {
92+
return name, []byte(authData), nil
93+
}
94+
}
95+
96+
return "", nil, errors.New("no matching MIT-MAGIC-COOKIE-1 entry found")
97+
}
98+
99+
// Reads strings from reader by defined length.
100+
func readString(r *bytes.Reader) (string, error) {
101+
var length uint16
102+
if err := binary.Read(r, binary.BigEndian, &length); err != nil {
103+
return "", err
104+
}
105+
buf := make([]byte, length)
106+
if _, err := r.Read(buf); err != nil {
107+
return "", err
108+
}
109+
return string(buf), nil
110+
}
111+
112+
// Performs handshake authorization with opened X display.
113+
func performHandshake(conn net.Conn, authName string, authData []byte) error {
114+
authNameBytes := []byte(authName)
115+
116+
pad := func(n int) int {
117+
if n%4 == 0 {
118+
return n
119+
}
120+
return n + (4 - (n % 4))
121+
}
122+
123+
authNameLen := len(authNameBytes)
124+
authDataLen := len(authData)
125+
126+
packetLen := 12 +
127+
pad(authNameLen) +
128+
pad(authDataLen)
129+
130+
buf := make([]byte, packetLen)
131+
132+
buf[0] = 'l'
133+
binary.LittleEndian.PutUint16(buf[2:], 11)
134+
binary.LittleEndian.PutUint16(buf[4:], 0)
135+
binary.LittleEndian.PutUint16(buf[6:], uint16(authNameLen))
136+
binary.LittleEndian.PutUint16(buf[8:], uint16(authDataLen))
137+
138+
offset := 12
139+
copy(buf[offset:], authNameBytes)
140+
offset += pad(authNameLen)
141+
142+
copy(buf[offset:], authData)
143+
144+
if _, err := conn.Write(buf); err != nil {
145+
return err
146+
}
147+
148+
reply := make([]byte, 8)
149+
if _, err := conn.Read(reply); err != nil {
150+
return err
151+
}
152+
153+
if reply[0] != 1 {
154+
return errors.New("X server authentication failed")
155+
}
156+
157+
return nil
158+
}

src/xlib.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/xlib_noxlib.go

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)