See ChangeLog: Wed Jan 20 18:59:49 CET 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Wed, 20 Jan 1999 18:10:35 +0000 (18:10 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 20 Jan 1999 18:10:35 +0000 (18:10 +0000)
15 files changed:
NEWS
THANKS
cipher/ChangeLog
cipher/rndunix.c
g10/ChangeLog
g10/armor.c
g10/filter.h
g10/mainproc.c
g10/plaintext.c
g10/sign.c
g10/textfilter.c
include/iobuf.h
include/util.h
util/ChangeLog
util/http.c

diff --git a/NEWS b/NEWS
index eec5c8f..163c967 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@
 
     * Upgraded to zlib 1.1.3
 
+    * More cleanup on the cleartext signatures.
+
 
 Noteworthy changes in version 0.9.1
 -----------------------------------
diff --git a/THANKS b/THANKS
index fb9835f..e880ad2 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -72,6 +72,7 @@ SL Baur               steve@xemacs.org
 Stefan Karrmann        S.Karrmann@gmx.net
 Steffen Ullrich        ccrlphr@xensei.com
 Steffen Zahn           zahn@berlin.snafu.de
+Steven Bakker          steven@icoe.att.com
 Susanne Schultz        schultz@hsp.de
 Thiago Jung Bauermann  jungmann@usa.net
 Thomas Roessler        roessler@guug.de
index c46ca5d..273b6fd 100644 (file)
@@ -1,3 +1,7 @@
+Wed Jan 20 18:59:49 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndunix.c (gather_random): Fix to avoid infinite loop.
+
 Sun Jan 17 11:04:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * des.c (is_weak_key): Replace system memcmp due to bugs
index f0b6319..716b026 100644 (file)
@@ -709,6 +709,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
     /* now read from the gatherer */
     while( length ) {
        int goodness;
+       ulong subtract;
 
        if( read_a_msg( pipedes[0], &msg ) ) {
            g10_log_error("reading from gatherer pipe failed: %s\n",
@@ -742,7 +743,9 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
        (*add)( msg.data, n, requester );
 
        /* this is the trick how e cope with the goodness */
-       length -= (ulong)n * goodness / 100;
+       subtract = (ulong)n * goodness / 100;
+       /* subtract at least 1 byte to avoid infinite loops */
+       length -= subtract ? subtract : 1;
     }
 
     return 0;
index c9137ed..e3ba21f 100644 (file)
@@ -1,3 +1,8 @@
+Wed Jan 20 18:59:49 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * textfilter.c: Mostly rewritten
+       * plaintext.c (handle_plaintext): Use now text_filter semantics.
+
 Tue Jan 19 19:34:58 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * export.c (export_pubkeys_stream): New.
index 491cab4..195fc2c 100644 (file)
@@ -518,8 +518,6 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
                    putc('\n', stderr);
                }
                lastline = 1;
-               if( len >= 2 && !afx->not_dash_escaped )
-                   len -= 2; /* remove the last CR,LF */
                rc = -1;
            }
        }
index df436be..bfd1e7a 100644 (file)
@@ -86,6 +86,12 @@ typedef struct {
     unsigned buffer_len;    /* used length of the buffer */
     unsigned buffer_pos;    /* read position */
     int truncated;         /* number of truncated lines */
+    int clearsign;
+    int not_dash_escaped;
+    int escape_from;
+    MD_HANDLE md;
+    int pending_lf;
+    int pending_esc;
 } text_filter_context_t;
 
 
index 2e5575d..51547b8 100644 (file)
@@ -279,7 +279,7 @@ proc_plaintext( CTX c, PACKET *pkt )
        md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
        md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
     }
-    /*md_start_debug( c->mfx.md, "verify" );*/
+    md_start_debug( c->mfx.md, "verify" );
     rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
     if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
        /* can't write output but we hash it anyway to
index 0dc2469..98c4314 100644 (file)
@@ -89,6 +89,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
     }
 
     if( pt->len ) {
+       assert( !clearsig );
        for( ; pt->len; pt->len-- ) {
            if( (c = iobuf_get(pt->buf)) == -1 ) {
                log_error("Problem reading source (%u bytes remaining)\n",
@@ -98,7 +99,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
            }
            if( mfx->md )
                md_putc(mfx->md, c );
-           if( convert && !clearsig && c == '\r' )
+           if( convert && c == '\r' )
                continue; /* fixme: this hack might be too simple */
            if( fp ) {
                if( putc( c, fp ) == EOF ) {
@@ -110,11 +111,11 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
            }
        }
     }
