Esempio n. 1
0
  const json IPCClientPrivate::receiveOne()
  {
    char *data = new char[1<<20];
    ssize_t recv_size;

    if ((recv_size = qb_ipcc_event_recv(_qb_conn, data, 1<<20, 500)) < 0) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Receive error");
    }

    if (recv_size < (ssize_t)sizeof(struct qb_ipc_response_header)) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Message too small");
    }

    const struct qb_ipc_response_header *hdr = \
      (const struct qb_ipc_response_header *)data;

    if (hdr->size != recv_size) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Invalid size in header");
    }

    const char *jdata = data + sizeof(struct qb_ipc_response_header);
    const size_t jsize = recv_size - sizeof(struct qb_ipc_response_header);
    const std::string json_string(jdata, jsize);
    const json jobj = json::parse(json_string);
    delete [] data;
    return std::move(jobj);
  }
Esempio n. 2
0
Socket::Type Socket::getType() const
{
    int family;
    socklen_t length = sizeof(family);

    if (::getsockopt(mFD, SOL_SOCKET, SO_DOMAIN, &family, &length)) {
        if (errno == EBADF) {
            return Type::INVALID;
        } else {
            const std::string msg = "Error getting socket type: " + getSystemErrorMessage();
            LOGE(msg);
            throw IPCException(msg);
        }
    }


    if (family == AF_UNIX || family == AF_LOCAL) {
        return Type::UNIX;
    }

    if (family == AF_INET || family == AF_INET6) {
        return Type::INET;
    }

    return Type::INVALID;
}
Esempio n. 3
0
  IPCException IPC::IPCExceptionFromMessage(const MessagePointer& message)
  {
    const IPC::Exception* const exception_message = \
      reinterpret_cast<const IPC::Exception*>(message.get());

    return IPCException(exception_message->context(),
                        exception_message->object(),
                        exception_message->reason(),
                        exception_message->request_id());
  }
Esempio n. 4
0
std::shared_ptr<Socket> Socket::accept()
{
    int sockfd = ::accept(mFD, nullptr, nullptr);
    if (sockfd == -1) {
        const std::string msg = "Error in accept: " + getSystemErrorMessage();
        LOGE(msg);
        throw IPCException(msg);
    }
    setFdOptions(sockfd);
    return std::make_shared<Socket>(sockfd);
}
int AbstractSharedMemory::getId(const char *fileName, int id, int flags) {
	key_t clave = ftok (fileName, id);
	if ( clave == -1 ) {
		char error[255];
		sprintf(error, "Fallo la operacion ftok: %s", strerror(errno));
		char className[255];
		strcpy(className, "AbstractSharedMemory");
		throw IPCException((const char*)className, error);
	}

	this->id = shmget( clave, this->getMemorySize() , flags);
	if ( this->id == -1 ) {
		char error[255];
		sprintf(error, "Fallo la operacion shmget: %s", strerror(errno));
		char className[255];
		strcpy(className, "AbstractSharedMemory");	
		throw IPCException((const char*)className, error);
	}
	return 0;
}
Esempio n. 6
0
  void IPCClientPrivate::connect()
  {
    _qb_conn = qb_ipcc_connect("usbguard", 1<<20);

    if (_qb_conn == nullptr) {
      throw IPCException(IPCException::ConnectionError, "IPC Connection not established");
    }

    qb_ipcc_fd_get(_qb_conn, &_qb_conn_fd);

    if (_qb_conn_fd < 0) {
      qb_ipcc_disconnect(_qb_conn);
      _qb_conn = nullptr;
      _qb_conn_fd = -1;
      throw IPCException(IPCException::ConnectionError, "Bad file descriptor");
    }

    qb_loop_poll_add(_qb_loop, QB_LOOP_HIGH, _qb_conn_fd, POLLIN, this, qbIPCMessageProcessFn);
    _p_instance.IPCConnected();
    return;
  }
