Пример #1
0
/**
 * ssl_socket_open - Open an SSL socket - Implements Connection::conn_open()
 */
static int ssl_socket_open(struct Connection *conn)
{
  if (raw_socket_open(conn) < 0)
    return -1;

  int rc = ssl_setup(conn);
  if (rc)
    raw_socket_close(conn);

  return rc;
}
Пример #2
0
/**
 * mutt_ssl_starttls - Negotiate TLS over an already opened connection
 * @param conn Connection to a server
 * @retval  0 Success
 * @retval -1 Error
 */
int mutt_ssl_starttls(struct Connection *conn)
{
  if (ssl_init())
    return -1;

  int rc = ssl_setup(conn);

  /* hmm. watch out if we're starting TLS over any method other than raw. */
  conn->conn_read = ssl_socket_read;
  conn->conn_write = ssl_socket_write;
  conn->conn_close = ssl_socket_close_and_restore;

  return rc;
}
Пример #3
0
int gitno_connect(git_transport *t, const char *host, const char *port)
{
	struct addrinfo *info = NULL, *p;
	struct addrinfo hints;
	int ret;
	GIT_SOCKET s = INVALID_SOCKET;

	memset(&hints, 0x0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = AF_UNSPEC;

	if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) {
		giterr_set(GITERR_NET,
			"Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
		return -1;
	}

	for (p = info; p != NULL; p = p->ai_next) {
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

		if (s == INVALID_SOCKET) {
			net_set_error("error creating socket");
			break;
		}

		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
			break;

		/* If we can't connect, try the next one */
		gitno_close(s);
		s = INVALID_SOCKET;
	}

	/* Oops, we couldn't connect to any address */
	if (s == INVALID_SOCKET && p == NULL) {
		giterr_set(GITERR_OS, "Failed to connect to %s", host);
		return -1;
	}

	t->socket = s;
	p_freeaddrinfo(info);

	if (t->use_ssl && ssl_setup(t, host) < 0)
		return -1;

	return 0;
}
Пример #4
0
/*! \brief
* creates a FILE * from the fd passed by the accept thread.
* This operation is potentially expensive (certificate verification),
* so we do it in the child thread context.
*
* \note must decrement ref count before returning NULL on error
*/
static void *handle_tcptls_connection(void *data)
{
	struct ast_tcptls_session_instance *tcptls_session = data;
#ifdef DO_SSL
	int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
	int ret;
	char err[256];
#endif

	/* TCP/TLS connections are associated with external protocols, and
	 * should not be allowed to execute 'dangerous' functions. This may
	 * need to be pushed down into the individual protocol handlers, but
	 * this seems like a good general policy.
	 */
	if (ast_thread_inhibit_escalations()) {
		ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
		ast_tcptls_close_session_file(tcptls_session);
		ao2_ref(tcptls_session, -1);
		return NULL;
	}

	tcptls_session->stream_cookie = tcptls_stream_alloc();
	if (!tcptls_session->stream_cookie) {
		ast_tcptls_close_session_file(tcptls_session);
		ao2_ref(tcptls_session, -1);
		return NULL;
	}

	/*
	* open a FILE * as appropriate.
	*/
	if (!tcptls_session->parent->tls_cfg) {
		tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie, NULL,
			tcptls_session->fd, -1);
		if (tcptls_session->f) {
			if (setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
				ast_tcptls_close_session_file(tcptls_session);
			}
		}
	}
#ifdef DO_SSL
	else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
		SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
		if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
			ast_log(LOG_ERROR, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
		} else if ((tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie,
			tcptls_session->ssl, tcptls_session->fd, -1))) {
			if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
				|| (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
				X509 *peer;
				long res;
				peer = SSL_get_peer_certificate(tcptls_session->ssl);
				if (!peer) {
					ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
					ast_tcptls_close_session_file(tcptls_session);
					ao2_ref(tcptls_session, -1);
					return NULL;
				}

				res = SSL_get_verify_result(tcptls_session->ssl);
				if (res != X509_V_OK) {
					ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
					X509_free(peer);
					ast_tcptls_close_session_file(tcptls_session);
					ao2_ref(tcptls_session, -1);
					return NULL;
				}
				if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
					ASN1_STRING *str;
					unsigned char *str2;
					X509_NAME *name = X509_get_subject_name(peer);
					int pos = -1;
					int found = 0;

					for (;;) {
						/* Walk the certificate to check all available "Common Name" */
						/* XXX Probably should do a gethostbyname on the hostname and compare that as well */
						pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
						if (pos < 0) {
							break;
						}
						str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
						ret = ASN1_STRING_to_UTF8(&str2, str);
						if (ret < 0) {
							continue;
						}

						if (str2) {
							if (strlen((char *) str2) != ret) {
								ast_log(LOG_WARNING, "Invalid certificate common name length (contains NULL bytes?)\n");
							} else if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2)) {
								found = 1;
							}
							ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
							OPENSSL_free(str2);
						}
						if (found) {
							break;
						}
					}
					if (!found) {
						ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
						X509_free(peer);
						ast_tcptls_close_session_file(tcptls_session);
						ao2_ref(tcptls_session, -1);
						return NULL;
					}
				}
				X509_free(peer);
			}
		}
		if (!tcptls_session->f) {	/* no success opening descriptor stacking */
			SSL_free(tcptls_session->ssl);
		}
	}
