@@ -12,7 +12,10 @@ class Teamcity < HTTP
1212 module Crypto
1313 # https://github.com/openssl/openssl/blob/a08a145d4a7e663dd1e973f06a56e983a5e916f7/crypto/rsa/rsa_pk1.c#L125
1414 # https://datatracker.ietf.org/doc/html/rfc3447#section-7.2.1
15- def self . pkcs1pad2 ( text , n )
15+ def pkcs1pad2 ( text , n )
16+ raise ArgumentError , "Cannot pad the text: '#{ text . inspect } '" unless text . is_a? ( String )
17+ raise ArgumentError , "Invalid message length: '#{ n . inspect } '" unless n . is_a? ( Integer )
18+
1619 if n < text . length + 11
1720 raise ArgumentError , 'Message too long'
1821 end
@@ -49,7 +52,7 @@ def self.pkcs1pad2(text, n)
4952 # @param [String] exponent
5053 # @param [String] text
5154 # @return [String]
52- def self . rsa_encrypt ( modulus , exponent , text )
55+ def rsa_encrypt ( modulus , exponent , text )
5356 n = modulus . to_i ( 16 )
5457 e = exponent . to_i ( 16 )
5558
@@ -60,19 +63,26 @@ def self.rsa_encrypt(modulus, exponent, text)
6063 h . length . odd? ? h . prepend ( '0' ) : h
6164 end
6265
63- def self . two_byte_chars? ( str )
66+ def two_byte_chars? ( str )
67+ raise ArgumentError , 'Unable to check char size for non-string value' unless str . is_a? ( String )
68+
6469 str . bytesize > str . length
6570 end
6671
67- def self . max_data_size ( str )
72+ def max_data_size ( str )
73+ raise ArgumentError , 'Unable to get maximum data size for non-string value' unless str . is_a? ( String )
74+
6875 # Taken from TeamCity's login page JavaScript sources.
6976 two_byte_chars? ( str ) ? 58 : 116
7077 end
7178
7279 # @param [String] text The text to encrypt.
7380 # @param [String] public_key The hex representation of the public key to use.
7481 # @return [String] A string blob.
75- def self . encrypt_data ( text , public_key )
82+ def encrypt_data ( text , public_key )
83+ raise ArgumentError , "Cannot encrypt the provided data: '#{ text . inspect } '" unless text . is_a? ( String )
84+ raise ArgumentError , "Cannot encrypt data with the public key: '#{ public_key . inspect } '" unless public_key . is_a? ( String )
85+
7686 exponent = '10001'
7787 e = [ ]
7888 g = max_data_size ( text )
@@ -92,6 +102,7 @@ def self.encrypt_data(text, public_key)
92102 end
93103 end
94104
105+ include Crypto
95106
96107 DEFAULT_PORT = 8111
97108 LIKELY_PORTS = [ 8111 ]
@@ -151,7 +162,7 @@ def create_login_request(username, password, public_key)
151162 _remember : '' ,
152163 submitLogin : 'Log in' ,
153164 publicKey : public_key ,
154- encryptedPassword : Crypto . encrypt_data ( password , public_key )
165+ encryptedPassword : encrypt_data ( password , public_key )
155166 }
156167 }
157168 end
@@ -205,7 +216,11 @@ def logout_with_headers(headers)
205216 'headers' => headers
206217 }
207218
208- send_request ( logout_params )
219+ begin
220+ send_request ( logout_params )
221+ rescue Rex ::ConnectionError => _e
222+ # ignore
223+ end
209224 end
210225
211226 def attempt_login ( credential )
0 commit comments