Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cef4ade8 authored by Lingfeng Yang's avatar Lingfeng Yang Committed by Joshua Duong
Browse files

adb client interface for secure services

This CL exposes a callback-based interface to perform some action for
each resolved pairing/connect service as a function of their hostname,
ip address, and port.

The ADB client can then use this information to either set up secure
connections directly, or to tell the adb host server to do so, or
something.

Bug: 111434128, 119490749

Test: N/A
Exempt-From-Owner-Approval: already approved
Change-Id: I2dd04c322df5b0597859f44703cfd2f3f29fd737
parent 4b62bcde
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -23,6 +23,10 @@ const char* kADBServiceType = "_adb._tcp";
const char* kADBSecurePairingServiceType = "_adb_secure_pairing._tcp";
const char* kADBSecureConnectServiceType = "_adb_secure_connect._tcp";

const int kADBTransportServiceRefIndex = 0;
const int kADBSecurePairingServiceRefIndex = 1;
const int kADBSecureConnectServiceRefIndex = 2;

const char* kADBDNSServices[] = {
        kADBServiceType,
        kADBSecurePairingServiceType,
@@ -30,6 +34,5 @@ const char* kADBDNSServices[] = {
};

const int kNumADBDNSServices = arraysize(kADBDNSServices);
const int kADBTransportServiceRefIndex = 0;

#endif
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#pragma once

#include <functional>
#include <optional>
#include <string>

@@ -86,3 +87,16 @@ std::optional<std::string> adb_get_server_executable_path();
// Globally acccesible argv/envp, for the purpose of re-execing adb.
extern const char* _Nullable * _Nullable __adb_argv;
extern const char* _Nullable * _Nullable __adb_envp;

// ADB Secure DNS service interface. Used to query what ADB Secure DNS services have been
// resolved, and to run some kind of callback for each one.
using adb_secure_foreach_service_callback = std::function<void(
        const char* _Nonnull host_name, const char* _Nonnull ip_address, uint16_t port)>;

// Queries pairing/connect services that have been discovered and resolved.
// If |host_name| is not null, run |cb| only for services
// matching |host_name|. Otherwise, run for all services.
void adb_secure_foreach_pairing_service(const char* _Nullable host_name,
                                        adb_secure_foreach_service_callback cb);
void adb_secure_foreach_connect_service(const char* _Nullable host_name,
                                        adb_secure_foreach_service_callback cb);
+90 −2
Original line number Diff line number Diff line
@@ -25,10 +25,12 @@
#endif

#include <thread>
#include <vector>

#include <android-base/stringprintf.h>
#include <dns_sd.h>

#include "adb_client.h"
#include "adb_mdns.h"
#include "adb_trace.h"
#include "fdevent/fdevent.h"
@@ -163,14 +165,44 @@ class ResolvedService : public AsyncServiceRef {
        if (adb_DNSServiceShouldConnect(regType_.c_str())) {
            std::string response;
            connect_device(android::base::StringPrintf(addr_format, ip_addr_, port_), &response);
            D("Connect to %s (%s:%hu) : %s", serviceName_.c_str(), ip_addr_, port_,
              response.c_str());
            D("Connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
              ip_addr_, port_, response.c_str());
        } else {
            D("Not immediately connecting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)",
              serviceName_.c_str(), regType_.c_str(), ip_addr_, port_);
        }

        int adbSecureServiceType = serviceIndex();
        switch (adbSecureServiceType) {
            case kADBSecurePairingServiceRefIndex:
                sAdbSecurePairingServices->push_back(this);
                break;
            case kADBSecureConnectServiceRefIndex:
                sAdbSecureConnectServices->push_back(this);
                break;
            default:
                break;
        }
    }

    int serviceIndex() const { return adb_DNSServiceIndexByName(regType_.c_str()); }

    std::string hostTarget() const { return hosttarget_; }

    std::string ipAddress() const { return ip_addr_; }

    uint16_t port() const { return port_; }

    using ServiceRegistry = std::vector<ResolvedService*>;

    static ServiceRegistry* sAdbSecurePairingServices;
    static ServiceRegistry* sAdbSecureConnectServices;

    static void initAdbSecure();

    static void forEachService(const ServiceRegistry& services, const std::string& hostname,
                               adb_secure_foreach_service_callback cb);

  private:
    std::string serviceName_;
    std::string regType_;
@@ -181,6 +213,55 @@ class ResolvedService : public AsyncServiceRef {
    char ip_addr_[INET6_ADDRSTRLEN];
};

// static
std::vector<ResolvedService*>* ResolvedService::sAdbSecurePairingServices = NULL;

// static
std::vector<ResolvedService*>* ResolvedService::sAdbSecureConnectServices = NULL;

// static
void ResolvedService::initAdbSecure() {
    if (!sAdbSecurePairingServices) {
        sAdbSecurePairingServices = new ServiceRegistry;
    }
    if (!sAdbSecureConnectServices) {
        sAdbSecureConnectServices = new ServiceRegistry;
    }
}

// static
void ResolvedService::forEachService(const ServiceRegistry& services,
                                     const std::string& wanted_host,
                                     adb_secure_foreach_service_callback cb) {
    initAdbSecure();

    for (auto service : services) {
        auto hostname = service->hostTarget();
        auto ip = service->ipAddress();
        auto port = service->port();

        if (wanted_host == "") {
            cb(hostname.c_str(), ip.c_str(), port);
        } else if (hostname == wanted_host) {
            cb(hostname.c_str(), ip.c_str(), port);
        }
    }
}

// static
void adb_secure_foreach_pairing_service(const char* host_name,
                                        adb_secure_foreach_service_callback cb) {
    ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices,
                                    host_name ? host_name : "", cb);
}

// static
void adb_secure_foreach_connect_service(const char* host_name,
                                        adb_secure_foreach_service_callback cb) {
    ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices,
                                    host_name ? host_name : "", cb);
}

static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/,
                                          DNSServiceFlags /*flags*/,
                                          uint32_t /*interfaceIndex*/,
@@ -193,6 +274,12 @@ static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/,
    std::unique_ptr<ResolvedService> data(
        reinterpret_cast<ResolvedService*>(context));
    data->Connect(address);

    // For ADB Secure services, keep those ResolvedService's around
    // for later processing with secure connection establishment.
    if (data->serviceIndex() != kADBTransportServiceRefIndex) {
        data.release();
    }
}

static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
@@ -314,5 +401,6 @@ void init_mdns_transport_discovery_thread(void) {
}

void init_mdns_transport_discovery(void) {
    ResolvedService::initAdbSecure();
    std::thread(init_mdns_transport_discovery_thread).detach();
}