From fd83a2b6be400be6da3e6f1c6ba33fea7cad4ee7 Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Sun, 18 Jun 2017 18:03:19 -0400 Subject: [PATCH 1/4] fixed a small courner case in the error detection - error: vs error fixed resource to use 'shellwords' module to escape the query requested chances in method architecture for testing added unit tests Fixes: #1814 Signed-off-by: Aaron Lippold --- lib/resources/postgres_session.rb | 29 +++++++++++++------- test/unit/resources/postgres_session_test.rb | 26 ++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 test/unit/resources/postgres_session_test.rb diff --git a/lib/resources/postgres_session.rb b/lib/resources/postgres_session.rb index f4bcbd482a..6033eb5cf2 100644 --- a/lib/resources/postgres_session.rb +++ b/lib/resources/postgres_session.rb @@ -4,6 +4,8 @@ # author: Christoph Hartmann # author: Aaron Lippold +require 'shellwords' + module Inspec::Resources class Lines attr_reader :output @@ -38,6 +40,7 @@ class PostgresSession < Inspec.resource(1) its('output') { should eq('') } end " + attr_reader :user, :pass, :host, :db, :escaped_query, :psql_cmd def initialize(user, pass, host = nil) @user = user || 'postgres' @@ -45,18 +48,24 @@ def initialize(user, pass, host = nil) @host = host || 'localhost' end - def query(query, db = []) + def escaped_query(query) + return warn 'no query specificed' if query.empty? || query.nil? + Shellwords.escape(query) + end + + def create_psql_cmd(query, db = []) + @db = db dbs = db.map { |x| "-d #{x}" }.join(' ') - # TODO: simple escape, must be handled by a library - # that does this securely - escaped_query = query.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$') - # run the query - cmd = inspec.command("PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c \"#{escaped_query}\"") + @escaped_query = escaped_query(query) + "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{@escaped_query}" + end + + def query(query, db = []) + @db = db + @psql_cmd = create_psql_cmd(query, @db) + cmd = inspec.command(@psql_cmd) out = cmd.stdout + "\n" + cmd.stderr - if cmd.exit_status != 0 or - out =~ /could not connect to .*/ or - out.downcase =~ /^error/ - # skip this test if the server can't run the query + if cmd.exit_status != 0 || out =~ /could not connect to .*/ || out.downcase =~ /^error:.*/ skip_resource "Can't read run query #{query.inspect} on postgres_session: #{out}" else Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}") diff --git a/test/unit/resources/postgres_session_test.rb b/test/unit/resources/postgres_session_test.rb new file mode 100644 index 0000000000..17b55b9874 --- /dev/null +++ b/test/unit/resources/postgres_session_test.rb @@ -0,0 +1,26 @@ +# encoding: utf-8 +# author: Aaron Lippold + +require 'helper' + +describe 'Inspec::Resources::PostgresSession' do + it 'verify postgres_session basic init configuration' do + resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') + _(resource.user).must_equal "myuser" + _(resource.pass).must_equal "mypass" + _(resource.host).must_equal "127.0.0.1" + end + + it 'verify postgres_session create_psql_cmd function' do + resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') + _(resource.create_psql_cmd("SELECT * FROM STUDENTS;",['testdb'])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;" + _(resource.db).must_equal ['testdb'] + end + + it 'verify postgres_session escaped_query function' do + resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') + _(resource.escaped_query("SELECT * FROM STUDENTS;")).must_equal "SELECT\\ \\*\\ FROM\\ STUDENTS\\;" + resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') + _(resource.escaped_query("SELECT current_setting('client_min_messages')")).must_equal "SELECT\\ current_setting\\(\\'client_min_messages\\'\\)" + end +end From e5101684a446fedf82f5975dabecef2bacfa3ea2 Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Sat, 24 Jun 2017 10:31:01 -0400 Subject: [PATCH 2/4] updated resource and tests with requested review changes Signed-off-by: Aaron Lippold --- lib/resources/postgres_session.rb | 32 +++++++++----------- test/unit/resources/postgres_session_test.rb | 19 +++--------- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/lib/resources/postgres_session.rb b/lib/resources/postgres_session.rb index 6033eb5cf2..02e3887668 100644 --- a/lib/resources/postgres_session.rb +++ b/lib/resources/postgres_session.rb @@ -37,10 +37,9 @@ class PostgresSession < Inspec.resource(1) # db: databse == db_user running the sql query describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do - its('output') { should eq('') } + its('output') { should eq '' } end " - attr_reader :user, :pass, :host, :db, :escaped_query, :psql_cmd def initialize(user, pass, host = nil) @user = user || 'postgres' @@ -48,22 +47,9 @@ def initialize(user, pass, host = nil) @host = host || 'localhost' end - def escaped_query(query) - return warn 'no query specificed' if query.empty? || query.nil? - Shellwords.escape(query) - end - - def create_psql_cmd(query, db = []) - @db = db - dbs = db.map { |x| "-d #{x}" }.join(' ') - @escaped_query = escaped_query(query) - "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{@escaped_query}" - end - def query(query, db = []) - @db = db - @psql_cmd = create_psql_cmd(query, @db) - cmd = inspec.command(@psql_cmd) + psql_cmd = create_psql_cmd(query, db) + cmd = inspec.command(psql_cmd) out = cmd.stdout + "\n" + cmd.stderr if cmd.exit_status != 0 || out =~ /could not connect to .*/ || out.downcase =~ /^error:.*/ skip_resource "Can't read run query #{query.inspect} on postgres_session: #{out}" @@ -71,5 +57,17 @@ def query(query, db = []) Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}") end end + + private + + def escaped_query(query) + Shellwords.escape(query) + end + + def create_psql_cmd(query, db = []) + dbs = db.map { |x| "-d #{x}" }.join(' ') + @escaped_query = escaped_query(query) + "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}" + end end end diff --git a/test/unit/resources/postgres_session_test.rb b/test/unit/resources/postgres_session_test.rb index 17b55b9874..3103cef99f 100644 --- a/test/unit/resources/postgres_session_test.rb +++ b/test/unit/resources/postgres_session_test.rb @@ -4,23 +4,12 @@ require 'helper' describe 'Inspec::Resources::PostgresSession' do - it 'verify postgres_session basic init configuration' do + it 'verify postgres_session create_psql_cmd with a basic query' do resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') - _(resource.user).must_equal "myuser" - _(resource.pass).must_equal "mypass" - _(resource.host).must_equal "127.0.0.1" + _(resource.send(:create_psql_cmd,"SELECT * FROM STUDENTS;",['testdb']).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;") end - - it 'verify postgres_session create_psql_cmd function' do - resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') - _(resource.create_psql_cmd("SELECT * FROM STUDENTS;",['testdb'])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;" - _(resource.db).must_equal ['testdb'] - end - - it 'verify postgres_session escaped_query function' do - resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') - _(resource.escaped_query("SELECT * FROM STUDENTS;")).must_equal "SELECT\\ \\*\\ FROM\\ STUDENTS\\;" + it 'verify postgres_session escaped_query with a complex query' do resource = load_resource('postgres_session','myuser','mypass','127.0.0.1') - _(resource.escaped_query("SELECT current_setting('client_min_messages')")).must_equal "SELECT\\ current_setting\\(\\'client_min_messages\\'\\)" + _(resource.send(:create_psql_cmd,"SELECT current_setting('client_min_messages')",['testdb']).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ current_setting\\(\\'client_min_messages\\'\\)") end end From 9737770ee93a0b3690ea890c86bcdf7fb5bdbcab Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Mon, 26 Jun 2017 12:13:26 -0400 Subject: [PATCH 3/4] removed unneeded call to `escaped_query` in the `create_sql_cmd`. Signed-off-by: Aaron Lippold --- lib/resources/postgres_session.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/resources/postgres_session.rb b/lib/resources/postgres_session.rb index 02e3887668..309a7ca465 100644 --- a/lib/resources/postgres_session.rb +++ b/lib/resources/postgres_session.rb @@ -66,7 +66,6 @@ def escaped_query(query) def create_psql_cmd(query, db = []) dbs = db.map { |x| "-d #{x}" }.join(' ') - @escaped_query = escaped_query(query) "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}" end end From 7d60aa74c8fe6218fd88041a9a871573e81975a9 Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Mon, 26 Jun 2017 12:14:51 -0400 Subject: [PATCH 4/4] removed license info Signed-off-by: Aaron Lippold