void OutPacket::encryptBody(unsigned char *b, int length, unsigned char *body, int *bodyLen) { switch(command){ case QQ_CMD_SERVER_DETECT: case QQ_CMD_REQUEST_LOGIN_TOKEN: case QQ_CMD_LOGIN: *bodyLen = length; memcpy(body, b, length); break; case QQ_CMD_REQUEST_LOGIN_TOKEN_EX:{ memcpy(body, QQ_Client_Key, 16); EvaCrypt::encrypt(b, length, (unsigned char*)(QQ_Client_Key), body+16, bodyLen); (*bodyLen) +=16; } break; default:{ unsigned char * sessionKey = getSessionKey(); if(sessionKey == NULL) { fprintf(stderr, "OutPacket->encryptBody: sessionkey not set yet, set encrypted length to 0\n"); *bodyLen = 0; return; } EvaCrypt::encrypt(b, length, sessionKey, body, bodyLen); } } }
KeyExchangeSession::KeyExchangeSession(int protocol, const dtn::data::EID &peer, unsigned int uniqueId, SessionState *state) : _protocol(protocol), _unique_id(uniqueId), _peer(peer.getNode()), _state(state), _expiration(0) { // generate session key _session_key = getSessionKey(_peer, _unique_id); // set a expiration time (10 minutes) _expiration = dtn::utils::Clock::getMonotonicTimestamp() + 600; }
/** * Opens a connection, exchanges a session key and * communicates with symmetric encryption using the * session key */ int main(int argc , char *argv[]){ /* Wait for a connection */ int client_sock = openConnection(); /* exchange encryption keys */ unsigned char *session_key = getSessionKey(client_sock); /* client-server communication */ serverLoop(client_sock, session_key); return 0; }
void Authenticator::FeedPassword (bool authFailure) { const QString& login = XmlSettingsManager::Instance () .property ("lastfm.login").toString (); lastfm::ws::Username = login; if (login.isEmpty ()) return; const auto& text = tr ("Enter password for Last.fm account with login %1:") .arg (login); const auto& password = Util::GetPassword ("org.LeechCraft.Lastfmscrobble/" + login, text, Proxy_, !authFailure); if (password.isEmpty ()) return; const QString& authToken = AuthToken (lastfm::ws::Username, password); const QString& api_sig = ApiSig (lastfm::ws::ApiKey, authToken, "auth.getMobileSession", lastfm::ws::Username, lastfm::ws::SharedSecret); const QString& url = QString ("%1?method=%2&username=%3&authToken=%4&api_key=%5&api_sig=%6") .arg (ScrobblingSite) .arg ("auth.getMobileSession") .arg (lastfm::ws::Username) .arg (authToken) .arg (lastfm::ws::ApiKey) .arg (api_sig); QNetworkReply *reply = NAM_->get (QNetworkRequest (QUrl (url))); connect (reply, SIGNAL (finished ()), this, SLOT (getSessionKey ())); }
//////////////////////////////////////////////////// // handle a new packet on the stream void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet) { emit numPacket(++m_packetCount, (int)m_streamid); // Packet is ours now. Logging needs to know this later on. packet.setSessionKey(getSessionKey()); // Only accept packets if we've been initialized unless they are // initialization packets! if (packet.getNetOpCode() != OP_SessionRequest && packet.getNetOpCode() != OP_SessionResponse && ! m_sessionKey) { #if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1) seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.", (const char*)packet.getIPv4SourceA(), packet.getSourcePort(), (const char*)packet.getIPv4DestA(), packet.getDestPort(), packet.getNetOpCode(), packet.payloadLength(), (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif return; } // Only accept packets that correspond to our latched client port, if // it is set. This helps filter out multiple sessions on the same physical // host when two eq clients zone at the same time. The first one will win. if (m_sessionClientPort != 0 && ((dir() == DIR_Server && m_sessionClientPort != packet.getDestPort()) || (dir() == DIR_Client && m_sessionClientPort != packet.getSourcePort()))) { #if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1) seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Multiple sessions on the same box? Ignoring all but one of them. Latched client port %d. Session tracking %s.", (const char*)packet.getIPv4SourceA(), packet.getSourcePort(), (const char*)packet.getIPv4DestA(), packet.getDestPort(), packet.getNetOpCode(), packet.payloadLength(), m_sessionClientPort, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif return; } // Only accept packets that pass the EQ protocol-level CRC check. This helps // weed out non-EQ packets that we might see. #ifdef APPLY_CRC_CHECK if (packet.hasCRC()) { uint16_t calcedCRC = calculateCRC(packet); if (calcedCRC != packet.crc()) { seqWarn("INVALID PACKET: Bad CRC [%s:%d -> %s:%d] netOp %04x seq %04x len %d crc (%04x != %04x)", (const char*)packet.getIPv4SourceA(), packet.getSourcePort(), (const char*)packet.getIPv4DestA(), packet.getDestPort(), packet.getNetOpCode(), packet.arqSeq(), packet.getUDPPayloadLength(), packet.crc(), calcedCRC); return; } } #endif /* APPLY_CRC_CHECK */ // Decode the packet first if (! packet.decode(m_maxLength)) { seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.", EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), packet.getFlags()); return; } #ifdef PACKET_DECODE_DIAG else if (packet.hasFlags()) { seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.", EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), packet.getFlags()); } #endif // Raw packet emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, packet.getNetOpCode()); processPacket(packet, false); // false = isn't subpacket // if the cache isn't empty, then process it. if (!m_cache.empty()) processCache(); }
void LoginReplyPacket::parseBody() { replyCode = decryptedBuf[0]; switch(replyCode) { case TQQ_LOGIN_REPLY_OK: { // length of 16 bytes: 001-016, session key setSessionKey(decryptedBuf+1); // 4 bytes: 017-020, user id(QQ number) qqNum = ntohl( *((int *)(decryptedBuf + TQQ_KEY_LENGTH + 1) ) ); // now we can set the file session key char *fsbuf = new char[TQQ_KEY_LENGTH + 4]; // copy the big endian qqNum directly memcpy(fsbuf, decryptedBuf + TQQ_KEY_LENGTH + 1 , 4); // qqNum in network bytes order // then, the session key memcpy(fsbuf+4, getSessionKey(), TQQ_KEY_LENGTH); // save it as the file session key setFileSessionKey((unsigned char *)EvaUtil::doMd5(fsbuf, 4 + TQQ_KEY_LENGTH)); delete []fsbuf; // 021-024 user IP IP = ntohl(* ((int *)(decryptedBuf + 21)) ); // 025-026 user port port = ntohs(* ((short *)(decryptedBuf + 25)) ); // 027-030 server IP ( always 127.0.0.1 in QQ2006 standard) serverIP = ntohl(* ((int *)(decryptedBuf + 27)) ); // 031-032 server port ( should be 0x1f40(8000) ) serverPort = ntohs(* ((short *)(decryptedBuf + 31)) ); // 033-036 login time loginTime = ntohl(* ((int *)(decryptedBuf + 33)) ); /// 037-038 2 unknown bytes // 039-062 file share token used in Qun disk share file access setFileShareToken(decryptedBuf+39); /// 063 -> 082: unknown bytes // 83-114 client key for QQ Home setClientKey(decryptedBuf+83, 32); // always 32 bytes long /// 115 - 118, unknown 4 bytes ( 0x00 00 00 01) /// 119 - 126, unknown 8 bytes, all 0x0s // 127-130 user IP when last login lastLoginIP = ntohl(* ((int *)(decryptedBuf + 127)) ); // 131-134 last login time, not sure lastLoginTime = ntohl(* ((int *)(decryptedBuf + 131)) ); // 135 - 138 might be IP, 4 bytes // 139 - 142 might be IP, 4 bytes // 143 -183 unknow bytes break; } case TQQ_LOGIN_REPLY_REDIRECT: // redirect user to another server for balance reason { // 001-004 user qq number qqNum = ntohl(* ((int *)(decryptedBuf + 1)) ); // 005-008 the new server IP address redirectedIP = ntohl(* ((int *)(decryptedBuf + 5)) ); // 009-010 the new server's Port number redirectedPort = ntohs(* ((short *)(decryptedBuf + 9)) ); break; } case TQQ_LOGIN_REPLY_PWD_ERROR: case TQQ_LOGIN_REPLY_NEED_REACTIVATE: // message from server when password is wrong. the messege is encoded by "GB18030" { char *tmpMsg = new char[bodyLength]; memcpy(tmpMsg, decryptedBuf+1, bodyLength-1); tmpMsg[bodyLength-1]=0; replyMessage.assign(tmpMsg); delete []tmpMsg; break; } case TQQ_LOGIN_REPLY_REDIRECT_EX: // redirect user to another server for balance reason { // 001-004 user qq number qqNum = ntohl(* ((int *)(decryptedBuf + 1)) ); /// 5 - 14, 10 unknown bytes // 005-008 the new server IP address redirectedIP = ntohl(* ((int *)(decryptedBuf + 15)) ); redirectedPort = -1; printf("login reply(first byte is reply code)\n"); for(int i=0; i<bodyLength; i++){ if(!(i%8)) printf("\n%d: ",i); char t = decryptedBuf[i]; printf("%2x ", (uint8_t)t); } printf("\n"); break; } case TQQ_LOGIN_REPLY_PWD_ERROR_EX: { char *tmpMsg = new char[bodyLength]; memcpy(tmpMsg, decryptedBuf+1, bodyLength-1); tmpMsg[bodyLength-1]=0; replyMessage.assign(tmpMsg); delete []tmpMsg; } break; default: replyCode = TQQ_LOGIN_REPLY_MISC_ERROR; { printf("login unknown reply(first byte is reply code)\n"); for(int i=0; i<bodyLength; i++){ if(!(i%8)) printf("\n%d: ",i); char t = decryptedBuf[i]; printf("%2x ", (uint8_t)t); } printf("\n"); } break; } }
string Subject::registerObserver(shared_ptr<Observer> observer) { observerList.push_front(weak_ptr<Observer>(observer)); return getSessionKey(); }
void InPacket::decryptBody(unsigned char * buf, int len) { int ret = 0; bodyLength = MAX_PACKET_SIZE; unsigned char * passwordKey = getPasswordKey(); unsigned char * sessionKey = getSessionKey(); /* if(command == QQ_CMD_REQUEST_LOGIN_TOKEN ){ memcpy(decryptedBuf, buf, len); bodyLength = len; return; } if(passwordKey == NULL) { fprintf(stderr, "InPacket->decryptBody: password key not set yet, set decrypted length to 0\n"); bodyLength = 0; return; } if((command != QQ_CMD_LOGIN) && (sessionKey == NULL)) { fprintf(stderr, "InPacket->decryptBody: session key not set yet, set decrypted length to 0\n"); command = -1; bodyLength = 0; return; } if(command == QQ_CMD_LOGIN) { ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength); if(ret == 0){ bodyLength = MAX_PACKET_SIZE; ret = EvaCrypt::decrypt(buf, len, iniKey, decryptedBuf, &bodyLength); if(ret == 0){ printf("CANNOT DECRYPT! ----- login reply data(len:%d):\n", len); for(int i=0; i<len; i++){ if(!(i%8)) printf("\n%d: ",i); char t = buf[i]; printf("%2x ", (unsigned char)t); } printf("\n"); } } } else { ret = EvaCrypt::decrypt(buf, len, sessionKey, decryptedBuf, &bodyLength); if(ret == 0){ bodyLength = MAX_PACKET_SIZE; ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength); } } if(ret == 0) bodyLength = 0; */ switch(command){ case QQ_CMD_REQUEST_LOGIN_TOKEN: memcpy(decryptedBuf, buf, len); bodyLength = len; ret = 1; break; case QQ_CMD_SERVER_DETECT: case QQ_CMD_REQUEST_LOGIN_TOKEN_EX: ret = EvaCrypt::decrypt(buf, len, (unsigned char *)(QQ_Client_Key), decryptedBuf, &bodyLength); if(ret == 0){ fprintf(stderr, "InPacket->decryptBody: cannot decryt reply packet( command: 0x%2x\n", command); } break; case QQ_CMD_LOGIN: if(passwordKey == NULL) { fprintf(stderr, "InPacket->decryptBody: password key not set yet, set decrypted length to 0\n"); command = -1; bodyLength = 0; return; } ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength); if(ret == 0){ bodyLength = MAX_PACKET_SIZE; ret = EvaCrypt::decrypt(buf, len, iniKey, decryptedBuf, &bodyLength); if(ret == 0){ printf("CANNOT DECRYPT! ----- login reply data(len:%d):\n", len); for(int i=0; i<len; i++){ if(!(i%8)) printf("\n%d: ",i); char t = buf[i]; printf("%2x ", (unsigned char)t); } printf("\n"); } } break; default: if(sessionKey == NULL) { fprintf(stderr, "InPacket->decryptBody: session key not set yet, set decrypted length to 0\n"); command = -1; bodyLength = 0; break; } ret = EvaCrypt::decrypt(buf, len, sessionKey, decryptedBuf, &bodyLength); if(ret == 0){ if(passwordKey == NULL) { fprintf(stderr, "InPacket->decryptBody: password key not set yet, set decrypted length to 0\n"); bodyLength = 0; return; } bodyLength = MAX_PACKET_SIZE; ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength); } break; } if(ret == 0){ bodyLength = 0; } }