Beispiel #1
0
void SocketStreamHandle::privateReceive()
{
    SocketBuffer buffer;
    buffer.m_data = m_receive_buffer;

    // The downside of using curl_easy_recv is that it does a read on the socket with MSG_PEEK
    // before doing the real read each time (inside easy_connection) to see if the socket is still
    // connected.  This is extra unnecessary overhead.
    if (m_use_curl_easy_send_recv) {
        MutexLocker lock(m_close_mutex);
        m_curl_code = curl_easy_recv(m_curlHandle, buffer.m_data, receiveBufferSize, &buffer.m_size);
        if (m_curl_code == CURLE_AGAIN) {
            m_curl_code = CURLE_OK;
            return;
        }
    }
    else {
        MutexLocker lock(m_close_mutex);
        int nread = recv(m_socket, buffer.m_data, receiveBufferSize, 0);
        if (-1 == nread) {
            int error = WSAGetLastError();
            LOG_CONNECT(Network, "SocketStreamHandleCurl: privateReceive, error on recv (%d) [%p][thread=%d]\n", error, this, GetCurrentThreadId());
            // If we get WOULDBLOCK, then we can't read data now, so go back to the select loop.
            if (WSAEWOULDBLOCK == error)
                return;
            else
                m_curl_code = CURLE_RECV_ERROR;
        }
        else if (0 == nread) {
            // the remote side has closed the connection
            m_curl_code = CURLE_UNSUPPORTED_PROTOCOL;
        }
        else
            buffer.m_size = nread;
    }

    if (m_curl_code != CURLE_OK) {
        if (m_curl_code == CURLE_UNSUPPORTED_PROTOCOL) {
            LOG_CONNECT(Network, "SocketStreamHandleCurl: privateReceive, remote side closed connection [%p][thread=%d]\n", this, GetCurrentThreadId());
            sendMessageToMainThread(DidClose);
        }
        else {
            LOG_CONNECT(Network, "SocketStreamHandleCurl: privateReceive, error receiving data [%p][thread=%d]\n", this, GetCurrentThreadId());
            sendMessageToMainThread(DidFail);
        }
        return;
    }

    //LOG(Network, "SocketStreamHandleCurl: privateReceive, read %d bytes [%p][thread=%d]\n", buffer.m_size, this, GetCurrentThreadId()); // comment this
    MutexLocker lock(m_receive_buffer_mutex);
    m_receive_buffer = NULL;
    m_receive_buffers.append(buffer);
    if (m_receive_buffers.size() == 1) {
        //LOG(Network, "SocketStreamHandleCurl: privateReceive, received data [%p]\n", this); // comment this
        sendMessageToMainThread(DidReceiveData);
    }
}
Beispiel #2
0
//Fill the buffer, note that URL may be left in an unusable state on error!
CURLcode urlFetchData(URL_t *URL) {
    CURLcode rv;
    size_t len;

    if(URL->filePos != -1) URL->filePos += URL->bufLen;
    else URL->filePos = 0;

    rv = curl_easy_recv(URL->x.curl, URL->memBuf+URL->bufLen, URL->bufSize, &len);
    return rv;
}
Beispiel #3
0
bool k8s_http::on_data()
{
	size_t iolen = 0;
	char buf[1024] = { 0 };
	CURLcode ret;

	do
	{
		iolen = 0;
		try
		{
			check_error(ret = curl_easy_recv(m_curl, buf, 1024, &iolen));
		}
		catch(sinsp_exception& ex)
		{
			g_logger.log(std::string("Data receive error: ").append(ex.what()), sinsp_logger::SEV_ERROR);
			return false;
		}
		if(iolen > 0)
		{
			if(m_data_ready)
			{
				m_k8s.on_watch_data(k8s_event_data(k8s_component::get_type(m_component), buf, iolen));
			}
			else // wait for a line with "\r\n" only
			{
				std::string data(buf, iolen);
				std::string end = "\r\n\r\n";
				std::string::size_type pos = data.find(end);
				if(pos != std::string::npos)
				{
					pos += end.size();
					if(iolen == pos) // right on the edge of data
					{
						m_data_ready = true;
					}
					else
					{
						char* pbuf = &buf[pos];
						m_data_ready = true;
						m_k8s.on_watch_data(k8s_event_data(k8s_component::get_type(m_component), pbuf, iolen - pos));
					}
				}
			}
		}
		else if(ret != CURLE_AGAIN)
		{
			g_logger.log("Connection closed", sinsp_logger::SEV_ERROR);
			m_data_ready = false;
			return false;
		}
	} while(iolen && ret != CURLE_AGAIN);

	return true;
}
Beispiel #4
0
int curl_get(CURL *curl, const char *url){
  CURLcode res=curl_easy_perform(curl);
  FAIL_IF_NOT_EQUAL((int)res,0);
	if (res!=0){
		ONION_ERROR("%s",curl_easy_strerror(res));
	}
  long int http_code;
  res=curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &http_code);
  FAIL_IF_NOT_EQUAL((int)res,0);
  char buffer[1024]; size_t l;
  curl_easy_recv(curl,buffer,sizeof(buffer),&l);
  FAIL_IF_NOT_EQUAL_INT((int)http_code, HTTP_OK);

  return http_code;
}
Beispiel #5
0
static ssize_t curls_read(git_stream *stream, void *data, size_t len)
{
	int error;
	size_t read;
	CURLcode res;
	curl_stream *s = (curl_stream *) stream;

	do {
		if ((error = wait_for(s->socket, true)) < 0)
			return error;

		res = curl_easy_recv(s->handle, data, len, &read);
	} while (res == CURLE_AGAIN);

	if (res != CURLE_OK)
		return seterr_curl(s);

	return read;
}
Beispiel #6
0
static int progressCallback(void *arg,
                            double dltotal,
                            double dlnow,
                            double ultotal,
                            double ulnow)
{
  CURLcode res = 0;
  (void)arg;
  (void)dltotal;
  (void)dlnow;
  (void)ultotal;
  (void)ulnow;
  res = curl_easy_recv(curl, NULL, 0, NULL);
  printf("curl_easy_recv returned %d\n", res);
  res = curl_easy_send(curl, NULL, 0, NULL);
  printf("curl_easy_send returned %d\n", res);

  return 1;
}
Beispiel #7
0
STATIC gchar*
post_rest_form( CURL *curl, const form_field_t *form )
{
	gchar                      *url_host;
	gchar                      *url_path;
	gchar                      *headers;
	struct curl_write_buffer_t body            = { .data = NULL, .size = 0 };
	gchar                      content_length[ 10 ];
	gchar                      *html_post;
	GRegex                     *url_split_regex;
	GMatchInfo                 *match_info;

	long                       socket_value;
	curl_socket_t              socket;
	size_t                     bytes_sent;
	char                       response_buffer[ 1024 ];
	CURLcode                   status;
	size_t                     bytes_received;
	gboolean                   read_error;

		/* Split the form action URL into host and path. */
		url_split_regex = g_regex_new( "^http[s?]://([a-zA-Z0-9_\\.-]+)/(.*)$",
									   0, 0, NULL );
		if( g_regex_match( url_split_regex, form_action, 0, &match_info ) )
		{
			url_host = g_match_info_fetch( match_info, 1 );
			url_path = g_match_info_fetch( match_info, 2 );
			g_match_info_free( match_info );
			g_regex_unref( url_split_regex );

			/* Build the HTML post. */
			if( url_host != NULL )
			{
				/* Build the body. */
				if( form_name != NULL )
				{
					body.data = g_strconcat( form_name, "=", form_value, NULL );
					body.size = strlen( body.data );
				}
				g_slist_foreach( form->input_fields, fill_body_with_input,
								 &body );

				/* Build the headers. */
				g_sprintf( content_length, "%d\n\0", (gint) body.size );
				headers = g_strconcat(
					"POST ", url_path, " HTTP/1.1\n",
					"Host: ", url_host, "\n",
					"Content-Type: application/x-www-form-urlencoded\n",
					"Content-Length: ", content_length,
					NULL );
				g_free( url_path );
				g_free( url_host );

				/* Combine the headers and the body. */
				html_post = g_strconcat( headers, "\n", body.data, NULL );
				g_free( body.data );
				g_free( headers );

				printf( "DEBUG: Sending:\n-------\n%s-------", html_post );
				/* Prepare a connection. */
				curl_easy_setopt( curl, CURLOPT_URL, form_action );
				curl_easy_setopt( curl, CURLOPT_CONNECT_ONLY, 1 );
				curl_easy_perform( curl );
				curl_easy_getinfo( curl, CURLINFO_LASTSOCKET, &socket_value );
				socket = socket_value;
				/* Wait for the socket to become ready for sending. */
				if( wait_for_socket( socket, FALSE, 60000L ) == FALSE )
				{
					g_free( html_post );
					g_fprintf( stderr, "Timeout connecting to "
							   "the Google REST service\n" );
				}
				else
				{
					/* Submit the post. */
					curl_easy_send( curl, html_post, strlen( html_post ),
									&bytes_sent );
					/* To do: verify that all the bytes were sent; if not,
					   send the remainding bytes in a second, third, ...
					   call. */
					printf( "DEBUG: Sent %d out of %d bytes\n", (int)bytes_sent, (int) strlen(html_post) );
					g_free( html_post );

					/* Receive the response. */
					read_error = FALSE;
					do
					{
						/* Wait for the socket to become ready for receiving. */
						if( wait_for_socket( socket, TRUE, 60000L ) == FALSE )
						{
							read_error = TRUE;
							g_fprintf( stderr, "Timeout connecting to "
									   "the Google REST service\n" );
							break;
						}
						/* Copy chunks of data into html_response. */
						else
						{
							status = curl_easy_recv( curl, response_buffer,
													 sizeof( response_buffer ),
													 &bytes_received );
							if( status == CURLE_OK )
							{
								receive_curl_response( response_buffer,
													   bytes_received, 1,
													   &html_response );
							}
						}
					} while( ( status == CURLE_AGAIN ) &&
							 ( read_error == FALSE ) );
					printf( "DEBUG: CURL code %d: %s\n", (int)status, curl_easy_strerror( status ) );
				}
			}
		}
}
#endif



