Example #1
0
bool FlipFlat::initProperties()
{
    INDI::DefaultDevice::initProperties();

    // Status
    IUFillText(&StatusT[0], "Cover", "", nullptr);
    IUFillText(&StatusT[1], "Light", "", nullptr);
    IUFillText(&StatusT[2], "Motor", "", nullptr);
    IUFillTextVector(&StatusTP, StatusT, 3, getDeviceName(), "Status", "", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);

    // Firmware version
    IUFillText(&FirmwareT[0], "Version", "", nullptr);
    IUFillTextVector(&FirmwareTP, FirmwareT, 1, getDeviceName(), "Firmware", "", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);

    initDustCapProperties(getDeviceName(), MAIN_CONTROL_TAB);
    initLightBoxProperties(getDeviceName(), MAIN_CONTROL_TAB);

    LightIntensityN[0].min  = 0;
    LightIntensityN[0].max  = 255;
    LightIntensityN[0].step = 10;

    // Set DUSTCAP_INTEFACE later on connect after we verify whether it's flip-flat (dust cover + light) or just flip-man (light only)
    setDriverInterface(AUX_INTERFACE | LIGHTBOX_INTERFACE);

    addAuxControls();

    serialConnection = new Connection::Serial(this);
    serialConnection->registerHandshake([&]() { return Handshake(); });
    registerConnection(serialConnection);

    return true;
}
Example #2
0
// --------------------------------------------------------------------------
//
// Function
//		Name:    SocketStreamTLS::Open(const TLSContext &, int, const char *, int)
//		Purpose: Open connection, and perform TLS handshake
//		Created: 2003/08/06
//
// --------------------------------------------------------------------------
void SocketStreamTLS::Open(const TLSContext &rContext, Socket::Type Type,
	const std::string& rName, int Port)
{
	SocketStream::Open(Type, rName, Port);
	Handshake(rContext);
	ResetCounters();
}
Example #3
0
bool
CAudioScrobbler::Scrobble(centry_t* entry)
{
	bool retval = false;
	if(!_authed) {
		eprintf("Handshake hasn't been done yet.");
		Handshake();
		return retval;
	}
	iprintf("Scrobbling: %s - %s", entry->artist.c_str(), entry->title.c_str());
	
	OpenURL(ROOTURL, CreateScrobbleMessage(0, entry).c_str());
	if(_response.find("<lfm status=\"ok\">") != std::string::npos) {
		iprintf("%s", "Scrobbled successfully.");
		retval = true;
	}
	else if(_response.find("<lfm status=\"failed\">") != std::string::npos) {
		eprintf("%s%s", "Last.fm returned an error while scrobbling:\n", _response.c_str());
		if(CheckFailure(_response))
			Failure();
	}
	CLEANUP();

	return retval;
}
Example #4
0
int ViewerClient::Run()
{
    ErrorValue err = ConnectSocket(socket_, options_.game_server_host, options_.game_server_port);
    if (!err.success) {
        std::cerr << "Error connecting to game server: " << err.message << std::endl;
        return 1;
    }
    err = Handshake();
    if (!err.success) {
        std::cerr << "Error during handshake: " << err.message << std::endl;
        return 1;
    }
    while (true) {
        bool should_continue = false;
        err = GetNextFieldState(should_continue);
        if (!err.success) {
            std::cerr << "Error getting field state: " << err.message << std::endl;
            return 1;
        }
        if (!should_continue)
            break;
    }

    return 0;
}
Example #5
0
	void ConnectProtocol::Update() {
		// if timed out, send again!
		if (state != CONNECTED && state != NOT_CONNECTED && timer.Finished()) {
			if (is_instigator && --attempts == 0) {
				key->SetResult(false);
				key->Pulse();
				key = 0;
				//state = NOT_CONNECTED; // this line is unneccessary
				connection->Disconnect();
			} else {
				if (state == WAITING_FOR_SYN)
					Handshake(SEND_CON); 
				if (state == WAITING_FOR_ACK)
					Handshake(SEND_SYN); 
			}
		}
	}
Example #6
0
PortW32::PortAccessStatus PortW32::POpen_Second()
{
   if (IsPortParallel()) {
      if (m_ProtectedOS)
         m_lastError = this->OpenPortTalk();
      else
         m_PortTalk_Handle = (HANDLE)0;  // dummy for raw access init done

      if (m_lastError!=IPAC_Success)
         m_portAddress = 0;
   }

   else if (IsPortSerial()) {
      m_lastError = this->OpenSerialPort();
      if (m_lastError==IPAC_Success) {
         PSetBaudrate(BaudRate());
         PSetHandshake(Handshake());
      }
   }
   else if (IsPortGPUSB()) {
      // GPUSB Port - start access is OK but not more
      CloseGPUSB();
      m_pGpUsb = GPUsb::Create();
      bool retVal = m_pGpUsb->Open();
      m_lastError = (retVal) ? IPAC_Success : IPAC_NoInterface;
      if (m_lastError==IPAC_Success) {
         m_pGpUsb->SetValue(0);// all lines high i.e. there is no guiding then
      }
      else {
         CloseGPUSB(); // just delete this port
      }
  }
   else if (IsPortLXUSB()) {
      // LXUSB Port - start access is OK but not more
      CloseLXUSB();
      m_pLxUsb = LXUsb::Create();
      bool retVal = m_pLxUsb->Open();
      m_lastError = (retVal) ? IPAC_Success : IPAC_NoInterface;
      if (m_lastError==IPAC_Success) {
         m_pLxUsb->SetValue(0); // all lines high i.e. cam is in regular mode then
      }
      else {
         CloseLXUSB(); // just delete this port
      }
   }
   else if (IsPortLXLED()) {
      // TucLED Port - start access is OK but not more
      // note this port does not exist in Windows
   }
   else if (IsPortDummy()) {
      // Dummy Port - start access is OK but not more
   }
   else {
      // other Port ?? - start access is OK but not more
   }

	return m_lastError;
}
Example #7
0
void
CAudioScrobbler::Failure()
{
	_failcount += 1;
	if(_failcount >= 3) {
		eprintf("%s", "Re-Handshaking!");
		_failcount = 0;
		Handshake();
	}
}
Example #8
0
	bool ConnectProtocol::HandlePacket(Datagram *data) {
		switch (data->pack->GetType()) {
			case CON_PACKET:
				{
					DBG_PRINT("Received Connect Packet");
					if (!is_instigator) {
						Handshake(SEND_SYN);
						if (state == NOT_CONNECTED)
							state = WAITING_FOR_ACK;
					}
					return true;
				}
			case SYN_PACKET:
				{
					DBG_PRINT("Received Syn Packet");
					if (is_instigator) {
						Handshake(SEND_ACK);
						if (state == WAITING_FOR_SYN) {
							key->SetResult(true);
							key->Pulse();
							key = 0;
							state = CONNECTED;
						}
					}
					return true;
				}
			case ACK_PACKET:
				{
					DBG_PRINT("Received Ack Packet");
					if (state == WAITING_FOR_ACK)
						state = CONNECTED;
					connection->Connect();
					return true;
				}
			default:
				// Do not accept packets before being connected,
				// if not relevant to the connection protocol
				if (state != CONNECTED)
					return true;
				return false;
		}
	}
