vines 0.4.7 → 0.4.8

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: 8a283e328bc02906cb090b08bcdc5c5bbc954a93
4
+ data.tar.gz: 37528ba4506f7a6bf6f57a569696eb80e7eed6d1
5
+ SHA512:
6
+ metadata.gz: 16915f6f177f20dd6311d6d57df91bf3981382f38d3ab50d94979d8813db203a20d027e6bde673d5086a637b6db4f140c324d2519866dcd2d8476d79e1d86393
7
+ data.tar.gz: 7cbf9026d98a8d1452af15ffecf2d7544222086fbb0a11ee9ba2e965c0644feefb163dd2e6ea77e0bab881e9b3c724de46eeb3251dbe90d3c3d0b8ed1177e3d6
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2012 Negative Code
1
+ Copyright (c) 2010-2013 Negative Code
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/bin/vines CHANGED
@@ -1,104 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
2
 
4
- require 'optparse'
5
3
  require 'vines'
6
-
7
- COMMANDS = %w[start stop restart init bcrypt cert ldap schema]
8
-
9
- def register_storage
10
- %w[couchdb mongodb redis sql].each do |backend|
11
- begin
12
- require 'vines/storage/%s' % backend
13
- rescue LoadError
14
- # do nothing
15
- end
16
- end
17
- end
18
-
19
- def parse(args)
20
- options = {}
21
- parser = OptionParser.new do |opts|
22
- opts.banner = "Usage: vines [options] #{COMMANDS.join('|')}"
23
-
24
- opts.separator ""
25
- opts.separator "Daemon options:"
26
-
27
- opts.on('-d', '--daemonize', 'Run daemonized in the background') do |daemonize|
28
- options[:daemonize] = daemonize
29
- end
30
-
31
- options[:log] = 'log/vines.log'
32
- opts.on('-l', '--log FILE', 'File to redirect output (default: log/vines.log)') do |log|
33
- options[:log] = log
34
- end
35
-
36
- options[:pid] = 'pid/vines.pid'
37
- opts.on('-P', '--pid FILE', 'File to store PID (default: pid/vines.pid)') do |pid|
38
- options[:pid] = pid
39
- end
40
-
41
- opts.separator ""
42
- opts.separator "Common options:"
43
-
44
- opts.on('-h', '--help', 'Show this message') do |help|
45
- options[:help] = help
46
- end
47
-
48
- opts.on('-v', '--version', 'Show version') do |version|
49
- options[:version] = version
50
- end
51
- end
52
-
53
- begin
54
- parser.parse!(args)
55
- rescue
56
- puts parser
57
- exit(1)
58
- end
59
-
60
- if options[:version]
61
- puts Vines::VERSION
62
- exit
63
- end
64
-
65
- if options[:help]
66
- puts parser
67
- exit
68
- end
69
-
70
- command = args.shift
71
- unless COMMANDS.include?(command)
72
- puts parser
73
- exit(1)
74
- end
75
-
76
- options.tap do |opts|
77
- opts[:args] = args
78
- opts[:command] = command
79
- opts[:config] = File.expand_path('conf/config.rb')
80
- opts[:pid] = File.expand_path(opts[:pid])
81
- opts[:log] = File.expand_path(opts[:log])
82
- end
83
- end
84
-
85
- def check_config(opts)
86
- return if %w[bcrypt init].include?(opts[:command])
87
- unless File.exists?(opts[:config])
88
- puts "No config file found at #{opts[:config]}"
89
- exit(1)
90
- end
91
- end
92
-
93
- register_storage
94
- opts = parse(ARGV)
95
- check_config(opts)
96
- command = Vines::Command.const_get(opts[:command].capitalize).new
97
- begin
98
- command.run(opts)
99
- rescue SystemExit
100
- # do nothing
101
- rescue Exception => e
102
- puts e.message
103
- exit(1)
104
- end
4
+ Vines::CLI.start
@@ -68,11 +68,13 @@ end
68
68
  net/ldap
69
69
  nokogiri
70
70
  openssl
71
+ optparse
71
72
  resolv
72
73
  set
73
74
  socket
74
75
  yaml
75
76
 
77
+ vines/cli
76
78
  vines/log
77
79
  vines/jid
