-
Notifications
You must be signed in to change notification settings - Fork 118
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
Problem with single quotes in run_wql #143
Comments
Here is a patch for the 2 issues, which is more concise : diff --git a/lib/winrm/winrm_service.rb b/lib/winrm/winrm_service.rb
index 0882832..e7d1345 100644
--- a/lib/winrm/winrm_service.rb
+++ b/lib/winrm/winrm_service.rb
@@ -157,16 +157,11 @@ module WinRM
builder.tag! :env, :Envelope, namespaces do |env|
env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_command,h_opts,selector_shell_id(shell_id))) }
env.tag!(:env, :Body) do |env_body|
- env_body.tag!("#{NS_WIN_SHELL}:CommandLine") { |cl| cl << Gyoku.xml(body) }
+ env_body.tag!("#{NS_WIN_SHELL}:CommandLine") { |cl| cl << Gyoku.xml(body).gsub(''', '\'') }
end
end
- # Grab the command element and unescape any single quotes - issue 69
- xml = builder.target!
- escaped_cmd = /<#{NS_WIN_SHELL}:Command>(.+)<\/#{NS_WIN_SHELL}:Command>/m.match(xml)[1]
- xml[escaped_cmd] = escaped_cmd.gsub(/'/, "'")
-
- resp_doc = send_message(xml)
+ resp_doc = send_message(builder.target!)
command_id = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:CommandId").text
if block_given?
@@ -336,14 +331,14 @@ module WinRM
builder.tag! :env, :Envelope, namespaces do |env|
env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_wmi,action_enumerate)) }
env.tag!(:env, :Body) do |env_body|
- env_body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(body) }
+ env_body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(body).gsub(''', '\'') }
end
end
I didn't test extensively, but it should work. |
Thanks, this LGTM! I wish there was a comment around the old implementation, because it is more complex than just a gsub. I suspect I was just being conservative. |
As far as I understand, you were matching the command part of the commandline, and unescaping the quotes. You can test with : puts wws.cmd %Q|echo Hello Bob's world|
puts wws.cmd 'echo', ["Hello", "Bob's", "world"] The second one fails with current code, and works with mine. PS: what is "LGTM" ? Looks good to me ? |
While testing all this, I noticed another problem. You accept commands either as a big string, or as a string and an array of arguments. def shell_split(line)
words = []
field = ''
line.gsub!(/\^(['"])/, '\\\\\1')
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
field << (word || sq || (dq || esc).gsub(/\\(.)/, '\\1'))
if sep
words << field.gsub(/(['"])/, '^\1')
field = ''
end
end
words
end I just change "^'" and "^"" before parsing, and change them back after. And in run_command : command, *arguments = shell_split(command).concat(arguments)
body = { "#{NS_WIN_SHELL}:Command" => "#{command}", "#{NS_WIN_SHELL}:Arguments" => arguments} Ideally, run_command should raise an error, and run_cmd should issue a warning, before splitting the command. All applied, it looks like this : |
It looks like I need to look into this a bit more and see what the actual behavior is. From the MS documentation it looks like you can pass arguments either way either via the command line or via arguments, but not both.
|
I have a new duplicate problem. It seems now Gyoku changes quotes to Forget about the arguments issue, I will open a new one. However, I would like the quote issue to be fixed. As I did not find how to tell Gyoku not to escape quotes, I just gsubed them back : diff --git a/lib/winrm/winrm_service.rb b/lib/winrm/winrm_service.rb
index 8ce4fc8..3ad8261 100644
--- a/lib/winrm/winrm_service.rb
+++ b/lib/winrm/winrm_service.rb
@@ -392,7 +392,7 @@ module WinRM
builder.tag! :env, :Envelope, namespaces do |env|
env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_wmi,action_enumerate)) }
env.tag!(:env, :Body) do |env_body|
- env_body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(body) }
+ env_body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(body).gsub('"', "'") }
end
end |
I just read #131 and I don't have time right now for a better patch. |
After looking more carefully, I think I have a better patch. Instead of bruteforcing Gyoku output, it seems possible to make it not change the input. I did not test run_cmd, but I did test run_wql. diff --git a/lib/winrm/winrm_service.rb b/lib/winrm/winrm_service.rb
index 8ce4fc8..f643445 100644
--- a/lib/winrm/winrm_service.rb
+++ b/lib/winrm/winrm_service.rb
@@ -169,9 +169,13 @@ module WinRM
consolemode = cmd_opts.has_key?(:console_mode_stdin) ? cmd_opts[:console_mode_stdin] : 'TRUE'
skipcmd = cmd_opts.has_key?(:skip_cmd_shell) ? cmd_opts[:skip_cmd_shell] : 'FALSE'
- h_opts = { "#{NS_WSMAN_DMTF}:OptionSet" => {
- "#{NS_WSMAN_DMTF}:Option" => [consolemode, skipcmd],
- :attributes! => {"#{NS_WSMAN_DMTF}:Option" => {'Name' => ['WINRS_CONSOLEMODE_STDIN','WINRS_SKIP_CMD_SHELL']}}}
+ h_opts = {
+ "#{NS_WSMAN_DMTF}:OptionSet" => {
+ "#{NS_WSMAN_DMTF}:Option" => [
+ { :@Name => 'WINRS_CONSOLEMODE_STDIN', :content! => consolemode },
+ { :@Name => 'WINRS_SKIP_CMD_SHELL', :content! => skipcmd }
+ ]
+ }
}
body = { "#{NS_WIN_SHELL}:Command" => "\"#{command}\"", "#{NS_WIN_SHELL}:Arguments" => arguments}
@@ -184,12 +188,7 @@ module WinRM
end
end
- # Grab the command element and unescape any single quotes - issue 69
- xml = builder.target!
- escaped_cmd = /<#{NS_WIN_SHELL}:Command>(.+)<\/#{NS_WIN_SHELL}:Command>/m.match(xml)[1]
- xml[escaped_cmd] = escaped_cmd.gsub(/'/, "'")
-
- resp_doc = send_message(xml)
+ resp_doc = send_message(builder.target!)
command_id = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:CommandId").text
if block_given?
@@ -382,9 +381,11 @@ module WinRM
def run_wql(wql)
body = { "#{NS_WSMAN_DMTF}:OptimizeEnumeration" => nil,
- "#{NS_WSMAN_DMTF}:MaxElements" => '32000',
- "#{NS_WSMAN_DMTF}:Filter" => wql,
- :attributes! => { "#{NS_WSMAN_DMTF}:Filter" => {'Dialect' => 'http://schemas.microsoft.com/wbem/wsman/1/WQL'}}
+ "#{NS_WSMAN_DMTF}:MaxElements" => '32000',
+ "#{NS_WSMAN_DMTF}:Filter" => [
+ { :@Dialect => 'http://schemas.microsoft.com/wbem/wsman/1/WQL',
+ :content! => wql }
+ ]
}
builder = Builder::XmlMarkup.new |
Hi
I was trying to enumerate directories with run_wql, and winRM crashes if the directory has a quote in his name.
Here is the query :
ASSOCIATORS OF {Win32_Directory.Name="#{path}"} WHERE AssocClass = Win32_Subdirectory ResultRole = PartComponent
Applying a similar fix as #73 in run_wql seems to fix the problem.
The text was updated successfully, but these errors were encountered: