Skip to content

Commit 91ceb0a

Browse files
author
Kate Donaldson
committed
Merge branch 'hdabrows-enable-ssl-certificate-verification'
2 parents 9f6af46 + 030af8d commit 91ceb0a

File tree

8 files changed

+176
-8
lines changed

8 files changed

+176
-8
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ tmtags
4040

4141
# Skip the log file
4242
jenkins_api_client.log
43+
44+
# Vagrant
45+
.vagrant

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ Request Forgery exploits' to be disabled. The API will check in with the
8989
Jenkins server to determine whether crumbs are enabled or not, and use them
9090
if appropriate.
9191

92+
### SSL certificate verification
93+
94+
When connecting over HTTPS if the server's certificate is not trusted the
95+
connection will be aborted. To trust a certificate specify the `ca_file`
96+
parameter when creating the client. The value should be a path to a PEM encoded
97+
file containing the certificates.
98+
9299
### Basic Usage
93100

94101
As discussed earlier, you can either specify all the credentials and server

lib/jenkins_api_client/client.rb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class Client
6969
"ssl",
7070
"pkcs_file_path",
7171
"pass_phrase",
72+
"ca_file",
7273
"follow_redirects",
7374
"identity_file",
7475
"cookies"
@@ -96,6 +97,7 @@ class Client
9697
# @option args [Boolean] :ssl (false) indicates if Jenkins is accessible over HTTPS
9798
# @option args [String] :pkcs_file_path ("/") the optional context path for pfx or p12 binary certificate file
9899
# @option args [String] :pass_phrase password for pkcs_file_path certificate file
100+
# @option args [String] :ca_file the path to a PEM encoded file containing trusted certificates used to verify peer certificate
99101
# @option args [Boolean] :follow_redirects this argument causes the client to follow a redirect (jenkins can
100102
# return a 30x when starting a build)
101103
# @option args [Fixnum] :timeout (120) This argument sets the timeout for operations that take longer (in seconds)
@@ -265,6 +267,7 @@ def to_s
265267
def inspect
266268
"#<JenkinsApi::Client:0x#{(self.__id__ * 2).to_s(16)}" +
267269
" @ssl=#{@ssl.inspect}," +
270+
" @ca_file=#{@ca_file.inspect}," +
268271
" @log_location=#{@log_location.inspect}," +
269272
" @log_level=#{@log_level.inspect}," +
270273
" @crumbs_enabled=#{@crumbs_enabled.inspect}," +
@@ -282,13 +285,7 @@ def inspect
282285
#
283286
def get_artifact(job_name,filename)
284287
@artifact = job.find_artifact(job_name)
285-
uri = URI.parse(@artifact)
286-
http = Net::HTTP.new(uri.host, uri.port)
287-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
288-
http.use_ssl = @ssl
289-
request = Net::HTTP::Get.new(uri.request_uri)
290-
request.basic_auth(@username, @password)
291-
response = http.request(request)
288+
response = make_http_request(Net::HTTP::Get.new(@artifact))
292289
if response.code == "200"
293290
File.write(File.expand_path(filename), response.body)
294291
else
@@ -364,7 +361,9 @@ def make_http_request(request, follow_redirect = @follow_redirects)
364361
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
365362
elsif @ssl
366363
http.use_ssl = true
367-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
364+
365+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
366+
http.ca_file = @ca_file if @ca_file
368367
end
369368
http.open_timeout = @http_open_timeout
370369
http.read_timeout = @http_read_timeout

spec/func_tests/client_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,31 @@
106106
end
107107

108108
end
109+
110+
context "Given a server with a self-signed SSL certificate" do
111+
let(:creds_file) { '~/.jenkins_api_client/spec.yml' }
112+
let(:creds) {
113+
creds = YAML.load_file(File.expand_path(creds_file, __FILE__))
114+
creds[:server_port] = 8443
115+
creds[:ssl] = true
116+
creds
117+
}
118+
let(:client) { JenkinsApi::Client.new(creds) }
119+
120+
it "Should abort the connection with an SSL error" do
121+
expect {
122+
client.job.list_all
123+
}.to raise_error(OpenSSL::SSL::SSLError, /certificate verify failed/)
124+
end
125+
126+
context "Given a client configured to trust the server's certificate" do
127+
before do
128+
creds[:ca_file] = File.expand_path('~/.jenkins_api_client/server.cert.pem', __FILE__)
129+
end
130+
131+
it "Should connect without an error" do
132+
expect { client.job.list_all }.not_to raise_error
133+
end
134+
end
135+
end
109136
end