Esempio n. 7
0
//-----------------------------------------------------------------------------
int Semaphore::destroy(void)
{
	int resultado = semctl(this->id, 0, IPC_RMID, (struct semid_ds *) 0);
	if ( resultado == -1 ) {		
		char error[255];
		sprintf(error, "Fallo la operacion semctl (destroy): %s", strerror(errno));
		char className[255];
		strcpy(className, "Semaphore");
		throw IPCException(className, error);
	}
	return resultado;	
}
Esempio n. 8
0
//-----------------------------------------------------------------------------
int Semaphore::getId(char *fileName, int id, int qty, int flags)
{ 
	char buffer[255];
	key_t clave = ftok (fileName, id);
	if ( clave == -1 ) {
		char error[255];
		sprintf(error, "Fallo la operacion ftok: %s", strerror(errno));
		char className[255];
		strcpy(className, "Semaphore");
		throw IPCException(className, error);
	}

	this->id = semget( clave, qty, flags);
	if ( this->id == -1 ) {	
		char error[255];
		sprintf(error, "Fallo la operacion semget: %s", strerror(errno));
		char className[255];
		strcpy(className, "Semaphore");
		throw IPCException(className, error);
	}
	return 0;
}
int AbstractSharedMemory::attachMemory() {
	// Me attacho a la memoria dejando al SO que elija donde ubicar la memoria 
	//(atributo en NULL)y para lectura/escritura (atributo en 0)
	void *shmaddr = shmat(this->id, NULL, 0);
	if (shmaddr == (void *)-1) {
		char error[255];
		sprintf(error, "Fallo la operacion shmat: %s", strerror(errno));
		char className[255];
		strcpy(className, "AbstractSharedMemory");
		throw IPCException((const char*)className, error);
	}
	data = shmaddr;
	return 0;
}
Esempio n. 10
0
//-----------------------------------------------------------------------------
void Semaphore::wait(int numSem)
{	
	struct sembuf oper;
	oper.sem_num = numSem;
	oper.sem_op = -1;
	int resultado = semop(this->id, &oper, 1);
	if (resultado == -1) {
		char error[255];
		sprintf(error, "Fallo la operacion wait: %s", strerror(errno));
		char className[255];
		strcpy(className, "Semaphore");
		throw IPCException(className, error);	
	}
}
int AbstractMessageQueue::getId(char *fileName, int id, int flags) {
	
	char buffer[255];
			
	key_t clave = ftok (fileName, id);
	if ( clave == -1 ) {
		char error[255];
		sprintf(error, "Fallo la operacion ftok: %s", strerror(errno));
		char className[255];
		strcpy(className, "AbstractMessageQueue");
		throw IPCException(className, error);
	}
	
	this->id = msgget ( clave ,flags );
	if ( this->id == -1 ) {
		char error[255];
		sprintf(error, "Fallo la operacion msgget: %s", strerror(errno));
		char className[255];
		strcpy(className, "AbstractMessageQueue");
		throw IPCException(className, error);
	}
	return 0;
}
Esempio n. 12
0
unsigned short Socket::getPort() const
{
    ::sockaddr_storage address = {0, 0, {0}};
    ::socklen_t length = sizeof(address);
    if (::getsockname(mFD, reinterpret_cast<sockaddr*>(&address), &length) != 0) {
        const std::string msg = "Failed to get socked address: " + getSystemErrorMessage();
        LOGE(msg);
        throw IPCException(msg);
    }

    if (length == sizeof(sockaddr_in)) {
        return ntohs(reinterpret_cast<const sockaddr_in*>(&address)->sin_port);
    } else {
        return ntohs(reinterpret_cast<const sockaddr_in6*>(&address)->sin6_port);
    }
}
Esempio n. 13
0
int Socket::createSocketInternal(const std::string& path)
{
    // Isn't the path too long?
    if (path.size() >= sizeof(sockaddr_un::sun_path)) {
        const std::string msg = "Socket's path too long";
        LOGE(msg);
        throw IPCException(msg);
    }

    ::sockaddr_un serverAddress;
    serverAddress.sun_family = AF_UNIX;
    ::strncpy(serverAddress.sun_path, path.c_str(), path.length() + 1);

    return getBoundFd(AF_UNIX,
                      SOCK_STREAM,
                      UNIX_SOCKET_PROTOCOL,
                      reinterpret_cast<struct sockaddr*>(&serverAddress),
                      sizeof(struct sockaddr_un));
}
Esempio n. 14
0
int Socket::getSystemdSocketInternal(const std::string& path)
{
    int n = ::sd_listen_fds(-1 /*Block further calls to sd_listen_fds*/);
    if (n < 0) {
        const std::string msg = "sd_listen_fds failed: " + getSystemErrorMessage(-n);
        LOGE(msg);
        throw IPCException(msg);
    }

    for (int fd = SD_LISTEN_FDS_START;
            fd < SD_LISTEN_FDS_START + n;
            ++fd) {
        if (0 < ::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0)) {
            setFdOptions(fd);
            return fd;
        }
    }
    LOGW("No usable sockets were passed by systemd.");
    return -1;
}
Esempio n. 15
0
 void IPCClientPrivate::processOne(const json& jobj)
 {
   if (!jobj["_e"].is_null()) {
     processExceptionJSON(jobj);
   }
   else if (!jobj["_s"].is_null()) {
     processSignalJSON(jobj);
   }
   else if (!jobj["_r"].is_null()) {
     processMethodReturnJSON(jobj);
   }
   else if (!jobj["_m"].is_null()) {
     processMethodCallJSON(jobj);
   }
   else {
     disconnect();
     throw IPCException(IPCException::ProtocolError, "Unknown message");
   }
   return;
 }
