encinch 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: edb2e2e7c096ffda8693dcd2c641689724862796
4
+ data.tar.gz: 2d8fcb47f7ee5ef3673503654d9cb6224f86d07f
5
+ SHA512:
6
+ metadata.gz: 589cea1054cbf7f40b792fd6e52b9e51b4d69f81171f13819d204be8616c3576586f44a19a1590cc54a0e1efe80aaa393fe7a1dcf1717a4a8b190c18018ea36f
7
+ data.tar.gz: 5f640b06f13ca5e1c253ee0bae607762c22dec34e11b7201121a6f02e410cd7377c35825d49e41453448e035defc703bacbfc296377f886aa56ffa6badc97580
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .DS_Store
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Jason Franz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+
2
+ # Encinch
3
+
4
+ Transparent blowfish encryption plugin for Cinch: An IRC Bot Building Framework
5
+
6
+ https://github.com/cinchrb/cinch
7
+
8
+
9
+ ## Installation
10
+
11
+ $[sudo] gem install encinch
12
+
13
+ ## Example
14
+ ```
15
+ require 'cinch'
16
+ require 'cinch/plugins/encinch'
17
+
18
+
19
+ bot = Cinch::Bot.new do
20
+ configure do |c|
21
+ c.nick = "EnCinch"
22
+ c.server = "irc.freenode.org"
23
+ c.port = 7000
24
+ c.ssl.use = true
25
+ c.channels = ["#cryptedchan", "#plaintext"]
26
+
27
+ c.plugins.plugins = [Cinch::Plugins::EnCinch] # optionally add more plugins
28
+
29
+ c.plugins.options[Cinch::Plugins::EnCinch] = {
30
+ :ignore => ["#ignorechannel", "ignoreperson"],
31
+ :encrypt => {
32
+ '#cryptedchan' => "myfishkey",
33
+ 'cryptednick' => "notmyfishkey",
34
+ :default => "adefaultfishkey"
35
+ },
36
+ :uncrypted => ["#plaintext"]
37
+ }
38
+ end
39
+ end
40
+
41
+ bot.start
42
+ ```
43
+
44
+ ## Commands
45
+ None, yet.
46
+
47
+
48
+ ## Options
49
+ ### :encrypt
50
+ A hash of encryption targets and their corresponding encryption keys. Targets should all be lowercase.
51
+ :default can provide a general purpose key, generally good for private communications with the bot.
52
+ The :encrypt option must be set, :default is optional.
53
+
54
+ ### :uncrypted
55
+ An array of channels and individuals from which the bot will not encrypt messages. All entries must be lowercase. This option must be set. If there are no desired unencrypted targets set an empty array.
56
+
57
+ ### :ignore
58
+ An array of channels and individuals (other bots?) to ignore encrypted messages. All entries must be lower case.
59
+ :ignore is optional.
60
+
61
+ ## TODO
62
+ 1) keyexchange
63
+ 2) maybe store keys to a file?
64
+ 3) add commands for updating, removing and adding keys and other settings?
65
+ 4) user feedback... :-)
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cinch/plugins/encinch/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "encinch"
8
+ spec.version = EnCinch::Version::VERSION
9
+ spec.authors = ["jfrazx"]
10
+ spec.email = ["staringblind@gmail.com"]
11
+ spec.summary = %q{Transparent blowfish encryption plugin for Cinch: An IRC Bot Building Framework}
12
+ spec.description = %q{}
13
+ spec.platform = Gem::Platform::RUBY
14
+ spec.homepage = "https://github.com/jfrazx/EnCinch"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "cinch", "~> 2.0"
23
+ spec.add_runtime_dependency "crypt", "~> 2.0"
24
+ end
@@ -0,0 +1,5 @@
1
+ require 'cinch'
2
+ require 'crypt/blowfish'
3
+ require "cinch/plugins/encinch/encryption"
4
+ require "cinch/plugins/encinch/encinch"
5
+ require "cinch/plugins/encinch/extend"
@@ -0,0 +1,137 @@
1
+
2
+ module Cinch
3
+ module Plugins
4
+ class EnCinch
5
+ include Cinch::Plugin
6
+
7
+ def initialize(*)
8
+ super
9
+
10
+ # does Cinch have something to checked required options already???
11
+ raise MissingRequiredPluginOptions unless config[:encrypt]
12
+ raise MissingRequiredPluginOptions unless config[:uncrypted]
13
+
14
+ end
15
+
16
+ #
17
+ # All blowfish communication should be prefixed with +OK
18
+ # capture this to start the process
19
+ #
20
+
21
+ match(/\+OK (\S+)/, use_prefix: false, strip_colors: true, method: :capture)
22
+
23
+ def capture(m, message)
24
+ target = (m.channel ? m.channel.name : m.user.nick).downcase
25
+ message = strip(m, message)
26
+
27
+ return if config[:ignore].include?(target) rescue nil
28
+ @key = config[:encrypt][target] || config[:encrypt][:default] rescue nil
29
+
30
+ return unless @key
31
+
32
+ blowfish(@key)
33
+
34
+ decrypted = decrypt(message)
35
+ decrypted << '\u0001' if m.action?
36
+
37
+ raw = modify_raw(m.raw, decrypted)
38
+
39
+ dispatch(Message.new(raw, m.bot))
40
+ end
41
+
42
+ #
43
+ # matching for key exchange
44
+ # NOT WORKING YET
45
+ # It appears Cinch does not emit a :notice event, unfortunate
46
+ #
47
+
48
+ match(/DH1080_INIT/, use_prefix: false, react_on: [:private, :notice], method: :key_exchange)
49
+
50
+ def key_exchange(m)
51
+ return if m.channel?
52
+
53
+ debug "captured key exchange event with key: #{m.message}"
54
+
55
+ #TODO -- everything
56
+ end
57
+
58
+ # not sure this is actually needed
59
+ def encrypt(message)
60
+ @fish.encrypt(message)
61
+ end
62
+
63
+ def decrypt(message)
64
+ @fish.decrypt(message)
65
+ end
66
+
67
+ def blowfish(key)
68
+ @fish = Cinch::Plugins::EnCinch::Encryption.new(key)
69
+ end
70
+
71
+ private
72
+
73
+ def dispatch(msg)
74
+ events = [[:catchall]]
75
+
76
+ if ["PRIVMSG", "NOTICE"].include?(msg.command)
77
+ events << [:ctcp] if msg.ctcp?
78
+
79
+ if msg.channel?
80
+ events << [:channel]
81
+ else
82
+ events << [:private]
83
+ end
84
+
85
+ if msg.command == "PRIVMSG"
86
+ events << [:message]
87
+ else
88
+ events << [:notice]
89
+ end
90
+
91
+ if msg.action?
92
+ events << [:action]
93
+ end
94
+ end
95
+
96
+ meth = "on_#{msg.command.downcase}"
97
+ __send__(meth, msg, events) if respond_to?(meth, true)
98
+
99
+ if msg.error?
100
+ events << [:error]
101
+ end
102
+
103
+ events << [msg.command.downcase.to_sym]
104
+
105
+ msg.events = events
106
+
107
+ #if its still encrypted for whatever reason we will not be processing it again
108
+ msg.events.each do |event, *args|
109
+ msg.bot.handlers.dispatch(event, msg, *args)
110
+ end unless encrypted?(msg.raw)
111
+ end
112
+
113
+ #
114
+ # TODO: strip ctcp? others?
115
+ #
116
+
117
+ def strip(m, data)
118
+ data.sub!(/\u0001$/, '') if m.action?
119
+
120
+ data
121
+ end
122
+
123
+ def encrypted?(data)
124
+ !!data.match(/\+OK \S+/)
125
+ end
126
+
127
+ #
128
+ # replace the encrypted message with the decrypted
129
+ #
130
+
131
+ def modify_raw(data, decrypted)
132
+ data.sub!(/\+OK \S+(\s+)?(\S+)?/, decrypted)
133
+ data
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,109 @@
1
+ #
2
+ # much of this code was pilfered from Cinch's long dormant 'feature/fish' branch
3
+ # https://github.com/cinchrb/cinch/tree/feature/fish
4
+ # or from weechat's fish plugin
5
+ # https://github.com/weechat/scripts/blob/master/ruby/weefish.rb
6
+ #
7
+
8
+ module Cinch
9
+ module Plugins
10
+ class EnCinch
11
+ class Encryption
12
+ module Base64
13
+
14
+ Alphabet = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze
15
+
16
+ def self.encode(data)
17
+ res = String.new
18
+ data = data.dup.force_encoding("BINARY")
19
+
20
+ data.chars.each_slice(8) do |slice|
21
+ slice = slice.join
22
+ left, right = slice.unpack('L>L>')
23
+ 6.times do
24
+ res << Alphabet[right & 0x3f]
25
+ right >>= 6
26
+ end
27
+
28
+ 6.times do
29
+ res << Alphabet[left & 0x3f]
30
+ left >>= 6
31
+ end
32
+ end
33
+
34
+ return res
35
+ end
36
+
37
+ def self.decode(data)
38
+ res = String.new
39
+ data = data.dup.force_encoding("BINARY")
40
+ data.chars.each_slice(12) do |slice|
41
+ slice = slice.join
42
+ left = right = 0
43
+
44
+ slice[0..5].each_char.with_index do |p, i|
45
+ right |= Alphabet.index(p) << (i * 6)
46
+ end
47
+
48
+ slice[6..11].each_char.with_index do |p, i|
49
+ left |= Alphabet.index(p) << (i * 6)
50
+ end
51
+
52
+ res << [left, right].pack('L>L>')
53
+ end
54
+
55
+ return res
56
+ end
57
+ end
58
+
59
+
60
+ def initialize(key)
61
+ @blowfish = Crypt::Blowfish.new(key)
62
+ end
63
+
64
+ def encrypt(text)
65
+ text = pad(text, 8)
66
+ result = String.new
67
+
68
+ num_block = text.length / 8
69
+ num_block.times do |n|
70
+ block = text[n*8..(n+1)*8-1]
71
+ enc = @blowfish.encrypt_block(block)
72
+ result += Base64.encode(enc)
73
+ end
74
+
75
+ return "+OK " << result
76
+ end
77
+
78
+ def decrypt(text)
79
+ return nil if not text.length % 12 == 0
80
+
81
+ result = String.new
82
+
83
+ num_block = (text.length / 12).to_i
84
+ num_block.times do |n|
85
+ block = Base64.decode( text[n*12..(n+1)*12-1] )
86
+ result += @blowfish.decrypt_block(block)
87
+ end
88
+
89
+ return result.gsub(/\0*$/, "")
90
+ end
91
+
92
+ def self.generate
93
+ # generate a key for key exchange
94
+ end
95
+
96
+ private
97
+
98
+ def pad(text, n=8)
99
+ pad_num = n - (text.length % n)
100
+ if pad_num > 0 and pad_num != n
101
+ pad_num.times { text += 0.chr }
102
+ end
103
+
104
+ return text
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Cinch
3
+ module Exceptions
4
+
5
+ # error to raise for missing required plugin options
6
+ class MissingRequiredPluginOptions < Generic
7
+ end
8
+ end
9
+
10
+
11
+ class IRC
12
+
13
+ # Send a message to the server.
14
+ # @param [String] msg
15
+ # @return [void]
16
+ def send(msg)
17
+
18
+ # TODO match and modify ACTION
19
+ if msg.match(/(PRIVMSG|NOTICE)/) && !msg.match(/\+OK (\S+)/)
20
+
21
+ verb, target, *message = msg.split
22
+ message = message.join(' ')[1..-1] rescue nil
23
+
24
+ # retrieve bot options
25
+ if (message && !message.empty?) && options = @bot.config.plugins.options[Cinch::Plugins::EnCinch]
26
+
27
+ # key exists
28
+ if key = (options[:encrypt][target.downcase] || options[:encrypt][:default])
29
+
30
+ # ignore if target is in the 'uncrypted' array
31
+ unless options[:uncrypted].include?(target.downcase)
32
+
33
+ fish = Cinch::Plugins::EnCinch::Encryption.new(key)
34
+ encrypted = fish.encrypt(message)
35
+ msg.sub!(message, encrypted)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ @queue.queue(msg)
42
+ end
43
+
44
+ private
45
+
46
+ end
47
+ end
@@ -0,0 +1,6 @@
1
+
2
+ class EnCinch
3
+ class Version
4
+ VERSION = "0.0.3"
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: encinch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - jfrazx
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cinch
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: crypt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ description: ''
42
+ email:
43
+ - staringblind@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - LICENSE.txt
50
+ - README.md
51
+ - encinch.gemspec
52
+ - lib/cinch/plugins/encinch.rb
53
+ - lib/cinch/plugins/encinch/encinch.rb
54
+ - lib/cinch/plugins/encinch/encryption.rb
55
+ - lib/cinch/plugins/encinch/extend.rb
56
+ - lib/cinch/plugins/encinch/version.rb
57
+ homepage: https://github.com/jfrazx/EnCinch
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.2.2
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: 'Transparent blowfish encryption plugin for Cinch: An IRC Bot Building Framework'
81
+ test_files: []