diff --git a/lib/asterisk/irc_client.rb b/lib/asterisk/irc_client.rb new file mode 100644 index 0000000..4aa8cfc --- /dev/null +++ b/lib/asterisk/irc_client.rb @@ -0,0 +1,111 @@ +require "socket" +require "openssl" +require "ircparser" + +require_relative "irc_profile" + +class W3DHub + class Asterisk + class 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.tap(&:set_default_paths) + 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 = nil) + @irc_profile = irc_profile + + socket = dial( + @irc_profile.server_hostname, + @irc_profile.server_port, + ssl_context: irc_profile.server_ssl ? irc_profile.server_verify_ssl ? SSL.default_context : SSL.no_verify : false + ) + + authenticate_with_brenbot!(socket) + ensure + socket&.close + 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_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 + end + + def authenticate_with_brenbot!(socket) + pp @irc_profile, "#{@irc_profile.nickname}!#{@irc_profile.username.split("/").first}" + # exit + + pass = IRCParser::Message.new(command: "PASS", parameters: [@irc_profile.password]) + user = IRCParser::Message.new(command: "USER", parameters: [@irc_profile.username, "0", "*", ":#{@irc_profile.nickname}"]) + nick = IRCParser::Message.new(command: "NICK", parameters: [@irc_profile.nickname]) + + socket.puts(pass) + socket.puts(user) + socket.puts(nick) + + pp socket + 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.server_bot, "!auth #{@irc_profile.bot_auth_username} password"]) + socket.puts(pm) + + quit = IRCParser::Message.new(command: "QUIT", parameters: ["Quiting from an Asterisk"]) + socket.puts(quit) + socket.flush + + socket.close + end + end + end + end + end +end + +W3DHub::Asterisk::IRCClient.new