#if 0
/**
 * Auxiliary function used by decode_user_code_response to copy a JSON
 * response into a local data structure.
 * @param node [in] Object with JSON data (unused).
 * @param member_name [in] Name of the JSON field.
 * @param member_node [in] Node with JSON data.
 * @param user_code_ptr [out] Pointer to the structure where the JSON
 *        data will be stored.
 * @return Nothing.
 */
STATIC void
parse_user_code_json( const gchar *member_name,
					  JsonNode *member_node, gpointer user_code_ptr )
{
	struct user_code_t *user_code = user_code_ptr;

	SET_JSON_MEMBER( user_code, device_code );
	SET_JSON_MEMBER( user_code, verification_url );
	SET_JSON_MEMBER( user_code, user_code );
}
#endif




/**
 * Decode the initial OAuth2 response with device code, user code, and
 * verification URL.
 * @param user_code_response [in] Raw JSON response data.
 * @return \a user_code_t structure with authentication data, or \a FALSE
 *         if the user code could not be obtained.
 */
#if 0
STATIC struct user_code_t*
decode_user_code_response( const gchar *user_code_response )
{
	struct user_code_t *user_code;

	user_code = g_new0( struct user_code_t, 1 );

	if( user_code_response != NULL )
	{
		/* Decode the JSON response. */
		decode_json_reply( user_code_response, parse_user_code_json,
						   user_code );
		/* Verify that all fields have been decoded. */
		if( ( user_code->device_code == NULL ) ||
			( user_code->user_code == NULL ) ||
			( user_code->verification_url == NULL ) )
		{
			g_free( (gchar*) user_code->device_code );
			g_free( (gchar*) user_code->user_code );
			g_free( (gchar*) user_code->verification_url );
			g_free( user_code );
			user_code = NULL;
		}
	}

	return( user_code );
}
#endif



/**
 * Obtain a device code for device access.  The CURL session must include the
 * user's login to Google, which may be obtained by calling \a login_to_gmail
 * with the user's credentials.
 * @param curl [in] CURL handle.
 * @param client_id [in] Google Developer Client ID.
 * @return Device code or \a NULL if an error occurred.
 * Test: manual (via non-automated test).
 */
struct user_code_t*
obtain_device_code( CURL *curl, const gchar *client_id )
{
	/* Note: the following code is more elegant than the code that is
	   currently used but is disabled because a bug in Google's API system
	   prevents devices from using the tasks scope. */
#if 0
	static gchar *form_action = 
		"https://accounts.google.com/o/oauth2/device/code";
	gchar *scope =
//		"https://www.googleapis.com/auth/userinfo.email "
//	    "https://www.googleapis.com/auth/userinfo.profile";
	    "https://www.googleapis.com/auth/tasks";
	form_field_t       form = { .name         = NULL,
								.value        = NULL,
								.action       = form_action,
								.input_fields = NULL };
	gchar              *user_code_response;
	struct user_code_t *user_code;
	gboolean           success;

	/* Create a user code request. */
	add_input_to_form( &form, "client_id", client_id );
	add_input_to_form( &form, "scope", scope );

	/* Post the request and decode the response. */
	user_code_response = post_form( curl, &form );
	destroy_form_inputs( &form );
	g_printf( "%s\n", user_code_response );
	user_code = decode_user_code_response( user_code_response );
	return( user_code );
#endif
}