#endif /* DO_SSL */

	if (!tcptls_session->f) {
		ast_tcptls_close_session_file(tcptls_session);
		ast_log(LOG_WARNING, "FILE * open failed!\n");
#ifndef DO_SSL
		if (tcptls_session->parent->tls_cfg) {
			ast_log(LOG_ERROR, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
		}
#endif
		ao2_ref(tcptls_session, -1);
		return NULL;
	}

	if (tcptls_session->parent->worker_fn) {
		return tcptls_session->parent->worker_fn(tcptls_session);
	} else {
		return tcptls_session;
	}
}
Пример #5
0
/*! \brief
* creates a FILE * from the fd passed by the accept thread.
* This operation is potentially expensive (certificate verification),
* so we do it in the child thread context.
*
* \note must decrement ref count before returning NULL on error
*/
static void *handle_tcptls_connection(void *data)
{
	struct ast_tcptls_session_instance *tcptls_session = data;
#ifdef DO_SSL
	int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
	int ret;
	char err[256];
#endif

	/*
	* open a FILE * as appropriate.
	*/
	if (!tcptls_session->parent->tls_cfg) {
		tcptls_session->f = fdopen(tcptls_session->fd, "w+");
		setvbuf(tcptls_session->f, NULL, _IONBF, 0);
	}
#ifdef DO_SSL
	else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
		SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
		if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
			ast_verb(2, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
		} else {
#if defined(HAVE_FUNOPEN)	/* the BSD interface */
			tcptls_session->f = funopen(tcptls_session->ssl, ssl_read, ssl_write, NULL, ssl_close);

#elif defined(HAVE_FOPENCOOKIE)	/* the glibc/linux interface */
			static const cookie_io_functions_t cookie_funcs = {
				ssl_read, ssl_write, NULL, ssl_close
			};
			tcptls_session->f = fopencookie(tcptls_session->ssl, "w+", cookie_funcs);
#else
			/* could add other methods here */
			ast_debug(2, "no tcptls_session->f methods attempted!");
#endif
			if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
				|| (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
				X509 *peer;
				long res;
				peer = SSL_get_peer_certificate(tcptls_session->ssl);
				if (!peer)
					ast_log(LOG_WARNING, "No peer SSL certificate\n");
				res = SSL_get_verify_result(tcptls_session->ssl);
				if (res != X509_V_OK)
					ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
				if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
					ASN1_STRING *str;
					unsigned char *str2;
					X509_NAME *name = X509_get_subject_name(peer);
					int pos = -1;
					int found = 0;
				
					for (;;) {
						/* Walk the certificate to check all available "Common Name" */
						/* XXX Probably should do a gethostbyname on the hostname and compare that as well */
						pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
						if (pos < 0)
							break;
						str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
						ASN1_STRING_to_UTF8(&str2, str);
						if (str2) {
							if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2))
								found = 1;
							ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
							OPENSSL_free(str2);
						}
						if (found)
							break;
					}
					if (!found) {
						ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
						if (peer)
							X509_free(peer);
						close(tcptls_session->fd);
						fclose(tcptls_session->f);
						ao2_ref(tcptls_session, -1);
						return NULL;
					}
				}
				if (peer)
					X509_free(peer);
			}
		}
		if (!tcptls_session->f)	/* no success opening descriptor stacking */
			SSL_free(tcptls_session->ssl);
   }
