@@ -3,15 +3,19 @@ package xorg
33import (
44 "bytes"
55 _ "embed"
6+ "errors"
67 "fmt"
7- "html/template "
8+ "io "
89 "os"
10+ "syscall"
11+ "text/template"
912
1013 "github.com/hertg/egpu-switcher/internal/logger"
1114)
1215
1316//go:embed conf.template
14- var confTemplate string
17+ var embeddedTemplate string
18+ var templatePath = "/usr/share/egpu-switcher/x11-template.conf"
1519
1620func RemoveEgpuFile (path string , verbose bool ) error {
1721 f , _ := os .Stat (path )
@@ -44,7 +48,7 @@ func CreateEgpuFile(path string, contents string, verbose bool) error {
4448 return nil
4549}
4650
47- func RenderConf (id string , driver string , busid string , modesetting bool ) string {
51+ func RenderConf (id string , driver string , busid string , modesetting bool , verbose bool ) ( string , bool , error ) {
4852
4953 type conf struct {
5054 Id string
@@ -60,12 +64,70 @@ func RenderConf(id string, driver string, busid string, modesetting bool) string
6064 Modesetting : modesetting ,
6165 }
6266
63- buf := bytes .NewBuffer (nil )
67+ customTemplatePermissionCheck ()
68+
69+ confTemplate , isCustom := templateString (verbose )
6470 t := template .Must (template .New ("conf" ).Parse (confTemplate ))
71+ buf := bytes .NewBuffer (nil )
6572 err := t .Execute (buf , c )
6673 if err != nil {
67- panic (err )
74+ return "" , isCustom , err
75+ }
76+
77+ return buf .String (), isCustom , nil
78+ }
79+
80+ func templateString (verbose bool ) (string , bool ) {
81+ var confTemplate string
82+ templateFile , err := os .OpenFile (templatePath , os .O_RDONLY , 0644 )
83+ isCustom := false
84+ if err != nil {
85+ if ! errors .Is (err , os .ErrNotExist ) {
86+ // if we get an error, other than "not exists", print an error
87+ // the "not exists" error is an expected outcome when the config file is not customized
88+ logger .Error ("unable to open custom x11 config template, using default template instead" )
89+ }
90+ if verbose {
91+ logger .Debug ("using default template for x11 conf" )
92+ }
93+ confTemplate = embeddedTemplate
94+ } else {
95+ if verbose {
96+ logger .Debug ("using custom template at '%s' for x11 conf" , templatePath )
97+ }
98+ var buf bytes.Buffer
99+ io .Copy (& buf , templateFile )
100+ confTemplate = buf .String ()
101+ isCustom = true
102+ }
103+ return confTemplate , isCustom
104+ }
105+
106+ func customTemplatePermissionCheck () {
107+ logWarn := false
108+ info , err := os .Stat (templatePath )
109+ if err != nil {
110+ logger .Error ("%s" , err )
111+ return
68112 }
113+ if stat , ok := info .Sys ().(* syscall.Stat_t ); ok {
114+ if stat .Uid != 0 {
115+ logger .Warn ("the custom x11 config template is not owned by root user" )
116+ logWarn = true
117+ }
118+ if stat .Gid != 0 {
119+ logger .Warn ("the custom x11 config template is not owned by root group" )
120+ logWarn = true
121+ }
69122
70- return buf .String ()
123+ otherPerm := info .Mode ().Perm () & 0x007
124+ if otherPerm & 0x2 != 0 {
125+ logger .Warn ("the custom x11 config template is writable by other" )
126+ logWarn = true
127+ }
128+ }
129+ if logWarn {
130+ logger .Warn ("ensure that the custom x11 config template at '%s' is not writable by unauthorized users." +
131+ "this could pose a security risk. file should be owned by root:root and have a file permission of 644" , templatePath )
132+ }
71133}
0 commit comments