Search in sources :

Example 1 with ChsDatabase

use of dev.hawala.xns.level4.common.ChsDatabase in project dodo by devhawala.

the class MailingOldImpl method transport_post.

/*
	 *  post
	 *   = procedure 1
	 */
private static void transport_post(PostParams params, PostResults results) {
    // log ingoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        params.append(sb, "  ", "params");
        log("##\n## procedure MailingImpl.transport_post() -- params\n%s\n##\n", sb.toString());
    }
    // check the credentials:
    // - this procedure is called for the generic mail server ("Mail Service:CHServers:CHServers")
    // - not for this specific mail service (which the 1st mail service name in the clearinghouse database)
    // - so use the generic name
    // - and: only the machine id for *this* mail service works...
    Credentials credentials = params.authPair.credentials;
    Verifier verifier = params.authPair.verifier;
    StrongVerifier decodedVerifier = StrongVerifier.make();
    int[] decodedConversationKey = new int[4];
    ThreePartName senderName = // throws an exception on invalid credentials
    mailService.checkCredentials(mailService.getChsDatabase().getGenericMailServiceName(), mailService.getMachineId(), credentials, verifier, decodedConversationKey, decodedVerifier);
    // check the recipients
    NameList allRecipients = NameList.make();
    ChsDatabase chs = mailService.getChsDatabase();
    for (int i = 0; i < params.recipients.size(); i++) {
        Name rcpt = params.recipients.get(i);
        String rcptFqn = chs.resolveName(rcpt);
        List<Name> dlMemberNames;
        if (rcptFqn != null && mailService.hasMailbox(rcptFqn)) {
            Name rcptName = Name.make();
            rcptName.from(rcptFqn);
            allRecipients.addDistinct(rcptName);
        } else if (params.allowDLRecipients.get() && rcptFqn != null && (dlMemberNames = getUserGroupMembersLcFqns(rcptFqn)) != null) {
            for (Name dlMember : dlMemberNames) {
                allRecipients.addDistinct(dlMember);
            }
        } else {
            UndeliveredName undelivered = UndeliveredName.make();
            undelivered.reason.set(UndeliveredNameType.noSuchRecipient);
            undelivered.name.from(rcpt);
            results.invalidNames.add(undelivered);
        }
    }
    // if invalid recipients are not allowed and we have some or if all recipients are invalid: throw error...
    if ((results.invalidNames.size() > 0 && !params.postIfInvalidNames.get()) || results.invalidNames.size() == params.recipients.size()) {
        InvalidRecipientsErrorRecord err = new InvalidRecipientsErrorRecord();
        for (int i = 0; i < results.invalidNames.size(); i++) {
            err.nameList.add(results.invalidNames.get(i));
        }
        err.raise();
    }
    // so create the mail
    try {
        ByteContentSource source = new ByteContentSource(params.content);
        if (allRecipients.size() > 0) {
            int[] mailId = mailService.postMail(senderName, allRecipients, params.contentsType.get(), source);
            for (int i = 0; i < mailId.length; i++) {
                results.msgID.get(i).set(mailId[i]);
            }
        } else {
            // abort bulk-data transfer
            source.read(null);
        }
    } catch (EndOfMessageException e) {
        new ConnectionErrorRecord(ConnectionProblem.otherCallProblem).raise();
    }
    // log outgoing data
    if (logParamsAndResults) {
        StringBuilder sb = new StringBuilder();
        results.append(sb, "  ", "results");
        log("##\n## procedure MailingImpl.transport_post() -- results\n%s\n##\n", sb.toString());
    }
}
Also used : NameList(dev.hawala.xns.level4.mailing.MailingCommon.NameList) InvalidRecipientsErrorRecord(dev.hawala.xns.level4.mailing.MailTransport4.InvalidRecipientsErrorRecord) StrongVerifier(dev.hawala.xns.level4.common.AuthChsCommon.StrongVerifier) Verifier(dev.hawala.xns.level4.common.AuthChsCommon.Verifier) ConnectionErrorRecord(dev.hawala.xns.level4.mailing.MailingCommon.ConnectionErrorRecord) Name(dev.hawala.xns.level4.common.AuthChsCommon.Name) UndeliveredName(dev.hawala.xns.level4.mailing.MailingCommon.UndeliveredName) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) StrongVerifier(dev.hawala.xns.level4.common.AuthChsCommon.StrongVerifier) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) UndeliveredName(dev.hawala.xns.level4.mailing.MailingCommon.UndeliveredName) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) ChsDatabase(dev.hawala.xns.level4.common.ChsDatabase) ByteContentSource(dev.hawala.xns.level4.filing.ByteContentSource) Credentials(dev.hawala.xns.level4.common.AuthChsCommon.Credentials)

