summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Ross <tross@apache.org>2009-01-20 21:26:28 +0000
committerTed Ross <tross@apache.org>2009-01-20 21:26:28 +0000
commit861692abf515cf136e86e70446d005e7849a0f87 (patch)
tree10025e3499876dbdae8697f2dda4c68b4ec55933
parent15488eba1c867bac8b6db1f7ad870b277c4fa748 (diff)
downloadqpid-python-861692abf515cf136e86e70446d005e7849a0f87.tar.gz
QPID-1602 SASL Authentication, Authorization, and Security Layer for Ruby Client.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@736111 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--ruby/Rakefile37
-rw-r--r--ruby/ext/sasl/extconf.rb10
-rw-r--r--ruby/ext/sasl/sasl.c432
-rw-r--r--ruby/lib/qpid/delegates.rb36
-rw-r--r--ruby/lib/qpid/framer.rb35
-rw-r--r--ruby/lib/qpid/qmf.rb43
6 files changed, 564 insertions, 29 deletions
diff --git a/ruby/Rakefile b/ruby/Rakefile
index 64044ca351..7ac6c09eeb 100644
--- a/ruby/Rakefile
+++ b/ruby/Rakefile
@@ -27,20 +27,48 @@ PKG_NAME='ruby-qpid'
PKG_VERSION='0.10.2'
GEM_NAME='qpid'
+EXT_CONF="ext/sasl/extconf.rb"
+MAKEFILE="ext/sasl/Makefile"
+SASL_MODULE="ext/sasl/sasl.so"
+SASL_SRC=SASL_MODULE.gsub(/.so$/, ".c")
+
#
# Additional files for clean/clobber
#
-CLEAN.include [ "**/*~", "lib/*/spec_cache" ]
+CLEAN.include [ "**/*~", "lib/*/spec_cache", SASL_MODULE, "ext/**/*.o" ]
+
+CLOBBER.include [ "config.save", "ext/**/mkmf.log",
+ MAKEFILE ]
+
+file MAKEFILE => EXT_CONF do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "ruby #{File::basename(EXT_CONF)}"
+ $stderr.puts "Failed to run extconf"
+ break
+ end
+ end
+end
+
+file SASL_MODULE => [ MAKEFILE, SASL_SRC ] do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "make"
+ $stderr.puts "make failed"
+ break
+ end
+ end
+end
+desc "Build the native library"
+task :build => SASL_MODULE
Rake::TestTask.new(:test) do |t|
t.test_files = FileList['tests/*.rb'].exclude("tests/util.rb")
- t.libs = [ 'lib' ]
+ t.libs = [ 'lib', 'ext/sasl' ]
end
Rake::TestTask.new(:"test_0-8") do |t|
t.test_files = FileList["tests_0-8/*.rb"]
- t.libs = [ 'lib' ]
+ t.libs = [ 'lib', 'ext/sasl' ]
end
desc "Create cached versions of the AMQP specs"
@@ -63,7 +91,8 @@ end
PKG_FILES = FileList[
"DISCLAIMER", "LICENSE.txt", "NOTICE.txt",
"Rakefile", "RELEASE_NOTES",
- "lib/**/*.rb", "lib/*/spec_cache/*.rb*", "tests/**/*", "examples/**"
+ "lib/**/*.rb", "lib/*/spec_cache/*.rb*", "tests/**/*", "examples/**", "ext/**/*.[ch]",
+ "ext/**/MANIFEST", "ext/**/extconf.rb"
]
DIST_FILES = FileList[
diff --git a/ruby/ext/sasl/extconf.rb b/ruby/ext/sasl/extconf.rb
new file mode 100644
index 0000000000..5c9a24c35c
--- /dev/null
+++ b/ruby/ext/sasl/extconf.rb
@@ -0,0 +1,10 @@
+require 'mkmf'
+
+extension_name = 'sasl'
+have_library("c", "main")
+
+unless have_library("sasl2")
+ raise "Package cyrus-sasl-devel not found"
+end
+
+create_makefile(extension_name)
diff --git a/ruby/ext/sasl/sasl.c b/ruby/ext/sasl/sasl.c
new file mode 100644
index 0000000000..2a2a829aa8
--- /dev/null
+++ b/ruby/ext/sasl/sasl.c
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <sasl/sasl.h>
+#include <ruby.h>
+
+static VALUE mSasl;
+
+#define INPUT_SIZE 512
+#define MECH_SIZE 32
+
+typedef void* sasl_context_t;
+
+#define QSASL_OK 0
+#define QSASL_CONTINUE 1
+#define QSASL_FAILED 2
+
+typedef struct {
+ char magic[8];
+ sasl_conn_t* conn;
+ sasl_callback_t callbacks[8];
+ char* userName;
+ char* password;
+ unsigned int minSsf;
+ unsigned int maxSsf;
+ char mechanism[MECH_SIZE];
+ char input[INPUT_SIZE];
+} context_t;
+
+//
+// Resolve forward references
+//
+static VALUE qsasl_free(int, VALUE*, VALUE);
+
+//
+// Validate an input string to ensure that it is either NULL or of reasonable size.
+//
+static int qsasl_valid(char* str)
+{
+ int idx;
+
+ if (str == 0)
+ return 1;
+
+ for (idx = 0; idx < INPUT_SIZE; idx++) {
+ if (str[idx] == '\0')
+ return 1;
+ }
+
+ return 0;
+}
+
+//
+// SASL callback for identity and authentication identity.
+//
+static int qsasl_cb_user(void* _context, int id, const char **result, unsigned *len)
+{
+ context_t* context = (context_t*) _context;
+
+ if (context->userName)
+ *result = context->userName;
+
+ return SASL_OK;
+}
+
+//
+// SASL callback for passwords.
+//
+static int qsasl_cb_password(sasl_conn_t* conn, void* _context, int id, sasl_secret_t **psecret)
+{
+ context_t* context = (context_t*) _context;
+ sasl_secret_t* secret;
+ size_t length;
+
+ if (context->password)
+ length = strlen(context->password);
+ else
+ length = 0;
+
+ secret = (sasl_secret_t*) malloc(sizeof(sasl_secret_t) + length);
+ secret->len = length;
+ if (length)
+ memcpy(secret->data, context->password, length);
+ *psecret = secret;
+
+ return SASL_OK;
+}
+
+//
+// Interactively prompt the user for authentication data.
+//
+static void qsasl_prompt(sasl_context_t _context, sasl_interact_t* interact)
+{
+ context_t* context = (context_t*) _context;
+ char *pass;
+ char *input;
+ char passwdPrompt[100];
+
+ if (interact->id == SASL_CB_PASS) {
+ strncpy(passwdPrompt, interact->prompt, 95);
+ strcat(passwdPrompt, ": ");
+ pass = getpass(passwdPrompt);
+ strncpy(context->input, pass, INPUT_SIZE - 1);
+ context->input[INPUT_SIZE - 1] = '\0';
+ } else {
+ printf(interact->prompt);
+ if (interact->defresult) {
+ printf(" (%s)", interact->defresult);
+ }
+ printf(": ");
+ input = fgets(context->input, INPUT_SIZE, stdin);
+ if (input != context->input) {
+ rb_raise(rb_eRuntimeError, "Unexpected EOF on interactive prompt");
+ }
+ }
+
+ interact->result = context->input;
+ interact->len = strlen(context->input);
+}
+
+//
+// Initialize the SASL client library.
+//
+static VALUE qsasl_client_init()
+{
+ int result;
+
+ result = sasl_client_init(0);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError,
+ "sasl_client_init failed: %d - %s",
+ result, sasl_errstring(result, -0, 0));
+ return Qnil;
+}
+
+//
+// Allocate a new SASL client context.
+//
+static VALUE qsasl_client_new(int argc, VALUE *argv, VALUE obj)
+{
+ char* mechanism = 0;
+ char* serviceName = 0;
+ char* hostName = 0;
+ char* userName = 0;
+ char* password = 0;
+ unsigned int minSsf = 0;
+ unsigned int maxSsf = 65535;
+
+ int result;
+ int i = 0;
+ context_t *context;
+ sasl_security_properties_t secprops;
+
+ if (argc != 7)
+ rb_raise(rb_eRuntimeError, "Wrong number of arguments");
+
+ if (!NIL_P(argv[0]))
+ mechanism = StringValuePtr(argv[0]);
+ if (!NIL_P(argv[1]))
+ serviceName = StringValuePtr(argv[1]);
+ if (!NIL_P(argv[2]))
+ hostName = StringValuePtr(argv[2]);
+ if (!NIL_P(argv[3]))
+ userName = StringValuePtr(argv[3]);
+ if (!NIL_P(argv[4]))
+ password = StringValuePtr(argv[4]);
+ minSsf = FIX2INT(argv[5]);
+ maxSsf = FIX2INT(argv[6]);
+
+ if (!qsasl_valid(mechanism) || !qsasl_valid(serviceName) ||
+ !qsasl_valid(hostName) || !qsasl_valid(userName) ||
+ !qsasl_valid(password)) {
+ rb_raise(rb_eRuntimeError, "Invalid string argument");
+ }
+
+ context = (context_t*) malloc(sizeof(context_t));
+ memset(context, 0, sizeof(context_t));
+ strcpy(context->magic, "QSASL01");
+
+ context->minSsf = minSsf;
+ context->maxSsf = maxSsf;
+ if (mechanism != 0) {
+ strncpy(context->mechanism, mechanism, MECH_SIZE - 1);
+ context->mechanism[MECH_SIZE - 1] = '\0';
+ }
+
+ context->callbacks[i].id = SASL_CB_GETREALM;
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = 0;
+
+ if (userName != 0 && userName[0] != '\0') {
+ context->userName = (char*) malloc(strlen(userName) + 1);
+ strcpy(context->userName, userName);
+
+ context->callbacks[i].id = SASL_CB_USER;
+ context->callbacks[i].proc = qsasl_cb_user;
+ context->callbacks[i++].context = context;
+
+ context->callbacks[i].id = SASL_CB_AUTHNAME;
+ context->callbacks[i].proc = qsasl_cb_user;
+ context->callbacks[i++].context = context;
+ }
+
+ context->callbacks[i].id = SASL_CB_PASS;
+ if (password != 0 && password[0] != '\0') {
+ context->password = (char*) malloc(strlen(password) + 1);
+ strcpy(context->password, password);
+
+ context->callbacks[i].proc = qsasl_cb_password;
+ } else
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = context;
+
+ context->callbacks[i].id = SASL_CB_LIST_END;
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = 0;
+
+ result = sasl_client_new(serviceName, hostName, 0, 0,
+ context->callbacks, 0, &context->conn);
+
+ if (result != SASL_OK) {
+ context->conn = 0;
+ qsasl_free(1, (VALUE*) &context, Qnil);
+ rb_raise(rb_eRuntimeError, "sasl_client_new failed: %d - %s",
+ result, sasl_errstring(result, 0, 0));
+ }
+
+ secprops.min_ssf = minSsf;
+ secprops.max_ssf = maxSsf;
+ secprops.maxbufsize = 65535;
+ secprops.property_names = 0;
+ secprops.property_values = 0;
+ secprops.security_flags = 0;//TODO: provide means for application to configure these
+
+ result = sasl_setprop(context->conn, SASL_SEC_PROPS, &secprops);
+ if (result != SASL_OK) {
+ qsasl_free(1, (VALUE*) &context, Qnil);
+ rb_raise(rb_eRuntimeError, "sasl_setprop failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+ }
+
+ return (VALUE) context;
+}
+
+//
+// Free a SASL client context.
+//
+static VALUE qsasl_free(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+
+ if (argc == 1)
+ context = (context_t*) argv[0];
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ if (context->conn)
+ sasl_dispose(&context->conn);
+ if (context->userName)
+ free(context->userName);
+ if (context->password)
+ free(context->password);
+ free(context);
+
+ return Qnil;
+}
+
+//
+// Start the SASL exchange from the client's point of view.
+//
+static VALUE qsasl_client_start(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ char* mechList;
+ char* mechToUse;
+ int result;
+ const char* response;
+ unsigned int len;
+ sasl_interact_t* interact = 0;
+ const char* chosen;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ mechList = StringValuePtr(argv[1]);
+ } else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ if (strlen(context->mechanism) == 0)
+ mechToUse = mechList;
+ else
+ mechToUse = context->mechanism;
+
+ do {
+ result = sasl_client_start(context->conn, mechToUse, &interact,
+ &response, &len, &chosen);
+ if (result == SASL_INTERACT) {
+ qsasl_prompt(context, interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ rb_raise(rb_eRuntimeError, "sasl_client_start failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ return rb_ary_new3(3, INT2NUM(result), rb_str_new(response, len), rb_str_new2(chosen));
+}
+
+//
+// Take a step in the SASL exchange (only needed for multi-challenge mechanisms).
+//
+static VALUE qsasl_client_step(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE challenge;
+ int result;
+ const char* response;
+ unsigned int len;
+ sasl_interact_t* interact = 0;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ challenge = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ do {
+ result = sasl_client_step(context->conn,
+ RSTRING(challenge)->ptr, RSTRING(challenge)->len,
+ &interact, &response, &len);
+ if (result == SASL_INTERACT) {
+ qsasl_prompt(context, interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ return QSASL_FAILED;
+
+ return rb_ary_new3(2, INT2NUM(result), rb_str_new(response, len));
+}
+
+//
+// Encode transport data for the security layer.
+//
+static VALUE qsasl_encode(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE clearText;
+ const char* outBuffer;
+ unsigned int outSize;
+ int result;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ clearText = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ result = sasl_encode(context->conn,
+ RSTRING(clearText)->ptr, RSTRING(clearText)->len,
+ &outBuffer, &outSize);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError, "sasl_encode failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ return rb_str_new(outBuffer, outSize);
+}
+
+//
+// Decode transport data for the security layer.
+//
+static VALUE qsasl_decode(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE cipherText;
+ const char* outBuffer;
+ unsigned int outSize;
+ int result;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ cipherText = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ result = sasl_decode(context->conn,
+ RSTRING(cipherText)->ptr, RSTRING(cipherText)->len,
+ &outBuffer, &outSize);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError, "sasl_decode failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ return rb_str_new(outBuffer, outSize);
+}
+
+//
+// Initialize the Sasl module.
+//
+void Init_sasl()
+{
+ mSasl = rb_define_module("Sasl");
+
+ rb_define_module_function(mSasl, "client_init", qsasl_client_init, -1);
+ rb_define_module_function(mSasl, "client_new", qsasl_client_new, -1);
+ rb_define_module_function(mSasl, "free", qsasl_free, -1);
+ rb_define_module_function(mSasl, "client_start", qsasl_client_start, -1);
+ rb_define_module_function(mSasl, "client_step", qsasl_client_step, -1);
+ rb_define_module_function(mSasl, "encode", qsasl_encode, -1);
+ rb_define_module_function(mSasl, "decode", qsasl_decode, -1);
+}
diff --git a/ruby/lib/qpid/delegates.rb b/ruby/lib/qpid/delegates.rb
index 21513fc677..9707cdbc76 100644
--- a/ruby/lib/qpid/delegates.rb
+++ b/ruby/lib/qpid/delegates.rb
@@ -18,6 +18,7 @@
#
require 'rbconfig'
+require 'sasl'
module Qpid
@@ -173,9 +174,17 @@ module Qpid
def initialize(connection, args)
super(connection)
- @username = args[:username] || "guest"
- @password = args[:password] || "guest"
- @mechanism= args[:mechanism] || "PLAIN"
+ result = Sasl::client_init
+
+ @mechanism= args[:mechanism]
+ @username = args[:username]
+ @password = args[:password]
+ @service = args[:service] || "qpidd"
+ @min_ssf = args[:min_ssf] || 0
+ @max_ssf = args[:max_ssf] || 65535
+
+ @saslConn = Sasl.client_new(@mechanism, @service, args[:host],
+ @username, @password, @min_ssf, @max_ssf)
end
def start
@@ -184,18 +193,31 @@ module Qpid
end
def connection_start(ch, start)
- r = "\0%s\0%s" % [@username, @password]
+ mech_list = ""
+ start.mechanisms.each do |m|
+ mech_list += m + " "
+ end
+ resp = Sasl.client_start(@saslConn, mech_list)
ch.connection_start_ok(:client_properties => PROPERTIES,
- :mechanism => @mechanism,
- :response => r)
+ :mechanism => resp[2],
+ :response => resp[1])
+ end
+
+ def connection_secure(ch, secure)
+ resp = Sasl.client_step(@saslConn, secure.challenge)
+ ch.connection_secure_ok(:response => resp[1])
end
def connection_tune(ch, tune)
- ch.connection_tune_ok()
+ ch.connection_tune_ok(:channel_max => tune.channel_max,
+ :max_frame_size => tune.max_frame_size,
+ :heartbeat => 0)
ch.connection_open()
+ @connection.security_layer_tx = @saslConn
end
def connection_open_ok(ch, open_ok)
+ @connection.security_layer_rx = @saslConn
@connection.opened = true
@connection.signal
end
diff --git a/ruby/lib/qpid/framer.rb b/ruby/lib/qpid/framer.rb
index 2a565a69a8..abac221f00 100644
--- a/ruby/lib/qpid/framer.rb
+++ b/ruby/lib/qpid/framer.rb
@@ -19,6 +19,7 @@
require 'monitor'
require 'logger'
+require 'sasl'
module Qpid
@@ -109,21 +110,31 @@ module Qpid
def initialize(sock)
@sock = sock
@sock.extend(MonitorMixin)
- @buf = ""
+ @tx_buf = ""
+ @rx_buf = ""
+ @security_layer_tx = nil
+ @security_layer_rx = nil
+ @maxbufsize = 65535
end
attr_reader :sock
+ attr_accessor :security_layer_tx, :security_layer_rx
def aborted? ; false ; end
def write(buf)
- @buf += buf
+ @tx_buf += buf
end
def flush
@sock.synchronize do
- _write(@buf)
- @buf = ""
+ if @security_layer_tx
+ cipher_buf = Sasl.encode(@security_layer_tx, @tx_buf)
+ _write(cipher_buf)
+ else
+ _write(@tx_buf)
+ end
+ @tx_buf = ""
frm.debug("FLUSHED") if frm
end
end
@@ -139,12 +150,14 @@ module Qpid
end
def read(n)
- data = ""
- while data.size < n
+ while @rx_buf.size < n
begin
- s = @sock.read(n - data.size)
+ s = @sock.recv(@maxbufsize)
+ if @security_layer_rx
+ s = Sasl.decode(@security_layer_rx, s)
+ end
rescue IOError => e
- raise e if data != ""
+ raise e if @rx_buf != ""
@sock.close unless @sock.closed?
raise Closed
end
@@ -153,9 +166,11 @@ module Qpid
@sock.close unless @sock.closed?
raise Closed
end
- data += s
- raw.debug("RECV #{n}/#{data.size} #{s.inspect}") if raw
+ @rx_buf += s
+ raw.debug("RECV #{n}/#{@rx_buf.size} #{s.inspect}") if raw
end
+ data = @rx_buf[0, n]
+ @rx_buf = @rx_buf[n, @rx_buf.size - n]
return data
end
diff --git a/ruby/lib/qpid/qmf.rb b/ruby/lib/qpid/qmf.rb
index 0309b65a6c..ee165305c3 100644
--- a/ruby/lib/qpid/qmf.rb
+++ b/ruby/lib/qpid/qmf.rb
@@ -65,16 +65,15 @@ module Qpid::Qmf
class BrokerURL
- attr_reader :host, :port, :auth_name, :auth_pass, :auth_mech
+ attr_reader :host, :port, :auth_name, :auth_pass
def initialize(text)
uri = URI.parse(text)
@host = uri.host
@port = uri.port ? uri.port : 5672
- @auth_name = uri.user ? uri.user : "guest"
- @auth_pass = uri.password ? uri.password: "guest"
- @auth_mech = "PLAIN"
+ @auth_name = uri.user
+ @auth_pass = uri.password
return uri
end
@@ -178,9 +177,32 @@ module Qpid::Qmf
end
# Connect to a Qpid broker. Returns an object of type Broker
- def add_broker(target="amqp://localhost")
+ #
+ # To supply a username for authentication, use the URL syntax:
+ #
+ # amqp://username@hostname:port
+ #
+ # If the broker needs a password for the client, an interactive prompt will be
+ # provided to the user.
+ #
+ # To supply a username and a password, use
+ #
+ # amqp://username:password@hostname:port
+ #
+ # The following keyword arguments may be used to control authentication:
+ #
+ # :mechanism - SASL mechanism (i.e. "PLAIN", "GSSAPI", "ANONYMOUS", etc.
+ # - defaults to unspecified (the system chooses for you)
+ # :service - SASL service name (i.e. the kerberos principal of the broker)
+ # - defaults to "qpidd"
+ # :min_ssf - Minimum Security Strength Factor for SASL security layers
+ # - defaults to 0
+ # :max_ssf - Maximum Security Strength Factor for SASL security layers
+ # - defaults to 65535
+ #
+ def add_broker(target = "amqp://localhost", kwargs = {})
url = BrokerURL.new(target)
- broker = Broker.new(self, url.host, url.port, url.auth_mech, url.auth_name, url.auth_pass)
+ broker = Broker.new(self, url.host, url.port, url.auth_name, url.auth_pass, kwargs)
unless broker.connected? || @manage_connections
raise broker.error
end
@@ -1201,7 +1223,7 @@ module Qpid::Qmf
attr_accessor :broker_id, :sync_result
- def initialize(session, host, port, auth_mech, auth_name, auth_pass)
+ def initialize(session, host, port, auth_name, auth_pass, kwargs)
super()
# For debugging..
@@ -1212,6 +1234,8 @@ module Qpid::Qmf
@port = port
@auth_name = auth_name
@auth_pass = auth_pass
+ @auth_mechanism = kwargs[:mechanism]
+ @auth_service = kwargs[:service]
@broker_bank = 1
@agents = {}
@agents["1.0"] = Agent.new(self, 0, "BrokerAgent")
@@ -1368,8 +1392,11 @@ module Qpid::Qmf
# FIXME: Need sth for Qpid::Util::connect
@conn = Qpid::Connection.new(TCPSocket.new(@host, @port),
+ :mechanism => @auth_mechanism,
:username => @auth_name,
- :password => @auth_pass)
+ :password => @auth_pass,
+ :host => @host,
+ :service => @auth_service)
@conn.start
@reply_name = "reply-%s" % amqp_session_id
@amqp_session = @conn.session(@amqp_session_id)