78
80
 
@@ -0,0 +1,132 @@
1
+ module Vines
2
+ # The command line application that's invoked by the `vines` binary included
3
+ # in the gem. Parses the command line arguments to create a new server
4
+ # directory, and starts and stops the server.
5
+ class CLI
6
+ COMMANDS = %w[start stop restart init bcrypt cert ldap schema]
7
+
8
+ def self.start
9
+ self.new.start
10
+ end
11
+
12
+ # Run the command line application to parse arguments and run sub-commands.
13
+ # Exits the process with a non-zero return code to indicate failure.
14
+ #
15
+ # Returns nothing.
16
+ def start
17
+ register_storage
18
+ opts = parse(ARGV)
19
+ check_config(opts)
20
+ command = Command.const_get(opts[:command].capitalize).new
21
+ begin
22
+ command.run(opts)
23
+ rescue SystemExit
24
+ # do nothing
25
+ rescue Exception => e
26
+ puts e.message
27
+ exit(1)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Try to load various storage backends provided by vines-* gems and register
34
+ # them with the storage system for the config file to use.
35
+ #
36
+ # Returns nothing.
37
+ def register_storage
38
+ %w[couchdb mongodb redis sql].each do |backend|
39
+ begin
40
+ require 'vines/storage/%s' % backend
41
+ rescue LoadError
42
+ # do nothing
43
+ end
44
+ end
45
+ end
46
+
47
+ # Parse the command line arguments and run the matching sub-command
48
+ # (e.g. init, start, stop, etc).
49
+ #
50
+ # args - The ARGV array provided by the command line.
51
+ #
52
+ # Returns nothing.
53
+ def parse(args)
54
+ options = {}
55
+ parser = OptionParser.new do |opts|
56
+ opts.banner = "Usage: vines [options] #{COMMANDS.join('|')}"
57
+
58
+ opts.separator ""
59
+ opts.separator "Daemon options:"
60
+
61
+ opts.on('-d', '--daemonize', 'Run daemonized in the background') do |daemonize|
62
+ options[:daemonize] = daemonize
63
+ end
64
+
65
+ options[:log] = 'log/vines.log'
66
+ opts.on('-l', '--log FILE', 'File to redirect output (default: log/vines.log)') do |log|
67
+ options[:log] = log
68
+ end
69
+
70
+ options[:pid] = 'pid/vines.pid'
71
+ opts.on('-P', '--pid FILE', 'File to store PID (default: pid/vines.pid)') do |pid|
72
+ options[:pid] = pid
73
+ end
74
+
75
+ opts.separator ""
76
+ opts.separator "Common options:"
77
+
78
+ opts.on('-h', '--help', 'Show this message') do |help|
79
+ options[:help] = help
80
+ end
81
+
82
+ opts.on('-v', '--version', 'Show version') do |version|
83
+ options[:version] = version
84
+ end
85
+ end
86
+
87
+ begin
88
+ parser.parse!(args)
89
+ rescue
90
+ puts parser
91
+ exit(1)
92
+ end
93
+
94
+ if options[:version]
95
+ puts Vines::VERSION
96
+ exit
97
+ end
98
+
99
+ if options[:help]
100
+ puts parser
101
+ exit
102
+ end
103
+
104
+ command = args.shift
105
+ unless COMMANDS.include?(command)
106
+ puts parser
107
+ exit(1)
108
+ end
109
+
110
+ options.tap do |opts|
111
+ opts[:args] = args
112
+ opts[:command] = command
113
+ opts[:config] = File.expand_path('conf/config.rb')
114
+ opts[:pid] = File.expand_path(opts[:pid])
115
+ opts[:log] = File.expand_path(opts[:log])
116
+ end
117
+ end
118
+
119
+ # Many commands must be run in the context of a vines server directory
120
+ # created with `vines init`. If the command can't find the server's config
121
+ # file, print an error message and exit.
122
+ #
123
+ # Returns nothing.
124
+ def check_config(opts)
125
+ return if %w[bcrypt init].include?(opts[:command])
126
+ unless File.exists?(opts[:config])
127
+ puts "No config file found at #{opts[:config]}"
128
+ exit(1)
129
+ end
130
+ end
131
+ end
132
+ end
@@ -12,11 +12,18 @@ module Vines
12
12
  @stream = stream