STATIC gboolean
submit_approval_form( CURL *curl, const gchar *approval_page )
{
	form_field_t       *approval_form;
	const gchar *const approval_names[ ] = { "submit_access", NULL };
	gchar              *form_response;
	gboolean           success;

	approval_form = find_form( approval_page,
						"https://accounts.google.com/o/oauth2/",
					    approval_names );
	if( approval_form != NULL )
	{
		g_printf( "Submitting approval form\n" );

		/* Submit the approval form. */
		form_response = post_form( curl, approval_form );

		destroy_form( approval_form );
		g_free( form_response );
		success = TRUE;
	}
	else
	{
		success = FALSE;
	}

	return( success );
}
Beispiel #8
0
int test(char *URL)
{
  CURLcode res;
  CURL *curl;

  if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  test_setopt(curl, CURLOPT_URL, URL);
  test_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
  test_setopt(curl, CURLOPT_VERBOSE, 1L);

  res = curl_easy_perform(curl);

  if(!res) {
    /* we are connected, now get a HTTP document the raw way */
    const char *request =
#ifdef CURL_DOES_CONVERSIONS
      /* ASCII representation with escape sequences for non-ASCII platforms */
      "\x47\x45\x54\x20\x2f\x35\x35\x36\x20\x48\x54\x54\x50\x2f\x31\x2e"
      "\x32\x0d\x0a\x48\x6f\x73\x74\x3a\x20\x6e\x69\x6e\x6a\x61\x0d\x0a"
      "\x0d\x0a";
#else
      "GET /556 HTTP/1.2\r\n"
      "Host: ninja\r\n\r\n";
#endif
    size_t iolen;

    res = curl_easy_send(curl, request, strlen(request), &iolen);

    if(!res) {
      /* we assume that sending always work */

      do {
        char buf[1024];
        /* busy-read like crazy */
        res = curl_easy_recv(curl, buf, sizeof(buf), &iolen);

#ifdef TPF
        sleep(1); /* avoid ctl-10 dump */
#endif

        if(iolen) {
          /* send received stuff to stdout */
          if(!write(STDOUT_FILENO, buf, iolen))
            break;
        }

      } while((res == CURLE_OK && iolen != 0) || (res == CURLE_AGAIN));
    }

    if(iolen != 0)
      res = TEST_ERR_FAILURE;
  }

test_cleanup:

  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return (int)res;
}
int parseProcessNextPushNotification(ParseClient client)
{
    ParseClientInternal *clientInternal = getClient(client);
    if (clientInternal->pushCurlHandle != NULL) {
        size_t read = 0;;
        int length = -1;
        int start = 0;
        char* message = NULL;

        while (length == -1 && parse_push_message_size < sizeof(parse_push_message_buffer)) {
            CURLcode result = curl_easy_recv(clientInternal->pushCurlHandle,
                                             parse_push_message_buffer + parse_push_message_size,
                                             sizeof(parse_push_message_buffer) - parse_push_message_size,
                                             &read);
            if (result == CURLE_OK) {
                parseLog(PARSE_LOG_INFO, "got ok!\n");
                parse_push_message_size += read;
                message = (char *)getPushJson(parse_push_message_buffer,
                                              parse_push_message_size,
                                              &start,
                                              &length);
            } else if (result == CURLE_AGAIN) {
                break;
            } else {
                parseLog(PARSE_LOG_ERROR, "curl_easy_recv read %i an error %s\n", length, curl_easy_strerror(result));
                if (clientInternal->pushCallback != NULL) {
                    clientInternal->pushCallback(client, ECONNRESET, NULL);
                }
                return 0;
            }
        }
        if (length == -1 && parse_push_message_size == sizeof(parse_push_message_buffer)) {
            // this message is bigger than the buffer, we need to drop it :-(
            parse_push_message_size = 0;
            return 0;
        }

        parseLog(PARSE_LOG_INFO, "message = %p, start = %i, length = %i\n", message, start, length);

        if (length > 0 && message != NULL) {

            message[length] = '\0'; // We assume messages are separated by '\n'.
            parseLog(PARSE_LOG_INFO, "message = '%s'\n", message);

            char time[32];
            if (simpleJsonProcessor(message, "time", time, sizeof(time))) {
                if (clientInternal->lastPushTime) {
                    free(clientInternal->lastPushTime);
                }
                clientInternal->lastPushTime = strdup(time);
                parseOsStoreKey(clientInternal->applicationId, PARSE_LAST_PUSH_TIME, time);
                parseLog(PARSE_LOG_INFO, "lastPush = '%s'\n", clientInternal->lastPushTime);
            }
            if (strncmp("{}", message, 2) == 0) {
                // we got a hearbeat back
                parseLog(PARSE_LOG_DEBUG, "got heartbeat\n");
            } else if (clientInternal->pushCallback != NULL) {
                clientInternal->pushCallback(client, 0, message);
            }
            parse_push_message_size -= length + 1;
            if (parse_push_message_size > 0) {
                memmove(parse_push_message_buffer, parse_push_message_buffer + length + 1, parse_push_message_size);
            }

            return (parse_push_message_size > 0) ? 1 : 0;
        }

        unsigned int seconds = secondsSinceBoot();
        if (seconds > clientInternal->lastHearbeat + PARSE_HEARTBIT_INTERVAL_SECONDS) {
            clientInternal->lastHearbeat = seconds;
            size_t sent;
            curl_easy_send(clientInternal->pushCurlHandle, "{}\n", 3, &sent);
        }
    }
    return 0;
}
Beispiel #10
0
void SocketManageFunction()
{
	std::list<CRequest *>::iterator eSocket = requestSocketQueue.end();
	std::list<CRequest *>::iterator iSocket = requestSocketQueue.begin();

	for ( ; iSocket != eSocket; iSocket++ )
	{
		// remove canceled request
		if ( iSocket != eSocket && (*iSocket)->GetRequestStatus() == RSCancel )
		{
			DecrementRequestCount((*iSocket)->GetMethodHttp());
			CRequest *toRemove = (*iSocket);
			iSocket = requestSocketQueue.erase(iSocket);
            delete toRemove;
			if (iSocket == eSocket) break;
		}

		if ( ( (*iSocket)->GetRequestStatus() == RSSend || 
				(*iSocket)->GetRequestStatus() == RSReady ||
				(*iSocket)->GetRequestStatus() == RSOpen) && 
				(*iSocket)->GetMethodHttp() == MethodSocket )
		{
			CURLcode code;
			size_t iolen;
			long socketExtract;
			bool shouldBeHandled = true;

			if ( (*iSocket)->GetRequestStatus() == RSReady)
			{
					
				if (g_actualSocketRequestsCount >= MAX_SOCKET_REQUESTS)
				{
					shouldBeHandled = false;
				}
				if (shouldBeHandled)
				{
					code = curl_easy_perform((*iSocket)->GetCurl());
 
					if (code != CURLE_OK)
					{
						printf("Error: Socket Perform : %s\n", curl_easy_strerror(code));
						(*iSocket)->SendErrorByCallback(ErrorSocketPerform, code);
						continue; 
					}
					IncrementRequestCount((*iSocket)->GetMethodHttp());
					(*iSocket)->SetStatusSend();	// hould be RSOpen or RSSend?????????
				}
					
			}
			if (shouldBeHandled)
			{
				code = curl_easy_getinfo( (*iSocket)->GetCurl(), CURLINFO_LASTSOCKET, &socketExtract);
				
				if (code != CURLE_OK)
				{
					printf("Error: %ld\n", socketExtract);
					printf("Error: %s\n", curl_easy_strerror(code));
					(*iSocket)->SendErrorByCallback(ErrorSocketGetInfo, code);
					continue;
				}
				if ( (*iSocket)->GetRequestStatus() == RSSend )
				{

					(*iSocket)->SetSocket(socketExtract);
					
					if ( !(*iSocket)->WaitOnSocket( (*iSocket)->GetSocket(), 0, 0L) )
					{
						printf("Error: Socket timeout.\n");
						(*iSocket)->SendErrorByCallback(ErrorSocketTimeout);
						continue;
					}

					code = curl_easy_send( (*iSocket)->GetCurl(), (*iSocket)->GetData(), (*iSocket)->GetDataLength(), &iolen);

					if ( (*iSocket)->GetDataLength() > iolen)
					{
						printf("Warning: Not all sended in easy_send for socket.\n");
						(*iSocket)->SendErrorByCallback(ErrorSocketWarningNotAllSend, code);
					}
					(*iSocket)->SetStatusOpen();
				}
				
				char buf[1024];
				
				(*iSocket)->WaitOnSocket( (*iSocket)->GetSocket(), 1, 0L);
				code = curl_easy_recv( (*iSocket)->GetCurl(), buf, 1024, &iolen);
 
				if (code == CURLE_AGAIN)
				{
					//printf("No data on socket.");

					// One of possible solutions is to call curl_easy_recv in loop and
					// resize buf if iolen == buf length till socket is empty and then 
					// send buf with all data
				}

				if (code == CURLE_OK)
				{
					curl_off_t nread;
					nread = (curl_off_t)iolen;

					(*iSocket)->SetDownloadedDataBySocket(buf, nread);
					(*iSocket)->SetSuccess();
					//printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n", nread);

					// send to callback this data 
				}
			}
		}
	}
}
Beispiel #11
0
int main(void)
{
  CURL *curl;
  CURLcode res;
  /* Minimalistic http request */
  const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
  curl_socket_t sockfd; /* socket */
  long sockextr;
  size_t iolen;
  curl_off_t nread;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
    /* Do not do the transfer - only connect to host */
    curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
    res = curl_easy_perform(curl);

    if(CURLE_OK != res)
    {
      printf("Error: %s\n", strerror(res));
      return 1;
    }

    /* Extract the socket from the curl handle - we'll need it for waiting.
     * Note that this API takes a pointer to a 'long' while we use
     * curl_socket_t for sockets otherwise.
     */
    res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);

    if(CURLE_OK != res)
    {
      printf("Error: %s\n", curl_easy_strerror(res));
      return 1;
    }

    sockfd = sockextr;

    /* wait for the socket to become ready for sending */
    if(!wait_on_socket(sockfd, 0, 60000L))
    {
      printf("Error: timeout.\n");
      return 1;
    }

    puts("Sending request.");
    /* Send the request. Real applications should check the iolen
     * to see if all the request has been sent */
    res = curl_easy_send(curl, request, strlen(request), &iolen);

    if(CURLE_OK != res)
    {
      printf("Error: %s\n", curl_easy_strerror(res));
      return 1;
    }
    puts("Reading response.");

    /* read the response */
    for(;;)
    {
      char buf[1024];

      wait_on_socket(sockfd, 1, 60000L);
      res = curl_easy_recv(curl, buf, 1024, &iolen);

      if(CURLE_OK != res)
        break;

      nread = (curl_off_t)iolen;

      printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n", nread);
    }

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return 0;
}
Beispiel #12
0
void spider(void *pack,char *line,char * pathtable)
{
	struct MemoryStruct chunk;
	FILE *fp=NULL;
	bool match_string=false,save_response=false,test_tamper=false;
	long status=0,length=0;
	int old=0,res=0,counter=0,counter_cookie=0,counter_agent=0,POST=0,timeout=0,debug_host=3; 
	char *make=NULL,*make_cookie=NULL,*make_agent=NULL,*tamper=NULL,*responsetemplate=NULL,*tmp_response=NULL,*tmp_make=NULL,*tmp_make_cookie=NULL,*tmp_make_agent=NULL,*tmp_line=NULL,*tmp_line2=NULL;
	char **pack_ptr=(char **)pack,**arg = pack_ptr;
	char randname[16],line2[1024],log[2048],tabledata[4086],pathsource[1024];

	if(arg[12]!=NULL)
		save_response=true;

	if(arg[8]!=NULL)
		timeout=atoi(arg[8]);


// payload tamper 
	if(arg[20]!=NULL)
	{
		tamper=arg[20];
			
		if(strstr(tamper,"encode64"))
		{
			line=encode64(line,strlen(line)-1);
			test_tamper=true;
		}

		if(strstr(tamper,"randcase"))
		{
			line=rand_case(line);
			test_tamper=true;
		}


		if(strstr(tamper,"urlencode"))
		{
			line=urlencode(line);
			test_tamper=true;
		}

		if(strstr(tamper,"double_urlencode"))
		{
			line=double_urlencode(line);
			test_tamper=true;
		}

		if(strstr(tamper,"spaces2comment"))
		{
			line=spaces2comment(line);
			test_tamper=true;
		}

		if(strstr(tamper,"unmagicquote"))
		{
			line=unmagicquote(line);
			test_tamper=true;
		}


		if(strstr(tamper,"apostrophe2nullencode"))
		{
			line=apostrophe2nullencode(line);
			test_tamper=true;
		}

		if(strstr(tamper,"rand_comment"))
		{
			line=rand_comment(line);
			test_tamper=true;
		}



		if(strstr(tamper,"rand_space"))
		{
			line=rand_space(line);
			test_tamper=true;
		}


		if(test_tamper==false)
		{
			DEBUG("error at tamper argument\n");
			exit(0);
		}

		
	}


		

	memset(pathsource,0,sizeof(char)*1023);

	if(save_response==false)
	{
		strcat(pathsource,"0");
	}

// brute POST/GET/COOKIES/UserAgent
	if(arg[21]==NULL)
	{
		POST=(arg[4]==NULL)?0:1;
		counter=char_type_counter(POST?arg[4]:arg[0],'^');
		counter_cookie=char_type_counter(arg[13]!=NULL?arg[13]:"",'^');
		counter_agent=char_type_counter(arg[19]!=NULL?arg[19]:"",'^');
		old=counter;  
	} else {
		char *file_request=readLine(arg[21]);
		counter=char_type_counter(file_request,'^');
		old=counter;
		xfree((void**)&file_request);

	}
	chomp(line);

// goto to fix signal stop if user do ctrl+c
	try_again:

	while ( old > 0 || counter_cookie > 0  || counter_agent > 0 )
	{

		CURL *curl;  
//		curl_global_init(CURL_GLOBAL_ALL); 

		chunk.memory=NULL; 
		chunk.size = 0;  

		curl_socket_t sockfd; /* socket */
		long sockextr;
		size_t iolen;


		curl = curl_easy_init();
// DEBUG("counts ^ : %d \n",old);	
		

		if(arg[21]==NULL)
		{
			make=payload_injector( (POST?arg[4]:arg[0]),line,old);
		 		
			if(arg[13]!=NULL)
				make_cookie=payload_injector( arg[13],line,counter_cookie);	
	
			if(arg[19]!=NULL)
				make_agent=payload_injector( arg[19],line,counter_agent);

			curl_easy_setopt(curl,  CURLOPT_URL, POST?arg[0]:make);
		} else {
// if is custom request
			char *request_file=readLine(arg[21]);
			make=payload_injector( request_file,line,old);	
			curl_easy_setopt(curl,  CURLOPT_URL, arg[0]);
			xfree((void**)&request_file);
		}	
 
		if ( POST )
			curl_easy_setopt(curl, CURLOPT_POSTFIELDS, make);
      
		curl_easy_setopt(curl,  CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
		curl_easy_setopt(curl,  CURLOPT_WRITEDATA, (void *)&chunk);

// load user agent     
		if ( arg[6]!=NULL )
		{
			curl_easy_setopt(curl,  CURLOPT_USERAGENT, arg[6]);
		} else {
			curl_easy_setopt(curl,  CURLOPT_USERAGENT, "Mozilla/5.0 (0d1n v0.1) ");
		}

// json headers to use JSON

		if(arg[14]!=NULL)
		{
			struct curl_slist *headers = NULL;
			curl_slist_append(headers, arg[14]);
			if(arg[16]!=NULL)
			{
				curl_slist_append(headers, "Accept: application/json");
				curl_slist_append(headers, "Content-Type: application/json");
			}
			curl_easy_setopt(curl,  CURLOPT_HTTPHEADER, headers);
			curl_slist_free_all(headers);
		} else {
			if(arg[16] != NULL)
			{
				struct curl_slist *headers = NULL;

				curl_slist_append(headers, "Accept: application/json");
				curl_slist_append(headers, "Content-Type: application/json");
				curl_easy_setopt(curl,  CURLOPT_HTTPHEADER, headers);
				curl_slist_free_all(headers);
			}
		}
	
//use custom method PUT,DELETE...
		if(arg[15]!=NULL)
		{
			curl_easy_setopt(curl,  CURLOPT_CUSTOMREQUEST, arg[15]);
		}
 
		curl_easy_setopt(curl,  CURLOPT_ENCODING,"gzip,deflate");

// load cookie jar
		if ( arg[3] != NULL )
		{
			curl_easy_setopt(curl,CURLOPT_COOKIEFILE,arg[3]);
			curl_easy_setopt(curl,CURLOPT_COOKIEJAR,arg[3]);
		} else {
			curl_easy_setopt(curl,CURLOPT_COOKIEJAR,"odin_cookiejar.txt");
		}
// LOAD cookie fuzz

		if(arg[13]!=NULL)
		{
			curl_easy_setopt(curl,CURLOPT_COOKIE,make_cookie);
		}


// LOAD UserAgent FUZZ
		if(arg[19]!=NULL)
		{
			curl_easy_setopt(curl,CURLOPT_USERAGENT,make_agent);
		}


		curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1);
// Load cacert
		if ( arg[7] != NULL ) 
		{
			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
			curl_easy_setopt(curl, CURLOPT_CAINFO, arg[7]);
		} else {

			curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L); 
			curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,0L); 
		}

		if(timeout) 
			curl_easy_setopt(curl,CURLOPT_TIMEOUT,timeout); 