Esempio n. 16
0
  uint32_t IPCClientPrivate::appendRule(const std::string& rule_spec, uint32_t parent_seqn, uint32_t timeout_sec)
  {
    const json jreq = {
      {          "_m", "appendRule" },
      {   "rule_spec", rule_spec },
      { "parent_seqn", parent_seqn },
      { "timeout_sec", timeout_sec },
      {          "_i", IPC::uniqueID() }
    };

    const json jrep = qbIPCSendRecvJSON(jreq);

    try {
      const uint32_t retval = jrep["retval"];
      return retval;
    } catch(...) {
      throw IPCException(IPCException::ProtocolError,
			 "Invalid or missing return value after calling appendRule");
    }
  }
Esempio n. 17
0
//-----------------------------------------------------------------------------
int Semaphore::initializeSemaphore(int numSem, int val)
{
	// Structure used in semctl
	union semun {
		int val;					// Value for SETVAL
		struct semid_ds *buf;		// Buffer por IPC_STAT, IPC_SET
		unsigned short *array;		// Array for GETALL, SETALL
		struct semifo *__buf;		// Buffer for IPC_INFO(Linux specific)
	} arg;

	arg.val = val;
	int resultado = semctl(this->id, numSem, SETVAL, arg);
	if ( resultado == -1 ) {		
		char error[255];
		sprintf(error, "Fallo la operacion semctl (init): %s", strerror(errno));
		char className[255];
		strcpy(className, "Semaphore");
		throw IPCException(className, error);
	}
	return resultado;
} 
Esempio n. 18
0
Socket Socket::connectUNIX(const std::string& path, const int timeoutMs)
{
    // Isn't the path too long?
    if (path.size() >= sizeof(::sockaddr_un::sun_path)) {
        const std::string msg = "Socket's path too long";
        LOGE(msg);
        throw IPCException(msg);
    }

    // Fill address
    struct ::sockaddr_un serverAddress;
    serverAddress.sun_family = AF_UNIX;
    ::strncpy(serverAddress.sun_path, path.c_str(), sizeof(::sockaddr_un::sun_path));

    int fd = getConnectedFd(AF_UNIX,
                            SOCK_STREAM,
                            UNIX_SOCKET_PROTOCOL,
                            reinterpret_cast<struct sockaddr*>(&serverAddress),
                            sizeof(struct ::sockaddr_un),
                            timeoutMs);

    return Socket(fd);
}
Esempio n. 19
0
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void RtSigSet::del (unsigned signum) throw (IPCException)
{
    if (sigdelset(this, SIGRTMIN + signum))
        throw IPCException (errno);
}
Esempio n. 20
0
  json IPCClientPrivate::qbIPCSendRecvJSON(const json& jval)
  {
    if (!isConnected()) {
      throw IPCException(IPCException::ConnectionError, "Not connected");
    }

    const std::string json_string = jval.dump();

    struct qb_ipc_request_header hdr;
    hdr.id = 0;
    hdr.size = sizeof hdr + json_string.size();

    struct iovec iov[2];
    iov[0].iov_base = &hdr;
    iov[0].iov_len = sizeof hdr;
    iov[1].iov_base = (void *)json_string.c_str();
    iov[1].iov_len = json_string.size();

    const uint64_t id = jval["_i"];

    /* Lock the return value slot map */
    std::unique_lock<std::mutex> rv_map_lock(_rv_map_mutex);

    /*
     * Create the promise and future objects.
     * The promise will be fullfiled by the message
     * processing handlers after they process
     * a reply from the server.
     */
    auto& promise = _rv_map[id];
    auto future = promise.get_future();

    qb_ipcc_sendv(_qb_conn, iov, 2);

    /* 
     * Unlock the return value map so that the message
     * processing handler aren't blocked.
     */
    rv_map_lock.unlock();

    /* Wait for some time for the reply to be received */
    const std::chrono::milliseconds timeout_ms(5*1000);
    const bool timed_out = \
      future.wait_for(timeout_ms) == std::future_status::timeout;

    json retval;

    if (!timed_out) {
      retval = future.get();
    }

    /* Remove the slot from the return value slot map */
    rv_map_lock.lock();
    _rv_map.erase(id);
    rv_map_lock.unlock();

    if (timed_out) {
      throw IPCException(IPCException::TransientError, "Timed out while waiting for IPC reply");
    }
    else {
      /*
       * We might have caused an exception. Check whether
       * that's the case and if true, throw it here.
       */
      if (isExceptionJSON(retval)) {
	throw IPCException(IPCException::ProtocolError, "The remote end sent an exception");
      }
      else {
	return std::move(retval);
      }
    }
    return json();
  }
