vines-backdoor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-*
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
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # coding: utf-8
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Strech (Sergey Fedorov)
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,81 @@
1
+ [![Build Status](https://travis-ci.org/Strech/vines-backdoor.png?branch=master)](https://travis-ci.org/Strech/vines-backdoor)
2
+ [![Code Climate](https://codeclimate.com/github/Strech/vines-backdoor.png)](https://codeclimate.com/github/Strech/vines-backdoor)
3
+
4
+ # Vines::Backdoor
5
+
6
+ Allows you to authenticate and generate bosh session for vines user by sigle request without password.
7
+
8
+ All that you need – a secret key from backdoor of your vines
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'vines-backdoor'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install vines-backdoor
23
+
24
+ ## :warning: Attention :warning:
25
+
26
+ Never, ever, ever use this for external client authentication. This extension is only for internal server use :fire:
27
+
28
+ ## Usage
29
+
30
+ Modify your vines config file
31
+
32
+ ```ruby
33
+ # conf/config.rb
34
+
35
+ require 'vines/backdoor'
36
+
37
+ # http bind section
38
+ http '0.0.0.0', 5280 do
39
+ bind '/http-bind'
40
+ max_stanza_size 65536
41
+ max_resources_per_account 5
42
+ root 'web'
43
+ vroute ''
44
+ backdoor 'my-secret-backdoor-key'
45
+ end
46
+ ```
47
+
48
+ Now http service accept extended requests with some extra data in it.
49
+ All response messages (errors and success responses) are RFC compatible
50
+
51
+ Send authentication and binding request in a batch
52
+
53
+ ```html
54
+ <body xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0"
55
+ content="text/xml; charset=utf-8" rid="235205804" to="localhost" secure="true" wait="60" hold="1"
56
+ backdoor="my-secret-backdoor-key">
57
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
58
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
59
+ <resource>pidgin</resource>
60
+ </bind>
61
+ </body>
62
+ ```
63
+
64
+ And get a successful response
65
+
66
+ ```html
67
+ <iq type="result" id="235205804">
68
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
69
+ <jid>user@localhost/pidgin</jid>
70
+ <sid>f27c71df-f124-4829-b415-5855b8c04109</sid>
71
+ </bind>
72
+ </iq>
73
+ ```
74
+
75
+ ## Contributing
76
+
77
+ 1. Fork it ( http://github.com/Strech/vines-backdoor/fork )
78
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
79
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
80
+ 4. Push to the branch (`git push origin my-new-feature`)
81
+ 5. Create new Pull Request
@@ -0,0 +1,3 @@
1
+ # coding: utf-8
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+ require "vines/backdoor/version"
3
+ require "vines/backdoor/gap"
4
+ require "vines/backdoor/bind"
5
+ require "vines/backdoor/auth"
6
+ require "vines/backdoor/config/port"
7
+ require "vines/backdoor/stream/http"
8
+ require "vines/backdoor/stream/http/start"
@@ -0,0 +1,39 @@
1
+ # coding: UTF-8
2
+ module Vines
3
+ module Backdoor
4
+ class Auth < Vines::Stream::Client::Auth
5
+ INTERNAL = "INTERNAL".freeze
6
+
7
+ def auth(node)
8
+ raise StreamErrors::NotAuthorized unless auth?(node)
9
+
10
+ node = node.xpath('ns:auth', 'ns' => NS).first
11
+
12
+ if node.text.empty?
13
+ send_auth_fail(SaslErrors::MalformedRequest.new)
14
+ elsif stream.authentication_mechanisms.include?(node[MECHANISM])
15
+ if node[MECHANISM] == INTERNAL
16
+ stream.user = authenticate(node.text) or raise StreamErrors::NotAuthorized
17
+ end
18
+ else
19
+ send_auth_fail(SaslErrors::InvalidMechanism.new)
20
+ end
21
+ end
22
+
23
+ private
24
+ def auth?(node)
25
+ node.xpath('ns:auth', 'ns' => NS).any?
26
+ end
27
+
28
+ def authenticate(jid)
29
+ log.info("Authenticating user: %s" % jid)
30
+ stream.storage.find_user(jid).tap do |user|
31
+ log.info("Authentication succeeded (backdoor): %s" % user.jid) if user
32
+ end
33
+ rescue => e
34
+ log.error("Failed to authenticate: #{e.to_s}")
35
+ raise Vines::SaslErrors::TemporaryAuthFailure
36
+ end
37
+ end # class Auth
38
+ end # module Backdoor
39
+ end # module Vines
@@ -0,0 +1,35 @@
1
+ # coding: UTF-8
2
+ module Vines
3
+ module Backdoor
4
+ class Bind < Vines::Stream::Client::Bind
5
+ def bind(node)
6
+ @attempts += 1
7
+ raise StreamErrors::NotAuthorized unless bind?(node)
8
+ raise StreamErrors::PolicyViolation.new('max bind attempts reached') if @attempts > MAX_ATTEMPTS
9
+ raise StanzaErrors::ResourceConstraint.new(fabricate_request(node), 'wait') if resource_limit_reached?
10
+
11
+ stream.bind!(resource(node))
12
+ end
13
+
14
+ private
15
+ def bind?(node)
16
+ node.xpath('ns:bind', 'ns' => NS).any?
17
+ end
18
+
19
+ def resource(node)
20
+ el = node.xpath('ns:bind/ns:resource', 'ns' => NS).first
21
+ resource = el ? el.text.strip : ''
22
+ generate = resource.empty? || !resource_valid?(resource) || resource_used?(resource)
23
+ generate ? Vines::Kit.uuid : resource
24
+ end
25
+
26
+ def fabricate_request(node)
27
+ doc = Document.new
28
+ doc.create_element('iq') do |el|
29
+ el['id'] = node['rid']
30
+ el << node.xpath('ns:bind/ns:resource', 'ns' => NS).first
31
+ end
32
+ end
33
+ end # class Bind
34
+ end # module Backdoor
35
+ end # module Vines
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ module Vines
3
+ class Config
4
+ class HttpPort
5
+ def backdoor(secret_key = nil)
6
+ if secret_key
7
+ @settings[:backdoor_secret_key] = secret_key
8
+ else
9
+ @settings[:backdoor_secret_key]
10
+ end
11
+ end
12
+ end # class HttpPort
13
+ end # class Config
14
+ end # module Vines
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ require "nokogiri"
3
+
4
+ module Vines
5
+ module Backdoor
6
+ class Gap
7
+ BACKDOOR = "backdoor".freeze
8
+
9
+ attr_reader :stream
10
+
11
+ def initialize(stream)
12
+ @stream = stream
13
+ end
14
+
15
+ def node(node)
16
+ raise StreamErrors::NotAuthorized unless backdoor?(node)
17
+
18
+ stream.start_session(node)
19
+ Backdoor::Auth.new(stream).auth(node)
20
+ Backdoor::Bind.new(stream).bind(node)
21
+
22
+ advance(node)
23
+ end
24
+
25
+ private
26
+ def advance(node)
27
+ doc = Nokogiri::XML::Document.new
28
+ result = doc.create_element('iq', 'id' => node['rid'], 'type' => 'result') do |el|
29
+ el << doc.create_element('bind') do |bind|
30
+ bind.default_namespace = Vines::Stream::Client::Bind::NS
31
+ bind << doc.create_element('jid', stream.user.jid.to_s)
32
+ bind << doc.create_element('sid', stream.id)
33
+ end
34
+ end
35
+
36
+ stream.write(result)
37
+ end
38
+
39
+ def backdoor?(node)
40
+ node[BACKDOOR] && node[BACKDOOR] == @stream.backdoor
41
+ end
42
+ end # class Gap
43
+ end # module Backdoor
44
+ end # module Vines
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ module Vines
3
+ class Stream
4
+ class Http < Client
5
+ MECHANISMS = %w[PLAIN INTERNAL].freeze
6
+
7
+ def backdoor(*args)
8
+ config[:http].backdoor(*args)
9
+ end
10
+
11
+ def authentication_mechanisms
12
+ MECHANISMS
13
+ end
14
+
15
+ def start_session(node)
16
+ domain, type, hold, wait, rid = %w[to content hold wait rid].map {|a| (node[a] || '').strip }
17
+ version = node.attribute_with_ns('version', NAMESPACES[:bosh]).value rescue nil
18
+
19
+ @session.inactivity = 20
20
+ @session.domain = domain
21
+ @session.content_type = type unless type.empty?
22
+ @session.hold = hold.to_i unless hold.empty?
23
+ @session.wait = wait.to_i unless wait.empty?
24
+
25
+ raise StreamErrors::UndefinedCondition.new('rid required') if rid.empty?
26
+ raise StreamErrors::UnsupportedVersion unless version == '1.0'
27
+ raise StreamErrors::ImproperAddressing unless valid_address?(domain)
28
+ raise StreamErrors::HostUnknown unless config.vhost?(domain)
29
+ raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:http_bind]
30
+
31
+ Sessions[@session.id] = @session
32
+ end
33
+ end # class Http
34
+ end # class Stream
35
+ end # module Vines
@@ -0,0 +1,24 @@
1
+ # coding: UTF-8
2
+ module Vines
3
+ class Stream
4
+ class Http
5
+ class Start < State
6
+ def node(node)
7
+ raise StreamErrors::NotAuthorized unless body?(node)
8
+ if session = Sessions[node['sid']]
9
+ session.resume(stream, node)
10
+ else
11
+
12
+ if node['backdoor']
13
+ backdoor = Vines::Backdoor::Gap.new(stream)
14
+ backdoor.node(node)
15
+ else
16
+ stream.start(node)
17
+ advance
18
+ end
19
+ end
20
+ end
21
+ end # class Start
22
+ end # class Http
23
+ end # class Stream
24
+ end # module Vines
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ module Vines
3
+ module Backdoor
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
@@ -0,0 +1,67 @@
1
+ # coding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Vines::Backdoor::Auth do
5
+ let(:klass) { described_class.new(stream) }
6
+ let(:storage) { double("Storage") }
7
+ let(:stream) do
8
+ double("Stream", storage: storage,
9
+ authentication_mechanisms: ["INTERNAL"]).as_null_object
10
+ end
11
+
12
+ context "when missing auth namespace" do
13
+ let(:xml) { node(%q{<body><auth mechanism="INTERNAL">user@localhost</auth></body>}) }
14
+
15
+ it { expect { klass.auth(xml) }.to raise_error Vines::StreamErrors::NotAuthorized }
16
+ end
17
+
18
+ context "when used unknown mechanism" do
19
+ let(:xml) do
20
+ node(%q{<body>
21
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="FOO">user@localhost</auth>
22
+ </body>})
23
+ end
24
+
25
+ after { klass.auth(xml) }
26
+
27
+ it { expect(stream).to receive(:error).with(kind_of Vines::SaslErrors::InvalidMechanism) }
28
+ end
29
+
30
+ context "when no username is given" do
31
+ let(:xml) do
32
+ node(%q{<body>
33
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL"></auth>
34
+ </body>})
35
+ end
36
+
37
+ after { klass.auth(xml) }
38
+
39
+ it { expect(stream).to receive(:error).with(kind_of Vines::SaslErrors::MalformedRequest) }
40
+ end
41
+
42
+ context "when user not found" do
43
+ let(:xml) do
44
+ node(%q{<body>
45
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
46
+ </body>})
47
+ end
48
+
49
+ before { storage.stub(:find_user).with("user@localhost").and_return nil }
50
+
51
+ it { expect { klass.auth(xml) }.to raise_error Vines::StreamErrors::NotAuthorized }
52
+ end
53
+
54
+ context "when user is authenticated" do
55
+ let(:user) { double("User", jid: "user@localhost") }
56
+ let(:xml) do
57
+ node(%q{<body>
58
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
59
+ </body>})
60
+ end
61
+
62
+ before { storage.stub(:find_user).with("user@localhost").and_return user }
63
+ after { klass.auth(xml) }
64
+
65
+ it { expect(stream).to receive(:user=).with(user) }
66
+ end
67
+ end
@@ -0,0 +1,73 @@
1
+ # coding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Vines::Backdoor::Bind do
5
+ let(:klass) { described_class.new(stream) }
6
+ let(:storage) { double("Storage") }
7
+ let(:stream) { double("Stream", storage: storage) }
8
+
9
+ context "when missing bind namespace" do
10
+ let(:xml) { node(%q{<body><bind><resource>pidgin</resource></bind></body>}) }
11
+
12
+ it { expect { klass.bind(xml) }.to raise_error Vines::StreamErrors::NotAuthorized }
13
+ end
14
+
15
+ context "when max attemps is reached" do
16
+ let(:xml) do
17
+ node(%q{<body>
18
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
19
+ <resource>pidgin</resource>
20
+ </bind></body>})
21
+ end
22
+
23
+ before { stub_const("Vines::Stream::Client::Bind::MAX_ATTEMPTS", 0) }
24
+
25
+ it { expect { klass.bind(xml) }.to raise_error Vines::StreamErrors::PolicyViolation }
26
+ end
27
+
28
+ context "when resource limit is reached" do
29
+ let(:xml) do
30
+ node(%q{<body>
31
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
32
+ <resource>pidgin</resource>
33
+ </bind></body>})
34
+ end
35
+
36
+ before { klass.stub(resource_limit_reached?: true) }
37
+
38
+ it { expect { klass.bind(xml) }.to raise_error Vines::StanzaErrors::ResourceConstraint }
39
+ end
40
+
41
+ context "when bind session with given resource" do
42
+ let(:xml) do
43
+ node(%q{<body>
44
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
45
+ <resource>pidgin</resource>
46
+ </bind></body>})
47
+ end
48
+
49
+ before do
50
+ klass.stub(resource_valid?: true)
51
+ klass.stub(resource_limit_reached?: false)
52
+ klass.stub(:resource_used?).with("pidgin").and_return false
53
+ end
54
+ after { klass.bind(xml) }
55
+
56
+ it { expect(stream).to receive(:bind!).with("pidgin") }
57
+ end
58
+
59
+ context "when bind session with generated resource" do
60
+ let(:xml) { node(%q{<body><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></body>}) }
61
+
62
+ before do
63
+ klass.stub(resource_valid?: true)
64
+ klass.stub(resource_limit_reached?: false)
65
+ end
66
+ after { klass.bind(xml) }
67
+
68
+ it do
69
+ expect(Vines::Kit).to receive(:uuid).and_return "random-resource"
70
+ expect(stream).to receive(:bind!).with("random-resource")
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,71 @@
1
+ # coding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Vines::Backdoor::Gap do
5
+ let(:klass) { described_class.new(stream) }
6
+ let(:storage) { double("Storage") }
7
+ let(:stream) { double("Stream", storage: storage).as_null_object }
8
+
9
+ context "when backdoor attribute is missing" do
10
+ let(:xml) do
11
+ node(%q{<body>
12
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
13
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
14
+ <resource>pidgin</resource>
15
+ </bind></body>})
16
+ end
17
+
18
+ it { expect { klass.node(xml) }.to raise_error Vines::StreamErrors::NotAuthorized }
19
+ end
20
+
21
+ context "when backdoor attribute is wrong" do
22
+ let(:xml) do
23
+ node(%q{<body backdoor="12345">
24
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
25
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
26
+ <resource>pidgin</resource>
27
+ </bind></body>})
28
+ end
29
+
30
+ before { stream.stub(backdoor: 9000) }
31
+
32
+ it { expect { klass.node(xml) }.to raise_error Vines::StreamErrors::NotAuthorized }
33
+ end
34
+
35
+ context "when user is authenticated and session is binded" do
36
+ let(:user) { double("User", jid: "user@localhost/pidgin") }
37
+ let(:xml) do
38
+ node(%q{<body rid="100500" backdoor="9000">
39
+ <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="INTERNAL">user@localhost</auth>
40
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
41
+ <resource>pidgin</resource>
42
+ </bind></body>})
43
+ end
44
+ let(:expected) do
45
+ node(%q{<iq id="100500" type="result">
46
+ <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
47
+ <jid>user@localhost/pidgin</jid>
48
+ <sid>abcde-12345-fghijk-6789-xyz</sid>
49
+ </bind></iq>})
50
+ end
51
+
52
+ before do
53
+ stream.stub(backdoor: "9000")
54
+ stream.stub(authentication_mechanisms: ["INTERNAL"])
55
+ stream.stub(user: user)
56
+ stream.stub(id: "abcde-12345-fghijk-6789-xyz")
57
+
58
+ storage.stub(:find_user).with("user@localhost").and_return user
59
+
60
+ Vines::Backdoor::Bind.any_instance.stub(resource_valid?: true)
61
+ Vines::Backdoor::Bind.any_instance.stub(resource_limit_reached?: false)
62
+ end
63
+ after { klass.node(xml) }
64
+
65
+ it do
66
+ expect(stream).to receive(:write) do |response|
67
+ expect(response.to_s).to eq expected.to_s
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Vines::Stream::Http::Start do
5
+ context "when backdoor attribute present" do
6
+ let(:start) { described_class.new(stream) }
7
+ let(:xml) { node(%q{<body xmlns="http://jabber.org/protocol/httpbind" rid="42" backdoor="12345"/>}) }
8
+ let(:gap) { double("Backdoor gap").as_null_object }
9
+ let(:stream) { double("Stream", backdoor: "12345") }
10
+
11
+ after { em { start.node(xml) } }
12
+
13
+ it do
14
+ expect(Vines::Backdoor::Gap).to receive(:new).with(stream).and_return gap
15
+ expect(gap).to receive(:node).with(xml)
16
+ end
17
+ end
18
+
19
+ context "when backdoor attribute is missing" do
20
+ let(:start) { described_class.new(stream) }
21
+ let(:xml) { node(%q{<body xmlns="http://jabber.org/protocol/httpbind" rid="42" />}) }
22
+ let(:stream) { double("Stream", backdoor: "12345") }
23
+
24
+ after { em { start.node(xml) } }
25
+
26
+ it do
27
+ expect(stream).to receive(:start).with(xml)
28
+ expect(stream).to receive(:advance)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ if ENV["COV"]
3
+ require "simplecov"
4
+
5
+ SimpleCov.start do
6
+ add_filter "/spec/"
7
+ end
8
+ end
9
+
10
+ require "vines"
11
+ require "vines/backdoor"
12
+
13
+ # Disable vines logger
14
+ Class.new.extend(Vines::Log).log.level = Logger::FATAL
15
+ Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each { |file| require file }
16
+
17
+ RSpec.configure do |config|
18
+ config.formatter = :progress
19
+ config.order = :random
20
+ config.color = true
21
+
22
+ include Helpers
23
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ module Helpers
3
+ def node(xml)
4
+ xml = xml.strip.gsub(/\n|\s{2,}/, '')
5
+ Nokogiri::XML(xml).root
6
+ end
7
+
8
+ def em
9
+ EM.run do
10
+ yield if block_given?
11
+ EM.stop
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "vines/backdoor/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "vines-backdoor"
9
+ spec.version = Vines::Backdoor::VERSION
10
+ spec.authors = ["Strech (Sergey Fedorov)"]
11
+ spec.email = ["strech_ftf@mail.ru"]
12
+ spec.summary = "Accelerated http-bind session creation"
13
+ spec.description = "XMPP protocol extension for Vines server"
14
+ spec.homepage = "https://github.com/Strech/vines-backdoor"
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_dependency "vines", ">= 0.4.5"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rspec", "~> 2.14"
26
+ spec.add_development_dependency "simplecov"
27
+ spec.add_development_dependency "rake"
28
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vines-backdoor
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Strech (Sergey Fedorov)
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: vines
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.4.5
22
+ requirement: !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: 0.4.5
28
+ type: :runtime
29
+ prerelease: false
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.5'
38
+ requirement: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '1.5'
44
+ type: :development
45
+ prerelease: false
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.14'
54
+ requirement: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: '2.14'
60
+ type: :development
61
+ prerelease: false
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirement: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :development
93
+ prerelease: false
94
+ description: XMPP protocol extension for Vines server
95
+ email:
96
+ - strech_ftf@mail.ru
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - .travis.yml
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - lib/vines/backdoor.rb
108
+ - lib/vines/backdoor/auth.rb
109
+ - lib/vines/backdoor/bind.rb
110
+ - lib/vines/backdoor/config/port.rb
111
+ - lib/vines/backdoor/gap.rb
112
+ - lib/vines/backdoor/stream/http.rb
113
+ - lib/vines/backdoor/stream/http/start.rb
114
+ - lib/vines/backdoor/version.rb
115
+ - spec/lib/vines/backdoor/auth_spec.rb
116
+ - spec/lib/vines/backdoor/bind_spec.rb
117
+ - spec/lib/vines/backdoor/gap_spec.rb
118
+ - spec/lib/vines/backdoor/stream/http/start_spec.rb
119
+ - spec/spec_helper.rb
120
+ - spec/support/helpers.rb
121
+ - vines-backdoor.gemspec
122
+ homepage: https://github.com/Strech/vines-backdoor
123
+ licenses:
124
+ - MIT
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 1.8.25
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: Accelerated http-bind session creation
147
+ test_files:
148
+ - spec/lib/vines/backdoor/auth_spec.rb
149
+ - spec/lib/vines/backdoor/bind_spec.rb
150
+ - spec/lib/vines/backdoor/gap_spec.rb
151
+ - spec/lib/vines/backdoor/stream/http/start_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/support/helpers.rb