// load single proxy
		if(arg[17] != NULL)
		{
			curl_easy_setopt(curl, CURLOPT_PROXY, arg[17]);
	//		curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1);
		}

// load random proxy in list 
		if(arg[18] != NULL)
		{
			char *randproxy=Random_linefile(arg[18]);
	//		printf("PROXY LOAD: %s\n",randproxy);
			curl_easy_setopt(curl, CURLOPT_PROXY, randproxy);
	//		curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1);
		}


		if ( arg[9] != NULL ) 
			curl_easy_setopt(curl,CURLOPT_SSLVERSION,(long)atoi(arg[9]));

                curl_easy_setopt(curl,CURLOPT_VERBOSE,0); 
		curl_easy_setopt(curl,CURLOPT_HEADER,1);  
		
		if(arg[21]!=NULL)
		{
			curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
		}
		res=curl_easy_perform(curl);
		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,&status);

// custom http request
		if(arg[21]!=NULL)
		{
			curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr); 
			sockfd = sockextr;

			if(!wait_on_socket(sockfd, 0, 60000L))
			{
				DEBUG("error in socket at custom http request");
			}
			res=curl_easy_send(curl, make, strlen(make), &iolen);
// recv data
			while(1)
			{
				wait_on_socket(sockfd, 1, 60000L);
				chunk.memory=xmalloc(sizeof(char)*3024); 
				res = curl_easy_recv(curl, chunk.memory, 3023, &iolen); 
				chunk.size=strlen(chunk.memory);				

				if(strlen(chunk.memory) > 8)
					break;

			        if(CURLE_OK != res)
        				break;

			}

			
			status=(long)parse_http_status(chunk.memory);