-    else {
+    else if( !clearsig ) {
        while( (c = iobuf_get(pt->buf)) != -1 ) {
            if( mfx->md )
                md_putc(mfx->md, c );
-           if( convert && !clearsig && c == '\r' )
+           if( convert && c == '\r' )
                continue; /* fixme: this hack might be too simple */
            if( fp ) {
                if( putc( c, fp ) == EOF ) {
@@ -127,6 +128,47 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
        }
        pt->buf = NULL;
     }
+    else {  /* clear text signature - don't hash the last cr,lf  */
+       int state = 0;
+
+       while( (c = iobuf_get(pt->buf)) != -1 ) {
+           if( fp ) {
+               if( putc( c, fp ) == EOF ) {
+                   log_error("Error writing to `%s': %s\n",
+                                               fname, strerror(errno) );
+                   rc = G10ERR_WRITE_FILE;
+                   goto leave;
+               }
+           }
+           if( !mfx->md )
+               continue;
+           if( state == 2 ) {
+               md_putc(mfx->md, '\r' );
+               md_putc(mfx->md, '\n' );
+               state = 0;
+           }
+           if( !state ) {
+               if( c == '\r'  )
+                   state = 1;
+               else
+                   md_putc(mfx->md, c );
+           }
+           else if( state == 1 ) {
+               if( c == '\n'  )
+                   state = 2;
+               else {
+                   md_putc(mfx->md, '\r' );
+                   if( c == '\r'  )
+                       state = 1;
+                   else {
+                       state = 0;
+                       md_putc(mfx->md, c );
+                   }
+               }
+           }
+       }
+       pt->buf = NULL;
+    }
 
     if( fp && fp != stdout && fclose(fp) ) {
        log_error("Error closing `%s': %s\n", fname, strerror(errno) );
index e8582f4..fe13461 100644 (file)
@@ -455,7 +455,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
 }
 
 
-
+#if 0
 /****************
  * Note: We do not calculate the hash over the last CR,LF
  */
@@ -554,7 +554,7 @@ write_dash_escaped( IOBUF inp, IOBUF out, MD_HANDLE md )
 
     return 0; /* fixme: add error handling */
 }
-
+#endif
 
 /****************
  * make a clear signature. note that opt.armor is not needed
@@ -572,6 +572,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
     SK_LIST sk_rover = NULL;
     int old_style = opt.rfc1991;
     int only_md5 = 0;
+    int c;
 
     memset( &afx, 0, sizeof afx);
     memset( &tfx, 0, sizeof tfx);
@@ -645,13 +646,23 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
        PKT_secret_key *sk = sk_rover->sk;
        md_enable(textmd, hash_for(sk->pubkey_algo));
     }
-    /*md_start_debug( textmd, "create" );*/
-    if( !opt.not_dash_escaped )
-       iobuf_push_filter( inp, text_filter, &tfx );
-    rc = write_dash_escaped( inp, out, textmd );
-    if( rc )
-       goto leave;
+    md_start_debug( textmd, "sign" );
+    tfx.clearsign = 1;
+    tfx.not_dash_escaped = opt.not_dash_escaped;
+    tfx.escape_from = opt.escape_from;
+    tfx.md = textmd;
+    iobuf_push_filter( inp, text_filter, &tfx );
+    /* read input and write it to the output.  The textfilter handles
+     * the calculation of the hash and the dash escaping */
+    while( (c=iobuf_get(inp)) != -1 )  {
+       if( iobuf_put(out, c) == -1 ) {
+           rc = G10ERR_WRITE_FILE;
+           goto leave;
+       }
+    }
+    /* fixme: check for read errors */
 
+    /* now write the armor */
     afx.what = 2;
     iobuf_push_filter( out, armor_filter, &afx );
 
index 9959c93..07630d0 100644 (file)
@@ -1,5 +1,5 @@
 /* textfilter.c
- *     Copyright (C) 1998 Free Software Foundation, Inc.
+ *     Copyright (C) 1998,1999 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "i18n.h"
 
 
-#define MAX_LINELEN 20000
+#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */
+                         /* to make sure that a warning is displayed while */
+                         /* creating a message */
+
+unsigned
+len_without_trailing_ws( byte *line, unsigned len )
+{
+    byte *p, *mark;
+    unsigned n;
+
+    for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
+       if( strchr(" \t\r\n", *p ) ) {
+           if( !mark )
+               mark = p;
+       }
+       else
+           mark = NULL;
+    }
+
+    return mark? (mark - line) : len;
+}
+
+
+
+
+static int
+standard( text_filter_context_t *tfx, IOBUF a,
+         byte *buf, size_t size, size_t *ret_len)
+{
+    int rc=0;
+    size_t len = 0;
+    unsigned maxlen;
+
+    assert( size > 10 );
+    size -= 2; /* reserve 2 bytes to append CR,LF */
+    while( !rc && len < size ) {
+       int lf_seen;
+
+       while( len < size && tfx->buffer_pos < tfx->buffer_len )
+           buf[len++] = tfx->buffer[tfx->buffer_pos++];
+       if( len >= size )
+           continue;
+
+       /* read the next line */
+       maxlen = MAX_LINELEN;
+       tfx->buffer_pos = 0;
+       tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
+                                          &tfx->buffer_size, &maxlen );
+       if( !maxlen )
+           tfx->truncated++;
+       if( !tfx->buffer_len ) {
+           if( !len )
+               rc = -1; /* eof */
+           break;
+       }
+       lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
+       tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
+       if( lf_seen ) {
+           tfx->buffer[tfx->buffer_len++] = '\r';
+           tfx->buffer[tfx->buffer_len++] = '\n';
+       }
+    }
+    *ret_len = len;
+    return rc;
+}
+
+static int
+clearsign( text_filter_context_t *tfx, IOBUF a,
+           byte *buf, size_t size, size_t *ret_len)
+{
+    int rc=0;
+    size_t len = 0;
+    unsigned maxlen;
+
+    assert( size > 2 );
+    size -= 3; /* reserve for dash escaping and extra LF */
+    while( !rc && len < size ) {
+       unsigned n;
+       byte *p;
+
+       if( tfx->pending_esc ) {
+           buf[len++] = '-';
+           buf[len++] = ' ';
+           tfx->pending_esc = 0;
+       }
+       while( len < size && tfx->buffer_pos < tfx->buffer_len )
+           buf[len++] = tfx->buffer[tfx->buffer_pos++];
+       if( len >= size )
+           continue;
+
+       /* read the next line */
+       maxlen = MAX_LINELEN;
+       tfx->buffer_pos = 0;
+       tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
+                                          &tfx->buffer_size, &maxlen );
+       p = tfx->buffer;
+       n = tfx->buffer_len;
+       if( !maxlen )
+           tfx->truncated++;
+       if( !n ) { /* readline has returned eof */
+           /* don't hash a pending lf here because the last one is
+            * not part of the signed material. OpenPGP does not
+            * hash the last LF because it may have to add an
+            * extra one in case that the original material
+            * does not end with one.  The clear signed text
+            * must end in a LF, so that the following armor
+            * line can be detected by the parser
+            */
+           if( !tfx->pending_lf ) {
+               /* make sure that the file ends with a LF */
+               buf[len++] = '\n';
+               if( tfx->not_dash_escaped )
+                   md_putc(tfx->md, '\n' );
+               tfx->pending_lf = 1;
+           }
+           if( !len )
+               rc = -1; /* eof */
+           break;
+       }
+       if( tfx->md ) {
+           if( tfx->not_dash_escaped )
+               md_write( tfx->md, p, n );
+           else {
+               if( tfx->pending_lf ) {
+                   md_putc(tfx->md, '\r' );
+                   md_putc(tfx->md, '\n' );
+               }
+               md_write( tfx->md, p, len_without_trailing_ws( p, n ) );
+           }
+       }
+       tfx->pending_lf = p[n-1] == '\n';
+       if( tfx->not_dash_escaped )
+           ;
+       else if( *p == '-' )
+           tfx->pending_esc = 1;
+       else if( tfx->escape_from && n > 4 && !memcmp(p, "From ", 5 ) )
+           tfx->pending_esc = 1;
+    }
+    *ret_len = len;
+    return rc;
+}
 
 
 /****************
@@ -49,43 +189,11 @@ text_filter( void *opaque, int control,
     int rc=0;
 
     if( control == IOBUFCTRL_UNDERFLOW ) {
-       size_t len = 0;
-       unsigned maxlen;
-
-       assert( size > 10 );
-       size -= 2;  /* reserve 2 bytes to append CR,LF */
-       while( !rc && len < size ) {
-           int lf_seen;
-
-           while( len < size && tfx->buffer_pos < tfx->buffer_len )
-               buf[len++] = tfx->buffer[tfx->buffer_pos++];
-           if( len >= size )
-               continue;
-
-           /* read the next line */
-           maxlen = MAX_LINELEN;
-           tfx->buffer_pos = 0;
-           tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
-                                              &tfx->buffer_size, &maxlen );
-           if( !maxlen )
-               tfx->truncated++;
-           if( !tfx->buffer_len ) {
-               if( !len )
-                   rc = -1; /* eof */
-               break;
-           }
-           lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
-           tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
-           if( lf_seen ) {
-               tfx->buffer[tfx->buffer_len++] = '\r';
-               tfx->buffer[tfx->buffer_len++] = '\n';
-           }
-       }
-
-       *ret_len = len;
+       if( tfx->clearsign )
+           rc = clearsign( tfx, a, buf, size, ret_len );
+       else
+           rc = standard( tfx, a, buf, size, ret_len );
     }