Example #9
0
	void ConnectProtocol::TryConnecting(int max_attempts, int ms_delay, Turnkey<bool> *key) {
		this->key = key;

		Handshake(SEND_CON);
		state = WAITING_FOR_SYN;	
		is_instigator = true;
		this->attempts = max_attempts;
		this->ms_delay = ms_delay;

		DBG_PRINT("Trying to Connect");
	}
Example #10
0
bool INDI::FilterWheel::callHandshake()
{
    if (filterConnection > 0)
    {
        if (getActiveConnection() == serialConnection)
            PortFD = serialConnection->getPortFD();
        else if (getActiveConnection() == tcpConnection)
            PortFD = tcpConnection->getPortFD();
    }

    return Handshake();
}
Example #11
0
bool Weather::callHandshake()
{
    if (weatherConnection > 0)
    {
        if (getActiveConnection() == serialConnection)
            PortFD = serialConnection->getPortFD();
        else if (getActiveConnection() == tcpConnection)
            PortFD = tcpConnection->getPortFD();
    }

    return Handshake();
}
Example #12
0
	virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
	{		
		issl_session* session = &sessions[fd];

		if(!session->sess)
		{
			ServerInstance->Log(DEBUG, "m_ssl_openssl.so: OnRawSocketWrite: No session to write to");
			CloseSession(session);
			return 1;
		}
		
		ServerInstance->Log(DEBUG, "m_ssl_openssl.so: OnRawSocketWrite: Adding %d bytes to the outgoing buffer", count);		
		session->outbuf.append(buffer, count);
		
		if(session->status == ISSL_HANDSHAKING)
		{
			// The handshake isn't finished, try to finish it.
			if(session->rstat == ISSL_WRITE || session->wstat == ISSL_WRITE)
			{
				if(Handshake(session))
				{
					// Handshake successfully resumed.
					ServerInstance->Log(DEBUG, "m_ssl_openssl.so: OnRawSocketWrite: successfully resumed handshake");
				}
				else
				{
					// Couldn't resume handshake.	
					ServerInstance->Log(DEBUG, "m_ssl_openssl.so: OnRawSocketWrite: failed to resume handshake"); 
				}
			}
			else
			{
				ServerInstance->Log(DEBUG, "m_ssl_openssl.so: OnRawSocketWrite: handshake wants to read data but we are currently writing");			
			}
		}
		
		if(session->status == ISSL_OPEN)
		{
			if(session->rstat == ISSL_WRITE)
			{
				DoRead(session);
			}
			
			if(session->wstat == ISSL_WRITE)
			{
				return DoWrite(session);
			}
		}
		
		return 1;
	}
Example #13
0
    // Returns 1 if application I/O should proceed, 0 if it must wait for the underlying protocol to progress, -1 on fatal error
    int PrepareIO(StreamSocket* sock)
    {
        if (status == ISSL_HANDSHAKEN)
            return 1;
        else if (status == ISSL_HANDSHAKING)
        {
            // The handshake isn't finished, try to finish it
            return Handshake(sock);
        }

        CloseSession();
        sock->SetError("No SSL session");
        return -1;
    }
void TransportLayerDtls::PacketReceived(TransportLayer* layer,
                                        const unsigned char *data,
                                        size_t len) {
  CheckThread();
  MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "PacketReceived(" << len << ")");

  if (state_ != TS_CONNECTING && state_ != TS_OPEN) {
    MOZ_MTLOG(ML_DEBUG,
              LAYER_INFO << "Discarding packet in inappropriate state");
    return;
  }

  nspr_io_adapter_->PacketReceived(data, len);

  // If we're still connecting, try to handshake
  if (state_ == TS_CONNECTING) {
    Handshake();
  }

  // Now try a recv if we're open, since there might be data left
  if (state_ == TS_OPEN) {
    // nICEr uses a 9216 bytes buffer to allow support for jumbo frames
    unsigned char buf[9216];

    int32_t rv;
    // One packet might contain several DTLS packets
    do {
      rv = PR_Recv(ssl_fd_, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT);
      if (rv > 0) {
        // We have data
        MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS");
        SignalPacketReceived(this, buf, rv);
      } else if (rv == 0) {
        TL_SET_STATE(TS_CLOSED);
      } else {
        int32_t err = PR_GetError();

        if (err == PR_WOULD_BLOCK_ERROR) {
          // This gets ignored
          MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Receive would have blocked");
        } else {
          MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "NSS Error " << err);
          TL_SET_STATE(TS_ERROR);
        }
      }
    } while (rv > 0);
  }
}
Example #15
0
void cLuaTCPLink::cLinkSslContext::TryFinishHandshaking(void)
{
	// Hold self alive for the duration of this function
	cLinkSslContextPtr Self(m_Self);

	// If the handshake hasn't finished yet, retry:
	if (!HasHandshaken())
	{
		Handshake();
	}

	// If the handshake succeeded, write all the queued plaintext data:
	if (HasHandshaken())
	{
		WritePlain(m_CleartextData.data(), m_CleartextData.size());
		m_CleartextData.clear();
	}
}
Example #16
0
void cTCPLinkImpl::cLinkTlsContext::TryFinishHandshaking(void)
{
	// Hold self alive for the duration of this function
	cLinkTlsContextPtr Self(m_Self);

	// If the handshake hasn't finished yet, retry:
	if (!HasHandshaken())
	{
		Handshake();
		// If the handshake succeeded, write all the queued plaintext data:
		if (HasHandshaken())
		{
			m_Link.GetCallbacks()->OnTlsHandshakeCompleted();
			WritePlain(m_CleartextData.data(), m_CleartextData.size());
			m_CleartextData.clear();
		}
	}
}
void TransportLayerDtls::PacketReceived(TransportLayer* layer,
                                        const unsigned char *data,
                                        size_t len) {
  CheckThread();
  MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "PacketReceived(" << len << ")");

  if (state_ != TS_CONNECTING && state_ != TS_OPEN) {
    MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Discarding packet in inappropriate state");
    return;
  }

  nspr_io_adapter_->PacketReceived(data, len);

  // If we're still connecting, try to handshake
  if (state_ == TS_CONNECTING) {
    Handshake();
  }

  // Now try a recv if we're open, since there might be data left
  if (state_ == TS_OPEN) {
    unsigned char buf[2000];

    int32_t rv = PR_Recv(ssl_fd_, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT);
    if (rv > 0) {
      // We have data
      MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS");
      SignalPacketReceived(this, buf, rv);
    } else if (rv == 0) {
      SetState(TS_CLOSED);
    } else {
      int32_t err = PR_GetError();

      if (err == PR_WOULD_BLOCK_ERROR) {
        // This gets ignored
        MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "Would have blocked");
      } else {
        MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "NSS Error " << err);
        SetState(TS_ERROR);
      }
    }
  }
}
Example #18
0
/************************************************************************************
 *
* ***********************************************************************************/
bool FocusLynxF1::Connect()
/* Overide of connect() function
 * different for F1 or F2 focuser
 * F1 connect only himself to the driver and
 * it is the only one who's connect to the communication port to establish the physical communication
 */
{
    configurationComplete = false;
    if (isSimulation())
        /* PortFD value used to give the /dev/ttyUSBx or TCP descriptor
         * if -1 = no physical port selected or simulation mode
         * if 0 = no descriptor created, F1 not connected (error)
         * other value = descriptor number
         */
        PortFD = -1;
    else
        if (!INDI::Focuser::Connect())
            return false;

    return Handshake();
}
Example #19
0
	void InitSession(StreamSocket* user, bool me_server)
	{
		issl_session* session = &sessions[user->GetFd()];

		gnutls_init(&session->sess, me_server ? GNUTLS_SERVER : GNUTLS_CLIENT);
		session->socket = user;

		#ifdef GNUTLS_NEW_PRIO_API
		gnutls_priority_set(session->sess, priority);
		#endif
		gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred);
		gnutls_dh_set_prime_bits(session->sess, dh_bits);
		gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(session));
		gnutls_transport_set_push_function(session->sess, gnutls_push_wrapper);
		gnutls_transport_set_pull_function(session->sess, gnutls_pull_wrapper);

		if (me_server)
			gnutls_certificate_server_set_request(session->sess, GNUTLS_CERT_REQUEST); // Request client certificate if any.

		Handshake(session, user);
	}