//status=404;
		}

			

// length of response
		if(chunk.size<=0)
			length=0.0;
		else
			length=chunk.size;

		
		if(status==0)
		{	
			debug_host--;
			DEBUG("Problem in Host: \n %s",chunk.memory);
			if(debug_host<0)
				exit(0);
		
			goto try_again;
		
		}


// arg[10]  list to find with regex , arg[2] list without regex
		if(  (arg[2]) || (arg[10])  )
		{
			if(save_response==true)
			{
				memset(pathsource,0,sizeof(char)*1023);
			}

			fp = fopen((arg[2]!=NULL)?arg[2]:arg[10], "r");

			if ( !fp )
			{ 
				DEBUG("error to open response list"); 
				exit(1);
			}

			while ( fgets(line2,1023,fp) != NULL) 
			{
				chomp(line2);

// find a string in response
				if(status != 0)
				{
					if ( arg[2] != NULL )
						match_string=strstr(chunk.memory,line2)?true:false;

					if ( arg[10] != NULL )
						match_string=strstr_regex(chunk.memory,line2)?true:false;
				}

				if(chunk.memory && (match_string == true) ) 
				{
					if(make_cookie!=NULL)
					{
						fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Grep: %s %s %s  Params: %s \nCookie: %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,line2,YELLOW,make,make_cookie,LAST);
					} 

					if(make_agent!=NULL)
					{
						fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Grep: %s %s %s  Params: %s \nCookie: %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,line2,YELLOW,make,make_agent,LAST);
					
					} else {

						fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Grep: %s %s %s  Params: %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,line2,YELLOW,make,LAST);
					
					}

					if(save_response==true)
					{
// create responses path
						memset(pathsource,0,sizeof(char)*1023);
						strncat(pathsource,"response_sources/",18);
						strncat(pathsource,arg[5], 15);
						mkdir(pathsource,S_IRWXU|S_IRWXG|S_IRWXO);
						snprintf(pathsource,986,"response_sources/%s/%s.html",arg[5],rand_str(randname, sizeof randname));
					}
// write log file
					snprintf(log,2047,"[ %ld ] Payload: %s  Grep: %s Params: %s cookie: %s  UserAgent: %s \n Path Response Source: %s\n",status,line,line2,make,(make_cookie!=NULL)?make_cookie:" ",(make_agent!=NULL)?make_agent:" ",pathsource);
					WriteFile(arg[5],log);
					memset(log,0,2047);		

					if(save_response==true)
					{
// write highlights response
						responsetemplate=NULL;
                				responsetemplate=readLine(TEMPLATE);
						WriteFile(pathsource,responsetemplate);
						memset(responsetemplate,0,strlen(responsetemplate)-1);
						tmp_response=NULL;
						tmp_response=html_entities(chunk.memory);
						WriteFile(pathsource,tmp_response);
						memset(tmp_response,0,strlen(tmp_response)-1);
						WriteFile(pathsource,"</pre></html>");
					}
// create datatables	
				
					tmp_make=html_entities(make);
					tmp_line2=html_entities(line2);
					tmp_line=html_entities(line);

					if(make_cookie!=NULL)
					{
						tmp_make_cookie=html_entities(make_cookie);
						snprintf(tabledata,4085,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s cookie: %s\",\"%s\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_make_cookie,tmp_line2,tmp_line);
						memset(tmp_make_cookie,0,strlen(tmp_make_cookie)-1);
					}

					if(make_agent!=NULL)
					{
						tmp_make_agent=html_entities(make_agent);
						snprintf(tabledata,4085,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s UserAgent: %s\",\"%s\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_make_agent,tmp_line2,tmp_line);
						memset(tmp_make_agent,0,strlen(tmp_make_agent)-1);
					} else {
						snprintf(tabledata,4085,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s\",\"%s\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_line2,tmp_line);
      					}

					WriteFile(pathtable,tabledata);
				//	memset(tmp_make,0,strlen(tmp_make)-1);
				//	memset(tmp_make_cookie,0,strlen(tmp_make_cookie)-1);
				//	memset(tmp_make_agent,0,strlen(tmp_make_agent)-1);
					memset(tmp_line,0,strlen(tmp_line)-1);
					memset(tmp_line2,0,strlen(tmp_line2)-1);
					memset(tabledata,0,4085);
					memset(pathsource,0,strlen(pathsource)-1);


				}
			}
 
			
			if( fclose(fp) == EOF )
			{
				DEBUG("Error in close()");
				exit(1);
			}

			
			fp=NULL;

		} else {

			if(counter_cookie)
			{
				fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Params: %s %s\n Cookie: %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,make,make_cookie,LAST);
			}
			if(counter_agent)
			{
				fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Params: %s %s\n UserAgent: %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,make,make_agent,LAST);
			} else {
				fprintf(stdout,"%s [ %s %ld %s ] Payload: %s %s %s Params: %s %s %s\n",YELLOW,CYAN,status,YELLOW,GREEN,line,YELLOW,CYAN,make,LAST);
			}
	
			if(save_response==true)
			{		
			//	memset(pathsource,0,sizeof(char)*1023);
				strncat(pathsource,"response_sources/",18);
				strncat(pathsource,arg[5], 15);
				mkdir(pathsource,S_IRWXU|S_IRWXG|S_IRWXO);
				snprintf(pathsource,986,"response_sources/%s/%s.html",arg[5],rand_str(randname, sizeof randname));
			}
