summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/workers/irker_worker.rb18
-rw-r--r--doc/api/status_checks.md1
-rw-r--r--spec/models/integrations/irker_spec.rb18
-rw-r--r--spec/support/helpers/dns_helpers.rb10
-rw-r--r--spec/workers/irker_worker_spec.rb15
5 files changed, 52 insertions, 10 deletions
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index 3097a9fbc03..4f51bb69b8c 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -2,6 +2,7 @@
require 'json'
require 'socket'
+require 'resolv'
class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
@@ -43,9 +44,18 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
private
def start_connection(irker_server, irker_port)
+ ip_address = Resolv.getaddress(irker_server)
+ # handle IP6 addresses
+ domain = Resolv::IPv6::Regex.match?(ip_address) ? "[#{ip_address}]" : ip_address
+
begin
- @socket = TCPSocket.new irker_server, irker_port
- rescue Errno::ECONNREFUSED => e
+ Gitlab::UrlBlocker.validate!(
+ "irc://#{domain}",
+ allow_localhost: allow_local_requests?,
+ allow_local_network: allow_local_requests?,
+ schemes: ['irc'])
+ @socket = TCPSocket.new ip_address, irker_port
+ rescue Errno::ECONNREFUSED, Gitlab::UrlBlocker::BlockedUrlError => e
logger.fatal "Can't connect to Irker daemon: #{e}"
return false
end
@@ -53,6 +63,10 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
true
end
+ def allow_local_requests?
+ Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ end
+
def send_to_irker(privmsg)
to_send = { to: @channels, privmsg: privmsg }
diff --git a/doc/api/status_checks.md b/doc/api/status_checks.md
index c0dba71bdc5..7de188ad185 100644
--- a/doc/api/status_checks.md
+++ b/doc/api/status_checks.md
@@ -45,6 +45,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/status_checks
## Set status of an external status check
For a single merge request, use the API to inform GitLab that a merge request has passed a check by an external service.
+To set the status of an external check, the personal access token used must belong to a user with at least the developer role on the target project of the merge request.
```plaintext
POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
diff --git a/spec/models/integrations/irker_spec.rb b/spec/models/integrations/irker_spec.rb
index 8b207e8b43e..8aea2c26dc5 100644
--- a/spec/models/integrations/irker_spec.rb
+++ b/spec/models/integrations/irker_spec.rb
@@ -2,6 +2,7 @@
require 'spec_helper'
require 'socket'
+require 'timeout'
require 'json'
RSpec.describe Integrations::Irker do
@@ -37,6 +38,7 @@ RSpec.describe Integrations::Irker do
before do
@irker_server = TCPServer.new 'localhost', 0
+ allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true)
allow(irker).to receive_messages(
active: true,
project: project,
@@ -58,13 +60,17 @@ RSpec.describe Integrations::Irker do
irker.execute(sample_data)
conn = @irker_server.accept
- conn.each_line do |line|
- msg = Gitlab::Json.parse(line.chomp("\n"))
- expect(msg.keys).to match_array(%w(to privmsg))
- expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits",
- "irc://test.net/#test"])
+
+ Timeout.timeout(5) do
+ conn.each_line do |line|
+ msg = Gitlab::Json.parse(line.chomp("\n"))
+ expect(msg.keys).to match_array(%w(to privmsg))
+ expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits",
+ "irc://test.net/#test"])
+ end
end
- conn.close
+ ensure
+ conn.close if conn
end
end
end
diff --git a/spec/support/helpers/dns_helpers.rb b/spec/support/helpers/dns_helpers.rb
index ba32ccbb6f1..b941e7c4808 100644
--- a/spec/support/helpers/dns_helpers.rb
+++ b/spec/support/helpers/dns_helpers.rb
@@ -23,7 +23,15 @@ module DnsHelpers
end
def permit_local_dns!
- local_addresses = /\A(127|10)\.0\.0\.\d{1,3}|(192\.168|172\.16)\.\d{1,3}\.\d{1,3}|0\.0\.0\.0|localhost\z/i
+ local_addresses = %r{
+ \A
+ ::1? | # IPV6
+ (127|10)\.0\.0\.\d{1,3} | # 127.0.0.x or 10.0.0.x local network
+ (192\.168|172\.16)\.\d{1,3}\.\d{1,3} | # 192.168.x.x or 172.16.x.x local network
+ 0\.0\.0\.0 | # loopback
+ localhost
+ \z
+ }xi
allow(Addrinfo).to receive(:getaddrinfo).with(local_addresses, anything, nil, :STREAM).and_call_original
allow(Addrinfo).to receive(:getaddrinfo).with(local_addresses, anything, nil, :STREAM, anything, anything, any_args).and_call_original
end
diff --git a/spec/workers/irker_worker_spec.rb b/spec/workers/irker_worker_spec.rb
index aa1f1d2fe1d..c3d40ad2783 100644
--- a/spec/workers/irker_worker_spec.rb
+++ b/spec/workers/irker_worker_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe IrkerWorker, '#perform' do
channels,
false,
push_data,
- server_settings
+ HashWithIndifferentAccess.new(server_settings)
]
end
@@ -35,6 +35,14 @@ RSpec.describe IrkerWorker, '#perform' do
allow(tcp_socket).to receive(:close).and_return(true)
end
+ context 'local requests are not allowed' do
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(false)
+ end
+
+ it { expect(worker.perform(*arguments)).to be_falsey }
+ end
+
context 'connection fails' do
before do
allow(TCPSocket).to receive(:new).and_raise(Errno::ECONNREFUSED.new('test'))
@@ -44,6 +52,11 @@ RSpec.describe IrkerWorker, '#perform' do
end
context 'connection successful' do
+ before do
+ allow(Gitlab::CurrentSettings)
+ .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true)
+ end
+
it { expect(subject.perform(*arguments)).to be_truthy }
context 'new branch' do