Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
1b46f866
Commit
1b46f866
authored
Sep 25, 2017
by
Ondřej Kuzník
Committed by
Ondřej Kuzník
Nov 17, 2020
Browse files
Client TLS support
parent
a0cd41ec
Changes
3
Hide whitespace changes
Inline
Side-by-side
servers/lloadd/client.c
View file @
1b46f866
...
...
@@ -240,6 +240,99 @@ handle_one_request( Connection *c )
return
handler
(
c
,
op
);
}
/*
* The connection has a token assigned to it when the callback is set up.
*/
void
client_tls_handshake_cb
(
evutil_socket_t
s
,
short
what
,
void
*
arg
)
{
Connection
*
c
=
arg
;
int
rc
=
0
;
CONNECTION_LOCK_DECREF
(
c
);
if
(
what
&
EV_TIMEOUT
)
{
Debug
(
LDAP_DEBUG_CONNS
,
"client_tls_handshake_cb: "
"connid=%lu, timeout reached, destroying
\n
"
,
c
->
c_connid
);
goto
fail
;
}
/*
* In case of StartTLS, make sure we flush the response first.
* Also before we try to read anything from the connection, it isn't
* permitted to Abandon a StartTLS exop per RFC4511 anyway.
*/
ldap_pvt_thread_mutex_lock
(
&
c
->
c_io_mutex
);
if
(
c
->
c_pendingber
)
{
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
CONNECTION_UNLOCK_INCREF
(
c
);
connection_write_cb
(
s
,
what
,
arg
);
ldap_pvt_thread_mutex_lock
(
&
c
->
c_io_mutex
);
CONNECTION_LOCK_DECREF
(
c
);
if
(
!
c
->
c_live
)
{
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
goto
fail
;
}
/* Do we still have data pending? If so, connection_write_cb would
* already have arranged the write callback to trigger again */
if
(
c
->
c_pendingber
)
{
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
CONNECTION_UNLOCK_INCREF
(
c
);
return
;
}
}
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
rc
=
ldap_pvt_tls_accept
(
c
->
c_sb
,
slap_tls_ctx
);
if
(
rc
<
0
)
{
goto
fail
;
}
if
(
rc
==
0
)
{
struct
event_base
*
base
=
event_get_base
(
c
->
c_read_event
);
/*
* We're finished, replace the callbacks
*
* This is deadlock-safe, since both share the same base - the one
* that's just running us.
*/
event_del
(
c
->
c_read_event
);
event_del
(
c
->
c_write_event
);
event_assign
(
c
->
c_read_event
,
base
,
c
->
c_fd
,
EV_READ
|
EV_PERSIST
,
connection_read_cb
,
c
);
event_add
(
c
->
c_read_event
,
NULL
);
event_assign
(
c
->
c_write_event
,
base
,
c
->
c_fd
,
EV_WRITE
,
connection_write_cb
,
c
);
Debug
(
LDAP_DEBUG_CONNS
,
"client_tls_handshake_cb: "
"connid=%lu finished
\n
"
,
c
->
c_connid
);
c
->
c_is_tls
=
LLOAD_TLS_ESTABLISHED
;
/* The temporary reference established for us is no longer needed */
CONNECTION_UNLOCK_OR_DESTROY
(
c
);
return
;
}
else
if
(
ber_sockbuf_ctrl
(
c
->
c_sb
,
LBER_SB_OPT_NEEDS_WRITE
,
NULL
)
)
{
event_add
(
c
->
c_write_event
,
lload_write_timeout
);
Debug
(
LDAP_DEBUG_CONNS
,
"client_tls_handshake_cb: "
"connid=%lu need write rc=%d
\n
"
,
c
->
c_connid
,
rc
);
}
CONNECTION_UNLOCK_INCREF
(
c
);
return
;
fail:
Debug
(
LDAP_DEBUG_CONNS
,
"client_tls_handshake_cb: "
"connid=%lu failed rc=%d
\n
"
,
c
->
c_connid
,
rc
);
CONNECTION_DESTROY
(
c
);
}
Connection
*
client_init
(
ber_socket_t
s
,
...
...
@@ -266,6 +359,25 @@ client_init(
c
->
c_state
=
LLOAD_C_READY
;
if
(
flags
&
CONN_IS_TLS
)
{
int
rc
;
c
->
c_is_tls
=
LLOAD_LDAPS
;
rc
=
ldap_pvt_tls_accept
(
c
->
c_sb
,
slap_tls_ctx
);
if
(
rc
<
0
)
{
Debug
(
LDAP_DEBUG_CONNS
,
"client_init: "
"connid=%lu failed initial TLS accept rc=%d
\n
"
,
c
->
c_connid
,
rc
);
goto
fail
;
}
if
(
rc
)
{
c
->
c_refcnt
++
;
read_cb
=
write_cb
=
client_tls_handshake_cb
;
}
}
event
=
event_new
(
base
,
s
,
EV_READ
|
EV_PERSIST
,
read_cb
,
c
);
if
(
!
event
)
{
Debug
(
LDAP_DEBUG_ANY
,
"client_init: "
...
...
servers/lloadd/extended.c
View file @
1b46f866
...
...
@@ -22,6 +22,82 @@
Avlnode
*
lload_exop_handlers
=
NULL
;
int
handle_starttls
(
Connection
*
c
,
Operation
*
op
)
{
struct
event_base
*
base
=
event_get_base
(
c
->
c_read_event
);
BerElement
*
output
;
char
*
msg
=
NULL
;
int
rc
=
LDAP_SUCCESS
;
tavl_delete
(
&
c
->
c_ops
,
op
,
operation_client_cmp
);
if
(
c
->
c_is_tls
==
LLOAD_TLS_ESTABLISHED
)
{
rc
=
LDAP_OPERATIONS_ERROR
;
msg
=
"TLS layer already in effect"
;
}
else
if
(
c
->
c_state
==
LLOAD_C_BINDING
)
{
rc
=
LDAP_OPERATIONS_ERROR
;
msg
=
"bind in progress"
;
}
else
if
(
c
->
c_ops
)
{
rc
=
LDAP_OPERATIONS_ERROR
;
msg
=
"cannot start TLS when operations are outstanding"
;
}
else
if
(
!
slap_tls_ctx
)
{
rc
=
LDAP_UNAVAILABLE
;
msg
=
"Could not initialize TLS"
;
}
Debug
(
LDAP_DEBUG_STATS
,
"handle_starttls: "
"handling StartTLS exop connid=%lu rc=%d msg=%s
\n
"
,
c
->
c_connid
,
rc
,
msg
);
if
(
rc
)
{
/* We've already removed the operation from the queue */
return
operation_send_reject_locked
(
op
,
rc
,
msg
,
1
);
}
CONNECTION_UNLOCK_INCREF
(
c
);
event_del
(
c
->
c_read_event
);
event_del
(
c
->
c_write_event
);
/*
* At this point, we are the only thread handling the connection:
* - there are no upstream operations
* - the I/O callbacks have been successfully removed
*
* This means we can safely reconfigure both I/O events now.
*/
ldap_pvt_thread_mutex_lock
(
&
c
->
c_io_mutex
);
output
=
c
->
c_pendingber
;
if
(
output
==
NULL
&&
(
output
=
ber_alloc
())
==
NULL
)
{
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
CONNECTION_LOCK_DECREF
(
c
);
operation_destroy_from_client
(
op
);
CONNECTION_DESTROY
(
c
);
return
-
1
;
}
c
->
c_pendingber
=
output
;
ber_printf
(
output
,
"t{tit{ess}}"
,
LDAP_TAG_MESSAGE
,
LDAP_TAG_MSGID
,
op
->
o_client_msgid
,
LDAP_RES_EXTENDED
,
LDAP_SUCCESS
,
""
,
""
);
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
CONNECTION_LOCK_DECREF
(
c
);
event_assign
(
c
->
c_read_event
,
base
,
c
->
c_fd
,
EV_READ
|
EV_PERSIST
,
client_tls_handshake_cb
,
c
);
event_add
(
c
->
c_read_event
,
NULL
);
event_assign
(
c
->
c_write_event
,
base
,
c
->
c_fd
,
EV_WRITE
,
client_tls_handshake_cb
,
c
);
/* We already have something to write */
event_add
(
c
->
c_write_event
,
lload_write_timeout
);
operation_destroy_from_client
(
op
);
CONNECTION_UNLOCK_INCREF
(
c
);
return
-
1
;
}
int
request_extended
(
Connection
*
c
,
Operation
*
op
)
{
...
...
@@ -67,7 +143,9 @@ request_extended( Connection *c, Operation *op )
return
request_process
(
c
,
op
);
}
ExopHandler
lload_exops
[]
=
{
{
BER_BVNULL
}
ExopHandler
lload_exops
[]
=
{
{
BER_BVC
(
LDAP_EXOP_START_TLS
),
handle_starttls
},
{
BER_BVNULL
}
};
int
...
...
servers/lloadd/proto-slap.h
View file @
1b46f866
...
...
@@ -74,6 +74,7 @@ LDAP_SLAPD_F (int) handle_vc_bind_response( Operation *op, BerElement *ber );
LDAP_SLAPD_F
(
int
)
request_abandon
(
Connection
*
c
,
Operation
*
op
);
LDAP_SLAPD_F
(
int
)
request_process
(
Connection
*
c
,
Operation
*
op
);
LDAP_SLAPD_F
(
int
)
handle_one_request
(
Connection
*
c
);
LDAP_SLAPD_F
(
void
)
client_tls_handshake_cb
(
evutil_socket_t
s
,
short
what
,
void
*
arg
);
LDAP_SLAPD_F
(
Connection
*
)
client_init
(
ber_socket_t
s
,
Listener
*
url
,
const
char
*
peername
,
struct
event_base
*
base
,
int
use_tls
);
LDAP_SLAPD_F
(
void
)
client_reset
(
Connection
*
c
);
LDAP_SLAPD_F
(
void
)
client_destroy
(
Connection
*
c
);
...
...
Write
Preview
Supports
Markdown
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