Skip to content

Instantly share code, notes, and snippets.

@BoboTiG
Created January 20, 2021 15:28
Show Gist options
  • Save BoboTiG/c3a484414223158904e80489372a35e9 to your computer and use it in GitHub Desktop.
Save BoboTiG/c3a484414223158904e80489372a35e9 to your computer and use it in GitHub Desktop.
Medium - The Mystery of the Endless HTTPS Call
/*
# OpenSSL is compiled with debug and trace:
./config --prefix=$HOME/openssl-bin --openssldir=$HOME/openssl --debug -DDEBUG_SAFESTACK enable-ssl-trace
# Gen & exec
$ gcc cclient.c -o cclient -lssl -lcrypto -L$HOME/openssl-bin/lib -I$HOME/openssl-bin/include
$ ./main.o HOST USER TOKEN BATCH_ID
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
void print_current_time_with_ms(void) {
long ms; // Milliseconds
time_t s; // Seconds
struct timespec spec;
clock_gettime(CLOCK_MONOTONIC, &spec);
s = spec.tv_sec;
ms = spec.tv_nsec / 1.0e6; // Convert nanoseconds to milliseconds
if (ms > 999) {
s++;
ms = 0;
}
printf("\ntime[%09ld.%03ld] ", s, ms);
}
long bio_dump_callback(BIO *bio, int cmd, const char *argp,
int argi, long argl, long ret)
{
BIO *out;
print_current_time_with_ms();
BIO_debug_callback(bio, cmd, argp, argi, argl, ret);
out = (BIO *)BIO_get_callback_arg(bio);
if (out != NULL) {
if (argp) {
BIO_dump(out, argp, ret);
}
}
return ret;
}
int main(int argc, char **argv) {
if (argc != 5) {
printf("Usage: %s HOST USER TOKEN BATCH_ID\n", argv[0]);
return 1;
}
char* host = argv[1];
char* user = argv[2];
char* token = argv[3];
char* batch_id = argv[4];
// Registers the SSL/TLS ciphers and digests,
// basically start the security layer
SSL_library_init();
// Creates a new SSL_CTX object as a framework to establish TLS/SSL
SSL_CTX* ctx;
ctx = SSL_CTX_new(SSLv23_client_method());
if (ctx == NULL) {
printf(" ! Ctx is null.\n");
return 1;
}
// Creates a new BIO chain consisting of an SSL BIO
BIO* bio;
bio = BIO_new_ssl_connect(ctx);
// Enable BIO tracing
BIO_set_callback(bio, bio_dump_callback);
BIO_set_callback_arg(bio, (char *)BIO_new_fp(stdout, 0));
// Attempts to connect the supplied BIO
BIO_set_conn_hostname(bio, host);
if (BIO_do_connect(bio) < 1) {
printf(" ! Connection failed.\n");
return 1;
}
// The HTTP request
char payload[128], write_buf[1024];
sprintf(
payload,
"{\"params\": {\"context\": {\"currentDocument\": \"/default-domain/UserWorkspaces/%s\"}}",
user
);
sprintf(
write_buf,
"POST /nuxeo/api/v1/upload/%s/0/execute/FileManager.Import HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Length: %zu\r\n"
"Content-Type: application/json\r\n"
"X-Batch-No-Drop: true\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n"
"Cookie: X-Authentication-Token=%s\r\n"
"\r\n"
"%s",
batch_id, host, strlen(payload), token, payload
);
printf(" > HTTPS request\n%s\n", write_buf);
// Attempts to write len bytes from buf to BIO
if (BIO_write(bio, write_buf, strlen(write_buf)) <= 0) {
printf(" ! POST failed.\n");
return 1;
}
// Variables used to read the response from the server
int size;
int buf_size = 1023;
char buf[buf_size + 1];
// Read the response message
printf(" < HTTPS response:\n");
do {
// Get chunks of the response *buf_size* bytes at the time
size = BIO_read(bio, buf, buf_size);
// Terminate the string with a 0, to let know C when the string ends
buf[size] = 0;
printf("%s", buf);
} while (size == buf_size);
printf("\n");
// Clean-up
BIO_free_all(bio);
SSL_CTX_free(ctx);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment