#define MAX_REQUEST_LINE 4096
+static int fdopen_read_write(int socket, FILE **read_fd, FILE **write_fd);
static int connect_to_host(const char *hostname, const char *port);
static int read_http_request(FILE *client_fd, char *request, size_t length);
unsigned int status;
char buffer[MAX_REQUEST_LINE];
int server;
- FILE *fd;
+ FILE *fd_read, *fd_write;
gnutls_session_t session;
gnutls_certificate_credentials_t xcred;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
- if (argc != 5) {
+ if (argc != 5 && argc != 6) {
fprintf(stderr,
- "Usage: %s <ca-file> <hostname> <port> <hostname-verify>\n",
+ "Usage: %s <ca-file> <hostname> <port> <hostname-verify> "
+ "[<digest-authentication>]\n",
argv[0]);
return EXIT_FAILURE;
}
if (server == -1) {
return EXIT_FAILURE;
}
- fd = fdopen(server, "a+");
- if (fd == NULL) {
- perror("fdopen()");
+ if (fdopen_read_write(server, &fd_read, &fd_write) != 0) {
return EXIT_FAILURE;
}
/* Talk to tlsproxy. */
- fprintf(fd, "CONNECT %s:%s HTTP/1.0\r\n", argv[2], argv[3]);
- fprintf(fd, "\r\n");
- fflush(fd);
- if (read_http_request(fd, buffer, sizeof(buffer)) == -1) {
+ fprintf(fd_write, "CONNECT %s:%s HTTP/1.0\r\n", argv[2], argv[3]);
+ if (argc == 6) {
+ fprintf(fd_write, "Proxy-Authorization: Basic %s\r\n", argv[5]);
+ }
+ fprintf(fd_write, "\r\n");
+ fflush(fd_write);
+ if (read_http_request(fd_read, buffer, sizeof(buffer)) == -1) {
fprintf(stderr, "invalid proxy response\n");
return EXIT_FAILURE;
}
gnutls_x509_crt_deinit(cert);
gnutls_bye(session, GNUTLS_SHUT_RDWR);
- fclose(fd);
+ fclose(fd_read);
+ fclose(fd_write);
gnutls_deinit(session);
gnutls_certificate_free_credentials(xcred);
/* Copied from src/connection.c (and removed LOG_* stuff)! Don't modify. */
+static int fdopen_read_write(int socket, FILE **read_fd, FILE **write_fd) {
+ *read_fd = fdopen(socket, "r");
+ if (*read_fd == NULL) {
+ perror("fdopen_read_write(): fdopen(\"r\") failed");
+ return -1;
+ }
+
+ *write_fd = fdopen(dup(socket), "w");
+ if (*write_fd == NULL) {
+ perror("fdopen_read_write(): fdopen(\"w\") failed");
+ fclose(*read_fd);
+ *read_fd = NULL; /* "tell" caller read_fd is already closed */
+ return -1;
+ }
+
+ return 0;
+}
+
static int connect_to_host(const char *hostname, const char *port) {
struct addrinfo gai_hints;
struct addrinfo *gai_result;
server_socket = socket(server->ai_family,
server->ai_socktype,
server->ai_protocol);
- if (server_socket == -1) {
+ if (server_socket < 0) {
perror("connect_to_host(): socket(), trying next");
continue;
}
- if (connect(server_socket, server->ai_addr, server->ai_addrlen) != -1) {
+ if (connect(server_socket, server->ai_addr, server->ai_addrlen) == 0) {
break;
}
perror("connect_to_host(): connect(), trying next");
perror("read_http_request(): fgets()");
return -1;
}
-
+ /* EOF */
return -2;
}
- while (fgets(buffer, MAX_REQUEST_LINE, client_fd) != NULL) {
+ while (fgets(buffer, sizeof(buffer), client_fd) != NULL) {
/* End of header. */
if (!strcmp(buffer, "\n") || !strcmp(buffer, "\r\n")) {
break;