1 module pgsql.socket;
2 
3 import vibe.core.net;
4 import vibe.core.stream;
5 import vibe.stream.tls;
6 import vibe.stream.wrapper;
7 
8 import pgsql.ssl;
9 
10 struct VibeSocket {
11 	void connect(const(char)[] host, ushort port) {
12 		socket_ = connectTCP(cast(string)host, port);
13 		socket_.keepAlive = true;
14 		socket_.tcpNoDelay = true;
15 		static if (is(StreamProxy)) {
16 			stream_ = createProxyStream(socket_);
17 		} else {
18 			stream_ = socket_;
19 		}
20 	}
21 
22 	bool connected() inout {
23 		return socket_ && socket_.connected();
24 	}
25 
26 	void close() {
27 		if (socket_) {
28 			socket_.close();
29 			static if (is(typeof(socket_) == class)) {
30 				socket_ = null;
31 			}
32 		}
33 
34 	}
35 
36 	void read(ubyte[] buffer) {
37 		stream_.read(buffer);
38 	}
39 
40 	void write(in ubyte[] buffer) {
41 		stream_.write(buffer);
42 	}
43 
44 	void flush() {
45 		stream_.flush();
46 	}
47 
48 	bool empty() {
49 		return stream_.empty;
50 	}
51 
52 	void startSSL(const(char)[] hostName, SSLConfig config) {
53 		TLSVersion tlsVersion;
54 
55 		final switch (config.sslVersion) with (SSLConfig.Version) {
56 		case any:
57 			tlsVersion = TLSVersion.any;
58 			break;
59 		case ssl3:
60 			tlsVersion = TLSVersion.ssl3;
61 			break;
62 		case tls1:
63 			tlsVersion = TLSVersion.tls1;
64 			break;
65 		case tls1_1:
66 			tlsVersion = TLSVersion.tls1_1;
67 			break;
68 		case tls1_2:
69 			tlsVersion = TLSVersion.tls1_2;
70 			break;
71 		case dtls1:
72 			tlsVersion = TLSVersion.dtls1;
73 			break;
74 		}
75 
76 		TLSPeerValidationMode peerValidationMode;
77 
78 		final switch (config.validate) with (SSLConfig.Validate) {
79 		case basic:
80 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert;
81 			break;
82 		case trust:
83 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert | TLSPeerValidationMode.checkTrust;
84 			break;
85 		case identity:
86 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert | TLSPeerValidationMode.checkTrust | TLSPeerValidationMode.checkPeer;
87 			break;
88 		}
89 
90 		auto ctx = createTLSContext(TLSContextKind.client, tlsVersion);
91 		ctx.peerValidationMode = peerValidationMode;
92 
93 		if (config.rootCertFile.length)
94 			ctx.useTrustedCertificateFile(config.rootCertFile.idup);
95 
96 		if (config.ciphers.length)
97 			ctx.setCipherList(config.ciphers.idup);
98 
99 		auto peerName = config.hostName.length ? config.hostName : hostName;
100 
101 		stream_ = createTLSStream(socket_, ctx, TLSStreamState.connecting, peerName.idup, socket_.remoteAddress);
102 	}
103 
104 private:
105 	TCPConnection socket_;
106 	static if (is(StreamProxy)) {
107 		StreamProxy stream_;
108 	} else {
109 		Stream stream_;
110 	}
111 }