#endif /* DO_SSL */

	if (!tcptls_session->f) {
		close(tcptls_session->fd);
		ast_log(LOG_WARNING, "FILE * open failed!\n");
		ao2_ref(tcptls_session, -1);
		return NULL;
	}

	if (tcptls_session && tcptls_session->parent->worker_fn)
		return tcptls_session->parent->worker_fn(tcptls_session);
	else
		return tcptls_session;
}
Пример #6
0
int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int flags)
{
	struct addrinfo *info = NULL, *p;
	struct addrinfo hints;
	GIT_SOCKET s = INVALID_SOCKET;
	int ret;

#ifdef GIT_WIN32
	/* on win32, the WSA context needs to be initialized
	 * before any socket calls can be performed */
	WSADATA wsd;

	if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
		giterr_set(GITERR_OS, "Winsock init failed");
		return -1;
	}

	if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
		WSACleanup();
		giterr_set(GITERR_OS, "Winsock init failed");
		return -1;
	}
#endif

	/* Zero the socket structure provided */
	memset(s_out, 0x0, sizeof(gitno_socket));

	memset(&hints, 0x0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = AF_UNSPEC;

	if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) {
		giterr_set(GITERR_NET,
			"Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
		return -1;
	}

	for (p = info; p != NULL; p = p->ai_next) {
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

		if (s == INVALID_SOCKET) {
			net_set_error("error creating socket");
			break;
		}

		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
			break;

		/* If we can't connect, try the next one */
		gitno__close(s);
		s = INVALID_SOCKET;
	}

	/* Oops, we couldn't connect to any address */
	if (s == INVALID_SOCKET && p == NULL) {
		giterr_set(GITERR_OS, "Failed to connect to %s", host);
		p_freeaddrinfo(info);
		return -1;
	}

	s_out->socket = s;
	p_freeaddrinfo(info);

#ifdef GIT_SSL
	if ((flags & GITNO_CONNECT_SSL) && ssl_setup(s_out, host, flags) < 0)
		return -1;
#else
	/* SSL is not supported */
	if (flags & GITNO_CONNECT_SSL) {
		giterr_set(GITERR_OS, "SSL is not supported by this copy of libgit2.");
		return -1;
	}
#endif

	return 0;
}
Пример #7
0
/****************************************************************************
 * http_request
 * Retrieves the specified URL, and stores it in the specified file or buffer
 ***************************************************************************/
