detached 4175002

feat(app): contain udp proxy key handling

commit
41750027f03ae2a3598d39df76c3bd8e0cfc68c9
author
brice · · 2026-07-23 20:32 UTC
parent
9f8c7d2
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +42 -17
M internal/app/run.go +42 -17
@@ -48,6 +48,7 @@ import (
4848 "github.com/bnema/vev/internal/usecase/client"
4949 "github.com/bnema/vev/internal/usecase/confirm"
5050 "github.com/bnema/vev/internal/usecase/daemon"
51+ pdgram "github.com/bnema/vev/pkg/dgram"
5152 "github.com/bnema/vev/pkg/kv"
5253 )
5354
@@ -929,10 +930,6 @@ func runUDPProxy(ctx context.Context, session string, ready io.Writer) (retErr e
929930 return err
930931 }
931932 defer func() { _ = conn.Close() }()
932- key := make([]byte, 32)
933- if _, err := rand.Read(key); err != nil {
934- return err
935- }
936933 daemonTr, err := ensureDaemon(ctx, ipc.SocketDir(), func(ctx context.Context, dir string) (ports.Transport, error) {
937934 return ipc.DialContext(ctx, dir, ipc.WithRuntimeObserver(observer))
938935 }, realSpawn, defaultBackoff)
@@ -942,26 +939,54 @@ func runUDPProxy(ctx context.Context, session string, ready io.Writer) (retErr e
942939 defer func() { _ = daemonTr.Close() }()
943940 udpOptions := udpProxyClientTransportOptions
944941 udpOptions.Observe = dgram.DiagnosticLogObserver(log)
945- dg, err := dgram.NewTransportWithOptions(conn, nil, key, 2, 1, udpOptions, dgram.WithRuntimeObserver(observer))
946- if err != nil {
947- return err
948- }
949- defer func() { _ = dg.Close() }()
950-
951942 addr, ok := conn.LocalAddr().(*net.UDPAddr)
952943 if !ok {
953944 return errors.New("vev: udp proxy did not get a UDP address")
954945 }
955- keyText := base64.StdEncoding.EncodeToString(key)
956946 registry := dgram.NewProxyRegistry(filepath.Join(ipc.SocketDir(), "udp-proxies"))
957- record := dgram.ProxyRecord{Session: session, PID: os.Getpid(), Port: addr.Port, KeyFingerprint: dgram.KeyFingerprint(key)}
958- if err := registry.Publish(record); err != nil {
959- return err
947+
948+ var (
949+ dg *dgram.Transport
950+ record dgram.ProxyRecord
951+ published bool
952+ setupErr error
953+ )
954+ pdgram.SecretDo(func() {
955+ key := make([]byte, pdgram.KeySize)
956+ defer pdgram.Erase(key)
957+ if _, setupErr = rand.Read(key); setupErr != nil {
958+ return
959+ }
960+ dg, setupErr = dgram.NewTransportWithOptions(conn, nil, key, 2, 1, udpOptions, dgram.WithRuntimeObserver(observer))
961+ if setupErr != nil {
962+ return
963+ }
964+ record = dgram.ProxyRecord{Session: session, PID: os.Getpid(), Port: addr.Port, KeyFingerprint: dgram.KeyFingerprint(key)}
965+ if setupErr = registry.Publish(record); setupErr != nil {
966+ return
967+ }
968+ published = true
969+
970+ readiness := append([]byte("VEV-UDP "), strconv.Itoa(addr.Port)...)
971+ readiness = append(readiness, ' ')
972+ readiness = base64.StdEncoding.AppendEncode(readiness, key)
973+ readiness = append(readiness, '\n')
974+ defer pdgram.Erase(readiness)
975+ _, setupErr = ready.Write(readiness)
976+ pdgram.Erase(readiness)
977+ pdgram.Erase(key)
978+ })
979+ if setupErr != nil {
980+ if dg != nil {
981+ _ = dg.Close()
982+ }
983+ if published {
984+ _ = registry.RemoveOwned(record)
985+ }
986+ return setupErr
960987 }
988+ defer func() { _ = dg.Close() }()
961989 defer func() { _ = registry.RemoveOwned(record) }()
962- if _, err := fmt.Fprintf(ready, "VEV-UDP %d %s\n", addr.Port, keyText); err != nil {
963- return err
964- }
965990
966991 return runUDPProxyRuntime(ctx, session, dg, daemonTr, os.Environ(), log)
967992 }
@@ -48,6 +48,7 @@ import (
48 "github.com/bnema/vev/internal/usecase/client"48 "github.com/bnema/vev/internal/usecase/client"
49 "github.com/bnema/vev/internal/usecase/confirm"49 "github.com/bnema/vev/internal/usecase/confirm"
50 "github.com/bnema/vev/internal/usecase/daemon"50 "github.com/bnema/vev/internal/usecase/daemon"
51+ pdgram "github.com/bnema/vev/pkg/dgram"
51 "github.com/bnema/vev/pkg/kv"52 "github.com/bnema/vev/pkg/kv"
52 )53 )
53 54
@@ -929,10 +930,6 @@ func runUDPProxy(ctx context.Context, session string, ready io.Writer) (retErr e
929 return err930 return err
930 }931 }
931 defer func() { _ = conn.Close() }()932 defer func() { _ = conn.Close() }()
932- key := make([]byte, 32)
933- if _, err := rand.Read(key); err != nil {
934- return err
935- }
936 daemonTr, err := ensureDaemon(ctx, ipc.SocketDir(), func(ctx context.Context, dir string) (ports.Transport, error) {933 daemonTr, err := ensureDaemon(ctx, ipc.SocketDir(), func(ctx context.Context, dir string) (ports.Transport, error) {
937 return ipc.DialContext(ctx, dir, ipc.WithRuntimeObserver(observer))934 return ipc.DialContext(ctx, dir, ipc.WithRuntimeObserver(observer))
938 }, realSpawn, defaultBackoff)935 }, realSpawn, defaultBackoff)
@@ -942,26 +939,54 @@ func runUDPProxy(ctx context.Context, session string, ready io.Writer) (retErr e
942 defer func() { _ = daemonTr.Close() }()939 defer func() { _ = daemonTr.Close() }()
943 udpOptions := udpProxyClientTransportOptions940 udpOptions := udpProxyClientTransportOptions
944 udpOptions.Observe = dgram.DiagnosticLogObserver(log)941 udpOptions.Observe = dgram.DiagnosticLogObserver(log)
945- dg, err := dgram.NewTransportWithOptions(conn, nil, key, 2, 1, udpOptions, dgram.WithRuntimeObserver(observer))
946- if err != nil {
947- return err
948- }
949- defer func() { _ = dg.Close() }()
950-
951 addr, ok := conn.LocalAddr().(*net.UDPAddr)942 addr, ok := conn.LocalAddr().(*net.UDPAddr)
952 if !ok {943 if !ok {
953 return errors.New("vev: udp proxy did not get a UDP address")944 return errors.New("vev: udp proxy did not get a UDP address")
954 }945 }
955- keyText := base64.StdEncoding.EncodeToString(key)
956 registry := dgram.NewProxyRegistry(filepath.Join(ipc.SocketDir(), "udp-proxies"))946 registry := dgram.NewProxyRegistry(filepath.Join(ipc.SocketDir(), "udp-proxies"))
957- record := dgram.ProxyRecord{Session: session, PID: os.Getpid(), Port: addr.Port, KeyFingerprint: dgram.KeyFingerprint(key)}947+
958- if err := registry.Publish(record); err != nil {948+ var (
959- return err949+ dg *dgram.Transport
950+ record dgram.ProxyRecord
951+ published bool
952+ setupErr error
953+ )
954+ pdgram.SecretDo(func() {
955+ key := make([]byte, pdgram.KeySize)
956+ defer pdgram.Erase(key)
957+ if _, setupErr = rand.Read(key); setupErr != nil {
958+ return
959+ }
960+ dg, setupErr = dgram.NewTransportWithOptions(conn, nil, key, 2, 1, udpOptions, dgram.WithRuntimeObserver(observer))
961+ if setupErr != nil {
962+ return
963+ }
964+ record = dgram.ProxyRecord{Session: session, PID: os.Getpid(), Port: addr.Port, KeyFingerprint: dgram.KeyFingerprint(key)}
965+ if setupErr = registry.Publish(record); setupErr != nil {
966+ return
967+ }
968+ published = true
969+
970+ readiness := append([]byte("VEV-UDP "), strconv.Itoa(addr.Port)...)
971+ readiness = append(readiness, ' ')
972+ readiness = base64.StdEncoding.AppendEncode(readiness, key)
973+ readiness = append(readiness, '\n')
974+ defer pdgram.Erase(readiness)
975+ _, setupErr = ready.Write(readiness)
976+ pdgram.Erase(readiness)
977+ pdgram.Erase(key)
978+ })
979+ if setupErr != nil {
980+ if dg != nil {
981+ _ = dg.Close()
982+ }
983+ if published {
984+ _ = registry.RemoveOwned(record)
985+ }
986+ return setupErr
960 }987 }
988+ defer func() { _ = dg.Close() }()
961 defer func() { _ = registry.RemoveOwned(record) }()989 defer func() { _ = registry.RemoveOwned(record) }()
962- if _, err := fmt.Fprintf(ready, "VEV-UDP %d %s\n", addr.Port, keyText); err != nil {
963- return err
964- }
965 990
966 return runUDPProxyRuntime(ctx, session, dg, daemonTr, os.Environ(), log)991 return runUDPProxyRuntime(ctx, session, dg, daemonTr, os.Environ(), log)
967 }992 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close