Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Update password symbol for user creation #262
* Add support for td-client-ruby 2.x.x #267
* Add SSL certificate options (--insecure, --ssl-ca-file) for proxy environments
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is for current release, please remove. We will add the changelog during release process


== 2023-03-18 version 0.17.1

Expand Down
26 changes: 24 additions & 2 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,32 @@ These are the available hooks:

$ TD_TOOLBELT_UPDATE_ROOT="http://toolbelt.treasuredata.com"

* Specify an alternative endpoint to use updating the JAR file (default: https://repo1.maven.org):
=== SSL Options

$ TD_TOOLBELT_JARUPDATE_ROOT="https://repo1.maven.org"
Comment on lines -147 to -149
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to remove these lines?

The CLI supports SSL certificate verification options to help with proxy environments:

* Disable SSL certificate verification:

$ td --insecure ...

* Use a custom CA certificate file:

$ td --ssl-ca-file /path/to/ca.crt ...

* Configure in ~/.td/td.conf:

[ssl]
verify = false
ca_file = /path/to/ca.crt

* Set environment variables:

$ TD_SSL_VERIFY=false td ...
$ TD_SSL_CA_FILE=/path/to/ca.crt td ...

The priority order is: CLI options > environment variables > config file > default.

Note: These options do not apply to the 'td workflow' command, which uses its own HTTP client.

= Copyright

Expand Down
8 changes: 8 additions & 0 deletions lib/td/command/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ def get_client(opts={})
opts[:retry_post_requests] = Config.retry_post_requests
end

# SSL verification options
ssl_option = Config.ssl_option
if ssl_option == false || (ssl_option.is_a?(String) && ssl_option.downcase == 'false')
opts[:verify] = false
elsif ssl_option.is_a?(String) && ssl_option.downcase != 'false'
opts[:verify] = ssl_option
end

# apikey is mandatory
apikey = Config.apikey
raise ConfigError, "Account is not configured." unless apikey
Expand Down
12 changes: 3 additions & 9 deletions lib/td/command/import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,15 +306,9 @@ def set_sysprops_endpoint(sysprops)

# generic URI
host, port = endpoint.split(':', 2)
port = port.to_i
# Config.secure = false is the --insecure option was used
if Config.secure
port = 443 if port == 0
ssl = true
else
port = 80 if port == 0
ssl = false
end
port = port.to_i == 0 ? 443 : port.to_i
ssl = true

end

sysprops << "-Dtd.api.server.scheme=#{ssl ? 'https' : 'http'}://"
Expand Down
23 changes: 19 additions & 4 deletions lib/td/command/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def run(argv=ARGV)
endpoint = @endpoint
import_endpoint = @import_endpoint || @endpoint
insecure = nil
ssl_ca_file = nil
$verbose = false
#$debug = false
retry_post_requests = false
Expand All @@ -104,16 +105,24 @@ def run(argv=ARGV)
import_endpoint = e
}

op.on('--insecure', "Insecure access: disable SSL (enabled by default)") {|b|
insecure = true
op.on('--ssl-verify VALUE', "SSL verification: 'false' to disable, or path to CA certificate file (default: true)") {|s|
require 'td/command/common'
if s.downcase == 'false'
insecure = true
else
unless File.exist?(s)
raise ParameterConfigurationError, "CA certification file not found: #{s}"
end
ssl_ca_file = s
end
}

op.on('-v', '--verbose', "verbose mode", TrueClass) {|b|
$verbose = b
}

#op.on('-d', '--debug', "debug mode", TrueClass) {|b|
# $debug = b
# $debug = b
#}

op.on('-h', '--help', "show help") {
Expand Down Expand Up @@ -155,7 +164,13 @@ def run(argv=ARGV)
Config.cl_import_endpoint = true
end
if insecure
Config.secure = false
Config.ssl_option = false
Config.cl_ssl_option = true
$stderr.puts "Warning: --insecure option disables SSL certificate verification, which is not recommended for production use."
end
if ssl_ca_file
Config.ssl_option = ssl_ca_file
Config.cl_ssl_option = true
end
if retry_post_requests
Config.retry_post_requests = true
Expand Down
82 changes: 82 additions & 0 deletions lib/td/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Config
@@cl_import_endpoint = false # flag to indicate whether an endpoint has been provided through the command-line option
@@secure = true
@@retry_post_requests = false
@@ssl_option = ENV['TD_SSL_VERIFY'] || ENV['TD_SSL_CA_FILE'] || true
@@cl_ssl_option = false # flag to indicate whether ssl option has been provided through the command-line

def initialize
@path = nil
Expand Down Expand Up @@ -194,12 +196,92 @@ def self.workflow_endpoint
end
end

def self.ssl_option
if @@cl_ssl_option
return @@ssl_option
end

begin
conf = read
if conf['ssl.verify']
return conf['ssl.verify'].downcase == 'false' ? false : conf['ssl.verify']
elsif conf['ssl.ca_file']
return conf['ssl.ca_file']
end
rescue ConfigNotFoundError
end

return @@ssl_option
end

def self.ssl_option=(option)
@@ssl_option = option
end

def self.cl_ssl_option
@@cl_ssl_option
end

def self.cl_ssl_option=(flag)
@@cl_ssl_option = flag
end

# Compatibility methods for existing code
def self.ssl_verify
option = ssl_option
return false if option == false || (option.is_a?(String) && option.downcase == 'false')
return true if option == true || option.nil?
return true # if it's a file path, verification is enabled
end

def self.ssl_verify=(verify)
self.ssl_option = verify
end

def self.ssl_ca_file
option = ssl_option
return option if option.is_a?(String) && option.downcase != 'false' && File.exist?(option)
return nil
end

def self.ssl_ca_file=(ca_file)
self.ssl_option = ca_file
end

def self.cl_ssl_verify
@@cl_ssl_option
end

def self.cl_ssl_verify=(flag)
@@cl_ssl_option = flag
end

def self.cl_ssl_ca_file
@@cl_ssl_option
end

def self.cl_ssl_ca_file=(flag)
@@cl_ssl_option = flag
end

# renders the apikey and endpoint options as a string for the helper commands
def self.cl_options_string
require 'shellwords'

string = ""
string += "-k #{@@apikey} " if @@cl_apikey
string += "-e #{@@endpoint} " if @@cl_endpoint
string += "--import-endpoint #{@@import_endpoint} " if @@cl_import_endpoint

# Handle simplified SSL option
if @@cl_ssl_option && @@ssl_option
if @@ssl_option == false || (@@ssl_option.is_a?(String) && @@ssl_option.downcase == 'false')
string += "--ssl-verify false "
elsif @@ssl_option.is_a?(String)
string += "--ssl-verify #{Shellwords.escape(@@ssl_option)} "
end
end

string
end

Expand Down
Loading