Skip to content

Instantly share code, notes, and snippets.

@rlipscombe
Created January 17, 2018 19:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rlipscombe/78d6e3bbfc67e010f1e7a9ddd8c87099 to your computer and use it in GitHub Desktop.
Save rlipscombe/78d6e3bbfc67e010f1e7a9ddd8c87099 to your computer and use it in GitHub Desktop.
Demonstrate memory leak with debdiff from #1722411
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <gnutls/x509.h>
#include <assert.h>
// g++ -o gnutls-client gnutls-client.cpp -lgnutls
// valgrind --leak-check=yes ./gnutls-client localhost /etc/ssl/certs/ca-certificates.crt
#define CHECK(x) assert((x) >= 0);
int main(int argc, char *argv[])
{
if (argc < 3) {
fprintf(stderr, "gnutls-client host ca.crt\n");
exit(1);
}
const char *server_name = argv[1];
const char *ca_bundle = argv[2];
gnutls_global_init();
printf("gnutls-client (GnuTLS/%s)\n", gnutls_check_version(NULL));
gnutls_certificate_credentials_t creds = NULL;
CHECK(gnutls_certificate_allocate_credentials(&creds));
gnutls_certificate_set_verify_flags(creds,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
int certificateCount = gnutls_certificate_set_x509_trust_file(creds,
ca_bundle, GNUTLS_X509_FMT_PEM);
if (certificateCount >= 0) {
printf("%d certificate(s) processed\n", certificateCount);
}
else {
printf("Failed to set trust file: %d\n", certificateCount);
exit(1);
}
struct addrinfo hint, *addr;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;
getaddrinfo(server_name, "https", &hint, &addr);
const int COUNT = 1000;
for (int i = 0; i < COUNT; ++i) {
gnutls_session_t session = NULL;
CHECK(gnutls_init(&session, GNUTLS_CLIENT));
CHECK(gnutls_server_name_set(session, GNUTLS_NAME_DNS,
server_name, strlen(server_name)));
CHECK(gnutls_set_default_priority(session));
CHECK(gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, creds));
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
CHECK(connect(sockfd, addr->ai_addr, addr->ai_addrlen));
gnutls_transport_set_int(session, sockfd);
int ret;
do {
ret = gnutls_handshake(session);
} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
if (ret < 0) {
fprintf(stderr, "ret: %d\n", ret);
}
unsigned int verify_status;
CHECK(gnutls_certificate_verify_peers2(session, &verify_status));
close(sockfd);
gnutls_deinit(session);
}
freeaddrinfo(addr);
gnutls_certificate_free_credentials(creds);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment