Created
December 2, 2014 14:18
-
-
Save bararchy/589e3b81d3e6b47a06a6 to your computer and use it in GitHub Desktop.
Try 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'securerandom' | |
require 'thread' | |
require 'prime' | |
require 'openssl' | |
require 'socket' | |
require 'zlib' | |
require 'base64' | |
class IRC_RSA | |
def initialize | |
print "\r\nGenerating keys.." | |
# Generate private and public key | |
@priv = OpenSSL::PKey::RSA.new(4096) | |
@pub = @priv.public_key | |
end | |
def loop | |
connect | |
create_chan_nick | |
while true | |
begin | |
data = gets.chomp | |
check_write_special(data) | |
rescue Errno::EPIPE, IOError | |
puts "\r\nServer closed connection" | |
exit 0 | |
end | |
end | |
end | |
private | |
def connect | |
# Connect to Free_node | |
@sock = TCPSocket.new("irc.freenode.net", 6667) | |
# Fork and stream data | |
fork do | |
while true | |
begin | |
check_read_special(@sock.readpartial(1024)) | |
rescue IO::WaitReadable | |
retry | |
rescue EOFError, IOError, Errno::ECONNRESET, Errno::EPIPE | |
puts "Server closed socket, killing connection" | |
exit 0 | |
end | |
end | |
exit 0 | |
end | |
end | |
def create_chan_nick | |
@nick = "super#{SecureRandom.hex(5)}" | |
puts "\r\nLogging in to IRC" | |
sleep 5 | |
@sock.write "USER #{@nick} . . :real name\r\n" | |
@sock.write "NICK #{@nick}\r\n" | |
puts "\r\nDo we (h)ost or (j)oin ?" | |
@manager = gets.chomp.downcase | |
if @manager == 'h' | |
sleep 2 | |
@channel = SecureRandom.hex(5) | |
@sock.write "JOIN ##{@channel}\r\n" | |
puts "\r\nTell your partner to join ##{@channel} on freenode network" | |
key_exchange_send | |
else | |
puts "\r\nWhat channel are we using?: (don't forget the #)" | |
@channel = gets.chomp | |
@sock.write "JOIN #{@channel}\r\n" | |
sleep 2 | |
key_exchange_recive | |
end | |
end | |
def check_read_special(data) | |
case data | |
when /PING/i | |
data = data.match(/PING :(.*)/).to_a[1] | |
@sock.write "PONG :#{data}\r\n" | |
when /PRIVMSG/i | |
read_n_convert(data) | |
else | |
#return data | |
end | |
end | |
def check_write_special(data) | |
case data | |
when /QUIT/i | |
@sock.write "QUIT\r\n" | |
@sock.flush | |
exit 0 | |
when /JOIN/i | |
@sock.write data | |
when /PRIVMSG/i | |
@sock.write data | |
else | |
slice_n_dice(data) | |
end | |
@sock.flush | |
end | |
def slice_n_dice(data) | |
data = @other_pub.public_encrypt(data) #encrypt | |
data = Zlib::Deflate.deflate(data) #compress | |
data = data.unpack('C*').join("-") #encode in hex and replace , with - | |
data = data.chars.each_slice(400).map(&:join) # slice to 400 size packets (IRC Maximum is 510) | |
@sock.puts "PRIVMSG ##{@channel} size:#{data.join.size}\r\n" | |
data.each do |packet| | |
@sock.puts "PRIVMSG ##{@channel} #{packet}\r\n" | |
sleep 0.1 | |
end | |
@sock.puts "PRIVMSG ##{@channel} end\r\n" | |
end | |
def read_n_convert(data) | |
size = data.match(/size:(.*)/).to_a[1].to_i | |
buffer = "" | |
buffer << @sock.readpartial(1024).match(/#{@channel} :(.*)/).to_a[1] until @sock.readpartial(1024) =~ /end/ | |
if buffer.size == size | |
buffer = buffer.split("-").pack('C*') #decode from hex and replace - with , | |
buffer = Zlib::Inflate.inflate(buffer) #inflate | |
puts "\r\n#{@priv.private_decrypt(buffer)}" | |
else | |
puts "\r\nPackge size is wrong" | |
end | |
end | |
def key_exchange_send | |
# Send Key | |
puts "\r\nPress enter to send the key" | |
gets | |
puts "sending key..." | |
data = Zlib::Deflate.deflate(@pub.to_s).unpack('C*').join("-") | |
data = data.chars.each_slice(400).map(&:join) | |
data.each do |packet| | |
@sock.puts "PRIVMSG ##{@channel} #{packet}\r\n" | |
sleep 0.1 | |
end | |
@sock.puts "PRIVMSG ##{@channel} end\r\n" | |
@sock.puts "PRIVMSG ##{@channel} end\r\n" | |
# Recive Key | |
puts "listening for key" | |
buffer = "" | |
until @sock.readpartial(1024) =~ /end/ | |
buffer << @sock.readpartial(1024).match(/#{@channel} :(.*)/).to_a[1] | |
puts "getting key..." | |
end | |
buffer = buffer.split("-").pack('C*') #decode from hex and replace - with , | |
buffer = buffer = Zlib::Inflate.inflate(buffer) #inflate | |
@other_pub = buffer | |
end | |
def key_exchange_recive | |
# Recive Key | |
puts "listening for key" | |
buffer = "" | |
until @sock.readpartial(1024).match(/end/i) | |
buffer << @sock.readpartial(1024).match(/#{@channel} :(.*)/).to_a[1] | |
puts "getting key..." | |
end | |
puts buffer | |
buffer = buffer.split("-").pack('C*') #decode from hex and replace - with , | |
buffer = buffer = Zlib::Inflate.inflate(buffer) #inflate | |
@other_pub = buffer | |
# Send Key | |
puts "sending key..." | |
data = Zlib::Deflate.deflate(@pub.to_s).unpack('C*').join("-") | |
data = data.chars.each_slice(400).map(&:join) | |
data.each do |packet| | |
@sock.puts "PRIVMSG ##{@channel} #{packet}\r\n" | |
sleep 0.1 | |
end | |
@sock.puts "PRIVMSG ##{@channel} end\r\n" | |
@sock.puts "PRIVMSG ##{@channel} end\r\n" | |
end | |
end | |
client = IRC_RSA.new | |
client.loop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment