/* * Double any quote characters present in a quoted field. */ static char * qquote(struct flavor *fl, const char *s) { const char *sp; struct k5buf buf; k5_buf_init_dynamic(&buf); for (sp = s; *sp != '\0'; sp++) { k5_buf_add_len(&buf, sp, 1); if (*sp == fl->quotechar) k5_buf_add_len(&buf, sp, 1); } return buf.data; }
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 { k5_buf_init_dynamic(&buf); for (p = i_princ_name; p < at_rlm_name; p++) { if (*p == '@') k5_buf_add(&buf, "\\"); k5_buf_add_len(&buf, p, 1); } k5_buf_add(&buf, at_rlm_name); *o_princ_name = k5_buf_data(&buf); if (!*o_princ_name) return ENOMEM; } return 0; }
static void buf_add_printable_len(struct k5buf *buf, const char *p, size_t len) { char text[5]; size_t i; if (buf_is_printable(p, len)) { k5_buf_add_len(buf, p, len); } else { for (i = 0; i < len; i++) { if (buf_is_printable(p + i, 1)) { k5_buf_add_len(buf, p + i, 1); } else { snprintf(text, sizeof(text), "\\x%02x", (unsigned)(p[i] & 0xff)); k5_buf_add_len(buf, text, 4); } } } }
static krb5_error_code make_proxy_request(struct conn_state *state, const krb5_data *realm, const krb5_data *message, char **req_out, size_t *len_out) { krb5_kkdcp_message pm; krb5_data *encoded_pm = NULL; struct k5buf buf; const char *uri_path; krb5_error_code ret; *req_out = NULL; *len_out = 0; /* * Stuff the message length in at the front of the kerb_message field * before encoding. The proxied messages are actually the payload we'd * be sending and receiving if we were using plain TCP. */ memset(&pm, 0, sizeof(pm)); ret = alloc_data(&pm.kerb_message, message->length + 4); if (ret != 0) goto cleanup; store_32_be(message->length, pm.kerb_message.data); memcpy(pm.kerb_message.data + 4, message->data, message->length); pm.target_domain = *realm; ret = encode_krb5_kkdcp_message(&pm, &encoded_pm); if (ret != 0) goto cleanup; /* Build the request to transmit: the headers + the proxy message. */ k5_buf_init_dynamic(&buf); uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : ""; k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path); k5_buf_add(&buf, "Cache-Control: no-cache\r\n"); k5_buf_add(&buf, "Pragma: no-cache\r\n"); k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n"); k5_buf_add(&buf, "Content-type: application/kerberos\r\n"); k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length); k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length); if (k5_buf_status(&buf) != 0) { ret = ENOMEM; goto cleanup; } *req_out = buf.data; *len_out = buf.len; cleanup: krb5_free_data_contents(NULL, &pm.kerb_message); krb5_free_data(NULL, encoded_pm); return ret; }
/* Load four bytes from the cache file and return their value as a 32-bit * unsigned integer according to the file format. Also append them to buf. */ static krb5_error_code read32(krb5_context context, krb5_ccache id, struct k5buf *buf, uint32_t *out) { krb5_error_code ret; char bytes[4]; k5_cc_mutex_assert_locked(context, &((fcc_data *)id->data)->lock); ret = read_bytes(context, id, bytes, 4); if (ret) return ret; if (buf != NULL) k5_buf_add_len(buf, bytes, 4); *out = (version(id) < 3) ? load_32_n(bytes) : load_32_be(bytes); return 0; }
/* 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; k5_buf_init_dynamic(&buf); while (TRUE) { count = strcspn(in, special); k5_buf_add_len(&buf, in, count); in += count; if (*in == '\0') break; k5_buf_add_fmt(&buf, "\\%2x", (unsigned char)*in++); } return buf.data; }
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; k5_buf_init_dynamic(&buf); while (TRUE) { /* Advance to the next word in braces. */ len = strcspn(fmt, "{"); k5_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) { k5_buf_add_fmt(&buf, "%d", va_arg(ap, int)); } else if (strcmp(tmpbuf, "long") == 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 *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. */ k5_buf_init_dynamic(&extbuf); k5_buf_add_fmt(&extbuf, "HASH:%s %lu:%s %lu:%s", rep->msghash, (unsigned long)clientlen, rep->client, (unsigned long)serverlen, rep->server); if (k5_buf_status(&extbuf) != 0) return KRB5_RC_MALLOC; extstr = extbuf.data; /* * Put the extension value into the server field of a * regular-format record, with an empty client field. */ k5_buf_init_dynamic(&buf); len = 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, "", 1); len = strlen(extstr) + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, extstr, len); k5_buf_add_len(&buf, (char *)&rep->cusec, sizeof(rep->cusec)); k5_buf_add_len(&buf, (char *)&rep->ctime, sizeof(rep->ctime)); free(extstr); } else /* No extension record needed. */ k5_buf_init_dynamic(&buf); len = clientlen + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, rep->client, len); len = serverlen + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, rep->server, len); k5_buf_add_len(&buf, (char *)&rep->cusec, sizeof(rep->cusec)); k5_buf_add_len(&buf, (char *)&rep->ctime, sizeof(rep->ctime)); if (k5_buf_status(&buf) != 0) return KRB5_RC_MALLOC; ret = krb5_rc_io_write(context, &t->d, buf.data, buf.len); k5_buf_free(&buf); return ret; }