13
13
  end
14
14
 
15
- # Authenticate s2s streams, comparing their domain to their SSL certificate.
16
- # Return +true+ if the base64 encoded domain matches the TLS certificate
17
- # presented earlier in stream negotiation. Raise a +SaslError+ if
18
- # authentication failed.
19
- # http://xmpp.org/extensions/xep-0178.html#s2s
15
+ # Authenticate server-to-server streams, comparing their domain to their
16
+ # SSL certificate.
17
+ #
18
+ # http://xmpp.org/extensions/xep-0178.html#s2s
19
+ #
20
+ # encoded - The Base64 encoded remote domain name String sent by the
21
+ # server stream.
22
+ #
23
+ # Returns true if the Base64 encoded domain matches the TLS certificate
24
+ # presented earlier in stream negotiation.
25
+ #
26
+ # Raises a SaslError if authentication failed.
20
27
  def external_auth(encoded)
21
28
  unless encoded == EMPTY
22
29
  authzid = decode64(encoded)
@@ -27,8 +34,12 @@ module Vines
27
34
  matches_from or raise SaslErrors::NotAuthorized
28
35
  end
29
36
 
30
- # Authenticate c2s streams using a username and password. Return the
31
- # authenticated +User+ or raise a +SaslError+ if authentication failed.
37
+ # Authenticate client-to-server streams using a username and password.
38
+ #
39
+ # encoded - The Base64 encoded jid and password String sent by the
40
+ # client stream.
41
+ #
42
+ # Returns the authenticated User or raises SaslError if authentication failed.
32
43
  def plain_auth(encoded)
33
44
  jid, password = decode_credentials(encoded)
34
45
  user = authenticate(jid, password)
@@ -39,7 +50,13 @@ module Vines
39
50
 
40
51
  # Storage backends should not raise errors, but if an unexpected error
41
52
  # occurs during authentication, convert it to a temporary-auth-failure.
42
- # Return the authenticated +User+ or +nil+ if authentication failed.
53
+ #
54
+ # jid - The user's jid String.
55
+ # password - The String password.
56
+ #
57
+ # Returns the authenticated User or nil if authentication failed.
58
+ #
59
+ # Raises TemoraryAuthFailure if the storage system failed.
43
60
  def authenticate(jid, password)
44
61
  log.info("Authenticating user: %s" % jid)
45
62
  @stream.storage.authenticate(jid, password).tap do |user|
@@ -50,10 +67,15 @@ module Vines
50
67
  raise SaslErrors::TemporaryAuthFailure
51
68
  end
52
69
 
53
- # Return the +JID+ and password decoded from the base64 encoded SASL PLAIN
70
+ # Return the JID and password decoded from the Base64 encoded SASL PLAIN
54
71
  # credentials formatted as authzid\0authcid\0password.
55
- # http://tools.ietf.org/html/rfc6120#section-6.3.8
56
- # http://tools.ietf.org/html/rfc4616
72
+ #
73
+ # http://tools.ietf.org/html/rfc6120#section-6.3.8
74
+ # http://tools.ietf.org/html/rfc4616
75
+ #
76
+ # encoded - The Base64 encoded String from which to extract jid and password.
77
+ #
78
+ # Returns an Array of jid String and password String.
57
79
  def decode_credentials(encoded)
58
80
  authzid, node, password = decode64(encoded).split("\x00")
59
81
  raise SaslErrors::NotAuthorized if node.nil? || node.empty? || password.nil? || password.empty?
@@ -71,7 +93,13 @@ module Vines
71
93
  # widely supported. However, Strophe and Blather send a bare JID, in
72
94
  # compliance with RFC 6120, but Smack sends just the user name as the
73
95
  # authzid. So, take care to handle non-compliant clients here.
74
- # http://tools.ietf.org/html/rfc6120#section-6.3.8
96
+ #
97
+ # http://tools.ietf.org/html/rfc6120#section-6.3.8
98
+ #
99
+ # authzid - The authzid String (may be nil).
100
+ # jid - The username String.
101
+ #
102
+ # Returns nothing.
75
103
  def validate_authzid!(authzid, jid)
