-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add service commands to system api group #97
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
package system | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
) | ||
|
@@ -11,6 +13,17 @@ import ( | |
// internal/server/system/server.go so that logic can be easily unit-tested | ||
// without requiring specific OS environments. | ||
|
||
type ServiceInfo struct { | ||
// Service display name | ||
DisplayName string `json:"DisplayName"` | ||
|
||
// Service start type | ||
StartType uint32 `json:"StartType"` | ||
|
||
// Service status | ||
Status uint32 `json:"Status"` | ||
} | ||
|
||
type APIImplementor struct{} | ||
|
||
func New() APIImplementor { | ||
|
@@ -37,3 +50,51 @@ func (APIImplementor) GetBIOSSerialNumber() (string, error) { | |
} | ||
return lines[1], nil | ||
} | ||
|
||
func (APIImplementor) GetService(name string) (*ServiceInfo, error) { | ||
script := `Get-Service -Name $env:ServiceName | Select-Object DisplayName, Status, StartType | ` + | ||
`ConvertTo-JSON` | ||
cmd := exec.Command("powershell", "/c", script) | ||
cmd.Env = append(os.Environ(), fmt.Sprintf("ServiceName=%s", name)) | ||
|
||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return nil, fmt.Errorf("error querying service name=%s. cmd: %s, output: %s, error: %v", name, cmd, string(out), err) | ||
} | ||
|
||
var serviceInfo ServiceInfo | ||
err = json.Unmarshal(out, &serviceInfo) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &serviceInfo, nil | ||
} | ||
|
||
func (APIImplementor) StartService(name string) error { | ||
script := `Start-Service -Name $env:ServiceName` | ||
cmd := exec.Command("powershell", "/c", script) | ||
cmd.Env = append(os.Environ(), fmt.Sprintf("ServiceName=%s", name)) | ||
|
||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return fmt.Errorf("error starting service name=%s. cmd: %s, output: %s, error: %v", name, cmd, string(out), err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (APIImplementor) StopService(name string, force bool) error { | ||
script := `Stop-Service -Name $env:ServiceName -Force:$([System.Convert]::ToBoolean($env:Force))` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as before: Is there a reason to set the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see above, tell me what you think |
||
cmd := exec.Command("powershell", "/c", script) | ||
cmd.Env = append(os.Environ(), | ||
fmt.Sprintf("ServiceName=%s", name), | ||
fmt.Sprintf("Force=%t", force)) | ||
|
||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return fmt.Errorf("error stopping service name=%s. cmd: %s, output: %s, error: %v", name, cmd, string(out), err) | ||
} | ||
|
||
return nil | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to set the
servicename
parameter through an environment variable here? Why not usesprintf
directly here rather than a couple of lines below?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, thanks for the review! :)
I've built this upon the comments that were left in the smb api group:
csi-proxy/internal/os/smb/api.go
Lines 55 to 60 in 6966676
I tried to find more data online about Powershell command injection, but I haven't found anyone referring to env variables. I did find this link which might indicate that env variables could prevent injection.
Anyway, if this really solves injection then it's a good idea to add this in all csi-proxy commands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing out the link! Makes complete sense to use this protection in case the csi-proxy is being used to invoke arbitrary commands in a malicious context on the host.