-    else if( control == IOBUFCTRL_DESC )
-       *(char**)buf = "text_filter";
     else if( control == IOBUFCTRL_FREE ) {
        if( tfx->truncated )
            log_error(_("can't handle text lines longer than %d characters\n"),
@@ -93,6 +201,8 @@ text_filter( void *opaque, int control,
        m_free( tfx->buffer );
        tfx->buffer = NULL;
     }
+    else if( control == IOBUFCTRL_DESC )
+       *(char**)buf = "text_filter";
     return rc;
 }
 
index 9f4e8e7..9267100 100644 (file)
@@ -104,6 +104,7 @@ int  iobuf_writebyte(IOBUF a, unsigned c);
 int  iobuf_write(IOBUF a, byte *buf, unsigned buflen );
 int  iobuf_writestr(IOBUF a, const char *buf );
 
+void iobuf_flush_temp( IOBUF temp );
 int  iobuf_write_temp( IOBUF a, IOBUF temp );
 size_t iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen );
 void iobuf_unget_and_close_temp( IOBUF a, IOBUF temp );
index 892d508..8b8df37 100644 (file)
@@ -161,6 +161,7 @@ STRLIST strlist_last( STRLIST node );
 const char *memistr( const char *buf, size_t buflen, const char *sub );
 char *mem2str( char *, const void *, size_t);
 char *trim_spaces( char *string );
