Antonio Mika
·
2026-10-22
1package pssh
2
3import (
4 "encoding/binary"
5 "strings"
6)
7
8func SessionMessage(sesh *SSHServerConnSession, msg string) {
9 _, _ = sesh.Write([]byte(msg + "\r\n"))
10}
11
12// HelpNotice writes help to the session, translating newlines for the client's pty.
13func HelpNotice(help string) SSHServerMiddleware {
14 return func(next SSHServerHandler) SSHServerHandler {
15 return func(sesh *SSHServerConnSession) error {
16 SessionMessage(sesh, strings.ReplaceAll(strings.TrimRight(help, "\n"), "\n", "\r\n"))
17 return next(sesh)
18 }
19 }
20}
21
22func PtyMdw(mdw SSHServerMiddleware) SSHServerMiddleware {
23 return func(next SSHServerHandler) SSHServerHandler {
24 return func(sesh *SSHServerConnSession) error {
25 _, _, ok := sesh.Pty()
26 if !ok {
27 return next(sesh)
28 }
29 return mdw(next)(sesh)
30 }
31 }
32}
33
34type Window struct {
35 Width int
36 Height int
37 HeightPixels int
38 WidthPixels int
39}
40
41type Pty struct {
42 Term string
43 Window Window
44}
45
46func (p *Pty) Resize(width, height int) error {
47 return nil
48}
49
50func (p *Pty) Name() string {
51 return ""
52}
53
54func parsePtyRequest(s []byte) (pty Pty, ok bool) {
55 term, s, ok := parseString(s)
56 if !ok {
57 return
58 }
59 width32, s, ok := parseUint32(s)
60 if !ok {
61 return
62 }
63 height32, _, ok := parseUint32(s)
64 if !ok {
65 return
66 }
67 pty = Pty{
68 Term: term,
69 Window: Window{
70 Width: int(width32),
71 Height: int(height32),
72 },
73 }
74 return
75}
76
77func parseWinchRequest(s []byte) (win Window, ok bool) {
78 width32, s, ok := parseUint32(s)
79 if width32 < 1 {
80 ok = false
81 }
82 if !ok {
83 return
84 }
85 height32, _, ok := parseUint32(s)
86 if height32 < 1 {
87 ok = false
88 }
89 if !ok {
90 return
91 }
92 win = Window{
93 Width: int(width32),
94 Height: int(height32),
95 }
96 return
97}
98
99func parseString(in []byte) (out string, rest []byte, ok bool) {
100 if len(in) < 4 {
101 return
102 }
103 length := binary.BigEndian.Uint32(in)
104 if uint32(len(in)) < 4+length {
105 return
106 }
107 out = string(in[4 : 4+length])
108 rest = in[4+length:]
109 ok = true
110 return
111}
112
113func parseUint32(in []byte) (uint32, []byte, bool) {
114 if len(in) < 4 {
115 return 0, nil, false
116 }
117 return binary.BigEndian.Uint32(in), in[4:], true
118}