int http_request(const char *url, FILE *hfile, u8 *buffer, u32 maxsize, bool silent, bool accept_encoding)
{
	int res = 0; int chunked = 0;
	char http_host[64];
	char http_path[256];
	char content_encoding[16] = "";
	u16 http_port;
	#ifdef DEBUGHEADERS
		int debugging = 0;
	#endif
	http_res result;
	u32 sizeread = 0;

	content_length = 0;

	int linecount;

	if(maxsize > MAX_SIZE){
		#ifdef DEBUGERRORS
			InfoPrompt("maxsize > MAX_SIZE");
		#endif
		return 0;
	}

	if (url == NULL || (hfile == NULL && buffer == NULL)){
		#ifdef DEBUGERRORS
			InfoPrompt("!url || (!hfile && !buffer)");
		#endif
		return 0;
	}

	if(!silent)
		ShowAction("Sending data...");
	
	split_res = http_split_url(http_host, http_path, url); // 2 : https ;  1 : http ;  0 : invalid url

	if (split_res == 2){
		http_port = 443;
		writeFunc = ssl_write;
		readFunc = ssl_read;		
	}else if( split_res == 1 ){
		http_port = 80;
		writeFunc = net_write;
		readFunc = net_read;
	}else{
		#ifdef DEBUGERRORS
			InfoPrompt("Invalid url");
		#endif
		return 0;
	}

	http_status = 404;

	int s = tcp_connect(http_host, http_port);

	if (s < 0)
	{
		result = HTTPR_ERR_CONNECT;
		#ifdef DEBUGERRORS
			InfoPrompt("Socket!");
		#endif
		return 0;
	}

	int ssl_context = 0;
	
	if(split_res == 2){  
		ssl_context = ssl_setup(http_host, s);
		#ifdef DEBUGERRORS
			if(ssl_context < 0){
				InfoPrompt("ssl_context() failed");
			}
		#endif
		if(ssl_context < 0){
			net_close(s);
			return 0;
		}
		scktctx = &ssl_context;
	} else{
		scktctx = &s;
	}

	if(curl_request){ //Request made by through the CURL class
		res = tcp_write(*scktctx, (u8 *) curl_request, strlen(curl_request));
	}else{
		char request[1024];
		char *r = request;
		r += sprintf(r, "GET %s HTTP/1.1\r\n", http_path);
		r += sprintf(r, "Host: %s\r\n", http_host);
		if(accept_encoding && hfile){
			r += sprintf(r, "Accept-Encoding: gzip, deflate\r\n");
		}
		r += sprintf(r, "Cache-Control: no-cache\r\n\r\n");
		res = tcp_write(*scktctx, (u8 *) request, strlen(request));
	}

	if(!silent)
		CancelAction();
		
	#ifdef DEBUGHEADERS
		InfoPrompt(http_path);
	#endif
	char line[1024]; //Twitter sends a long header

	for (linecount = 0; linecount < 45; linecount++)
	{
		if (tcp_readln(*scktctx, line, 1024) != 0)
		{
			#ifdef DEBUGERRORS
				InfoPrompt("tcp_readln != 0");
			#endif
			http_status = 404;
			result = HTTPR_ERR_REQUEST;
			break;
		}

		if (!line[0])
			break;

		#ifdef DEBUGHEADERS
				if(sscanf(line, "HTTP/1.%*u %u", &http_status)){
					if(http_status != 200)
						debugging = 1;
				}

				if(sscanf(line, "Content-Length: %u", &content_length) || sscanf(line, "Content-Encoding: %s", content_encoding)){
					if(!debugging){
						InfoPrompt(line);
					}
				}
				if(!strncmp(line, "Transfer-Encoding: chunked", 25)){ InfoPrompt("Transfer-Encoding: chunked"); chunked = 1; }
		#else
				sscanf(line, "HTTP/1.%*u %u", &http_status);
				sscanf(line, "Content-Length: %u", &content_length);
				sscanf(line, "Content-Encoding: %s", content_encoding);
				if(!strncmp(line, "Transfer-Encoding: chunked", 25)) chunked = 1;
		#endif

		u32 api_ratelimit=0;
		if(sscanf(line, "X-RateLimit-Remaining: %u", &api_ratelimit) && api_ratelimit <= 10 && api_ratelimit % 5 == 0){
			WindowPrompt("You are on fire!", "You are about to reach Twitter's requests limit. WiiTweet will not work correctly then.", "I'll take a break", 0);
		}
		
		if(get_timeoffset){
			if(!strncasecmp(line, "Date:", 5)){ //Case insensitiveness just in case...
				const char format[] = "%a, %d %b %Y %H:%M:%S %Z";
				const char *pointline = line;
				pointline += 6;
				struct tm tm;
				memset(&tm, 0, sizeof(tm));
				strptime(pointline, format, &tm);
				timeoffset = mktime(&tm) - time(NULL);
				get_timeoffset = 0;
			}
		}
		#ifdef DEBUGHEADERS
			if(debugging){
				InfoPrompt(line);
			}
		#endif
	}

	if (http_status != 200)
	{
		result = HTTPR_ERR_STATUS;
		#ifdef DEBUGERRORS
			if(ssl_context){
				if(ssl_shutdown(ssl_context)){
					InfoPrompt("ssl_shutdown() 1");
				}
			}
			net_close(s);
		#else
			if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
		#endif
		#ifdef DEBUGERRORS
			char status[64];
			sprintf(status, "HTTP Status = %d", http_status);
			InfoPrompt(status);
		#endif
		return 0;
	}//Try to read anyways? ssl gets rude if it is not convinced there is no data

	//length unknown - just read as much as we can
	if(content_length == 0)
	{
		content_length = maxsize;
	}
	else if (content_length > maxsize) //ssl_shutdown() would fail in this case (?), but it is not likely for our purposes...
	{
		result = HTTPR_ERR_TOOBIG;
		#ifdef DEBUGERRORS
			if(ssl_context){
				if(ssl_shutdown(ssl_context)){
					InfoPrompt("ssl_shutdown() 2");
				}
			}
			net_close(s);
		#else
			if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
		#endif
		#ifdef DEBUGERRORS
			InfoPrompt("content_length > maxsize");
		#endif
		return 0;
	}

	unsigned int inflatetype = 0;
	if(!strncasecmp(content_encoding, "gzip", 4)){
		inflatetype = 2;
	}else if(!strncasecmp(content_encoding, "deflate", 7)){
		inflatetype = 1;
	}else if(content_encoding[0] != '\0'){//Unsupported encoding. This should never happen.
		#ifdef DEBUGERRORS
			if(ssl_context){
				if(ssl_shutdown(ssl_context)){
					InfoPrompt("ssl_shutdown() 3");
				}
			}
			net_close(s);
		#else
			if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
		#endif
		#ifdef DEBUGERRORS
			InfoPrompt("Unsupported encoding");
		#endif
		return 0;
	}

	if (buffer != NULL)
	{
		if(!silent)
			ShowAction("Downloading...");

		if(inflatetype){ //Compressed content
			u8 * inflate_me = (u8 *) mem2_malloc(content_length, MEM2_OTHER);
			if(!inflate_me){
				#ifdef DEBUGERRORS
					if(ssl_context){
						if(ssl_shutdown(ssl_context)){
							InfoPrompt("ssl_shutdown() 4");
						}
					}
					net_close(s);
				#else
					if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
				#endif
				#ifdef DEBUGERRORS
					InfoPrompt("!inflate_me");
				#endif
				return 0;
			}
			#ifdef DEBUGHEADERS
				int tcpread = tcp_read(*scktctx, inflate_me, content_length, chunked);
				char atoi[64];
				sprintf(atoi, "%d", tcpread);
				WindowPrompt("tcp_read()", atoi, "ok", 0);
			#else
				int tcpread = tcp_read(*scktctx, inflate_me, content_length, chunked);
			#endif
/*
			static int s = 0;
			char path[256];
			sprintf(path, "sd:/catcha%d", s++);
			SaveFile ((char *)inflate_me, path, tcpread, 1);
*/
			sizeread = httpInflate(buffer, inflate_me, tcpread, inflatetype);
			if(sizeread < 0){
				mem2_free(inflate_me, MEM2_OTHER);
				#ifdef DEBUGERRORS
					if(ssl_context){
						if(ssl_shutdown(ssl_context)){
							InfoPrompt("ssl_shutdown() 5");
						}
					}
					net_close(s);
				#else
					if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
				#endif
				#ifdef DEBUGERRORS
					InfoPrompt("sizeread < 0");
				#endif
				return 0;
			}

			mem2_free(inflate_me, MEM2_OTHER);
		}else{ //Uncomprpessed content
			sizeread = tcp_read(*scktctx, buffer, content_length, chunked);
		}

		if(!silent)
			CancelAction();
	}
	else // write into file
	{
		/* Uncompressed data. This may fail if the content is chunked and longer than 32KB+2B but chunked is not used in such scenarios */

		u32 bufSize = (1024 * 32);
		u32 bytesLeft = content_length;
		u32 readSize;

		if(!silent)
			ShowProgress("Downloading...", 0, content_length);
		u8 * fbuffer = (u8 *) malloc(bufSize);
		if(fbuffer)
		{
			while (bytesLeft > 0)
			{
				if (bytesLeft < bufSize)
					readSize = bytesLeft;
				else
					readSize = bufSize;

				res = tcp_read(*scktctx, fbuffer, readSize, chunked);
				if (!res)
					break;

				sizeread += res;
				bytesLeft -= res;

				res = fwrite(fbuffer, 1, res, hfile);
				if (!res)
					break;
 
				if(!silent)
					ShowProgress("Downloading...", (content_length - bytesLeft), content_length);
			}
			free(fbuffer);
		}
		if(!silent)
			CancelAction();
	}

	#ifdef DEBUGERRORS
		if(ssl_context){
			if(ssl_shutdown(ssl_context)){
				InfoPrompt("ssl_shutdown() 6");
			}
		}
		net_close(s);
	#else
		if(ssl_context){ssl_shutdown(ssl_context);} net_close(s);
	#endif

	if (content_length < maxsize && sizeread != content_length && !inflatetype)
	{
		#ifdef DEBUGERRORS
			InfoPrompt("ERR_RECEIVE");
		#endif
		result = HTTPR_ERR_RECEIVE;
		return 0;
	}

	if (http_status != 200){
		#ifdef DEBUGERRORS
			InfoPrompt("http_status != 200");
		#endif
		return 0;
	}

	if(result) //Avoid ugly compiler warning :p
		result = HTTPR_OK;

	return sizeread;
}
Пример #8
0
Файл: main.c Проект: jkniiv/burp
static enum cliret do_client(struct conf *conf,
	enum action action, int vss_restore, int json)
{
	enum cliret ret=CLIENT_OK;
	int rfd=-1;
	int resume=0;
	SSL *ssl=NULL;
	SSL_CTX *ctx=NULL;
	struct cntr *cntr=NULL;
	char *incexc=NULL;
	long name_max=0;
	enum action act=action;
	struct async *as=NULL;
	struct asfd *asfd=NULL;

//	as->settimers(0, 100);