Example #20
0
void CTlsSocket::OnSend()
{
	m_pOwner->LogMessage(Debug_Debug, _T("CTlsSocket::OnSend()"));

	m_canWriteToSocket = true;

	if (!m_session)
		return;

	if (!gnutls_record_get_direction(m_session))
		return;

	if (m_tlsState == handshake)
		Handshake();
	else if (m_tlsState == closing)
		ContinueShutdown();
	else if (m_tlsState == conn)
	{
		CheckResumeFailedWrite();
		TriggerEvents();
	}
}
void TransportLayerDtls::StateChange(TransportLayer *layer, State state) {
  if (state <= state_) {
    MOZ_MTLOG(ML_ERROR, "Lower layer state is going backwards from ours");
    TL_SET_STATE(TS_ERROR);
    return;
  }

  switch (state) {
    case TS_NONE:
      MOZ_ASSERT(false);  // Can't happen
      break;

    case TS_INIT:
      MOZ_MTLOG(ML_ERROR,
                LAYER_INFO << "State change of lower layer to INIT forbidden");
      TL_SET_STATE(TS_ERROR);
      break;

    case TS_CONNECTING:
      MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Lower layer is connecting.");
      break;

    case TS_OPEN:
      MOZ_MTLOG(ML_ERROR,
                LAYER_INFO << "Lower layer is now open; starting TLS");
      Handshake();
      break;

    case TS_CLOSED:
      MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Lower layer is now closed");
      TL_SET_STATE(TS_CLOSED);
      break;

    case TS_ERROR:
      MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Lower layer experienced an error");
      TL_SET_STATE(TS_ERROR);
      break;
  }
}
Example #22
0
	virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport)
	{
		issl_session* session = &sessions[fd];
	
		session->fd = fd;
		session->inbuf = new char[inbufsize];
		session->inbufoffset = 0;		
		session->sess = SSL_new(ctx);
		session->status = ISSL_NONE;
	
		if(session->sess == NULL)
		{
			ServerInstance->Log(DEBUG, "m_ssl.so: Couldn't create SSL object: %s", get_error());
			return;
		}
		
		if(SSL_set_fd(session->sess, fd) == 0)
		{
			ServerInstance->Log(DEBUG, "m_ssl.so: Couldn't set fd for SSL object: %s", get_error());
			return;
		}

 		Handshake(session);
	}
Example #23
0
TLSSocket::TLSSocket(TCPSocket& socket, HandshakeRole role) :
  session(nullptr)
{
  Handshake(socket, role);
}
Example #24
0
/*****************************************************************************
 * Run : call Handshake() then submit songs
 *****************************************************************************/
