Пример #1
0
void TorController::authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply)
{
    if (reply.code == 250) {
        LogPrint("tor", "tor: SAFECOOKIE authentication challenge successful\n");
        std::pair<std::string,std::string> l = SplitTorReplyLine(reply.lines[0]);
        if (l.first == "AUTHCHALLENGE") {
            std::map<std::string,std::string> m = ParseTorReplyMapping(l.second);
            std::vector<uint8_t> serverHash = ParseHex(m["SERVERHASH"]);
            std::vector<uint8_t> serverNonce = ParseHex(m["SERVERNONCE"]);
            LogPrint("tor", "tor: AUTHCHALLENGE ServerHash %s ServerNonce %s\n", HexStr(serverHash), HexStr(serverNonce));
            if (serverNonce.size() != 32) {
                LogPrintf("tor: ServerNonce is not 32 bytes, as required by spec\n");
                return;
            }

            std::vector<uint8_t> computedServerHash = ComputeResponse(TOR_SAFE_SERVERKEY, cookie, clientNonce, serverNonce);
            if (computedServerHash != serverHash) {
                LogPrintf("tor: ServerHash %s does not match expected ServerHash %s\n", HexStr(serverHash), HexStr(computedServerHash));
                return;
            }

            std::vector<uint8_t> computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce);
            conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, _1, _2));
        } else {
            LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n");
        }
    } else {
        LogPrintf("tor: SAFECOOKIE authentication challenge failed\n");
    }
}
Пример #2
0
//test for collisions and report the results. Also provide a 
//simple collision response to colliding objects.
void CollisionTestReportAndRespond(void)
{
    VCReport report;

    vc.Collide( &report );  //perform collision test.
                            //default is VC_FIRST_CONTACT
    int j;

    for (j = 0; j < report.numObjPairs(); j++)
    {
      std::cout << "Detected collision between objects "
           << report.obj1ID(j) <<" and "<< report.obj2ID(j) <<"\n";
  
      polyObject *p1 = GetObjectWithId(report.obj1ID(j));
      polyObject *p2 = GetObjectWithId(report.obj2ID(j));

      Vector normal;
	
      normal = p1->position - p2->position;
      normal.normalize();
      ComputeResponse(normal, (p1->v), &(p1->v) );
    
      normal = p2->position - p1->position;
      normal.normalize();
      ComputeResponse(normal, (p2->v), &(p2->v) );
      
    }

    SinkAndSource();
}
Пример #3
0
bool PluginAuth::FullAuth(XmppHandler * xmpp, QByteArray const& data, Bunny ** pBunny, QByteArray & answer)
{
	switch(xmpp->currentAuthStep)
	{
		case 0:
			// We should receive <?xml version='1.0' encoding='UTF-8'?><stream:stream to='ojn.soete.org' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>"
			if(data.startsWith("<?xml version='1.0' encoding='UTF-8'?>"))
			{
				// Send an auth Request
				answer.append("<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='2173750751' from='xmpp.nabaztag.com' version='1.0' xml:lang='en'>");
				answer.append("<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms><register xmlns='http://violet.net/features/violet-register'/></stream:features>");
				xmpp->currentAuthStep = 1;
				return true;
			}
			LogError("Bad Auth Step 0, disconnect");
			return false;
			
		case 1:
			{
				// Bunny request a register <iq type='get' id='1'><query xmlns='violet:iq:register'/></iq>
				IQ iq(data);
				if(iq.IsValid() && iq.Type() == IQ::Iq_Get && iq.Content() == "<query xmlns='violet:iq:register'/>")
				{
					// Send the request
					answer = iq.Reply(IQ::Iq_Result, "from='" + xmpp->GetXmppDomain() + "' %1 %4", "<query xmlns='violet:iq:register'><instructions>Choose a username and password to register with this server</instructions><username/><password/></query>");
					xmpp->currentAuthStep = 100;
					return true;
				}
				// Bunny request an auth <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
				if(data.startsWith("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>"))
				{
					// Send a challenge
					// <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>...</challenge>
					// <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>nonce="random_number",qop="auth",charset=utf-8,algorithm=md5-sess</challenge>
					QByteArray nonce = QByteArray::number((unsigned int)qrand());
					QByteArray challenge = "nonce=\"" + nonce + "\",qop=\"auth\",charset=utf-8,algorithm=md5-sess";
					answer.append("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + challenge.toBase64() + "</challenge>");
					xmpp->currentAuthStep = 2;
					return true;
				}
				LogError("Bad Auth Step 1, disconnect");
				return false;
			}
			
		case 2:
			{
				// We should receive <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>...</response>
				QRegExp rx("<response[^>]*>(.*)</response>");
				if (rx.indexIn(data) != -1)
				{
					QByteArray authString = QByteArray::fromBase64(rx.cap(1).toAscii()).replace((char)0, "");
					// authString is like : username="",nonce="",cnonce="",nc=,qop=auth,digest-uri="",response=,charset=utf-8
					// Parse values
					rx.setPattern("username=\"([^\"]*)\",nonce=\"([^\"]*)\",cnonce=\"([^\"]*)\",nc=([^,]*),qop=auth,digest-uri=\"([^\"]*)\",response=([^,]*),charset=utf-8");
					if(rx.indexIn(authString) != -1)
					{
						QByteArray const username = rx.cap(1).toAscii();
						Bunny * bunny = BunnyManager::GetBunny(username);

						// Check if we want to bypass auth for this bunny
						if((GlobalSettings::Get("Config/StandAloneAuthBypass", false)) == true && (username == GlobalSettings::GetString("Config/StandAloneAuthBypassBunny")))
						{
							// Send success
							LogInfo("Sending success instead of password verification");
							answer.append("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>");

							bunny->Authenticating();
							*pBunny = bunny; // Auth OK, set current bunny

							xmpp->currentAuthStep = 4;
							return true;
						}


						QByteArray const password = bunny->GetBunnyPassword();
						QByteArray const nonce = rx.cap(2).toAscii();
						QByteArray const cnonce = rx.cap(3).toAscii().append((char)0); // cnonce have a dummy \0 at his end :(
						QByteArray const nc = rx.cap(4).toAscii();
						QByteArray const digest_uri = rx.cap(5).toAscii();
						QByteArray const bunnyResponse = rx.cap(6).toAscii();
						if(bunnyResponse == ComputeResponse(username, password, nonce, cnonce, nc, digest_uri, "AUTHENTICATE"))
						{
							// Send challenge back
							// <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>...</challenge>
							// rspauth=...
							QByteArray const rspAuth = "rspauth=" + ComputeResponse(username, password, nonce, cnonce, nc, digest_uri, "");
							answer.append("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + rspAuth.toBase64() + "</challenge>");

							bunny->Authenticating();
							*pBunny = bunny; // Auth OK, set current bunny

							xmpp->currentAuthStep = 3;
							return true;
						}

						LogError("Authentication failure for bunny");
						// Bad password, send failure and restart auth
						answer.append("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/></failure>");
						xmpp->currentAuthStep = 0;
						return true;
					}
				}
				LogError("Bad Auth Step 2, disconnect");
				return false;
			}
			
		case 3:
			// We should receive <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
			if(data.startsWith("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"))
			{
				// Send success
				answer.append("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>");
				xmpp->currentAuthStep = 4;
				return true;
			}
			LogError("Bad Auth Step 3, disconnect");
			return false;
			
		case 4:
			// We should receive <?xml version='1.0' encoding='UTF-8'?>
			if(data.startsWith("<?xml version='1.0' encoding='UTF-8'?>"))
			{
				// Send success
				answer.append("<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1331400675' from='xmpp.nabaztag.com' version='1.0' xml:lang='en'>");
				answer.append("<stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required/></bind><unbind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></stream:features>");
				xmpp->currentAuthStep = 0;
				(*pBunny)->Authenticated();
				(*pBunny)->SetXmppHandler(xmpp);
				// Bunny is now authenticated
				return true;
			}
			LogError("Bad Auth Step 4, disconnect");
			return false;


		case 100: // Register Bunny
			{
				// We should receive <iq to='xmpp.nabaztag.com' type='set' id='2'><query xmlns="violet:iq:register"><username>0019db01dbd7</username><password>208e6d83bfb2</password></query></iq>
				IQ iqAuth(data);
				if(iqAuth.IsValid() && iqAuth.Type() == IQ::Iq_Set)
				{
					QByteArray content = iqAuth.Content();
					QRegExp rx("<query xmlns=\"violet:iq:register\"><username>([0-9a-f]*)</username><password>([0-9a-f]*)</password></query>");
					if(rx.indexIn(content) != -1)
					{
						QByteArray user = rx.cap(1).toAscii();
						QByteArray password = rx.cap(2).toAscii();
						Bunny * bunny = BunnyManager::GetBunny(user);
						if(bunny->SetBunnyPassword(ComputeXor(user,password)))
						{
							answer.append(iqAuth.Reply(IQ::Iq_Result, "%1 %2 %3 %4", content));
							xmpp->currentAuthStep = 1;
							return true;
						}
						LogError(QString("Password already set for bunny : ").append(QString(user)));
						return false;
					}
				}
				LogError("Bad Register, disconnect");
				return false;
			}
			
		default:
			LogError("Unknown Auth Step, disconnect");
			return false;
	}
}