	logp("begin client\n");

	if(!(cntr=cntr_alloc()) || cntr_init(cntr, conf->cname)) goto error;
	conf->cntr=cntr;

	if(act!=ACTION_ESTIMATE
	  && ssl_setup(&rfd, &ssl, &ctx, conf))
		goto error;

	if(!(as=async_alloc())
	  || !(asfd=asfd_alloc())
	  || as->init(as, act==ACTION_ESTIMATE)
	  || asfd->init(asfd, as, rfd, ssl, conf))
		goto end;
	as->add_asfd(as, asfd);

	// Set quality of service bits on backup packets.
	if(act==ACTION_BACKUP
	  || act==ACTION_BACKUP_TIMED
	  || act==ACTION_TIMER_CHECK)
		as->asfd->set_bulk_packets(as->asfd);

	if(act!=ACTION_ESTIMATE)
	{
		if((ret=initial_comms(as, &act, &incexc, &name_max, conf)))
			goto end;
	}

	rfd=-1;
	switch(act)
	{
		case ACTION_BACKUP:
			ret=backup_wrapper(asfd, act, "backupphase1",
			  incexc, resume, name_max, conf);
			break;
		case ACTION_BACKUP_TIMED:
			ret=backup_wrapper(asfd, act, "backupphase1timed",
			  incexc, resume, name_max, conf);
			break;
		case ACTION_TIMER_CHECK:
			ret=backup_wrapper(asfd, act, "backupphase1timedcheck",
			  incexc, resume, name_max, conf);
			break;
		case ACTION_RESTORE:
		case ACTION_VERIFY:
			ret=restore_wrapper(asfd, act, vss_restore, conf);
			break;
		case ACTION_ESTIMATE:
			if(do_backup_client(asfd, conf, act, name_max, 0))
				goto error;
			break;
		case ACTION_DELETE:
			if(do_delete_client(asfd, conf)) goto error;
			break;
		case ACTION_LIST:
		case ACTION_LONG_LIST:
		default:
			if(do_list_client(asfd, conf, act, json)) goto error;
			break;
	}