static void *Run(void *data)
{
    intf_thread_t          *p_intf = data;
    uint8_t                 p_buffer[1024];
    int                     canc = vlc_savecancel();
    bool                    b_handshaked = false;
    bool                    b_nowp_submission_ongoing = false;

    /* data about audioscrobbler session */
    vlc_tick_t              next_exchange = VLC_TICK_INVALID; /**< when can we send data  */
    unsigned int            i_interval = 0;     /**< waiting interval (secs)*/

    intf_sys_t *p_sys = p_intf->p_sys;

    /* main loop */
    for (;;)
    {
        vlc_restorecancel(canc);
        if (next_exchange != VLC_TICK_INVALID)
            vlc_tick_wait(next_exchange);

        vlc_mutex_lock(&p_sys->lock);
        mutex_cleanup_push(&p_sys->lock);

        while (p_sys->i_songs == 0 && p_sys->b_submit_nowp == false)
            vlc_cond_wait(&p_sys->wait, &p_sys->lock);

        vlc_cleanup_pop();
        vlc_mutex_unlock(&p_sys->lock);
        canc = vlc_savecancel();

        /* handshake if needed */
        if (!b_handshaked)
        {
            msg_Dbg(p_intf, "Handshaking with last.fm ...");

            switch(Handshake(p_intf))
            {
                case VLC_ENOMEM:
                    goto out;

                case VLC_ENOVAR:
                    /* username not set */
                    vlc_dialog_display_error(p_intf,
                        _("Last.fm username not set"),
                        "%s", _("Please set a username or disable the "
                        "audioscrobbler plugin, and restart VLC.\n"
                        "Visit http://www.last.fm/join/ to get an account."));
                    goto out;

                case VLC_SUCCESS:
                    msg_Dbg(p_intf, "Handshake successful :)");
                    b_handshaked = true;
                    i_interval = 0;
                    next_exchange = VLC_TICK_INVALID;
                    break;

                case VLC_AUDIOSCROBBLER_EFATAL:
                    msg_Warn(p_intf, "Exiting...");
                    goto out;

                case VLC_EGENERIC:
                default:
                    /* protocol error : we'll try later */
                    HandleInterval(&next_exchange, &i_interval);
                    break;
            }
            /* if handshake failed let's restart the loop */
            if (!b_handshaked)
                continue;
        }

        msg_Dbg(p_intf, "Going to submit some data...");
        vlc_url_t *url;
        struct vlc_memstream req, payload;

        vlc_memstream_open(&payload);
        vlc_memstream_printf(&payload, "s=%s", p_sys->psz_auth_token);

        /* forge the HTTP POST request */
        vlc_mutex_lock(&p_sys->lock);

        if (p_sys->b_submit_nowp)
        {
            audioscrobbler_song_t *p_song = &p_sys->p_current_song;

            b_nowp_submission_ongoing = true;
            url = &p_sys->p_nowp_url;

            vlc_memstream_printf(&payload, "&a=%s", p_song->psz_a);
            vlc_memstream_printf(&payload, "&t=%s", p_song->psz_t);
            vlc_memstream_puts(&payload, "&b=");
            if (p_song->psz_b != NULL)
                vlc_memstream_puts(&payload, p_song->psz_b);
            vlc_memstream_printf(&payload, "&l=%d", p_song->i_l);
            vlc_memstream_puts(&payload, "&n=");
            if (p_song->psz_n != NULL)
                vlc_memstream_puts(&payload, p_song->psz_n);
            vlc_memstream_puts(&payload, "&m=");
            if (p_song->psz_m != NULL)
                vlc_memstream_puts(&payload, p_song->psz_m);
        }
        else
        {
            url = &p_sys->p_submit_url;

            for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
            {
                audioscrobbler_song_t *p_song = &p_sys->p_queue[i_song];

                vlc_memstream_printf(&payload, "&a%%5B%d%%5D=%s",
                                     i_song, p_song->psz_a);
                vlc_memstream_printf(&payload, "&t%%5B%d%%5D=%s",
                                     i_song, p_song->psz_t);
                vlc_memstream_printf(&payload, "&i%%5B%d%%5D=%"PRIu64,
                                     i_song, (uint64_t)p_song->date);
                vlc_memstream_printf(&payload, "&o%%5B%d%%5D=P", i_song);
                vlc_memstream_printf(&payload, "&r%%5B%d%%5D=", i_song);
                vlc_memstream_printf(&payload, "&l%%5B%d%%5D=%d",
                                     i_song, p_song->i_l);
                vlc_memstream_printf(&payload, "&b=%%5B%d%%5D=", i_song);
                if (p_song->psz_b != NULL)
                    vlc_memstream_puts(&payload, p_song->psz_b);
                vlc_memstream_printf(&payload, "&n=%%5B%d%%5D=", i_song);
                if (p_song->psz_n != NULL)
                    vlc_memstream_puts(&payload, p_song->psz_n);
                vlc_memstream_printf(&payload, "&m=%%5B%d%%5D=", i_song);
                if (p_song->psz_m != NULL)
                    vlc_memstream_puts(&payload, p_song->psz_m);
            }
        }

        vlc_mutex_unlock(&p_sys->lock);

        if (vlc_memstream_close(&payload))
            goto out;

        vlc_memstream_open(&req);
        vlc_memstream_printf(&req, "POST %s HTTP/1.1\r\n", url->psz_path);
        vlc_memstream_printf(&req, "Host: %s\r\n", url->psz_host);
        vlc_memstream_puts(&req, "User-Agent:"
                                 " "PACKAGE_NAME"/"PACKAGE_VERSION"\r\n");
        vlc_memstream_puts(&req, "Connection: close\r\n");
        vlc_memstream_puts(&req, "Accept-Encoding: identity\r\n");
        vlc_memstream_puts(&req, "Content-Type:"
                                 " application/x-www-form-urlencoded\r\n");
        vlc_memstream_printf(&req, "Content-Length: %zu\r\n", payload.length);
        vlc_memstream_puts(&req, "\r\n");
        /* Could avoid copying payload with iovec... but efforts */
        vlc_memstream_write(&req, payload.ptr, payload.length);
        vlc_memstream_puts(&req, "\r\n\r\n");
        free(payload.ptr);

        if (vlc_memstream_close(&req)) /* Out of memory */
            goto out;

        vlc_tls_t *sock = vlc_tls_SocketOpenTCP(VLC_OBJECT(p_intf),
                                                url->psz_host, url->i_port);
        if (sock == NULL)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            free(req.ptr);
            continue;
        }

        /* we transmit the data */
        int i_net_ret = vlc_tls_Write(sock, req.ptr, req.length);
        free(req.ptr);
        if (i_net_ret == -1)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            vlc_tls_Close(sock);
            continue;
        }

        /* FIXME: this might wait forever */
        /* FIXME: With TCP, you should never assume that a single read will
         * return the entire response... */
        i_net_ret = vlc_tls_Read(sock, p_buffer, sizeof(p_buffer) - 1, false);
        vlc_tls_Close(sock);
        if (i_net_ret <= 0)
        {
            /* if we get no answer, something went wrong : try again */
            continue;
        }
        p_buffer[i_net_ret] = '\0';

        char *failed = strstr((char *) p_buffer, "FAILED");
        if (failed)
        {
            msg_Warn(p_intf, "%s", failed);
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "BADSESSION"))
        {
            msg_Err(p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?");
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "OK"))
        {
            if (b_nowp_submission_ongoing)
            {
                b_nowp_submission_ongoing = false;
                p_sys->b_submit_nowp = false;
            }
            else
            {
                for (int i = 0; i < p_sys->i_songs; i++)
                    DeleteSong(&p_sys->p_queue[i]);
                p_sys->i_songs = 0;
            }

            i_interval = 0;
            next_exchange = VLC_TICK_INVALID;
            msg_Dbg(p_intf, "Submission successful!");
        }
        else
        {
            msg_Err(p_intf, "Authentication failed, handshaking again (%s)",
                             p_buffer);
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
        }
    }
out:
    vlc_restorecancel(canc);
    return NULL;
}
Example #25
0
/*****************************************************************************
 * Run : call Handshake() then submit songs
 *****************************************************************************/
