func Test_executing_a_regex_command(t *testing.T) { w := &wsman{} id := w.HandleCommand(MatchPattern(`echo .* >> C:\file.cmd`), func(out, err io.Writer) int { return 0 }) res := httptest.NewRecorder() req, _ := http.NewRequest("POST", "", strings.NewReader(fmt.Sprintf(` <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell"> <env:Header> <a:Action mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/shell/Command</a:Action> </env:Header> <env:Body> <rsp:CommandLine><rsp:Command>"echo %d >> C:\file.cmd"</rsp:Command></rsp:CommandLine> </env:Body> </env:Envelope>`, uuid.NewV4().String()))) w.ServeHTTP(res, req) if res.Code != http.StatusOK { t.Errorf("Expected 200 OK but was %d.\n", res.Code) } env, err := xmlpath.Parse(res.Body) if err != nil { t.Error("Couldn't compile the SOAP response.") } xpath, _ := xmlpath.CompileWithNamespace( "//rsp:CommandId", soap.GetAllNamespaces()) result, _ := xpath.String(env) if result != id { t.Errorf("Expected CommandId=%s but was \"%s\"", id, result) } }
func first(node *xmlpath.Node, xpath string) (content string, err error) { path, err := xmlpath.CompileWithNamespace(xpath, soap.GetAllNamespaces()) if err != nil { return } content, _ = path.String(node) return }
func any(node *xmlpath.Node, xpath string) (found bool, err error) { path, err := xmlpath.CompileWithNamespace(xpath, soap.GetAllNamespaces()) if err != nil { return } found = path.Exists(node) return }
func readCommandIDFromDesiredStream(env *xmlpath.Node) string { xpath, err := xmlpath.CompileWithNamespace( "//rsp:DesiredStream/@CommandId", soap.GetAllNamespaces()) if err != nil { return "" } id, _ := xpath.String(env) return id }
func readAction(env *xmlpath.Node) string { xpath, err := xmlpath.CompileWithNamespace( "//a:Action", soap.GetAllNamespaces()) if err != nil { return "" } action, _ := xpath.String(env) return action }
func xpath(node *xmlpath.Node, xpath string) (nodes []xmlpath.Node, err error) { path, err := xmlpath.CompileWithNamespace(xpath, soap.GetAllNamespaces()) if err != nil { return } nodes = make([]xmlpath.Node, 0, 1) iter := path.Iter(node) for iter.Next() { nodes = append(nodes, *(iter.Node())) } return }
func parseXPath(doc *dom.Document, request string) (*xmlpath.Node, *xmlpath.Path, error) { content := strings.NewReader(doc.String()) node, err := xmlpath.Parse(content) if err != nil { return nil, nil, err } path, err := xmlpath.CompileWithNamespace(request, soap.GetAllNamespaces()) if err != nil { return nil, nil, err } return node, path, nil }
func readCommand(env *xmlpath.Node) string { xpath, err := xmlpath.CompileWithNamespace( "//rsp:Command", soap.GetAllNamespaces()) if err != nil { return "" } command, _ := xpath.String(env) if unquoted, err := strconv.Unquote(command); err == nil { return unquoted } return command }
func Test_creating_a_shell(t *testing.T) { w := &wsman{} res := httptest.NewRecorder() req, _ := http.NewRequest("POST", "", strings.NewReader(` <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <env:Header> <a:Action mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action> </env:Header> <env:Body> <rsp:Shell> <rsp:InputStream>stdin</rsp:InputStream> <rsp:OutputStreams>stdout stderr</rsp:OutputStreams> </rsp:Shell> </env:Body> </env:Envelope>`)) w.ServeHTTP(res, req) if res.Code != http.StatusOK { t.Errorf("Expected 200 OK but was %d.\n", res.Code) } if contentType := res.HeaderMap.Get("Content-Type"); contentType != "application/soap+xml" { t.Errorf("Expected ContentType application/soap+xml was %s.\n", contentType) } env, err := xmlpath.Parse(res.Body) if err != nil { t.Error("Couldn't compile the SOAP response.") } xpath, _ := xmlpath.CompileWithNamespace( "//rsp:ShellId", soap.GetAllNamespaces()) if _, found := xpath.String(env); !found { t.Error("Expected a Shell identifier.") } }
func Test_receiving_command_results(t *testing.T) { w := &wsman{} id := w.HandleCommand(MatchText("echo tacos"), func(out, err io.Writer) int { out.Write([]byte("tacos")) return 0 }) res := httptest.NewRecorder() req, _ := http.NewRequest("POST", "", strings.NewReader(fmt.Sprintf(` <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell"> <env:Header> <a:Action mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive</a:Action> </env:Header> <env:Body> <rsp:Receive><rsp:DesiredStream CommandId="%s">stdout stderr</rsp:DesiredStream></rsp:Receive> </env:Body> </env:Envelope>`, id))) w.ServeHTTP(res, req) if res.Code != http.StatusOK { t.Errorf("Expected 200 OK but was %d.\n", res.Code) } env, err := xmlpath.Parse(res.Body) if err != nil { t.Error("Couldn't compile the SOAP response.") } xpath, _ := xmlpath.CompileWithNamespace("//rsp:ReceiveResponse", soap.GetAllNamespaces()) iter := xpath.Iter(env) if !iter.Next() { t.Error("Expected a ReceiveResponse element.") } xresp := iter.Node() xpath, _ = xmlpath.CompileWithNamespace( fmt.Sprintf("rsp:Stream[@CommandId='%s']", id), soap.GetAllNamespaces()) iter = xpath.Iter(xresp) if !iter.Next() || !nodeHasAttribute(iter.Node(), "Name", "stdout") || iter.Node().String() != "dGFjb3M=" { t.Error("Expected an stdout Stream with the text \"dGFjb3M=\".") } if !iter.Next() || !nodeHasAttribute(iter.Node(), "Name", "stdout") || !nodeHasAttribute(iter.Node(), "End", "true") { t.Error("Expected an stdout Stream with an \"End\" attribute.") } if !iter.Next() || !nodeHasAttribute(iter.Node(), "Name", "stderr") || !nodeHasAttribute(iter.Node(), "End", "true") { t.Error("Expected an stderr Stream with an \"End\" attribute.") } xpath, _ = xmlpath.CompileWithNamespace( "//rsp:CommandState[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done']", soap.GetAllNamespaces()) if _, found := xpath.String(env); !found { t.Error("Expected CommandState=\"Done\"") } xpath, _ = xmlpath.CompileWithNamespace("//rsp:CommandState/rsp:ExitCode", soap.GetAllNamespaces()) if code, _ := xpath.String(env); code != "0" { t.Errorf("Expected ExitCode=0 but found \"%s\"\n", code) } }