From f0dfc828031a2a773e85d29dc89d9f73ee2dd42e Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Fri, 19 Apr 2019 06:26:41 -0500 Subject: [PATCH] Add nuuo client request rex and spec --- lib/rex/proto/nuuo/client_request.rb | 30 +--- .../lib/rex/proto/nuuo/client_request_spec.rb | 135 ++++++++++++++++++ 2 files changed, 138 insertions(+), 27 deletions(-) create mode 100644 spec/lib/rex/proto/nuuo/client_request_spec.rb diff --git a/lib/rex/proto/nuuo/client_request.rb b/lib/rex/proto/nuuo/client_request.rb index 79d2e5da5a..df7ebc9c2a 100644 --- a/lib/rex/proto/nuuo/client_request.rb +++ b/lib/rex/proto/nuuo/client_request.rb @@ -12,9 +12,6 @@ class ClientRequest # 'method' => 'USERLOGIN', 'server_version' => nil, - #'username' => nil, - #'password' => nil, - #'timezone' => nil, 'data' => nil, 'headers' => nil, 'proto' => 'NUCM', @@ -22,9 +19,6 @@ class ClientRequest 'file_name' => nil, 'file_type' => nil, 'user_session' => nil, - #'device_id' => nil, - #'source_server' => nil, - #'last_one' => nil, } attr_reader :opts @@ -43,12 +37,6 @@ class ClientRequest # Set headers req << set_header('server_version', 'Version') - #req << set_header('username', 'Username') - #req << set_length_header('password', 'Password-Length') - #req << set_length_header('timezone', 'TimeZone-Length') - req << set_header('file_name', 'FileName') - req << set_header('file_type', 'FileType') - #req << set_length_header('data', 'Content-Length') req << set_header('user_session', 'User-Session-No') # Add any additional headers @@ -70,24 +58,12 @@ class ClientRequest # Return header # def set_header(key, name) - if opts['headers'] && opts['headers'].keys.map(&:downcase).include?(name.downcase) - return '' + unless opts['headers'] && opts['headers'].keys.map(&:downcase).include?(name.downcase) + return opts[key] ? set_formatted_header(name, opts[key]) : '' end - - opts[key] ? set_formatted_header(name, opts[key]) : '' + '' end - # Return length header - def set_length_header(key, name) - if opts['headers'] && opts['headers'].keys.map(&:downcase).include?(name) - return '' - end - - return '' unless opts[key] - set_formatted_header(name, opts[key].to_s.length) - end - - # # Return additional headers # def set_extra_headers diff --git a/spec/lib/rex/proto/nuuo/client_request_spec.rb b/spec/lib/rex/proto/nuuo/client_request_spec.rb new file mode 100644 index 0000000000..9d27676054 --- /dev/null +++ b/spec/lib/rex/proto/nuuo/client_request_spec.rb @@ -0,0 +1,135 @@ +# -*- coding:binary -*- +require 'rex/proto/nuuo/client_request' + +RSpec.describe Rex::Proto::Nuuo::ClientRequest do + subject(:client_request) { + opts = { + 'user_session' => user_session, + 'headers' => headers_hash, + 'data' => data + } + described_class.new(opts) + } + let(:user_session) {nil} + let(:headers_hash) {{}} + let(:data) {nil} + + describe '#to_s' do + context 'given no additional options' do + it 'returns a USERLOGIN request' do + expect(client_request.to_s).to eq("USERLOGIN NUCM/1.0\r\n\r\n") + end + end + + context 'given a headers hash' do + let(:headers_hash) {{ + 'TestHeader' => 'TestValue', + 'TestHeader1' => 'TestValue1' + }} + it 'dumps the headers after the method line' do + expect(client_request.to_s).to eq("USERLOGIN NUCM/1.0\r\nTestHeader: TestValue\r\nTestHeader1: TestValue1\r\n\r\n") + end + end + + context 'given a user_session and User-Session-No header' do + let(:user_session) {'0'} + let(:headers_hash) {{'User-Session-No' => '1'}} + + it 'prefers the User-Session-No in the headers hash' do + expect(client_request.to_s).to eq("USERLOGIN NUCM/1.0\r\nUser-Session-No: 1\r\n\r\n") + end + end + end + + describe '#set_method' do + it 'returns the method variable' do + expect(client_request.set_method).to eq('USERLOGIN') + end + end + + describe '#set_proto_version' do + it 'returns the protocol and version separated by /' do + expect(client_request.set_proto_version).to eq("NUCM/1.0\r\n") + end + end + + + describe '#set_header' do + + context 'given no user session number' do + let(:user_session) {nil} + + it 'returns an empty header' do + expect(client_request.set_header('user_session', 'User-Session-No')).to eq('') + end + end + + context 'given user session number' do + let(:user_session) {'987'} + + it 'returns a User-Session-No header' do + expect(client_request.set_header('user_session', 'User-Session-No')).to eq("User-Session-No: 987\r\n") + end + end + + context 'given a nonexistent key' do + it 'returns an empty header' do + expect(client_request.set_header('DoesNotExist', 'DoesNotExist')).to eq('') + end + end + + context 'given a key specified in the headers hash' do + let(:user_session) {'987'} + let(:headers_hash) {{'User-Session-No' => '1000'}} + + it 'returns an empty header' do + expect(client_request.set_header('user_session', 'User-Session-No')).to eq('') + end + end + + end + + describe '#set_extra_headers' do + context 'given an empty headers hash' do + it 'returns an empty string' do + expect(client_request.set_extra_headers).to eq('') + end + end + + context 'given a headers hash' do + let(:headers_hash) {{ + 'Header' => 'Value', + 'Another' => 'One' + }} + + it 'returns formatted headers' do + expect(client_request.set_extra_headers).to eq("Header: Value\r\nAnother: One\r\n") + end + end + end + + describe '#set_body' do + context 'given an empty body variable' do + it 'returns \r\n' do + expect(client_request.set_body).to eq("\r\n") + end + end + + context 'given body content' do + let(:data) {"test data"} + + it 'returns \r\n followed by the body content' do + expect(client_request.set_body).to eq("\r\ntest data") + end + end + end + + describe '#set_formatted_header' do + let(:name) {'HeaderName'} + let(:value) {'HeaderValue'} + + it 'creates a request header' do + expect(subject.set_formatted_header(name, value)).to eq("HeaderName: HeaderValue\r\n") + end + end +end