vines-backdoor 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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