示例#1
0
/**
 * tries connecting to the domain controllers in the "controllers" ring,
 * with failover if the adequate option is specified.
 */
const char *
obtain_challenge()
{
    int j = 0;
    const char *ch = NULL;
    for (j = 0; j < numcontrollers; j++) {
        debug("obtain_challenge: selecting %s\\%s (attempt #%d)\n",
              current_dc->domain, current_dc->controller, j + 1);
        if (current_dc->dead != 0) {
            if (time(NULL) - current_dc->dead >= DEAD_DC_RETRY_INTERVAL) {
                /* mark helper as retry-worthy if it's so. */
                debug("Reviving DC\n");
                current_dc->dead = 0;
            } else {		/* skip it */
                debug("Skipping it\n");
                continue;
            }
        }
        /* else branch. Here we KNOW that the DC is fine */
        debug("attempting challenge retrieval\n");
        ch = make_challenge(current_dc->domain, current_dc->controller);
        debug("make_challenge retuned %p\n", ch);
        if (ch) {
            debug("Got it\n");
            return ch;		/* All went OK, returning */
        }
        /* Huston, we've got a problem. Take this DC out of the loop */
        debug("Marking DC as DEAD\n");
        current_dc->dead = time(NULL);
        /* Try with the next */
        debug("moving on to next controller\n");
        current_dc = current_dc->next;
    }
    /* all DCs failed. */
    return NULL;
}
示例#2
0
/* Outputs the selected tokeninfo and possibly a value and pin.
 * Prompting may occur. */
static krb5_error_code
prompt_for_token(krb5_context context, krb5_prompter_fct prompter,
                 void *prompter_data, krb5_otp_tokeninfo **tis,
                 krb5_otp_tokeninfo **out_ti, krb5_data *out_value,
                 krb5_data *out_pin)
{
    krb5_otp_tokeninfo **filtered = NULL;
    krb5_otp_tokeninfo *ti = NULL;
    krb5_error_code retval;
    int i, challengers = 0;
    char *challenge = NULL;
    char otpvalue[1024];
    krb5_data value, pin;

    memset(otpvalue, 0, sizeof(otpvalue));

    if (tis == NULL || tis[0] == NULL || out_ti == NULL)
        return EINVAL;

    /* Count how many challenges we have. */
    for (i = 0; tis[i] != NULL; i++) {
        if (tis[i]->challenge.data != NULL)
            challengers++;
    }

    /* If we have only one tokeninfo as input, choose it. */
    if (i == 1)
        ti = tis[0];

    /* Setup our challenge, if present. */
    if (challengers > 0) {
        /* If we have multiple tokeninfos still, choose now. */
        if (ti == NULL) {
            retval = prompt_for_tokeninfo(context, prompter, prompter_data,
                                          tis, &ti);
            if (retval != 0)
                return retval;
        }

        /* Create the challenge prompt. */
        retval = make_challenge(ti, &challenge);
        if (retval != 0)
            return retval;
    }

    /* Prompt for token value. */
    retval = doprompt(context, prompter, prompter_data, challenge,
                      _("Enter OTP Token Value"), otpvalue, sizeof(otpvalue));
    free(challenge);
    if (retval != 0)
        return retval;

    if (ti == NULL) {
        /* Filter out tokeninfos that don't match our token value. */
        retval = filter_tokeninfos(context, otpvalue, tis, &filtered, &ti);
        if (retval != 0)
            return retval;

        /* If we still don't have a single tokeninfo, choose now. */
        if (filtered != NULL) {
            retval = prompt_for_tokeninfo(context, prompter, prompter_data,
                                          filtered, &ti);
            free(filtered);
            if (retval != 0)
                return retval;
        }
    }

    assert(ti != NULL);

    /* Set the value. */
    value = make_data(strdup(otpvalue), strlen(otpvalue));
    if (value.data == NULL)
        return ENOMEM;

    /* Collect the PIN, if necessary. */
    retval = collect_pin(context, prompter, prompter_data, ti, &pin);
    if (retval != 0) {
        krb5_free_data_contents(context, &value);
        return retval;
    }

    *out_value = value;
    *out_pin = pin;
    *out_ti = ti;
    return 0;
}