travis/default.conf

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# defaults for jenkins continuous integration server
2+
3+
# pulled in from the init script; makes things easier.
4+
NAME=jenkins
5+
6+
# location of java
7+
JAVA=/usr/bin/java
8+
9+
# arguments to pass to java
10+
JAVA_ARGS="-Djava.awt.headless=true" # Allow graphs etc. to work even when an X server is present
11+
#JAVA_ARGS="-Xmx256m"
12+
#JAVA_ARGS="-Djava.net.preferIPv4Stack=true" # make jenkins listen on IPv4 address
13+
14+
PIDFILE=/var/run/$NAME/$NAME.pid
15+
16+
# user and group to be invoked as (default to jenkins)
17+
JENKINS_USER=$NAME
18+
JENKINS_GROUP=$NAME
19+
20+
# location of the jenkins war file
21+
JENKINS_WAR=/usr/share/$NAME/$NAME.war
22+
23+
# jenkins home location
24+
JENKINS_HOME=/var/lib/$NAME
25+
26+
# set this to false if you don't want Hudson to run by itself
27+
# in this set up, you are expected to provide a servlet container
28+
# to host jenkins.
29+
RUN_STANDALONE=true
30+
31+
# log location. this may be a syslog facility.priority
32+
JENKINS_LOG=/var/log/$NAME/$NAME.log
33+
#JENKINS_LOG=daemon.info
34+
35+
# OS LIMITS SETUP
36+
# comment this out to observe /etc/security/limits.conf
37+
# this is on by default because http://github.com/jenkinsci/jenkins/commit/2fb288474e980d0e7ff9c4a3b768874835a3e92e
38+
# reported that Ubuntu's PAM configuration doesn't include pam_limits.so, and as a result the # of file
39+
# descriptors are forced to 1024 regardless of /etc/security/limits.conf
40+
MAXOPENFILES=8192
41+
42+
# set the umask to control permission bits of files that Jenkins creates.
43+
# 027 makes files read-only for group and inaccessible for others, which some security sensitive users
44+
# might consider benefitial, especially if Jenkins runs in a box that's used for multiple purposes.
45+
# Beware that 027 permission would interfere with sudo scripts that run on the master (JENKINS-25065.)
46+
#
47+
# Note also that the particularly sensitive part of $JENKINS_HOME (such as credentials) are always
48+
# written without 'others' access. So the umask values only affect job configuration, build records,
49+
# that sort of things.
50+
#
51+
# If commented out, the value from the OS is inherited, which is normally 022 (as of Ubuntu 12.04,
52+
# by default umask comes from pam_umask(8) and /etc/login.defs
53+
54+
# UMASK=027
55+
56+
# port for HTTP connector (default 8080; disable with -1)
57+
HTTP_PORT=8080
58+
59+
# port for AJP connector (disabled by default)
60+
AJP_PORT=-1
61+
62+
# servlet context, important if you want to use apache proxying
63+
PREFIX=/$NAME
64+
65+
# arguments to pass to jenkins.
66+
# --javahome=$JAVA_HOME
67+
# --httpPort=$HTTP_PORT (default 8080; disable with -1)
68+
# --httpsPort=$HTTP_PORT
69+
# --ajp13Port=$AJP_PORT
70+
# --argumentsRealm.passwd.$ADMIN_USER=[password]
71+
# --argumentsRealm.roles.$ADMIN_USER=admin
72+
# --webroot=~/.jenkins/war
73+
# --prefix=$PREFIX
74+
75+
HTTPS_PORT=8443
76+
HTTPS_CERTIFICATE=/opt/jenkins_api_client/travis/ssl/server.cert.pem
77+
HTTPS_PRIVATE_KEY=/opt/jenkins_api_client/travis/ssl/server.key.pem
78+
79+
JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT --httpsPort=$HTTPS_PORT --ajp13Port=$AJP_PORT --httpsCertificate=$HTTPS_CERTIFICATE --httpsPrivateKey=$HTTPS_PRIVATE_KEY"

