--- a/src/client.c +++ b/src/client.c @@ -195,12 +195,48 @@ static void run_client(CLI *c) { #endif } +static void send_client_info(CLI *c) +{ + size_t len; + SSL_CIPHER *cipher; + char buf[STRLEN], *i, *j; + + len = strlen (c->accepted_address); + + write (c->remote_fd.fd, c->accepted_address, len); + write (c->remote_fd.fd, ";", 1); + + cipher = SSL_get_current_cipher (c->ssl); + SSL_CIPHER_description (cipher, buf, STRLEN); + i = j = buf; + + do + { + switch (*i) + { + case ' ': + case '\n': + *j = 0; + break; + default: + *j++ = *i; + } + } while (*i++); + + len = strlen (buf); + write (c->remote_fd.fd, buf, len); + write (c->remote_fd.fd, "\n", 1); +} + static void do_client(CLI *c) { init_local(c); if(!c->opt->option.client && !c->opt->protocol) { /* Server mode and no protocol negotiation needed */ init_ssl(c); init_remote(c); + if(c->opt->option.send_client_info ){ + send_client_info(c); + } } else { init_remote(c); negotiate(c); --- a/src/options.c +++ b/src/options.c @@ -647,6 +647,28 @@ static char *service_options(CMD cmd, LO s_log(LOG_RAW, "%-15s = list of permitted SSL ciphers", "ciphers"); break; } + /* send client info */ + switch(cmd) { + case CMD_INIT: + section->option.send_client_info=0; + break; + case CMD_EXEC: + if(strcasecmp(opt, "send_client_info")) + break; + if(!strcasecmp(arg, "yes")) + section->option.send_client_info=1; + else if(!strcasecmp(arg, "no")) + section->option.send_client_info=0; + else + return "Argument should be either 'yes' or 'no'"; + return NULL; /* OK */ + case CMD_DEFAULT: + break; + case CMD_HELP: + s_log(LOG_RAW, "%-15s = yes|no send client info (to server)", + "send_client_info"); + break; + } /* client */ switch(cmd) { --- a/src/prototypes.h +++ b/src/prototypes.h @@ -224,6 +224,7 @@ typedef struct local_options { /* on/off switches */ struct { unsigned int cert:1; + unsigned int send_client_info:1; unsigned int client:1; unsigned int delayed_lookup:1; unsigned int accept:1;