diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-01 18:39:45 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-01 18:39:45 +0000 |
commit | d36c5c143c94c6ee3d165a80ca2c7979e03db9ca (patch) | |
tree | 43716259f0f3d72974052f40b08ef930cd2bb8c7 | |
parent | af15da7a2d647bc1c22ff4b268dce0116ba98266 (diff) | |
download | gnutls-d36c5c143c94c6ee3d165a80ca2c7979e03db9ca.tar.gz |
A new patch by Arne. More bug fixes and optimizations.
-rw-r--r-- | lib/gnutls_alert.c | 4 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 2 | ||||
-rw-r--r-- | lib/gnutls_record.c | 17 | ||||
-rw-r--r-- | lib/gnutls_state.c | 3 | ||||
-rw-r--r-- | lib/minitasn1/structure.c | 2 | ||||
-rw-r--r-- | src/cli.c | 45 | ||||
-rw-r--r-- | src/common.c | 20 | ||||
-rw-r--r-- | src/serv.c | 73 |
8 files changed, 94 insertions, 72 deletions
diff --git a/lib/gnutls_alert.c b/lib/gnutls_alert.c index be5d44291d..5350650ead 100644 --- a/lib/gnutls_alert.c +++ b/lib/gnutls_alert.c @@ -74,8 +74,8 @@ static const gnutls_alert_entry sup_alerts[] = { * gnutls_alert_get_name - Returns a string describing the alert number given * @alert: is an alert number &gnutls_session structure. * - * Returns a string that describes the given alert number. - * See. gnutls_alert_get(). + * Returns a string that describes the given alert number or NULL. + * See gnutls_alert_get(). * **/ const char* gnutls_alert_get_name( gnutls_alert_level alert) diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 02e5e82fac..74901d017a 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -189,7 +189,7 @@ void gnutls_perror(int error) /* avoid prefix */ GNUTLS_ERROR_ALG_LOOP(ret = p->desc); - + if (ret == NULL) ret = "(unknown)"; fprintf(stderr, "GNUTLS ERROR: %s\n", ret); } diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 9284fd0bf1..0c024292c0 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -449,7 +449,7 @@ ssize_t _gnutls_send_int( gnutls_session session, ContentType type, HandshakeTyp */ ssize_t _gnutls_send_change_cipher_spec( gnutls_session session, int again) { - opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC }; + static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC }; _gnutls_handshake_log( "REC[%x]: Sent ChangeCipherSpec\n", session); @@ -679,7 +679,7 @@ static int _gnutls_record_check_type( gnutls_session session, ContentType recv_t /* This function behaves exactly like read(). The only difference is * that it accepts the gnutls_session and the ContentType of data to - * send (if called by the user the Content is Userdata only) + * receive (if called by the user the Content is Userdata only) * It is intended to receive data, under the current session. */ ssize_t _gnutls_recv_int( gnutls_session session, ContentType type, HandshakeType htype, char *data, size_t sizeofdata) @@ -707,11 +707,6 @@ ssize_t _gnutls_recv_int( gnutls_session session, ContentType type, HandshakeTyp return GNUTLS_E_TOO_MANY_EMPTY_PACKETS; } - /* default headers for TLS 1.0 - */ - header_size = RECORD_HEADER_SIZE; - ret = 0; - if ( _gnutls_session_is_valid(session)!=0 || session->internals.may_read!=0) { gnutls_assert(); return GNUTLS_E_INVALID_SESSION; @@ -725,6 +720,10 @@ ssize_t _gnutls_recv_int( gnutls_session session, ContentType type, HandshakeTyp return ret; + /* default headers for TLS 1.0 + */ + header_size = RECORD_HEADER_SIZE; + if ( (ret = _gnutls_io_read_buffered( session, &headers, header_size, -1)) != header_size) { if (ret < 0 && gnutls_error_is_fatal(ret)==0) return ret; @@ -778,7 +777,7 @@ ssize_t _gnutls_recv_int( gnutls_session session, ContentType type, HandshakeTyp /* check if we have that data into buffer. */ - if ( (ret = _gnutls_io_read_buffered( session, &recv_data, header_size+length, recv_type)) != length+header_size) { + if ( (ret = _gnutls_io_read_buffered( session, &recv_data, header_size+length, recv_type)) != header_size+length) { if (ret<0 && gnutls_error_is_fatal(ret)==0) return ret; _gnutls_session_unresumable( session); @@ -869,7 +868,7 @@ ssize_t _gnutls_recv_int( gnutls_session session, ContentType type, HandshakeTyp } } else { gnutls_assert(); - ret = GNUTLS_E_UNEXPECTED_PACKET; + return GNUTLS_E_UNEXPECTED_PACKET; /* we didn't get what we wanted to */ } diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 5c93549acf..490ba7670f 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -146,7 +146,6 @@ void _gnutls_handshake_internal_state_clear( gnutls_session session) { } #define MIN_DH_BITS 727 -#define _gnutls_free(x) if(x!=NULL) gnutls_free(x) /** * gnutls_init - This function initializes the session to null (null encryption etc...). * @con_end: is used to indicate if this session is to be used for server or @@ -308,7 +307,7 @@ void _gnutls_deinit(gnutls_session session) _gnutls_mpi_release(&session->key->rsa[1]); _gnutls_mpi_release(&session->key->dh_secret); - _gnutls_free(session->key); + gnutls_free(session->key); session->key = NULL; } diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c index 1291a00981..fbcd832d18 100644 --- a/lib/minitasn1/structure.c +++ b/lib/minitasn1/structure.c @@ -661,7 +661,7 @@ asn1_print_structure(FILE *out,ASN1_TYPE structure,const char *name,int mode) break; case TYPE_TAG: if(mode == ASN1_PRINT_ALL) - fprintf(out," value:%s",p->value); + if(p->value) fprintf(out," value:%s",p->value); break; case TYPE_SIZE: if(mode == ASN1_PRINT_ALL) @@ -47,7 +47,7 @@ #endif #define SA struct sockaddr -#define ERR(err,s) if (err==-1) {perror(s);return(1);} +#define ERR(err,s) do { if (err==-1) {perror(s);return(1);} } while (0) #define MAX_BUF 4096 /* global stuff here */ @@ -78,20 +78,20 @@ static gnutls_srp_client_credentials srp_cred; static gnutls_anon_client_credentials anon_cred; static gnutls_certificate_credentials xcred; -int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; -int kx_priority[16] = +static const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; +static const int kx_priority[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, /* Do not use anonymous authentication, unless you know what that means */ GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA_EXPORT, 0 }; -int cipher_priority[16] = +static const int cipher_priority[] = { GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR_40, 0 }; -int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; -int mac_priority[16] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; -int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; +static const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; +static const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; +static const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; /* end of global stuff */ @@ -104,13 +104,14 @@ typedef struct { } socket_st; ssize_t socket_recv(socket_st socket, void *buffer, int buffer_size); -ssize_t socket_send(socket_st socket, void *buffer, int buffer_size); +ssize_t socket_send(socket_st socket, const void *buffer, int buffer_size); void socket_bye(socket_st * socket); static void check_rehandshake(socket_st socket, int ret); static int do_handshake(socket_st * socket); static void init_global_tls_stuff(void); +#undef MAX #define MAX(X,Y) (X >= Y ? X : Y); /* A callback function to be used at the certificate selection time. @@ -208,7 +209,7 @@ static void gaa_parser(int argc, char **argv); static int handle_error(socket_st hd, int err) { int alert, ret; - const char *err_type; + const char *err_type, *str; if (err >= 0) return 0; @@ -220,14 +221,17 @@ static int handle_error(socket_st hd, int err) err_type = "Fatal"; } + str = gnutls_strerror(err); + if (str == NULL) str = "(unknown)"; fprintf(stderr, - "*** %s error: %s\n", err_type, gnutls_strerror(err)); + "*** %s error: %s\n", err_type, str); if (err == GNUTLS_E_WARNING_ALERT_RECEIVED || err == GNUTLS_E_FATAL_ALERT_RECEIVED) { alert = gnutls_alert_get(hd.session); - printf("*** Received alert [%d]: %s\n", - alert, gnutls_alert_get_name(alert)); + str = gnutls_alert_get_name(alert); + if (str == NULL) str = "(unknown)"; + printf("*** Received alert [%d]: %s\n", alert, str); } @@ -261,6 +265,10 @@ int main(int argc, char **argv) socket_st hd; gaa_parser(argc, argv); + if (hostname == NULL) { + fprintf(stderr, "No hostname given\n"); + exit(1); + } signal(SIGPIPE, SIG_IGN); @@ -284,7 +292,11 @@ int main(int argc, char **argv) sa.sin_addr.s_addr = *((unsigned int *) server_host->h_addr); - inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF); + if (inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF) == NULL) { + perror("inet_ntop()"); + return(1); + } + fprintf(stderr, "Connecting to '%s:%d'...\n", buffer, port); err = connect(sd, (SA *) & sa, sizeof(sa)); @@ -433,11 +445,10 @@ int main(int argc, char **argv) socket_bye(&hd); user_term = 1; } - continue; } else { user_term = 1; - continue; } + continue; } if (crlf != 0) { @@ -559,7 +570,7 @@ ssize_t socket_recv(socket_st socket, void *buffer, int buffer_size) return ret; } -ssize_t socket_send(socket_st socket, void *buffer, int buffer_size) +ssize_t socket_send(socket_st socket, const void *buffer, int buffer_size) { int ret; @@ -648,7 +659,7 @@ static void tls_log_func(int level, const char *str) fprintf(stderr, "|<%d>| %s", level, str); } -static void init_global_tls_stuff() +static void init_global_tls_stuff(void) { int ret; diff --git a/src/common.c b/src/common.c index 93af1608de..4fbd6132a8 100644 --- a/src/common.c +++ b/src/common.c @@ -15,13 +15,14 @@ int xml = 0; #define PRINT_PGP_NAME(X) PRINTX( "NAME:", X.name); \ PRINTX( "EMAIL:", X.email) -static const char *my_ctime(time_t * tv) +static const char *my_ctime(const time_t * tv) { static char buf[256]; struct tm *tp; - tp = localtime(tv); - strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y\n", tp); + if ( ( (tp = localtime(tv)) == NULL ) || + (!strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y\n", tp)) ) + strcpy(buf, "unknown"); /* make sure buf text isn't garbage */ return buf; @@ -62,8 +63,9 @@ void print_x509_info(gnutls_session session, const char* hostname) gnutls_x509_crt_import(crt, &cert_list[j], GNUTLS_X509_FMT_DER); if (ret < 0) { - fprintf(stderr, "Decoding error: %s\n", - gnutls_strerror(ret)); + const char* str = gnutls_strerror(ret); + if (str == NULL) str = "(unknown)"; + fprintf(stderr, "Decoding error: %s\n", str); return; } @@ -87,8 +89,10 @@ void print_x509_info(gnutls_session session, const char* hostname) ret = gnutls_x509_crt_to_xml( crt, &xml_data, 0); if (ret < 0) { + const char* str = gnutls_strerror(ret); + if (str == NULL) str = "(unknown)"; fprintf(stderr, "XML encoding error: %s\n", - gnutls_strerror(ret)); + str); return; } @@ -122,7 +126,9 @@ void print_x509_info(gnutls_session session, const char* hostname) digest_size = sizeof(digest); if ((ret=gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_MD5, digest, &digest_size)) < 0) { - fprintf(stderr, "Error in fingerprint calculation: %s\n", gnutls_strerror(ret)); + const char* str = gnutls_strerror(ret); + if (str == NULL) str = "(unknown)"; + fprintf(stderr, "Error in fingerprint calculation: %s\n", str); } else { print = printable; for (i = 0; i < digest_size; i++) { diff --git a/src/serv.c b/src/serv.c index 14a4b4ff43..578de0bb66 100644 --- a/src/serv.c +++ b/src/serv.c @@ -245,21 +245,21 @@ static int generate_rsa_params(void) return 0; } -int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; -int kx_priority[16] = +static const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; +static const int kx_priority[] = { GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, /* Do not use anonymous authentication, unless you know what that means */ GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA_EXPORT, 0 }; -int cipher_priority[16] = +static const int cipher_priority[] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_CIPHER_ARCFOUR_40, 0 }; -int comp_priority[16] = +static const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_LZO, GNUTLS_COMP_NULL, 0 }; -int mac_priority[16] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; -int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; +static const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; +static const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; LIST_DECLARE_INIT(listener_list, listener_item, listener_free); @@ -301,7 +301,7 @@ gnutls_session initialize_session(void) return session; } -static char DEFAULT_DATA[] = "This is the default message reported " +static const char DEFAULT_DATA[] = "This is the default message reported " "by GnuTLS TLS version 1.0 implementation. For more information " "please visit http://www.gnutls.org or even http://www.gnu.org/software/gnutls."; @@ -315,6 +315,7 @@ char *peer_print_info(gnutls_session session, int *ret_length, unsigned char sesid[32]; int sesid_size, i; char *http_buffer = malloc(5 * 1024 + strlen(header)); + gnutls_kx_algorithm kx_alg; if (http_buffer == NULL) return NULL; @@ -356,24 +357,25 @@ char *peer_print_info(gnutls_session session, int *ret_length, } + kx_alg = gnutls_kx_get(session); + /* print srp specific data */ #ifdef ENABLE_SRP - if (gnutls_kx_get(session) == GNUTLS_KX_SRP) { + if (kx_alg == GNUTLS_KX_SRP) { sprintf(tmp2, "<p>Connected as user '%s'.</p>\n", gnutls_srp_server_get_username(session)); } #endif #ifdef ENABLE_ANON - if (gnutls_kx_get(session) == GNUTLS_KX_ANON_DH) { + if (kx_alg == GNUTLS_KX_ANON_DH) { sprintf(tmp2, "<p> Connect using anonymous DH (prime of %d bits)</p>\n", gnutls_dh_get_prime_bits(session)); } #endif - if (gnutls_kx_get(session) == GNUTLS_KX_DHE_RSA - || gnutls_kx_get(session) == GNUTLS_KX_DHE_DSS) { + if (kx_alg == GNUTLS_KX_DHE_RSA || kx_alg == GNUTLS_KX_DHE_DSS) { sprintf(tmp2, "Ephemeral DH using prime of <b>%d</b> bits.<br>\n", gnutls_dh_get_prime_bits(session)); @@ -395,7 +397,7 @@ char *peer_print_info(gnutls_session session, int *ret_length, tmp); } - tmp = gnutls_kx_get_name(gnutls_kx_get(session)); + tmp = gnutls_kx_get_name(kx_alg); sprintf(tmp2, "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp); tmp = gnutls_compression_get_name(gnutls_compression_get(session)); @@ -407,7 +409,7 @@ char *peer_print_info(gnutls_session session, int *ret_length, tmp = gnutls_mac_get_name(gnutls_mac_get(session)); sprintf(tmp2, "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", tmp); - tmp = gnutls_cipher_suite_get_name(gnutls_kx_get(session), + tmp = gnutls_cipher_suite_get_name(kx_alg, gnutls_cipher_get(session), gnutls_mac_get(session)); sprintf(tmp2, "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n", @@ -417,14 +419,14 @@ char *peer_print_info(gnutls_session session, int *ret_length, strcat(http_buffer, header); strcat(http_buffer, "</PRE></P>"); - strcat(http_buffer, "</P>\n" HTTP_END); + strcat(http_buffer, "\n" HTTP_END); *ret_length = strlen(http_buffer); return http_buffer; } -static int listen_socket(char *name, int listen_port) +static int listen_socket(const char *name, int listen_port) { struct sockaddr_in a; int s; @@ -436,9 +438,10 @@ static int listen_socket(char *name, int listen_port) } yes = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes)) + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const void *)&yes, sizeof(yes)) < 0) { perror("setsockopt() failed"); + failed: close(s); return -1; } @@ -447,12 +450,15 @@ static int listen_socket(char *name, int listen_port) a.sin_family = AF_INET; if (bind(s, (struct sockaddr *) &a, sizeof(a)) < 0) { perror("bind() failed"); - close(s); - return -1; + goto failed; + } + + if (listen(s, 10) < 0) { + perror("listen() failed"); + goto failed; } printf("%s ready. Listening to port '%d'.\n\n", name, listen_port); - listen(s, 10); return s; } @@ -481,34 +487,32 @@ static void get_response(gnutls_session session, char *request, *response = peer_print_info(session, response_length, h); } else { *response = strdup(request); - *response_length = strlen(*response); + *response_length = ( (*response) ? strlen(*response) : 0 ); } return; unimplemented: *response = strdup(HTTP_UNIMPLEMENTED); - *response_length = strlen(*response); + *response_length = ( (*response) ? strlen(*response) : 0 ); } void terminate(int sig) { fprintf(stderr, "Exiting via signal %d\n", sig); - exit(0); + exit(1); } -void check_alert(gnutls_session session, int ret) +static void check_alert(gnutls_session session, int ret) { - int last_alert; - if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { - last_alert = gnutls_alert_get(session); + int last_alert = gnutls_alert_get(session); if (last_alert == GNUTLS_A_NO_RENEGOTIATION && ret == GNUTLS_E_WARNING_ALERT_RECEIVED) printf - ("* Received NO_RENEGOTIATION alert. Client Does not support renegotiation.\n"); + ("* Received NO_RENEGOTIATION alert. Client does not support renegotiation.\n"); else printf("* Received alert '%d': %s.\n", last_alert, gnutls_alert_get_name(last_alert)); @@ -534,6 +538,7 @@ int main(int argc, char **argv) signal(SIGHUP, SIG_IGN); signal(SIGTERM, terminate); signal(SIGINT, terminate); + /* CHECKME: background processes shouldn't handle SIGINT! */ gaa_parser(argc, argv); @@ -686,7 +691,7 @@ int main(int argc, char **argv) lloopstart(listener_list, j) { val = fcntl(j->fd, F_GETFL, 0); - if (fcntl(j->fd, F_SETFL, val | O_NONBLOCK) < 0) { + if ( (val == -1) || (fcntl(j->fd, F_SETFL, val | O_NONBLOCK) < 0) ) { perror("fcntl()"); exit(1); } @@ -703,7 +708,7 @@ int main(int argc, char **argv) lloopend(listener_list, j); /* core operation */ - n = select(n + 1, &rd, &wr, 0, 0); + n = select(n + 1, &rd, &wr, NULL, NULL); if (n == -1 && errno == EINTR) continue; if (n < 0) { @@ -718,7 +723,8 @@ int main(int argc, char **argv) tls_session = initialize_session(); - memset(&client_address, 0, l = sizeof(client_address)); + l = sizeof(client_address); + memset(&client_address, 0, l); accept_fd = accept(h, (struct sockaddr *) &client_address, &l); if (accept_fd < 0) { @@ -795,7 +801,7 @@ int main(int argc, char **argv) min(1024, SMALL_READ_TEST)); if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) { /* do nothing */ - } else if (r < 0 || r == 0) { + } else if (r <= 0) { j->http_state = HTTP_STATE_CLOSING; if (r < 0 && r != GNUTLS_E_UNEXPECTED_PACKET_LENGTH) { check_alert(j->tls_session, r); @@ -865,6 +871,7 @@ int main(int argc, char **argv) } if (j->handshake_ok == 1) { + /* FIXME if j->http_response == NULL? */ r = gnutls_record_send(j->tls_session, j->http_response + j->response_written, @@ -873,7 +880,7 @@ int main(int argc, char **argv) SMALL_READ_TEST)); if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) { /* do nothing */ - } else if (r < 0 || r == 0) { + } else if (r <= 0) { if (http != 0) j->http_state = HTTP_STATE_CLOSING; else { @@ -1100,7 +1107,7 @@ static int recv_openpgp_key(gnutls_session session, const unsigned char *keyfpr, unsigned int keyfpr_length, gnutls_datum * key) { - static const char *hostname = "hkp://wwwkeys.pgp.net"; + static const char hostname[] = "hkp://wwwkeys.pgp.net"; static const short port = 11371; int rc; CDK_KBNODE knode = NULL; |