void SocksConnection::HandleRequest() { if(_socket->bytesAvailable() < _addr_len) { return; } QByteArray socks_addr = _socket->read(_addr_len); QString host; quint16 port; if(!ParseSocksAddress(socks_addr, host, port)) { EstablishFail(SocksReply_AddressTypeNotSupported); return; } qDebug() << "SOCKS Host Parsed:" << host << port; switch(_command) { case SocksCommand_Connect: StartConnect(host, port); break; case SocksCommand_UdpAssociate: StartUdpAssociate(host, port); break; default: qDebug() << "FAIL: Command not supported"; EstablishFail(SocksReply_CommandNotSupported); return; } if(_socket->bytesAvailable()) { ReadFromSocket(); } }
void SocksConnection::HandleRequestHeader() { int header_len = 5; if(_socket->bytesAvailable() < header_len) { return; } QByteArray request_buf = _socket->read(3); char addr[2]; Q_ASSERT(2 == _socket->peek(addr, 2)); // Request header -- 4 bytes fixed: // byte[0] = version // byte[1] = command (connect, bind, or UDP associate) // byte[2] = reserved // byte[3] = address type // byte[4] = first byte of address if(((uchar)request_buf[0] != (uchar)SocksVersion_5) || request_buf[2]) { Close(); return; } _command = request_buf[1]; _addr_len = 1; switch(addr[0]) { case SocksAddress_IPv4: qDebug() << "IS IPv4 address"; _addr_len += 4; break; case SocksAddress_DomainName: qDebug() << "IS DomainName address"; _addr_len += addr[1] + 1; break; case SocksAddress_IPv6: _addr_len += 16; break; default: qDebug() << "Received an invalid SocksAddress type"; EstablishFail(SocksReply_AddressTypeNotSupported); return; } // Add two bytes for the port number _addr_len += 2; _state = ConnState_WaitingForRequest; if(_socket->bytesAvailable() >= _addr_len) { ReadFromSocket(); } }
void SocksConnection::HandleRequestHeader() { const int header_len = 5; const int bytes_left = header_len - _request_buf.count(); _request_buf.append(_socket->read(bytes_left)); if(_request_buf.count() == header_len) { ProcessRequestHeader(); } ReadFromSocket(); }
void SocksConnection::HandleRequest() { const int bytes_left = _addr_len - _addr_buf.count(); _addr_buf.append(_socket->read(bytes_left)); qDebug() << "_addr_buf len" << _addr_buf.count(); if(_addr_buf.count() == _addr_len) { ProcessRequest(); } ReadFromSocket(); }
SocksConnection::SocksConnection(QTcpSocket *socket) : _state(ConnState_WaitingForMethodHeader), _socket(socket), _socket_open(true), _crypto_lib(CryptoFactory::GetInstance().GetLibrary()), _hash_algo(_crypto_lib->GetHashAlgorithm()), _signing_key(_crypto_lib->CreatePrivateKey()), _verif_key(_signing_key->GetPublicKey()) { connect(socket, SIGNAL(readyRead()), this, SLOT(ReadFromSocket())); connect(socket, SIGNAL(disconnected()), this, SLOT(Close())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(HandleError(QAbstractSocket::SocketError))); };
void SocksConnection::StartConnect(const SocksHostAddress &dest_host) { QByteArray verif_bytes = _verif_key->GetByteArray(); QByteArray packet = TcpStartPacket(verif_bytes, dest_host).ToByteArray(); // Start the connection _conn_id = _hash_algo->ComputeHash(verif_bytes); emit ProxyConnected(); _state = ConnState_Connected; SendUpstreamPacket(packet); WriteSocksReply(SocksReply_Succeeded, QHostAddress(), 8888); ReadFromSocket(); }
LRESULT BTCtcp::ProcessNotifications(HWND hWnd, LPARAM lParam) { int wsaErr = WSAGETSELECTERROR(lParam); unsigned int ui=0; TCHAR szText[MAX_LOADSTRING]; switch (WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: break; case FD_CONNECT: // connect() operation terminated if (wsaErr == ERROR_SUCCESS) { // and no error --> we are connected :) iBTCSocketStatus = 5; iBTCError = ERROR_SUCCESS; ui=IDS_SS_CONNECTED; } else { iBTCSocketStatus = 3; // "connecting..." status did not complete successfully iBTCError = wsaErr; // save error information iBTCNodeStatus=0; // no connection ui=IDS_SS_FAILED; ShowError(IDS_Err_Socket, iBTCError); } break; case FD_WRITE: bWriteReady = true; // we are notified we can send (again) WriteToSocket(); // try to send data if something is waiting in our buffer break; case FD_READ: ReadFromSocket(hWnd); // data is awaiting break; case FD_CLOSE: // connection has been closed closesocket(skBTC); // release the socket iBTCSocketStatus=1; iBTCNodeStatus=0; ui=IDS_SS_NOTHING; break; } if (ui) { // show something to user LoadString(hInst, ui, szText, MAX_LOADSTRING); SetWindowText(hStaticSocketStatus, szText); // update status window related to our TCP connection InvalidateRect(hWnd, &rcSocketStatus, true); LoadString(hInst, (iBTCSocketStatus>3) ? IDS_DISCONNECT:IDS_CONNECT, szText, MAX_LOADSTRING); SetDlgItemText(hWnd, IDC_BTNBTCCONNECT, szText); EnableWindow(GetDlgItem(hWnd, IDC_BTNSQLCONNECT), iBTCSocketStatus<2); } return 0; }
void SocksConnection::HandleMethods() { const int n_methods = static_cast<int>(_n_methods); const int bytes_left = n_methods - _methods_buf.count(); // Need more bytes if(bytes_left < 0) { return; } _methods_buf.append(_socket->read(bytes_left)); if(_methods_buf.count() == n_methods) { SendMethodsReply(); } ReadFromSocket(); }
void SocksConnection::HandleMethodHeader() { // Header: // byte 0 = protocol version (should be 0x05) // byte 1 = number of following method bytes if(_socket->bytesAvailable() < 2) return; if(!_socket->getChar(&_version)) { qDebug() << "Could not read version character"; return; } if(!_socket->getChar(&_n_methods)) { _socket->ungetChar(_version); qDebug() << "Could not read n_methods char"; } _state = ConnState_WaitingForMethods; ReadFromSocket(); }
int CSTATEngine::SendCommand(CSTATScriptCommand *pSendCommand, CSTATScriptCommand **ppRecvCommand) { int ret = GENERAL_FAILURE; CSTATScriptCommand tempCommand; tempCommand.cCommandID = pSendCommand->cCommandID; // the first instance of a 'R' or 'T' command, it could set a data socket instead of a file if(pSendCommand->cCommandID=='T' || pSendCommand->cCommandID=='R') { if(dataSocket==NULL && settingSocket && pSendCommand->Command()!=NULL) { char *comma = strchr(pSendCommand->Command(),','); if(!(comma > pSendCommand->Command() + pSendCommand->Length())) { switch(pSendCommand->cCommandID) { case 'R': { char *colon = strchr(comma,':'); if(colon==NULL) break; comma += 1; std::string ipAdd( comma, colon - comma ); colon += 1; std::string ipPort( colon ); ret = SetSocket(ipAdd.c_str() , atoi( ipPort.c_str() )); if(ret!=ITS_OK) { return ret; } break; } case 'T': { char *colon = strchr( pSendCommand->Command() , ':' ); if(colon==NULL) break; std::string ipAdd( pSendCommand->Command() , colon - pSendCommand->Command() ); colon += 1; if(comma < colon) break; std::string ipPort( colon , comma - colon ); ret = SetSocket(ipAdd.c_str() , atoi(ipPort.c_str())); if(ret!=ITS_OK) { return ret; } break; } } } } settingSocket=false; } // send the first command if ((ret = SendSingleCommand(pSendCommand, ppRecvCommand)) == ITS_OK) { // check our response - if Serial/Infra-red, need to break it down if (pComms->GetMaxPacketSize() != 0) { // break up the command into buffer-sized chunks if (pSendCommand->Length() > pComms->GetMaxPacketSize() || (dataSocket!=NULL && pSendCommand->cCommandID=='T')) { int i = 0; unsigned long offset = 0; unsigned long ulTotalWritten = 0; unsigned long AmountToWrite = pComms->GetMaxPacketSize(); unsigned long OriginalLength = pSendCommand->Length(); if(dataSocket==NULL) { int iWrites = pSendCommand->Length() / pComms->GetMaxPacketSize() + 1; Message("Writing %d bytes of data in %d separate writes...", OriginalLength, iWrites); for (i=0;i<iWrites;i++) { offset = i * pComms->GetMaxPacketSize(); if ((pSendCommand->Length() - offset) < pComms->GetMaxPacketSize()) AmountToWrite = (pSendCommand->Length() - offset); if (AmountToWrite) { //Sleep(100); // pause a bit for slower machines - probably doesn't need it but it can't hurt... // now send the command Message("Writing %d bytes from offset %d", AmountToWrite, offset); tempCommand.SetData(pSendCommand->Command() + ulTotalWritten, AmountToWrite); if ((ret = SendSingleCommand(&tempCommand, ppRecvCommand)) == ITS_OK) { //Message("%d bytes successfully written", AmountToWrite); } else return ret; ulTotalWritten += AmountToWrite; } } } else { //uses socket transmission char *pData = new char[AmountToWrite]; tempCommand.ulLength = (unsigned long) -1; if((ret = SendSingleCommand(&tempCommand, ppRecvCommand)) != ITS_OK) { delete [] pData; return ret; } while(true){ int AmountToWrite = pComms->GetMaxPacketSize(); ReadFromSocket(pData, &AmountToWrite ); if(AmountToWrite>=0) { Message("Writing %d bytes", AmountToWrite); tempCommand.SetData(pData , AmountToWrite); if ((ret = SendSingleCommand(&tempCommand, ppRecvCommand)) == ITS_OK) { //Message("%d bytes successfully written", AmountToWrite); } else { settingSocket=true; delete [] pData; return ret; } ulTotalWritten +=AmountToWrite; } else { eStopProcessing = STAT_PAUSE; break; } if(AmountToWrite==0) { break; } } delete [] pData; } // once completely sent, send an empty command to show that we've finished if(dataSocket == NULL ) { if (ulTotalWritten == OriginalLength) { // send the command that signals the end of our transmission Message("Sending completion command %c", tempCommand.cCommandID); tempCommand.SetData(NULL, 0); if ((ret = SendSingleCommand(&tempCommand, ppRecvCommand)) == ITS_OK) { //Message("Completion command successfully written"); } } else { Message("Incorrect number of bytes written - expected %ld got %ld", ulTotalWritten, OriginalLength); ret = E_BADNUMBERBYTES; } } } } } if (ret == ITS_OK) { // check our response - if Serial/Infra-red, need to break it down // if < STAT_BUFFERSIZE, nothing more to do // if not, we need to read in as many times as it takes to // assemble our complete command response if (pComms->GetMaxPacketSize() != 0) { if (ppRecvCommand && (*ppRecvCommand)->Length() > pComms->GetMaxPacketSize()) { unsigned long TotalLength = (*ppRecvCommand)->Length(); Message("%s: About to read %d bytes of data", GetConnection(eConnectType), TotalLength); // allocate memory to hold entire command char *pTemp = new char [TotalLength]; if (pTemp) { unsigned long ulTotalRead = 0; // empty packets tempCommand.SetData(NULL, 0); // now read data until we get an empty packet while((*ppRecvCommand)->Length()) { //Sleep(100); // pause a bit for slower machines - probably doesn't need it but it can't hurt... //Message("Sending continuation command %c", tempCommand.cCommandID); if ((ret = SendSingleCommand(&tempCommand, ppRecvCommand)) == ITS_OK) { if ((*ppRecvCommand)->Length()) { Message("%s to offset %d", pComms->Error(), ulTotalRead); //copy the data into the buffer memcpy(pTemp + ulTotalRead, (*ppRecvCommand)->Command(), (*ppRecvCommand)->Length()); if(dataSocket!=NULL) { int bytesSent = (int)(*ppRecvCommand)->Length(); WriteToSocket((*ppRecvCommand)->Command() , &bytesSent); if(bytesSent <= 0) { eStopProcessing = STAT_PAUSE; } } //increment the pointer to the end of the first chunk received ulTotalRead += (*ppRecvCommand)->Length(); } } else { settingSocket=true; delete [] pTemp; return ret; } } // make sure we got what we expected if (ulTotalRead == TotalLength) { // set our final response to the complete data transmission (*ppRecvCommand)->SetData(pTemp, ulTotalRead); //Message("Received successfully %ld bytes", ulTotalRead); } else { Message("Incorrect number of bytes read - expected %ld got %ld", ulTotalRead, TotalLength); ret = E_BADNUMBERBYTES; } // finished with it delete [] pTemp; } else { Message("Could not allocate %d bytes of memory", TotalLength); ret = E_OUTOFMEM; } } else if(dataSocket!=NULL && pSendCommand->cCommandID=='R') { int bytesSent = (int)(*ppRecvCommand)->Length(); WriteToSocket((*ppRecvCommand)->Command(), &bytesSent); } } } return ret; }
PRStatus nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags) { LOGDEBUG(("socks: DoHandshake(), state = %d", mState)); switch (mState) { case SOCKS_INITIAL: return StartDNS(fd); case SOCKS_DNS_IN_PROGRESS: PR_SetError(PR_IN_PROGRESS_ERROR, 0); return PR_FAILURE; case SOCKS_DNS_COMPLETE: return ConnectToProxy(fd); case SOCKS_CONNECTING_TO_PROXY: return ContinueConnectingToProxy(fd, oflags); case SOCKS4_WRITE_CONNECT_REQUEST: if (WriteToSocket(fd) != PR_SUCCESS) return PR_FAILURE; WantRead(8); mState = SOCKS4_READ_CONNECT_RESPONSE; return PR_SUCCESS; case SOCKS4_READ_CONNECT_RESPONSE: if (ReadFromSocket(fd) != PR_SUCCESS) return PR_FAILURE; return ReadV4ConnectResponse(); case SOCKS5_WRITE_AUTH_REQUEST: if (WriteToSocket(fd) != PR_SUCCESS) return PR_FAILURE; WantRead(2); mState = SOCKS5_READ_AUTH_RESPONSE; return PR_SUCCESS; case SOCKS5_READ_AUTH_RESPONSE: if (ReadFromSocket(fd) != PR_SUCCESS) return PR_FAILURE; return ReadV5AuthResponse(); case SOCKS5_WRITE_CONNECT_REQUEST: if (WriteToSocket(fd) != PR_SUCCESS) return PR_FAILURE; // The SOCKS 5 response to the connection request is variable // length. First, we'll read enough to tell how long the response // is, and will read the rest later. WantRead(5); mState = SOCKS5_READ_CONNECT_RESPONSE_TOP; return PR_SUCCESS; case SOCKS5_READ_CONNECT_RESPONSE_TOP: if (ReadFromSocket(fd) != PR_SUCCESS) return PR_FAILURE; return ReadV5ConnectResponseTop(); case SOCKS5_READ_CONNECT_RESPONSE_BOTTOM: if (ReadFromSocket(fd) != PR_SUCCESS) return PR_FAILURE; return ReadV5ConnectResponseBottom(); case SOCKS_CONNECTED: LOGERROR(("socks: already connected")); HandshakeFinished(PR_IS_CONNECTED_ERROR); return PR_FAILURE; case SOCKS_FAILED: LOGERROR(("socks: already failed")); return PR_FAILURE; } LOGERROR(("socks: executing handshake in invalid state, %d", mState)); HandshakeFinished(PR_INVALID_STATE_ERROR); return PR_FAILURE; }