From 7154e46361c1cacc1ce4c09b3db9eb07828f8e3a Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 20 May 2009 21:15:32 +0000 Subject: Numerous fixes in the qmf console for Ruby Added proper connection close if the SASL security context expires. Added :timeout and :async features to qmf console. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@776856 13f79535-47bb-0310-9956-ffa450edef68 --- ruby/ext/sasl/sasl.c | 40 ++++++++++++++++++++++++++++ ruby/lib/qpid/connection.rb | 3 ++- ruby/lib/qpid/delegates.rb | 2 ++ ruby/lib/qpid/framer.rb | 2 ++ ruby/lib/qpid/qmf.rb | 63 +++++++++++++++++++++++++++------------------ ruby/lib/qpid/session.rb | 4 +-- ruby/tests/qmf.rb | 4 +-- 7 files changed, 88 insertions(+), 30 deletions(-) (limited to 'ruby') diff --git a/ruby/ext/sasl/sasl.c b/ruby/ext/sasl/sasl.c index 2a2a829aa8..2d4e40d30e 100644 --- a/ruby/ext/sasl/sasl.c +++ b/ruby/ext/sasl/sasl.c @@ -41,6 +41,7 @@ typedef struct { sasl_callback_t callbacks[8]; char* userName; char* password; + char* operUserName; unsigned int minSsf; unsigned int maxSsf; char mechanism[MECH_SIZE]; @@ -280,6 +281,8 @@ static VALUE qsasl_free(int argc, VALUE *argv, VALUE obj) free(context->userName); if (context->password) free(context->password); + if (context->operUserName) + free(context->operUserName); free(context); return Qnil; @@ -294,10 +297,12 @@ static VALUE qsasl_client_start(int argc, VALUE *argv, VALUE obj) char* mechList; char* mechToUse; int result; + int propResult; const char* response; unsigned int len; sasl_interact_t* interact = 0; const char* chosen; + const char* operName; if (argc == 2) { context = (context_t*) argv[0]; @@ -322,6 +327,14 @@ static VALUE qsasl_client_start(int argc, VALUE *argv, VALUE obj) rb_raise(rb_eRuntimeError, "sasl_client_start failed: %d - %s", result, sasl_errdetail(context->conn)); + if (result == SASL_OK) { + propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName); + if (propResult == SASL_OK) { + context->operUserName = (char*) malloc(strlen(operName) + 1); + strcpy(context->operUserName, operName); + } + } + return rb_ary_new3(3, INT2NUM(result), rb_str_new(response, len), rb_str_new2(chosen)); } @@ -333,7 +346,9 @@ static VALUE qsasl_client_step(int argc, VALUE *argv, VALUE obj) context_t* context; VALUE challenge; int result; + int propResult; const char* response; + const char* operName; unsigned int len; sasl_interact_t* interact = 0; @@ -356,9 +371,33 @@ static VALUE qsasl_client_step(int argc, VALUE *argv, VALUE obj) if (result != SASL_OK && result != SASL_CONTINUE) return QSASL_FAILED; + if (result == SASL_OK) { + propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName); + if (propResult == SASL_OK) { + context->operUserName = (char*) malloc(strlen(operName) + 1); + strcpy(context->operUserName, operName); + } + } + return rb_ary_new3(2, INT2NUM(result), rb_str_new(response, len)); } +static VALUE qsasl_user_id(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->operUserName) + return rb_str_new2(context->operUserName); + + return Qnil; +} + // // Encode transport data for the security layer. // @@ -427,6 +466,7 @@ void Init_sasl() 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, "user_id", qsasl_user_id, -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/connection.rb b/ruby/lib/qpid/connection.rb index 59d88196a3..d2efbfb263 100644 --- a/ruby/lib/qpid/connection.rb +++ b/ruby/lib/qpid/connection.rb @@ -36,7 +36,7 @@ module Qpid include MonitorMixin attr_reader :spec, :attached, :sessions, :thread - attr_accessor :opened, :failed, :close_code + attr_accessor :opened, :failed, :close_code, :user_id def initialize(sock, args={}) super(sock) @@ -58,6 +58,7 @@ module Qpid @thread = nil @channel_max = 65535 + @user_id = nil @delegate = delegate.call(self, args) end diff --git a/ruby/lib/qpid/delegates.rb b/ruby/lib/qpid/delegates.rb index 8d866e895f..6d655067ef 100644 --- a/ruby/lib/qpid/delegates.rb +++ b/ruby/lib/qpid/delegates.rb @@ -202,6 +202,7 @@ module Qpid end begin resp = Sasl.client_start(@saslConn, mech_list) + @connection.user_id = Sasl.user_id(@saslConn) ch.connection_start_ok(:client_properties => PROPERTIES, :mechanism => resp[2], :response => resp[1]) @@ -214,6 +215,7 @@ module Qpid def connection_secure(ch, secure) resp = Sasl.client_step(@saslConn, secure.challenge) + @connection.user_id = Sasl.user_id(@saslConn) ch.connection_secure_ok(:response => resp[1]) end diff --git a/ruby/lib/qpid/framer.rb b/ruby/lib/qpid/framer.rb index abac221f00..d057605383 100644 --- a/ruby/lib/qpid/framer.rb +++ b/ruby/lib/qpid/framer.rb @@ -137,6 +137,8 @@ module Qpid @tx_buf = "" frm.debug("FLUSHED") if frm end + rescue + @sock.close unless @sock.closed? end def _write(buf) diff --git a/ruby/lib/qpid/qmf.rb b/ruby/lib/qpid/qmf.rb index ebca7ee5ab..b7309155c3 100644 --- a/ruby/lib/qpid/qmf.rb +++ b/ruby/lib/qpid/qmf.rb @@ -252,7 +252,7 @@ module Qpid::Qmf args = { :exchange => "qpid.management", :queue => broker.topic_name, :binding_key => "console.obj.*.*.#{package_name}.#" } - broker.amqpSession.exchange_bind(args) + broker.amqp_session.exchange_bind(args) end end @@ -264,7 +264,7 @@ module Qpid::Qmf args = { :exchange => "qpid.management", :queue => broker.topic_name, :binding_key=> "console.obj.*.*.#{package_name}.#{class_name}.#" } - broker.amqpSession.exchange_bind(args) + broker.amqp_session.exchange_bind(args) end end @@ -277,7 +277,7 @@ module Qpid::Qmf args = { :exchange => "qpid.management", :queue => broker.topic_name, :binding_key => "console.obj.*.*.#{pname}.#{cname}.#" } - broker.amqpSession.exchange_bind(args) + broker.amqp_session.exchange_bind(args) end end @@ -319,7 +319,7 @@ module Qpid::Qmf # The default timeout for this synchronous operation is 60 seconds. To change the timeout, # use the following argument: # - # :_timeout =