63
63
/* Sets the protocol name to connect to in case of timeout */
64
64
void set_ontimeout(const char* name)
66
asprintf(&on_timeout, "%s", name);
66
int res = asprintf(&on_timeout, "%s", name);
67
CHECK_RES_DIE(res, "asprintf");
69
70
/* Returns the protocol to connect to in case of timeout;
124
125
/* Is the buffer the beginning of an SSH connection? */
125
126
static int is_ssh_protocol(const char *p, int len, struct proto *proto)
127
if (!strncmp(p, "SSH-", 4)) {
131
return !strncmp(p, "SSH-", 4);
133
134
/* Is the buffer the beginning of an OpenVPN connection?
162
170
static int is_xmpp_protocol( const char *p, int len, struct proto *proto)
164
return strstr(p, "jabber") ? 1 : 0;
175
return memmem(p, len, "jabber", 6) ? 1 : 0;
167
static int probe_http_method(const char *p, const char *opt)
178
static int probe_http_method(const char *p, int len, const char *opt)
169
return !strcmp(p, opt);
180
if (len < strlen(opt))
183
return !strncmp(p, opt, len);
172
186
/* Is the buffer the beginning of an HTTP connection? */
173
187
static int is_http_protocol(const char *p, int len, struct proto *proto)
175
190
/* If it's got HTTP in the request (HTTP/1.1) then it's HTTP */
176
if (strstr(p, "HTTP"))
191
if (memmem(p, len, "HTTP", 4))
194
#define PROBE_HTTP_METHOD(opt) if ((res = probe_http_method(p, len, opt)) != PROBE_NEXT) return res
179
196
/* Otherwise it could be HTTP/1.0 without version: check if it's got an
180
197
* HTTP method (RFC2616 5.1.1) */
181
probe_http_method(p, "OPTIONS");
182
probe_http_method(p, "GET");
183
probe_http_method(p, "HEAD");
184
probe_http_method(p, "POST");
185
probe_http_method(p, "PUT");
186
probe_http_method(p, "DELETE");
187
probe_http_method(p, "TRACE");
188
probe_http_method(p, "CONNECT");
198
PROBE_HTTP_METHOD("OPTIONS");
199
PROBE_HTTP_METHOD("GET");
200
PROBE_HTTP_METHOD("HEAD");
201
PROBE_HTTP_METHOD("POST");
202
PROBE_HTTP_METHOD("PUT");
203
PROBE_HTTP_METHOD("DELETE");
204
PROBE_HTTP_METHOD("TRACE");
205
PROBE_HTTP_METHOD("CONNECT");
207
#undef PROBE_HTTP_METHOD
193
212
static int is_tls_protocol(const char *p, int len, struct proto *proto)
195
217
/* TLS packet starts with a record "Hello" (0x16), followed by version
196
218
* (0x03 0x00-0x03) (RFC6101 A.1)
197
219
* This means we reject SSLv2 and lower, which is actually a good thing (RFC6176)
202
224
static int regex_probe(const char *p, int len, struct proto *proto)
204
regex_t** probe_list = (regex_t**)(proto->data);
207
while (probe_list[i]) {
208
if (!regexec(probe_list[i], p, 0, NULL, 0)) {
226
regex_t **probe = proto->data;
227
regmatch_t pos = { 0, len };
229
for (; *probe && regexec(*probe, p, 0, &pos, REG_STARTEND); probe++)
232
return (probe != NULL);
217
236
* Read the beginning of data coming from the client connection and check if
218
* it's a known protocol. Then leave the data on the defered
219
* write buffer of the connection and returns a pointer to the protocol
237
* it's a known protocol.
238
* Return PROBE_AGAIN if not enough data, or PROBE_MATCH if it succeeded in
239
* which case cnx->proto is set to the appropriate protocol.
222
struct proto* probe_client_protocol(struct connection *cnx)
241
int probe_client_protocol(struct connection *cnx)
224
243
char buffer[BUFSIZ];
232
251
* function does not have to deal with a specific failure condition (the
233
252
* connection will just fail later normally). */
254
int res = PROBE_NEXT;
235
256
defer_write(&cnx->q[1], buffer, n);
237
for (p = protocols; p; p = p->next) {
258
for (p = cnx->proto; p && res == PROBE_NEXT; p = p->next) {
238
259
if (! p->probe) continue;
239
260
if (verbose) fprintf(stderr, "probing for %s\n", p->description);
240
if (p->probe(buffer, n, p)) {
241
if (verbose) fprintf(stderr, "probe %s successful\n", p->description);
263
res = p->probe(cnx->q[1].begin_deferred_data, cnx->q[1].deferred_data_size, p);
265
if (res != PROBE_NEXT)