/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2013 Wilmer van der Gaast and others * \********************************************************************/ /* HTTP(S) module */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License with the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; if not, write to the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "http_client.h" #include "url.h" #include "sock.h" static gboolean http_connected(gpointer data, int source, b_input_condition cond); static gboolean http_ssl_connected(gpointer data, int returncode, void *source, b_input_condition cond); static gboolean http_incoming_data(gpointer data, int source, b_input_condition cond); static void http_free(struct http_request *req); struct http_request *http_dorequest(char *host, int port, int ssl, char *request, http_input_function func, gpointer data) { struct http_request *req; int error = 0; req = g_new0(struct http_request, 1); if (ssl) { req->ssl = ssl_connect(host, port, TRUE, http_ssl_connected, req); if (req->ssl == NULL) { error = 1; } } else { req->fd = proxy_connect(host, port, http_connected, req); if (req->fd < 0) { error = 1; } } if (error) { http_free(req); return NULL; } req->func = func; req->data = data; req->request = g_strdup(request); req->request_length = strlen(request); req->redir_ttl = 3; req->content_length = -1; if (getenv("BITLBEE_DEBUG")) { printf("About to send HTTP request:\n%s\n", req->request); } return req; } struct http_request *http_dorequest_url(char *url_string, http_input_function func, gpointer data) { url_t *url = g_new0(url_t, 1); char *request; void *ret; if (!url_set(url, url_string)) { g_free(url); return NULL; } if (url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS) { g_free(url); return NULL; } request = g_strdup_printf("GET %s HTTP/1.0\r\n" "Host: %s\r\n" "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n" "\r\n", url->file, url->host); ret = http_dorequest(url->host, url->port, url->proto == PROTO_HTTPS, request, func, data); g_free(url); g_free(request); return ret; } /* This one is actually pretty simple... Might get more calls if we can't write the whole request at once. */ static gboolean http_connected(gpointer data, int source, b_input_condition cond) { struct http_request *req = data; int st; if (source < 0) { goto error; } if (req->inpa > 0) { b_event_remove(req->inpa); } sock_make_nonblocking(req->fd); if (req->ssl) { st = ssl_write(req->ssl, req->request + req->bytes_written, req->request_length - req->bytes_written); if (st < 0) { if (ssl_errno != SSL_AGAIN) { ssl_disconnect(req->ssl); goto error; } } } else { st = write(source, req->request + req->bytes_written, req->request_length - req->bytes_written); if (st < 0) { if (!sockerr_again()) { closesocket(req->fd); goto error; } } } if (st > 0) { req->bytes_written += st; } if (req->bytes_written < req->request_length) { req->inpa = b_input_add(source, req->ssl ? ssl_getdirection(req->ssl) : B_EV_IO_WRITE, http_connected, req); } else { req->inpa = b_input_add(source, B_EV_IO_READ, http_incoming_data, req); } return FALSE; error: if (req->status_string == NULL) { req->status_string = g_strdup("Error while writing HTTP request"); } req->func(req); http_free(req); return FALSE; } static gboolean http_ssl_connected(gpointer data, int returncode, void *source, b_input_condition cond) { struct http_request *req = data; if (source == NULL) { if (returncode != 0) { char *err = ssl_verify_strerror(returncode); req->status_string = g_strdup_printf( "Certificate verification problem 0x%x: %s", returncode, err ? err : "Unknown"); g_free(err); } return http_connected(data, -1, cond); } req->fd = ssl_getfd(source); return http_connected(data, req->fd, cond); } typedef enum { CR_OK, CR_EOF, CR_ERROR, CR_ABORT, } htt
#include <stdlib.h>
#include <glib.h>
#include <gmodule.h>
#include <check.h>
#include <string.h>
#include <stdio.h>
#include "md5.h"

/* From RFC 1321 */
struct md5_test {
	const char *str;
	md5_byte_t expected[16];
} tests[] = {
	{ "", 
		{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
	{ "a",
		{ 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
	{ "abc", 
		{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
	{ "message digest", 
		{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0