travis/setup.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ sudo cp -f travis/jenkins_config.xml /var/lib/jenkins/config.xml
1212
sudo cp -f travis/hudson.model.UpdateCenter.xml /var/lib/jenkins/hudson.model.UpdateCenter.xml
1313
sudo mkdir -p /var/lib/jenkins/users/testuser
1414
sudo cp -f travis/user_config.xml /var/lib/jenkins/users/testuser/config.xml
15+
sudo cp -f travis/default.conf /etc/default/jenkins
1516
sudo service jenkins start
1617
# Jenkins takes a bit to get dressed up and become ready, so be patient...
1718
sleep 60
@@ -21,3 +22,5 @@ echo `sudo service jenkins status`
2122
# Create the credentials file used by functional tests
2223
sudo mkdir ~/.jenkins_api_client
2324
sudo cp -f travis/spec.yml ~/.jenkins_api_client/spec.yml
25+
# Create the server certificate used by functional tests
26+
sudo cp -f travis/ssl/server.cert.pem ~/.jenkins_api_client/server.cert.pem

travis/ssl/server.cert.pem

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIID4DCCAsigAwIBAgIJALVj1GL6SP+KMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV
3+
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRswGQYDVQQKExJKZW5raW5zIEFQ
4+
SSBDbGllbnQxEjAQBgNVBAMTCTEyNy4wLjAuMTAeFw0xNjAyMTUyMjE2MjBaFw00
5+
MzA3MDIyMjE2MjBaMFMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl
6+
MRswGQYDVQQKExJKZW5raW5zIEFQSSBDbGllbnQxEjAQBgNVBAMTCTEyNy4wLjAu
7+
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANmWHldmymeZf2VjQqzG
8+
2ENomJ2NEbdUXCL3uArzmK3Mqb2SyIbJokX8/2eFVbNQRoU/H9Pz84Q9kLfrcLQ2
9+
UO+Mr++/v7yZJR901Z5n5sX7k94Pa1aXcFMhF5jnzQn0GDnfzwAmavVM7QKpx+x6
10+
9a5NGGzMDWoAn0TLT/TTwGRCDtGQdMuKBkiVi4fjrrP68Ppm7I2c4IXnZvSb87dm
11+
1ZSLVIUt5AIeqXVMF4zW6Pe4AI0XHs4EZBPMuiG5SpBia23+mSsyrSvdJ+VOMIBA
12+
Jhd8m1kBe2jZ913obIrYGn8KFIgHmTkwZDysqFt5RYZQ/gQA736FmAiw7/Pb/W4a
13+
HPkCAwEAAaOBtjCBszAdBgNVHQ4EFgQU9fkWUyLVRLwg7d5AleAcp9jlOBkwgYMG
14+
A1UdIwR8MHqAFPX5FlMi1US8IO3eQJXgHKfY5TgZoVekVTBTMQswCQYDVQQGEwJB
15+
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEbMBkGA1UEChMSSmVua2lucyBBUEkgQ2xp
16+
ZW50MRIwEAYDVQQDEwkxMjcuMC4wLjGCCQC1Y9Ri+kj/ijAMBgNVHRMEBTADAQH/
17+
MA0GCSqGSIb3DQEBBQUAA4IBAQBC31OuFUQ25pCNMCNIj7KEJC/Y5x1ui0wZyB6r
18+
k+SkgFm1NIeCKM/LI/MLkbaSErFXmh9QRmYrNfWif8P3TrEAUbtMhQFmJ2bFdOqK
19+
CP/F0qMqBGOBk1PyU78ZDTyUmfF1XiAwNTw76KopPvILKlpNDMYbCDRAGxmagbeF
20+
SteyfoqU27CpGCNSIu31mq2+p5onDbti4c+qkO1xGGtG2HYoqY6heWmw9HkOKxXN
21+
ourNqAvcTK3je9sOqDLLLIqDntBaiz2KTXD2oSqHw3+TrQ/NcSjdWdb9FTueCy3L
22+
eSy6nflY+hAviQjJvqjiOzPB/5F5jBkRk+B3IcSOwriF3ACJ
23+
-----END CERTIFICATE-----

