예제 #1
0
krb5_error_code
krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name)
{
    const char *at_rlm_name, *p;
    struct k5buf buf;

    at_rlm_name = strrchr(i_princ_name, '@');
    if (!at_rlm_name) {
        *o_princ_name = strdup(i_princ_name);
        if (!o_princ_name)
            return ENOMEM;
    } else {
        krb5int_buf_init_dynamic(&buf);
        for (p = i_princ_name; p < at_rlm_name; p++) {
            if (*p == '@')
                krb5int_buf_add(&buf, "\\");
            krb5int_buf_add_len(&buf, p, 1);
        }
        krb5int_buf_add(&buf, at_rlm_name);
        *o_princ_name = krb5int_buf_data(&buf);
        if (!*o_princ_name)
            return ENOMEM;
    }
    return 0;
}
예제 #2
0
static 
char *handle_sam_labels(krb5_sam_challenge *sc)
{
    char *label = sc->sam_challenge_label.data;
    unsigned int label_len = sc->sam_challenge_label.length;
    char *prompt = sc->sam_response_prompt.data;
    unsigned int prompt_len = sc->sam_response_prompt.length;
    char *challenge = sc->sam_challenge.data;
    unsigned int challenge_len = sc->sam_challenge.length;
    struct k5buf buf;

    if (sc->sam_cksum.length == 0) {
      /* or invalid -- but lets just handle presence now XXX */
      switch (sc->sam_type) {
      case PA_SAM_TYPE_ENIGMA:	/* Enigma Logic */
	label = "Challenge for Enigma Logic mechanism";
	break;
      case PA_SAM_TYPE_DIGI_PATH: /*  Digital Pathways */
      case PA_SAM_TYPE_DIGI_PATH_HEX: /*  Digital Pathways */
	label = "Challenge for Digital Pathways mechanism";
	break;
      case PA_SAM_TYPE_ACTIVCARD_DEC: /*  Digital Pathways */
      case PA_SAM_TYPE_ACTIVCARD_HEX: /*  Digital Pathways */
	label = "Challenge for Activcard mechanism";
	break;
      case PA_SAM_TYPE_SKEY_K0:	/*  S/key where  KDC has key 0 */
	label = "Challenge for Enhanced S/Key mechanism";
	break;
      case PA_SAM_TYPE_SKEY:	/*  Traditional S/Key */
	label = "Challenge for Traditional S/Key mechanism";
	break;
      case PA_SAM_TYPE_SECURID:	/*  Security Dynamics */
	label = "Challenge for Security Dynamics mechanism";
	break;
      case PA_SAM_TYPE_SECURID_PREDICT:	/* predictive Security Dynamics */
	label = "Challenge for Security Dynamics mechanism";
	break;
      }
      prompt = "Passcode";
      label_len = strlen(label);
      prompt_len = strlen(prompt);
    }

    /* example:
       Challenge for Digital Pathways mechanism: [134591]
       Passcode: 
     */
    krb5int_buf_init_dynamic(&buf);
    if (challenge_len) {
	krb5int_buf_add_len(&buf, label, label_len);
	krb5int_buf_add(&buf, ": [");
	krb5int_buf_add_len(&buf, challenge, challenge_len);
	krb5int_buf_add(&buf, "]\n");
    }
    krb5int_buf_add_len(&buf, prompt, prompt_len);
    krb5int_buf_add(&buf, ": ");
    return krb5int_buf_data(&buf);
}
예제 #3
0
파일: ldap_realm.c 프로젝트: mihais/krb5
/* Return a copy of in, quoting all characters which are special in an LDAP
 * filter (RFC 4515) or DN string (RFC 4514).  Return NULL on failure. */