+unsigned trim_trailing_ws( byte *line, unsigned len );
 int string_count_chr( const char *string, int c );
 int set_native_charset( const char *newset );
 char *native_to_utf8( const char *string );
index 356e6df..1afdf76 100644 (file)
@@ -1,3 +1,7 @@
+Wed Jan 20 18:59:49 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * http.c (send_request): Removed double LF
+
 Tue Jan 19 19:34:58 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * * iobuf.c (iobuf_push_filter): Allow filters for temp streams
index 22c5699..4f04b62 100644 (file)
@@ -90,7 +90,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
        }
     }
 
-    if( !hd->fp_read && !hd->fp_write )
+    if( !hd->fp_read && !hd->fp_write && hd->socket != -1 )
        close( hd->socket );
     iobuf_close( hd->fp_read );
     iobuf_close( hd->fp_write);
@@ -102,7 +102,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
 
 
 void
-ttp_start_data( HTTP_HD hd )
+http_start_data( HTTP_HD hd )
 {
     if( !hd->in_data ) {
        iobuf_put( hd->fp_write, '\n' );
@@ -166,7 +166,7 @@ http_close( HTTP_HD hd )
 {
     if( !hd || !hd->initialized )
        return;
-    if( !hd->fp_read && !hd->fp_write )
+    if( !hd->fp_read && !hd->fp_write && hd->socket != -1 )
        close( hd->socket );
     iobuf_close( hd->fp_read );
     iobuf_close( hd->fp_write );
@@ -433,7 +433,7 @@ send_request( HTTP_HD hd )
 
     p = build_rel_path( hd->uri );
     request = m_alloc( strlen(p) + 20 );
-    sprintf( request, "%s %s%s HTTP/1.0\r\n\r\n",
+    sprintf( request, "%s %s%s HTTP/1.0\r\n",
                          hd->req_type == HTTP_REQ_GET ? "GET" :
                          hd->req_type == HTTP_REQ_HEAD? "HEAD":
                          hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
@@ -553,12 +553,77 @@ parse_response( HTTP_HD hd )
     return 0;
 }
 
+#if 0
+static int
+start_server()
+{
+    struct sockaddr_in mya;
+    struct sockaddr_in peer;
+    int fd, client;
+    fd_set rfds;
+    int addrlen;
+    int i;
+
+    if( (fd=socket(AF_INET,SOCK_STREAM, 0)) == -1 ) {
+       log_error("socket() failed: %s\n", strerror(errno));
+       return -1;
+    }
+    i = 1;
+    if( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (byte*)&i, sizeof(i) ) )
+       log_info("setsockopt(SO_REUSEADDR) failed: %s\n", strerror(errno) );
+
+    mya.sin_family=AF_INET;
+    memset(&mya.sin_addr, 0, sizeof(mya.sin_addr));
+    mya.sin_port=htons(11371);
 
+    if( bind( fd, (struct sockaddr *)&mya, sizeof(mya)) ) {
+       log_error("bind to port 11371 failed: %s\n", strerror(errno) );
+       close( fd );
+       return -1;
+    }
 
+    if( listen( fd, 5 ) ) {
+       log_error("listen failed: %s\n", strerror(errno) );
+       close( fd );
+       return -1;
+    }
 
+    for(;;) {
+       FD_ZERO(&rfds);
+       FD_SET( fd, &rfds );
 
+       if( select( fd+1, &rfds, NULL, NULL, NULL) <= 0 )
+           continue; /* ignore any errors */
 
+       if( !FD_ISSET( fd, &rfds ) )
+           continue;
 
+       addrlen = sizeof peer;
+       client = accept( fd, (struct sockaddr *)&peer, &addrlen);
+       if( client == -1 )
+           continue; /* oops */
+
+       log_info("connect from %s\n", inet_ntoa( peer.sin_addr ) );
+
+       fflush(stdout);
+       fflush(stderr);
+       if( !fork() ) {
+           int c;
+           FILE *fp;
+
+           fp = fdopen( client , "r" );
+           while( (c=getc(fp)) != EOF )
+               putchar(c);
+           fclose(fp);
+           exit(0);
+       }
+       close( client );
+    }
+
+
+    return 0;
+}
+#endif
 
 
 
@@ -632,6 +697,11 @@ main(int argc, char **argv)
     int c;
 
     log_set_name("http-test");
+    if( argc == 1 ) {
+       start_server();
+       return 0;
+    }
+
     if( argc != 2 ) {
        fprintf(stderr,"usage: http-test uri\n");
        return 1;
@@ -663,7 +733,7 @@ main(int argc, char **argv)
     }
     release_parsed_uri( uri ); uri = NULL;
 
-    rc = open_http_document( &hd, *argv, 0 );
+    rc = http_open_document( &hd, *argv, 0 );
     if( rc ) {
        log_error("can't get `%s': %s\n", *argv, g10_errstr(rc));
        return 1;
@@ -671,7 +741,7 @@ main(int argc, char **argv)
     log_info("open_http_document succeeded; status=%u\n", hd.status_code );
     while( (c=iobuf_get( hd.fp_read)) != -1 )
        putchar(c);
-    close_http_document( &hd );
+    http_close( &hd );
     return 0;
 }
 #endif /*TEST*/