76
104
  return if authzid.nil? || authzid.empty?
77
105
  authzid.downcase!
@@ -80,10 +108,18 @@ module Vines
80
108
  raise SaslErrors::InvalidAuthzid unless compliant || smack
81
109
  end
82
110
 
83
- # Decode the base64 encoded string, raising an error for invalid data.
84
- # http://tools.ietf.org/html/rfc6120#section-13.9.1
111
+ # Decode the Base64 encoded string, raising an error for invalid data.
112
+ #
113
+ # http://tools.ietf.org/html/rfc6120#section-13.9.1
114
+ #
115
+ # encoded - The Base64 encoded String.
116
+ #
117
+ # Returns a UTF-8 String.
85
118
  def decode64(encoded)
86
- Base64.strict_decode64(encoded)
119
+ Base64.strict_decode64(encoded).tap do |decoded|
120
+ decoded.force_encoding(Encoding::UTF_8)
121
+ raise SaslErrors::IncorrectEncoding unless decoded.valid_encoding?
122
+ end
87
123
  rescue
88
124
  raise SaslErrors::IncorrectEncoding
89
125
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Vines
4
- VERSION = '0.4.7'
4
+ VERSION = '0.4.8'
5
5
  end
@@ -97,6 +97,18 @@ describe Vines::Stream::SASL do
97
97
  storage.verify
98
98
  end
99
99
 
100
+ it 'passes with valid password and unicode jid' do
101
+ user = Vines::User.new(jid: 'piñata@verona.lit')
102
+ storage.expect :authenticate, user, [user.jid, 'secr3t']
103
+ stream.expect :storage, storage
104
+
105
+ encoded = Base64.strict_encode64("\x00piñata\x00secr3t")
106
+ subject.plain_auth(encoded).must_equal user
107
+
108
+ stream.verify
109
+ storage.verify
110
+ end
111
+
100
112
  it 'passes with valid password and authzid provided by strophe and blather' do
101
113
  storage.expect :authenticate, romeo, [romeo.jid, 'secr3t']
102
114
  stream.expect :storage, storage
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
5
- prerelease:
4
+ version: 0.4.8
6
5
  platform: ruby
7
6
  authors:
8
7
  - David Graham
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-23 00:00:00.000000000 Z
11
+ date: 2013-10-30 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bcrypt-ruby
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: em-hiredis
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: eventmachine
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: http_parser.rb
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: net-ldap
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ~>
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ~>
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: nokogiri
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ~>
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ~>
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: minitest
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ~>
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ~>
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: rake
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ~>
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ~>
140
123
  - !ruby/object:Gem::Version
@@ -154,6 +137,7 @@ files:
154
137
  - README.md
155
138
  - vines.gemspec
156
139
  - bin/vines
140
+ - lib/vines/cli.rb
157
141
  - lib/vines/cluster/connection.rb
158
142
  - lib/vines/cluster/publisher.rb
159
143
  - lib/vines/cluster/pubsub.rb
@@ -324,30 +308,26 @@ files:
324
308
  homepage: http://www.getvines.org
325
309
  licenses:
326
310
  - MIT
311
+ metadata: {}
327
312
  post_install_message:
328
313
  rdoc_options: []
329
314
  require_paths:
330
315
  - lib
331
316
  required_ruby_version: !ruby/object:Gem::Requirement
332
- none: false
333
317
  requirements:
334
- - - ! '>='
318
+ - - '>='
335
319
  - !ruby/object:Gem::Version
336
320
  version: 1.9.3
337
321
  required_rubygems_version: !ruby/object:Gem::Requirement
338
- none: false
339
322
  requirements:
340
- - - ! '>='
323
+ - - '>='
341
324
  - !ruby/object:Gem::Version
342
325
  version: '0'
343
- segments:
344
- - 0
345
- hash: -1025629835892307549
346
326
  requirements: []
347
327
  rubyforge_project:
348
- rubygems_version: 1.8.23
328
+ rubygems_version: 2.0.3
349
329
  signing_key:
350
- specification_version: 3
330
+ specification_version: 4
351
331
  summary: Vines is an XMPP chat server that's easy to install and run.
352
332
  test_files:
353
333
  - test/cluster/publisher_test.rb