The attached patches alter the way 'openssl s_client' surprisingly 
interprets the 'Q' and 'R' characters at the start of a line.

Option 1: openssl-removeqr.patch : eliminates the 'Q' and 'R' "commands" 
completely, from s_client and the documentation.

Option 2: openssl-commandkeys.patch : adds a commandline argument 
'-commandkeys', that enables the commands in "interactive" mode (i.e. no 
'-ign_eof' and no '-quiet').  It is *not* enabled by default.

Option 1 is what I'd use, but only because I really have no idea what the 
initial use-case was for these "commands" (especially since "Q" is 
identical to EOF).


Justification:  The 'R' for 'r'enegotiate in particular seems to be 
nothing but a source of confusion and bugs to be worked-around.  Googling 
(unquoted:) "s_client renegotiate" yields nothing in the first 50 results 
that isn't one of:

1) the s_client 'man' page
2) someone warning others to not start their s_client lines with 'R'
3) a patch to other software to use the -ign_eof flag to avoid this

The use of 'Q' and 'R' affects interactive sessions of SMTP, IMAP, and 
POP3 (that I know of), which are prime candidates for testing via 
s_client.  (In SMTP, 'RCPT TO' is essential.  In IMAP, 'Q' and 'R' are 
perfectly fine starting chars for command identifiers.  And POP3 has 
'RETR'.)

Thanks for the consideration.

Best,
Ben
Index: apps/s_client.c
===================================================================
RCS file: /v/openssl/cvs/openssl/apps/s_client.c,v
retrieving revision 1.123
diff -u -r1.123 s_client.c
--- apps/s_client.c     15 Feb 2009 15:29:59 -0000      1.123
+++ apps/s_client.c     20 Mar 2009 06:18:59 -0000
@@ -211,6 +211,7 @@
 static BIO *bio_c_out=NULL;
 static int c_quiet=0;
 static int c_ign_eof=0;
+static int c_commandkeys=0;
 
 #ifndef OPENSSL_NO_PSK
 /* Default PSK identity and key */
@@ -309,6 +310,7 @@
        BIO_printf(bio_err," -quiet        - no s_client output\n");
        BIO_printf(bio_err," -ign_eof      - ignore input eof (default when 
-quiet)\n");
        BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
+       BIO_printf(bio_err," -commandkeys  - 'Q' and 'R' are special after 
CRLF\n");
 #ifndef OPENSSL_NO_PSK
        BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
        BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
@@ -449,6 +451,7 @@
        c_Pause=0;
        c_quiet=0;
        c_ign_eof=0;
+       c_commandkeys=0;
        c_debug=0;
        c_msg=0;
        c_showcerts=0;
@@ -540,6 +543,8 @@
                        c_ign_eof=1;
                else if (strcmp(*argv,"-no_ign_eof") == 0)
                        c_ign_eof=0;
+               else if (strcmp(*argv,"-commandkeys") == 0)
+                       c_commandkeys=1;
                else if (strcmp(*argv,"-pause") == 0)
                        c_Pause=1;
                else if (strcmp(*argv,"-debug") == 0)
@@ -1531,14 +1536,14 @@
                        else
                                i=raw_read_stdin(cbuf,BUFSIZZ);
 
-                       if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
+                       if ((!c_ign_eof) && ((i <= 0) || ((c_commandkeys) && 
(cbuf[0] == 'Q'))))
                                {
                                BIO_printf(bio_err,"DONE\n");
                                ret=0;
                                goto shut;
                                }
 
-                       if ((!c_ign_eof) && (cbuf[0] == 'R'))
+                       if ((!c_ign_eof) && (c_commandkeys) && (cbuf[0] == 'R'))
                                {
                                BIO_printf(bio_err,"RENEGOTIATING\n");
                                SSL_renegotiate(con);
Index: doc/apps/s_client.pod
===================================================================
RCS file: /v/openssl/cvs/openssl/doc/apps/s_client.pod,v
retrieving revision 1.16
diff -u -r1.16 s_client.pod
--- doc/apps/s_client.pod       23 Aug 2007 11:34:48 -0000      1.16
+++ doc/apps/s_client.pod       20 Mar 2009 06:18:59 -0000
@@ -28,6 +28,7 @@
 [B<-crlf>]
 [B<-ign_eof>]
 [B<-quiet>]
+[B<-commandkeys>]
 [B<-ssl2>]
 [B<-ssl3>]
 [B<-tls1>]
@@ -161,6 +162,11 @@
 inhibit printing of session and certificate information.  This implicitly
 turns on B<-ign_eof> as well.
 
+=item B<-commandkeys>
+
+enable the 'Q' (quit) and 'R' (renegotiate) command keys when connected in
+interactive mode.
+
 =item B<-psk_identity identity>
 
 Use the PSK identity B<identity> when using a PSK cipher suite.
@@ -239,9 +245,10 @@
 If a connection is established with an SSL server then any data received
 from the server is displayed and any key presses will be sent to the
 server. When used interactively (which means neither B<-quiet> nor B<-ign_eof>
-have been given), the session will be renegotiated if the line begins with an
-B<R>, and if the line begins with a B<Q> or if end of file is reached, the
-connection will be closed down.
+have been given), if end of file is reached, the connection will be closed
+down. In addition, if B<-commandkeys> has been given, the session will be
+renegotiated if the line begins with an B<R>, and the connection will be closed
+if the line begins with a B<Q>.
 
 =head1 NOTES
 
Index: apps/s_client.c
===================================================================
RCS file: /v/openssl/cvs/openssl/apps/s_client.c,v
retrieving revision 1.123
diff -u -r1.123 s_client.c
--- apps/s_client.c     15 Feb 2009 15:29:59 -0000      1.123
+++ apps/s_client.c     20 Mar 2009 06:26:29 -0000
@@ -1531,19 +1531,12 @@
                        else
                                i=raw_read_stdin(cbuf,BUFSIZZ);
 
-                       if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
+                       if ((!c_ign_eof) && (i <= 0))
                                {
                                BIO_printf(bio_err,"DONE\n");
                                ret=0;
                                goto shut;
                                }
-
-                       if ((!c_ign_eof) && (cbuf[0] == 'R'))
-                               {
-                               BIO_printf(bio_err,"RENEGOTIATING\n");
-                               SSL_renegotiate(con);
-                               cbuf_len=0;
-                               }
                        else
                                {
                                cbuf_len=i;
Index: doc/apps/s_client.pod
===================================================================
RCS file: /v/openssl/cvs/openssl/doc/apps/s_client.pod,v
retrieving revision 1.16
diff -u -r1.16 s_client.pod
--- doc/apps/s_client.pod       23 Aug 2007 11:34:48 -0000      1.16
+++ doc/apps/s_client.pod       20 Mar 2009 06:26:30 -0000
@@ -239,9 +239,7 @@
 If a connection is established with an SSL server then any data received
 from the server is displayed and any key presses will be sent to the
 server. When used interactively (which means neither B<-quiet> nor B<-ign_eof>
-have been given), the session will be renegotiated if the line begins with an
-B<R>, and if the line begins with a B<Q> or if end of file is reached, the
-connection will be closed down.
+have been given), the connection will be closed down if end of file is reached.
 
 =head1 NOTES
 

Reply via email to