Example 2 with ChsDatabase

use of dev.hawala.xns.level4.common.ChsDatabase in project dodo by devhawala.

the class Authentication2Impl method init.

/**
 * Set values to use for responses.
 *
 * @param network networkId for the local network
 * @param machine hostId of the local machine
 * @param chsDb clearinghouse database to use for courier requests
 * @param hostIds explicit list of network addresses to respond BfS requests with
 * 		(if the local machine is to be part of the BfS responses, the host
 * 		{@code network}/{@code machine} must be explicitely added to {@code hostIds})
 */
public static void init(long network, long machine, ChsDatabase chsDb, List<NetworkAddress> hostIds) {
    networkId = network;
    machineId = machine;
    chsDatabase = chsDb;
    bfsHosts.clear();
    if (hostIds == null || hostIds.isEmpty()) {
        // add the only known server to the address list: ourself
        NetworkAddress addr = NetworkAddress.make();
        addr.network.set((int) networkId);
        addr.host.set(machineId);
        addr.socket.set(0);
        bfsHosts.add(addr);
    } else {
        bfsHosts.addAll(hostIds);
    }
}
Also used : NetworkAddress(dev.hawala.xns.level4.common.AuthChsCommon.NetworkAddress)

Example 3 with ChsDatabase

use of dev.hawala.xns.level4.common.ChsDatabase in project dodo by devhawala.

the class Clearinghouse3Impl method checkCredentials.

/* internal functionality */
private static void checkCredentials(String procName, Authenticator agent, boolean allowEmptyCredentials) {
    boolean credentialsOk = false;
    try {
        if (agent.credentials.value.size() == 0) {
            credentialsOk = allowEmptyCredentials;
        } else if (agent.credentials.type.get() == CredentialsType.simple) {
            credentialsOk = AuthChsCommon.simpleCheckPasswordForSimpleCredentials(chsDatabase, agent.credentials, agent.verifier) != null;
        } else {
            credentialsOk = AuthChsCommon.checkStrongCredentials(chsDatabase, agent.credentials, agent.verifier, chsDatabase.getChsQueryName(), machineId, null, null) != null;
        }
    } catch (IllegalArgumentException iac) {
        AuthenticationErrorRecord err = new AuthenticationErrorRecord(Problem.credentialsInvalid);
        Log.C.printf("CHS3", "Clearinghouse3Impl.%s() IllegalArgumentException (name not existing) -> rejecting with AuthenticationError[credentialsInvalid]\n", procName);
        err.raise();
    } catch (EndOfMessageException e) {
        AuthenticationErrorRecord err = new AuthenticationErrorRecord(Problem.inappropriateCredentials);
        Log.C.printf("CHS3", "Clearinghouse3Impl.%s() EndOfMessageException when deserializing credsObject -> rejecting with AuthenticationError[inappropriateCredentials]\n", procName);
        err.raise();
    } catch (Exception e) {
        AuthenticationErrorRecord err = new AuthenticationErrorRecord(Problem.otherProblem);
        Log.C.printf("CHS3", "Clearinghouse3Impl.%s() Exception when checking credentials -> rejecting with AuthenticationError[otherProblem]: %s\n", procName, e.getMessage());
        err.raise();
    }
    if (!credentialsOk) {
        AuthenticationErrorRecord err = new AuthenticationErrorRecord(Problem.credentialsInvalid);
        Log.C.printf("CHS3", "Clearinghouse3Impl.%s() -> rejecting with AuthenticationError[credentialsInvalid]\n", procName);
        err.raise();
    }
}
Also used : AuthenticationErrorRecord(dev.hawala.xns.level4.chs.Clearinghouse3.AuthenticationErrorRecord) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException) NoMoreWriteSpaceException(dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException) EndOfMessageException(dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException)

