void Connection::scramble(const char *_scramble1, const char *_scramble2, UINT8 _outToken[20]) { std::string seed; seed += _scramble1; seed += _scramble2; CSHA1 passdg; UINT8 stage1_hash[20]; passdg.Update ( (UINT8 *) m_password.c_str(), m_password.size()); passdg.Final(); passdg.GetHash(stage1_hash); CSHA1 stage2dg; UINT8 stage2_hash[20]; stage2dg.Update (stage1_hash, 20); stage2dg.Final(); stage2dg.GetHash(stage2_hash); CSHA1 finaldg; UINT8 final_hash[20]; finaldg.Update( (UINT8*) seed.c_str(), seed.size()); finaldg.Update(stage2_hash, 20); finaldg.Final(); finaldg.GetHash(final_hash); for (int index = 0; index < 20; index ++) { _outToken[index] = final_hash[index] ^ stage1_hash[index]; } }
EXPORT_C void CX509Certificate::InternalizeL(RReadStream& aStream) { if (iIssuerName != NULL) //just to check cert is uninitialised { User::Leave(KErrArgument); } iKeyFactory = new(ELeave) TX509KeyFactory; TInt len = aStream.ReadInt32L(); //Read the length of the streamed encoding HBufC8* temp= HBufC8::NewLC(len); TPtr8 ptr=temp->Des(); aStream.ReadL(ptr,len); iEncoding=temp->AllocL(); CleanupStack::PopAndDestroy(); // temp TASN1DecSequence encSeq; TInt pos = 0; CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(*iEncoding, pos, 3, 3); TASN1DecGeneric* encSigAlg = seq->At(1); iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(encSigAlg->Encoding()); TASN1DecBitString encBS; iSignature = encBS.ExtractOctetStringL(*(seq->At(2))); CleanupStack::PopAndDestroy();//seq CSHA1* hash = CSHA1::NewL(); CleanupStack::PushL(hash); iFingerprint = hash->Final(Encoding()).AllocL(); CleanupStack::PopAndDestroy();//hash ConstructCertL(); }
void EncoreBootImage::prepareImageHeader(boot_image_header_t & header) { // get identifier for the first bootable section Section * firstBootSection = findFirstBootableSection(); section_id_t firstBootSectionID = 0; if (firstBootSection) { firstBootSectionID = firstBootSection->getIdentifier(); } // fill in header fields header.m_signature[0] = 'S'; header.m_signature[1] = 'T'; header.m_signature[2] = 'M'; header.m_signature[3] = 'P'; header.m_majorVersion = ROM_BOOT_IMAGE_MAJOR_VERSION; header.m_minorVersion = ROM_BOOT_IMAGE_MINOR_VERSION; header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_headerFlags); header.m_imageBlocks = ENDIAN_HOST_TO_LITTLE_U32(getImageSize()); header.m_firstBootableSectionID = ENDIAN_HOST_TO_LITTLE_U32(firstBootSectionID); header.m_keyCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_keys.size()); header.m_headerBlocks = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(header))); header.m_sectionCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_sections.size()); header.m_sectionHeaderSize = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(section_header_t))); header.m_signature2[0] = 's'; header.m_signature2[1] = 'g'; header.m_signature2[2] = 't'; header.m_signature2[3] = 'l'; header.m_timestamp = ENDIAN_HOST_TO_LITTLE_U64(getTimestamp()); header.m_driveTag = m_driveTag; // Prepare version fields by converting them to the correct byte order. header.m_productVersion = m_productVersion; header.m_componentVersion = m_componentVersion; header.m_productVersion.fixByteOrder(); header.m_componentVersion.fixByteOrder(); // the fields are dependant on others header.m_keyDictionaryBlock = ENDIAN_HOST_TO_LITTLE_U16(header.m_headerBlocks + header.m_sectionCount * header.m_sectionHeaderSize); header.m_firstBootTagBlock = ENDIAN_HOST_TO_LITTLE_U32(header.m_keyDictionaryBlock + header.m_keyCount * 2); // generate random pad bytes RandomNumberGenerator rng; rng.generateBlock(header.m_padding0, sizeof(header.m_padding0)); rng.generateBlock(header.m_padding1, sizeof(header.m_padding1)); // compute SHA-1 digest over the image header uint8_t * message = reinterpret_cast<uint8_t *>(&header.m_signature); uint32_t length = static_cast<uint32_t>(sizeof(header) - sizeof(header.m_digest)); // include padding CSHA1 hash; hash.Reset(); hash.Update(message, length); hash.Final(); hash.GetHash(header.m_digest); }
string sha1(const string& input) { SHA1.Reset(); SHA1.Update((unsigned char *)input.c_str(), input.size()); SHA1.Final(); unsigned char uResult[20]; SHA1.GetHash(uResult); BYTEARRAY MapSHA1 = UTIL_CreateByteArray( uResult, 20 ); string sResult = UTIL_ByteArrayToHexStringWithoutSpaces(MapSHA1); return sResult; }
// ----------------------------------------------------------------------------- // RoapStorageClient::GetDevicePublicKeyHashL // ----------------------------------------------------------------------------- // EXPORT_C TInt Roap::RRoapStorageClient::GetDevicePublicKeyHashL( TDes8& aHash ) { CSHA1* hash = NULL; HBufC8* key = NULL; GetDevicePublicKeyDerL( key ); CleanupStack::PushL( key ); hash = CSHA1::NewL(); CleanupStack::PushL( hash ); hash->Hash( *key ); aHash.Copy( hash->Final() ); CleanupStack::PopAndDestroy( hash ); CleanupStack::PopAndDestroy( key ); return KErrNone; }
static void print_sha1 (ImageInput *input) { imagesize_t size = input->spec().image_bytes (); if (size >= std::numeric_limits<size_t>::max()) { printf (" SHA1 digest: (unable to compute, image is too big)\n"); return; } boost::scoped_array<unsigned char> buf(new unsigned char[(unsigned int)size]); input->read_image (input->spec().format, &buf[0]); CSHA1 sha; sha.Update ((const unsigned char *)&buf[0], (unsigned int) size); sha.Final (); std::string digest; sha.ReportHashStl (digest, CSHA1::REPORT_HEX_SHORT); printf (" SHA-1: %s\n", digest.c_str()); }
string generateSHA(string& value) { CSHA1 sha; sha.Update((UINT_8*)value.c_str(), value.length()); sha.Final(); UINT_8 digest[20]; if (sha.GetHash(digest)) { const int size = sizeof(digest) / sizeof(UINT_8); return binToHex((char*)digest, size); } return ""; }
void TorrentFile::CreateInfoHash() { if(info_len == 0) return; CSHA1 sha; unsigned char * info = new unsigned char[info_len]; for(int i = 0; i < info_len; i++) { info[i] = (unsigned char)m_data[info_start+i]; } sha.Update(info, info_len); sha.Final(); unsigned char * temp = new unsigned char[256]; sha.GetHash(temp); char retStr[61]; retStr[0] = 0; char szTemp[4]; char c[2]; c[1] = 0; for(int i = 0; i < 20; i++) { sprintf(szTemp, "%u", temp[i]); int value = atoi(szTemp); m_info_hash[i] = value; if((value > 0 && value < 255) && (isalnum(value))) { c[0] = value; strcat(retStr, c); } else { c[0] = '%'; strcat(retStr, c); if(value < 16) strcat(retStr, "0"); itoa(value, szTemp, 16); strcat(retStr, szTemp); } } retStr[60] = 0; m_info_hash_string = retStr; delete [] info; info = NULL; delete [] temp; }
CCData *TimeHashVerifier::encode_verification(CCString *private_key, CCString *public_key, CCString *secret_key) { time_t now = this->time_gen(NULL); CSHA1 hexhash; char timehex[9] = {0,}; sprintf(timehex, "%08lx", now); hexhash.Update((UINT_8 *)private_key->getCString(), private_key->length()); hexhash.Update((UINT_8 *)public_key->getCString(), public_key->length()); hexhash.Update((UINT_8 *)timehex, 8); hexhash.Final(); unsigned char hexhashbin[20]; hexhash.GetHash(hexhashbin); char hexhashhex[41] = {0,}; for (int i = 0; i < 20; i++) { sprintf(hexhashhex + i * 2, "%02x", hexhashbin[i]); } int verification_len = public_key->length() + 1 + 8 + 40; char verification[verification_len + 1]; bzero(verification, verification_len + 1); sprintf(verification, "%s$%8lx%s", public_key->getCString(), now, hexhashhex); CCData *data = new CCData(new CCData((unsigned char *)verification, verification_len)); //data->autorelease(); return data; }
void CX509Certificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos) { TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos)); gen.InitL(); // The outermost tag for X509 certificates is always a sequence. // Since this tag does not form part of the signed data it is possible // to corrupt the tag by changing it to any other ASN.1 tag and process // the rest of the certificate as normal. // However, we still reject the certificate anyway to avoid // confusion because the data does not match the X.509 specification. if (gen.Tag() != EASN1Sequence) { User::Leave(KErrArgument); } aPos += gen.LengthDER(); iKeyFactory = new(ELeave) TX509KeyFactory; iEncoding = gen.Encoding().AllocL(); TASN1DecSequence encSeq; TInt pos = 0; CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(*iEncoding, pos, 3, 3); TASN1DecGeneric* encSigAlg = seq->At(1); iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(encSigAlg->Encoding()); TASN1DecBitString encBS; iSignature = encBS.ExtractOctetStringL(*(seq->At(2))); CleanupStack::PopAndDestroy();//seq CSHA1* hash = CSHA1::NewL(); CleanupStack::PushL(hash); iFingerprint = hash->Final(Encoding()).AllocL(); CleanupStack::PopAndDestroy();//hash ConstructCertL(); }
//! \todo Optimize writing section data. Right now it only writes one block at a //! time, which is of course quite slow (in relative terms). //! \todo Refactor this into several different methods for writing each region //! of the image. Use a context structure to keep track of shared data between //! each of the methods. //! \todo Refactor the section and boot tag writing code to only have a single //! copy of the block writing and encryption loop. void EncoreBootImage::writeToStream(std::ostream & stream) { // always generate the session key or DEK even if image is unencrypted m_sessionKey.randomize(); // prepare to compute CBC-MACs with each KEK unsigned i; smart_array_ptr<RijndaelCBCMAC> macs(0); if (isEncrypted()) { macs = new RijndaelCBCMAC[m_keys.size()]; for (i=0; i < m_keys.size(); ++i) { RijndaelCBCMAC mac(m_keys[i]); (macs.get())[i] = mac; } } // prepare to compute SHA-1 digest over entire image CSHA1 hash; hash.Reset(); // count of total blocks written to the file unsigned fileBlocksWritten = 0; // we need some pieces of the header down below boot_image_header_t imageHeader; prepareImageHeader(imageHeader); // write plaintext header { // write header assert(sizeOfPaddingForCipherBlocks(sizeof(boot_image_header_t)) == 0); stream.write(reinterpret_cast<char *>(&imageHeader), sizeof(imageHeader)); fileBlocksWritten += numberOfCipherBlocks(sizeof(imageHeader)); // update CBC-MAC over image header if (isEncrypted()) { for (i=0; i < m_keys.size(); ++i) { (macs.get())[i].update(reinterpret_cast<uint8_t *>(&imageHeader), sizeof(imageHeader)); } } // update SHA-1 hash.Update(reinterpret_cast<uint8_t *>(&imageHeader), sizeof(imageHeader)); } // write plaintext section table { section_iterator_t it = beginSection(); for (; it != endSection(); ++it) { Section * section = *it; // write header for this section assert(sizeOfPaddingForCipherBlocks(sizeof(section_header_t)) == 0); section_header_t sectionHeader; section->fillSectionHeader(sectionHeader); stream.write(reinterpret_cast<char *>(§ionHeader), sizeof(sectionHeader)); fileBlocksWritten += numberOfCipherBlocks(sizeof(sectionHeader)); // update CBC-MAC over this entry if (isEncrypted()) { for (i=0; i < m_keys.size(); ++i) { (macs.get())[i].update(reinterpret_cast<uint8_t *>(§ionHeader), sizeof(sectionHeader)); } } // update SHA-1 hash.Update(reinterpret_cast<uint8_t *>(§ionHeader), sizeof(sectionHeader)); } } // finished with the CBC-MAC if (isEncrypted()) { for (i=0; i < m_keys.size(); ++i) { (macs.get())[i].finalize(); } } // write key dictionary if (isEncrypted()) { key_iterator_t it = beginKeys(); for (i=0; it != endKeys(); ++it, ++i) { // write CBC-MAC result for this key, then update SHA-1 RijndaelCBCMAC & mac = (macs.get())[i]; const RijndaelCBCMAC::block_t & macResult = mac.getMAC(); stream.write(reinterpret_cast<const char *>(&macResult), sizeof(RijndaelCBCMAC::block_t)); hash.Update(reinterpret_cast<const uint8_t *>(&macResult), sizeof(RijndaelCBCMAC::block_t)); fileBlocksWritten++; // encrypt DEK with this key, write it out, and update image digest Rijndael cipher; cipher.init(Rijndael::CBC, Rijndael::Encrypt, *it, Rijndael::Key16Bytes, imageHeader.m_iv); AESKey<128>::key_t wrappedSessionKey; cipher.blockEncrypt(m_sessionKey, sizeof(AESKey<128>::key_t) * 8, wrappedSessionKey); stream.write(reinterpret_cast<char *>(&wrappedSessionKey), sizeof(wrappedSessionKey)); hash.Update(reinterpret_cast<uint8_t *>(&wrappedSessionKey), sizeof(wrappedSessionKey)); fileBlocksWritten++; } } // write sections and boot tags { section_iterator_t it = beginSection(); for (; it != endSection(); ++it) { section_iterator_t itCopy = it; bool isLastSection = (++itCopy == endSection()); Section * section = *it; cipher_block_t block; unsigned blockCount = section->getBlockCount(); unsigned blocksWritten = 0; Rijndael cipher; cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv); // Compute the number of padding blocks needed to align the section. This first // call to getPadBlockCountForOffset() passes an offset that excludes // the boot tag for this section. unsigned paddingBlocks = getPadBlockCountForSection(section, fileBlocksWritten); // Insert nop commands as padding to align the start of the section, if // the section has special alignment requirements. NopCommand nop; while (paddingBlocks--) { blockCount = nop.getBlockCount(); blocksWritten = 0; while (blocksWritten < blockCount) { nop.getBlocks(blocksWritten, 1, &block); if (isEncrypted()) { // re-init after encrypt to update IV cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block); cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block); } stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t)); hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t)); blocksWritten++; fileBlocksWritten++; } } // reinit cipher for boot tag cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv); // write boot tag TagCommand tag(*section); tag.setLast(isLastSection); if (!isLastSection) { // If this isn't the last section, the tag needs to include any // padding for the next section in its length, otherwise the ROM // won't be able to find the next section's boot tag. unsigned nextSectionOffset = fileBlocksWritten + section->getBlockCount() + 1; tag.setSectionLength(section->getBlockCount() + getPadBlockCountForSection(*itCopy, nextSectionOffset)); } blockCount = tag.getBlockCount(); blocksWritten = 0; while (blocksWritten < blockCount) { tag.getBlocks(blocksWritten, 1, &block); if (isEncrypted()) { // re-init after encrypt to update IV cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block); cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block); } stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t)); hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t)); blocksWritten++; fileBlocksWritten++; } // reinit cipher for section data cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv); // write section data blockCount = section->getBlockCount(); blocksWritten = 0; while (blocksWritten < blockCount) { section->getBlocks(blocksWritten, 1, &block); // Only encrypt the section contents if the entire boot image is encrypted // and the section doesn't have the "leave unencrypted" flag set. Even if the // section is unencrypted the boot tag will remain encrypted. if (isEncrypted() && !section->getLeaveUnencrypted()) { // re-init after encrypt to update IV cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block); cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block); } stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t)); hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t)); blocksWritten++; fileBlocksWritten++; } } } // write SHA-1 digest over entire image { // allocate enough room for digest and bytes to pad out to the next cipher block const unsigned padBytes = sizeOfPaddingForCipherBlocks(sizeof(sha1_digest_t)); unsigned digestBlocksSize = sizeof(sha1_digest_t) + padBytes; smart_array_ptr<uint8_t> digestBlocks = new uint8_t[digestBlocksSize]; hash.Final(); hash.GetHash(digestBlocks.get()); // set the pad bytes to random values RandomNumberGenerator rng; rng.generateBlock(&(digestBlocks.get())[sizeof(sha1_digest_t)], padBytes); // encrypt with session key if (isEncrypted()) { Rijndael cipher; cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv); cipher.blockEncrypt(digestBlocks.get(), digestBlocksSize * 8, digestBlocks.get()); } // write to the stream stream.write(reinterpret_cast<char *>(digestBlocks.get()), digestBlocksSize); } }
// Thread which gets lines from the DCC Q, and processes it. void DCCThr(XChange *XGlobal) { char IRC_Line[1024]; IRCLineInterpret LineInterpret; TCPConnect *DCCChat, *FServChat, *DCCAccept, *SwarmConnect; DCC_Container_t *DCC_Container; THR_EXITCODE thr_exit = 1; THR_HANDLE DCCChatThrH = 0, FileServerThrH = 0, TransferThrH = 0; bool retvalb; int retval; char MyNick[64]; LineParse LineP; const char *parseptr; char *tmpbuf; CSHA1 SHA; FilesDetail *FD; char Response[1024]; Helper H; TCPConnect T; // Just for a little help. THREADID tempTID; size_t my_resume_position; char DotIp[20]; // cant be more than 3 + 1 + 3 + 1 + 3 + 1 + 3 int SwarmIndex; bool isSwarmed; TRACE_INIT_CRASH("DCCThr"); TRACE(); H.init(XGlobal); while (true) { XGlobal->IRC_DCC.getLineAndDelete(IRC_Line); if (XGlobal->isIRC_QUIT()) break; if (XGlobal->isIRC_DisConnected()) continue; LineInterpret = IRC_Line; switch (LineInterpret.Command) { case IC_CTCPFILESHA1REPLY: // Compare FileName, FileSize, SHA1 and update Server UI. // If FileSize = 0 and SHA1 = 0, => error string present in FileName XGlobal->lock(); if ( (XGlobal->SHA1_FileName) && (XGlobal->SHA1_SHA1) && (strcasecmp(LineInterpret.FileName, XGlobal->SHA1_FileName) == 0) && (LineInterpret.FileSize == XGlobal->SHA1_FileSize) ) { // Reply matches what we are waiting for. // Compare SHAs if (strcasecmp(XGlobal->SHA1_SHA1, LineInterpret.InfoLine) == 0) { sprintf(Response, "Server 04[%s FILECHECK REPLY]: \"%s\" can be resumed from me", LineInterpret.From.Nick, LineInterpret.FileName); } else { sprintf(Response, "Server 04[%s FILECHECK REPLY]: \"%s\" CANNOT be resumed from me", LineInterpret.From.Nick, LineInterpret.FileName); } // Delete the Global as we are done with this. delete [] XGlobal->SHA1_FileName; XGlobal->SHA1_FileName = NULL; delete [] XGlobal->SHA1_SHA1; XGlobal->SHA1_SHA1 = NULL; } else { sprintf(Response, "Server 04[%s FILECHECK REPLY]: %s", LineInterpret.From.Nick, LineInterpret.FileName); } XGlobal->unlock(); XGlobal->IRC_ToUI.putLine(Response); break; case IC_CTCPFILESHA1: // Reply back to his request with a IC_CTCPFILESHA1REPLY // Same thing that we did in the UI to generate IC_CTCPFILESHA1 // Here we will search for the file in MyFilesDB. If not found // there, we use MyPartialFilesDB. FD = XGlobal->MyFilesDB.getFilesDetailListMatchingFileName(LineInterpret.FileName); if (FD == NULL) { // Lets try MyPartialFilesDB. FD = XGlobal->MyPartialFilesDB.getFilesDetailListMatchingFileName(LineInterpret.FileName); if (FD == NULL) { sprintf(Response, "Server 04[%s FILECHECK]: File: %s FileSize: %lu - We do not have this file.", LineInterpret.From.Nick, LineInterpret.FileName, LineInterpret.FileSize); XGlobal->IRC_ToUI.putLine(Response); sprintf(Response, "NOTICE %s :\001FILESHA1 0 0 I do not have the file requested: %s\001", LineInterpret.From.Nick, LineInterpret.FileName); XGlobal->IRC_ToServer.putLine(Response); break; } else { // File in MyPartialFilesDB. Prepare filename in Response XGlobal->lock(); sprintf(Response, "%s%s%s", XGlobal->PartialDir, DIR_SEP, LineInterpret.FileName); XGlobal->unlock(); } } else { // File in MyFilesDB. Prepare filename in Response XGlobal->lock(); if (FD->DirName) { sprintf(Response, "%s%s%s%s%s", XGlobal->ServingDir[FD->ServingDirIndex], DIR_SEP, FD->DirName, DIR_SEP, LineInterpret.FileName); } else { sprintf(Response, "%s%s%s", XGlobal->ServingDir[FD->ServingDirIndex], DIR_SEP, LineInterpret.FileName); } XGlobal->unlock(); } XGlobal->MyFilesDB.freeFilesDetailList(FD); FD = NULL; // we are here => Response has full file path. tmpbuf = new char[FILE_RESUME_GAP]; if (getFileResumeChunk(Response, LineInterpret.FileSize, tmpbuf) == false) { sprintf(Response, "Server 04[%s FILECHECK]: File: %s FileSize: %lu - Error Reading Chunk.", LineInterpret.From.Nick, LineInterpret.FileName, LineInterpret.FileSize); XGlobal->IRC_ToUI.putLine(Response); sprintf(Response, "NOTICE %s :\001FILESHA1 0 0 Error reading chunk: %s\001", LineInterpret.From.Nick, LineInterpret.FileName); XGlobal->IRC_ToServer.putLine(Response); delete [] tmpbuf; break; } SHA.Reset(); SHA.Update((UINT_8 *) tmpbuf, (UINT_32) FILE_RESUME_GAP); SHA.Final(); SHA.ReportHash(tmpbuf); sprintf(Response, "Server 04[%s FILECHECK]: File: %s FileSize: %lu.", LineInterpret.From.Nick, LineInterpret.FileName, LineInterpret.FileSize); XGlobal->IRC_ToUI.putLine(Response); sprintf(Response, "NOTICE %s :\001FILESHA1 %lu %s %s\001", LineInterpret.From.Nick, LineInterpret.FileSize, tmpbuf, LineInterpret.FileName); XGlobal->IRC_ToServer.putLine(Response); delete [] tmpbuf; break; case IC_USERHOST: char windowname[32]; unsigned long longip, myip; char *correct_nick; COUT(cout << "IC_USERHOST: IRCLine: " << IRC_Line << endl;) COUT(LineInterpret.printDebug();) // InfoLine contains: [email protected] // batata_wada*[email protected] (ircop) // We parse it nice and update XGlobal with dotted ip and long ip // if its our nick, and update NickList with long ip. LineP = LineInterpret.InfoLine; LineP.setDeLimiter('@'); parseptr = LineP.getWord(2); longip = T.getLongFromHostName((char *) parseptr); T.getDottedIpAddressFromLong(longip, DotIp); // Lets get our nick. XGlobal->getIRC_Nick(MyNick); XGlobal->resetIRC_Nick_Changed(); LineP.setDeLimiter('='); parseptr = LineP.getWord(1); correct_nick = new char[strlen(parseptr) + 1]; strcpy(correct_nick, parseptr); if (correct_nick[strlen(correct_nick) - 1] == '*') { // Remove the * at end of ircop nick. correct_nick[strlen(correct_nick) - 1] = '\0'; } // correct_nick contains corrected nick. if (strcasecmp(correct_nick, MyNick) == 0) { // Its my own Nick XGlobal->putIRC_IP(longip, DotIp); sprintf(Response, "Server 09USERHOST: DottedIP: %s LongIP: %lu", DotIp, longip); XGlobal->IRC_ToUI.putLine(Response); } // Update the XGlobal->NickList XGlobal->NickList.setNickIP(correct_nick, longip); // For testing. if (longip != 0) { sprintf(Response, "Server 09USERHOST: Nick: %s DottedIP: %s LongIP: %lu", correct_nick, DotIp, longip); } else { sprintf(Response, "Server 04USERHOST: Nick: %s DottedIP: %s LongIP: %lu", correct_nick, DotIp, longip); } XGlobal->IRC_ToUI.putLine(Response); // If the USERHOST response is of Nick which is same as in // XChange->DCCChatnick, then we need to try to Chat with this nick. retval = 1; XGlobal->lock(); if (XGlobal->DCCChatNick) { retval = strcasecmp(correct_nick, XGlobal->DCCChatNick); } XGlobal->unlock(); if (retval == 0) { FilesDetail *FD; XGlobal->lock(); delete [] XGlobal->DCCChatNick; XGlobal->DCCChatNick = NULL; XGlobal->unlock(); // Check if a DCCChat is already in progress. (allow only 1) if (XGlobal->DCCChatInProgress.getCount(NULL) != 0) { sprintf(Response, "Server * 04DCC-CHAT: A CHAT is already in progress."); XGlobal->IRC_ToUI.putLine(Response); delete [] correct_nick; break; } if (longip != 0) { // Try to connect to his DCCServer as a CHAT. TCPConnect *DCCChat = new TCPConnect; DCCChat->TCPConnectionMethod = XGlobal->getIRC_CM(); XGlobal->resetIRC_CM_Changed(); retvalb = DCCChat->getConnection(DotIp, DCCSERVER_PORT); Response[0] = '\0'; if (retvalb) { // Connection was successful sprintf(Response, "100 %s\n", MyNick); DCCChat->writeData(Response, strlen(Response), DCCSERVER_TIMEOUT); retval = DCCChat->readLine(Response, sizeof(Response) - 1, DCCSERVER_TIMEOUT); LineP = Response; parseptr = LineP.getWord(1); if (retval && strcasecmp(parseptr, "101") == 0) { // Now also check if the nick matches. Else he has some // other client listening at that port. parseptr = LineP.getWord(2); if (strcasecmp(parseptr, correct_nick) == 0) { // We have established a CHAT. // Now we pass the buck on to the DCC Chat Thr // It will add it in DCCChatInProgress etc. COUT(cout << "DCCChatThr: IC_DCC_CHAT (DCC)" << endl;) // Here we spawn a thread to take care of this DCC Chat. // We pass it the ESTABLISED connection // The created thread should free this structure before exiting. DCC_Container = new DCC_Container_t; DCC_CONTAINER_INIT(DCC_Container); DCC_Container->RemoteNick = new char [strlen(parseptr) + 1]; strcpy(DCC_Container->RemoteNick, parseptr); DCC_Container->Connection = DCCChat; DCC_Container->XGlobal = XGlobal; // Have to set DCC_Container->RemoteLongIP. DCC_Container->RemoteDottedIP = new char[strlen(DotIp) + 1]; strcpy(DCC_Container->RemoteDottedIP, DotIp); DCC_Container->RemoteLongIP = longip; #ifdef __MINGW32__ DCCChatThrH = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DCCChatThr, DCC_Container, 0, &tempTID); #else { pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); pthread_create(&DCCChatThrH, &thread_attr, (void * (*)(void *)) DCCChatThr, DCC_Container); } #endif delete [] correct_nick; break; }