Example #1
0
    void findIP(const string &s, int start, int count, 
                vector<string> &ret, string &IP) {
        if (count == 3 && isValid(s.substr(start))) {
            ret.push_back(IP+s.substr(start));
            return;
        }
        if (s.length()-start > (4-count)*3) // prune the bad partitions
            return;

        for (int i = 1; i <= 3 && start+i <= s.length(); i++) {
            string str = s.substr(start, i);
            if (isValid(str)) {
                str = IP + str + '.';
                findIP(s, start+i, count+1, ret, str);
            }
        }
    }
Example #2
0
wxString Config::validateConfig()
{
    wxRegEx findIP( wxT("^(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])$"));
    wxRegEx b64Validate( wxT("^[A-Za-z0-9+/]+={0,3}$"));
    wxRegEx portStringValidate( wxT("(tcp|udp)/+[0-9]"));

    if (this->NICK_NAME.CmpNoCase(wxEmptyString) == 0 ) {
        return wxT("You must choose a Nickname.");
    } else if (this->SERVER_IP.Find(_(".")) == wxNOT_FOUND) { //check for valid ip or hostname -- Relex this check greatly and throw the error when trying to send.
        return wxT("You must supply a valid server address.");
    } else if((wxAtoi(this->SERVER_PORT) < 1 || wxAtoi(this->SERVER_PORT) > 65535) && this->SERVER_PORT.CmpNoCase(wxT("Random")) != 0){
        return wxT("Invalid Server Port"); //check server port is valid port or random
    } else if (this->LEGACY == true && this->HMAC.CmpNoCase(wxEmptyString) != 0) {//check no hmac with legacy
        return wxT("You cannot use an HMAC in legacy mode.");
    } else if (this->KEY_BASE64 && wxStrlen(this->KEY) % 4 != 0) { //check base64 must have a multiple of 4 length
        return wxT("Invalid Base64 Key Length.");
    } else if (this->KEY_BASE64 && !b64Validate.Matches(this->KEY)) { // looks for disallowed b64 characters
        return wxT("Invalid Base64 Key.");
    } else if (this->HMAC_BASE64 && wxStrlen(this->HMAC) % 4 != 0) { //check base64 must have a multiple of 4 length
        return wxT("Invalid Base64 HMAC Length.");
    } else if (this->HMAC_BASE64 && !b64Validate.Matches(this->HMAC)) { // looks for disallowed b64 characters
        return wxT("Invalid Base64 HMAC.");
    } else if (!(this->MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0 || portStringValidate.Matches(this->PORTS))) { //If not a server command, make sure the port string is valid
        return wxT("Invalid Port string. Must look like tcp/22.");
    } else if (!(this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0 ||  this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0 || this->ACCESS_IP.CmpNoCase(wxT("Prompt IP")) == 0 || findIP.Matches(this->ACCESS_IP) )) { //if specifying ip, make sure is valid
        return wxT("Invalid IP to allow."); // Have to have a valid ip to allow, if using allow ip
    } else if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0 && !(0 < wxAtoi(NAT_PORT) && wxAtoi(NAT_PORT) < 65536)) { //NAT_IP must be a valid ip, and NAT_PORT must be a valid port
        return wxT("Invalid NAT port.");
    } else if (!(this->DIGEST_TYPE.CmpNoCase(wxT("MD5")) == 0
                || this->DIGEST_TYPE.CmpNoCase(wxT("SHA1")) == 0
                || this->DIGEST_TYPE.CmpNoCase(wxT("SHA256")) == 0
                || this->DIGEST_TYPE.CmpNoCase(wxT("SHA384")) == 0
                || this->DIGEST_TYPE.CmpNoCase(wxT("SHA512")) == 0)) {
        return wxT("Invalid SPA digest type.");
    } else if (!(this->HMAC_TYPE.CmpNoCase(wxT("MD5")) == 0
                || this->HMAC_TYPE.CmpNoCase(wxT("SHA1")) == 0
                || this->HMAC_TYPE.CmpNoCase(wxT("SHA256")) == 0
                || this->HMAC_TYPE.CmpNoCase(wxT("SHA384")) == 0
                || this->HMAC_TYPE.CmpNoCase(wxT("SHA512")) == 0)) {
        return wxT("Invalid HMAC digest type.");
    } else { //Could check for valid looking gpg keys if enabled
        return wxT("valid");
    }
}
Example #3
0
void TracerouteData::pushInToQueue( uint32_t destinationIP )
{
	if( finish_ )
		throw std::runtime_error( "Traceroute Data not accepting more lookups" );
	ipQueueData tmp;
	tmp.destinationIP = destinationIP;
	tmp.TTL = 0;
	//see if we already have data...
	indexLookupMutex_.lock();
	int index = indexLookup_[ destinationIP ];
	indexLookupMutex_.unlock();
	if( index != 0 )
	{
		//already preforming lookup or lookup already done..
		return;
	}
	//need to save an index
	indexLookupMutex_.lock();
	tracerouteLookupTableMutex_.lock();
	tracerouteLookupTable_.push_back( NULL );
	index = tracerouteLookupTable_.size() - 1;
	tracerouteLookupTableMutex_.unlock();
	indexLookup_[destinationIP] = index;
	indexLookupMutex_.unlock();
	ipQueueMutex_.lock();
  if( !findIP( ipQueue_, destinationIP ) )
	{
		for(tmp.TTL = 1; tmp.TTL < maxTimeToLive_ + 1 ; ++tmp.TTL )
		{
			ipQueue_.push_back( tmp );
			semaphore_.post();
		}
	}
	ipQueueMutex_.unlock();
	
	Mutex* mutexPtr = new Mutex;
	mutexPtr->lock( );
	tracerouteFinishedMutex_.lock();
	tracerouteFinished_[destinationIP] = mutexPtr;
	tracerouteFinishedMutex_.unlock();
}
Example #4
0
wxString Config::gen_SPA(wxString ip_resolver_url, wxString gpgEngine, wxString gpgHomeFolder, bool debug)
{
    CURLcode curl_Res;
    fko_ctx_t ctx;
    fwknop_options_t opts;
    int key_len = 0;
    int res;
    int hmac_str_len = 0;
    short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    short digest_type = FKO_DIGEST_SHA256;
    short hmac_type = FKO_HMAC_SHA256;
    char key_str[129] = {0}, hmac_str[129] = {0};
    char spa_msg[256] = {0};
//    char spa_buf[4096] = {0};
//    char * spa_buf_ptr;
//    char crypt_buf[4096] = {0};
    char nat_access_str[25] = {0};
//    char * hmac_buf;
//    char * spa_digest_ptr;


    memset(&opts, 0, sizeof(fwknop_options_t));

    if (this->KEY.IsEmpty() && !this->USE_GPG_CRYPT)
        return _("Key cannot be blank!");

    wxBusyInfo wait(_("Please wait, working..."));
    if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0)
    {
        srand((int)wxGetLocalTime());
        this->SERVER_PORT.Empty();
        this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function
    }
    if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
        this->ACCESS_IP = wxT("0.0.0.0");
    else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
    {
        std::ostringstream oss;
        curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss);
        if (curl_Res == CURLE_OK)
        {
            wxString result_tmp = wxString::FromUTF8(oss.str().c_str());
            wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"));
            if (!findIP.Matches(result_tmp))
                return _("Unable to resolve our IP!");

            this->ACCESS_IP = findIP.GetMatch(result_tmp);
        } else
            return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res));

    } //end resolve ip
    if (fko_new(&ctx) != FKO_SUCCESS)
        return _("Could not get new FKO context");

    if (USE_GPG_CRYPT) {
        fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG);
        fko_set_gpg_exe(ctx, gpgEngine.mb_str());
        fko_set_gpg_home_dir(ctx, gpgHomeFolder.mb_str());


        fko_set_gpg_recipient(ctx, GPG_CRYPT_ID.mb_str());
        if (GPG_SIG_ID.CmpNoCase(_("None")) != 0)
        fko_set_gpg_signer(ctx, GPG_SIG_ID.mb_str());



        fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC);

    } else {
        if (this->KEY_BASE64)
        {
            key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str);
        } else {
            strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128);
            key_len = (int)strlen(key_str);
        }
    }

    if (this->HMAC_BASE64)
    {
        hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str);
    } else {
        strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128);
        hmac_str_len = (int)strlen(hmac_str);
    }



    if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
    {
        message_type = FKO_COMMAND_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
            return _("Could not set message type");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8));
        res = fko_set_spa_message(ctx, spa_msg);
        if (res != FKO_SUCCESS)
            return _("Could not set command message");

    } else {
        if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS)
            return _("Could not set SPA timeout");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8));
        if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS)
            return _("Could not set SPA Message");

    }
    if (this->LEGACY) { // technically should trim hmac keys
        if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS)
            return _("Could not set Legacy mode.");

    }
    if (!this->HMAC.IsEmpty()){
        if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0)
            hmac_type = FKO_HMAC_MD5;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0)
            hmac_type = FKO_HMAC_SHA1;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0)
            hmac_type = FKO_HMAC_SHA256;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0)
            hmac_type = FKO_HMAC_SHA384;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0)
            hmac_type = FKO_HMAC_SHA512;
        if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS)
            return _("Could not set HMAC type.");

    }
    if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
    {
        sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");

    } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) {
        message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
        return _("Chould not set message type");
        sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");
    }
    if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0)
        digest_type = FKO_DIGEST_MD5;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0)
        digest_type = FKO_DIGEST_SHA1;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0)
        digest_type = FKO_DIGEST_SHA256;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0)
        digest_type = FKO_DIGEST_SHA384;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0)
        digest_type = FKO_DIGEST_SHA512;
    if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS)
        return _("Could not set SPA digest type.");
    if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS)
        return _("Could not generate SPA data.");

    if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS)
        return _("Could not retrieve SPA data.");
   // if (!USE_GPG_CRYPT) {
        this->SPA_STRING = wxString::FromUTF8(opts.spa_data);
    /*} else {  //could retain this for libfko without gpg support
        fko_get_encoded_data(ctx, &spa_buf_ptr);
        fko_get_spa_digest(ctx, &spa_digest_ptr);
        sprintf(spa_buf,"%s:%s", spa_buf_ptr, spa_digest_ptr);
        ourGPG->encryptAndSign(GPG_CRYPT_ID, GPG_SIG_ID, spa_buf, crypt_buf);
        fko_set_spa_data(ctx, crypt_buf);
        fko_set_spa_hmac(ctx, hmac_str, hmac_str_len);
        fko_get_spa_hmac(ctx, &hmac_buf);
        strcat(crypt_buf, hmac_buf);
        this->SPA_STRING = wxString::FromUTF8(crypt_buf + 2);

    }*/

    if (debug) {
        wxTextEntryDialog *debugMessage = new wxTextEntryDialog(NULL, _("Debug info"), _("Debug info"),  "Source IP: " + this->ACCESS_IP +"\n" + "SPA String: " + this->SPA_STRING, wxOK | wxTE_MULTILINE );
        debugMessage->SetSize(620, 320);
        debugMessage->ShowModal();
        debugMessage->Destroy();
    }
    return _("Success");
}
Example #5
0
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
  int result = 404;
  struct ValidIP* ip;
  bool valid = FALSE;

  switch (ev) {
    case MG_AUTH: return MG_TRUE;

    case MG_REQUEST:

      // Log all headers for request if from Google
      // has a referer
      if (isLogable(conn))
         logGoogle(conn);

      // Get validIP entry.  Add new entry if necessary
      ip = findIP(conn->remote_ip);
      if (ip != NULL)
         updateCnt(ip);

      // validate and process
      valid = FALSE;
      result = 501;
      if (ip != NULL && (ip->banned == 0) && isValidMethod(conn)) {
         result = 404;
         valid = isValidReq(conn);

         // Handle Letsencrypt challenge
         if ((letsencrypt_req[0] != '\0') && strncmp(conn->uri, acme_header, strlen(acme_header)) == 0) {
             valid = TRUE;
             checkip_letsencrypt(conn);
             result = 200;
         }

         // Handle general cases
         if (valid && strcmp(conn->uri, "/") == 0) {
             checkip_req(conn);
             result = 200;
         }
         if (valid && strcmp(conn->uri, "/robots.txt") == 0) {
             checkip_robots(conn);
             result = 200;
         }
         if (valid && strcmp(conn->uri, "/sitemap.xml") == 0) {
             checkip_sitemap(conn);
             result = 200;
         }
         if (valid && strcmp(conn->uri, "/googled01a3874d935c921.html") == 0) {
             valid = FALSE;
             result = 200;
         }
      }

      if (!valid) {
         reject_req(conn, result);
      }

      // update the ban count and possibly ban the ip addr
      updateScore(conn->uri, ip, result);

      // log the request to syslog
      if (ip->score > 0 || strcmp(conn->uri, "/") != 0) {
		  log_msg(daemon_mode, "[%d] %s: %s '%s%s%s' %d score=%d",
							   conn->local_port,
							   conn->remote_ip,
							   conn->request_method,
							   conn->uri,
							   ((conn->query_string == NULL) ? "" : "?"),
							   ((conn->query_string == NULL) ? "" : conn->query_string),
							   result,
							   ip->score
		  );
      }

      // if necessary, ban the IP address
      if (ip->score >= LIMIT || strcmp(conn->request_method, "GET") != 0) {
        banIP(ip, conn->remote_ip);
      }
      return (result == 200) ? MG_TRUE : MG_FALSE;

    default:
      return MG_FALSE;
  }
}
Example #6
0
 vector<string> restoreIpAddresses(string s) {
     vector<string> ret;
     string IP;
     findIP(s, 0, 0, ret, IP);
     return ret;
 }