Example 4 with ChsDatabase

use of dev.hawala.xns.level4.common.ChsDatabase in project dodo by devhawala.

the class AuthChsCommon method checkStrongCredentials.

/**
 * Check that the strong credentials and the strong verifier are
 * both valid for the recipient on the given machine.
 *
 * @param chsDatabase the clearinghouse database to check against
 * @param credentials the credentials to verify
 * @param verifier the verifier going with the credentials
 * @param recipient the recipient for which the the strong credentials are encoded
 * @param recipientMachineId the target machine for which the verifier is encoded
 * @param decodedConversationKey target where to store the conversation encryption key for
 *   the session (the key will only be stored there if not {@code null} and at least
 *   4 entries long).
 * @return {@code null} if the credentials is not of strong type or the
 *   initiator encoded in the credentials is invalid or if the expiration time
 *   of the credentials are expired or the verifier timestamp is invalid;
 *   else the Clearinghouse name of the user if the credentials passed the tests.
 * @throws EndOfMessageException if decoding the credentials or verifier after
 *    decryption fails
 * @throws IllegalArgumentException if the recipient is invalid or has no
 *    strong password for decryption
 * @throws Exception if any decryption fails
 */
public static ThreePartName checkStrongCredentials(ChsDatabase chsDatabase, Credentials credentials, Verifier verifier, ThreePartName recipient, long recipientMachineId, int[] decodedConversationKey, StrongVerifier decodedVerifier) throws Exception {
    // get the recipient decryption password
    if (credentials.type.get() != CredentialsType.strong) {
        return null;
    }
    byte[] recipientStrongPw = chsDatabase.getStrongPassword(recipient);
    if (recipientStrongPw == null) {
        throw new IllegalArgumentException("Invalid recipient (strong password not found)");
    }
    int[] recipientDecryptPw = StrongAuthUtils.toWords(recipientStrongPw);
    // decode the credentials with the recipient's strong password
    StrongCredentials creds = StrongCredentials.make();
    decryptFrom(recipientDecryptPw, credentials.value, creds);
    // decrypt the verifier
    if (decodedConversationKey == null || decodedConversationKey.length < 4) {
        decodedConversationKey = new int[4];
    }
    decodedConversationKey[0] = creds.conversationKey.get(0).get();
    decodedConversationKey[1] = creds.conversationKey.get(1).get();
    decodedConversationKey[2] = creds.conversationKey.get(2).get();
    decodedConversationKey[3] = creds.conversationKey.get(3).get();
    StrongVerifier verfr = StrongVerifier.make();
    decryptFrom(decodedConversationKey, verifier, verfr);
    // left justified machine-id => upper 32 bits
    long rcptTimestampMachineId32Bits = (recipientMachineId >> 16) & 0xFFFFFFFFL;
    // left justified machine-id => lower 32 bits
    long rcptTicksMachineId32Bits = (recipientMachineId & 0x0000FFFFL) << 16;
    long verifierTicks = verfr.ticks.get() ^ rcptTicksMachineId32Bits;
    long verifierTimestamp = verfr.timeStamp.get() ^ rcptTimestampMachineId32Bits;
    if (decodedVerifier != null) {
        decodedVerifier.ticks.set(verifierTicks);
        decodedVerifier.timeStamp.set(verifierTimestamp);
    }
    // (temp) log the relevant data
    Time now = Time.make().now();
    System.out.printf("creds.initiator: %s:%s:%s\n", creds.initiator.object.get(), creds.initiator.domain.get(), creds.initiator.organization.get());
    System.out.printf("creds.expiration: %d (now: %d)\n", creds.expirationTime.get(), now.get());
    System.out.printf("verifier.timeStamp: 0x%08X = %d -> xor-ed(machineId): 0x%08X = %s (now: 0x%08X =  %d)\n", verfr.timeStamp.get(), verfr.timeStamp.get(), verifierTimestamp, verifierTimestamp, now.get(), now.get());
    System.out.printf("verifier.ticks: 0x%08X = %d -> xor-ed(machineId): 0x%08X = %d\n", verfr.ticks.get(), verfr.ticks.get(), verifierTicks, verifierTicks);
    // check the credentials / verifier
    if (!chsDatabase.isValidName(creds.initiator)) {
        System.out.println("** checkStrongCredentials() => ERR: creds.initiator is not a valid name");
        return null;
    }
    boolean skipTimestampChecks = MachineIds.getCfgBoolean(credentials.remoteHostId.get(), MachineIds.CFG_AUTH_SKIP_TIMESTAMP_CHECKS, false);
    if (!skipTimestampChecks) {
        if (now.get() > creds.expirationTime.get()) {
            System.out.println("** checkStrongCredentials() => ERR: now > creds.expirationTime");
            return null;
        }
        if (now.get() < verifierTimestamp) {
            System.out.println("** checkStrongCredentials() => ERR: now < verifierTimestamp");
            return null;
        }
        if (now.get() > (verifierTimestamp + 60)) {
            System.out.println("** checkStrongCredentials() => ERR: now > verifierTimestamp+60secs");
            return null;
        }
    } else {
        System.out.println("** checkStrongCredentials() => timestamp checks skipped (creds.expirationTime, verifier.timestamp)");
    }
    System.out.println("** checkStrongCredentials() => strong credentials OK");
    return new ThreePartName().from(creds.initiator);
}
Also used : Time(dev.hawala.xns.level4.common.Time2.Time)

