示例#1
0
文件: lptree.c 项目: JonasKunze/lpeg
/*
** choice operator; optimizations:
** charset / charset => charset
** true / x => true, x / false => x, false / x => x
** (x / true is not equivalent to true)
*/
static int lp_choice (lua_State *L) {
  Charset st1, st2;
  TTree *t1 = getpatt(L, 1, NULL);
  TTree *t2 = getpatt(L, 2, NULL);
  if (tocharset(t1, &st1) && tocharset(t2, &st2)) {
    TTree *t = newcharset(L);
    loopset(i, treebuffer(t)[i] = st1.cs[i] | st2.cs[i]);
  }
  else if (nofail(t1) || t2->tag == TFalse)
    lua_pushvalue(L, 1);  /* true / x => true, x / false => x */
  else if (t1->tag == TFalse)
    lua_pushvalue(L, 2);  /* false / x => x */
  else
    newroot2sib(L, TChoice);
  return 1;
}
示例#2
0
krb5_error_code KRB5_CALLCONV
krb5_verify_init_creds(krb5_context context,
                       krb5_creds *creds,
                       krb5_principal server_arg,
                       krb5_keytab keytab_arg,
                       krb5_ccache *ccache_arg,
                       krb5_verify_init_creds_opt *options)
{
    krb5_error_code ret;
    krb5_principal server;
    krb5_keytab keytab;
    krb5_ccache ccache;
    krb5_keytab_entry kte;
    krb5_creds in_creds, *out_creds;
    krb5_auth_context authcon;
    krb5_data ap_req;

    /* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN */

    server = NULL;
    keytab = NULL;
    ccache = NULL;
    out_creds = NULL;
    authcon = NULL;
    ap_req.data = NULL;

    if (keytab_arg) {
        keytab = keytab_arg;
    } else {
        if ((ret = krb5_kt_default(context, &keytab)))
            goto cleanup;
    }

    if (server_arg) {
        ret = krb5_copy_principal(context, server_arg, &server);
        if (ret)
            goto cleanup;
    } else {
        /* Use a principal name from the keytab. */
        ret = k5_kt_get_principal(context, keytab, &server);
        if (ret) {
            /* There's no keytab, or it's empty, or we can't read it.
             * Allow this unless configuration demands verification. */
            if (!nofail(context, options, creds))
                ret = 0;
            goto cleanup;
        }
    }

    /* first, check if the server is in the keytab.  If not, there's
       no reason to continue.  rd_req does all this, but there's
       no way to know that a given error is caused by a missing
       keytab or key, and not by some other problem. */

    if (krb5_is_referral_realm(&server->realm)) {
        krb5_free_data_contents(context, &server->realm);
        ret = krb5_get_default_realm(context, &server->realm.data);
        if (ret) goto cleanup;
        server->realm.length = strlen(server->realm.data);
    }

    if ((ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte))) {
        /* this means there is no keying material.  This is ok, as long as
           it is not prohibited by the configuration */
        if (!nofail(context, options, creds))
            ret = 0;
        goto cleanup;
    }

    krb5_kt_free_entry(context, &kte);

    /* If the creds are for the server principal, we're set, just do a mk_req.
     * Otherwise, do a get_credentials first.
     */

    if (krb5_principal_compare(context, server, creds->server)) {
        /* make an ap_req */
        if ((ret = krb5_mk_req_extended(context, &authcon, 0, NULL, creds,
                                        &ap_req)))
            goto cleanup;
    } else {
        /* this is unclean, but it's the easiest way without ripping the
           library into very small pieces.  store the client's initial cred
           in a memory ccache, then call the library.  Later, we'll copy
           everything except the initial cred into the ccache we return to
           the user.  A clean implementation would involve library
           internals with a coherent idea of "in" and "out". */

        /* insert the initial cred into the ccache */

        if ((ret = krb5_cc_new_unique(context, "MEMORY", NULL, &ccache))) {
            ccache = NULL;
            goto cleanup;
        }

        if ((ret = krb5_cc_initialize(context, ccache, creds->client)))
            goto cleanup;

        if ((ret = krb5_cc_store_cred(context, ccache, creds)))
            goto cleanup;

        /* set up for get_creds */
        memset(&in_creds, 0, sizeof(in_creds));
        in_creds.client = creds->client;
        in_creds.server = server;
        if ((ret = krb5_timeofday(context, &in_creds.times.endtime)))
            goto cleanup;
        in_creds.times.endtime += 5*60;

        if ((ret = krb5_get_credentials(context, 0, ccache, &in_creds,
                                        &out_creds)))
            goto cleanup;

        /* make an ap_req */
        if ((ret = krb5_mk_req_extended(context, &authcon, 0, NULL, out_creds,
                                        &ap_req)))
            goto cleanup;
    }

    /* wipe the auth context for mk_req */
    if (authcon) {
        krb5_auth_con_free(context, authcon);
        authcon = NULL;
    }

    /* verify the ap_req */

    if ((ret = krb5_rd_req(context, &authcon, &ap_req, server, keytab,
                           NULL, NULL)))
        goto cleanup;

    /* if we get this far, then the verification succeeded.  We can
       still fail if the library stuff here fails, but that's it */

    if (ccache_arg && ccache) {
        if (*ccache_arg == NULL) {
            krb5_ccache retcc;

            retcc = NULL;

            if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) ||
                (ret = krb5_cc_initialize(context, retcc, creds->client)) ||
                (ret = copy_creds_except(context, ccache, retcc,
                                         creds->server))) {
                if (retcc)
                    krb5_cc_destroy(context, retcc);
            } else {
                *ccache_arg = retcc;
            }
        } else {
            ret = copy_creds_except(context, ccache, *ccache_arg,
                                    server);
        }
    }

    /* if any of the above paths returned an errors, then ret is set accordingly.
     * Either that, or it's zero, which is fine, too
     */