char *
ldap_filter_correct (char *in)
{
    size_t count;
    const char special[] = "*()\\ #\"+,;<>";
    struct k5buf buf;

    krb5int_buf_init_dynamic(&buf);
    while (TRUE) {
        count = strcspn(in, special);
        krb5int_buf_add_len(&buf, in, count);
        in += count;
        if (*in == '\0')
            break;
        krb5int_buf_add_fmt(&buf, "\\%2x", (unsigned char)*in++);
    }
    return krb5int_buf_data(&buf);
}
예제 #4
0
파일: trace.c 프로젝트: detrout/debian-krb5
static char *
trace_format(krb5_context context, const char *fmt, va_list ap)
{
    struct k5buf buf;
    krb5_error_code kerr;
    size_t len, i;
    int err;
    struct conn_state *cs;
    const krb5_data *d;
    krb5_data data;
    char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV], tmpbuf[200], *str;
    const char *p;
    krb5_const_principal princ;
    const krb5_keyblock *keyblock;
    krb5_key key;
    const krb5_checksum *cksum;
    krb5_pa_data **padata;
    krb5_ccache ccache;
    krb5_keytab keytab;
    krb5_creds *creds;
    krb5_enctype *etypes, etype;

    krb5int_buf_init_dynamic(&buf);
    while (TRUE) {
        /* Advance to the next word in braces. */
        len = strcspn(fmt, "{");
        krb5int_buf_add_len(&buf, fmt, len);
        if (fmt[len] == '\0')
            break;
        fmt += len + 1;
        len = strcspn(fmt, "}");
        if (fmt[len] == '\0' || len > sizeof(tmpbuf) - 1)
            break;
        memcpy(tmpbuf, fmt, len);
        tmpbuf[len] = '\0';
        fmt += len + 1;

        /* Process the format word. */
        if (strcmp(tmpbuf, "int") == 0) {
            krb5int_buf_add_fmt(&buf, "%d", va_arg(ap, int));
        } else if (strcmp(tmpbuf, "long") == 0) {
예제 #5
0
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
                                        krb5_get_init_creds_opt *opt,
                                        krb5_ccache ccache)
{
    krb5_error_code retval = 0;
    struct k5buf buf;
    char *cc_name;

    krb5int_buf_init_dynamic(&buf);
    krb5int_buf_add(&buf, krb5_cc_get_type(context, ccache));
    krb5int_buf_add(&buf, ":");
    krb5int_buf_add(&buf, krb5_cc_get_name(context, ccache));
    cc_name = krb5int_buf_data(&buf);
    if (cc_name)
        retval = krb5_get_init_creds_opt_set_fast_ccache_name(context, opt,
                                                              cc_name);
    else
        retval = ENOMEM;
    krb5int_free_buf(&buf);
    return retval;
}
예제 #6
0
파일: chpw.c 프로젝트: detrout/debian-krb5
static krb5_error_code
decode_ad_policy_info(const krb5_data *data, char **msg_out)
{
    struct ad_policy_info policy;
    uint64_t password_days;
    const char *p;
    char *msg;
    struct k5buf buf;

    *msg_out = NULL;
    if (data->length != AD_POLICY_INFO_LENGTH)
        return 0;

    p = data->data;
    policy.zero_bytes = load_16_be(p);
    p += 2;

    /* first two bytes are zeros */
    if (policy.zero_bytes != 0)
        return 0;

    /* Read in the rest of structure */
    policy.min_length_password = load_32_be(p);
    p += 4;
    policy.password_history = load_32_be(p);
    p += 4;
    policy.password_properties = load_32_be(p);
    p += 4;
    policy.expire = load_64_be(p);
    p += 8;
    policy.min_passwordage = load_64_be(p);
    p += 8;

    /* Check that we processed exactly the expected number of bytes. */
    assert(p == data->data + AD_POLICY_INFO_LENGTH);

    krb5int_buf_init_dynamic(&buf);

    /*
     * Update src/tests/misc/test_chpw_message.c if changing these strings!
     */

    if (policy.password_properties & AD_POLICY_COMPLEX) {
        krb5int_buf_add(&buf,
                        _("The password must include numbers or symbols.  "
                          "Don't include any part of your name in the "
                          "password."));
    }
    if (policy.min_length_password > 0) {
        add_spaces(&buf);
        krb5int_buf_add_fmt(&buf,
                            ngettext("The password must contain at least %d "
                                     "character.",
                                     "The password must contain at least %d "
                                     "characters.",
                                     policy.min_length_password),
                            policy.min_length_password);
    }
    if (policy.password_history) {
        add_spaces(&buf);
        krb5int_buf_add_fmt(&buf,
                            ngettext("The password must be different from the "
                                     "previous password.",
                                     "The password must be different from the "
                                     "previous %d passwords.",
                                     policy.password_history),
                            policy.password_history);
    }
    if (policy.min_passwordage) {
        password_days = policy.min_passwordage / AD_POLICY_TIME_TO_DAYS;
        if (password_days == 0)
            password_days = 1;
        add_spaces(&buf);
        krb5int_buf_add_fmt(&buf,
                            ngettext("The password can only be changed once a "
                                     "day.",
                                     "The password can only be changed every "
                                     "%d days.", (int)password_days),
                            (int)password_days);
    }

    msg = krb5int_buf_data(&buf);
    if (msg == NULL)
        return ENOMEM;

    if (*msg != '\0')
        *msg_out = msg;
    else
        free(msg);
    return 0;
}
예제 #7
0
static krb5_error_code
krb5_rc_io_store(krb5_context context, struct dfl_data *t,
                 krb5_donot_replay *rep)
{
    size_t clientlen, serverlen;
    unsigned int len;
    krb5_error_code ret;
    struct k5buf buf, extbuf;
    char *ptr, *extstr;

    clientlen = strlen(rep->client);
    serverlen = strlen(rep->server);

    if (rep->msghash) {
        /*
         * Write a hash extension record, to be followed by a record
         * in regular format (without the message hash) for the
         * benefit of old implementations.
         */

        /* Format the extension value so we know its length. */
        krb5int_buf_init_dynamic(&extbuf);
        krb5int_buf_add_fmt(&extbuf, "HASH:%s %lu:%s %lu:%s", rep->msghash,
                            (unsigned long) clientlen, rep->client,
                            (unsigned long) serverlen, rep->server);
        extstr = krb5int_buf_data(&extbuf);
        if (!extstr)
            return KRB5_RC_MALLOC;

        /*
         * Put the extension value into the server field of a
         * regular-format record, with an empty client field.
         */
        krb5int_buf_init_dynamic(&buf);
        len = 1;
        krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
        krb5int_buf_add_len(&buf, "", 1);
        len = strlen(extstr) + 1;
        krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
        krb5int_buf_add_len(&buf, extstr, len);
        krb5int_buf_add_len(&buf, (char *) &rep->cusec, sizeof(rep->cusec));
        krb5int_buf_add_len(&buf, (char *) &rep->ctime, sizeof(rep->ctime));
        free(extstr);
    } else  /* No extension record needed. */
        krb5int_buf_init_dynamic(&buf);

    len = clientlen + 1;
    krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
    krb5int_buf_add_len(&buf, rep->client, len);
    len = serverlen + 1;
    krb5int_buf_add_len(&buf, (char *) &len, sizeof(len));
    krb5int_buf_add_len(&buf, rep->server, len);
    krb5int_buf_add_len(&buf, (char *) &rep->cusec, sizeof(rep->cusec));
    krb5int_buf_add_len(&buf, (char *) &rep->ctime, sizeof(rep->ctime));

    ptr = krb5int_buf_data(&buf);
    if (ptr == NULL)
        return KRB5_RC_MALLOC;

    ret = krb5_rc_io_write(context, &t->d, ptr, krb5int_buf_len(&buf));
    krb5int_free_buf(&buf);
    return ret;
}
예제 #8
0
void
krb5int_debug_fprint (const char *fmt, ...)
{
#ifdef DEBUG
    va_list args;

    /* Temporaries for variable arguments, etc.  */
    krb5_error_code kerr;
    int err;
    fd_set *rfds, *wfds, *xfds;
    int i;
    int maxfd;
    struct timeval *tv;
    struct addrinfo *ai;
    const krb5_data *d;
    char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV];
    const char *p;
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
    char tmpbuf[max(NI_MAXHOST + NI_MAXSERV + 30, 200)];
    struct k5buf buf;

    if (!krb5int_debug_sendto_kdc)
        return;

    va_start(args, fmt);

#define putf(FMT,X)     (snprintf(tmpbuf,sizeof(tmpbuf),FMT,X),putstr(tmpbuf))

    for (; *fmt; fmt++) {
        if (*fmt != '%') {
            const char *fmt2;
            size_t len;
            for (fmt2 = fmt+1; *fmt2; fmt2++)
                if (*fmt2 == '%')
                    break;
            len = fmt2 - fmt;
            put(fmt, len);
            fmt += len - 1;     /* then fmt++ in loop header */
            continue;
        }
        /* After this, always processing a '%' sequence.  */
        fmt++;
        switch (*fmt) {
        case 0:
        default:
            abort();
        case 'E':
            /* %E => krb5_error_code */
            kerr = va_arg(args, krb5_error_code);
            snprintf(tmpbuf, sizeof(tmpbuf), "%lu/", (unsigned long) kerr);
            putstr(tmpbuf);
            p = error_message(kerr);
            putstr(p);
            break;
        case 'm':
            /* %m => errno value (int) */
            /* Like syslog's %m except the errno value is passed in
               rather than the current value.  */
            err = va_arg(args, int);
            putf("%d/", err);
            p = NULL;
#ifdef HAVE_STRERROR_R
            if (strerror_r(err, tmpbuf, sizeof(tmpbuf)) == 0)
                p = tmpbuf;
#endif
            if (p == NULL)
                p = strerror(err);
            putstr(p);
            break;
        case 'F':
            /* %F => fd_set *, fd_set *, fd_set *, int */
            rfds = va_arg(args, fd_set *);
            wfds = va_arg(args, fd_set *);
            xfds = va_arg(args, fd_set *);
            maxfd = va_arg(args, int);

            for (i = 0; i < maxfd; i++) {
                int r = FD_ISSET(i, rfds);
                int w = wfds && FD_ISSET(i, wfds);
                int x = xfds && FD_ISSET(i, xfds);
                if (r || w || x) {
                    putf(" %d", i);
                    if (r)
                        putstr("r");
                    if (w)
                        putstr("w");
                    if (x)
                        putstr("x");
                }
            }
            putstr(" ");
            break;
        case 's':
            /* %s => char * */
            p = va_arg(args, const char *);
            putstr(p);
            break;
        case 't':
            /* %t => struct timeval * */
            tv = va_arg(args, struct timeval *);
            if (tv) {
                snprintf(tmpbuf, sizeof(tmpbuf), "%ld.%06ld",
                         (long) tv->tv_sec, (long) tv->tv_usec);
                putstr(tmpbuf);
            } else
                putstr("never");
            break;
        case 'd':
            /* %d => int */
            putf("%d", va_arg(args, int));
            break;
        case 'p':
            /* %p => pointer */
            putf("%p", va_arg(args, void*));
            break;
        case 'A':
            /* %A => addrinfo */
            ai = va_arg(args, struct addrinfo *);
            krb5int_buf_init_dynamic(&buf);
            if (ai->ai_socktype == SOCK_DGRAM)
                krb5int_buf_add(&buf, "dgram");
            else if (ai->ai_socktype == SOCK_STREAM)
                krb5int_buf_add(&buf, "stream");
            else
                krb5int_buf_add_fmt(&buf, "socktype%d", ai->ai_socktype);

            if (0 != getnameinfo (ai->ai_addr, ai->ai_addrlen,
                                  addrbuf, sizeof (addrbuf),
                                  portbuf, sizeof (portbuf),
                                  NI_NUMERICHOST | NI_NUMERICSERV)) {
                if (ai->ai_addr->sa_family == AF_UNSPEC)
                    krb5int_buf_add(&buf, " AF_UNSPEC");
                else
                    krb5int_buf_add_fmt(&buf, " af%d", ai->ai_addr->sa_family);
            } else
                krb5int_buf_add_fmt(&buf, " %s.%s", addrbuf, portbuf);
            if (krb5int_buf_data(&buf))
                putstr(krb5int_buf_data(&buf));
            krb5int_free_buf(&buf);
            break;
        case 'D':
            /* %D => krb5_data * */
            d = va_arg(args, krb5_data *);
            /* may not be nul-terminated */
            put(d->data, d->length);
            break;
        }
    }
    va_end(args);
#endif
}