static void *Run(void *data)
{
    intf_thread_t          *p_intf = data;
    uint8_t                 p_buffer[1024];
    int                     canc = vlc_savecancel();
    bool                    b_handshaked = false;

    /* data about audioscrobbler session */
    mtime_t                 next_exchange = -1; /**< when can we send data  */
    unsigned int            i_interval = 0;     /**< waiting interval (secs)*/

    intf_sys_t *p_sys = p_intf->p_sys;

    /* main loop */
    for (;;)
    {
        vlc_restorecancel(canc);
        vlc_mutex_lock(&p_sys->lock);
        mutex_cleanup_push(&p_sys->lock);

        do
            vlc_cond_wait(&p_sys->wait, &p_sys->lock);
        while (mdate() < next_exchange);

        vlc_cleanup_run();
        canc = vlc_savecancel();

        /* handshake if needed */
        if (!b_handshaked)
        {
            msg_Dbg(p_intf, "Handshaking with last.fm ...");

            switch(Handshake(p_intf))
            {
                case VLC_ENOMEM:
                    goto out;

                case VLC_ENOVAR:
                    /* username not set */
                    dialog_Fatal(p_intf,
                        _("Last.fm username not set"),
                        "%s", _("Please set a username or disable the "
                        "audioscrobbler plugin, and restart VLC.\n"
                        "Visit http://www.last.fm/join/ to get an account."));
                    goto out;

                case VLC_SUCCESS:
                    msg_Dbg(p_intf, "Handshake successful :)");
                    b_handshaked = true;
                    i_interval = 0;
                    next_exchange = mdate();
                    break;

                case VLC_AUDIOSCROBBLER_EFATAL:
                    msg_Warn(p_intf, "Exiting...");
                    goto out;

                case VLC_EGENERIC:
                default:
                    /* protocol error : we'll try later */
                    HandleInterval(&next_exchange, &i_interval);
                    break;
            }
            /* if handshake failed let's restart the loop */
            if (!b_handshaked)
                continue;
        }

        msg_Dbg(p_intf, "Going to submit some data...");
        char *psz_submit;
        if (asprintf(&psz_submit, "s=%s", p_sys->psz_auth_token) == -1)
            break;

        /* forge the HTTP POST request */
        vlc_mutex_lock(&p_sys->lock);
        audioscrobbler_song_t *p_song;
        for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
        {
            char *psz_submit_song, *psz_submit_tmp;
            p_song = &p_sys->p_queue[i_song];
            if (asprintf(&psz_submit_song,
                    "&a%%5B%d%%5D=%s"
                    "&t%%5B%d%%5D=%s"
                    "&i%%5B%d%%5D=%u"
                    "&o%%5B%d%%5D=P"
                    "&r%%5B%d%%5D="
                    "&l%%5B%d%%5D=%d"
                    "&b%%5B%d%%5D=%s"
                    "&n%%5B%d%%5D=%s"
                    "&m%%5B%d%%5D=%s",
                    i_song, p_song->psz_a,
                    i_song, p_song->psz_t,
                    i_song, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */
                    i_song,
                    i_song,
                    i_song, p_song->i_l,
                    i_song, p_song->psz_b,
                    i_song, p_song->psz_n,
                    i_song, p_song->psz_m
           ) == -1)
            {   /* Out of memory */
                vlc_mutex_unlock(&p_sys->lock);
                goto out;
            }
            psz_submit_tmp = psz_submit;
            if (asprintf(&psz_submit, "%s%s",
                    psz_submit_tmp, psz_submit_song) == -1)
            {   /* Out of memory */
                free(psz_submit_tmp);
                free(psz_submit_song);
                vlc_mutex_unlock(&p_sys->lock);
                goto out;
            }
            free(psz_submit_song);
            free(psz_submit_tmp);
        }
        vlc_mutex_unlock(&p_sys->lock);

        int i_post_socket = net_ConnectTCP(p_intf, p_sys->p_submit_url.psz_host,
                                        p_sys->p_submit_url.i_port);

        if (i_post_socket == -1)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            free(psz_submit);
            continue;
        }

        /* we transmit the data */
        int i_net_ret = net_Printf(p_intf, i_post_socket, NULL,
            "POST %s HTTP/1.1\n"
            "Accept-Encoding: identity\n"
            "Content-length: %zu\n"
            "Connection: close\n"
            "Content-type: application/x-www-form-urlencoded\n"
            "Host: %s\n"
            "User-agent: VLC media player/"VERSION"\r\n"
            "\r\n"
            "%s\r\n"
            "\r\n",
            p_sys->p_submit_url.psz_path, strlen(psz_submit),
            p_sys->p_submit_url.psz_host, psz_submit
       );

        free(psz_submit);
        if (i_net_ret == -1)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            continue;
        }

        i_net_ret = net_Read(p_intf, i_post_socket, NULL,
                    p_buffer, sizeof(p_buffer) - 1, false);
        if (i_net_ret <= 0)
        {
            /* if we get no answer, something went wrong : try again */
            continue;
        }

        net_Close(i_post_socket);
        p_buffer[i_net_ret] = '\0';

        char *failed = strstr((char *) p_buffer, "FAILED");
        if (failed)
        {
            msg_Warn(p_intf, "%s", failed);
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "BADSESSION"))
        {
            msg_Err(p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?");
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "OK"))
        {
            for (int i = 0; i < p_sys->i_songs; i++)
                DeleteSong(&p_sys->p_queue[i]);
            p_sys->i_songs = 0;
            i_interval = 0;
            next_exchange = mdate();
            msg_Dbg(p_intf, "Submission successful!");
        }
        else
        {
            msg_Err(p_intf, "Authentication failed, handshaking again (%s)",
                             p_buffer);
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
        }
    }