Esempio n. 21
0
  void IPCClientPrivate::processSignalJSON(const json& jobj)
  {
    try {
      const std::string name = jobj["_s"];
      if (name == "DeviceInserted") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	std::vector<USBInterfaceType> interfaces;
	for (auto const& jitem : jobj["interfaces"]) {
	  const std::string type_string = jitem;
	  interfaces.push_back(USBInterfaceType(type_string));
	}

	_p_instance.DeviceInserted(jobj["seqn"],
				   attributes,
				   interfaces,
				   jobj["rule_match"],
				   jobj["rule_seqn"]);
      }
      else if (name == "DevicePresent") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	std::vector<USBInterfaceType> interfaces;
	for (auto const& jitem : jobj["interfaces"]) {
	  const std::string type_string = jitem;
	  interfaces.push_back(USBInterfaceType(type_string));
	}

	_p_instance.DevicePresent(jobj["seqn"],
				  attributes,
				  interfaces,
				  Rule::targetFromString(jobj["target"]));
      }
      else if (name == "DeviceRemoved") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	_p_instance.DeviceRemoved(jobj["seqn"],
				  attributes);
      }
      else if (name == "DeviceAllowed") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	_p_instance.DeviceAllowed(jobj["seqn"],
				  attributes,
				  jobj["rule_match"],
				  jobj["rule_seqn"]);
      }
      else if (name == "DeviceBlocked") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	_p_instance.DeviceBlocked(jobj["seqn"],
				  attributes,
				  jobj["rule_match"],
				  jobj["rule_seqn"]);
      }
      else if (name == "DeviceRejected") {
	const json attributes_json = jobj.at("attributes");
	std::map<std::string,std::string> attributes;

	for (auto it = attributes_json.begin(); it != attributes_json.end(); ++it) {
	  const std::string key = it.key();
	  const std::string value = it.value();
	  attributes[key] = value;
	}

	_p_instance.DeviceRejected(jobj["seqn"],
				   attributes,
				   jobj["rule_match"],
				   jobj["rule_seqn"]);
      }
      else {
	throw 0;
      }
    } catch(...) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Invalid IPC signal data");
    }
    return;
  }