//write logs
			snprintf(log,2047,"[%ld Payload: %s Params: %s Cookie: %s UserAgent: %s \n Path Response Source: %s\n",status,line,make,(make_cookie!=NULL)?make_cookie:" ",(make_agent!=NULL)?make_agent:" ",pathsource);
			WriteFile(arg[5],log);
			memset(log,0,2047);

			if(save_response==true)
			{
// write response source with highlights
              	 		responsetemplate=readLine(TEMPLATE);
				WriteFile(pathsource,responsetemplate);
				//memset(responsetemplate,0,strlen(responsetemplate)-1);
				tmp_response=html_entities(chunk.memory);
				WriteFile(pathsource,tmp_response);
				//memset(tmp_response,0,strlen(tmp_response)-1);
	
				WriteFile(pathsource,"</pre></html>");
			}
// create datatables
			tmp_make=html_entities(make);
			tmp_line=html_entities(line);

			if(counter_cookie)
			{
				
				tmp_make_cookie=html_entities(make_cookie);
				snprintf(tabledata,4085,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s  cookie: %s\",\"\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_make_cookie,tmp_line);
			//	memset(tmp_make_cookie,0,strlen(tmp_make_cookie)-1);
			}

			if(counter_agent)
			{
				
				tmp_make_agent=html_entities(make_agent);
				snprintf(tabledata,4085,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s  UserAgent: %s\",\"\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_make_agent,tmp_line);

			} else {
				snprintf(tabledata,4047,"[\"<a class=\\\"fancybox fancybox.iframe\\\" href=\\\"../%s\\\">%ld </a>\",\"%ld\",\"%s\",\"\",\"%s\"],\n",pathsource,status,length,tmp_make,tmp_line);
			}
  			WriteFile(pathtable,tabledata);
			memset(tmp_make,0,strlen(tmp_make)-1);
			memset(tmp_line,0,strlen(tmp_line)-1);
			memset(tabledata,0,4085);
			memset(pathsource,0,strlen(pathsource)-1);

//DEBUG("part B");

		}

//DEBUG("END PARTS");
//		memset(make,0,strlen(make)-1);
//		memset(make_cookie,0,strlen(make_cookie)-1);
//		memset(make_agent,0,strlen(make_agent)-1);
//		memset(pathsource,0,strlen(pathsource)-1);
		xfree((void **)&chunk.memory);
	
	//	curl_easy_cleanup(curl);
       // 	curl_global_cleanup();

		if(old>0)
			old--;

		if(counter_cookie > 0)
			counter_cookie--;

		if(counter_agent > 0)
			counter_agent--;

		debug_host=3;

	
	
	}

	xfree((void **)&make_agent);
	xfree((void **)&make_cookie);
	xfree((void **)&make);
	xfree((void **)&tmp_make);
	xfree((void **)&tmp_make_cookie);
	xfree((void **)&tmp_make_agent); 
	xfree((void **)&tmp_line);
	xfree((void **)&tmp_line2);
	xfree((void **)&responsetemplate);
	xfree((void **)&tmp_response);

	if(arg[20] != NULL)
		xfree((void **)&line);
