Hi,
I noticed that latest/greatest stunnel does not support the Start TLS operation for LDAP (RFC2830). Yet, I need it in my organisation as a quick workaround.
After fiddling with OpenLDAP, tracing, and reading RFC 2830 a bit, I patched stunnel 4.56 and the patch has not failed me yet. But I must remark that I am no LDAP expert, nor an certified stunnel hacker. So, I will submit this patch as a first suggestion.
Will you consider the feature request of implementing the Start TLS feature as described in RFC 2830?
Cheers, Bart Dopheide
My patch suggestion is: dopheideb@anguish:/tmp$ diff -aur stunnel-4.56 stunnel-4.56-ldap-starttls-patch diff -aur stunnel-4.56/src/protocol.c stunnel-4.56-ldap-starttls-patch/src/protocol.c --- stunnel-4.56/src/protocol.c 2013-03-13 14:41:16.000000000 +0100 +++ stunnel-4.56-ldap-starttls-patch/src/protocol.c 2013-11-05 11:19:10.388365359 +0100 @@ -53,6 +53,7 @@ static void imap_client(CLI *); static void imap_server(CLI *); static void nntp_client(CLI *); +static void openldap_client(CLI *); static void connect_server(CLI *); static void connect_client(CLI *);
@@ -82,6 +83,7 @@ {"pop3", {{PROTOCOL_PRE_SSL, pop3_server}, {PROTOCOL_PRE_SSL, pop3_client}}}, {"imap", {{PROTOCOL_PRE_SSL, imap_server}, {PROTOCOL_PRE_SSL, imap_client}}}, {"nntp", {{PROTOCOL_NONE, NULL}, {PROTOCOL_PRE_SSL, nntp_client}}}, + {"openldap",{{PROTOCOL_NONE, NULL}, {PROTOCOL_PRE_SSL, openldap_client}}}, {"connect", {{PROTOCOL_PRE_CONNECT, connect_server}, {PROTOCOL_PRE_SSL, connect_client}}}, {NULL, {{PROTOCOL_NONE, NULL}, {PROTOCOL_NONE, NULL}}} }; @@ -513,6 +515,88 @@ str_free(line); }
+/**************************************** LDAP, RFC 2830 */ + +u8 ldap_startssl_message[0x1d + 2] = +{ + 0x30, /* tag = UNIVERSAL SEQUENCE */ + 0x1d, /* len = 29 (the remaining number of bytes in this message) */ + 0x02, /* messageID */ + 0x01, /* len = 1 */ + 0x01, /* value = 1 (this is messageID 1) */ + /* --- */ + 0x77, /* protocolOp = APPLICATION (23) (=ExtendedRequest) + * 0b01xxxxxx => APPLICATION + * 0bxx1xxxxx => ? + * 0xxxx10111 => 23 + */ + 0x18, /* len = 24 */ + 0x80, /* type = requstName? */ + 0x16, /* len = 22 */ + /* OID: 1.3.6.1.4.1.1466.20037 (=LDAP_START_TLS_OID)*/ + '1', '.', + '3', '.', + '6', '.', + '1', '.', + '4', '.', + '1', '.', + '1', '4', '6', '6', '.', + '2', '0', '0', '3', '7' + /* No requestValue, as per RFC2830 (in 2.1: "The requestValue field is absent") */ +}; +static void openldap_client(CLI *c) { + u8 buffer[1]; + u8 ldap_response[256]; + + s_log(LOG_DEBUG, "Requesting LDAP Start TLS"); + write_blocking(c, c->remote_fd.fd, ldap_startssl_message, ldap_startssl_message[1] + 2); + + read_blocking(c, c->remote_fd.fd, buffer, 1); + if(buffer[0] != 0x30) { + s_log(LOG_ERR, "start tag is not UNIVERSAL SEQUENCE"); + longjmp(c->err, 1); + } + + s_log(LOG_DEBUG, "Reading LDAP message size (1 byte)."); + read_blocking(c, c->remote_fd.fd, buffer, 1); + + s_log(LOG_DEBUG, "Reading LDAP message (%u byte(s))", buffer[0]); + read_blocking(c, c->remote_fd.fd, ldap_response, buffer[0]); + + if(ldap_response[0] != 0x02) { + s_log(LOG_ERR, "LDAP response does not start with type messageID"); + longjmp(c->err, 1); + } + if(ldap_response[1] != 0x01) { + s_log(LOG_ERR, "This is not an extendedResp(1)"); + longjmp(c->err, 1); + } + if(ldap_response[2] != 0x01) { + s_log(LOG_ERR, "Non-matching messageID"); + longjmp(c->err, 1); + } + if(ldap_response[3] != 0x78) { + s_log(LOG_ERR, "This is not a protocolOp for APPLICATION ExtendedResponse"); + longjmp(c->err, 1); + } + if(ldap_response[4] != 0x07) { + s_log(LOG_ERR, "Expected 0x07 indicating extendedResp is 7 bytes long"); + longjmp(c->err, 1); + } + if(ldap_response[5] != 0x0a) { + s_log(LOG_ERR, "This is not an extendedResp"); + longjmp(c->err, 1); + } + if(ldap_response[6] != 0x01) { + s_log(LOG_ERR, "This is not an extendedResp"); + longjmp(c->err, 1); + } + if(ldap_response[7] != 0x00) { + s_log(LOG_ERR, "This is not resultCode success"); + longjmp(c->err, 1); + } +} + /**************************************** connect */
static void connect_server(CLI *c) { dopheideb@anguish:/tmp$
Hi stunnel users,
I´m using SLES with stunnel 4.54-0.9.24, which is stored in /usr/sbin in this distribution. Stunnel is used with xinetd in non-daemon mode. With stunnel in /usr/sbin, I can use stunnel only with root (I know I can do a sudoers entry for stunnel....but let´s try it the way it was meant by the distribution).
I wanted so use a stunnel.conf like this:
exec = /bin/su execargs = su -l -c "/home/abc/bin/binary" abc cert = /home/abc/certs/cert.pem key = /home/abc/certs/cert.key CAfile = /home/fex/certs/CA.pem TIMEOUTclose = 2
xinetd.d/service config looks like this:
service abc { socket_type = stream wait = no type = unlisted protocol = tcp port = 443 cps = 5 10 user = root groups = yes server = /usr/sbin/stunnel server_args = /home/abc/etc/stunnel.conf nice = 0 disable = no }
The "su -l ...." command works fine on a root shell, but with this stunnel.conf it refuses to work. Can anybody give me a hint how to resolve that problem?
Best regards Florian Götz
Mit freundlichen Grüßen Florian Götz
-----------------------------------------------------------------
Dipl.-Inf. (FH) Florian Götz Rechenzentrum Hochschule Mannheim Paul-Wittsack-Straße 10 68163 Mannheim Tel: 0621/292-6232
EMail: f.goetz@hs-mannheim.de Internet: http://www.rz.hs-mannheim.de
-----
On Thu, Nov 07, 2013 at 09:58:25AM +0100, Florian Götz wrote:
Hi stunnel users,
I´m using SLES with stunnel 4.54-0.9.24, which is stored in /usr/sbin in this distribution. Stunnel is used with xinetd in non-daemon mode. With stunnel in /usr/sbin, I can use stunnel only with root (I know I can do a sudoers entry for stunnel....but let´s try it the way it was meant by the distribution).
I wanted so use a stunnel.conf like this:
exec = /bin/su execargs = su -l -c "/home/abc/bin/binary" abc
Hi,
It's interesting that first you talk of sudoers, then you try to use su(8). On many systems, including Linux, the su(8) utility was initially developed for interactive use and only later (ok, many, many years ago, but still only later) was it extended to be, well, more convenient for non-interactive use by other programs. On the other hand, sudo has always been developed with both these goals in mind, it is much, much easier to use and it has much fewer pitfalls.
So... my advice to you would be to really use sudo and not su. There are a lot of factors influencing a su execution, and there are a lot of problems that you may run into while trying to pass a program with properly-quoted arguments to it.
That said, the difference between a root login shell and a non-interactive execution by xinetd is most probably twofold:
- a login shell, by definition, loads a different set of shell startup scripts; and yes, even when you run su with -c, it still executes a (non-login, non-interactive) shell to run your command after setting a proper value for PATH and some other variables. And yes, I see that you are running su with the -l option; still, I'm not completely sure that it will be able to properly run a login shell. This is a point where using sudo might make things a bit easier, since it will be, well, a bit more predictable, being designed for that kind of use.
- an interactive shell (attached to a terminal) also sets the environment up in a way different from a non-interactive one; if there are any differences in the output of the 'printenv' command from a root login shell and from an xinetd invocation, some of them might be related to that. This is where sudo would not really help, you have to figure out how to deal with the differences by yourself :)
I understand where you're coming from with using just the facilities provided by the OS base system, but, well, IMHO sudo is already a pretty well-established sysadmin tool and there's no need to exclude it from the set of the minimal reasonable extensions to the base OS (which, for me, besides sudo, usually include zsh, screen or tmux, rsync and a non-minimal version of vim).
G'luck, Peter