Example #7
0
wxString Config::gen_SPA(wxString ip_resolver_url)
{
    CURLcode curl_Res;
    fko_ctx_t ctx;
    fwknop_options_t opts;
    int key_len, res;
    int hmac_str_len = 0;
    short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    short digest_type = FKO_DIGEST_SHA256;
    short hmac_type = FKO_HMAC_SHA256;
    char key_str[129] = {0}, hmac_str[129] = {0};
    char spa_msg[256] = {0};
    char debug_buf[4096] = {0};
    char nat_access_str[25] = {0};

    memset(&opts, 0, sizeof(fwknop_options_t));

    if (this->KEY.IsEmpty())
        return _("Key cannot be blank!");

    wxBusyInfo wait(_("Please wait, working..."));
    if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0)
    {
        srand((int)wxGetLocalTime());
        this->SERVER_PORT.Empty();
        this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function
    }
    if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
        this->ACCESS_IP = wxT("0.0.0.0");
    else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
    {
        std::ostringstream oss;
        curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss); //Eventually make this a user definable service.
        if (curl_Res == CURLE_OK)
        {
            wxString result_tmp = wxString::FromUTF8(oss.str().c_str());
            wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"));
            if (!findIP.Matches(result_tmp))
                return _("Unable to resolve our IP!");

            this->ACCESS_IP = findIP.GetMatch(result_tmp);
        } else
            return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res));

    } //end resolve ip

    if (this->KEY_BASE64)
    {
        key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str);
    } else {
        strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128);
        key_len = (int)strlen(key_str);
    }

    if (this->HMAC_BASE64)
    {
        hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str);
    } else {
        strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128);
        hmac_str_len = (int)strlen(hmac_str);
    }

    if (fko_new(&ctx) != FKO_SUCCESS)
        return _("Could not get new FKO context");

    if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
    {
        message_type = FKO_COMMAND_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
            return _("Could not set message type");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8));
        res = fko_set_spa_message(ctx, spa_msg);
        if (res != FKO_SUCCESS)
            return _("Could not set command message");

    } else {
        if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS)
            return _("Could not set SPA timeout");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8));
        if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS)
            return _("Could not set SPA Message");

    }
    if (this->LEGACY) { // technically should trim hmac keys
        if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS)
            return _("Could not set Legacy mode.");

    }
    if (!this->HMAC.IsEmpty()){
        if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0)
            hmac_type = FKO_HMAC_MD5;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0)
            hmac_type = FKO_HMAC_SHA1;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0)
            hmac_type = FKO_HMAC_SHA256;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0)
            hmac_type = FKO_HMAC_SHA384;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0)
            hmac_type = FKO_HMAC_SHA512;
        if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS)
            return _("Could not set HMAC type.");

    }
    if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
    {
        sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");

    } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) {
        message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
        return _("Chould not set message type");
        sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");
    }
    if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0)
        digest_type = FKO_DIGEST_MD5;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0)
        digest_type = FKO_DIGEST_SHA1;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0)
        digest_type = FKO_DIGEST_SHA256;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0)
        digest_type = FKO_DIGEST_SHA384;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0)
        digest_type = FKO_DIGEST_SHA512;
    if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS)
        return _("Could not set SPA digest type.");

    if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS)
        return _("Could not generate SPA data.");

    if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS)
        return _("Could not retrieve SPA data.");

    //dump_ctx_to_buffer(ctx, debug_buf, sizeof(debug_buf));

    this->SPA_STRING = wxString::FromUTF8(opts.spa_data);
    return _("Success");
}
int main( int argc, char *argv[] ) {
   int sockfd, newsockfd, portno, clilen, remSock, htmlStart, i = 0;
   char buffer[8192], *tok_str, *ip, *host, *content, *request = "GET / HTTP/1.1\r\n\r\n";
   char buf[BUFSIZ +1];
   struct sockaddr_in serv_addr, cli_addr, rem_addr;
   int  n, m;
   FILE *fp;
   
   /* Creating a socket */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
   if (sockfd < 0) {
      printf("ERROR while opening the socket");
      exit(1);
   }
   
   /* Initializing the socket structure */

   portno = 45455;
   
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);
   
   /* Binding the socket to the port*/
   if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
      printf("ERROR while binding");
      exit(1);
   }
      
   /* Begin listening for incoming connections
   */
   
   listen(sockfd,5);
   clilen = sizeof(cli_addr);
   
   /* Accept connection request from the client */
   newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
	
   if (newsockfd < 0) {
      printf("ERROR on accept");
      exit(1);
   }
   
   /* Begin communication */
   bzero(buffer,8192);
   n = read( newsockfd,buffer,8192 );
   if (n < 0) {
      printf("ERROR reading from socket");
      exit(1);
   }
   tok_str = strtok(buffer, " /"); //buffer is the message read from the client
   while ((tok_str != NULL)&& (i < 2))// ' ' and '/' are delimiters
   {
	   //printf("%s\n", tok_str);
	   if (i == 1)
		host = tok_str;			//save the 2nd token as the webpage
	   tok_str = strtok(NULL, " /");
	   i++;
   }
   //printf("REQUESTED PAGE: %s\n", host);
   fp = fopen (host, "r");
   if (fp == NULL)	//if file is not on server
	{
	   fp = fopen(host, "w");	//open file for writing
	   printf("%s", request);	//Print get request
	   ip = findIP(host);		//find the ip of the host the client requested
	   printf("%s", ip);
	   remSock = socket(AF_INET, SOCK_STREAM, 0);	//create a socket to connect to the remote server
	   if (remSock < 0)
	   {
		   printf("ERROR creating remote socket");
		   exit(1);
	   }
	   rem_addr.sin_family = AF_INET;
	   rem_addr.sin_addr.s_addr = inet_addr(ip);
	   rem_addr.sin_port = htons(HTTPPORT);  //connect on port 80 for http request
	   if (connect(remSock, (struct sockaddr*)&rem_addr, sizeof(rem_addr)) < 0)
	   {
		   printf("ERROR attempting to connect to remote server");
		   exit(1);
	   }
	   n = write(remSock, request, strlen(request)); //send get request to remote server
	   if (n < 0)
	   {
		   printf("ERROR sending http request");
		   exit(1);
	   }
	   
	   memset(buf, 0, sizeof(buf));
	   htmlStart = 1;
	   while ((n = recv(remSock, buf, BUFSIZ, 0)) > 0)	//receive response from server
	   {
		  content = buf; //store response in content variable
		  if (htmlStart) 
		  {
			  //printf("%s", content);
			  m = write(newsockfd, content, strlen(content)); //write content to client
			  fputs(content, fp);	//write content to file for later access
			  fflush(fp);
		  }
		  memset (buf, 0, n);
	  }
	   if (n < 0)
	   {
		   printf("ERROR reading response");
		   exit(1);
	   }
	   close(remSock);
	   close(newsockfd);
	   close(sockfd);
   }
   else
   {
	   content = (char*) malloc(BUFSIZ);	//allocate buffer to read from file
	   while((fgets(content, BUFSIZ, fp)) != NULL)
	   {
			//printf("%s", content);
			n = write(newsockfd, content, strlen(content));
		}
		free(content);
	}
   
   if (n < 0) {
      printf("ERROR writing to socket");
      exit(1);
   }
   close(sockfd);
   close(newsockfd);
   fflush(fp);
   fflush(stdout);
      
   return 0;
}