//	DEBUG("GOOO3");
 
}
Beispiel #13
0
void HSocket::tickReceive(float INdt) {    
    curl_socket_t socketHandle;
    CURLcode code = curl_easy_getinfo(m_curl, CURLINFO_LASTSOCKET, &socketHandle);
    if (code != CURLE_OK) {
        CCLOG("socketExt error: %s", curl_easy_strerror(code));
        Director::getInstance()->getScheduler()->unschedule(schedule_selector(HSocket::tickReceive), this);
        if (m_delegate) {
            m_delegate->callbackDisconnected();
        }
        return;
    }
    if (socketHandle == CURL_SOCKET_BAD) {
        Director::getInstance()->getScheduler()->unschedule(schedule_selector(HSocket::tickReceive), this);
        if (m_delegate) {
            m_delegate->callbackDisconnected();
        }
        return;
    }
    memset(_bufTemp, 0, MAX_BUFFER_LENGTH);
    size_t ioLen;
    code = curl_easy_recv(m_curl, _bufTemp, MAX_BUFFER_LENGTH, &ioLen);
    if (code != CURLE_OK && code != CURLE_AGAIN) {
        CCLOG("recv error: %s", curl_easy_strerror(code));
        Director::getInstance()->getScheduler()->unschedule(schedule_selector(HSocket::tickReceive), this);
        if (m_delegate) {
            m_delegate->callbackDisconnected();
        }
        return;
    }
    if (ioLen == 0) {
        return;
    }
    size_t indexA = 0;
    while (true) {
        uint16_t bufferLengthPacket = 0;
        if (m_bufferLengthReceived > 1) {
            bufferLengthPacket = ntohs(*((uint16_t*)m_buffer));
            CCLOG("%d---", bufferLengthPacket);
            if (m_bufferLengthReceived + ioLen >= bufferLengthPacket) {
                size_t lenUsed = bufferLengthPacket - m_bufferLengthReceived;
                memcpy(m_buffer + m_bufferLengthReceived, _bufTemp + indexA, lenUsed);
                if (m_delegate) {
                    auto packet = _packetFactory->createPacket(m_buffer + 2, bufferLengthPacket - 2);
                    m_delegate->callbackReceived(packet);
                }
                memmove(m_buffer, m_buffer + bufferLengthPacket, MAX_BUFFER_LENGTH - bufferLengthPacket);
                m_bufferLengthReceived = 0;
                ioLen -= lenUsed;
                indexA += lenUsed;
            }
            else {
                memcpy(m_buffer + m_bufferLengthReceived, _bufTemp + indexA, ioLen);
                m_bufferLengthReceived += ioLen;
                break;
            }
        }
        else {
            if (m_bufferLengthReceived + ioLen > 1) {
                size_t lenUsed = 2 - m_bufferLengthReceived;
                memcpy(m_buffer + m_bufferLengthReceived, _bufTemp + indexA, lenUsed);
                m_bufferLengthReceived += lenUsed;
                ioLen -= lenUsed;
                indexA += lenUsed;
            }
            else {
                memcpy(m_buffer + m_bufferLengthReceived, _bufTemp + indexA, ioLen);
                m_bufferLengthReceived += ioLen;
                break;
            }
        }
    }
}
Beispiel #14
0
int _qvd_switch_protocols(qvdclient *qvd, int id)
{
  fd_set myset, zero;
  size_t bytes_sent, bytes_received, bytes_received_total;
  int socket, i, content_length, content_size_parsed;
  char url[MAX_BASEURL];
  char base64auth[MAX_PARAM];
  char *ptr, *content;

  _qvd_use_client_cert(qvd);
  curl_easy_setopt(qvd->curl, CURLOPT_URL, qvd->baseurl);
  curl_easy_setopt(qvd->curl, CURLOPT_CONNECT_ONLY, 1L);
  curl_easy_perform(qvd->curl);
  curl_easy_getinfo(qvd->curl, CURLINFO_LASTSOCKET, &socket);

  /*  if (snprintf(url, MAX_BASEURL, "GET /qvd/connect_to_vm?id=%d&qvd.client.os=%s&qvd.client.fullscreen=%d&qvd.client.geometry=%s&qvd.client.link=%s&qvd.client.keyboard=%s&qvd.client.printing.enabled=%d HTTP/1.1\nAuthorization: Basic %s\nConnection: Upgrade\nUpgrade: QVD/1.0\n\n", id, qvd->os, qvd->fullscreen, qvd->geometry, qvd->link, qvd->keyboard, qvd->print_enabled, qvd->authdigest) >= MAX_BASEURL) { */
  if (snprintf(url, MAX_BASEURL, "GET /qvd/connect_to_vm?id=%d&qvd.client.os=%s&qvd.client.geometry=%s&qvd.client.link=%s&qvd.client.keyboard=%s&qvd.client.fullscreen=%d HTTP/1.1\nAuthorization: Basic %s\nConnection: Upgrade\nUpgrade: QVD/1.0\n\n", id, qvd->os, qvd->geometry, qvd->link, qvd->keyboard, qvd->fullscreen, qvd->authdigest) >= MAX_BASEURL) {
    qvd_error(qvd, "Error initializing authdigest\n");
    return 1;
  }
  qvd_printf("Switch protocols the url is: <%s>\n", url);

  /*  char *url = "GET /qvd/connect_to_vm?id=1&qvd.client.os=linux&qvd.client.fullscreen=&qvd.client.geometry=800x600&qvd.client.link=local&qvd.client.keyboard=pc105%2Fus&qvd.client.printing.enabled=0 HTTP/1.1\nAuthorization: Basic bml0bzpuaXRv\nConnection: Upgrade\nUpgrade: QVD/1.0\n\n"; */
  if ((qvd->res = curl_easy_send(qvd->curl, url, strlen(url) , &bytes_sent )) != CURLE_OK ) {
    qvd_error(qvd, "An error ocurred in first curl_easy_send: %ul <%s>\n", qvd->res, curl_easy_strerror(qvd->res));
    return 1;
  }

  /* TODO perhaps put this in another func ??? */

  FD_ZERO(&myset);
  FD_ZERO(&zero);
  FD_SET(socket, &myset);
  qvd_printf("Before select on send socket is: %d\n", socket);
  for (i=0; i<MAX_HTTP_RESPONSES_FOR_UPGRADE; ++i) {
    /* TODO define timeouts perhaps in qvd_init */
    select(socket+1, &myset, &zero, &zero, NULL);
    if ((qvd->res = curl_easy_recv(qvd->curl, qvd->buffer.data, BUFFER_SIZE, &bytes_received)) != CURLE_OK ) {
      qvd_error(qvd, "An error ocurred in curl_easy_recv: %ul <%s>\n", qvd->res, curl_easy_strerror(qvd->res));
      return 2;
    }
    qvd->buffer.data[bytes_received] = 0;
    qvd_printf("%d input received was <%s>\n", i, qvd->buffer.data);
    /* TODO what happens if  for other strings
V/qvd     ( 7551): Before select on send socket is: 43
V/qvd     ( 7551): 0 input received was <HTTP/1.1 403 Forbidden
V/qvd     ( 7551): Content-Type: text/plain
V/qvd     ( 7551): Content-Length: 56
V/qvd     ( 7551): 
V/qvd     ( 7551): >
V/qvd     ( 7551): 1 input received was <The requested virtual machine is offline for maintenance>

 */


    if (strstr(qvd->buffer.data, "HTTP/1.1 101")) {
      qvd_printf("Upgrade of protocol was done\n");
      break;
    }

#define PROGRESSINFO "\r\nX-QVD-VM-Info: "
    if (strstr(qvd->buffer.data, "HTTP/1.1 102")) {
      qvd_printf("Progress message");
      if ((ptr = strcasestr(qvd->buffer.data, PROGRESSINFO)) != NULL) {
#ifdef TRACE
	qvd_printf("ptr is %s and size is %d", ptr, strlen(PROGRESSINFO));
#endif
	ptr += strlen(PROGRESSINFO);
	qvd_progress(qvd, ptr);
      }
#ifdef TRACE
      else {
	qvd_printf("Pointer finding %s is null", PROGRESSINFO);
      }
#endif
    }

    /* TODO cleanup printf */
    if (strstr(qvd->buffer.data, "HTTP/1.1 2")
	|| strstr(qvd->buffer.data, "HTTP/1.1 3")
	|| strstr(qvd->buffer.data, "HTTP/1.1 4")
	|| strstr(qvd->buffer.data, "HTTP/1.1 5")) {
      bytes_received_total = 0;
#define CONTENT_LENGTH "\r\nContent-Length: "
      if ((ptr = strcasestr(qvd->buffer.data, CONTENT_LENGTH)) != NULL) {
	ptr += strlen(CONTENT_LENGTH);
#ifdef TRACE
	qvd_printf("Parsing content length from <%s> and starting in <%s>", qvd->buffer.data, ptr);
#endif
	content_length = -1;
	if (sscanf(ptr, "%d", &content_length) != 1) {
	  qvd_printf("Error parsing content-length setting to -1: %d", content_length);
	  content_length = -1;	  
	}
      }
      while (bytes_received < BUFFER_SIZE) {
	qvd_printf("Waiting for extra data after found 2xx, 3xx, 4xx or 5xx code <%s>", qvd->buffer.data);
	select(socket+1, &myset, &zero, &zero, NULL);
       
	ptr = qvd->buffer.data;
	ptr += bytes_received;
	/* TODO implement callback for info */
	if ((qvd->res = curl_easy_recv(qvd->curl, ptr, BUFFER_SIZE, &bytes_received_total)) != CURLE_OK ) {
	  ptr = strstr(qvd->buffer.data, "\r\n\r\n");
	  qvd_error(qvd, "Error received in qvd_curl_easy_recv: %d. <%s>", qvd->res, ptr);
	  return 7;
	}
	bytes_received += bytes_received_total;
#define DOUBLENEWLINE "\r\n\r\n"
	content = strstr(qvd->buffer.data, DOUBLENEWLINE);
	content_size_parsed = content != NULL ? strlen(content): -1;
#ifdef TRACE
	qvd_printf("The bytes received were: %d, and curle code was: %d, content: <%s>, size of content: %d", bytes_received_total, qvd->res, content, content_size_parsed);
#endif
	if (bytes_received == 0 || content_size_parsed >= content_length) {
	  content += strlen(DOUBLENEWLINE);
	  qvd_error(qvd, "Error: <%s>", content);
	  return 8;
	}
     
      }
    }

  }
  if (i >=10 ) {
    qvd_error(qvd, "Error not received response for protocol upgrade in %d tries http/1.1\n", i);
    return 3;
  }

  return 0;
}
Beispiel #15
0
/*
 * _qvd_client_loop
 *            --------------------
 *            |                  |
 * proxyFd ---| _qvd_client_loop |---connFd            
 * (X display)|                  | (curl to remote host)
 *            --------------------
 * 
 *       -----   proxyRead  ---->
 *      <-----   proxyWrite ----
 *
 * We read from proxyFd and store it in the proxyRead buffer and then write it into connFd (curl)
 * We read from connFd and store it in the proxyWrite buffer and then write it ingo proxyFd (NX)
 *
 */
