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; }
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); }
/* 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); }
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) {
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; }
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; }
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; }
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 }