	goto end;
error:
	ret=CLIENT_ERROR;
end:
	close_fd(&rfd);
	async_free(&as);
	asfd_free(&asfd);
	if(ctx) ssl_destroy_ctx(ctx);
	if(incexc) free(incexc);
	conf->cntr=NULL;
	if(cntr) cntr_free(&cntr);

        //logp("end client\n");
	return ret;
}
Пример #9
0
Файл: main.c Проект: scosu/burp
static enum cliret do_client(struct conf **confs,
	enum action action, int vss_restore)
{
	enum cliret ret=CLIENT_OK;
	int rfd=-1;
	SSL *ssl=NULL;
	SSL_CTX *ctx=NULL;
	struct cntr *cntr=NULL;
	char *incexc=NULL;
	enum action act=action;
	struct async *as=NULL;
	struct asfd *asfd=NULL;

//	as->settimers(0, 100);

//	logp("begin client\n");
//	logp("action %d\n", action);

	// Status monitor forks a child process instead of connecting to
	// the server directly.
	if(action==ACTION_STATUS
	  || action==ACTION_STATUS_SNAPSHOT)
	{
#ifdef HAVE_WIN32
		logp("Status mode not implemented on Windows.\n");
		goto error;
#endif
		if(status_client_ncurses_init(act)
		  || status_client_ncurses(confs)) ret=CLIENT_ERROR;
		goto end;
	}

