Browse files

Simplify SASL implementation

  • Loading branch information...
1 parent 6406071 commit 1e3cecaa26594fc714167b7660e2e3521e395c5b @mperham mperham committed Dec 31, 2010
Showing with 14 additions and 142 deletions.
  1. +1 −0 .rvmrc
  2. +0 −14 lib/dalli/sasl/anonymous.rb
  3. +0 −89 lib/dalli/sasl/base.rb
  4. +0 −18 lib/dalli/sasl/plain.rb
  5. +3 −11 lib/dalli/server.rb
  6. +10 −10 test/test_sasl.rb
View
1 .rvmrc
@@ -1 +1,2 @@
rvm use 1.9.2@dalli --create
+export RUBYOPT='-Ilib:test'
View
14 lib/dalli/sasl/anonymous.rb
@@ -1,14 +0,0 @@
-module SASL
- ##
- # SASL ANONYMOUS where you only send a username that may not get
- # evaluated by the server.
- #
- # RFC 4505:
- # http://tools.ietf.org/html/rfc4505
- class Anonymous < Mechanism
- def start
- @state = nil
- ['auth', preferences.username.to_s]
- end
- end
-end
View
89 lib/dalli/sasl/base.rb
@@ -1,89 +0,0 @@
-module SASL
-
- MECHANISMS = {
- }
-
- class Preferences
- def authzid
- nil
- end
-
- def realm
- raise NotImplementedError
- end
-
- def digest_uri
- raise NotImplementedError
- end
-
- def username
- ENV['MEMCACHE_USERNAME']
- end
-
- def has_password?
- false
- end
-
- def allow_plaintext?
- false
- end
-
- def password
- ENV['MEMCACHE_PASSWORD']
- end
-
- def want_anonymous?
- false
- end
- end
-
- def SASL.new(mechanisms)
- mechanisms.each do |mech|
- if MECHANISMS.has_key?(mech)
- x = MECHANISMS[mech]
- return x.new(mech, Preferences.new)
- end
- end
-
- raise NotImplementedError, "No supported mechanisms in #{mechanisms.join(',')}"
- end
-
- ##
- # Common functions for mechanisms
- #
- # Mechanisms implement handling of methods start and receive. They
- # return: [message_name, content] or nil where message_name is
- # either 'auth' or 'response' and content is either a string which
- # may transmitted encoded as Base64 or nil.
- class Mechanism
- attr_reader :preferences
- attr_reader :name
-
- def initialize(name, preferences)
- @name = name
- @preferences = preferences
- @state = nil
- end
-
- def success?
- @state == :success
- end
- def failure?
- @state == :failure
- end
-
- def start
- raise NotImplementedError
- end
-
- def receive(message_name, content)
- case message_name
- when 'success'
- @state = :success
- when 'failure'
- @state = :failure
- end
- nil
- end
- end
-end
View
18 lib/dalli/sasl/plain.rb
@@ -1,18 +0,0 @@
-module SASL
- ##
- # RFC 4616:
- # http://tools.ietf.org/html/rfc4616
- class Plain < Mechanism
-
- def start
- @state = nil
- message = [preferences.authzid.to_s,
- preferences.username,
- preferences.password].join("\000")
- ['auth', message]
- end
- end
-
- MECHANISMS['PLAIN'] = SASL::Plain
-
-end
View
14 lib/dalli/server.rb
@@ -456,11 +456,6 @@ def need_auth?
@options[:username] || ENV['MEMCACHE_USERNAME']
end
- def init_sasl
- require 'dalli/sasl/base'
- require 'dalli/sasl/plain'
- end
-
def username
@options[:username] || ENV['MEMCACHE_USERNAME']
end
@@ -470,8 +465,6 @@ def password
end
def sasl_authentication
- init_sasl if !defined?(::SASL)
-
Dalli.logger.info { "Dalli/SASL authenticating as #{username}" }
# negotiate
@@ -484,12 +477,11 @@ def sasl_authentication
content = read(count)
return (Dalli.logger.debug("Authentication not required/supported by server")) if status == 0x81
mechanisms = content.split(' ')
+ raise NotImplementedError, "Dalli only supports the PLAIN authentication mechanism" if !mechanisms.include?('PLAIN')
# request
- sasl = ::SASL.new(mechanisms)
- msg = sasl.start[1]
- mechanism = sasl.name
- #p [mechanism, msg]
+ mechanism = 'PLAIN'
+ msg = "\x0#{username}\x0#{password}"
req = [REQUEST, OPCODES[:auth_request], mechanism.bytesize, 0, 0, 0, mechanism.bytesize + msg.bytesize, 0, 0, mechanism, msg].pack(FORMAT[:auth_request])
write(req)
View
20 test/test_sasl.rb
@@ -24,6 +24,15 @@ class TestSasl < Test::Unit::TestCase
end
end
+ should 'fail SASL authentication with wrong options' do
+ memcached(19124, '-S') do |dc|
+ dc = Dalli::Client.new('localhost:19124', :username => 'foo', :password => 'wrongpwd')
+ assert_raise Dalli::DalliError, /32/ do
+ dc.set('abc', 123)
+ end
+ end
+ end
+
# OSX: Create a SASL user for the memcached application like so:
#
# saslpasswd2 -a memcached -c testuser
@@ -55,7 +64,7 @@ class TestSasl < Test::Unit::TestCase
should 'pass SASL authentication with options' do
memcached(19124, '-S') do |dc|
- dc = Dalli::Client.new('localhost:11211', :username => 'testuser', :password => 'testtest')
+ dc = Dalli::Client.new('localhost:19124', :username => 'testuser', :password => 'testtest')
# I get "Dalli::DalliError: Error authenticating: 32" in OSX
# but SASL works on Heroku servers. YMMV.
assert_equal true, dc.set('abc', 123)
@@ -66,14 +75,5 @@ class TestSasl < Test::Unit::TestCase
end
end
- should 'fail SASL authentication with wrong options' do
- memcached(19124, '-S') do |dc|
- dc = Dalli::Client.new('localhost:11211', :username => 'foo', :password => 'wrongpwd')
- assert_raise Dalli::DalliError, /32/ do
- dc.set('abc', 123)
- end
- end
- end
-
end
end

0 comments on commit 1e3ceca

Please sign in to comment.