| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  | #ifndef NETWORK_ACCESS_MANAGER_HPP__
 | 
					
						
							|  |  |  | #define NETWORK_ACCESS_MANAGER_HPP__
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QNetworkAccessManager>
 | 
					
						
							|  |  |  | #include <QList>
 | 
					
						
							|  |  |  | #include <QSslError>
 | 
					
						
							|  |  |  | #include <QNetworkReply>
 | 
					
						
							|  |  |  | #include <QString>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MessageBox.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class QNetworkRequest; | 
					
						
							|  |  |  | class QIODevice; | 
					
						
							|  |  |  | class QWidget; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // sub-class QNAM to keep a list of accepted SSL errors and allow
 | 
					
						
							|  |  |  | // them in future replies
 | 
					
						
							|  |  |  | class NetworkAccessManager | 
					
						
							|  |  |  |   : public QNetworkAccessManager | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |   NetworkAccessManager (QWidget * parent) | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |     : QNetworkAccessManager (parent) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // handle SSL errors that have not been cached as allowed
 | 
					
						
							|  |  |  |     // exceptions and offer them to the user to add to the ignored
 | 
					
						
							|  |  |  |     // exception cache
 | 
					
						
							|  |  |  |     connect (this, &QNetworkAccessManager::sslErrors, [this, &parent] (QNetworkReply * reply, QList<QSslError> const& errors) { | 
					
						
							|  |  |  |         QString message; | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |         QList<QSslError> new_errors; | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |         for (auto const& error: errors) | 
					
						
							|  |  |  |           { | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |             if (!allowed_ssl_errors_.contains (error)) | 
					
						
							|  |  |  |               { | 
					
						
							|  |  |  |                 new_errors << error; | 
					
						
							|  |  |  |                 message += '\n' + reply->request ().url ().toDisplayString () + ": " | 
					
						
							|  |  |  |                   + error.errorString (); | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |         if (new_errors.size ()) | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |             QString certs; | 
					
						
							|  |  |  |             for (auto const& cert : reply->sslConfiguration ().peerCertificateChain ()) | 
					
						
							|  |  |  |               { | 
					
						
							|  |  |  |                 certs += cert.toText () + '\n'; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             if (MessageBox::Ignore == MessageBox::query_message (parent, tr ("Network SSL Errors"), message, certs, MessageBox::Abort | MessageBox::Ignore)) | 
					
						
							|  |  |  |               { | 
					
						
							|  |  |  |                 // accumulate new SSL error exceptions that have been allowed
 | 
					
						
							|  |  |  |                 allowed_ssl_errors_.append (new_errors); | 
					
						
							|  |  |  |                 reply->ignoreSslErrors (allowed_ssl_errors_); | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2016-12-11 21:19:23 +00:00
										 |  |  |             // no new exceptions so silently ignore the ones already allowed
 | 
					
						
							|  |  |  |             reply->ignoreSslErrors (allowed_ssl_errors_); | 
					
						
							| 
									
										
										
										
											2016-12-04 14:17:01 +00:00
										 |  |  |           } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |   QNetworkReply * createRequest (Operation operation, QNetworkRequest const& request, QIODevice * outgoing_data = nullptr) override | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     auto reply = QNetworkAccessManager::createRequest (operation, request, outgoing_data); | 
					
						
							|  |  |  |     // errors are usually certificate specific so passing all cached
 | 
					
						
							|  |  |  |     // exceptions here is ok
 | 
					
						
							|  |  |  |     reply->ignoreSslErrors (allowed_ssl_errors_); | 
					
						
							|  |  |  |     return reply; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   QList<QSslError> allowed_ssl_errors_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |