Initial https proxy work

The proxy can now sit between a client and a https web server. It does
this by looking for a CONNECT request that conventional proxies use to
open a tunnel between a client and an https server. Instead of opening
an opaque tunnel, yaip immediately sends bacck a "connection
established" response. This tells the client (browser normally) to
proceed and initiate an HTTPS connection.

I use the host that was send in the connect request to set up a fake SSL
server. If we have seen the domain before, we re-use the certificate,
otherwise we generate a new one and sign it using YAIP's built in
certificate authority.

I still need to do work on forwarding the request upstream. This is my
next job. Currently, yaip responds with a valid response of "it worked".

```
$ curl https://example.com --cacert ~/.config/yaip/cert.pem
It worked
```

Notice, we don't get any certificate errors because we are telling curl
to trust the authority that yaip uses
This commit is contained in:
Jonathan Hodgson 2022-01-30 12:25:57 +00:00
parent 1beca38af6
commit dd71d26245
15 changed files with 330 additions and 109 deletions

View file

@ -4,7 +4,7 @@
#include "munit/munit.h"
#include "../src/readline.h"
#include "../src/util.h"
#include "../src/request.h"
#include "../src/requestresponse.h"
@ -160,6 +160,18 @@ MunitResult testRequestToString(const MunitParameter params[],
return MUNIT_OK;
}
MunitResult testRequestFromString(const MunitParameter params[],
void* user_data_or_fixture){
char testString[] = "GET / HTTP/1.1\r\nHost: example.com\r\nAccept: */*\r\n\r\n";
Request *req = newRequestFromString(testString);
munit_assert_string_equal( req->method, "GET" );
munit_assert_string_equal( req->path, "/" );
munit_assert_string_equal( requestToString( req ), testString );
return MUNIT_OK;
}
MunitParameterEnum test_first_line_params[2] = {NULL, NULL};
static MunitTest request_tests[] = {
@ -226,6 +238,13 @@ static MunitTest request_tests[] = {
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
},{
"/fromstring", /* name */
testRequestFromString, /* test */
NULL, /* setup */
NULL, /* tear_down */
MUNIT_TEST_OPTION_NONE, /* options */
NULL /* parameters */
},
/* Mark the end of the array with an entry where the test
* function is NULL */

View file

@ -145,6 +145,37 @@ MunitResult testNewHostCertificate(const MunitParameter params[],
return MUNIT_OK;
}
MunitResult testFindCertListItem(const MunitParameter params[],
void* user_data_or_fixture){
CertList *head = newCertListItem( "example.com", NULL, NULL );
CertList *last = head;
CertList *curr;
for ( unsigned int i = 0; i < 10; i++ ){
char host[15] = {'\0'};
sprintf(host, "example%d.com", i+1);
last->next = newCertListItem( strdup(host), NULL, NULL );
last = last->next;
}
munit_assert_int( countCertListItems( head ), ==, 11 );
curr = findCertListItem( head, "example.com" );
munit_assert_not_null( curr );
munit_assert_string_equal( curr->host, "example.com" );
curr = findCertListItem( head, "example1.com" );
munit_assert_not_null( curr );
munit_assert_string_equal( curr->host, "example1.com" );
curr = findCertListItem( head, "example5.com" );
munit_assert_not_null( curr );
munit_assert_string_equal( curr->host, "example5.com" );
curr = findCertListItem( head, "doesnt-exist.com" );
munit_assert_null( curr );
return MUNIT_OK;
}
static char* count_parameters[] = {
"0", "1", "2", "10", "50", NULL
@ -180,6 +211,7 @@ static MunitTest ssl_tests[] = {
{ "/ca/cert/save", testNewCertificateSave, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
{ "/CertList/count", testCerlistCount, NULL, NULL, MUNIT_TEST_OPTION_NONE, count_params },
{ "/CertList/last", testCerlistLast, NULL, NULL, MUNIT_TEST_OPTION_NONE, count_params },
{ "/CertList/find", testFindCertListItem, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
{ "/hostcert/new", testNewHostCertificate, NULL, NULL, MUNIT_TEST_OPTION_NONE, x509_issuer_subject_params },
/* Mark the end of the array with an entry where the test
* function is NULL */