	if(!(cntr=cntr_alloc())
	  || cntr_init(cntr, get_string(confs[OPT_CNAME]))) goto error;
	set_cntr(confs[OPT_CNTR], cntr);

	if(act!=ACTION_ESTIMATE
	  && ssl_setup(&rfd, &ssl, &ctx, action, confs))
		goto could_not_connect;

	if(!(as=async_alloc())
	  || !(asfd=asfd_alloc())
	  || as->init(as, act==ACTION_ESTIMATE)
	  || asfd->init(asfd, "main socket", as, rfd, ssl,
		ASFD_STREAM_STANDARD, confs))
			goto end;
	as->asfd_add(as, asfd);

	// Set quality of service bits on backup packets.
	if(act==ACTION_BACKUP
	  || act==ACTION_BACKUP_TIMED
	  || act==ACTION_TIMER_CHECK)
		as->asfd->set_bulk_packets(as->asfd);

	if(act!=ACTION_ESTIMATE)
	{
		if((ret=initial_comms(as, &act, &incexc, confs)))
			goto end;
	}

	rfd=-1;
	switch(act)
	{
		case ACTION_BACKUP:
			ret=backup_wrapper(asfd, act, "backupphase1",
			  incexc, confs);
			break;
		case ACTION_BACKUP_TIMED:
			ret=backup_wrapper(asfd, act, "backupphase1timed",
			  incexc, confs);
			break;
		case ACTION_TIMER_CHECK:
			ret=backup_wrapper(asfd, act, "backupphase1timedcheck",
			  incexc, confs);
			break;
		case ACTION_RESTORE:
		case ACTION_VERIFY:
			ret=restore_wrapper(asfd, act, vss_restore, confs);
			break;
		case ACTION_ESTIMATE:
			if(do_backup_client(asfd, confs, act, 0))
				goto error;
			break;
		case ACTION_DELETE:
			if(do_delete_client(asfd, confs)) goto error;
			break;
		case ACTION_MONITOR:
			if(do_monitor_client(asfd, confs)) goto error;
			break;
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
/*
			if(!strcmp(get_string(confs[OPT_BACKUP2]), "n"))
				// Do a phase1 scan and diff that.
				ret=backup_wrapper(asfd, act,
					"backupphase1diff", incexc, confs);
			else
*/
			// Diff two backups that already exist.
			// Fall through, the list code is all we need
			// for simple diffs on the client side.
		case ACTION_LIST:
		case ACTION_LIST_LONG:
		default:
			if(do_list_client(asfd, act, confs)) goto error;
			break;
	}

	if(asfd_flush_asio(asfd))
		ret=CLIENT_ERROR;

	goto end;
error:
	ret=CLIENT_ERROR; goto end;
could_not_connect:
	ret=CLIENT_COULD_NOT_CONNECT;
end:
	close_fd(&rfd);
	async_free(&as);
	asfd_free(&asfd);
	if(ctx) ssl_destroy_ctx(ctx);
	free_w(&incexc);
	set_cntr(confs[OPT_CNTR], NULL);
	cntr_free(&cntr);

	//logp("end client\n");
	return ret;
}