Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
L
libzmq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
libzmq
Commits
1445516c
Commit
1445516c
authored
Oct 03, 2013
by
Mike Gatny
Committed by
Chris Busbey
Apr 24, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Establishing GSSAPI sec context is working now
parent
6290ba16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
162 additions
and
137 deletions
+162
-137
configure.ac
configure.ac
+1
-0
gssapi_client.cpp
src/gssapi_client.cpp
+75
-105
gssapi_client.hpp
src/gssapi_client.hpp
+8
-11
gssapi_mechanism_base.cpp
src/gssapi_mechanism_base.cpp
+46
-1
gssapi_mechanism_base.hpp
src/gssapi_mechanism_base.hpp
+25
-0
gssapi_server.cpp
src/gssapi_server.cpp
+0
-0
gssapi_server.hpp
src/gssapi_server.hpp
+7
-20
No files found.
configure.ac
View file @
1445516c
...
...
@@ -305,6 +305,7 @@ else
AC_CHECK_LIB([sodium], [sodium_init],,AC_MSG_WARN(libsodium is needed for CURVE security))
fi
AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context],,AC_MSG_WARN(libgssapi_krb5 is needed for GSSAPI security))
#
# Check if the compiler supports -fvisibility=hidden flag. MinGW32 uses __declspec
...
...
src/gssapi_client.cpp
View file @
1445516c
...
...
@@ -34,12 +34,24 @@
zmq
::
gssapi_client_t
::
gssapi_client_t
(
const
options_t
&
options_
)
:
gssapi_mechanism_base_t
(),
mechanism_t
(
options_
),
state
(
sending_hello
)
state
(
send_next_token
),
token_ptr
(
GSS_C_NO_BUFFER
),
mechs
(),
security_context_established
(
false
)
{
maj_stat
=
GSS_S_COMPLETE
;
service_name
=
strdup
(
"host"
);
/// FIXME add service_name to options
mechs
.
elements
=
NULL
;
mechs
.
count
=
0
;
}
zmq
::
gssapi_client_t
::~
gssapi_client_t
()
{
if
(
service_name
)
free
(
service_name
);
/// FIXME release this or not?
if
(
cred
)
gss_release_cred
(
&
min_stat
,
&
cred
);
}
int
zmq
::
gssapi_client_t
::
next_handshake_command
(
msg_t
*
msg_
)
...
...
@@ -47,24 +59,18 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
int
rc
=
0
;
switch
(
state
)
{
case
send
ing_hello
:
rc
=
produce_
hello
(
msg_
);
case
send
_next_token
:
rc
=
produce_
next_token
(
msg_
);
if
(
rc
==
0
)
state
=
waiting_for_welcome
;
state
=
recv_next_token
;
break
;
case
sending_initiate
:
rc
=
produce_initiate
(
msg_
);
if
(
rc
==
0
)
state
=
waiting_for_token
;
break
;
case
sending_token
:
rc
=
produce_token
(
msg_
,
0
,
(
char
*
)
"o, hai!"
,
7
);
if
(
rc
==
0
)
state
=
waiting_for_ready
;
//state = expecting_another_token? waiting_for_token: waiting_for_ready;
case
almost_ready
:
state
=
ready
;
break
;
default
:
errno
=
EAGAIN
;
rc
=
-
1
;
break
;
}
return
rc
;
}
...
...
@@ -72,135 +78,99 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
int
zmq
::
gssapi_client_t
::
process_handshake_command
(
msg_t
*
msg_
)
{
int
rc
=
0
;
int
flags
=
0
;
gss_buffer_desc
buf
;
buf
.
value
=
NULL
;
buf
.
length
=
0
;
switch
(
state
)
{
case
waiting_for_welcome
:
rc
=
process_
welcome
(
msg_
);
case
recv_next_token
:
rc
=
process_
next_token
(
msg_
);
if
(
rc
==
0
)
state
=
se
nding_initiate
;
state
=
se
curity_context_established
?
almost_ready
:
send_next_token
;
break
;
case
waiting_for_token
:
rc
=
process_token
(
msg_
,
flags
,
&
buf
.
value
,
buf
.
length
);
if
(
rc
==
0
)
state
=
sending_token
;
// state = expecting_another_token? sending_token: sending_ready;
break
;
case
waiting_for_ready
:
rc
=
process_ready
(
msg_
);
if
(
rc
==
0
)
state
=
ready
;
case
almost_ready
:
state
=
ready
;
break
;
default
:
errno
=
EPROTO
;
rc
=
-
1
;
break
;
}
if
(
buf
.
value
)
{
free
(
buf
.
value
);
}
if
(
rc
==
0
)
{
rc
=
msg_
->
close
();
errno_assert
(
rc
==
0
);
rc
=
msg_
->
init
();
errno_assert
(
rc
==
0
);
}
return
rc
;
}
bool
zmq
::
gssapi_client_t
::
is_handshake_complete
()
const
{
fprintf
(
stderr
,
"%s:%d: is_handshake_complete=%d, security_context_established=%d
\n
"
,
__FILE__
,
__LINE__
,
(
state
==
ready
),
security_context_established
);
/// FIXME remove
return
state
==
ready
;
}
int
zmq
::
gssapi_client_t
::
produce_
hello
(
msg_t
*
msg_
)
const
int
zmq
::
gssapi_client_t
::
produce_
next_token
(
msg_t
*
msg_
)
{
const
std
::
string
username
=
"admin"
;
zmq_assert
(
username
.
length
()
<
256
);
const
std
::
string
password
=
"secret"
;
zmq_assert
(
password
.
length
()
<
256
);
const
size_t
command_size
=
6
+
1
+
username
.
length
()
+
1
+
password
.
length
();
const
int
rc
=
msg_
->
init_size
(
command_size
);
errno_assert
(
rc
==
0
);
unsigned
char
*
ptr
=
static_cast
<
unsigned
char
*>
(
msg_
->
data
());
memcpy
(
ptr
,
"
\x05
HELLO"
,
6
);
ptr
+=
6
;
*
ptr
++
=
static_cast
<
unsigned
char
>
(
username
.
length
());
memcpy
(
ptr
,
username
.
c_str
(),
username
.
length
());
ptr
+=
username
.
length
();
*
ptr
++
=
static_cast
<
unsigned
char
>
(
password
.
length
());
memcpy
(
ptr
,
password
.
c_str
(),
password
.
length
());
ptr
+=
password
.
length
();
// First time through, import service_name into target_name
if
(
target_name
==
GSS_C_NO_NAME
)
{
send_tok
.
value
=
service_name
;
send_tok
.
length
=
strlen
(
service_name
);
OM_uint32
maj
=
gss_import_name
(
&
min_stat
,
&
send_tok
,
gss_nt_service_name
,
&
target_name
);
if
(
maj
!=
GSS_S_COMPLETE
)
{
fprintf
(
stderr
,
"%s:%d: failed to import service name
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat); /// FIXME die("parsing name", maj_stat, min_stat);
return
-
1
;
}
}
return
0
;
}
maj_stat
=
gss_init_sec_context
(
&
init_sec_min_stat
,
cred
,
&
context
,
target_name
,
mechs
.
elements
,
gss_flags
,
0
,
NULL
,
token_ptr
,
NULL
,
&
send_tok
,
&
ret_flags
,
NULL
);
if
(
token_ptr
!=
GSS_C_NO_BUFFER
)
free
(
recv_tok
.
value
);
if
(
send_tok
.
length
!=
0
)
{
// server expects another token
fprintf
(
stderr
,
"%s:%d: producing token
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat); /// FIXME die("parsing name", maj_stat, min_stat);
if
(
produce_token
(
msg_
,
TOKEN_CONTEXT
,
send_tok
.
value
,
send_tok
.
length
)
<
0
)
{
gss_release_buffer
(
&
min_stat
,
&
send_tok
);
gss_release_name
(
&
min_stat
,
&
target_name
);
return
-
1
;
}
}
else
fprintf
(
stderr
,
"%s:%d: skip producing token
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat); /// FIXME die("parsing name", maj_stat, min_stat);
int
zmq
::
gssapi_client_t
::
process_welcome
(
msg_t
*
msg_
)
{
const
unsigned
char
*
ptr
=
static_cast
<
unsigned
char
*>
(
msg_
->
data
());
size_t
bytes_left
=
msg_
->
size
();
gss_release_buffer
(
&
min_stat
,
&
send_tok
);
if
(
bytes_left
!=
8
||
memcmp
(
ptr
,
"
\x07
WELCOME"
,
8
))
{
errno
=
EPROTO
;
if
(
maj_stat
!=
GSS_S_COMPLETE
&&
maj_stat
!=
GSS_S_CONTINUE_NEEDED
)
{
fprintf
(
stderr
,
"%s:%d: failed to create GSSAPI security context
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat);
gss_release_name
(
&
min_stat
,
&
target_name
);
if
(
context
!=
GSS_C_NO_CONTEXT
)
gss_delete_sec_context
(
&
min_stat
,
&
context
,
GSS_C_NO_BUFFER
);
return
-
1
;
}
return
0
;
}
int
zmq
::
gssapi_client_t
::
pro
duce_initiate
(
msg_t
*
msg_
)
const
int
zmq
::
gssapi_client_t
::
pro
cess_next_token
(
msg_t
*
msg_
)
{
unsigned
char
*
const
command_buffer
=
(
unsigned
char
*
)
malloc
(
512
);
alloc_assert
(
command_buffer
);
unsigned
char
*
ptr
=
command_buffer
;
// Add mechanism string
memcpy
(
ptr
,
"
\x08
INITIATE"
,
9
);
ptr
+=
9
;
// Add socket type property
const
char
*
socket_type
=
socket_type_string
(
options
.
type
);
ptr
+=
add_property
(
ptr
,
"Socket-Type"
,
socket_type
,
strlen
(
socket_type
));
// Add identity property
if
(
options
.
type
==
ZMQ_REQ
||
options
.
type
==
ZMQ_DEALER
||
options
.
type
==
ZMQ_ROUTER
)
{
ptr
+=
add_property
(
ptr
,
"Identity"
,
options
.
identity
,
options
.
identity_size
);
if
(
maj_stat
==
GSS_S_CONTINUE_NEEDED
)
{
fprintf
(
stderr
,
"%s:%d: processing token
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat); /// FIXME die("parsing name", maj_stat, min_stat);
if
(
process_token
(
msg_
,
token_flags
,
&
recv_tok
.
value
,
recv_tok
.
length
)
<
0
)
{
gss_release_name
(
&
min_stat
,
&
target_name
);
return
-
1
;
}
token_ptr
=
&
recv_tok
;
}
else
fprintf
(
stderr
,
"%s:%d: skip processing token
\n
"
,
__FILE__
,
__LINE__
);
/// FIXME die("creating context", maj_stat, init_sec_min_stat); /// FIXME die("parsing name", maj_stat, min_stat);
const
size_t
command_size
=
ptr
-
command_buffer
;
const
int
rc
=
msg_
->
init_size
(
command_size
);
errno_assert
(
rc
==
0
);
memcpy
(
msg_
->
data
(),
command_buffer
,
command_size
);
free
(
command_buffer
);
if
(
maj_stat
==
GSS_S_COMPLETE
)
security_context_established
=
true
;
return
0
;
}
int
zmq
::
gssapi_client_t
::
process_ready
(
msg_t
*
msg_
)
{
const
unsigned
char
*
ptr
=
static_cast
<
unsigned
char
*>
(
msg_
->
data
());
size_t
bytes_left
=
msg_
->
size
();
if
(
bytes_left
<
6
||
memcmp
(
ptr
,
"
\x05
READY"
,
6
))
{
errno
=
EPROTO
;
return
-
1
;
}
ptr
+=
6
;
bytes_left
-=
6
;
return
parse_metadata
(
ptr
,
bytes_left
);
}
src/gssapi_client.hpp
View file @
1445516c
...
...
@@ -46,22 +46,19 @@ namespace zmq
private
:
enum
state_t
{
sending_hello
,
waiting_for_welcome
,
sending_initiate
,
sending_token
,
waiting_for_token
,
waiting_for_ready
,
send_next_token
,
recv_next_token
,
almost_ready
,
ready
};
state_t
state
;
gss_buffer_desc
*
token_ptr
;
gss_OID_set_desc
mechs
;
bool
security_context_established
;
int
produce_hello
(
msg_t
*
msg_
)
const
;
int
produce_initiate
(
msg_t
*
msg_
)
const
;
int
process_welcome
(
msg_t
*
msg
);
int
process_ready
(
msg_t
*
msg_
);
int
produce_next_token
(
msg_t
*
msg_
);
int
process_next_token
(
msg_t
*
msg_
);
};
}
...
...
src/gssapi_mechanism_base.cpp
View file @
1445516c
...
...
@@ -31,12 +31,29 @@
#include "gssapi_mechanism_base.hpp"
#include "wire.hpp"
zmq
::
gssapi_mechanism_base_t
::
gssapi_mechanism_base_t
()
zmq
::
gssapi_mechanism_base_t
::
gssapi_mechanism_base_t
()
:
send_tok
(),
recv_tok
(),
in_buf
(),
target_name
(
GSS_C_NO_NAME
),
service_name
(
NULL
),
maj_stat
(
GSS_S_COMPLETE
),
min_stat
(
0
),
init_sec_min_stat
(
0
),
ret_flags
(
0
),
gss_flags
(
GSS_C_MUTUAL_FLAG
|
GSS_C_REPLAY_FLAG
),
token_flags
(
0
),
cred
(
GSS_C_NO_CREDENTIAL
),
context
(
GSS_C_NO_CONTEXT
)
{
}
zmq
::
gssapi_mechanism_base_t
::~
gssapi_mechanism_base_t
()
{
if
(
target_name
)
gss_release_name
(
&
min_stat
,
&
target_name
);
if
(
context
)
gss_delete_sec_context
(
&
min_stat
,
&
context
,
GSS_C_NO_BUFFER
);
}
int
zmq
::
gssapi_mechanism_base_t
::
produce_token
(
msg_t
*
msg_
,
int
flags_
,
void
*
token_value_
,
size_t
token_length_
)
...
...
@@ -128,3 +145,31 @@ int zmq::gssapi_mechanism_base_t::process_token (msg_t *msg_, int &flags_, void
return
0
;
}
int
zmq
::
gssapi_mechanism_base_t
::
acquire_credentials
(
char
*
service_name_
,
gss_cred_id_t
*
cred_
)
{
OM_uint32
maj_stat
;
OM_uint32
min_stat
;
gss_name_t
server_name
;
gss_buffer_desc
name_buf
;
name_buf
.
value
=
service_name_
;
name_buf
.
length
=
strlen
((
char
*
)
name_buf
.
value
)
+
1
;
maj_stat
=
gss_import_name
(
&
min_stat
,
&
name_buf
,
gss_nt_service_name
,
&
server_name
);
if
(
maj_stat
!=
GSS_S_COMPLETE
)
return
-
1
;
maj_stat
=
gss_acquire_cred
(
&
min_stat
,
server_name
,
0
,
GSS_C_NO_OID_SET
,
GSS_C_ACCEPT
,
cred_
,
NULL
,
NULL
);
if
(
maj_stat
!=
GSS_S_COMPLETE
)
return
-
1
;
gss_release_name
(
&
min_stat
,
&
server_name
);
return
0
;
}
src/gssapi_mechanism_base.hpp
View file @
1445516c
...
...
@@ -41,6 +41,31 @@ namespace zmq
protected
:
int
produce_token
(
msg_t
*
msg_
,
int
flags_
,
void
*
token_value_
,
size_t
token_length_
);
int
process_token
(
msg_t
*
msg_
,
int
&
flags_
,
void
**
token_value_
,
size_t
&
token_length_
);
static
int
acquire_credentials
(
char
*
service_name_
,
gss_cred_id_t
*
cred_
);
protected
:
const
static
int
TOKEN_NOOP
=
(
1
<<
0
);
const
static
int
TOKEN_CONTEXT
=
(
1
<<
1
);
const
static
int
TOKEN_DATA
=
(
1
<<
2
);
const
static
int
TOKEN_MIC
=
(
1
<<
3
);
const
static
int
TOKEN_CONTEXT_NEXT
=
(
1
<<
4
);
const
static
int
TOKEN_WRAPPED
=
(
1
<<
5
);
const
static
int
TOKEN_ENCRYPTED
=
(
1
<<
6
);
const
static
int
TOKEN_SEND_MIC
=
(
1
<<
7
);
gss_buffer_desc
send_tok
;
gss_buffer_desc
recv_tok
;
gss_buffer_desc
in_buf
;
gss_name_t
target_name
;
char
*
service_name
;
OM_uint32
maj_stat
;
OM_uint32
min_stat
;
OM_uint32
init_sec_min_stat
;
OM_uint32
ret_flags
;
OM_uint32
gss_flags
;
int
token_flags
;
gss_cred_id_t
cred
;
gss_ctx_id_t
context
;
};
}
...
...
src/gssapi_server.cpp
View file @
1445516c
This diff is collapsed.
Click to expand it.
src/gssapi_server.hpp
View file @
1445516c
...
...
@@ -50,34 +50,21 @@ namespace zmq
private
:
enum
state_t
{
waiting_for_hello
,
sending_welcome
,
waiting_for_initiate
,
sending_token
,
waiting_for_token
,
sending_ready
,
send_next_token
,
recv_next_token
,
waiting_for_zap_reply
,
almost_ready
,
ready
};
session_base_t
*
const
session
;
const
std
::
string
peer_address
;
// True iff we are awaiting reply from ZAP reply.
bool
expecting_zap_reply
;
state_t
state
;
bool
security_context_established
;
gss_OID
doid
;
int
produce_welcome
(
msg_t
*
msg_
)
const
;
int
produce_ready
(
msg_t
*
msg_
)
const
;
int
process_hello
(
msg_t
*
msg_
);
int
process_initiate
(
msg_t
*
msg_
);
void
send_zap_request
(
const
std
::
string
&
username
,
const
std
::
string
&
password
);
int
receive_and_process_zap_reply
();
int
produce_next_token
(
msg_t
*
msg_
);
int
process_next_token
(
msg_t
*
msg_
);
};
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment