示例#1
0
vector<uint8_t> SslWrapper::get() {
	if (this->url.isUseSsl()) {
		Log::info << "Start requesting with ssl (it must be hard)" << endl;

		/*
		 Client                                               Server

		 ClientHello                  ----1---->
		 ServerHello
		 Certificate*
		 ServerKeyExchange*
		 CertificateRequest*
		 <---2-----      ServerHelloDone
		 Certificate*
		 ClientKeyExchange
		 CertificateVerify*
		 [ChangeCipherSpec]
		 Finished                     ----3---->
		 [ChangeCipherSpec]
		 <---4-----             Finished
		 Application Data             <---5---->     Application Data
		 */

		//phrase 1
		sendClientHello();

		//phrase 2
		//receive data

		try {
			pair<Record, Record> records = receiveServerHello();
			Record &serverCertificate = records.second;
			Record &serverHello = records.first;
			Log::info << "Make \"client_key_exchange\" record (hard)" << endl;
			//phrase 3
			sendClientCertificate(serverHello, serverCertificate);
			throw string("Deadline is coming. So that I stop here");

			//phrase 4: receive finished message
			try {
				receiveServerFinished();
				//phrase 5: send request
				sendData(url.httpGetRequest());
				//phrase 6: receive data
				return receiveData();
			} catch (string const& msg) {
				Log::err << msg << endl;
			}
		} catch (string const& err) {
			Log::err << err << endl;
		}
//		Log::warn << "Return empty result because of occurred error" << endl;
		return vector<uint8_t>();
	}

	Log::info << "Send request without using ssl" << endl;
	this->connection->send(this->url.httpGetRequest());
	return this->connection->receive();
}
示例#2
0
// if you get an error from connect see note at top of README
int SSL_connect(SSL* ssl)
{
    if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
        ssl->SetError(no_error);

    if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
    
        ssl->SetError(no_error);
        ssl->SendWriteBuffered();
        if (!ssl->GetError())
            ssl->useStates().UseConnect() =
                             ConnectState(ssl->getStates().GetConnect() + 1);
    }

    ClientState neededState;

    switch (ssl->getStates().GetConnect()) {

    case CONNECT_BEGIN :
        sendClientHello(*ssl);
        if (!ssl->GetError())
            ssl->useStates().UseConnect() = CLIENT_HELLO_SENT;

    case CLIENT_HELLO_SENT :
        neededState = ssl->getSecurity().get_resuming() ?
                      serverFinishedComplete : serverHelloDoneComplete;
        while (ssl->getStates().getClient() < neededState) {
            if (ssl->GetError()) break;
            processReply(*ssl);
            // if resumption failed, reset needed state 
            if (neededState == serverFinishedComplete)
                if (!ssl->getSecurity().get_resuming())
                    neededState = serverHelloDoneComplete;
        }
        if (!ssl->GetError())
            ssl->useStates().UseConnect() = FIRST_REPLY_DONE;

    case FIRST_REPLY_DONE :
        if(ssl->getCrypto().get_certManager().sendVerify())
            sendCertificate(*ssl);

        if (!ssl->getSecurity().get_resuming())
            sendClientKeyExchange(*ssl);

        if(ssl->getCrypto().get_certManager().sendVerify())
            sendCertificateVerify(*ssl);

        sendChangeCipher(*ssl);
        sendFinished(*ssl, client_end);
        ssl->flushBuffer();

        if (!ssl->GetError())
            ssl->useStates().UseConnect() = FINISHED_DONE;

    case FINISHED_DONE :
        if (!ssl->getSecurity().get_resuming())
            while (ssl->getStates().getClient() < serverFinishedComplete) {
                if (ssl->GetError()) break;
                processReply(*ssl);
            }
        if (!ssl->GetError())
            ssl->useStates().UseConnect() = SECOND_REPLY_DONE;

    case SECOND_REPLY_DONE :
        ssl->verifyState(serverFinishedComplete);
        ssl->useLog().ShowTCP(ssl->getSocket().get_fd());

        if (ssl->GetError()) {
            GetErrors().Add(ssl->GetError());
            return SSL_FATAL_ERROR;
        }   
        return SSL_SUCCESS;

    default :
        return SSL_FATAL_ERROR; // unkown state
    }
}
示例#3
0
void ovListener (ovStruct_t *ovP) {
	int sock;
    uchar buff[5000];  // uchar is important
    int bytes_recv, index, i, j;
    int set = 0;
    int remBytes = 0;
    ushort RecordHdrLengthRecvd = 0;
	jsonData_t* jsonData = ovP->jsonData;
	int ssl_len;
	int saveLen = 0;
	uchar saveBuff[5000];

	log_info(fp, "Entering OpenVPN Listener Loop..."); fflush(fp);
	while(1) {
        bytes_recv = recv(ovP->sock,&buff[0], 3000, 0);
        log_debug(fp, "OpenVPN Bytes_recv = %d, ", bytes_recv); fflush(fp);
        if (bytes_recv == -1) { perror("-1: Error during recv: "); exit(1); }
        if (bytes_recv == 0) {
            log_error(fp, "OpenVPN: Error: recvFunction: sock closed in recv, bytes_Recv = 0"); fflush(fp);
            sleep(10); // This is so that the main has time to gather stats
            exit(1); // No point keeping this since the sock is gone
        }
        switch((buff[0] & P_KEYID_MASK) >> 3) {
        case P_CONTROL_HARD_RESET_SERVER_V2:
            log_info(fp, "  <- OV: P_CONTROL_HARD_RESET_SERVER_V2"); 
			fflush(fp);
			ovP->toAck = GET_BE32(&buff[50]);
			memcpy(ovP->toSessionID, &buff[1], 8);
			log_info(fp, "toAck = %d", ovP->toAck); fflush(fp);
			log_info(fp, "\nOpenVPN toSession ID: ");
			for (j=0;j<8;j++)
				printf("%2x ", ovP->toSessionID[j]);
			fflush(stdout);
			sendAckV1(ovP, jsonData);
			sleep(1);
			sendClientHello(ovP, jsonData);
			break;
        case P_ACK_V1:
            log_info(fp, "  <- OV: P_ACK_V1"); 
			fflush(fp);
			break;
        case P_CONTROL_V1:
            log_info(fp, "  <- OV: P_CONTROL_V1"); fflush(fp);
			// Note that if saveLen is non Zero, then we have a continued 
			// SSL packet and we need to keep collecting the SSL pkt till
			// we get the complete pkt.
			if (saveLen != 0) {
				// Continuing pkts do not have ACK data, and thus their
				// len is 42 bytes.
				ovP->toAck = GET_BE32(&buff[38]);
				log_info(fp, "toAck: %d", ovP->toAck); fflush(fp);
				memcpy(&saveBuff[saveLen], &buff[42], bytes_recv-42);
				saveLen = saveLen + bytes_recv - 42;
				saveBuff[3] = saveBuff[3] & 0x7F; // clears the MSB flag
				ssl_len=GET_BE16(&saveBuff[3]);
				if (saveLen >= (ssl_len+5)) {
					log_info(fp, "We have complete SSL pkt %d of %d",
						saveLen, ssl_len+5); fflush(fp);
					// Control falls down to decoding the SSL hdr
					memcpy(buff, saveBuff, (ssl_len+5));
					index=0;
					// But, first set the next ssl pkt if partially recvd.
					memcpy(saveBuff, &saveBuff[ssl_len+5], saveLen-(ssl_len+5));
					saveLen = saveLen - (ssl_len+5);
					log_info(fp, "We have next partial SSL pkt of size %d",
						saveLen); fflush(fp);
				} else {
					log_info(fp, "We have partial SSL pkt %d of %d",
						saveLen, ssl_len+5); fflush(fp);
					sendAckV1(ovP, jsonData);
					continue;
				}	
			} else {
				ovP->toAck = GET_BE32(&buff[50]);
				// This occurs 1st time only for a complete or a partial pkt
				index = 54;
				buff[index+3] = buff[index+3] & 0x7F; // clears the MSB flag
				ssl_len = GET_BE16(&buff[index+3]);
				// If there is more than ssl_len+54+5 then we need to look for the 
				// 2nd SSL pkt now.
				if (bytes_recv > ssl_len+54+5) {
					int left =  bytes_recv - (ssl_len+54+5);
					log_info(fp, "Left over bytes: %d", left);
					fflush(fp);
					memcpy(&saveBuff[saveLen], &buff[ssl_len+54+5], left);
					saveLen += left;
				}
			}
			// Check in the pkt now to see the SSL Pkt type
			// Assuming 54 bytes OpenVPN Hdr, it the peer also is acking
			// the Client Hello pkt, we need to jump these many bytes to 
			// start decoding the SSL header.
        	switch(buff[index]) {
	        case change_cipher_spec:
   	             log_info(fp, "  <- SSL: Change Cipher: %d", ssl_len+5); break;
   	     	case alert:
   	             log_info(fp, "  <- SSL: Alert: %d", ssl_len+5); break;
   	     	case handshake:
   	             log_info(fp, "  <- SSL: Handshake: %d", ssl_len+5); break;
   	     	case application_data:
   	             log_info(fp, "  <- SSL: App data: %d", ssl_len+5); break;
   	     	default:
   	             log_error(fp, " <- SSL: Error pkt recvd: %d, ", buff[0]);
			}
        	if (buff[index] == change_cipher_spec) { break; }
        	if (buff[index] == alert) { break; }
			// TBD: Logic needed to read multiple Handshake msgs in 1 msg
			switch(buff[index+5]) {
        	case hello_request:
                log_info(fp, "      <- Handshake Type: Hello Request"); break;
        	case client_hello:
                log_info(fp, "      <- Handshake Type: Client Hello"); break;
        	case server_hello:
                log_info(fp, "      <- Handshake Type:  Server Hello");
                //recvServerHello(ovP);
                break;
        	case certificate:
                log_info(fp, "      <- Handshake Type: Certificate");
                //recvCertificate (ovP);
                break;
        	case server_key_exchange:
                log_info(fp, "      <- Handshake Type: Server Key Exchange");
                //ovP->handshakeResp |= set;
                break;
        	case certificate_request:
                log_info(fp, "      <- Handshake Type: Certificate Request");
				// TBD: Check if Server Hello Done is also in this message
				// We need a smarter way to parse multiple handshake msgs
				// so that we dont use this kludge here
				if (buff[bytes_recv-4] == 0x0E) {
                	log_info(fp, "      <- Handshake Type: Server Hello Done");
					ovSendClientCertificate(ovP, jsonData);
					ovSendClientKeyExchange(ovP, jsonData);
				}
                break;
        	case server_hello_done:
                log_info(fp, "      <- Handshake Type:  Server Hello Done");
                //recvServerHelloDone(ovP);
                break;
        	case certificate_verify:
                log_info(fp, "      <- Handshake Type: Certificate Verify"); break;
                break;
        	case client_key_exchange:
                log_info(fp, "      <- Handshake Type: Client Key Exchange"); break;
                break;
        	case finished:
                log_info(fp, "      <- Handshake Type: Finished");
                break;
        	default:
                log_info(fp, "      <- Handshake Type: Unknown");
			}
			sendAckV1(ovP, jsonData);
			break;
        default:
            log_error(fp, " <- OV: Error pkt recvd: %d, ", buff[0]);
            // We have some junk data. Throw it away
            log_info(fp, "..discarding %d len data\n", bytes_recv); continue;
        }
#ifdef DEBUG
		for (j=0;j<i;j++)
			printf("%2x ", buff[j]);
		fflush(fp);
#endif
	}
	exit(0);
}