lib/net/ssh/kerberos/gss/api.rb in net-ssh-kerberos-0.1.2 vs lib/net/ssh/kerberos/gss/api.rb in net-ssh-kerberos-0.1.3

- old
+ new

@@ -1,4 +1,163 @@ +require 'dl/import' +require 'dl/struct' -module Net; module SSH; module Kerberos; module GSS; class API +module Net; module SSH; module Kerberos; module GSS; -end; end; end; end; end + module API + + extend DL::Importable + + def self.struct2(fields, &block) + t = struct fields + return t unless block_given? + t.instance_variable_set :@methods, Module.new(&block) + class << t + alias :new_struct :new + def new(ptr) + mem = new_struct(ptr) + mem.extend @methods + mem + end + end + t + end + + if RUBY_PLATFORM =~ /cygwin/ + dlload('cyggss-1.dll') + else + dlload('libgssapi_krb5.so') + end + + typealias 'OM_uint32', 'unsigned int' + typealias 'size_t', 'unsigned int' + + GssBuffer = struct [ "size_t length", "char *value" ] + typealias 'gss_buffer_desc', 'GssBuffer' + typealias 'gss_buffer_t', 'gss_buffer_desc *' + GssOID = struct2 [ "OM_uint32 length", "char *elements" ] do + def to_hex + s = elements.to_s + s.unpack("H2" * s.length).join ' ' + end + end + typealias 'gss_OID_desc', 'GssOID' + typealias 'gss_OID', 'gss_OID_desc *' + GssOIDSet = struct [ "size_t count", "gss_OID elements" ] + typealias 'gss_OID_set_desc', 'GssOIDSet' + typealias 'gss_OID_set', 'gss_OID_set_desc *' + + typealias 'gss_ctx_id_t', 'void *' + typealias 'gss_cred_id_t', 'void *' + typealias 'gss_name_t', 'void *' + typealias 'gss_qop_t', 'OM_uint32' + typealias 'gss_cred_usage_t', 'int' + + GssNameRef = struct [ "gss_name_t handle" ] + GssContextRef = struct [ "gss_ctx_id_t handle" ] + GssCredRef = struct [ "gss_cred_id_t handle" ] + OM_uint32Ref = struct [ "OM_uint32 value" ] + GssCredUsageRef = struct [ "int value" ] + + GssOIDRef = struct2 [ "GssOID *ptr" ] do + def oid + @oid = GssOID.new(ptr) if (@oid.nil? or @oid.to_ptr != ptr) and ! ptr.nil? + @oid + end + end + + GssOIDSetRef = struct2 [ "GssOIDSet *ptr" ] do + def oidset + @oidset = GssOIDSet.new(ptr) if (@oidset.nil? or @oidset.to_ptr != ptr) and ! ptr.nil? + @oidset + end + end + + class GssResult < Struct.new(:major, :minor, :status, :calling_error, :routine_error) + def initialize(result, minor=nil) + self.major = (result >> 16) & 0x0000ffff + self.minor = minor.value if minor.respond_to? :value + self.status = result & 0x0000ffff + self.calling_error = (major >> 8) & 0x00ff + self.routine_error = major & 0x00ff + end + + def ok?; major.zero? end + + def complete?; status.zero? end + + def incomplete?; false end + + def failure?; major.nonzero? end + + def temporary_failure? + routine_error==GSS_S_CREDENTIALS_EXPIRED || + routine_error==GSS_S_CONTEXT_EXPIRED || + routine_error==GSS_S_UNAVAILABLE + end + + def to_s; "%#4.4x%4.4x [%#8.8x]" % [major, status, minor] end + end + + extern "OM_uint32 gss_acquire_cred (OM_uint32 *, gss_name_t, OM_uint32, gss_OID_set, gss_cred_usage_t, gss_cred_id_t *, gss_OID_set *, OM_uint32 *)" + extern "OM_uint32 gss_inquire_cred (OM_uint32 *, gss_cred_id_t, gss_name_t *, OM_uint32 *, gss_cred_usage_t *, gss_OID_set *)" + extern "OM_uint32 gss_release_cred (OM_uint32 *, gss_cred_id_t *)" + extern "OM_uint32 gss_import_name (OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *)" + extern "OM_uint32 gss_release_name (OM_uint32 *, gss_name_t *)" + extern "OM_uint32 gss_display_name (OM_uint32 *, gss_name_t, gss_buffer_t, gss_OID *)" + extern "OM_uint32 gss_release_buffer (OM_uint32 *, gss_buffer_t)" + extern "OM_uint32 gss_release_oid_set (OM_uint32 *, gss_OID_set *)" + extern "OM_uint32 gss_init_sec_context (OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, gss_name_t, gss_OID, OM_uint32, OM_uint32, void *, gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *)" + extern "OM_uint32 gss_delete_sec_context (OM_uint32 *, gss_ctx_id_t *, gss_buffer_t)" + extern "OM_uint32 gss_get_mic(OM_uint32 *, gss_ctx_id_t, gss_qop_t, gss_buffer_t, gss_buffer_t)" + + if @LIBS.empty? and ! defined? Net::SSH::Kerberos::SSPI::Context + $stderr.puts "error: Failed to a find a supported GSS implementation on this platform (#{RUBY_PLATFORM})" + end + end + + GSS_C_INITIATE = 1 + + GSS_C_DELEG_FLAG = 1 + GSS_C_MUTUAL_FLAG = 2 + GSS_C_REPLAY_FLAG = 4 + GSS_C_SEQUENCE_FLAG = 8 + GSS_C_CONF_FLAG = 16 + GSS_C_INTEG_FLAG = 32 + GSS_C_ANON_FLAG = 64 + GSS_C_PROT_READY_FLAG = 128 + GSS_C_TRANS_FLAG = 256 + + GSS_C_NO_NAME = nil + GSS_C_NO_BUFFER = nil + GSS_C_NO_OID = nil + GSS_C_NO_OID_SET = nil + GSS_C_NO_CONTEXT = nil + GSS_C_NO_CREDENTIAL = nil + GSS_C_NO_CHANNEL_BINDINGS = nil + GSS_C_QOP_DEFAULT = 0 + + GSS_S_COMPLETE = 0 + GSS_S_CONTINUE_NEEDED = 1 + GSS_S_DUPLICATE_TOKEN = 2 + GSS_S_OLD_TOKEN = 4 + GSS_S_UNSEQ_TOKEN = 8 + GSS_S_GAP_TOKEN = 16 + + #-- + # GSSAPI / Kerberos 5 OID(s) + #++ + GSS_C_NT_PRINCIPAL = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01" + GSS_C_NT_MACHINE_UID_NAME = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02" + GSS_C_NT_STRING_UID_NAME = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03" + GSS_C_NT_HOSTBASED_SERVICE = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" + GSS_C_NT_ANONYMOUS = "\x2b\x06\01\x05\x06\x03" + GSS_C_NT_EXPORT_NAME = "\x2b\x06\01\x05\x06\x04" + GSS_KRB5_MECH = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" + GSS_KRB5_MECH_USER2USER = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x03" + + #-- + # GSSAPI / Kerberos 5 Deprecated / Proprietary OID(s) + #++ + GSS_C_NT_HOSTBASED_SERVICE_X = "\x2b\x06\x01\x05\x06\x02" + +end; end; end; end