]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/helper.cc
Initial SSL server certificate validator implementation
[thirdparty/squid.git] / src / ssl / helper.cc
1 /*
2 * 2008/11/14
3 */
4
5 #include "squid.h"
6 #include "anyp/PortCfg.h"
7 #include "protos.h"
8 #include "ssl/Config.h"
9 #include "ssl/helper.h"
10 #include "SquidTime.h"
11 #include "SwapDir.h"
12 #include "wordlist.h"
13 #include "protos.h"
14
15 Ssl::Helper * Ssl::Helper::GetInstance()
16 {
17 static Ssl::Helper sslHelper;
18 return &sslHelper;
19 }
20
21 Ssl::Helper::Helper()
22 {
23 }
24
25 Ssl::Helper::~Helper()
26 {
27 Shutdown();
28 }
29
30 void Ssl::Helper::Init()
31 {
32 assert(ssl_crtd == NULL);
33
34 // we need to start ssl_crtd only if some port(s) need to bump SSL
35 bool found = false;
36 for (AnyP::PortCfg *s = ::Config.Sockaddr.http; !found && s; s = s->next)
37 found = s->sslBump;
38 for (AnyP::PortCfg *s = ::Config.Sockaddr.https; !found && s; s = s->next)
39 found = s->sslBump;
40 if (!found)
41 return;
42
43 ssl_crtd = new helper("ssl_crtd");
44 ssl_crtd->childs.updateLimits(Ssl::TheConfig.ssl_crtdChildren);
45 ssl_crtd->ipc_type = IPC_STREAM;
46 // The crtd messages may contain the eol ('\n') character. We are
47 // going to use the '\1' char as the end-of-message mark.
48 ssl_crtd->eom = '\1';
49 assert(ssl_crtd->cmdline == NULL);
50 {
51 char *tmp = xstrdup(Ssl::TheConfig.ssl_crtd);
52 char *tmp_begin = tmp;
53 char * token = NULL;
54 bool db_path_was_found = false;
55 bool block_size_was_found = false;
56 char buffer[20] = "2048";
57 while ((token = strwordtok(NULL, &tmp))) {
58 wordlistAdd(&ssl_crtd->cmdline, token);
59 if (!strcmp(token, "-b"))
60 block_size_was_found = true;
61 if (!strcmp(token, "-s")) {
62 db_path_was_found = true;
63 } else if (db_path_was_found) {
64 db_path_was_found = false;
65 int fs_block_size = 0;
66 storeDirGetBlkSize(token, &fs_block_size);
67 snprintf(buffer, sizeof(buffer), "%i", fs_block_size);
68 }
69 }
70 if (!block_size_was_found) {
71 wordlistAdd(&ssl_crtd->cmdline, "-b");
72 wordlistAdd(&ssl_crtd->cmdline, buffer);
73 }
74 safe_free(tmp_begin);
75 }
76 helperOpenServers(ssl_crtd);
77 }
78
79 void Ssl::Helper::Shutdown()
80 {
81 if (!ssl_crtd)
82 return;
83 helperShutdown(ssl_crtd);
84 wordlistDestroy(&ssl_crtd->cmdline);
85 delete ssl_crtd;
86 ssl_crtd = NULL;
87 }
88
89 void Ssl::Helper::sslSubmit(CrtdMessage const & message, HLPCB * callback, void * data)
90 {
91 static time_t first_warn = 0;
92 assert(ssl_crtd);
93
94 if (ssl_crtd->stats.queue_size >= (int)(ssl_crtd->childs.n_running * 2)) {
95 if (first_warn == 0)
96 first_warn = squid_curtime;
97 if (squid_curtime - first_warn > 3 * 60)
98 fatal("SSL servers not responding for 3 minutes");
99 debugs(34, DBG_IMPORTANT, HERE << "Queue overload, rejecting");
100 callback(data, (char *)"error 45 Temporary network problem, please retry later");
101 return;
102 }
103
104 first_warn = 0;
105 std::string msg = message.compose();
106 msg += '\n';
107 helperSubmit(ssl_crtd, msg.c_str(), callback, data);
108 }
109
110 /*ssl_crtd_validator*/
111
112 Ssl::CertValidationHelper * Ssl::CertValidationHelper::GetInstance()
113 {
114 static Ssl::CertValidationHelper sslHelper;
115 if (!Ssl::TheConfig.ssl_crt_validator)
116 return NULL;
117 return &sslHelper;
118 }
119
120 Ssl::CertValidationHelper::CertValidationHelper() : ssl_crt_validator(NULL)
121 {
122 }
123
124 Ssl::CertValidationHelper::~CertValidationHelper()
125 {
126 Shutdown();
127 }
128
129 void Ssl::CertValidationHelper::Init()
130 {
131 assert(ssl_crt_validator == NULL);
132
133 // we need to start ssl_crtd only if some port(s) need to bump SSL
134 bool found = false;
135 for (AnyP::PortCfg *s = ::Config.Sockaddr.http; !found && s; s = s->next)
136 found = s->sslBump;
137 for (AnyP::PortCfg *s = ::Config.Sockaddr.https; !found && s; s = s->next)
138 found = s->sslBump;
139 if (!found)
140 return;
141
142 ssl_crt_validator = new helper("ssl_crt_validator");
143 ssl_crt_validator->childs.updateLimits(Ssl::TheConfig.ssl_crt_validator_Children);
144 ssl_crt_validator->ipc_type = IPC_STREAM;
145 // The crtd messages may contain the eol ('\n') character. We are
146 // going to use the '\1' char as the end-of-message mark.
147 ssl_crt_validator->eom = '\1';
148 assert(ssl_crt_validator->cmdline == NULL);
149 {
150 char *tmp = xstrdup(Ssl::TheConfig.ssl_crt_validator);
151 char *tmp_begin = tmp;
152 char * token = NULL;
153 while ((token = strwordtok(NULL, &tmp))) {
154 wordlistAdd(&ssl_crt_validator->cmdline, token);
155 }
156 safe_free(tmp_begin);
157 }
158 helperOpenServers(ssl_crt_validator);
159 }
160
161 void Ssl::CertValidationHelper::Shutdown()
162 {
163 if (!ssl_crt_validator)
164 return;
165 helperShutdown(ssl_crt_validator);
166 wordlistDestroy(&ssl_crt_validator->cmdline);
167 delete ssl_crt_validator;
168 ssl_crt_validator = NULL;
169 }
170
171 void Ssl::CertValidationHelper::sslSubmit(CrtdMessage const & message, HLPCB * callback, void * data)
172 {
173 static time_t first_warn = 0;
174 assert(ssl_crt_validator);
175
176 if (ssl_crt_validator->stats.queue_size >= (int)(ssl_crt_validator->childs.n_running * 2)) {
177 if (first_warn == 0)
178 first_warn = squid_curtime;
179 if (squid_curtime - first_warn > 3 * 60)
180 fatal("SSL servers not responding for 3 minutes");
181 debugs(34, 1, HERE << "Queue overload, rejecting");
182 callback(data, (char *)"error 45 Temporary network problem, please retry later");
183 return;
184 }
185
186 first_warn = 0;
187 std::string msg = message.compose();
188 msg += '\n';
189 helperSubmit(ssl_crt_validator, msg.c_str(), callback, data);
190 }