out:
    vlc_restorecancel(canc);
    return NULL;
}
/*****************************************************************************
 * Run : call Handshake() then submit songs
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
    char                    *psz_submit, *psz_submit_song, *psz_submit_tmp;
    int                     i_net_ret;
    int                     i_song;
    uint8_t                 p_buffer[1024];
    char                    *p_buffer_pos;
    int                     i_post_socket;
    int                     canc = vlc_savecancel();

    intf_sys_t *p_sys = p_intf->p_sys;

    /* main loop */
    for( ;; )
    {
        bool b_wait = false;


        vlc_restorecancel( canc );
        vlc_mutex_lock( &p_sys->lock );
        mutex_cleanup_push( &p_sys->lock );

        if( mdate() < p_sys->next_exchange )
            /* wait until we can resubmit, i.e.  */
            b_wait = vlc_cond_timedwait( &p_sys->wait, &p_sys->lock,
                                          p_sys->next_exchange ) == 0;
        else
            /* wait for data to submit */
            /* we are signaled each time there is a song to submit */
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );
        vlc_cleanup_run();
        canc = vlc_savecancel();

        if( b_wait )
            continue; /* holding on until next_exchange */

        /* handshake if needed */
        if( !p_sys->b_handshaked )
        {
            msg_Dbg( p_intf, "Handshaking with last.fm ..." );

            switch( Handshake( p_intf ) )
            {
                case VLC_ENOMEM:
                    return;

                case VLC_ENOVAR:
                    /* username not set */
                    dialog_Fatal( p_intf,
                        _("Last.fm username not set"),
                        "%s", _("Please set a username or disable the "
                        "audioscrobbler plugin, and restart VLC.\n"
                        "Visit http://www.last.fm/join/ to get an account.")
                    );
                    return;

                case VLC_SUCCESS:
                    msg_Dbg( p_intf, "Handshake successfull :)" );
                    p_sys->b_handshaked = true;
                    p_sys->i_interval = 0;
                    p_sys->next_exchange = mdate();
                    break;

                case VLC_AUDIOSCROBBLER_EFATAL:
                    msg_Warn( p_intf, "Exiting..." );
                    return;

                case VLC_EGENERIC:
                default:
                    /* protocol error : we'll try later */
                    HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
                    break;
            }
            /* if handshake failed let's restart the loop */
            if( !p_sys->b_handshaked )
                continue;
        }

        msg_Dbg( p_intf, "Going to submit some data..." );

        /* The session may be invalid if there is a trailing \n */
        char *psz_ln = strrchr( p_sys->psz_auth_token, '\n' );
        if( psz_ln )
            *psz_ln = '\0';

        if( !asprintf( &psz_submit, "s=%s", p_sys->psz_auth_token ) )
        {   /* Out of memory */
            return;
        }

        /* forge the HTTP POST request */
        vlc_mutex_lock( &p_sys->lock );
        audioscrobbler_song_t *p_song;
        for( i_song = 0 ; i_song < p_sys->i_songs ; i_song++ )
        {
            p_song = &p_sys->p_queue[i_song];
            if( !asprintf( &psz_submit_song,
                    "&a%%5B%d%%5D=%s"
                    "&t%%5B%d%%5D=%s"
                    "&i%%5B%d%%5D=%u"
                    "&o%%5B%d%%5D=P"
                    "&r%%5B%d%%5D="
                    "&l%%5B%d%%5D=%d"
                    "&b%%5B%d%%5D=%s"
                    "&n%%5B%d%%5D=%s"
                    "&m%%5B%d%%5D=%s",
                    i_song, p_song->psz_a,
                    i_song, p_song->psz_t,
                    i_song, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */
                    i_song,
                    i_song,
                    i_song, p_song->i_l,
                    i_song, p_song->psz_b,
                    i_song, p_song->psz_n,
                    i_song, p_song->psz_m
            ) )
            {   /* Out of memory */
                vlc_mutex_unlock( &p_sys->lock );
                return;
            }
            psz_submit_tmp = psz_submit;
            if( !asprintf( &psz_submit, "%s%s",
                    psz_submit_tmp, psz_submit_song ) )
            {   /* Out of memory */
                free( psz_submit_tmp );
                free( psz_submit_song );
                vlc_mutex_unlock( &p_sys->lock );
                return;
            }
            free( psz_submit_song );
            free( psz_submit_tmp );
        }
        vlc_mutex_unlock( &p_sys->lock );

        i_post_socket = net_ConnectTCP( p_intf,
            p_sys->psz_submit_host, p_sys->i_submit_port );

        if ( i_post_socket == -1 )
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
            p_sys->b_handshaked = false;
            free( psz_submit );
            continue;
        }

        /* we transmit the data */
        i_net_ret = net_Printf(
            p_intf, i_post_socket, NULL,
            POST_REQUEST, p_sys->psz_submit_file,
            (unsigned)strlen( psz_submit ), p_sys->psz_submit_host,
            VERSION, psz_submit
        );

        free( psz_submit );
        if ( i_net_ret == -1 )
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
            p_sys->b_handshaked = false;
            continue;
        }

        i_net_ret = net_Read( p_intf, i_post_socket, NULL,
                    p_buffer, 1023, false );
        if ( i_net_ret <= 0 )
        {
            /* if we get no answer, something went wrong : try again */
            continue;
        }

        net_Close( i_post_socket );
        p_buffer[i_net_ret] = '\0';

        p_buffer_pos = strstr( ( char * ) p_buffer, "FAILED" );
        if ( p_buffer_pos )
        {
            msg_Warn( p_intf, "%s", p_buffer_pos );
            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
            continue;
        }

        p_buffer_pos = strstr( ( char * ) p_buffer, "BADSESSION" );
        if ( p_buffer_pos )
        {
            msg_Err( p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?" );
            p_sys->b_handshaked = false;
            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
            continue;
        }

        p_buffer_pos = strstr( ( char * ) p_buffer, "OK" );
        if ( p_buffer_pos )
        {
            int i;
            for( i = 0; i < p_sys->i_songs; i++ )
                DeleteSong( &p_sys->p_queue[i] );
            p_sys->i_songs = 0;
            p_sys->i_interval = 0;
            p_sys->next_exchange = mdate();
            msg_Dbg( p_intf, "Submission successful!" );
        }
        else
        {
            msg_Err( p_intf, "Authentication failed, handshaking again (%s)", 
                             p_buffer );
            p_sys->b_handshaked = false;
            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );
            continue;
        }
    }
    vlc_restorecancel( canc );
}
Example #27
0
/*****************************************************************************
 * Run : call Handshake() then submit songs
 *****************************************************************************/
