|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 #include "../StdAfx.h" 00029 #ifndef ONLY_LOCAL_PROXY 00030 #include "CALastMixA.hpp" 00031 #include "../CALibProxytest.hpp" 00032 #include "../CALastMixChannelList.hpp" 00033 #include "../CASingleSocketGroup.hpp" 00034 #include "../CAPool.hpp" 00035 #include "../CACmdLnOptions.hpp" 00036 #ifdef HAVE_EPOLL 00037 #include "../CASocketGroupEpoll.hpp" 00038 #endif 00039 00040 #ifdef LOG_CHANNEL 00041 //CAMsg::printMsg(LOG_DEBUG,"Channel time log format is as follows: Channel-ID,Channel Start [micros], Channel End [micros], Upload (bytes), Download (bytes), DataAndOpenAndClosePacketsFromUser, DataAndClosePacketsToUser\n"); 00042 #define MACRO_DO_LOG_CHANNEL(a)\ 00043 CAMsg::printMsg(LOG_DEBUG,#a ":%u,%Lu,%Lu,%u,%u,%u,%u\n",\ 00044 pChannelListEntry->channelIn,pChannelListEntry->timeCreated,pQueueEntry->timestamp_proccessing_end,\ 00045 pChannelListEntry->trafficInFromUser,pChannelListEntry->trafficOutToUser,\ 00046 pChannelListEntry->packetsDataInFromUser,pChannelListEntry->packetsDataOutToUser); 00047 #define MACRO_DO_LOG_CHANNEL_CLOSE_FROM_USER MACRO_DO_LOG_CHANNEL(1) 00048 #define MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX MACRO_DO_LOG_CHANNEL(2) 00049 #endif 00050 00051 #define LAST_MIX_SIZE_OF_SYMMETRIC_KEYS 2*KEY_SIZE 00052 00053 00054 SINT32 CALastMixA::loop() 00055 { 00056 #ifndef NEW_MIX_TYPE 00057 //CASocketList oSocketList; 00058 #ifdef DELAY_CHANNELS 00059 m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(), 00060 CALibProxytest::getOptions()->getDelayChannelBucketGrow(), 00061 CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall()); 00062 #endif 00063 #ifdef DELAY_CHANNELS_LATENCY 00064 m_pChannelList->setDelayLatencyParameters( CALibProxytest::getOptions()->getDelayChannelLatency()); 00065 #endif 00066 #ifdef HAVE_EPOLL 00067 CASocketGroupEpoll* psocketgroupCacheRead=new CASocketGroupEpoll(false); 00068 CASocketGroupEpoll* psocketgroupCacheWrite=new CASocketGroupEpoll(true); 00069 #else 00070 CASocketGroup* psocketgroupCacheRead=new CASocketGroup(false); 00071 CASocketGroup* psocketgroupCacheWrite=new CASocketGroup(true); 00072 #endif 00073 tQueueEntry* pQueueEntry=new tQueueEntry; 00074 MIXPACKET* pMixPacket=&pQueueEntry->packet; 00075 SINT32 ret; 00076 SINT32 retval; 00077 SINT32 countRead; 00078 lmChannelListEntry* pChannelListEntry; 00079 UINT8* rsaBuff=new UINT8[RSA_SIZE]; 00080 UINT32 rsaOutLen=RSA_SIZE; 00081 UINT8* tmpBuff=new UINT8[MIXPACKET_SIZE]; 00082 UINT8* ciphertextBuff=new UINT8[DATA_SIZE]; 00083 UINT8* plaintextBuff=new UINT8[DATA_SIZE - GCM_MAC_SIZE]; 00084 UINT16 payloadLen; 00085 bool bAktiv; 00086 m_logUploadedPackets=m_logDownloadedPackets=0; 00087 set64((UINT64&)m_logUploadedBytes,(UINT32)0); 00088 set64((UINT64&)m_logDownloadedBytes,(UINT32)0); 00089 CAThread* pLogThread=new CAThread((UINT8*)"CALastMixA - LogLoop"); 00090 pLogThread->setMainLoop(lm_loopLog); 00091 pLogThread->start(this); 00092 00093 #ifdef LOG_CRIME 00094 bool userSurveillance = false; 00095 #endif 00096 00097 #ifdef LOG_CHANNEL 00098 CAMsg::printMsg(LOG_DEBUG,"Channel time log format is as follows: Channel-ID,Channel Start [micros], Channel End [micros], Upload (bytes), Download (bytes), DataAndOpenPacketsFromUser, DataPacketsToUser\n"); 00099 #endif 00100 00101 while(!m_bRestart) 00102 { 00103 bAktiv=false; 00104 //Step 1a reading from previous Mix --> now in separate thread 00105 //Step 1b processing MixPackets from previous mix 00106 // processing maximal number of current channels packets 00107 if(m_pQueueReadFromMix->getSize()>=sizeof(tQueueEntry)) 00108 { 00109 bAktiv=true; 00110 UINT32 channels=m_pChannelList->getSize()+1; 00111 for(UINT32 k=0;k<channels&&m_pQueueReadFromMix->getSize()>=sizeof(tQueueEntry);k++) 00112 { 00113 ret=sizeof(tQueueEntry); 00114 m_pQueueReadFromMix->get((UINT8*)pQueueEntry,(UINT32*)&ret); 00115 #if defined(LOG_PACKET_TIMES) ||defined(LOG_CHANNEL) 00116 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start); 00117 #endif 00118 #ifdef LOG_PACKET_TIMES 00119 set64(pQueueEntry->timestamp_proccessing_start,pQueueEntry->timestamp_proccessing_start_OP); 00120 #endif 00121 if(pMixPacket->channel>0&&pMixPacket->channel<256) 00122 { 00123 m_pMuxInControlChannelDispatcher->proccessMixPacket(pMixPacket); 00124 continue; 00125 } 00126 // one packet received 00127 m_logUploadedPackets++; 00128 pChannelListEntry=m_pChannelList->get(pMixPacket->channel); 00129 00130 //check if this packet was marked by the previous mixes for user surveillance 00131 #ifdef LOG_CRIME 00132 userSurveillance = ((pMixPacket->flags & CHANNEL_SIG_CRIME) != 0); 00133 pMixPacket->flags &= ~CHANNEL_SIG_CRIME; 00134 #endif 00135 00136 if(pChannelListEntry==NULL) 00137 { 00138 if(pMixPacket->flags==CHANNEL_OPEN) 00139 { 00140 #if defined(_DEBUG) 00141 CAMsg::printMsg(LOG_DEBUG,"New Connection from previous Mix!\n"); 00142 #endif 00143 00144 m_pRSA->decryptOAEP(pMixPacket->data,rsaBuff,&rsaOutLen); 00145 #ifdef REPLAY_DETECTION 00146 // replace time(NULL) with the real timestamp () 00147 // packet-timestamp + m_u64ReferenceTime 00148 UINT32 stamp=((UINT32)(rsaBuff[13]<<16)+(UINT32)(rsaBuff[14]<<8)+(UINT32)(rsaBuff[15]))*REPLAY_BASE; 00149 if(m_pReplayDB->insert(rsaBuff,stamp+m_u64ReferenceTime)!=E_SUCCESS) 00150 // if(m_pReplayDB->insert(rsaBuff,time(NULL))!=E_SUCCESS) 00151 { 00152 CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n"); 00153 continue; 00154 } 00155 #endif 00156 CASymCipher* newCipher = new CASymCipher(); 00157 #ifdef WITH_INTEGRITY_CHECK 00158 newCipher->setGCMKeys(rsaBuff, rsaBuff + KEY_SIZE); 00159 00160 //Decrypt only the first two bytes to get the payload length 00161 UINT16 lengthAndFlagsField=0; 00162 newCipher->decryptMessage(rsaBuff + LAST_MIX_SIZE_OF_SYMMETRIC_KEYS, 2,(UINT8*) &lengthAndFlagsField, false); 00163 payloadLen = ntohs(lengthAndFlagsField); 00164 payloadLen &= PAYLOAD_LEN_MASK; 00165 if (payloadLen > (PAYLOAD_SIZE-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS-RSA_SIZE-GCM_MAC_SIZE - PAYLOAD_HEADER_SIZE+rsaOutLen)) 00166 retval=E_UNKNOWN; 00167 else 00168 { 00169 //prepend the asym decrypted sym encrypted part of teh Mix packet to the sym only encrypted part of the mix packet 00170 memcpy(pMixPacket->data+RSA_SIZE-rsaOutLen+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaBuff + LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS); 00171 //now decrpyt the whole sym encrypted part 00172 retval = newCipher->decryptMessage(pMixPacket->data +RSA_SIZE-rsaOutLen+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS, payloadLen+ GCM_MAC_SIZE + PAYLOAD_HEADER_SIZE , pMixPacket->data, true); 00173 } 00174 #else 00175 newCipher->setKeys(rsaBuff,LAST_MIX_SIZE_OF_SYMMETRIC_KEYS); 00176 newCipher->crypt1( 00177 pMixPacket->data+RSA_SIZE, 00178 pMixPacket->data+rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS, 00179 DATA_SIZE-RSA_SIZE); 00180 memcpy( pMixPacket->data,rsaBuff+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS, 00181 rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS); 00182 #endif 00183 00184 #ifdef LOG_PACKET_TIMES 00185 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP); 00186 #endif 00187 #ifdef WITH_INTEGRITY_CHECK 00188 if (retval != E_SUCCESS) 00189 { 00190 /* invalid MAC -> send channel close packet with integrity error flag */ 00191 getRandom(pMixPacket->data, DATA_SIZE); 00192 pMixPacket->flags = CHANNEL_CLOSE; 00193 pMixPacket->payload.len = htons(INTEGRITY_ERROR_FLAG); 00194 pMixPacket->payload.type = 0; 00195 newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00196 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00197 delete newCipher; 00198 newCipher = NULL; 00199 #ifdef LOG_PACKET_TIMES 00200 setZero64(pQueueEntry->timestamp_proccessing_start); 00201 #endif 00202 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00203 m_logDownloadedPackets++; 00204 CAMsg::printMsg(LOG_ERR, "Integrity check failed in channel-open packet!\n"); 00205 } else { 00206 #endif 00207 00208 CASocket* tmpSocket=new CASocket; 00209 CACacheLoadBalancing* ptmpLB=m_pCacheLB; 00210 ret=E_UNKNOWN; 00211 if(pMixPacket->payload.type==MIX_PAYLOAD_SOCKS) 00212 ptmpLB=m_pSocksLB; 00213 for(UINT32 count=0;count<ptmpLB->getElementCount();count++) 00214 { 00215 tmpSocket->create(); 00216 tmpSocket->setRecvBuff(50000); 00217 tmpSocket->setSendBuff(5000); 00218 ret=tmpSocket->connect(*ptmpLB->get(),LAST_MIX_TO_PROXY_CONNECT_TIMEOUT); 00219 if(ret==E_SUCCESS) 00220 break; 00221 tmpSocket->close(); 00222 } 00223 if(ret!=E_SUCCESS) 00224 { 00225 #if defined (_DEBUG) || defined (DELAY_CHANNELS_LATENCY) 00226 CAMsg::printMsg(LOG_DEBUG,"Cannot connect to Squid!\n"); 00227 #endif 00228 delete tmpSocket; 00229 tmpSocket = NULL; 00230 /* send a close packet signaling the connect error */ 00231 getRandom(pMixPacket->data, DATA_SIZE); 00232 pMixPacket->flags = CHANNEL_CLOSE; 00233 pMixPacket->payload.len = 0; 00234 pMixPacket->payload.type = CONNECTION_ERROR_FLAG; 00235 #ifdef WITH_INTEGRITY_CHECK 00236 newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00237 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00238 #else 00239 newCipher->crypt2(pMixPacket->data, pMixPacket->data, DATA_SIZE); 00240 #endif 00241 #ifdef LOG_PACKET_TIMES 00242 setZero64(pQueueEntry->timestamp_proccessing_start); 00243 #endif 00244 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00245 m_logDownloadedPackets++; 00246 delete newCipher; 00247 newCipher = NULL; 00248 } 00249 else 00250 { //connection to proxy successful 00251 UINT16 payLen=ntohs(pMixPacket->payload.len); 00252 00253 //output payload if packet is marked for user surveillance 00254 #ifdef LOG_CRIME 00255 if(userSurveillance) 00256 { 00257 UINT8 *domain = parseDomainFromPayload(pMixPacket->payload.data, payLen); 00258 00259 if(domain != NULL || (CALibProxytest::getOptions()->isPayloadLogged()) ) 00260 { 00261 CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u\n", pMixPacket->channel); 00262 if(domain != NULL) 00263 { 00264 CAMsg::printMsg(LOG_CRIT, "Domain: %s\n", domain); 00265 delete [] domain; 00266 } 00267 if(CALibProxytest::getOptions()->isPayloadLogged()) 00268 { 00270 UINT8 tempPayload[PAYLOAD_SIZE+1]; 00271 memcpy(tempPayload, pMixPacket->payload.data,payLen); 00272 tempPayload[payLen]=0; 00273 CAMsg::printMsg(LOG_CRIT, "Payload: %s\n",tempPayload); 00274 } 00275 } 00276 } 00277 #endif 00278 00279 #ifdef _DEBUG 00280 UINT8 c=pMixPacket->payload.data[30]; 00281 pMixPacket->payload.data[30]=0; 00282 CAMsg::printMsg(LOG_DEBUG,"Try sending data to Squid: %s\n",pMixPacket->payload.data); 00283 pMixPacket->payload.data[30]=c; 00284 #endif 00285 #ifdef LOG_CRIME 00286 if(payLen<=PAYLOAD_SIZE&&checkCrime(pMixPacket->payload.data,payLen,true)) 00287 { 00288 UINT8 crimeBuff[PAYLOAD_SIZE+1]; 00289 tQueueEntry oSigCrimeQueueEntry; 00290 memset(&oSigCrimeQueueEntry,0,sizeof(tQueueEntry)); 00291 memset(crimeBuff,0,PAYLOAD_SIZE+1); 00292 memcpy(crimeBuff,pMixPacket->payload.data,payLen); 00293 UINT32 id=m_pMuxIn->sigCrime(pMixPacket->channel,&oSigCrimeQueueEntry.packet); 00294 m_pQueueSendToMix->add(&oSigCrimeQueueEntry,sizeof(tQueueEntry)); 00295 int log=LOG_ENCRYPTED; 00296 if(!CALibProxytest::getOptions()->isEncryptedLogEnabled()) 00297 log=LOG_CRIT; 00298 CAMsg::printMsg(log,"Crime detected -- previous mix channel: " 00299 "%u -- Content: \n%s\n", pMixPacket->channel, 00300 (CALibProxytest::getOptions()->isPayloadLogged() ? crimeBuff : (UINT8 *)"<not logged>")); 00301 } 00302 #endif 00303 if(payLen>PAYLOAD_SIZE||tmpSocket->sendTimeOut(pMixPacket->payload.data,payLen,LAST_MIX_TO_PROXY_SEND_TIMEOUT)==SOCKET_ERROR) 00304 { 00305 #ifdef _DEBUG 00306 CAMsg::printMsg(LOG_DEBUG,"Error sending Data to Squid!\n"); 00307 #endif 00308 tmpSocket->close(); 00309 delete tmpSocket; 00310 tmpSocket = NULL; 00311 /* send a close packet signaling the connect error */ 00312 getRandom(pMixPacket->data, DATA_SIZE); 00313 pMixPacket->flags = CHANNEL_CLOSE; 00314 pMixPacket->payload.len = htons(CONNECTION_ERROR_FLAG); 00315 pMixPacket->payload.type = 0; 00316 #ifdef WITH_INTEGRITY_CHECK 00317 newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00318 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00319 #else 00320 newCipher->crypt2(pMixPacket->data, pMixPacket->data, DATA_SIZE); 00321 #endif 00322 #ifdef LOG_PACKET_TIMES 00323 setZero64(pQueueEntry->timestamp_proccessing_start); 00324 #endif 00325 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00326 m_logDownloadedPackets++; 00327 delete newCipher; 00328 newCipher = NULL; 00329 } 00330 else 00331 { 00332 tmpSocket->setNonBlocking(true); 00333 #if defined (DELAY_CHANNELS_LATENCY) 00334 UINT64 u64temp; 00335 getcurrentTimeMillis(u64temp); 00336 #endif 00337 CAQueue* pQueue=new CAQueue(PAYLOAD_SIZE); 00338 #ifdef LASTMIX_CHECK_MEMORY 00339 pQueue->logIfSizeGreaterThen(100000); 00340 #endif 00341 m_pChannelList->add(pMixPacket->channel,tmpSocket,newCipher,pQueue 00342 #if defined (LOG_CHANNEL) 00343 ,pQueueEntry->timestamp_proccessing_start,payLen 00344 #endif 00345 #if defined (DELAY_CHANNELS_LATENCY) 00346 ,u64temp 00347 #endif 00348 ); 00349 #ifdef HAVE_EPOLL 00350 psocketgroupCacheRead->add(*tmpSocket,m_pChannelList->get(pMixPacket->channel)); 00351 #else 00352 psocketgroupCacheRead->add(*tmpSocket); 00353 #endif 00354 #ifdef LOG_PACKET_TIMES 00355 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00356 m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_OPEN,true); 00357 #endif 00358 #ifdef DATA_RETENTION_LOG 00359 pQueueEntry->dataRetentionLogEntry.t_out=htonl(time(NULL)); 00360 pQueueEntry->dataRetentionLogEntry.entity.last.channelid=htonl(pMixPacket->channel); 00361 pQueueEntry->dataRetentionLogEntry.entity.last.port_out=tmpSocket->getLocalPort(); 00362 pQueueEntry->dataRetentionLogEntry.entity.last.port_out=htons(pQueueEntry->dataRetentionLogEntry.entity.last.port_out); 00363 tmpSocket->getLocalIP(pQueueEntry->dataRetentionLogEntry.entity.last.ip_out); 00364 m_pDataRetentionLog->log(&pQueueEntry->dataRetentionLogEntry); 00365 #endif 00366 00367 } 00368 } 00369 #ifdef WITH_INTEGRITY_CHECK 00370 } 00371 #endif 00372 } 00373 } 00374 else 00375 {//channellist entry !=NULL 00376 if(pMixPacket->flags==CHANNEL_CLOSE) 00377 { 00380 /* 00381 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00382 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00383 pChannelListEntry->pSocket->close(); 00384 delete pChannelListEntry->pSocket; 00385 pChannelListEntry->pSocket = NULL; 00386 delete pChannelListEntry->pCipher; 00387 pChannelListEntry->pCipher = NULL; 00388 delete pChannelListEntry->pQueueSend; 00389 pChannelListEntry->pQueueSend = NULL; 00390 */ 00391 pChannelListEntry->pQueueSend->close(); 00392 #ifdef HAVE_EPOLL 00393 psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket),pChannelListEntry); 00394 #else 00395 psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket)); 00396 #endif 00397 #if defined (LOG_PACKET_TIMES) ||defined (LOG_CHANNEL) 00398 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00399 #endif 00400 #if defined (LOG_PACKET_TIMES) 00401 set64(pQueueEntry->timestamp_proccessing_end_OP,pQueueEntry->timestamp_proccessing_end); 00402 m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_CLOSE,true); 00403 #endif 00404 #ifdef LOG_CHANNEL 00405 pChannelListEntry->packetsDataInFromUser++; 00406 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_USER 00407 #endif 00408 //m_pChannelList->removeChannel(pMixPacket->channel); 00409 } 00410 else if(pMixPacket->flags==CHANNEL_DATA) 00411 { 00412 #ifdef LOG_CHANNEL 00413 pChannelListEntry->packetsDataInFromUser++; 00414 #endif 00415 #ifdef WITH_INTEGRITY_CHECK 00416 /* decrypt only the first 2 bytes to get the payload length */ 00417 UINT16 lengthAndFlagsField=0; 00418 pChannelListEntry->pCipher->decryptMessage(pMixPacket->data, 2,(UINT8*) &lengthAndFlagsField, false); 00419 payloadLen = ntohs(lengthAndFlagsField); 00420 payloadLen &= PAYLOAD_LEN_MASK; 00421 if (payloadLen > PAYLOAD_SIZE) 00422 retval=E_UNKNOWN; 00423 else 00424 { 00425 retval = pChannelListEntry->pCipher->decryptMessage(pMixPacket->data, payloadLen + 3 + GCM_MAC_SIZE, plaintextBuff, true); 00426 } 00427 if (retval != E_SUCCESS) { 00428 /* invalid MAC -> send channel close packet with integrity error flag */ 00429 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00430 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00431 pChannelListEntry->pSocket->close(); 00432 delete pChannelListEntry->pSocket; 00433 pChannelListEntry->pSocket = NULL; 00434 delete pChannelListEntry->pQueueSend; 00435 pChannelListEntry->pQueueSend = NULL; 00436 getRandom(pMixPacket->data, DATA_SIZE); 00437 pMixPacket->flags = CHANNEL_CLOSE; 00438 pMixPacket->payload.len = htons(INTEGRITY_ERROR_FLAG); 00439 pMixPacket->payload.type = 0; 00440 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00441 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00442 delete pChannelListEntry->pCipher; 00443 pChannelListEntry->pCipher = NULL; 00444 #ifdef LOG_CHANNEL 00445 pChannelListEntry->packetsDataOutToUser++; 00446 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00447 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX 00448 #endif 00449 m_pChannelList->removeChannel(pMixPacket->channel); 00450 #ifdef LOG_PACKET_TIMES 00451 setZero64(pQueueEntry->timestamp_proccessing_start); 00452 #endif 00453 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00454 m_logDownloadedPackets++; 00455 CAMsg::printMsg(LOG_ERR, "Integrity check failed in data packet!\n"); 00456 } else { 00457 memcpy(pMixPacket->data, plaintextBuff, payloadLen + 3); 00458 #else 00459 pChannelListEntry->pCipher->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00460 #endif 00461 ret=ntohs(pMixPacket->payload.len); 00462 if(ret&NEW_FLOW_CONTROL_FLAG) 00463 { 00464 //CAMsg::printMsg(LOG_DEBUG,"got send me\n"); 00465 pChannelListEntry->sendmeCounterDownstream=max(0,pChannelListEntry->sendmeCounterDownstream-FLOW_CONTROL_SENDME_SOFT_LIMIT); 00466 } 00467 ret&=PAYLOAD_LEN_MASK; 00468 if(ret>=0&&ret<=PAYLOAD_SIZE) 00469 { 00470 #ifdef LOG_CHANNEL 00471 pChannelListEntry->trafficInFromUser+=ret; 00472 #endif 00473 #ifdef LOG_PACKET_TIMES 00474 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP); 00475 #endif 00476 00477 //output payload if packet is marked for user surveillance 00478 #ifdef LOG_CRIME 00479 if(userSurveillance) 00480 { 00481 UINT8 *domain = parseDomainFromPayload(pMixPacket->payload.data, ret); 00482 00483 if(domain != NULL || (CALibProxytest::getOptions()->isPayloadLogged()) ) 00484 { 00485 CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u\n", pMixPacket->channel); 00486 if(domain != NULL) 00487 { 00488 CAMsg::printMsg(LOG_CRIT, "Domain: %s\n", domain); 00489 delete [] domain; 00490 } 00491 if(CALibProxytest::getOptions()->isPayloadLogged()) 00492 { 00494 UINT8 tempPayload[PAYLOAD_SIZE+1]; 00495 memcpy(tempPayload, pMixPacket->payload.data,ret); 00496 tempPayload[ret]=0; 00497 CAMsg::printMsg(LOG_CRIT, "Payload: %s\n",tempPayload); 00498 } 00499 } 00500 } 00501 else if(checkCrime(pMixPacket->payload.data, ret,false)) // Note: false --> it make no sense to check for URL/Domain in DataPackets 00502 { 00503 UINT8 crimeBuff[PAYLOAD_SIZE+1]; 00504 tQueueEntry oSigCrimeQueueEntry; 00505 memset(&oSigCrimeQueueEntry,0,sizeof(tQueueEntry)); 00506 memset(crimeBuff,0,PAYLOAD_SIZE+1); 00507 memcpy(crimeBuff,pMixPacket->payload.data, ret); 00508 UINT32 id=m_pMuxIn->sigCrime(pMixPacket->channel,&oSigCrimeQueueEntry.packet); 00509 m_pQueueSendToMix->add(&oSigCrimeQueueEntry,sizeof(tQueueEntry)); 00510 int log=LOG_ENCRYPTED; 00511 if(!CALibProxytest::getOptions()->isEncryptedLogEnabled()) 00512 log=LOG_CRIT; 00513 CAMsg::printMsg(log,"Crime detected -- previous mix channel: " 00514 "%u -- Content: \n%s\n", pMixPacket->channel, 00515 (CALibProxytest::getOptions()->isPayloadLogged() ? crimeBuff : (UINT8 *)"<not logged>")); 00516 } 00517 00518 #endif 00519 00520 ret=pChannelListEntry->pQueueSend->add(pMixPacket->payload.data,ret); 00521 } 00522 else 00523 ret=SOCKET_ERROR; 00524 if(ret==SOCKET_ERROR) 00525 { 00526 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00527 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00528 pChannelListEntry->pSocket->close(); 00529 delete pChannelListEntry->pSocket; 00530 pChannelListEntry->pSocket = NULL; 00531 delete pChannelListEntry->pQueueSend; 00532 pChannelListEntry->pQueueSend = NULL; 00533 /* send a close packet signaling the connect error */ 00534 getRandom(pMixPacket->data, DATA_SIZE); 00535 pMixPacket->flags = CHANNEL_CLOSE; 00536 pMixPacket->payload.len = 0; 00537 pMixPacket->payload.type = 0; 00538 #ifdef WITH_INTEGRITY_CHECK 00539 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00540 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00541 #endif 00542 delete pChannelListEntry->pCipher; 00543 pChannelListEntry->pCipher = NULL; 00544 #ifdef LOG_CHANNEL 00545 pChannelListEntry->packetsDataOutToUser++; 00546 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00547 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX 00548 #endif 00549 m_pChannelList->removeChannel(pMixPacket->channel); 00550 #ifdef LOG_PACKET_TIMES 00551 setZero64(pQueueEntry->timestamp_proccessing_start); 00552 #endif 00553 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00554 m_logDownloadedPackets++; 00555 } 00556 else 00557 { 00558 //count this packet as Upstream packet... 00559 pChannelListEntry->sendmeCounterUpstream++; 00560 if(pChannelListEntry->sendmeCounterUpstream>=FLOW_CONTROL_SENDME_SOFT_LIMIT) //we need to sent the SENDME ack down to the client... 00561 { 00562 getRandom(pMixPacket->data, DATA_SIZE); 00563 pMixPacket->flags = CHANNEL_DATA; 00564 pMixPacket->payload.len = htons(NEW_FLOW_CONTROL_FLAG); //signal the SENDME 00565 pMixPacket->payload.type = 0; 00566 #ifdef WITH_INTEGRITY_CHECK 00567 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00568 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00569 #else 00570 pChannelListEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00571 #endif 00572 #ifdef LOG_CHANNEL 00573 pChannelListEntry->packetsDataOutToUser++; 00574 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00575 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX 00576 #endif 00577 #ifdef LOG_PACKET_TIMES 00578 setZero64(pQueueEntry->timestamp_proccessing_start); 00579 #endif 00580 CAMsg::printMsg(LOG_DEBUG,"sent send me\n"); 00581 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00582 m_logDownloadedPackets++; 00583 pChannelListEntry->sendmeCounterUpstream-=FLOW_CONTROL_SENDME_SOFT_LIMIT; 00584 } 00585 #ifdef HAVE_EPOLL 00586 psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket),pChannelListEntry); 00587 #else 00588 psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket)); 00589 #endif 00590 #ifdef LOG_PACKET_TIMES 00591 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00592 m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,true); 00593 #endif 00594 } 00595 #ifdef WITH_INTEGRITY_CHECK 00596 } 00597 #endif 00598 } 00599 } 00600 } 00601 } 00602 //end Step 1 00603 00604 //Step 2 Sending to Cache... 00605 countRead=psocketgroupCacheWrite->select(0); 00606 if(countRead>0) 00607 { 00608 bAktiv=true; 00609 #ifdef HAVE_EPOLL 00610 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheWrite->getFirstSignaledSocketData(); 00611 while(pChannelListEntry!=NULL) 00612 { 00613 #else 00614 pChannelListEntry=m_pChannelList->getFirstSocket(); 00615 while(pChannelListEntry!=NULL&&countRead>0) 00616 { 00617 if(psocketgroupCacheWrite->isSignaled(*(pChannelListEntry->pSocket))) 00618 { 00619 countRead--; 00620 #endif 00621 SINT32 len=MIXPACKET_SIZE; 00622 SINT32 ret=pChannelListEntry->pQueueSend->peek(tmpBuff,(UINT32*)&len); 00623 len=pChannelListEntry->pSocket->send(tmpBuff,len); 00624 if(len>=0) 00625 { 00626 add64((UINT64&)m_logUploadedBytes,len); 00627 pChannelListEntry->pQueueSend->remove((UINT32*)&len); 00628 if(pChannelListEntry->pQueueSend->isEmpty()) 00629 { 00630 if(pChannelListEntry->pQueueSend->isClosed()) //channel was closed by user // Queue: EMPTY + CLOSED 00631 { 00632 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00633 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00634 pChannelListEntry->pSocket->close(); 00635 delete pChannelListEntry->pSocket; 00636 pChannelListEntry->pSocket = NULL; 00637 delete pChannelListEntry->pCipher; 00638 pChannelListEntry->pCipher = NULL; 00639 delete pChannelListEntry->pQueueSend; 00640 pChannelListEntry->pQueueSend = NULL; 00641 m_pChannelList->removeChannel(pChannelListEntry->channelIn); 00642 } 00643 else //Queue: EMPTY+!CLOSED 00644 {//nothing more to write at the moment... 00645 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00646 } 00647 } 00648 } 00649 else 00650 { 00651 if(len==SOCKET_ERROR) 00652 { //do something if send error 00653 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00654 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00655 pChannelListEntry->pSocket->close(); 00656 delete pChannelListEntry->pSocket; 00657 pChannelListEntry->pSocket = NULL; 00658 /* send a close packet signaling the connect error */ 00659 getRandom(pMixPacket->data, DATA_SIZE); 00660 pMixPacket->flags = CHANNEL_CLOSE; 00661 pMixPacket->payload.len = 0; 00662 pMixPacket->payload.type = 0; 00663 #ifdef WITH_INTEGRITY_CHECK 00664 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00665 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00666 #endif 00667 delete pChannelListEntry->pCipher; 00668 pChannelListEntry->pCipher = NULL; 00669 delete pChannelListEntry->pQueueSend; 00670 pChannelListEntry->pQueueSend = NULL; 00671 pMixPacket->channel=pChannelListEntry->channelIn; 00672 #ifdef LOG_PACKET_TIMES 00673 setZero64(pQueueEntry->timestamp_proccessing_start); 00674 #endif 00675 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00676 m_logDownloadedPackets++; 00677 #ifdef LOG_CHANNEL 00678 pChannelListEntry->packetsDataOutToUser++; 00679 #endif 00680 #ifdef LOG_CHANNEL 00681 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00682 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX 00683 #endif 00684 m_pChannelList->removeChannel(pChannelListEntry->channelIn); 00685 } 00686 } 00687 #ifdef HAVE_EPOLL 00688 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheWrite->getNextSignaledSocketData(); 00689 #else 00690 } 00691 pChannelListEntry=m_pChannelList->getNextSocket(); 00692 #endif 00693 } 00694 } 00695 //End Step 2 00696 00697 //Step 3 Reading from Cache.... 00698 00699 countRead=psocketgroupCacheRead->select(0); 00700 #ifdef DELAY_CHANNELS_LATENCY 00701 UINT64 current_time_millis; 00702 getcurrentTimeMillis(current_time_millis); 00703 #endif 00704 if(countRead>0&&m_pQueueSendToMix->getSize()<MAX_MIXIN_SEND_QUEUE_SIZE) 00705 { 00706 #ifdef HAVE_EPOLL 00707 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheRead->getFirstSignaledSocketData(); 00708 while(pChannelListEntry!=NULL) 00709 { 00710 #else 00711 pChannelListEntry=m_pChannelList->getFirstSocket(); 00712 while(pChannelListEntry!=NULL&&countRead>0) 00713 { 00714 if(psocketgroupCacheRead->isSignaled(*(pChannelListEntry->pSocket))) 00715 { 00716 countRead--; 00717 #endif 00718 UINT32 bucketSize; 00719 if((pChannelListEntry->sendmeCounterDownstream<FLOW_CONTROL_SENDME_HARD_LIMIT) 00720 #ifdef DELAY_CHANNELS 00721 &&((bucketSize=m_pChannelList->getDelayBuckets(pChannelListEntry->delayBucketID))>0 ) 00722 #endif 00723 #ifdef DELAY_CHANNELS_LATENCY 00724 &&(isGreater64(current_time_millis,pChannelListEntry->timeLatency)) 00725 #endif 00726 ) 00727 { 00728 #ifndef DELAY_CHANNELS 00729 ret=pChannelListEntry->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE); 00730 #else 00731 UINT32 readLen= 00732 min( 00733 /*m_pChannelList->getDelayBuckets(pChannelListEntry->delayBucketID)*/bucketSize, 00734 PAYLOAD_SIZE); 00735 ret=pChannelListEntry->pSocket->receive(pMixPacket->payload.data,readLen); 00736 #endif 00737 #ifdef LOG_PACKET_TIMES 00738 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start); 00739 set64(pQueueEntry->timestamp_proccessing_start_OP,pQueueEntry->timestamp_proccessing_start); 00740 #endif 00741 bAktiv=true; 00742 if(ret==SOCKET_ERROR||ret==0) 00743 { 00744 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket)); 00745 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket)); 00746 pChannelListEntry->pSocket->close(); 00747 delete pChannelListEntry->pSocket; 00748 pChannelListEntry->pSocket = NULL; 00749 /* send a close packet signaling the connect error */ 00750 getRandom(pMixPacket->data, DATA_SIZE); 00751 pMixPacket->flags = CHANNEL_CLOSE; 00752 pMixPacket->payload.len = 0; 00753 pMixPacket->payload.type = 0; 00754 #ifdef WITH_INTEGRITY_CHECK 00755 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff); 00756 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE); 00757 #endif 00758 delete pChannelListEntry->pCipher; 00759 pChannelListEntry->pCipher = NULL; 00760 delete pChannelListEntry->pQueueSend; 00761 pChannelListEntry->pQueueSend = NULL; 00762 pMixPacket->channel=pChannelListEntry->channelIn; 00763 #ifdef LOG_PACKET_TIMES 00764 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP); 00765 #endif 00766 m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry)); 00767 m_logDownloadedPackets++; 00768 #ifdef LOG_CHANNEL 00769 pChannelListEntry->packetsDataOutToUser++; 00770 #endif 00771 #ifdef LOG_CHANNEL 00772 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00773 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX 00774 #endif 00775 m_pChannelList->removeChannel(pChannelListEntry->channelIn); 00776 } 00777 else 00778 { 00779 add64((UINT64&)m_logDownloadedBytes,ret); 00780 #if defined(LOG_CHANNEL) 00781 pChannelListEntry->trafficOutToUser+=ret; 00782 #endif 00783 #ifdef DELAY_CHANNELS 00784 m_pChannelList->reduceDelayBuckets(pChannelListEntry->delayBucketID, ret); 00785 #endif 00786 pMixPacket->channel=pChannelListEntry->channelIn; 00787 pMixPacket->flags=CHANNEL_DATA; 00788 pMixPacket->payload.type=0; 00789 pMixPacket->payload.len=htons((UINT16)ret); 00790 //#endif 00791 #ifdef WITH_INTEGRITY_CHECK 00792 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, ret + 3, ciphertextBuff); 00793 memcpy(pMixPacket->data, ciphertextBuff, ret + 3 + GCM_MAC_SIZE); 00794 getRandom(pMixPacket->data + ret + 3 + GCM_MAC_SIZE, DATA_SIZE - ret - 3 - GCM_MAC_SIZE); 00795 #else 00796 pChannelListEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00797 #endif 00798 #ifdef LOG_PACKET_TIMES 00799 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP); 00800 #endif 00801 m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry)); 00802 m_logDownloadedPackets++; 00803 #if defined(LOG_CHANNEL) 00804 pChannelListEntry->packetsDataOutToUser++; 00805 #endif 00806 pChannelListEntry->sendmeCounterDownstream++; 00807 } 00808 } 00809 #ifdef HAVE_EPOLL 00810 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheRead->getNextSignaledSocketData(); 00811 #else 00812 } 00813 pChannelListEntry=m_pChannelList->getNextSocket(); 00814 #endif 00815 } 00816 } 00817 //end Step 3 00818 00819 //Step 4 Writing to previous Mix 00820 // Now in a separate Thread! 00821 // 00822 //end step 4 00823 if(!bAktiv) 00824 msSleep(100); 00825 } 00826 00827 00828 00829 00830 //ERR: 00831 CAMsg::printMsg(LOG_CRIT,"Seems that we are restarting now!!\n"); 00832 m_bRunLog=false; 00833 //clean(); 00834 00835 delete []tmpBuff; 00836 tmpBuff = NULL; 00837 delete []rsaBuff; 00838 rsaBuff = NULL; 00839 delete []ciphertextBuff; 00840 ciphertextBuff = NULL; 00841 delete []plaintextBuff; 00842 plaintextBuff = NULL; 00843 delete pQueueEntry; 00844 pQueueEntry = NULL; 00845 pLogThread->join(); 00846 delete pLogThread; 00847 pLogThread = NULL; 00848 delete psocketgroupCacheWrite; 00849 psocketgroupCacheWrite = NULL; 00850 delete psocketgroupCacheRead; 00851 psocketgroupCacheRead = NULL; 00852 #endif //! NEW_MIX_TYPE 00853 return E_UNKNOWN; 00854 } 00855 #endif //ONLY_LOCAL_PROXY
1.7.6.1