mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2025-12-16 01:02:34 +00:00
140 lines
4.0 KiB
Ruby
140 lines
4.0 KiB
Ruby
require "socket"
|
|
require "openssl"
|
|
require "ircparser"
|
|
|
|
require_relative "irc_profile"
|
|
|
|
class W3DHub
|
|
class Asterisk
|
|
class IRCClient
|
|
TAG = "IRCClient"
|
|
|
|
class SSL
|
|
def self.default_context
|
|
verify_peer_and_hostname
|
|
end
|
|
|
|
def self.verify_peer_and_hostname
|
|
verify_peer.tap do |context|
|
|
context.verify_hostname = true
|
|
end
|
|
end
|
|
|
|
def self.verify_peer
|
|
no_verify.tap do |context|
|
|
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
context.cert_store = OpenSSL::X509::Store.new
|
|
if (ca_file = W3DHub.ca_bundle_path)
|
|
context.cert_store.add_file(ca_file)
|
|
else
|
|
context.cert_store.set_default_paths
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.verify_hostname_only
|
|
no_verify.tap do |context|
|
|
context.verify_hostname = true
|
|
end
|
|
end
|
|
|
|
def self.no_verify
|
|
OpenSSL::SSL::SSLContext.new
|
|
end
|
|
end
|
|
|
|
attr_reader :status
|
|
|
|
def initialize(irc_profile)
|
|
@irc_profile = irc_profile
|
|
|
|
ssl_context = false
|
|
|
|
if irc_profile.server_ssl
|
|
ssl_context = irc_profile.server_verify_ssl ? SSL.default_context : SSL.no_verify
|
|
end
|
|
|
|
socket = dial(
|
|
@irc_profile.server_hostname,
|
|
@irc_profile.server_port,
|
|
ssl_context: ssl_context
|
|
)
|
|
|
|
authenticate_with_brenbot!(socket)
|
|
ensure
|
|
close_socket(socket)
|
|
end
|
|
|
|
def dial(hostname, port = 6697, local_host: nil, local_port: nil, ssl_context: SSL.default_context)
|
|
Socket.tcp(hostname, port, local_host, local_port).then do |socket|
|
|
if ssl_context
|
|
@ssl_socket = true
|
|
|
|
ssl_context = SSL.send(ssl_context) if ssl_context.is_a?(Symbol)
|
|
|
|
OpenSSL::SSL::SSLSocket.new(socket, ssl_context).tap do |ssl_socket|
|
|
ssl_socket.hostname = hostname
|
|
ssl_socket.connect
|
|
end
|
|
else
|
|
socket
|
|
end
|
|
end
|
|
rescue StandardError => e
|
|
logger.error(TAG) { e }
|
|
logger.error(TAG) { e.backtrace }
|
|
end
|
|
|
|
def authenticate_with_brenbot!(socket)
|
|
username = @irc_profile.username.empty? ? @irc_profile.nickname : @irc_profile.username
|
|
|
|
pass = IRCParser::Message.new(command: "PASS", parameters: [Base64.strict_decode64(@irc_profile.password)]) unless @irc_profile.password.empty?
|
|
user = IRCParser::Message.new(command: "USER", parameters: [username, "0", "*", ":#{@irc_profile.nickname}"])
|
|
nick = IRCParser::Message.new(command: "NICK", parameters: [@irc_profile.nickname])
|
|
|
|
socket.puts(pass)
|
|
socket.puts(user)
|
|
socket.puts(nick)
|
|
|
|
socket.flush
|
|
|
|
until socket.closed?
|
|
raw = socket.gets
|
|
next if raw.to_s.empty?
|
|
|
|
msg = IRCParser::Message.parse(raw)
|
|
|
|
if msg.command == "PING"
|
|
pong = IRCParser::Message.new(command: "PONG", parameters: [msg.parameters.first.sub("\r\n", "")])
|
|
socket.puts("#{pong}")
|
|
socket.flush
|
|
elsif msg.command == "001" && msg.parameters.join.include?("#{@irc_profile.nickname}!#{@irc_profile.username.split("/").first}")
|
|
pm = IRCParser::Message.new(command: "PRIVMSG", parameters: [@irc_profile.bot_username, "!auth #{@irc_profile.bot_auth_username} #{Base64.strict_decode64(@irc_profile.bot_auth_password)}"])
|
|
socket.puts(pm)
|
|
|
|
quit = IRCParser::Message.new(command: "QUIT", parameters: ["Quiting from an Asterisk"])
|
|
socket.puts(quit)
|
|
socket.flush
|
|
|
|
sleep 15
|
|
close_socket(socket)
|
|
elsif msg.command == "ERROR"
|
|
close_socket(socket)
|
|
end
|
|
end
|
|
end
|
|
|
|
def close_socket(socket)
|
|
return unless socket
|
|
|
|
if @ssl_socket
|
|
socket.sync_close = true
|
|
socket.sysclose
|
|
else
|
|
socket.close
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|