static void *Run(void *data)
{
    intf_thread_t          *p_intf = data;
    uint8_t                 p_buffer[1024];
    int                     canc = vlc_savecancel();
    bool                    b_handshaked = false;
    bool                    b_nowp_submission_ongoing = false;

    /* data about audioscrobbler session */
    mtime_t                 next_exchange = 0; /**< when can we send data  */
    unsigned int            i_interval = 0;     /**< waiting interval (secs)*/

    intf_sys_t *p_sys = p_intf->p_sys;

    /* main loop */
    for (;;)
    {
        vlc_restorecancel(canc);
        mwait(next_exchange);

        vlc_mutex_lock(&p_sys->lock);
        mutex_cleanup_push(&p_sys->lock);

        while (p_sys->i_songs == 0 && p_sys->b_submit_nowp == false)
            vlc_cond_wait(&p_sys->wait, &p_sys->lock);

        vlc_cleanup_pop();
        vlc_mutex_unlock(&p_sys->lock);
        canc = vlc_savecancel();

        /* handshake if needed */
        if (!b_handshaked)
        {
            msg_Dbg(p_intf, "Handshaking with last.fm ...");

            switch(Handshake(p_intf))
            {
                case VLC_ENOMEM:
                    goto out;

                case VLC_ENOVAR:
                    /* username not set */
                    vlc_dialog_display_error(p_intf,
                        _("Last.fm username not set"),
                        "%s", _("Please set a username or disable the "
                        "audioscrobbler plugin, and restart VLC.\n"
                        "Visit http://www.last.fm/join/ to get an account."));
                    goto out;

                case VLC_SUCCESS:
                    msg_Dbg(p_intf, "Handshake successful :)");
                    b_handshaked = true;
                    i_interval = 0;
                    next_exchange = 0;
                    break;

                case VLC_AUDIOSCROBBLER_EFATAL:
                    msg_Warn(p_intf, "Exiting...");
                    goto out;

                case VLC_EGENERIC:
                default:
                    /* protocol error : we'll try later */
                    HandleInterval(&next_exchange, &i_interval);
                    break;
            }
            /* if handshake failed let's restart the loop */
            if (!b_handshaked)
                continue;
        }

        msg_Dbg(p_intf, "Going to submit some data...");
        char *psz_submit;
        vlc_url_t *url;
        char *psz_submit_song, *psz_submit_tmp;

        if (asprintf(&psz_submit, "s=%s", p_sys->psz_auth_token) == -1)
            break;

        /* forge the HTTP POST request */
        vlc_mutex_lock(&p_sys->lock);

        if (p_sys->b_submit_nowp)
        {
            b_nowp_submission_ongoing = true;
            url = &p_sys->p_nowp_url;
            if (asprintf(&psz_submit_song,
                "&a=%s"
                "&t=%s"
                "&b=%s"
                "&l=%d"
                "&n=%s"
                "&m=%s",
                p_sys->p_current_song.psz_a,
                p_sys->p_current_song.psz_t,
                p_sys->p_current_song.psz_b ? p_sys->p_current_song.psz_b : "",
                p_sys->p_current_song.i_l,
                p_sys->p_current_song.psz_n ? p_sys->p_current_song.psz_n : "",
                p_sys->p_current_song.psz_m ? p_sys->p_current_song.psz_m : ""
                ) == -1)
            {   /* Out of memory */
                vlc_mutex_unlock(&p_sys->lock);
                goto out;
            }

        }
        else
        {
            url = &p_sys->p_submit_url;
            audioscrobbler_song_t *p_song;
            for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
            {
                p_song = &p_sys->p_queue[i_song];
                if (asprintf(&psz_submit_song,
                        "&a%%5B%d%%5D=%s"
                        "&t%%5B%d%%5D=%s"
                        "&i%%5B%d%%5D=%u"
                        "&o%%5B%d%%5D=P"
                        "&r%%5B%d%%5D="
                        "&l%%5B%d%%5D=%d"
                        "&b%%5B%d%%5D=%s"
                        "&n%%5B%d%%5D=%s"
                        "&m%%5B%d%%5D=%s",
                        i_song, p_song->psz_a,
                        i_song, p_song->psz_t,
                        i_song, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */
                        i_song,
                        i_song,
                        i_song, p_song->i_l,
                        i_song, p_song->psz_b ? p_song->psz_b : "",
                        i_song, p_song->psz_n ? p_song->psz_n : "",
                        i_song, p_song->psz_m ? p_song->psz_m : ""
                       ) == -1)
                {   /* Out of memory */
                        vlc_mutex_unlock(&p_sys->lock);
                        goto out;
                }
            }
        }

        psz_submit_tmp = psz_submit;
        int print_ret = asprintf(&psz_submit, "%s%s",
                                 psz_submit_tmp, psz_submit_song);
        free(psz_submit_tmp);
        free(psz_submit_song);
        vlc_mutex_unlock(&p_sys->lock);

        if (print_ret == -1)
        {   /* Out of memory */
            goto out;
        }

        int i_post_socket = net_ConnectTCP(p_intf, url->psz_host,
                                        url->i_port);

        if (i_post_socket == -1)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            free(psz_submit);
            continue;
        }

        /* we transmit the data */
        int i_net_ret = net_Printf(p_intf, i_post_socket,
            "POST %s HTTP/1.1\r\n"
            "Host: %s\r\n"
            "User-Agent: "PACKAGE_NAME"/"PACKAGE_VERSION"\r\n"
            "Connection: close\r\n"
            "Accept-Encoding: identity\r\n"
            "Content-Type: application/x-www-form-urlencoded\r\n"
            "Content-Length: %zu\r\n"
            "\r\n"
            "%s\r\n"
            "\r\n",
            url->psz_path, url->psz_host, strlen(psz_submit), psz_submit);

        free(psz_submit);
        if (i_net_ret == -1)
        {
            /* If connection fails, we assume we must handshake again */
            HandleInterval(&next_exchange, &i_interval);
            b_handshaked = false;
            net_Close(i_post_socket);
            continue;
        }

        /* FIXME: this might wait forever */
        struct pollfd ufd = { .fd = i_post_socket, .events = POLLIN };
        while( poll( &ufd, 1, -1 ) == -1 );

        /* FIXME: With TCP, you should never assume that a single read will
         * return the entire response... */
        i_net_ret = recv(i_post_socket, p_buffer, sizeof(p_buffer) - 1, 0);
        if (i_net_ret <= 0)
        {
            /* if we get no answer, something went wrong : try again */
            net_Close(i_post_socket);
            continue;
        }

        net_Close(i_post_socket);
        p_buffer[i_net_ret] = '\0';

        char *failed = strstr((char *) p_buffer, "FAILED");
        if (failed)
        {
            msg_Warn(p_intf, "%s", failed);
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "BADSESSION"))
        {
            msg_Err(p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?");
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
            continue;
        }

        if (strstr((char *) p_buffer, "OK"))
        {
            if (b_nowp_submission_ongoing)
            {
                b_nowp_submission_ongoing = false;
                p_sys->b_submit_nowp = false;
            }
            else
            {
                for (int i = 0; i < p_sys->i_songs; i++)
                    DeleteSong(&p_sys->p_queue[i]);
                p_sys->i_songs = 0;
            }

            i_interval = 0;
            next_exchange = 0;
            msg_Dbg(p_intf, "Submission successful!");
        }
        else
        {
            msg_Err(p_intf, "Authentication failed, handshaking again (%s)",
                             p_buffer);
            b_handshaked = false;
            HandleInterval(&next_exchange, &i_interval);
        }
    }