cleanup:
    if ( server)
        krb5_free_principal(context, server);
    if (!keytab_arg && keytab)
        krb5_kt_close(context, keytab);
    if (ccache)
        krb5_cc_destroy(context, ccache);
    if (out_creds)
        krb5_free_creds(context, out_creds);
    if (authcon)
        krb5_auth_con_free(context, authcon);
    if (ap_req.data)
        free(ap_req.data);

    return(ret);
}
示例#3
0
krb5_error_code KRB5_CALLCONV
krb5_verify_init_creds(krb5_context context, krb5_creds *creds,
                       krb5_principal server, krb5_keytab keytab,
                       krb5_ccache *ccache,
                       krb5_verify_init_creds_opt *options)
{
    krb5_error_code ret;
    krb5_principal *host_princs = NULL;
    krb5_keytab defkeytab = NULL;
    krb5_keytab_entry kte;
    krb5_boolean have_keys = FALSE;
    size_t i;

    if (keytab == NULL) {
        ret = krb5_kt_default(context, &defkeytab);
        if (ret)
            goto cleanup;
        keytab = defkeytab;
    }

    if (server != NULL) {
        /* Check if server exists in keytab first. */
        ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte);
        if (ret)
            goto cleanup;
        krb5_kt_free_entry(context, &kte);
        have_keys = TRUE;
        ret = get_vfy_cred(context, creds, server, keytab, ccache);
    } else {
        /* Try using the host service principals from the keytab. */
        if (keytab->ops->start_seq_get == NULL) {
            ret = EINVAL;
            goto cleanup;
        }
        ret = get_host_princs_from_keytab(context, keytab, &host_princs);
        if (ret)
            goto cleanup;
        if (host_princs == NULL) {
            ret = KRB5_KT_NOTFOUND;
            goto cleanup;
        }
        have_keys = TRUE;

        /* Try all host principals until one succeeds or they all fail. */
        for (i = 0; host_princs[i] != NULL; i++) {
            ret = get_vfy_cred(context, creds, host_princs[i], keytab, ccache);
            if (ret == 0)
                break;
        }
    }

cleanup:
    /* If we have no key to verify with, pretend to succeed unless
     * configuration directs otherwise. */
    if (!have_keys && !nofail(context, options, creds))
        ret = 0;

    if (defkeytab != NULL)
        krb5_kt_close(context, defkeytab);
    krb5_free_principal(context, server);
    free_princ_list(context, host_princs);

    return ret;
}