void* rpmain(void* ctSock) { int sd, ct_sd, pc_sd; struct sockaddr_in replyaddr; ct_sd = *((int*)ctSock); if((pc_sd = getSockFromSock(ct_sd)) < 0) { printf("RP: Unable to receive socket to PC.\n"); pthread_exit(NULL); } if((sd = setupSocket(0)) < 0) { printf("RP: Unable to set up socket\n"); pthread_exit(NULL); } if(createAddr(htonl(INADDR_ANY), &replyaddr) == -1) { printf("RP: Unable to set up reply address\n"); pthread_exit(NULL); } while(1) { fd_set set; FD_ZERO(&set); FD_SET(ct_sd, &set); FD_SET(pc_sd, &set); if(select(((ct_sd > pc_sd) ? ct_sd : pc_sd) + 1, &set, NULL, NULL, NULL) == -1) { printf("Select error in RP\n"); close(sd); close(ct_sd); close(pc_sd); pthread_exit(NULL); } if(FD_ISSET(ct_sd, &set)) { switch(handleCommands(ct_sd)) { case 1: printf("rp shutting down.\n"); close(sd); close(ct_sd); close(pc_sd); pthread_exit(NULL); break; case -1: printf("RP:\tError while processing commands.\n"); close(sd); close(ct_sd); close(pc_sd); pthread_exit(NULL); break; } } if(FD_ISSET(pc_sd, &set)) { heartbeat* h; unsigned int len; h = getHeartbeatFromSock(pc_sd); if(h == NULL) { printf("RP:\tError while fetching heartbeat from PC\n"); close(sd); close(pc_sd); close(ct_sd); pthread_exit(NULL); } response* r = craftResponse(h); if(r == NULL) { printf("RP:\tError while crafting response\n"); close(sd); close(pc_sd); close(ct_sd); pthread_exit(NULL); } char* b = serializeResponse(r, &len); if(b == NULL) { printf("RP:\nError serializing response\n"); close(sd); close(pc_sd); close(ct_sd); pthread_exit(NULL); } ssize_t rc = sendto(sd, b, len, 0, (struct sockaddr*)&replyaddr, sizeof(replyaddr)); freeHeartbeat(h); free(r); free(b); if(rc < 0) { perror("sendto error"); close(sd); close(pc_sd); close(ct_sd); pthread_exit(NULL); } } } }
bool SASLAuthFeature::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE) { if (AStanza.kind() == "challenge") { QByteArray challengeData = QByteArray::fromBase64(AStanza.element().text().toLatin1()); LOG_STRM_DEBUG(FXmppStream->streamJid(),QString("SASL auth challenge received: %1").arg(QString::fromUtf8(challengeData))); QMap<QByteArray, QByteArray> responseMap; QMap<QByteArray, QByteArray> challengeMap = parseChallenge(challengeData); if (challengeMap.value("qop") == "auth") { QByteArray randBytes(32,' '); for (int i=0; i<randBytes.size(); i++) randBytes[i] = (char) (256.0 * qrand() / (RAND_MAX + 1.0)); responseMap["cnonce"] = randBytes.toHex(); if (challengeMap.contains("realm")) responseMap["realm"] = challengeMap.value("realm"); else responseMap["realm"] = FXmppStream->streamJid().pDomain().toUtf8(); responseMap["username"] = FXmppStream->streamJid().pNode().toUtf8(); responseMap["nonce"] = challengeMap.value("nonce"); responseMap["nc"] = "00000001"; responseMap["qop"] = "auth"; responseMap["digest-uri"] = QString("xmpp/%1").arg(FXmppStream->streamJid().pDomain()).toUtf8(); responseMap["charset"] = "utf-8"; responseMap["response"] = getResponseValue(responseMap,FXmppStream->password()); } QByteArray responseData = serializeResponse(responseMap); Stanza response("response",NS_FEATURE_SASL); response.element().appendChild(response.createTextNode(responseData.toBase64())); FXmppStream->sendStanza(response); LOG_STRM_DEBUG(FXmppStream->streamJid(),QString("SASL auth response sent: %1").arg(QString::fromUtf8(responseData))); } else { FXmppStream->removeXmppStanzaHandler(XSHO_XMPP_FEATURE,this); if (AStanza.kind() == "success") { LOG_STRM_INFO(FXmppStream->streamJid(),"Authorization successes"); deleteLater(); emit finished(true); } else if (AStanza.kind() == "failure") { XmppSaslError err(AStanza.element()); LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Authorization failed: %1").arg(err.condition())); emit error(err); } else { XmppError err(IERR_SASL_AUTH_INVALID_RESPONSE); LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Authorization error: Invalid stanza kind=%1").arg(AStanza.kind())); emit error(err); } } return true; } return false; }