Tweak the installation guide.
[mailpopbox.git] / deployment / tlstest.mm
1 // clang++ tlstest.mm -o tlstest -framework Foundation -framework Security -std=c++11
2
3 #include <CoreFoundation/CoreFoundation.h>
4 #import <Foundation/Foundation.h>
5 #include <Security/SecureTransport.h>
6
7 struct StreamPair {
8 NSInputStream* in;
9 NSOutputStream* out;
10 };
11
12 const size_t kBufferSize = 1024;
13
14 NSString* ReadBuffer(NSInputStream* stream) {
15 uint8_t buf[kBufferSize];
16 NSInteger bytes_read = [stream read:buf maxLength:sizeof(buf)];
17 NSString* line = [[[NSString alloc] initWithBytes:buf
18 length:bytes_read
19 encoding:NSASCIIStringEncoding] autorelease];
20 NSLog(@">>> %@", line);
21 return line;
22 }
23
24 void WriteLine(NSOutputStream* stream, NSString* line) {
25 NSLog(@"<<< %@", line);
26 [stream write:(const uint8_t*)[line UTF8String] maxLength:[line length]];
27 const uint8_t nl = '\n';
28 [stream write:&nl maxLength:1];
29 }
30
31 OSStatus MySSLRead(SSLConnectionRef conn, void* data, size_t* data_len) {
32 NSInputStream* stream = ((StreamPair*)conn)->in;
33 *data_len = [stream read:(uint8_t*)data maxLength:*data_len];
34 return noErr;
35 }
36
37 OSStatus MySSLWrite(SSLConnectionRef conn, const void* data, size_t* data_len) {
38 NSOutputStream* stream = ((StreamPair*)conn)->out;
39 *data_len = [stream write:(uint8_t*)data maxLength:*data_len];
40 return noErr;
41 }
42
43 NSString* ReadBuffer(SSLContextRef tlsctx) {
44 uint8_t buf[kBufferSize];
45 size_t data_len;
46 OSStatus status = SSLRead(tlsctx, buf, sizeof(buf), &data_len);
47 if (status != noErr) {
48 NSLog(@"SSLRead error: %d", status);
49 return nil;
50 }
51
52 NSString* line = [[[NSString alloc] initWithBytes:buf
53 length:data_len
54 encoding:NSASCIIStringEncoding] autorelease];
55 NSLog(@">+> %@", line);
56 return line;
57 }
58
59 void WriteLine(SSLContextRef tlsctx, NSString* line) {
60 NSLog(@"<+< %@", line);
61 size_t processed;
62 OSStatus status = SSLWrite(tlsctx, [line UTF8String], [line length], &processed);
63 if (status != noErr) {
64 NSLog(@"SSLWrite error: %d", status);
65 return;
66 }
67
68 const char nl = '\n';
69 status = SSLWrite(tlsctx, &nl, 1, &processed);
70 if (status != noErr) {
71 NSLog(@"SSLWrite error: %d", status);
72 return;
73 }
74 }
75
76 int main() {
77 CFReadStreamRef read_cf;
78 CFWriteStreamRef write_cf;
79 CFStreamCreatePairWithSocketToHost(NULL, CFSTR("localhost"), 9925, &read_cf, &write_cf);
80
81 NSInputStream* is = (NSInputStream*)read_cf;
82 NSOutputStream* os = (NSOutputStream*)write_cf;
83
84 [is open];
85 [os open];
86
87 ReadBuffer(is);
88 WriteLine(os, @"EHLO tlstest");
89 ReadBuffer(is);
90
91 StreamPair pair = { is, os };
92
93 SSLContextRef tlsctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
94 SSLSetIOFuncs(tlsctx, MySSLRead, MySSLWrite);
95 SSLSetConnection(tlsctx, &pair);
96 SSLSetSessionOption(tlsctx, kSSLSessionOptionBreakOnServerAuth, true);
97
98 WriteLine(os, @"STARTTLS");
99 ReadBuffer(is);
100
101 // Skip trust verification.
102 OSStatus handshake = SSLHandshake(tlsctx);
103 NSLog(@"SSL Handshake = %d", handshake);
104 if (handshake == errSSLServerAuthCompleted) {
105 handshake = SSLHandshake(tlsctx);
106 NSLog(@"SSL Handshake = %d", handshake);
107 }
108
109 ReadBuffer(tlsctx);
110 WriteLine(tlsctx, @"EHLO tlstest-tls");
111
112 ReadBuffer(tlsctx);
113 ReadBuffer(tlsctx);
114
115 WriteLine(tlsctx, @"MAIL FROM:<test@tlstest>");
116 ReadBuffer(tlsctx);
117
118 WriteLine(tlsctx, @"RCPT TO:<test@localhost>");
119 ReadBuffer(tlsctx);
120
121 WriteLine(tlsctx, @"DATA");
122 sleep(10);
123 ReadBuffer(tlsctx);
124
125 WriteLine(tlsctx, @"More data");
126 WriteLine(tlsctx, @"and some more");
127 WriteLine(tlsctx, @"more more more");
128 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
129 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
130 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
131 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
132 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
133 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
134 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
135 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
136 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
137 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
138 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
139 WriteLine(tlsctx, @"adfasdf;lan io;aweofani ef;awe");
140 WriteLine(tlsctx, @".");
141
142 ReadBuffer(tlsctx);
143
144 WriteLine(tlsctx, @"QUIT");
145 ReadBuffer(tlsctx);
146
147 SSLClose(tlsctx);
148
149 [is close];
150 [os close];
151 }