Example 5 with ChsDatabase

use of dev.hawala.xns.level4.common.ChsDatabase in project dodo by devhawala.

the class DodoServer method main.

public static void main(String[] args) throws XnsException {
    String machinesFile = null;
    String baseCfgFile = null;
    String cfgFile = null;
    boolean dumpChs = false;
    // get commandline args
    for (String arg : args) {
        if (arg.toLowerCase().startsWith("-machinecfg:")) {
            String[] parts = arg.split(":");
            machinesFile = parts[1];
        } else if (arg.toLowerCase().startsWith("-basecfg:")) {
            String[] parts = arg.split(":");
            baseCfgFile = parts[1];
        } else if ("-dumpchs".equalsIgnoreCase(arg)) {
            dumpChs = true;
        } else if (cfgFile == null) {
            cfgFile = arg;
        } else {
            System.out.printf("Warning: ignoring unknown argument: %s\n", arg);
        }
    }
    // load machines configuration
    if (!MachineIds.loadDefinitions(machinesFile)) {
        System.out.println("!! failed to load machines configuration");
    }
    // load configuration(s)
    if (baseCfgFile == null) {
        File f = new File(DEFAULT_BASECONFIG_FILE);
        if (f.exists() && f.canRead()) {
            baseCfgFile = DEFAULT_BASECONFIG_FILE;
            System.out.printf("Found and using default commons configuration: %s\n", baseCfgFile);
        }
    }
    if (cfgFile == null && (new File(DEFAULT_CONFIG_FILE)).canRead()) {
        cfgFile = DEFAULT_CONFIG_FILE;
    }
    if (baseCfgFile != null) {
        initializeConfiguration(baseCfgFile);
    }
    if (cfgFile != null && !initializeConfiguration(cfgFile)) {
        return;
    }
    // put parts of the configuration data as defaults for client machines
    MachineIds.setDefault(MachineIds.CFG_AUTH_SKIP_TIMESTAMP_CHECKS, authSkipTimestampChecks);
    MachineIds.setDefault(MachineIds.CFG_BOOTSVC_SIMPLEDATA_SEND_INTERVAL, bootServiceSimpleDataSendInterval);
    MachineIds.setDefault(MachineIds.CFG_BOOTSVC_SPPDATA_SEND_INTERVAL, bootServiceSppDataSendInterval);
    MachineIds.setDefault(MachineIds.CFG_SPP_HANDSHAKE_SENDACK_COUNTDOWN, sppHandshakeSendackCountdown);
    MachineIds.setDefault(MachineIds.CFG_SPP_RESEND_DELAY, sppResendDelay);
    MachineIds.setDefault(MachineIds.CFG_SPP_HANDSHAKE_RESEND_COUNTDOWN, sppHandshakeResendCountdown);
    MachineIds.setDefault(MachineIds.CFG_SPP_HANDSHAKE_MAX_RESENDS, sppHandshakeMaxResends);
    MachineIds.setDefault(MachineIds.CFG_SPP_RESEND_PACKET_COUNT, sppResendPacketCount);
    MachineIds.setDefault(MachineIds.CFG_SPP_SENDING_TIME_GAP, sppSendingTimeGap);
    // this parameter is global to all SPP connections (cannot be specified at client machine level)
    SppConnection.setHandshakeCheckInterval(sppHandshakeCheckInterval);
    // open CHS database if there are services requiring it
    ChsDatabase chsDatabase = null;
    if (startChsAndAuth || !fileServiceSpecs.isEmpty()) {
        // create the clearinghouse database
        chsDatabase = new ChsDatabase(networkNo, organizationName, domainName, chsDatabaseRoot, allowBlanksInObjectNames);
        if (dumpChs) {
            System.out.println("\n==\n== machine-id pre-definitions:\n==\n");
            MachineIds.dump();
            System.out.println("\n==\n== clearinghouse database dump: \n==\n");
            chsDatabase.dump();
            System.out.println("\n==\n== end of machine-id and clearinghouse database dumps\n==\n");
        }
    }
    // check if we have undefined machine names, aborting startup if any
    List<String> undefinedMachineNames = MachineIds.getUndefinedMachineNames();
    if (!undefinedMachineNames.isEmpty()) {
        System.out.println("The following machine names or IDs are undefined or invalid:");
        for (String name : undefinedMachineNames) {
            System.out.printf(" -> name: %s\n", name);
        }
        System.out.printf("Aborting Dodo startup ...\n... please correct the configuration or define the above names in the machine ids file (%s)\n", machinesFile);
        System.exit(2);
    }
    // configure and start the network engine
    LocalSite.configureHub(netHubHost, netHubPort);
    LocalSite.configureLocal(networkNo, machineId, "DodoServer", doChecksums, doDarkstarWorkaround);
    localSite = LocalSite.getInstance();
    // set time base for all time dependent items
    Time2.setTimeWarp(daysBackInTime);
    // boot service
    if (startBootService) {
        BootResponder bootService = new BootResponder(bootServiceBasedir, bootServiceVerbose);
        localSite.clientBindToSocket(IDP.KnownSocket.BOOT.getSocket(), bootService);
    }
    // echo service
    if (startEchoService) {
        localSite.clientBindToSocket(IDP.KnownSocket.ECHO.getSocket(), new EchoResponder());
    }
    // time service
    if (startTimeService) {
        localSite.pexListen(IDP.KnownSocket.TIME.getSocket(), new TimeServiceResponder(localTimeOffsetMinutes, timeServiceSendingTimeGap));
    }
    // routing protocol responder
    RipResponder ripResponder = null;
    if (startRipService) {
        ripResponder = new RipResponder();
        localSite.clientBindToSocket(IDP.KnownSocket.ROUTING.getSocket(), ripResponder);
    }
    // clearinghouse and authentication services
    if (startChsAndAuth) {
        // broadcast for clearinghouse service
        // one common implementation for versions 2 and 3, as both versions have the same RetrieveAddresses method
        Clearinghouse3Impl.init(localSite.getNetworkId(), localSite.getMachineId(), chsDatabase);
        localSite.pexListen(IDP.KnownSocket.CLEARINGHOUSE.getSocket(), new BfsClearinghouseResponder(ripResponder), null);
        // broadcast for authentication service
        // one common implementation for versions 1, 2 and 3, as all versions are assumed to have
        // the same (undocumented) RetrieveAddresses method
        Authentication2Impl.init(localSite.getNetworkId(), localSite.getMachineId(), chsDatabase);
        localSite.pexListen(IDP.KnownSocket.AUTH.getSocket(), new BfsAuthenticationResponder());
        // register clearinghouse and authentication courier programs in registry
        Clearinghouse3Impl.register();
        Authentication2Impl.register();
        // start the mailService always co-located with the clearinghouse
        if (mailServiceVolumePath != null) {
            MailingOldImpl.init(localSite.getNetworkId(), localSite.getMachineId(), chsDatabase, mailServiceVolumePath);
            MailingOldImpl.register();
            MailingNewImpl.init(localSite.getNetworkId(), localSite.getMachineId(), chsDatabase, MailingOldImpl.getMailService());
            MailingNewImpl.register();
            localSite.pexListen(0x001A, new MailingExpeditedCourierResponder());
        }
    }
    // print service
    if (printServiceName != null && printServiceOutputDirectory != null) {
        try {
            Printing3Impl.init(printServiceName, printServiceOutputDirectory, printServiceDisassembleIp, printServicePaperSizes, printServiceIp2PsProcFilename, printServicePsPostprocessor);
            Printing3Impl.register();
        } catch (Exception e) {
            System.out.printf("Error starting printservice '%s': %s\n", printServiceName, e.getMessage());
        }
    }
    // file service(s)
    if (fileServiceSpecs.size() > 0) {
        // initialize
        FilingImpl.init(localSite.getNetworkId(), localSite.getMachineId(), chsDatabase);
        // open volume(s)
        int openVolumes = 0;
        for (Entry<String, String> spec : fileServiceSpecs.entrySet()) {
            ThreePartName serviceName = ThreePartName.make().from(spec.getKey());
            String volumeBasedirName = spec.getValue();
            if (FilingImpl.addVolume(serviceName, volumeBasedirName)) {
                openVolumes++;
            }
        }
        // register Courier implementation if volume(s) were successfully opened
        if (openVolumes > 0) {
            FilingImpl.register();
        } else {
            System.out.printf("No volumes opened successfully, not registering Filing to Courier");
        }
    }
    // run courier server with dispatcher
    CourierServer courierServer = new CourierServer(localSite);
    // silence logging a bit
    Log.L0.doLog(false);
    Log.L1.doLog(false);
    Log.L2.doLog(false);
    Log.L3.doLog(false);
    Log.L4.doLog(false);
/*
		 * let the server machine run...
		 */
}
Also used : BootResponder(dev.hawala.xns.level4.boot.BootResponder) CourierServer(dev.hawala.xns.level3.courier.CourierServer) MailingExpeditedCourierResponder(dev.hawala.xns.level4.mailing.MailingExpeditedCourierResponder) BfsClearinghouseResponder(dev.hawala.xns.level4.chs.BfsClearinghouseResponder) ThreePartName(dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName) RipResponder(dev.hawala.xns.level4.rip.RipResponder) ChsDatabase(dev.hawala.xns.level4.common.ChsDatabase) EchoResponder(dev.hawala.xns.level4.echo.EchoResponder) File(java.io.File) TimeServiceResponder(dev.hawala.xns.level4.time.TimeServiceResponder) BfsAuthenticationResponder(dev.hawala.xns.level4.auth.BfsAuthenticationResponder)

