diff --git a/src/connection.zig b/src/connection.zig index b77655e..6d88c43 100644 --- a/src/connection.zig +++ b/src/connection.zig @@ -60,7 +60,7 @@ pub const AddressPort = struct { }; pub const Connection = opaque { - pub fn create(options: *ConnectionOptions) Error!*Connection { + pub fn connect(options: *ConnectionOptions) Error!*Connection { var self: *Connection = undefined; const status = Status.fromInt(nats_c.natsConnection_Connect(@ptrCast(&self), @ptrCast(options))); return status.toError() orelse self; diff --git a/tests/connection.zig b/tests/connection.zig index 629bad2..738f4c9 100644 --- a/tests/connection.zig +++ b/tests/connection.zig @@ -7,6 +7,11 @@ const nats = @import("nats"); const util = @import("./util.zig"); +const rsa_key = @embedFile("./data/client-rsa.key"); +const rsa_cert = @embedFile("./data/client-rsa.cert"); +const ecc_key = @embedFile("./data/client-ecc.key"); +const ecc_cert = @embedFile("./data/client-ecc.cert"); + test "nats.Connection.connectTo" { { var server = try util.TestServer.launch(.{}); @@ -46,11 +51,6 @@ test "nats.Connection.connectTo" { } } -fn tokenHandler(userdata: *u32) [:0]const u8 { - _ = userdata; - return "token"; -} - fn reconnectDelayHandler(userdata: *u32, connection: *nats.Connection, attempts: c_int) i64 { _ = userdata; _ = connection; @@ -103,19 +103,10 @@ test "nats.ConnectionOptions" { try options.setServers(&servers); try options.setCredentials("user", "password"); try options.setToken("test_token"); - // requires a functioning token handler, which I will not write right now. Also - // cannot be called if a token has already been set - // try options.setTokenHandler(u32, tokenHandler, &userdata); try options.setNoRandomize(false); try options.setTimeout(1000); try options.setName("name"); - // the following all require a build with openssl - // try options.setSecure(false); - // try options.setCiphers("-ALL:HIGH"); - // try options.setCipherSuites("TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"); - // try options.setExpectedHostname("host.name"); - // try options.skipServerVerification(true); try options.setVerbose(true); try options.setPedantic(true); try options.setPingInterval(1000); @@ -147,3 +138,67 @@ test "nats.ConnectionOptions" { try options.setCustomInboxPrefix("_FOOBOX"); try options.setMessageBufferPadding(123); } + +fn tokenHandler(userdata: *u32) [:0]const u8 { + _ = userdata; + return "token"; +} + +test "nats.ConnectionOptions (crypto edition)" { + try nats.init(nats.default_spin_count); + defer nats.deinit(); + + const options = try nats.ConnectionOptions.create(); + defer options.destroy(); + var userdata: u32 = 0; + + try options.setTokenHandler(u32, tokenHandler, &userdata); + try options.setSecure(false); + try options.setCertificatesChain(rsa_cert, rsa_key); + try options.setCiphers("-ALL:HIGH"); + try options.setCipherSuites("TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"); + try options.setExpectedHostname("test.nats.zig"); + try options.skipServerVerification(true); +} + +test "nats.ConnectionOptions (crypto connect)" { + { + var server = try util.TestServer.launch(.{ .tls = .rsa }); + defer server.stop(); + + try nats.init(nats.default_spin_count); + defer nats.deinit(); + + const options = try nats.ConnectionOptions.create(); + defer options.destroy(); + + try options.setSecure(true); + try options.skipServerVerification(true); + try options.setCertificatesChain(rsa_cert, rsa_key); + + const connection = try nats.Connection.connect(options); + defer connection.destroy(); + + try connection.publish("foo", "bar"); + } + + { + var server = try util.TestServer.launch(.{ .tls = .ecc }); + defer server.stop(); + + try nats.init(nats.default_spin_count); + defer nats.deinit(); + + const options = try nats.ConnectionOptions.create(); + defer options.destroy(); + + try options.setSecure(true); + try options.skipServerVerification(true); + try options.setCertificatesChain(ecc_cert, ecc_key); + + const connection = try nats.Connection.connect(options); + defer connection.destroy(); + + try connection.publish("foo", "bar"); + } +} diff --git a/tests/data/client-ecc.cert b/tests/data/client-ecc.cert new file mode 100644 index 0000000..d29c73d --- /dev/null +++ b/tests/data/client-ecc.cert @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIClTCCAhygAwIBAgIUNUxHIA2G0sEDgjWcx1svHk9wK1AwCgYIKoZIzj0EAwIw +gYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENp +dHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNl +Y3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIyMjEz +MzJaGA8yMTIzMDgwOTIyMTMzMlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlT +dGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFt +ZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5u +YXRzLnppZzB2MBAGByqGSM49AgEGBSuBBAAiA2IABPcAhGdzooeoL0SY1qJmY3SY +cyngBaon8ICyaQLRvOKEIhym25jB90xj4J2IDy3pg/5564G43NOOBZ/T4ClTv3XF ++2E71w+31HVGVKW4l+natAQt72oXn+HcjSnwrplYz6NTMFEwHQYDVR0OBBYEFFkN +/08ID2jBHkYMUzm7o8S8Ch86MB8GA1UdIwQYMBaAFFkN/08ID2jBHkYMUzm7o8S8 +Ch86MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDZwAwZAIwWauKBQMCf6XT +K1y2TvNZpqehk+MsQ8aDcNoUJ+iALJM7Y89XpibdZ4hvGPsQK/cgAjAg8SXHVWS5 +yeFNtZdnRowEuQhtk5rRaj983wMSLbMXbz9Oxm0MY7edcS4MWP7l7nI= +-----END CERTIFICATE----- diff --git a/tests/data/client-ecc.key b/tests/data/client-ecc.key new file mode 100644 index 0000000..3030cda --- /dev/null +++ b/tests/data/client-ecc.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDfkvPMjrVTAU06KSLK +vxKDF3+vdWDQUxQBIJ3F1qrSMJNzfuguXiYv8DMTbNvCNB+hZANiAAT3AIRnc6KH +qC9EmNaiZmN0mHMp4AWqJ/CAsmkC0bzihCIcptuYwfdMY+CdiA8t6YP+eeuBuNzT +jgWf0+ApU791xfthO9cPt9R1RlSluJfp2rQELe9qF5/h3I0p8K6ZWM8= +-----END PRIVATE KEY----- diff --git a/tests/data/client-rsa.cert b/tests/data/client-rsa.cert new file mode 100644 index 0000000..41ff772 --- /dev/null +++ b/tests/data/client-rsa.cert @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF5TCCA82gAwIBAgIUSiVHqM6yI2CBF8ZuakGuaXdAd0EwDQYJKoZIhvcNAQEL +BQAwgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM +CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu +eVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIy +MjE0MDZaGA8yMTIzMDgwOTIyMTQwNlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQI +DAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55 +TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0 +cy5uYXRzLnppZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOF2MLuH +xvEUbc2PXQKhTL7flDvl/KWGxikE4HBQ96vQ3bHAzVuLezTI9D0qLTOvY1SVBy0C +En4e5ZklufTHciOg/a1B76IC2EFPEnhY0oO7pLfLzA43MU7biNvb1BGPW/MEihOZ +2ZmGnK1CiwynFKTkRJdafzK8OrQV9nmz+WNX0UqbDH6Gjp36V6VMcz+gHi01hqK+ +v1lbAuUATGNEoZSVpGSoJx4+Ogyob9f4irsJX7GpO0dsKHUwd51pAm1pkpOH1rIU +CM+biSYaLt5fxFkSUJc9wqa+odE997hu5Ch6EEkdwg/4vYnigBMZxwFB3EVinXI0 +5ywrYMwO8ozCrKmIDVG/FhNlzspooKVkZFKl8/T/1n8rDElsLc8No7clD0xFQxU8 +3qyw05yaYm3khDMWTaD/B2w3AOoifZ9oWr6Ra2NN57yQx4sQdDy8s0WY4rVkv/nX +9VsBSeJwmmCfnnpse1Tq4Wfo7Jjz1Akl4n0GAQxkxR6gAkCfnkJrdkMKaOPQe+ep +Fs+5g2VrIeWQgzs5L4rte1qtMokK963IvqDSnsbPM6m9tcMQb8r+A0YbEOAK6D0D +nnKcguSKNkPP8hwaqJ9XNDXSN65I+DsgX0ngfHCh/grkSPJI2oEmx4DeaA8hgRzh +zbGpazOcVa4ahyUCxZKZi9c/+Aw3gir0fpQbAgMBAAGjUzBRMB0GA1UdDgQWBBRI +3sPebMsmYX0ourw+0SA8BqcXwTAfBgNVHSMEGDAWgBRI3sPebMsmYX0ourw+0SA8 +BqcXwTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCkGzTMZdGT +dUQBbAqTzHvoc1Vy5OxadgJ4UGly9s7GpYg8brsevFmHyGHl+J9dBsnhmmNGxs1t +rU5lvnMWLOyvg7iLyx/4rkNAR03wyRgx1jK+4xIxMBj7YDB0WK6AtL3OUiqvTW4h +INoEIylyrIIOf7oHS9UkzDdZ3ZghH+EADjE6ksM/PuCRK0oTz9z7LUSMlcI5UCeb +P/V6N2QHzz2n+/BvTo/bpjHrwyUZ+eZbUC7rCfZX7Pi/pTGS2bps16lO2Us6tzIn +9If5h+MHHGOZXQtOZPYDFi3nLo/E+bBzt6Lvrt0Vm5DjXKzplrq+UMPbsEtGue7v +xSfcbPsXf44n+kZSFtFTjZ4zqpP05/H3R5eTayRUhVLkJlxDZbPiFjOSEupUmZq+ +cpmf6Mq9OJJimyJBRaC0Lex4mCDUarXYLXXyNaIAQ2O+EmaNxZ2B86gHy6R3gaHr +w66pDXq0IXznJyr50aKu7WYJHOE5HOaBgptU7lXz35+5yId7WKWorXfGIYBWCc3g +LRDr0pgyLk1YVxz2tphR8hEJ7rJb+gMR3t5UzDElsUIqKJo/6Aziq4dRlrj5x62s +Vmm7JJqMSyh6UDJowwFicS3KTZbKZnxRHdyy8Km6gRvi26pdNWW5+/57ETLG3cn5 ++MDARAttyn8SEhbPolxttebRKDAIFnxYkQ== +-----END CERTIFICATE----- diff --git a/tests/data/client-rsa.key b/tests/data/client-rsa.key new file mode 100644 index 0000000..abc11d6 --- /dev/null +++ b/tests/data/client-rsa.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +qnLykaAJSPCsd4jY4P3EtZLNbee3fQ== +-----END PRIVATE KEY----- diff --git a/tests/data/server-ecc.cert b/tests/data/server-ecc.cert new file mode 100644 index 0000000..c020aab --- /dev/null +++ b/tests/data/server-ecc.cert @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICljCCAhygAwIBAgIUcjxQ8y9DFk5UChiI2CTG4fKNuzswCgYIKoZIzj0EAwIw +gYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENp +dHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNl +Y3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIyMjEy +NDJaGA8yMTIzMDgwOTIyMTI0MlowgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlT +dGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFt +ZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5u +YXRzLnppZzB2MBAGByqGSM49AgEGBSuBBAAiA2IABL1QQVL1CUI+g8EAFtW4OYRk +bsa4GpLMojjWYGZ5azB6zFJsjqr626hwl8B+yUOLV8O8COZtSHhh9TOwMK9my+mF +jSlRLkBhViJtiQS/i+lOAHLSZhyYGi0LMwR/84s9zqNTMFEwHQYDVR0OBBYEFDep +AJQvuHNpqaxaBt5Md4mAcMcBMB8GA1UdIwQYMBaAFDepAJQvuHNpqaxaBt5Md4mA +cMcBMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIwWiMIHiOwfO0+ +CcjrMZmSVqhBiDY8bcJgpPFCp+GFfPiTwse1eUQhYE0K2onU1mYTAjEA7atUdQxL +8SjkuTRdvNoRJ2EOVMHMeaYMU5HPAxHhIPDWBaHmHOHgOx5hUw/chRjf +-----END CERTIFICATE----- diff --git a/tests/data/server-ecc.key b/tests/data/server-ecc.key new file mode 100644 index 0000000..ff06900 --- /dev/null +++ b/tests/data/server-ecc.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAdXFWFvY4ujDsDxw2e +Vga7jpgVBKAg7mEA/AYL+yjLanR52DJ6XM8iU4qbPEaMH66hZANiAAS9UEFS9QlC +PoPBABbVuDmEZG7GuBqSzKI41mBmeWswesxSbI6q+tuocJfAfslDi1fDvAjmbUh4 +YfUzsDCvZsvphY0pUS5AYVYibYkEv4vpTgBy0mYcmBotCzMEf/OLPc4= +-----END PRIVATE KEY----- diff --git a/tests/data/server-rsa.cert b/tests/data/server-rsa.cert new file mode 100644 index 0000000..e4a56ba --- /dev/null +++ b/tests/data/server-rsa.cert @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF5TCCA82gAwIBAgIUUIWzfooDSLVR8sW3AiBJuqDHZMYwDQYJKoZIhvcNAQEL +BQAwgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM +CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu +eVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0cy5uYXRzLnppZzAgFw0yMzA5MDIy +MjA5MTdaGA8yMTIzMDgwOTIyMDkxN1owgYAxCzAJBgNVBAYTAlhYMRIwEAYDVQQI +DAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55 +TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRcwFQYDVQQDDA50ZXN0 +cy5uYXRzLnppZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOolz+6A +j1S3fJl8VSglQBaOplTsukup0Li7pDluS+Sgj5G5Vvl1Ki8jPVTWz9HcYl/7jgFz +iE7AG7qymH1+q/smzxl59MyiKkBPSvynRQ/iY35uyyCFSxgqNSFqnahzHmd1BpNX +9WJX2iRs+UyaWjhtj7T2cbIr2UZQtCUqF/ae0jeR+hb6beQCMoGzFG3Zn9uupazg +u49WdNmOSE/qf6DAmftnmdX7pc7u6jclMAk8WOvjL9LoxK8Nu+ZGusklJohjbUsG +DNdktsaqZQphlXbVCa6gV6cITup2oFmHQvMcncZ2xtYs/4Ul45UxGGEWGWQLQtaJ +KSS5B5YAkXTCga8k/cS+NRyy/NxQmuR3FeQUYYfMpiNhXweZ7zEWjosU9jjEiS6w +UhlTCQYH6p9/jZmByE8DySNQtcexV1IBVzOYsg7MS/AwHq9ym9iqT9tx+S9Vub/f +ysbgQU9GkKeic64iYVC+gG/Y2W8XS9LSzSKCJuvf8EUD18g3dmmRxzltwq7oH14W +f0KjyhwdzeJUhoEvPgaEgWvlvff9uSP0utX/KmOJPJckjoQrk9RN/GDxR01U2SPf +1pVclir3IEWSPOCNSil8Et/ut1MI7JGlDhsysZA3zoqIPAu+QYVUEytdSf+n3UHf +ZvT7VdDQlNyq2XYaP9kBEx4P7oGfto/HHOHtAgMBAAGjUzBRMB0GA1UdDgQWBBQV +GBaOUXiHmG3KT2uiwgOR7xBDSDAfBgNVHSMEGDAWgBQVGBaOUXiHmG3KT2uiwgOR +7xBDSDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCZhqnD3uVi +3q2plOHUBnlkYcCCoC0W7AHPSJ1pcb/wa1CgSkrXHNhBmaWfWEbs+JJ+eMHxStFr +kdJWNbVEnmS27ruMNE6S5XCj/1zdqncZnCr3gLRdmvb3S5yZHGphgEdNrAvPKIyi +XtfmROVh3y2/ZENRZfdJ984xU/yaHmfTy8ULiSCe0Jz9dxHvTgUCrZ5RVEIwmAkL +gcs1Hrw/5TDs/DagsNliH2Atn6cYzhAostBN9wDkra6xUkRqscE8R7D2/XJni+W3 +toL+DTTFIww0pNlh2BWG5DMqeLdYPODhuxWWw5JhdKWx3cisPhiJ9RDKaSy532wC +i/tjKQAnNWQRvGFGfJDMIEcPL3s1JhQM/lhSanlloMsxHmGpOJOEI6IN0clYpPaX +7COo+qvGueQPRLDq/7vDRM3i7sQHBHeC71VdEN4TgyJQvQcGMFjGPPQ868VvJhYG +2CbUWhBaADWlWjZ5d5tMI+WT8J/y6D6cSOymXcgbHV8DpUCB9vImmTKvgiL9TLi1 +PxZCP9nLUOCmCSnbz4vhupvxM38KesuvAfOUPKTEixjXBfD9iiEKVnMUKVv31TLO +5sfeYf6Zn8oDFCInUgdHgQRs/UXOAOTWYsOQQhS6xfZXJHom/Mcy0Q2TxsiI2dmw +ah/FB4DsF0XDCuDqGJWyywTbzQnh55uBBQ== +-----END CERTIFICATE----- diff --git a/tests/data/server-rsa.key b/tests/data/server-rsa.key new file mode 100644 index 0000000..78f22b7 --- /dev/null +++ b/tests/data/server-rsa.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +u2Iow+n+vuh3lPHBmdmCxfYo50P+HA== +-----END PRIVATE KEY----- diff --git a/tests/nats.zig b/tests/nats.zig index 7407c60..73ba9f6 100644 --- a/tests/nats.zig +++ b/tests/nats.zig @@ -70,7 +70,7 @@ test "misc" { // and switch. const signed = nats.sign("12345678", "12345678") catch { const err = nats.getLastError(); - std.debug.print("signing failed: {s}\n", .{err.desc}); + std.debug.print("as expected, signing failed: {s}\n", .{err.desc}); var stackmem = [_]u8{0} ** 512; var stackbuf: []u8 = &stackmem; diff --git a/tests/util.zig b/tests/util.zig index 68e9306..deb61f1 100644 --- a/tests/util.zig +++ b/tests/util.zig @@ -3,12 +3,24 @@ const std = @import("std"); +const KeyCert = struct { key: [:0]const u8, cert: [:0]const u8 }; +const server_rsa: KeyCert = .{ + .key = @embedFile("./data/server-rsa.key"), + .cert = @embedFile("./data/server-rsa.cert"), +}; + +const server_ecc: KeyCert = .{ + .key = @embedFile("./data/server-ecc.key"), + .cert = @embedFile("./data/server-ecc.cert"), +}; + const TestLaunchError = error{ NoLaunchStringFound, }; pub const TestServer = struct { process: std.ChildProcess, + key_dir: ?std.testing.TmpDir, pub const LaunchOptions = struct { executable: []const u8 = "nats-server", @@ -18,38 +30,71 @@ pub const TestServer = struct { token: []const u8, password: struct { user: []const u8, pass: []const u8 }, } = .none, + tls: enum { + none, + rsa, + ecc, + } = .none, allocator: std.mem.Allocator = std.testing.allocator, - - fn argLen(self: LaunchOptions) usize { - // executable, -a, 127.0.0.1, -p, 4222 - const base_len: usize = 5; - return base_len + switch (self.auth) { - .none => @as(usize, 0), - .token => @as(usize, 2), - .password => @as(usize, 4), - }; - } }; pub fn launch(options: LaunchOptions) !TestServer { - // const allocator = std.testing.allocator; var portbuf = [_]u8{0} ** 5; const strport = try std.fmt.bufPrint(&portbuf, "{d}", .{options.port}); - const argsbuf: [9][]const u8 = blk: { - const executable: [1][]const u8 = .{options.executable}; - const listen: [2][]const u8 = .{ "-a", "127.0.0.1" }; - const port: [2][]const u8 = .{ "-p", strport }; - const auth: [4][]const u8 = switch (options.auth) { - .none => .{""} ** 4, - .token => |tok| .{ "--auth", tok, "", "" }, - .password => |auth| .{ "--user", auth.user, "--pass", auth.pass }, + var key_dir: ?std.testing.TmpDir = null; + var key_path: ?[]const u8 = null; + var cert_path: ?[]const u8 = null; + // ChildProcess copies these, so we can free them before the process has + // closed. + defer { + if (key_path) |kp| options.allocator.free(kp); + if (cert_path) |cp| options.allocator.free(cp); + } + + const args: [][]const u8 = blk: { + const executable: []const []const u8 = &.{options.executable}; + const listen: []const []const u8 = &.{ "-a", "127.0.0.1" }; + const port: []const []const u8 = &.{ "-p", strport }; + const auth: []const []const u8 = switch (options.auth) { + .none => &[_][]const u8{}, + .token => |tok| &[_][]const u8{ "--auth", tok }, + .password => |auth| &[_][]const u8{ "--user", auth.user, "--pass", auth.pass }, + }; + const tls: []const []const u8 = switch (options.tls) { + .none => &[_][]const u8{}, + .rsa, .ecc => |keytype| keyb: { + const pair = switch (keytype) { + .rsa => server_rsa, + .ecc => server_ecc, + else => unreachable, + }; + + const out_dir = std.testing.tmpDir(.{}); + try out_dir.dir.writeFile("server.key", pair.key); + try out_dir.dir.writeFile("server.cert", pair.cert); + // since testing.tmpDir will actually bury itself in zig-cache/tmp, + // there's not an easy way to extract files from within the temp + // directory except through using realPath, as far as I can tell + // (or reproducing the path naming logic, but that seems fragile). + const out_key = try out_dir.dir.realpathAlloc(options.allocator, "server.key"); + const out_cert = try out_dir.dir.realpathAlloc(options.allocator, "server.cert"); + + key_dir = out_dir; + key_path = out_key; + cert_path = out_cert; + break :keyb &[_][]const u8{ "--tls", "--tlscert", out_cert, "--tlskey", out_key }; + }, }; - break :blk executable ++ listen ++ port ++ auth; + break :blk try std.mem.concat( + options.allocator, + []const u8, + &.{ executable, listen, port, auth, tls }, + ); }; - const args = argsbuf[0..options.argLen()]; + defer options.allocator.free(args); var child = std.ChildProcess.init(args, options.allocator); child.stdin_behavior = .Ignore; @@ -62,7 +107,7 @@ pub const TestServer = struct { while (try poller.poll()) { if (std.mem.indexOf(u8, poller.fifo(.stderr).buf, "[INF] Server is ready")) |_| { - return .{ .process = child }; + return .{ .process = child, .key_dir = key_dir }; } } @@ -72,6 +117,7 @@ pub const TestServer = struct { } pub fn stop(self: *TestServer) void { + if (self.key_dir) |*key_dir| key_dir.cleanup(); _ = self.process.kill() catch return; } };