gssapi_client.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 
5 #ifdef HAVE_LIBGSSAPI_KRB5
6 
7 #include <string.h>
8 #include <string>
9 
10 #include "msg.hpp"
11 #include "session_base.hpp"
12 #include "err.hpp"
13 #include "gssapi_client.hpp"
14 #include "wire.hpp"
15 
16 zmq::gssapi_client_t::gssapi_client_t (session_base_t *session_,
17  const options_t &options_) :
18  mechanism_base_t (session_, options_),
19  gssapi_mechanism_base_t (session_, options_),
20  state (call_next_init),
21  token_ptr (GSS_C_NO_BUFFER),
22  mechs (),
23  security_context_established (false)
24 {
25  const std::string::size_type service_size =
26  options_.gss_service_principal.size ();
27  service_name = static_cast<char *> (malloc (service_size + 1));
28  assert (service_name);
29  memcpy (service_name, options_.gss_service_principal.c_str (),
30  service_size + 1);
31 
32  service_name_type = convert_nametype (options_.gss_service_principal_nt);
33  maj_stat = GSS_S_COMPLETE;
34  if (!options_.gss_principal.empty ()) {
35  const std::string::size_type principal_size =
36  options_.gss_principal.size ();
37  principal_name = static_cast<char *> (malloc (principal_size + 1));
38  assert (principal_name);
39  memcpy (principal_name, options_.gss_principal.c_str (),
40  principal_size + 1);
41 
42  gss_OID name_type = convert_nametype (options_.gss_principal_nt);
43  if (acquire_credentials (principal_name, &cred, name_type) != 0)
44  maj_stat = GSS_S_FAILURE;
45  }
46 
47  mechs.elements = NULL;
48  mechs.count = 0;
49 }
50 
51 zmq::gssapi_client_t::~gssapi_client_t ()
52 {
53  if (service_name)
54  free (service_name);
55  if (cred)
56  gss_release_cred (&min_stat, &cred);
57 }
58 
59 int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
60 {
61  if (state == send_ready) {
62  int rc = produce_ready (msg_);
63  if (rc == 0)
64  state = connected;
65 
66  return rc;
67  }
68 
69  if (state != call_next_init) {
70  errno = EAGAIN;
71  return -1;
72  }
73 
74  if (initialize_context () < 0)
75  return -1;
76 
77  if (produce_next_token (msg_) < 0)
78  return -1;
79 
80  if (maj_stat != GSS_S_CONTINUE_NEEDED && maj_stat != GSS_S_COMPLETE)
81  return -1;
82 
83  if (maj_stat == GSS_S_COMPLETE) {
84  security_context_established = true;
85  state = recv_ready;
86  } else
87  state = recv_next_token;
88 
89  return 0;
90 }
91 
92 int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
93 {
94  if (state == recv_ready) {
95  int rc = process_ready (msg_);
96  if (rc == 0)
97  state = send_ready;
98 
99  return rc;
100  }
101 
102  if (state != recv_next_token) {
103  session->get_socket ()->event_handshake_failed_protocol (
104  session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
105  errno = EPROTO;
106  return -1;
107  }
108 
109  if (process_next_token (msg_) < 0)
110  return -1;
111 
112  if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
113  return -1;
114 
115  state = call_next_init;
116 
117  errno_assert (msg_->close () == 0);
118  errno_assert (msg_->init () == 0);
119 
120  return 0;
121 }
122 
123 int zmq::gssapi_client_t::encode (msg_t *msg_)
124 {
125  zmq_assert (state == connected);
126 
127  if (do_encryption)
128  return encode_message (msg_);
129 
130  return 0;
131 }
132 
133 int zmq::gssapi_client_t::decode (msg_t *msg_)
134 {
135  zmq_assert (state == connected);
136 
137  if (do_encryption)
138  return decode_message (msg_);
139 
140  return 0;
141 }
142 
143 zmq::mechanism_t::status_t zmq::gssapi_client_t::status () const
144 {
145  return state == connected ? mechanism_t::ready : mechanism_t::handshaking;
146 }
147 
148 int zmq::gssapi_client_t::initialize_context ()
149 {
150  // principal was specified but credentials could not be acquired
151  if (principal_name != NULL && cred == NULL)
152  return -1;
153 
154  // First time through, import service_name into target_name
155  if (target_name == GSS_C_NO_NAME) {
156  send_tok.value = service_name;
157  send_tok.length = strlen (service_name) + 1;
158  OM_uint32 maj = gss_import_name (&min_stat, &send_tok,
159  service_name_type, &target_name);
160 
161  if (maj != GSS_S_COMPLETE)
162  return -1;
163  }
164 
165  maj_stat = gss_init_sec_context (
166  &init_sec_min_stat, cred, &context, target_name, mechs.elements,
167  gss_flags, 0, NULL, token_ptr, NULL, &send_tok, &ret_flags, NULL);
168 
169  if (token_ptr != GSS_C_NO_BUFFER)
170  free (recv_tok.value);
171 
172  return 0;
173 }
174 
175 int zmq::gssapi_client_t::produce_next_token (msg_t *msg_)
176 {
177  if (send_tok.length != 0) { // Server expects another token
178  if (produce_initiate (msg_, send_tok.value, send_tok.length) < 0) {
179  gss_release_buffer (&min_stat, &send_tok);
180  gss_release_name (&min_stat, &target_name);
181  return -1;
182  }
183  }
184  gss_release_buffer (&min_stat, &send_tok);
185 
186  if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
187  gss_release_name (&min_stat, &target_name);
188  if (context != GSS_C_NO_CONTEXT)
189  gss_delete_sec_context (&min_stat, &context, GSS_C_NO_BUFFER);
190  return -1;
191  }
192 
193  return 0;
194 }
195 
196 int zmq::gssapi_client_t::process_next_token (msg_t *msg_)
197 {
198  if (maj_stat == GSS_S_CONTINUE_NEEDED) {
199  if (process_initiate (msg_, &recv_tok.value, recv_tok.length) < 0) {
200  gss_release_name (&min_stat, &target_name);
201  return -1;
202  }
203  token_ptr = &recv_tok;
204  }
205 
206  return 0;
207 }
208 
209 #endif
NULL
NULL
Definition: test_security_zap.cpp:405
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
Definition: zmq.h:425
EAGAIN
#define EAGAIN
Definition: errno.hpp:14
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
errno
int errno
wire.hpp
EPROTO
#define EPROTO
Definition: err.hpp:26
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
zmq::mechanism_t::status_t
status_t
Definition: mechanism.hpp:22
gssapi_client.hpp
msg.hpp
err.hpp
session_base.hpp
false
#define false
Definition: cJSON.c:70
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:53