Aggregations

EndOfMessageException (dev.hawala.xns.level3.courier.iWireStream.EndOfMessageException)5 ChsDatabase (dev.hawala.xns.level4.common.ChsDatabase)5 ThreePartName (dev.hawala.xns.level4.common.AuthChsCommon.ThreePartName)4 NoMoreWriteSpaceException (dev.hawala.xns.level3.courier.iWireStream.NoMoreWriteSpaceException)3 BfsClearinghouseResponder (dev.hawala.xns.level4.chs.BfsClearinghouseResponder)2 Name (dev.hawala.xns.level4.common.AuthChsCommon.Name)2 NetworkAddress (dev.hawala.xns.level4.common.AuthChsCommon.NetworkAddress)2 Volume (dev.hawala.xns.level4.filing.fs.Volume)2 NameList (dev.hawala.xns.level4.mailing.MailingCommon.NameList)2 File (java.io.File)2 IOException (java.io.IOException)2 Payload (dev.hawala.xns.level0.Payload)1 Error (dev.hawala.xns.level2.Error)1 PEX (dev.hawala.xns.level2.PEX)1 CourierServer (dev.hawala.xns.level3.courier.CourierServer)1 STRING (dev.hawala.xns.level3.courier.STRING)1 CourierException (dev.hawala.xns.level3.courier.exception.CourierException)1 BfsAuthenticationResponder (dev.hawala.xns.level4.auth.BfsAuthenticationResponder)1 BootResponder (dev.hawala.xns.level4.boot.BootResponder)1 AuthenticationErrorRecord (dev.hawala.xns.level4.chs.Clearinghouse3.AuthenticationErrorRecord)1