diff --git a/neon/Makefile.in b/neon/Makefile.in index d0acd6826..9b380ad0c 100644 --- a/neon/Makefile.in +++ b/neon/Makefile.in @@ -45,6 +45,7 @@ transform = @program_transform_name@ LIBTOOL = @LIBTOOL@ XMLTO = xmlto +GCOV = gcov # The headers to distribute - making up the public interface of neon DIST_HEADERS = ne_request.h ne_session.h ne_utils.h ne_uri.h ne_socket.h \ @@ -60,9 +61,16 @@ check: subdirs # Useful for doing coverage analysis; use e.g.: # make TESTS=string-tests MODULE=ne_string cover cover: subdirs - rm -f src/$(MODULE).da - cd test && $(MAKE) check - cd src; gcov -cb $(MODULE) + @rm -f src/$(MODULE).*da test/common/*.*da test/*.*da + @cd test && $(MAKE) check + @cd src && $(GCOV) -cb $(MODULE) + +# as per 'cover' target; prints list of functions without 100% coverage +uncover: subdirs + @rm -f src/*.*da test/common/*.*da test/*.*da + @cd test && $(MAKE) check + @cd src && $(GCOV) -cb $(MODULE) + @grep ^function src/$(MODULE).gcov | grep -v 'executed 100' | sort -nr -k 9,9 subdirs: cd src && $(MAKE) diff --git a/neon/macros/neon.m4 b/neon/macros/neon.m4 index 6baef5157..3e6d818ba 100644 --- a/neon/macros/neon.m4 +++ b/neon/macros/neon.m4 @@ -867,8 +867,10 @@ gnutls) ne_gnutls_ver=`$GNUTLS_CONFIG --version` case $ne_gnutls_ver in + 1.0.?|1.0.1?|1.0.20|1.0.21) + AC_MSG_ERROR([GNU TLS version $ne_gnutls_ver is too old -- 1.0.22 or later required]) ;; 1.*) ;; - *) AC_MSG_ERROR([GNU TLS major version "$ne_gnutls_ver" not supported]) ;; + *) AC_MSG_ERROR([GNU TLS version $ne_gnutls_ver is not supported]) ;; esac CPPFLAGS="$CPPFLAGS `$GNUTLS_CONFIG --cflags`" diff --git a/neon/src/ne_compress.c b/neon/src/ne_compress.c index e99f11ee9..e31884fae 100644 --- a/neon/src/ne_compress.c +++ b/neon/src/ne_compress.c @@ -57,20 +57,9 @@ struct ne_decompress_s { void *userdata; /* buffer for gzip header bytes. */ - union { - unsigned char buf[10]; - struct header { - unsigned char id1; - unsigned char id2; - unsigned char cmeth; /* compression method. */ - unsigned char flags; - unsigned int mtime; /* breaks when sizeof int != 4 */ - unsigned char xflags; - unsigned char os; - } hdr; - } in; - size_t incount; /* bytes in in.buf */ - + unsigned char header[10]; + size_t hdrcount; /* bytes in header */ + unsigned char footer[8]; size_t footcount; /* bytes in footer. */ @@ -91,6 +80,9 @@ struct ne_decompress_s { } state; }; +/* Convert 'buf' to unsigned int; 'buf' must be 'unsigned char *' */ +#define BUF2UINT(buf) (((buf)[3]<<24) + ((buf)[2]<<16) + ((buf)[1]<<8) + (buf)[0]) + #define ID1 0x1f #define ID2 0x8b @@ -98,6 +90,14 @@ struct ne_decompress_s { #define HDR_EXTENDED 1 #define HDR_ERROR 2 +#define HDR_ID1(ctx) ((ctx)->header[0]) +#define HDR_ID2(ctx) ((ctx)->header[1]) +#define HDR_CMETH(ctx) ((ctx)->header[2]) +#define HDR_FLAGS(ctx) ((ctx)->header[3]) +#define HDR_MTIME(ctx) (BUF2UINT(&(ctx)->header[4])) +#define HDR_XFLAGS(ctx) ((ctx)->header[8]) +#define HDR_OS(ctx) ((ctx)->header[9]) + /* parse_header parses the gzip header, sets the next state and returns * HDR_DONE: all done, bytes following are raw DEFLATE data. * HDR_EXTENDED: all done, expect a NUL-termianted string @@ -107,27 +107,25 @@ struct ne_decompress_s { static int parse_header(ne_decompress *ctx) /*@modifies ctx @*/ { - struct header *h = &ctx->in.hdr; - NE_DEBUG(NE_DBG_HTTP, "ID1: %d ID2: %d, cmeth %d, flags %d\n", - h->id1, h->id2, h->cmeth, h->flags); + HDR_ID1(ctx), HDR_ID2(ctx), HDR_CMETH(ctx), HDR_FLAGS(ctx)); - if (h->id1 != ID1 || h->id2 != ID2 || h->cmeth != 8) { + if (HDR_ID1(ctx) != ID1 || HDR_ID2(ctx) != ID2 || HDR_CMETH(ctx) != 8) { ne_set_error(ctx->session, "Compressed stream invalid"); return HDR_ERROR; } NE_DEBUG(NE_DBG_HTTP, "mtime: %d, xflags: %d, os: %d\n", - h->mtime, h->xflags, h->os); + HDR_MTIME(ctx), HDR_XFLAGS(ctx), HDR_OS(ctx)); /* TODO: we can only handle one NUL-terminated extensions field * currently. Really, we should count the number of bits set, and * skip as many fields as bits set (bailing if any reserved bits * are set. */ - if (h->flags == 8) { + if (HDR_FLAGS(ctx) == 8) { ctx->state = NE_Z_POST_HEADER; return HDR_EXTENDED; - } else if (h->flags != 0) { + } else if (HDR_FLAGS(ctx) != 0) { ne_set_error(ctx->session, "Compressed stream not supported"); return HDR_ERROR; } @@ -138,9 +136,6 @@ static int parse_header(ne_decompress *ctx) return HDR_DONE; } -/* Convert 'buf' to unsigned int; 'buf' must be 'unsigned char *' */ -#define BUF2UINT(buf) ((buf[3]<<24) + (buf[2]<<16) + (buf[1]<<8) + buf[0]) - /* Process extra 'len' bytes of 'buf' which were received after the * DEFLATE data. */ static int process_footer(ne_decompress *ctx, @@ -316,15 +311,15 @@ static int gz_reader(void *ud, const char *buf, size_t len) case NE_Z_IN_HEADER: /* copy as many bytes as possible into the buffer. */ - if (len + ctx->incount > 10) { - count = 10 - ctx->incount; + if (len + ctx->hdrcount > 10) { + count = 10 - ctx->hdrcount; } else { count = len; } - memcpy(ctx->in.buf + ctx->incount, buf, count); - ctx->incount += count; + memcpy(ctx->header + ctx->hdrcount, buf, count); + ctx->hdrcount += count; /* have we got the full header yet? */ - if (ctx->incount != 10) { + if (ctx->hdrcount != 10) { return 0; } @@ -435,9 +430,8 @@ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, return (ne_decompress *)req; } -int ne_decompress_destroy(ne_decompress *dc) +void ne_decompress_destroy(ne_decompress *dc) { - return 0; } #endif /* NE_HAVE_ZLIB */ diff --git a/neon/src/ne_gnutls.c b/neon/src/ne_gnutls.c index b6f3b4366..77ab9b968 100644 --- a/neon/src/ne_gnutls.c +++ b/neon/src/ne_gnutls.c @@ -467,7 +467,7 @@ int ne__negotiate_ssl(ne_request *req) NE_DEBUG(NE_DBG_SSL, "Negotiating SSL connection.\n"); - if (ne_sock_connect_ssl(sess->socket, ctx)) { + if (ne_sock_connect_ssl(sess->socket, ctx, sess)) { ne_set_error(sess, _("SSL negotiation failed: %s"), ne_sock_error(sess->socket)); return NE_ERROR; diff --git a/neon/src/ne_openssl.c b/neon/src/ne_openssl.c index 8b43376e5..410e3d183 100644 --- a/neon/src/ne_openssl.c +++ b/neon/src/ne_openssl.c @@ -453,8 +453,7 @@ static ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc) static int provide_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey) /*@modifies *cert, *pkey @*/ { - ne_ssl_context *ctx = SSL_get_app_data(ssl); - ne_session *sess = SSL_CTX_get_app_data(ctx->ctx); + ne_session *const sess = SSL_get_app_data(ssl); if (!sess->client_cert && sess->ssl_provide_fn) { ne_ssl_dname **dnames = NULL; @@ -571,11 +570,7 @@ int ne__negotiate_ssl(ne_request *req) NE_DEBUG(NE_DBG_SSL, "Doing SSL negotiation.\n"); - /* Rather a hack: link the ssl_context back to the ne_session, so - * provide_client_cert can get to the ne_session. */ - SSL_CTX_set_app_data(ctx->ctx, sess); - - if (ne_sock_connect_ssl(sess->socket, ctx)) { + if (ne_sock_connect_ssl(sess->socket, ctx, sess)) { if (ctx->sess) { /* remove cached session. */ SSL_SESSION_free(ctx->sess); @@ -595,6 +590,7 @@ int ne__negotiate_ssl(ne_request *req) if (cert) { chain = sk_X509_new_null(); sk_X509_push(chain, cert); + freechain = 1; } } diff --git a/neon/src/ne_socket.c b/neon/src/ne_socket.c index 2157c193c..ccbfcd16e 100644 --- a/neon/src/ne_socket.c +++ b/neon/src/ne_socket.c @@ -1167,7 +1167,7 @@ int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx) return 0; } -int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx) +int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata) { int ret; @@ -1192,7 +1192,7 @@ int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx) return NE_SOCK_ERROR; } - SSL_set_app_data(ssl, ctx); + SSL_set_app_data(ssl, userdata); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); SSL_set_fd(ssl, sock->fd); sock->ops = &iofns_ssl; @@ -1211,6 +1211,7 @@ int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx) /* DH and RSA params are set in ne_ssl_context_create */ gnutls_init(&sock->ssl, GNUTLS_CLIENT); gnutls_set_default_priority(sock->ssl); + gnutls_session_set_ptr(sock->ssl, userdata); gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred); gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr) sock->fd); diff --git a/neon/src/ne_socket.h b/neon/src/ne_socket.h index a306c9a2f..062bae9c5 100644 --- a/neon/src/ne_socket.h +++ b/neon/src/ne_socket.h @@ -177,8 +177,8 @@ int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t count) ssize_t ne_sock_readline(ne_socket *sock, char *buffer, size_t len) /*@modifies sock, buffer @*/; -/* Read exactly 'len' bytes into buffer; returns 0 on success, SOCK_* - * on error. */ +/* Read exactly 'len' bytes into buffer; returns 0 on success, + * NE_SOCK_* on error. */ ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t len) /*@modifies sock, buffer @*/; @@ -215,8 +215,11 @@ int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx) /*@modifies sock, ctx @*/; /* Negotiate an SSL connection on socket as an SSL client, using given - * SSL context. */ -int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx) + * SSL context. The 'userdata' parameter is associated with the + * underlying SSL library's socket structure for use in callbacks. + * Returns zero on success, or non-zero on error. */ +int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, + void *userdata) /*@modifies sock, ctx @*/; END_NEON_DECLS diff --git a/neon/src/ne_utils.c b/neon/src/ne_utils.c index 3f7eb1ac0..f0937b918 100644 --- a/neon/src/ne_utils.c +++ b/neon/src/ne_utils.c @@ -142,6 +142,8 @@ int ne_version_match(int major, int minor) int ne_has_support(int feature) { switch (feature) { +#if defined(NE_HAVE_SSL) || defined(NE_HAVE_ZLIB) || defined(NE_HAVE_IPV6) \ + || defined(NE_HAVE_IDNA) || defined(NE_HAVE_SOCKS) || defined(NE_HAVE_LFS) #ifdef NE_HAVE_SSL case NE_FEATURE_SSL: #endif @@ -161,6 +163,7 @@ int ne_has_support(int feature) case NE_FEATURE_LFS: #endif return 1; +#endif /* NE_HAVE_* */ default: return 0; } diff --git a/neon/test/Makefile.in b/neon/test/Makefile.in index b49fa550e..9971f282f 100644 --- a/neon/test/Makefile.in +++ b/neon/test/Makefile.in @@ -50,7 +50,8 @@ COMPILE = $(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) all: $(TESTS) clean: - rm -f $(TESTS) $(HELPERS) *.*o common/*.*o libtest.a *.log + rm -f $(TESTS) $(HELPERS) *.*o common/*.*o libtest.*a *.log + rm -f *.gc* *.da *.bb* common/*.bb* common/*.gc* common/*.da rm -rf ca .libs rm -f ca-stamp client.key *.csr ssigned.pem wrongcn.pem \ server.cert client.cert client.p12 *.cert sparse.bin diff --git a/neon/test/ca1.pem b/neon/test/ca1.pem index 32f25291a..6edeb75aa 100644 --- a/neon/test/ca1.pem +++ b/neon/test/ca1.pem @@ -3,13 +3,13 @@ MIICQTCCAeugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCR0Ix FTATBgNVBAgTDExpbmNvbG5zaGlyZTEQMA4GA1UEBxMHTGluY29sbjERMA8GA1UE ChMIQ0FzIEx0ZC4xGDAWBgNVBAsTD0ZpcnN0IFJhbmRvbSBDQTEaMBgGA1UEAxMR Zmlyc3QuZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9y -ZzAeFw0wNDExMDExNTAzMTNaFw0wNzA0MjAxNTAzMTNaMIGfMQswCQYDVQQGEwJH +ZzAeFw0wNDExMDYxNTU3NDVaFw0wNzA0MjUxNTU3NDVaMIGfMQswCQYDVQQGEwJH QjEVMBMGA1UECBMMTGluY29sbnNoaXJlMRAwDgYDVQQHEwdMaW5jb2xuMREwDwYD VQQKEwhDQXMgTHRkLjEYMBYGA1UECxMPRmlyc3QgUmFuZG9tIENBMRowGAYDVQQD ExFmaXJzdC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYu b3JnMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPNFTmxnz4JZA+8+SonD0qWgSBPY WrNlH1FP+psm5EGZGmGJGvSDsk6HkyvstdopKF50UuEaJ263IorAhkmdGG0CAwEA -AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAAqqk1T3oQdI5Wqy -W3chgRhhIbbIs7t5pmhqKgsGuDajJf5SVwrKfm7UY9TRI9L0P8KiECoh3OvzxbsG -txt298w= +AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAG9N9dXMmDr8uq84 +UABK7AZnYcTPYZfSkrORfVHMAz/MrFS2uvbXtr/oDnzJDQQ8I6zESWVfk0uphwY7 +/BKbB98= -----END CERTIFICATE----- diff --git a/neon/test/ca2.pem b/neon/test/ca2.pem index 3060b1464..d52aa8f05 100644 --- a/neon/test/ca2.pem +++ b/neon/test/ca2.pem @@ -3,13 +3,13 @@ MIICPzCCAemgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnjELMAkGA1UEBhMCR0Ix ETAPBgNVBAgTCENvcm53YWxsMREwDwYDVQQHEwhGYWxtb3V0aDERMA8GA1UEChMI Q0FzIEx0ZC4xGTAXBgNVBAsTEFNlY29uZCBSYW5kb20gQ0ExGzAZBgNVBAMTEnNl Y29uZC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYub3Jn -MB4XDTA0MTEwMTE1MDMxM1oXDTA3MDQyMDE1MDMxM1owgZ4xCzAJBgNVBAYTAkdC +MB4XDTA0MTEwNjE1NTc0NVoXDTA3MDQyNTE1NTc0NVowgZ4xCzAJBgNVBAYTAkdC MREwDwYDVQQIEwhDb3Jud2FsbDERMA8GA1UEBxMIRmFsbW91dGgxETAPBgNVBAoT CENBcyBMdGQuMRkwFwYDVQQLExBTZWNvbmQgUmFuZG9tIENBMRswGQYDVQQDExJz ZWNvbmQuZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9y ZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDzRU5sZ8+CWQPvPkqJw9KloEgT2Fqz ZR9RT/qbJuRBmRphiRr0g7JOh5Mr7LXaKShedFLhGidutyKKwIZJnRhtAgMBAAGj -EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQBp0fpX6RKUfZ58TAAp -w0JHXYgWHOcz7VpxAxh95lHM5dZiFXWLfisrugIjMInpvQZuoP/Cem0XA2vj89Af -d+zA +EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQCPuJfPl9zFulCUb4WO +qFxJWopamWi7vlsTC4HyhqEh7puNyHWb+nJeKbfKyWlC0+41Dd0ZNf2RQdRWy54Y +kqU6 -----END CERTIFICATE----- diff --git a/neon/test/ca3.pem b/neon/test/ca3.pem index 99b0fd918..85501c238 100644 --- a/neon/test/ca3.pem +++ b/neon/test/ca3.pem @@ -3,12 +3,12 @@ MIICNzCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCR0Ix EDAOBgNVBAgTB1N1ZmZvbGsxEDAOBgNVBAcTB0lwc3dpY2gxETAPBgNVBAoTCENB cyBMdGQuMRgwFgYDVQQLEw9UaGlyZCBSYW5kb20gQ0ExGjAYBgNVBAMTEXRoaXJk LmV4YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwHhcN -MDQxMTAxMTUwMzEzWhcNMDcwNDIwMTUwMzEzWjCBmjELMAkGA1UEBhMCR0IxEDAO +MDQxMTA2MTU1NzQ1WhcNMDcwNDI1MTU1NzQ1WjCBmjELMAkGA1UEBhMCR0IxEDAO BgNVBAgTB1N1ZmZvbGsxEDAOBgNVBAcTB0lwc3dpY2gxETAPBgNVBAoTCENBcyBM dGQuMRgwFgYDVQQLEw9UaGlyZCBSYW5kb20gQ0ExGjAYBgNVBAMTEXRoaXJkLmV4 YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwXDANBgkq hkiG9w0BAQEFAANLADBIAkEA80VObGfPglkD7z5KicPSpaBIE9has2UfUU/6mybk QZkaYYka9IOyToeTK+y12ikoXnRS4RonbrciisCGSZ0YbQIDAQABoxAwDjAMBgNV -HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAS9S1VrowKJt9GIozWcsq1hD9XX+F -h0m7o7WudpVzjMhhbU97DJ7p2XFz5sKNpyPwRhkFTJ4Zm5XSTEc8WcsWBw== +HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAKRnbRNHr5XYy21HJn24moScHZ/cX +1a5IaajvmcGDLmUdXK7OjYlTfE6ot1+d5PbeYvXAvv5cxWBLwLHpYqxqNw== -----END CERTIFICATE----- diff --git a/neon/test/ca4.pem b/neon/test/ca4.pem index a88f1383e..56763c60d 100644 --- a/neon/test/ca4.pem +++ b/neon/test/ca4.pem @@ -3,12 +3,12 @@ MIICOzCCAeWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnDELMAkGA1UEBhMCR0Ix EDAOBgNVBAgTB05vcmZvbGsxEDAOBgNVBAcTB05vcndpY2gxETAPBgNVBAoTCENB cyBMdGQuMRkwFwYDVQQLExBGb3VydGggUmFuZG9tIENBMRswGQYDVQQDExJmb3Vy dGguZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9yZzAe -Fw0wNDExMDExNTAzMTNaFw0wNzA0MjAxNTAzMTNaMIGcMQswCQYDVQQGEwJHQjEQ +Fw0wNDExMDYxNTU3NDVaFw0wNzA0MjUxNTU3NDVaMIGcMQswCQYDVQQGEwJHQjEQ MA4GA1UECBMHTm9yZm9sazEQMA4GA1UEBxMHTm9yd2ljaDERMA8GA1UEChMIQ0Fz IEx0ZC4xGTAXBgNVBAsTEEZvdXJ0aCBSYW5kb20gQ0ExGzAZBgNVBAMTEmZvdXJ0 aC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYub3JnMFww DQYJKoZIhvcNAQEBBQADSwAwSAJBAPNFTmxnz4JZA+8+SonD0qWgSBPYWrNlH1FP +psm5EGZGmGJGvSDsk6HkyvstdopKF50UuEaJ263IorAhkmdGG0CAwEAAaMQMA4w -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBADZrHP9K8nS2WFiVBQgzljbN -aeP00s2BF/fBZjhqi94FmP07SHEcLBRuN+cK4J3ThuDOqc6C6cFjP/o+dfF1T2M= +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAKQLFoMpovQDo0JHJHvqqzJu +7KeoX6w2MrA8JfBtsG3XRBDqY4SfZ4ooSERJ3d9XKP2LUobGbQYeM2D4BfkdxRI= -----END CERTIFICATE----- diff --git a/neon/test/calist.pem b/neon/test/calist.pem index b8d26539f..a711d7000 100644 --- a/neon/test/calist.pem +++ b/neon/test/calist.pem @@ -3,56 +3,56 @@ MIICQTCCAeugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCR0Ix FTATBgNVBAgTDExpbmNvbG5zaGlyZTEQMA4GA1UEBxMHTGluY29sbjERMA8GA1UE ChMIQ0FzIEx0ZC4xGDAWBgNVBAsTD0ZpcnN0IFJhbmRvbSBDQTEaMBgGA1UEAxMR Zmlyc3QuZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9y -ZzAeFw0wNDExMDExNTAzMTNaFw0wNzA0MjAxNTAzMTNaMIGfMQswCQYDVQQGEwJH +ZzAeFw0wNDExMDYxNTU3NDVaFw0wNzA0MjUxNTU3NDVaMIGfMQswCQYDVQQGEwJH QjEVMBMGA1UECBMMTGluY29sbnNoaXJlMRAwDgYDVQQHEwdMaW5jb2xuMREwDwYD VQQKEwhDQXMgTHRkLjEYMBYGA1UECxMPRmlyc3QgUmFuZG9tIENBMRowGAYDVQQD ExFmaXJzdC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYu b3JnMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPNFTmxnz4JZA+8+SonD0qWgSBPY WrNlH1FP+psm5EGZGmGJGvSDsk6HkyvstdopKF50UuEaJ263IorAhkmdGG0CAwEA -AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAAqqk1T3oQdI5Wqy -W3chgRhhIbbIs7t5pmhqKgsGuDajJf5SVwrKfm7UY9TRI9L0P8KiECoh3OvzxbsG -txt298w= +AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAG9N9dXMmDr8uq84 +UABK7AZnYcTPYZfSkrORfVHMAz/MrFS2uvbXtr/oDnzJDQQ8I6zESWVfk0uphwY7 +/BKbB98= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICPzCCAemgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnjELMAkGA1UEBhMCR0Ix ETAPBgNVBAgTCENvcm53YWxsMREwDwYDVQQHEwhGYWxtb3V0aDERMA8GA1UEChMI Q0FzIEx0ZC4xGTAXBgNVBAsTEFNlY29uZCBSYW5kb20gQ0ExGzAZBgNVBAMTEnNl Y29uZC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYub3Jn -MB4XDTA0MTEwMTE1MDMxM1oXDTA3MDQyMDE1MDMxM1owgZ4xCzAJBgNVBAYTAkdC +MB4XDTA0MTEwNjE1NTc0NVoXDTA3MDQyNTE1NTc0NVowgZ4xCzAJBgNVBAYTAkdC MREwDwYDVQQIEwhDb3Jud2FsbDERMA8GA1UEBxMIRmFsbW91dGgxETAPBgNVBAoT CENBcyBMdGQuMRkwFwYDVQQLExBTZWNvbmQgUmFuZG9tIENBMRswGQYDVQQDExJz ZWNvbmQuZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9y ZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDzRU5sZ8+CWQPvPkqJw9KloEgT2Fqz ZR9RT/qbJuRBmRphiRr0g7JOh5Mr7LXaKShedFLhGidutyKKwIZJnRhtAgMBAAGj -EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQBp0fpX6RKUfZ58TAAp -w0JHXYgWHOcz7VpxAxh95lHM5dZiFXWLfisrugIjMInpvQZuoP/Cem0XA2vj89Af -d+zA +EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQCPuJfPl9zFulCUb4WO +qFxJWopamWi7vlsTC4HyhqEh7puNyHWb+nJeKbfKyWlC0+41Dd0ZNf2RQdRWy54Y +kqU6 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICNzCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCR0Ix EDAOBgNVBAgTB1N1ZmZvbGsxEDAOBgNVBAcTB0lwc3dpY2gxETAPBgNVBAoTCENB cyBMdGQuMRgwFgYDVQQLEw9UaGlyZCBSYW5kb20gQ0ExGjAYBgNVBAMTEXRoaXJk LmV4YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwHhcN -MDQxMTAxMTUwMzEzWhcNMDcwNDIwMTUwMzEzWjCBmjELMAkGA1UEBhMCR0IxEDAO +MDQxMTA2MTU1NzQ1WhcNMDcwNDI1MTU1NzQ1WjCBmjELMAkGA1UEBhMCR0IxEDAO BgNVBAgTB1N1ZmZvbGsxEDAOBgNVBAcTB0lwc3dpY2gxETAPBgNVBAoTCENBcyBM dGQuMRgwFgYDVQQLEw9UaGlyZCBSYW5kb20gQ0ExGjAYBgNVBAMTEXRoaXJkLmV4 YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwXDANBgkq hkiG9w0BAQEFAANLADBIAkEA80VObGfPglkD7z5KicPSpaBIE9has2UfUU/6mybk QZkaYYka9IOyToeTK+y12ikoXnRS4RonbrciisCGSZ0YbQIDAQABoxAwDjAMBgNV -HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAS9S1VrowKJt9GIozWcsq1hD9XX+F -h0m7o7WudpVzjMhhbU97DJ7p2XFz5sKNpyPwRhkFTJ4Zm5XSTEc8WcsWBw== +HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAKRnbRNHr5XYy21HJn24moScHZ/cX +1a5IaajvmcGDLmUdXK7OjYlTfE6ot1+d5PbeYvXAvv5cxWBLwLHpYqxqNw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICOzCCAeWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnDELMAkGA1UEBhMCR0Ix EDAOBgNVBAgTB05vcmZvbGsxEDAOBgNVBAcTB05vcndpY2gxETAPBgNVBAoTCENB cyBMdGQuMRkwFwYDVQQLExBGb3VydGggUmFuZG9tIENBMRswGQYDVQQDExJmb3Vy dGguZXhhbXBsZS5jb20xHjAcBgkqhkiG9w0BCQEWD25lb25Ad2ViZGF2Lm9yZzAe -Fw0wNDExMDExNTAzMTNaFw0wNzA0MjAxNTAzMTNaMIGcMQswCQYDVQQGEwJHQjEQ +Fw0wNDExMDYxNTU3NDVaFw0wNzA0MjUxNTU3NDVaMIGcMQswCQYDVQQGEwJHQjEQ MA4GA1UECBMHTm9yZm9sazEQMA4GA1UEBxMHTm9yd2ljaDERMA8GA1UEChMIQ0Fz IEx0ZC4xGTAXBgNVBAsTEEZvdXJ0aCBSYW5kb20gQ0ExGzAZBgNVBAMTEmZvdXJ0 aC5leGFtcGxlLmNvbTEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYub3JnMFww DQYJKoZIhvcNAQEBBQADSwAwSAJBAPNFTmxnz4JZA+8+SonD0qWgSBPYWrNlH1FP +psm5EGZGmGJGvSDsk6HkyvstdopKF50UuEaJ263IorAhkmdGG0CAwEAAaMQMA4w -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBADZrHP9K8nS2WFiVBQgzljbN -aeP00s2BF/fBZjhqi94FmP07SHEcLBRuN+cK4J3ThuDOqc6C6cFjP/o+dfF1T2M= +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAANBAKQLFoMpovQDo0JHJHvqqzJu +7KeoX6w2MrA8JfBtsG3XRBDqY4SfZ4ooSERJ3d9XKP2LUobGbQYeM2D4BfkdxRI= -----END CERTIFICATE----- diff --git a/neon/test/chain.pem b/neon/test/chain.pem index f2a822fde..523cdd91f 100644 --- a/neon/test/chain.pem +++ b/neon/test/chain.pem @@ -3,14 +3,14 @@ MIICNzCCAeGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT B05lb3NpZ24xFDASBgNVBAsTC1JhbmRvbSBEZXB0MRwwGgYDVQQDExNub3doZXJl LmV4YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwHhcN -MDQxMTAxMTUwMzEzWhcNMDcwNDIwMTUwMzEzWjCBmjELMAkGA1UEBhMCVVMxEzAR +MDQxMTA2MTU1NzQ1WhcNMDcwNDI1MTU1NzQ1WjCBmjELMAkGA1UEBhMCVVMxEzAR BgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoTB05l b3NpZ24xFDASBgNVBAsTC1JhbmRvbSBEZXB0MRwwGgYDVQQDExNub3doZXJlLmV4 YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwXDANBgkq -hkiG9w0BAQEFAANLADBIAkEAulGu4rv1AMHc4Nbf/Nwi9a5Yi4cOM+hpUpkXQ7Bk -uAB2r2xlX5F0bQdlItnOHRsCQ5HSFEVXeIr3OFn998cIiQIDAQABoxAwDjAMBgNV -HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAJ4/6DGrb1MNN10RtYVc/gG8mEU64 -exTFjqe7lnmkGx/AJJ1oHM+YQ97rQyXppyYSARYO02bWJ3BRWPyy3jt1tg== +hkiG9w0BAQEFAANLADBIAkEAurGk2lKvGFyM3RqAU+yjQNLuUasTz5C9JZ3JqXsr +Nj45Ue2UXYbhCdZL2Cbw5D2WwohEDUCfuaG89NZTRrpeIwIDAQABoxAwDjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA0EAMiO7fPfCpEnUwbpobocx4NCIwgpt +Ng8Zqh2KfJ8CdFPNLG9vhkFipIjWYiICybFaOIoeYakwkZm1T02r9MVdPA== -----END CERTIFICATE----- Certificate: Data: @@ -19,8 +19,8 @@ Certificate: Signature Algorithm: md5WithRSAEncryption Issuer: C=US, ST=California, L=Oakland, O=Neosign, OU=Random Dept, CN=nowhere.example.com/emailAddress=neon@webdav.org Validity - Not Before: Nov 1 15:03:13 2004 GMT - Not After : Apr 20 15:03:13 2007 GMT + Not Before: Nov 6 15:57:45 2004 GMT + Not After : Apr 25 15:57:45 2007 GMT Subject: C=GB, ST=Cambridgeshire, L=Cambridge, O=Neon Hackers Ltd, OU=Neon QA Dept, CN=localhost/emailAddress=neon@webdav.org Subject Public Key Info: Public Key Algorithm: rsaEncryption @@ -36,21 +36,21 @@ Certificate: X509v3 Basic Constraints: CA:FALSE Signature Algorithm: md5WithRSAEncryption - 47:f4:42:07:69:04:84:cd:c8:e2:92:6a:6c:f2:d6:2c:83:27: - fd:e1:72:8f:a7:46:90:8f:ce:83:5b:4c:f9:17:a5:dd:2a:cf: - e6:6f:b8:f4:98:78:f0:d5:ce:80:4a:68:76:2c:7e:24:c7:a2: - 2e:2f:5e:3e:63:6d:8d:c6:ca:ab + ac:ad:d9:47:df:dd:13:49:4e:1b:7f:4f:68:c3:7f:bb:ea:2c: + 73:5e:8a:e8:3a:91:55:69:a0:5b:9f:70:9a:73:0b:85:75:d7: + da:f4:5f:4e:71:7c:12:28:97:68:64:d8:b1:6d:cc:44:ae:a5: + 5a:49:6d:5b:cf:a0:90:58:2c:3c -----BEGIN CERTIFICATE----- MIICOjCCAeSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT B05lb3NpZ24xFDASBgNVBAsTC1JhbmRvbSBEZXB0MRwwGgYDVQQDExNub3doZXJl LmV4YW1wbGUuY29tMR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcwHhcN -MDQxMTAxMTUwMzEzWhcNMDcwNDIwMTUwMzEzWjCBoDELMAkGA1UEBhMCR0IxFzAV +MDQxMTA2MTU1NzQ1WhcNMDcwNDI1MTU1NzQ1WjCBoDELMAkGA1UEBhMCR0IxFzAV BgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlkZ2UxGTAXBgNV BAoTEE5lb24gSGFja2VycyBMdGQxFTATBgNVBAsTDE5lb24gUUEgRGVwdDESMBAG A1UEAxMJbG9jYWxob3N0MR4wHAYJKoZIhvcNAQkBFg9uZW9uQHdlYmRhdi5vcmcw XDANBgkqhkiG9w0BAQEFAANLADBIAkEA80VObGfPglkD7z5KicPSpaBIE9has2Uf UU/6mybkQZkaYYka9IOyToeTK+y12ikoXnRS4RonbrciisCGSZ0YbQIDAQABow0w -CzAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBAUAA0EAR/RCB2kEhM3I4pJqbPLWLIMn -/eFyj6dGkI/Og1tM+Rel3SrP5m+49Jh48NXOgEpodix+JMeiLi9ePmNtjcbKqw== +CzAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBAUAA0EArK3ZR9/dE0lOG39PaMN/u+os +c16K6DqRVWmgW59wmnMLhXXX2vRfTnF8EiiXaGTYsW3MRK6lWkltW8+gkFgsPA== -----END CERTIFICATE----- diff --git a/neon/test/compress.c b/neon/test/compress.c index 7e23af166..88097e3da 100644 --- a/neon/test/compress.c +++ b/neon/test/compress.c @@ -150,6 +150,7 @@ static int do_fetch(const char *realfn, const char *gzipfn, NE_DEBUG(NE_DBG_HTTP, "session error: %s\n", ne_get_error(sess)); + ne_decompress_destroy(dc); ne_request_destroy(req); ne_session_destroy(sess); ne_buffer_destroy(buf); diff --git a/neon/test/socket.c b/neon/test/socket.c index 47a86f884..d3bfd2f1d 100644 --- a/neon/test/socket.c +++ b/neon/test/socket.c @@ -169,7 +169,7 @@ static int begin(ne_socket **sock, server_fn fn, void *ud) pair.userdata = ud; CALL(spawn_server(7777, wrap_serve, &pair)); CALL(do_connect(sock, localhost, 7777)); - ONV(ne_sock_connect_ssl(*sock, client_ctx), + ONV(ne_sock_connect_ssl(*sock, client_ctx, NULL), ("SSL negotation failed: %s", ne_sock_error(*sock))); return OK; } @@ -229,6 +229,8 @@ static int addr_make_v4(void) ne_iaddr_print(ia, pr, sizeof pr); ONV(strcmp(pr, "127.0.0.1"), ("address was %s not 127.0.0.1", pr)); + ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv4); + ne_iaddr_free(ia); return OK; } @@ -256,6 +258,8 @@ static int addr_make_v6(void) ONV(strcmp(pr, as[n].rep), ("address %d was '%s' not '%s'", n, pr, as[n].rep)); + ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv6); + ne_iaddr_free(ia); } @@ -292,9 +296,9 @@ static int addr_compare(void) ONN("comparison of IPv4 and IPv6 addresses was zero", ret == 0); ne_iaddr_free(ia1); - ia1 = ne_iaddr_make(ne_iaddr_ipv4, "feed::1"); + ia1 = ne_iaddr_make(ne_iaddr_ipv6, "feed::1"); ret = ne_iaddr_cmp(ia1, ia2); - ONN("comparison of equal IPv6 addresses was zero", ret == 0); + ONN("comparison of equal IPv6 addresses was zero", ret != 0); #endif @@ -335,7 +339,7 @@ static int addr_connect(void) static int expect_close(ne_socket *sock) { ssize_t n = ne_sock_read(sock, buffer, 1); - ONV(n > 0, ("read got %" NE_FMT_SSIZE_T "bytes not closure", n)); + ONV(n > 0, ("read got %" NE_FMT_SSIZE_T " bytes not closure", n)); ONV(n < 0 && n != NE_SOCK_CLOSED, ("read got error not closure: `%s'", ne_sock_error(sock))); return OK; @@ -409,15 +413,29 @@ static int read_expect(ne_socket *sock, const char *str, size_t len) { ssize_t ret = ne_sock_read(sock, buffer, len); ONV((ssize_t)len != ret, - ("peek got %" NE_FMT_SSIZE_T " bytes not %" NE_FMT_SIZE_T, ret, len)); + ("read got %" NE_FMT_SSIZE_T " bytes not %" NE_FMT_SIZE_T, ret, len)); ONV(memcmp(str, buffer, len), ("read mismatch: `%.*s' not `%.*s'", (int)len, buffer, (int)len, str)); return OK; } +/* do a sock_read() on sock for 'len' bytes, and expect 'str'. */ +static int fullread_expect(ne_socket *sock, const char *str, size_t len) +{ + ssize_t ret = ne_sock_fullread(sock, buffer, len); + ONV(ret, ("fullread failed (%" NE_FMT_SSIZE_T "): %s", + ret, ne_sock_error(sock))); + ONV(memcmp(str, buffer, len), + ("fullread mismatch: `%.*s' not `%.*s'", + (int)len, buffer, (int)len, str)); + return OK; +} + + /* Declare a struct string */ #define DECL(var,str) struct string var = { str, 0 }; var.len = strlen(str) +#define DECL_LONG(var,ch,n) struct string var; var.data = memset(ne_malloc(n), ch, n); var.len = n; /* Test a simple read. */ static int single_read(void) @@ -464,6 +482,7 @@ static int small_reads(void) /* peek or read, expecting to get given string. */ #define READ(str) CALL(read_expect(sock, str, strlen(str))) +#define FULLREAD(str) CALL(fullread_expect(sock, str, strlen(str))) #define PEEK(str) CALL(peek_expect(sock, str, strlen(str))) /* Stress out the read buffer handling a little. */ @@ -575,10 +594,31 @@ static int line_toolong(void) ret = ne_sock_readline(sock, buffer, 5); ONV(ret != NE_SOCK_ERROR, ("readline should fail on long line: %" NE_FMT_SSIZE_T, ret)); - + reap_server(); + ne_sock_close(sock); + return OK; +} + +#define OVERLEN (9000) + +static int line_overflow(void) +{ + ne_socket *sock; + ssize_t ret; + DECL_LONG(line, 'A', OVERLEN); + + CALL(begin(&sock, serve_sstring, &line)); + + PEEK("A"); /* fill the read buffer */ + ret = ne_sock_readline(sock, buffer, OVERLEN); + ONV(ret != NE_SOCK_ERROR, + ("readline should fail on overlong line: %" NE_FMT_SSIZE_T, ret)); + + ne_free(line.data); return finish(sock, 0); } + /* readline()s mingled with other operations: buffering tests. */ static int line_mingle(void) { @@ -609,6 +649,26 @@ static int line_chunked(void) return finish(sock, 1); } +static int line_long_chunked(void) +{ + ne_socket *sock; + ssize_t ret; + DECL_LONG(line, 'Z', OVERLEN); + + CALL(begin(&sock, serve_sstring_slowly, &line)); + + FULLREAD("ZZZZZZZZ"); /* fill the buffer */ + ret = ne_sock_readline(sock, buffer, sizeof buffer); + ONV(ret != NE_SOCK_ERROR, + ("readline gave %" NE_FMT_SSIZE_T " not failure", ret)); + + reap_server(); + ne_sock_close(sock); + ne_free(line.data); + return OK; +} + + static time_t to_start, to_finish; static int to_begin(ne_socket **sock) @@ -841,6 +901,49 @@ static int read_reset(void) } #endif +static int expect_block_timeout(ne_socket *sock, int timeout, const char *msg) +{ + int ret; + NE_DEBUG(NE_DBG_SOCKET, "blocking for %d\n", timeout); + ret = ne_sock_block(sock, timeout); + ONV(ret != NE_SOCK_TIMEOUT, ( + "ne_sock_block got %d not timeout: %s", ret, msg)); + return OK; +} + +static int blocking(void) +{ + ne_socket *sock; + int ret; + + CALL(begin(&sock, echo_server, NULL)); + CALL(expect_block_timeout(sock, 1, "with non-zero timeout")); + + WRITEL("Hello, world.\n"); + + /* poll for data */ + do { + ret = ne_sock_block(sock, 1); + } while (ret == NE_SOCK_TIMEOUT); + + ONV(ret != 0, ("ne_sock_block never got data: %d", ret)); + + PEEK("Hello,"); + ret = ne_sock_block(sock, 1); + ONV(ret != 0, ("ne_sock_block failed after peek: %d", ret)); + + LINE("Hello, world.\n"); + + return finish(sock, 0); +} + +static int block_timeout(void) +{ + TO_BEGIN; + TO_OP(ne_sock_block(sock, 1)); + TO_FINISH; +} + ne_test tests[] = { T(multi_init), T_LEAKY(resolve), @@ -864,11 +967,14 @@ ne_test tests[] = { T(line_closure), T(line_empty), T(line_toolong), + T(line_overflow), T(line_mingle), T(line_chunked), + T(line_long_chunked), T(small_writes), T(large_writes), T(echo_lines), + T(blocking), #ifdef SOCKET_SSL T(ssl_closure), T(ssl_truncate), @@ -880,5 +986,6 @@ ne_test tests[] = { T(peek_timeout), T(readline_timeout), T(fullread_timeout), + T(block_timeout), T(NULL) }; diff --git a/neon/test/stubs.c b/neon/test/stubs.c index 1c599623b..4b5d03e35 100644 --- a/neon/test/stubs.c +++ b/neon/test/stubs.c @@ -1,6 +1,6 @@ /* neon test suite - Copyright (C) 2002-2003, Joe Orton + Copyright (C) 2002-2004, Joe Orton This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -80,8 +80,7 @@ static int stub_decompress(void) ONREQ(ret); - ONN("decompress_destroy failed", ne_decompress_destroy(dc)); - + ne_decompress_destroy(dc); ne_request_destroy(req); ne_session_destroy(sess);