out:
    vlc_restorecancel(canc);
    return NULL;
}
Example #28
0
bool
Volkslogger::Connect(Port &port, OperationEnvironment &env,
                     unsigned timeout_ms)
{
  return Reset(port, env, 10) && Handshake(port, env, timeout_ms);
}
Example #29
0
bool TCP::Connect()
{
    if (AddressT[0].text == nullptr || AddressT[0].text[0] == '\0' || AddressT[1].text == nullptr ||
        AddressT[1].text[0] == '\0')
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Error! Server address is missing or invalid.");
        return false;
    }

    const char *hostname = AddressT[0].text;
    const char *port     = AddressT[1].text;

    DEBUGF(INDI::Logger::DBG_SESSION, "Connecting to %s@%s ...", hostname, port);

    if (device->isSimulation() == false)
    {
        struct sockaddr_in serv_addr;
        struct hostent *hp = nullptr;
        int ret            = 0;

        struct timeval ts;
        ts.tv_sec  = SOCKET_TIMEOUT;
        ts.tv_usec = 0;

        if (sockfd != -1)
            close(sockfd);

        // Lookup host name or IPv4 address
        hp = gethostbyname(hostname);
        if (!hp)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Failed to lookup IP Address or hostname.");
            return false;
        }

        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family      = AF_INET;
        serv_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr;
        serv_addr.sin_port        = htons(atoi(port));

        int socketType = 0;
        if (TcpUdpS[0].s == ISS_ON)
        {
            socketType = SOCK_STREAM;
        }
        else
        {
            socketType = SOCK_DGRAM;
        }

        if ((sockfd = socket(AF_INET, socketType, 0)) < 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Failed to create socket.");
            return false;
        }

        // Connect to the mount
        if ((ret = ::connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0)
        {
            DEBUGF(INDI::Logger::DBG_ERROR, "Failed to connect to mount %s@%s: %s.", hostname, port, strerror(errno));
            close(sockfd);
            sockfd = -1;
            return false;
        }

        // Set the socket receiving and sending timeouts
        setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&ts, sizeof(struct timeval));
        setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&ts, sizeof(struct timeval));
    }

    PortFD = sockfd;

    DEBUG(INDI::Logger::DBG_DEBUG, "Connection successful, attempting handshake...");
    bool rc = Handshake();

    if (rc)
    {
        DEBUGF(INDI::Logger::DBG_SESSION, "%s is online.", getDeviceName());
        device->saveConfig(true, "DEVICE_ADDRESS");
        device->saveConfig(true, "CONNECTION_TYPE");
    }
    else
        DEBUG(INDI::Logger::DBG_DEBUG, "Handshake failed.");

    return rc;
}
// TODO: make sure this is called from STS. Otherwise
// we have thread safety issues
bool TransportLayerDtls::Setup() {
  CheckThread();
  SECStatus rv;

  if (!downward_) {
    MOZ_MTLOG(ML_ERROR, "DTLS layer with nothing below. This is useless");
    return false;
  }
  nspr_io_adapter_ = new TransportLayerNSPRAdapter(downward_);

  if (!identity_) {
    MOZ_MTLOG(ML_ERROR, "Can't start DTLS without an identity");
    return false;
  }

  if (verification_mode_ == VERIFY_UNSET) {
    MOZ_MTLOG(ML_ERROR,
              "Can't start DTLS without specifying a verification mode");
    return false;
  }

  if (transport_layer_identity == PR_INVALID_IO_LAYER) {
    transport_layer_identity = PR_GetUniqueIdentity("nssstreamadapter");
  }

  ScopedPRFileDesc pr_fd(PR_CreateIOLayerStub(transport_layer_identity,
                                              &TransportLayerMethods));
  MOZ_ASSERT(pr_fd != nullptr);
  if (!pr_fd)
    return false;
  pr_fd->secret = reinterpret_cast<PRFilePrivate *>(nspr_io_adapter_.get());

  ScopedPRFileDesc ssl_fd(DTLS_ImportFD(nullptr, pr_fd));
  MOZ_ASSERT(ssl_fd != nullptr);  // This should never happen
  if (!ssl_fd) {
    return false;
  }

  pr_fd.forget(); // ownership transfered to ssl_fd;

  if (role_ == CLIENT) {
    MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as client");
    rv = SSL_GetClientAuthDataHook(ssl_fd, GetClientAuthDataHook,
                                   this);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't set identity");
      return false;
    }
  } else {
    MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as server");
    // Server side
    rv = SSL_ConfigSecureServer(ssl_fd, identity_->cert(),
                                identity_->privkey(),
                                kt_rsa);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't set identity");
      return false;
    }

    // Insist on a certificate from the client
    rv = SSL_OptionSet(ssl_fd, SSL_REQUEST_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't request certificate");
      return false;
    }

    rv = SSL_OptionSet(ssl_fd, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      MOZ_MTLOG(ML_ERROR, "Couldn't require certificate");
      return false;
    }
  }

  // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS
  // 1.0 for stream modes.
  SSLVersionRange version_range = {
    SSL_LIBRARY_VERSION_TLS_1_1,
    SSL_LIBRARY_VERSION_TLS_1_2
  };

  rv = SSL_VersionRangeSet(ssl_fd, &version_range);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Can't disable SSLv3");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable session tickets");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable session caching");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_DEFLATE, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable deflate");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_NEVER);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable renegotiation");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable false start");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_NO_LOCKS, PR_TRUE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable locks");
    return false;
  }

  rv = SSL_OptionSet(ssl_fd, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't disable ECDHE key reuse");
    return false;
  }

  if (!SetupCipherSuites(ssl_fd)) {
    return false;
  }

  // Certificate validation
  rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook,
                               reinterpret_cast<void *>(this));
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't set certificate validation hook");
    return false;
  }

  // Now start the handshake
  rv = SSL_ResetHandshake(ssl_fd, role_ == SERVER ? PR_TRUE : PR_FALSE);
  if (rv != SECSuccess) {
    MOZ_MTLOG(ML_ERROR, "Couldn't reset handshake");
    return false;
  }
  ssl_fd_ = ssl_fd.forget();

  // Finally, get ready to receive data
  downward_->SignalStateChange.connect(this, &TransportLayerDtls::StateChange);
  downward_->SignalPacketReceived.connect(this, &TransportLayerDtls::PacketReceived);

  if (downward_->state() == TS_OPEN) {
    Handshake();
  }

  return true;
}