int _qvd_client_loop(qvdclient *qvd, int connFd, int proxyFd)
{
  qvd_printf("_qvd_client_loop\n");
  size_t read = 0, written = 0;
  struct timeval timeout;
  fd_set rfds, wfds;
  int ret, res, err, maxfds, numunsupportedprotocolerrs = 0, result = 0, i;

  QvdBuffer proxyWrite, proxyRead;
  qvd_printf("_qvd_client_loop(%p, %d, %d)\n", qvd, connFd, proxyFd);
  QvdBufferInit(&proxyWrite);
  QvdBufferInit(&proxyRead);
  do
    {
      ret = 0;
      timeout.tv_sec = QVDLOOP_TIMEOUT_SEC;
      timeout.tv_usec = QVDLOOP_TIMEOUT_USEC;
      maxfds = 1+MAX(connFd, proxyFd);
      FD_ZERO(&rfds);
      FD_ZERO(&wfds);
      if (proxyFd > 0 && QvdBufferCanRead(&proxyRead))
	  FD_SET(proxyFd, &rfds);

      if (connFd > 0 && QvdBufferCanRead(&proxyWrite))
	FD_SET(connFd, &rfds);

      if (NXTransPrepare(&maxfds, &rfds, &wfds, &timeout))
	{
#ifdef TRACE
	  qvd_printf("_qvd_client_loop: executing select()\n");
#endif
	  NXTransSelect(&ret, &err, &maxfds, &rfds, &wfds, &timeout);
	  NXTransExecute(&ret, &err, &maxfds, &rfds, &wfds, &timeout);
	}
      if (ret == -1 && errno == EINTR)
	continue;

      if (ret < 0)
	{
	  qvd_error(qvd, "Error in _qvd_client_loop: select() %s\n", strerror(errno));
	  return 1;
	}
      if (qvd->end_connection)
	{
	  qvd_printf("Connection ended with qvd_end_connection().");
	  qvd_progress(qvd, "Connection ended with qvd_end_connection().");
	  return 0;
	}
#ifdef TRACE
      qvd_printf("isset proxyfd read: %d; connfd read: %d\n",
		   FD_ISSET(proxyFd, &rfds), FD_ISSET(connFd, &rfds));
#endif
      /* Read from curl socket and store in proxyWrite buffer */
      if (connFd > 0 && FD_ISSET(connFd, &rfds))
	{
	  read = 0; /* handle case of CURLE_UNSUPPORTED_PROTOCOL where read does not gets modified */
	  res = curl_easy_recv(qvd->curl, proxyWrite.data+proxyWrite.offset,
			       BUFFER_SIZE-proxyWrite.size, &read);

	  switch (res)
	    {
	    case CURLE_OK:
#ifdef TRACE
	      qvd_printf("curl: recv'd %ld\n", read);
#endif
	      proxyWrite.size += read;
	      if (read == 0)
		{
		  qvd_printf("Setting connFd to 0, End of stream\n");
		  connFd = -1; 
		}
	      numunsupportedprotocolerrs = 0;
	      break;
	    case CURLE_AGAIN:
	      qvd_printf("Nothing read. receiving curl_easy_recv: %d CURLE_AGAIN, read %d\n", res, read);
	      break;
	    case CURLE_UNSUPPORTED_PROTOCOL:
	      numunsupportedprotocolerrs++;
	      qvd_printf("Unsupported protocol. receiving curl_easy_recv: %d CURLE_UNSUPPORTED_PROTOCOL (wait for next iteration), read %d, number of sequential errors=%d\n", res, read, numunsupportedprotocolerrs);
	      qvd_printf("Error buffer: %s", qvd->error_buffer);
#ifdef TRACE
	      qvd_printf("curle_unsupported_protocol string size");
	      for (i=0; i < read; i++)
		qvd_printf("%x %c ",proxyWrite.data[i], proxyWrite.data[i]);
	      qvd_printf("\n");
#endif
# define MAX_CURLE_UNSUPPORTED_PROTOCOL 1
	      if (numunsupportedprotocolerrs >= MAX_CURLE_UNSUPPORTED_PROTOCOL) {
		qvd_error(qvd, "Unsupported protocol received %d times. receiving curl_easy_recv: %d CURLE_UNSUPPORTED_PROTOCOL (wait for next iteration), read %d, number of sequential errors=%d\n", MAX_CURLE_UNSUPPORTED_PROTOCOL, res, read, numunsupportedprotocolerrs);
		/* An error we need to finish the connection */
		connFd = -1;
		/*		  proxyFd = -1;  */
		result = 0;
	      }
	      break;
	    default:
	      qvd_error(qvd, "Error receiving curl_easy_recv: %d\n", res);
	      connFd = -1;
	      /* proxyFd = -1; */
	      result = -1;
	    }
	}
      /* Read from NX and store in proxyRead buffer */
      if (proxyFd > 0 && FD_ISSET(proxyFd, &rfds))
	{
	  ret = QvdBufferRead(&proxyRead, proxyFd);
	  if (ret == 0)
	    {
	      qvd_printf("No more bytes to read from proxyFd ending\n");
	      proxyFd = -1;
	    }
	  if (ret < 0)
	    {
	      qvd_error(qvd, "Error proxyFd read error: %s\n", strerror(errno));
	      proxyFd = -1;
	    }
	}
      if (proxyFd > 0 && QvdBufferCanWrite(&proxyWrite))
	{
	  ret = QvdBufferWrite(&proxyWrite, proxyFd);
	  if (ret < 0 && errno != EINTR) {
	    qvd_error(qvd, "Error reading from proxyFd: %d %s\n", errno, strerror(errno));
	    proxyFd = -1;
	  }
	}
      if (connFd > 0 && QvdBufferCanWrite(&proxyRead))
	{
	  /*QvdBufferWrite(&proxyRead, connFd);*/
	  res = curl_easy_send(qvd->curl, proxyRead.data+proxyRead.offset,
			       proxyRead.size-proxyRead.offset, &written);
	  switch (res)
	    {
	    case CURLE_OK:
	      proxyRead.offset += written;
#ifdef TRACE
	      qvd_printf("curl: send'd %ld\n", written);
#endif
	      if (proxyRead.offset >= proxyRead.size)
		QvdBufferReset(&proxyRead);
	      numunsupportedprotocolerrs = 0;
	      break;
	    case CURLE_AGAIN:
	      qvd_printf("Nothing written, wait for next iteration. curl_easy_send: %d CURLE_AGAIN, written %d\n", res, written);
	      break;
	    case CURLE_UNSUPPORTED_PROTOCOL:
	      numunsupportedprotocolerrs++;
	      qvd_printf("Unsupported protocol sent %d times. sending curl_easy_sendv: %d CURLE_UNSUPPORTED_PROTOCOL (wait for next iteration), written %d, number of sequential errors=%d\n", MAX_CURLE_UNSUPPORTED_PROTOCOL, res, written, numunsupportedprotocolerrs);
	      qvd_printf("Error buffer: %s", qvd->error_buffer);

#ifdef TRACE
	      qvd_printf("curle_unsupported_protocol string size");
	      for (i=0; i < written; i++)
		qvd_printf("%x %c ",proxyWrite.data[i], proxyWrite.data[i]);
	      qvd_printf("\n");
#endif
	      if (numunsupportedprotocolerrs >= MAX_CURLE_UNSUPPORTED_PROTOCOL) {
		qvd_error(qvd, "Unsupported protocol sent %d times. sending curl_easy_sendv: %d CURLE_UNSUPPORTED_PROTOCOL (wait for next iteration), written %d, number of sequential errors=%d\n", MAX_CURLE_UNSUPPORTED_PROTOCOL, res, written, numunsupportedprotocolerrs);
		/* An error we need to finish the connection */
		/* TODO only finish connFd */
		connFd = -1;
		/*		  proxyFd = -1; */
		result = 0;
	      }
	      break;
	    default:
	      qvd_error(qvd, "Error sending curl_easy_send: %d", res);
	      connFd = -1;
	    }
	}
    } while (connFd > 0 && proxyFd > 0);
  
  return result;
}