travis/ssl/server.key.pem

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpAIBAAKCAQEA2ZYeV2bKZ5l/ZWNCrMbYQ2iYnY0Rt1RcIve4CvOYrcypvZLI
3+
hsmiRfz/Z4VVs1BGhT8f0/PzhD2Qt+twtDZQ74yv77+/vJklH3TVnmfmxfuT3g9r
4+
VpdwUyEXmOfNCfQYOd/PACZq9UztAqnH7Hr1rk0YbMwNagCfRMtP9NPAZEIO0ZB0
5+
y4oGSJWLh+Ous/rw+mbsjZzghedm9Jvzt2bVlItUhS3kAh6pdUwXjNbo97gAjRce
6+
zgRkE8y6IblKkGJrbf6ZKzKtK90n5U4wgEAmF3ybWQF7aNn3XehsitgafwoUiAeZ
7+
OTBkPKyoW3lFhlD+BADvfoWYCLDv89v9bhoc+QIDAQABAoIBAE0zg151fTlW8Cm0
8+
F1MgVllMgmHcTL3kc7CAfk98cN6xsEQwEXApmKcGhkRfvbGauPrME+nrM6rnATMQ
9+
mXOHlh34p/AD8+7h05ceqDDFIs96XNO8WtRldRg5tJqvHEP81J+sNlESUH7qpWl9
10+
fg787bDDb/giSlwjDl+lV6BBhZDMa+IH0Z9v5BFVRWJKx+VgvfGl4PIJB49lxAGN
11+
Lo9p8qqLB8Y8aADBX9VXf4iZpsSDnI77ZpMPzjFz+Z64uHVmcgjH6CsQ6TmcpadH
12+
o6U5aM6HTxyv7JB/nf5liV77xb1dNoI0DhpNfD0TIfEK3PRCYNWpMUU+pha9Qk86
13+
vbbAuoUCgYEA7pCIo92kGgZOjnn1x9nBtlgnoQRGbBuT+YBAok/WKDVylbt91fHy
14+
jsBENsFShY6rNpeMkp06QV/scHo/8fiEwYtKXoVJ1T0MTxto90R3+5lMqFpj7z3C
15+
+dX9Bt+Xg9EyOsITgvXplgA1Dp/635tWk0UGJ0wddzUQ3SJMWjeu/Q8CgYEA6X0W
16+
+AJ1Oc5g2j9qGJGe+Ucw5jrDrssKDpKWFaZ9KCRjIb9voC1gOh6x12+b9Itn6Y92
17+
jz7/muZRrAl0DHC6j6MG1SoTYV4cTUd5wyYgPYSJ1VXi0MNH421680xcfUHMUHXV
18+
FNEPLjWasrXs2AGZRQRAAmuiV4cbShdQztN71XcCgYEA47POx+FwlWp5pqIgBs4A
19+
iCPiR1zGPr+f4KAakRH0zdId+W7Ir+FMbBZ1xXGGa3X+U5AZG4O4q9d73OvChxl2
20+
1Sk3JbrA+yhWzFbUPFb80ofC1FnaUuq3ZDFsXhgiDS4qbEz7xJ8lggfWnIv0L2Oc
21+
IdrbAb0zzqk23Gq1R9MoUd8CgYEAus2Sn8/Pm/UKtfIAXzG6X7PeYoRnZKQbIreS
22+
jjXKcmBSU4DGvP8wuq8uF6+6tXcHJuzZrRd5BqP4ecyCZSWXjS2gXNEx+jeCKy3h
23+
NAl/x9gPMnhpZB6omENSF+9jG++VmFX9qY7tN0o5v3sfx13YE0ioMYeNtbtpUOjA
24+
hQjcTVcCgYAEkYU/9eQja4S9Vytq6AZWOTvVZZoOGdtPeD5cn06HaG6dZ7tpOCHF
25+
Mm67/72N8+lYsFX50QkW62ZlD/J8QV6K1ayJcS6PxF71CgUBB7KYdys0QZisVmBX
26+
nkkyHEHpRybK3KDuUtq1FTYcmtEBBOKtJOTJXEyEMEFZgFwTCdmRjw==
27+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)