Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
a0cd41ec
Commit
a0cd41ec
authored
Sep 25, 2017
by
Ondřej Kuzník
Committed by
Ondřej Kuzník
Nov 17, 2020
Browse files
Upstream TLS support
parent
063981a0
Changes
4
Hide whitespace changes
Inline
Side-by-side
servers/lloadd/config.c
View file @
a0cd41ec
...
...
@@ -569,13 +569,14 @@ config_backend( ConfigArgs *c )
}
#else
/* HAVE_TLS */
/* Specifying ldaps:// overrides starttls= settings */
tmp
=
ldap_pvt_url_scheme2tls
(
lud
->
lud_scheme
);
if
(
tmp
)
{
b
->
b_tls
=
LLOAD_LDAPS
;
}
if
(
!
lud
->
lud_port
)
{
b
->
b_port
=
b
->
b_tls
?
LDAPS_PORT
:
LDAP_PORT
;
b
->
b_port
=
tmp
?
LDAPS_PORT
:
LDAP_PORT
;
}
else
{
b
->
b_port
=
lud
->
lud_port
;
}
...
...
@@ -1829,9 +1830,9 @@ config_push_cleanup( ConfigArgs *ca, ConfigDriver *cleanup )
}
static
slap_verbmasks
tlskey
[]
=
{
{
BER_BVC
(
"no"
),
SB_TLS_OFF
},
{
BER_BVC
(
"yes"
),
SB_TLS_ON
},
{
BER_BVC
(
"critical"
),
SB_TLS_CRITICAL
},
{
BER_BVC
(
"no"
),
LLOAD_CLEARTEXT
},
{
BER_BVC
(
"yes"
),
LLOAD_STARTTLS_OPTIONAL
},
{
BER_BVC
(
"critical"
),
LLOAD_STARTTLS
},
{
BER_BVNULL
,
0
}
};
...
...
@@ -1955,6 +1956,7 @@ static slap_cf_aux_table backendkey[] = {
{
BER_BVC
(
"max-pending-ops="
),
offsetof
(
Backend
,
b_max_pending
),
'i'
,
0
,
NULL
},
{
BER_BVC
(
"conn-max-pending="
),
offsetof
(
Backend
,
b_max_conn_pending
),
'i'
,
0
,
NULL
},
{
BER_BVC
(
"starttls="
),
offsetof
(
Backend
,
b_tls
),
'i'
,
0
,
tlskey
},
{
BER_BVNULL
,
0
,
0
,
0
,
NULL
}
};
...
...
@@ -1971,7 +1973,6 @@ static slap_cf_aux_table bindkey[] = {
{
BER_BVC
(
"authzID="
),
offsetof
(
slap_bindconf
,
sb_authzId
),
'b'
,
1
,
NULL
},
{
BER_BVC
(
"keepalive="
),
offsetof
(
slap_bindconf
,
sb_keepalive
),
'x'
,
0
,
(
slap_verbmasks
*
)
slap_keepalive_parse
},
#ifdef HAVE_TLS
{
BER_BVC
(
"starttls="
),
offsetof
(
slap_bindconf
,
sb_tls
),
'i'
,
0
,
tlskey
},
{
BER_BVC
(
"tls_cert="
),
offsetof
(
slap_bindconf
,
sb_tls_cert
),
's'
,
1
,
NULL
},
{
BER_BVC
(
"tls_key="
),
offsetof
(
slap_bindconf
,
sb_tls_key
),
's'
,
1
,
NULL
},
{
BER_BVC
(
"tls_cacert="
),
offsetof
(
slap_bindconf
,
sb_tls_cacert
),
's'
,
1
,
NULL
},
...
...
servers/lloadd/connection.c
View file @
a0cd41ec
...
...
@@ -335,10 +335,6 @@ connection_init( ber_socket_t s, const char *peername, int flags )
assert
(
peername
!=
NULL
);
#ifndef HAVE_TLS
assert
(
!
(
flags
&
CONN_IS_TLS
)
);
#endif
if
(
s
==
AC_SOCKET_INVALID
)
{
Debug
(
LDAP_DEBUG_ANY
,
"connection_init: "
"init of socket fd=%ld invalid
\n
"
,
...
...
@@ -362,10 +358,6 @@ connection_init( ber_socket_t s, const char *peername, int flags )
#endif
ber_sockbuf_add_io
(
c
->
c_sb
,
&
ber_sockbuf_io_fd
,
LBER_SBIOD_LEVEL_PROVIDER
,
(
void
*
)
&
s
);
#ifdef LDAP_PF_LOCAL_SENDMSG
if
(
!
BER_BVISEMPTY
(
peerbv
)
)
ber_sockbuf_ctrl
(
c
->
c_sb
,
LBER_SB_OPT_UNGET_BUF
,
peerbv
);
#endif
}
else
#endif
/* LDAP_PF_LOCAL */
{
...
...
@@ -382,18 +374,6 @@ connection_init( ber_socket_t s, const char *peername, int flags )
c
->
c_sb
,
&
ber_sockbuf_io_debug
,
INT_MAX
,
(
void
*
)
"lload_"
);
#endif
#ifdef HAVE_TLS
if
(
flags
&
CONN_IS_TLS
)
{
/* TODO: will need an asynchronous TLS implementation in libldap */
assert
(
0
);
c
->
c_is_tls
=
1
;
c
->
c_needs_tls_accept
=
1
;
}
else
{
c
->
c_is_tls
=
0
;
c
->
c_needs_tls_accept
=
0
;
}
#endif
c
->
c_next_msgid
=
1
;
c
->
c_refcnt
=
c
->
c_live
=
1
;
c
->
c_destroy
=
connection_destroy
;
...
...
servers/lloadd/slap.h
View file @
a0cd41ec
...
...
@@ -244,7 +244,9 @@ typedef enum {
enum
lload_tls_type
{
LLOAD_CLEARTEXT
=
0
,
LLOAD_LDAPS
,
LLOAD_STARTTLS_OPTIONAL
,
LLOAD_STARTTLS
,
LLOAD_TLS_ESTABLISHED
,
};
struct
PendingConnection
{
...
...
@@ -405,7 +407,6 @@ struct Connection {
#ifdef HAVE_TLS
enum
lload_tls_type
c_is_tls
;
/* true if this LDAP over raw TLS */
char
c_needs_tls_accept
;
/* true if SSL_accept should be called */
#endif
long
c_n_ops_executing
;
/* num of ops currently executing */
...
...
servers/lloadd/upstream.c
View file @
a0cd41ec
...
...
@@ -426,6 +426,180 @@ upstream_finish( Connection *c )
return
rc
;
}
static
void
upstream_tls_handshake_cb
(
evutil_socket_t
s
,
short
what
,
void
*
arg
)
{
Connection
*
c
=
arg
;
Backend
*
b
;
int
rc
=
LDAP_SUCCESS
;
CONNECTION_LOCK
(
c
);
if
(
what
&
EV_TIMEOUT
)
{
Debug
(
LDAP_DEBUG_CONNS
,
"upstream_tls_handshake_cb: "
"connid=%lu, timeout reached, destroying
\n
"
,
c
->
c_connid
);
goto
fail
;
}
b
=
c
->
c_private
;
rc
=
ldap_pvt_tls_connect
(
slap_tls_ld
,
c
->
c_sb
,
b
->
b_host
);
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
,
"upstream_tls_handshake_cb: "
"connid=%lu finished
\n
"
,
c
->
c_connid
);
c
->
c_is_tls
=
LLOAD_TLS_ESTABLISHED
;
CONNECTION_UNLOCK_INCREF
(
c
);
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
CONNECTION_LOCK_DECREF
(
c
);
rc
=
upstream_finish
(
c
);
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
if
(
rc
==
LDAP_SUCCESS
)
{
backend_retry
(
b
);
}
}
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
,
"upstream_tls_handshake_cb: "
"connid=%lu need write rc=%d
\n
"
,
c
->
c_connid
,
rc
);
}
CONNECTION_UNLOCK_OR_DESTROY
(
c
);
return
;
fail:
Debug
(
LDAP_DEBUG_CONNS
,
"upstream_tls_handshake_cb: "
"connid=%lu failed rc=%d
\n
"
,
c
->
c_connid
,
rc
);
CONNECTION_DESTROY
(
c
);
}
static
int
upstream_starttls
(
Connection
*
c
)
{
BerValue
matcheddn
,
message
,
responseOid
,
startTLSOid
=
BER_BVC
(
LDAP_EXOP_START_TLS
);
BerElement
*
ber
=
c
->
c_currentber
;
struct
event_base
*
base
;
ber_int_t
msgid
,
result
;
ber_tag_t
tag
;
c
->
c_currentber
=
NULL
;
if
(
ber_scanf
(
ber
,
"it"
,
&
msgid
,
&
tag
)
==
LBER_ERROR
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_starttls: "
"protocol violation from server
\n
"
);
goto
fail
;
}
if
(
msgid
!=
(
c
->
c_next_msgid
-
1
)
||
tag
!=
LDAP_RES_EXTENDED
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_starttls: "
"unexpected %s from server, msgid=%d
\n
"
,
slap_msgtype2str
(
tag
),
msgid
);
goto
fail
;
}
if
(
ber_scanf
(
ber
,
"{emm}"
,
&
result
,
&
matcheddn
,
&
message
)
==
LBER_ERROR
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_starttls: "
"protocol violation on StartTLS response
\n
"
);
goto
fail
;
}
if
(
(
tag
=
ber_get_tag
(
ber
))
!=
LBER_DEFAULT
)
{
if
(
tag
!=
LDAP_TAG_EXOP_RES_OID
||
ber_scanf
(
ber
,
"{m}"
,
&
responseOid
)
==
LBER_DEFAULT
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_starttls: "
"protocol violation on StartTLS response
\n
"
);
goto
fail
;
}
if
(
ber_bvcmp
(
&
responseOid
,
&
startTLSOid
)
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_starttls: "
"oid=%s not a StartTLS response
\n
"
,
responseOid
.
bv_val
);
goto
fail
;
}
}
if
(
result
!=
LDAP_SUCCESS
)
{
Backend
*
b
=
c
->
c_private
;
int
rc
;
Debug
(
LDAP_DEBUG_STATS
,
"upstream_starttls: "
"server doesn't support StartTLS rc=%d message='%s'%s
\n
"
,
result
,
message
.
bv_val
,
(
c
->
c_is_tls
==
LLOAD_STARTTLS_OPTIONAL
)
?
", ignored"
:
""
);
if
(
c
->
c_is_tls
!=
LLOAD_STARTTLS_OPTIONAL
)
{
goto
fail
;
}
c
->
c_is_tls
=
LLOAD_CLEARTEXT
;
ber_free
(
ber
,
1
);
CONNECTION_UNLOCK_INCREF
(
c
);
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
CONNECTION_LOCK_DECREF
(
c
);
rc
=
upstream_finish
(
c
);
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
if
(
rc
==
LDAP_SUCCESS
)
{
backend_retry
(
b
);
}
CONNECTION_UNLOCK_OR_DESTROY
(
c
);
return
rc
;
}
base
=
event_get_base
(
c
->
c_read_event
);
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
,
upstream_tls_handshake_cb
,
c
);
event_assign
(
c
->
c_write_event
,
base
,
c
->
c_fd
,
EV_WRITE
,
upstream_tls_handshake_cb
,
c
);
event_add
(
c
->
c_read_event
,
NULL
);
event_add
(
c
->
c_write_event
,
lload_write_timeout
);
CONNECTION_UNLOCK
(
c
);
ber_free
(
ber
,
1
);
return
-
1
;
fail:
ber_free
(
ber
,
1
);
CONNECTION_DESTROY
(
c
);
return
-
1
;
}
/*
* We must already hold b->b_mutex when called.
*/
...
...
@@ -439,7 +613,7 @@ upstream_init( ber_socket_t s, Backend *b )
assert
(
b
!=
NULL
);
flags
=
(
b
->
b_
tls
==
LLOAD_LDAPS
)
?
CONN_IS_
TLS
:
0
;
flags
=
(
b
->
b_
proto
==
LDAP_PROTO_IPC
)
?
CONN_IS_
IPC
:
0
;
if
(
(
c
=
connection_init
(
s
,
b
->
b_host
,
flags
))
==
NULL
)
{
return
NULL
;
}
...
...
@@ -473,11 +647,37 @@ upstream_init( ber_socket_t s, Backend *b )
/* We only add the write event when we have data pending */
c
->
c_write_event
=
event
;
rc
=
upstream_finish
(
c
);
if
(
rc
<
0
)
{
goto
fail
;
}
if
(
c
->
c_is_tls
==
LLOAD_CLEARTEXT
)
{
rc
=
upstream_finish
(
c
);
if
(
rc
<
0
)
{
goto
fail
;
}
}
else
if
(
c
->
c_is_tls
==
LLOAD_LDAPS
)
{
event_assign
(
c
->
c_read_event
,
base
,
s
,
EV_READ
|
EV_PERSIST
,
upstream_tls_handshake_cb
,
c
);
event_assign
(
c
->
c_write_event
,
base
,
s
,
EV_WRITE
,
upstream_tls_handshake_cb
,
c
);
event_add
(
c
->
c_write_event
,
lload_write_timeout
);
}
else
if
(
c
->
c_is_tls
==
LLOAD_STARTTLS
||
c
->
c_is_tls
==
LLOAD_STARTTLS_OPTIONAL
)
{
BerElement
*
output
;
ldap_pvt_thread_mutex_lock
(
&
c
->
c_io_mutex
);
if
(
(
output
=
c
->
c_pendingber
=
ber_alloc
())
==
NULL
)
{
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
goto
fail
;
}
ber_printf
(
output
,
"t{tit{ts}}"
,
LDAP_TAG_MESSAGE
,
LDAP_TAG_MSGID
,
c
->
c_next_msgid
++
,
LDAP_REQ_EXTENDED
,
LDAP_TAG_EXOP_REQ_OID
,
LDAP_EXOP_START_TLS
);
ldap_pvt_thread_mutex_unlock
(
&
c
->
c_io_mutex
);
c
->
c_pdu_cb
=
upstream_starttls
;
CONNECTION_UNLOCK_INCREF
(
c
);
connection_write_cb
(
s
,
0
,
c
);
CONNECTION_LOCK_DECREF
(
c
);
}
event_add
(
c
->
c_read_event
,
NULL
);
c
->
c_destroy
=
upstream_destroy
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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