31
31
#include " vmime/vmime.hpp"
32
32
#include " vmime/platforms/posix/posixHandler.hpp"
33
33
34
+ #include " example6_tracer.hpp"
35
+ #include " example6_authenticator.hpp"
36
+ #include " example6_certificateVerifier.hpp"
37
+ #include " example6_timeoutHandler.hpp"
38
+
34
39
35
40
// Global session object
36
41
static vmime::shared_ptr <vmime::net::session> g_session
37
42
= vmime::make_shared <vmime::net::session>();
38
43
39
44
40
- #if VMIME_HAVE_SASL_SUPPORT
41
-
42
- // SASL authentication handler
43
- class interactiveAuthenticator : public vmime ::security::sasl::defaultSASLAuthenticator
44
- {
45
- const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> > getAcceptableMechanisms
46
- (const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available,
47
- vmime::shared_ptr <vmime::security::sasl::SASLMechanism> suggested) const
48
- {
49
- std::cout << std::endl << " Available SASL mechanisms:" << std::endl;
50
-
51
- for (unsigned int i = 0 ; i < available.size () ; ++i)
52
- {
53
- std::cout << " " << available[i]->getName ();
54
-
55
- if (suggested && available[i]->getName () == suggested->getName ())
56
- std::cout << " (suggested)" ;
57
- }
58
-
59
- std::cout << std::endl << std::endl;
60
-
61
- return defaultSASLAuthenticator::getAcceptableMechanisms (available, suggested);
62
- }
63
-
64
- void setSASLMechanism (vmime::shared_ptr <vmime::security::sasl::SASLMechanism> mech)
65
- {
66
- std::cout << " Trying '" << mech->getName () << " ' authentication mechanism" << std::endl;
67
-
68
- defaultSASLAuthenticator::setSASLMechanism (mech);
69
- }
70
-
71
- const vmime::string getUsername () const
72
- {
73
- if (m_username.empty ())
74
- m_username = getUserInput (" Username" );
75
-
76
- return m_username;
77
- }
78
-
79
- const vmime::string getPassword () const
80
- {
81
- if (m_password.empty ())
82
- m_password = getUserInput (" Password" );
83
-
84
- return m_password;
85
- }
86
-
87
- static const vmime::string getUserInput (const std::string& prompt)
88
- {
89
- std::cout << prompt << " : " ;
90
- std::cout.flush ();
91
-
92
- vmime::string res;
93
- std::getline (std::cin, res);
94
-
95
- return res;
96
- }
97
-
98
- private:
99
-
100
- mutable vmime::string m_username;
101
- mutable vmime::string m_password;
102
- };
103
-
104
- #else // !VMIME_HAVE_SASL_SUPPORT
105
-
106
- // Simple authentication handler
107
- class interactiveAuthenticator : public vmime ::security::defaultAuthenticator
108
- {
109
- const vmime::string getUsername () const
110
- {
111
- if (m_username.empty ())
112
- m_username = getUserInput (" Username" );
113
-
114
- return m_username;
115
- }
116
-
117
- const vmime::string getPassword () const
118
- {
119
- if (m_password.empty ())
120
- m_password = getUserInput (" Password" );
121
-
122
- return m_password;
123
- }
124
-
125
- static const vmime::string getUserInput (const std::string& prompt)
126
- {
127
- std::cout << prompt << " : " ;
128
- std::cout.flush ();
129
-
130
- vmime::string res;
131
- std::getline (std::cin, res);
132
-
133
- return res;
134
- }
135
-
136
- private:
137
-
138
- mutable vmime::string m_username;
139
- mutable vmime::string m_password;
140
- };
141
-
142
- #endif // VMIME_HAVE_SASL_SUPPORT
143
-
144
-
145
- #if VMIME_HAVE_TLS_SUPPORT
146
-
147
- // Certificate verifier (TLS/SSL)
148
- class interactiveCertificateVerifier : public vmime ::security::cert::defaultCertificateVerifier
149
- {
150
- public:
151
-
152
- void verify (vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname)
153
- {
154
- try
155
- {
156
- setX509TrustedCerts (m_trustedCerts);
157
-
158
- defaultCertificateVerifier::verify (chain, hostname);
159
- }
160
- catch (vmime::exceptions::certificate_verification_exception&)
161
- {
162
- // Obtain subject's certificate
163
- vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt (0 );
164
-
165
- std::cout << std::endl;
166
- std::cout << " Server sent a '" << cert->getType () << " '" << " certificate." << std::endl;
167
- std::cout << " Do you want to accept this certificate? (Y/n) " ;
168
- std::cout.flush ();
169
-
170
- std::string answer;
171
- std::getline (std::cin, answer);
172
-
173
- if (answer.length () != 0 &&
174
- (answer[0 ] == ' Y' || answer[0 ] == ' y' ))
175
- {
176
- // Accept it, and remember user's choice for later
177
- if (cert->getType () == " X.509" )
178
- {
179
- m_trustedCerts.push_back (vmime::dynamicCast
180
- <vmime::security::cert::X509Certificate>(cert));
181
-
182
- setX509TrustedCerts (m_trustedCerts);
183
- defaultCertificateVerifier::verify (chain, hostname);
184
- }
185
-
186
- return ;
187
- }
188
-
189
- throw vmime::exceptions::certificate_verification_exception
190
- (" User did not accept the certificate." );
191
- }
192
- }
193
-
194
- private:
195
-
196
- static std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > m_trustedCerts;
197
- };
198
-
199
-
200
- std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> >
201
- interactiveCertificateVerifier::m_trustedCerts;
202
-
203
- #endif // VMIME_HAVE_TLS_SUPPORT
204
-
205
-
206
45
/* * Returns the messaging protocols supported by VMime.
207
46
*
208
47
* @param type service type (vmime::net::service::TYPE_STORE or
@@ -290,53 +129,6 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
290
129
}
291
130
292
131
293
- /* * Time out handler.
294
- * Used to stop the current operation after too much time, or if the user
295
- * requested cancellation.
296
- */
297
- class timeoutHandler : public vmime ::net::timeoutHandler
298
- {
299
- public:
300
-
301
- bool isTimeOut ()
302
- {
303
- // This is a cancellation point: return true if you want to cancel
304
- // the current operation. If you return true, handleTimeOut() will
305
- // be called just after this, and before actually cancelling the
306
- // operation
307
- return false ;
308
- }
309
-
310
- void resetTimeOut ()
311
- {
312
- // Called at the beginning of an operation (eg. connecting,
313
- // a read() or a write() on a socket...)
314
- }
315
-
316
- bool handleTimeOut ()
317
- {
318
- // If isTimeOut() returned true, this function will be called. This
319
- // allows you to interact with the user, ie. display a prompt to
320
- // know whether he wants to cancel the operation.
321
-
322
- // If you return true here, the operation will be actually cancelled.
323
- // If not, the time out is reset and the operation continues.
324
- return true ;
325
- }
326
- };
327
-
328
-
329
- class timeoutHandlerFactory : public vmime ::net::timeoutHandlerFactory
330
- {
331
- public:
332
-
333
- vmime::shared_ptr <vmime::net::timeoutHandler> create ()
334
- {
335
- return vmime::make_shared <timeoutHandler>();
336
- }
337
- };
338
-
339
-
340
132
/* * Print the MIME structure of a message on the standard output.
341
133
*
342
134
* @param s structure object
@@ -445,8 +237,12 @@ static void sendMessage()
445
237
446
238
vmime::utility::url url (urlString);
447
239
448
- vmime::shared_ptr <vmime::net::transport> tr =
449
- g_session->getTransport (url, vmime::make_shared <interactiveAuthenticator>());
240
+ vmime::shared_ptr <vmime::net::transport> tr;
241
+
242
+ if (url.getUsername ().empty () || url.getPassword ().empty ())
243
+ tr = g_session->getTransport (url, vmime::make_shared <interactiveAuthenticator>());
244
+ else
245
+ tr = g_session->getTransport (url);
450
246
451
247
#if VMIME_HAVE_TLS_SUPPORT
452
248
@@ -465,7 +261,12 @@ static void sendMessage()
465
261
466
262
// You can also set some properties (see example7 to know the properties
467
263
// available for each service). For example, for SMTP:
468
- // tr->setProperty("options.need-authentication", true);
264
+ if (!url.getUsername ().empty () || !url.getPassword ().empty ())
265
+ tr->setProperty (" options.need-authentication" , true );
266
+
267
+ // Trace communication between client and server
268
+ vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
269
+ tr->setTracerFactory (vmime::make_shared <myTracerFactory>(traceStream));
469
270
470
271
// Information about the mail
471
272
std::cout << " Enter email of the expeditor (eg. me@somewhere.com): " ;
@@ -520,6 +321,12 @@ static void sendMessage()
520
321
// ...
521
322
// tr->send(&msg);
522
323
324
+ // Display connection log
325
+ std::cout << std::endl;
326
+ std::cout << " Connection Trace:" << std::endl;
327
+ std::cout << " =================" << std::endl;
328
+ std::cout << traceStream->str ();
329
+
523
330
tr->disconnect ();
524
331
}
525
332
catch (vmime::exception& e)
@@ -580,6 +387,10 @@ static void connectStore()
580
387
581
388
#endif // VMIME_HAVE_TLS_SUPPORT
582
389
390
+ // Trace communication between client and server
391
+ vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
392
+ st->setTracerFactory (vmime::make_shared <myTracerFactory>(traceStream));
393
+
583
394
// Connect to the mail store
584
395
st->connect ();
585
396
@@ -621,6 +432,7 @@ static void connectStore()
621
432
choices.push_back (" Change folder" );
622
433
choices.push_back (" Add message (to the current folder)" );
623
434
choices.push_back (" Copy message (into the current folder)" );
435
+ choices.push_back (" Display trace output" );
624
436
choices.push_back (" Return to main menu" );
625
437
626
438
const int choice = printMenu (choices);
@@ -928,9 +740,18 @@ static void connectStore()
928
740
929
741
break ;
930
742
}
931
- // Main menu
743
+ // Display trace output
932
744
case 12 :
933
745
746
+ std::cout << std::endl;
747
+ std::cout << " Connection Trace:" << std::endl;
748
+ std::cout << " =================" << std::endl;
749
+ std::cout << traceStream->str ();
750
+ break ;
751
+
752
+ // Main menu
753
+ case 13 :
754
+
934
755
f->close (true ); // 'true' to expunge deleted messages
935
756
cont = false ;
936
757
break ;
@@ -979,7 +800,9 @@ static void connectStore()
979
800
std::cerr << std::endl;
980
801
std::cerr << " std::exception: " << e.what () << std::endl;
981
802
}
982
- }
803
+ } // for(cont)
804
+
805
+ st->disconnect ();
983
806
}
984
807
catch (vmime::exception& e)
985
808
{
0 commit comments