/* * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* $Id$ */ /* Data representation and related functions */ #include #include #include #include #include #include khm_int32 KHMAPI enctype_toString(const void * data, khm_size cbdata, wchar_t *destbuf, khm_size *pcbdestbuf, khm_int32 flags) { int resid = 0; int etype; wchar_t buf[256]; size_t cblength; if(cbdata != sizeof(khm_int32)) return KHM_ERROR_INVALID_PARAM; etype = *((khm_int32 *) data); switch(etype) { case ENCTYPE_NULL: resid = IDS_ETYPE_NULL; break; case ENCTYPE_DES_CBC_CRC: resid = IDS_ETYPE_DES_CBC_CRC; break; case ENCTYPE_DES_CBC_MD4: resid = IDS_ETYPE_DES_CBC_MD4; break; case ENCTYPE_DES_CBC_MD5: resid = IDS_ETYPE_DES_CBC_MD5; break; case ENCTYPE_DES_CBC_RAW: resid = IDS_ETYPE_DES_CBC_RAW; break; case ENCTYPE_DES3_CBC_SHA: resid = IDS_ETYPE_DES3_CBC_SHA; break; case ENCTYPE_DES3_CBC_RAW: resid = IDS_ETYPE_DES3_CBC_RAW; break; case ENCTYPE_DES_HMAC_SHA1: resid = IDS_ETYPE_DES_HMAC_SHA1; break; case ENCTYPE_DES3_CBC_SHA1: resid = IDS_ETYPE_DES3_CBC_SHA1; break; case ENCTYPE_AES128_CTS_HMAC_SHA1_96: resid = IDS_ETYPE_AES128_CTS_HMAC_SHA1_96; break; case ENCTYPE_AES256_CTS_HMAC_SHA1_96: resid = IDS_ETYPE_AES256_CTS_HMAC_SHA1_96; break; case ENCTYPE_ARCFOUR_HMAC: resid = IDS_ETYPE_ARCFOUR_HMAC; break; case ENCTYPE_ARCFOUR_HMAC_EXP: resid = IDS_ETYPE_ARCFOUR_HMAC_EXP; break; case ENCTYPE_UNKNOWN: resid = IDS_ETYPE_UNKNOWN; break; #if 0 case ENCTYPE_LOCAL_DES3_HMAC_SHA1: resid = IDS_ETYPE_LOCAL_DES3_HMAC_SHA1; break; case ENCTYPE_LOCAL_RC4_MD4: resid = IDS_ETYPE_LOCAL_RC4_MD4; break; #endif } if(resid != 0) { LoadString(hResModule, (UINT) resid, buf, ARRAYLENGTH(buf)); } else { StringCbPrintf(buf, sizeof(buf), L"#%d", etype); } StringCbLength(buf, ARRAYLENGTH(buf), &cblength); cblength += sizeof(wchar_t); if(!destbuf || *pcbdestbuf < cblength) { *pcbdestbuf = cblength; return KHM_ERROR_TOO_LONG; } else { StringCbCopy(destbuf, *pcbdestbuf, buf); *pcbdestbuf = cblength; return KHM_ERROR_SUCCESS; } } khm_int32 KHMAPI addr_list_comp(const void *d1, khm_size cb_d1, const void *d2, khm_size cb_d2) { if (cb_d1 < cb_d2) return -1; if (cb_d1 > cb_d2) return 1; return memcmp(d1, d2, cb_d1); } khm_int32 KHMAPI addr_list_toString(const void *d, khm_size cb_d, wchar_t *buf, khm_size *pcb_buf, khm_int32 flags) { wchar_t tbuf[2048]; wchar_t * strpos; khm_size cbleft; size_t t; k5_serial_address * addrs; if (cb_d == 0 || d == NULL) { tbuf[0] = L'\0'; } else { addrs = (k5_serial_address *) d; strpos = tbuf; cbleft = sizeof(tbuf); tbuf[0] = L'\0'; while (TRUE) { if (cb_d < sizeof(*addrs) || addrs->magic != K5_SERIAL_ADDRESS_MAGIC || cb_d < sizeof(*addrs) + addrs->length - sizeof(khm_int32)) break; if (strpos != tbuf) { if (FAILED(StringCbCatEx(strpos, cbleft, L" ", &strpos, &cbleft, 0))) break; } #ifdef DEBUG assert(*strpos == L'\0'); #endif one_addr(addrs, strpos, cbleft); t = 0; if (FAILED(StringCchLength(strpos, cbleft / sizeof(wchar_t), &t))) break; strpos += t; cbleft -= t * sizeof(wchar_t); t = sizeof(*addrs) + addrs->length - sizeof(khm_int32); addrs = (k5_serial_address *) BYTEOFFSET(addrs, t); cb_d -= t; } } StringCbLength(tbuf, sizeof(tbuf), &t); if (!buf || *pcb_buf < t) { *pcb_buf = t; return KHM_ERROR_TOO_LONG; } StringCbCopy(buf, *pcb_buf, tbuf); *pcb_buf = t; return KHM_ERROR_SUCCESS; } khm_int32 KHMAPI krb5flags_toString(const void *d, khm_size cb_d, wchar_t *buf, khm_size *pcb_buf, khm_int32 f) { wchar_t sbuf[32]; int i = 0; khm_size cb; khm_int32 flags; flags = *((khm_int32 *) d); if (flags & TKT_FLG_FORWARDABLE) sbuf[i++] = L'F'; if (flags & TKT_FLG_FORWARDED) sbuf[i++] = L'f'; if (flags & TKT_FLG_PROXIABLE) sbuf[i++] = L'P'; if (flags & TKT_FLG_PROXY) sbuf[i++] = L'p'; if (flags & TKT_FLG_MAY_POSTDATE) sbuf[i++] = L'D'; if (flags & TKT_FLG_POSTDATED) sbuf[i++] = L'd'; if (flags & TKT_FLG_INVALID) sbuf[i++] = L'i'; if (flags & TKT_FLG_RENEWABLE) sbuf[i++] = L'R'; if (flags & TKT_FLG_INITIAL) sbuf[i++] = L'I'; if (flags & TKT_FLG_HW_AUTH) sbuf[i++] = L'H'; if (flags & TKT_FLG_PRE_AUTH) sbuf[i++] = L'A'; sbuf[i++] = L'\0'; cb = i * sizeof(wchar_t); if (!buf || *pcb_buf < cb) { *pcb_buf = cb; return KHM_ERROR_TOO_LONG; } else { StringCbCopy(buf, *pcb_buf, sbuf); *pcb_buf = cb; return KHM_ERROR_SUCCESS; } } khm_int32 serialize_krb5_addresses(krb5_address ** a, void * buf, size_t * pcbbuf) { k5_serial_address * addr; khm_size cb_req; khm_size t; khm_boolean overflow = FALSE; addr = (k5_serial_address *) buf; cb_req = 0; for(; *a; a++) { t = sizeof(k5_serial_address) + (*a)->length - sizeof(khm_int32); cb_req += t; if (cb_req < *pcbbuf) { addr->magic = K5_SERIAL_ADDRESS_MAGIC; addr->addrtype = (*a)->addrtype; addr->length = (*a)->length; memcpy(&addr->data, (*a)->contents, (*a)->length); addr = (k5_serial_address *) BYTEOFFSET(addr, t); } else { overflow = TRUE; } } *pcbbuf = cb_req; return (overflow)?KHM_ERROR_TOO_LONG: KHM_ERROR_SUCCESS; } void one_addr(k5_serial_address *a, wchar_t * buf, khm_size cbbuf) { wchar_t retstr[256]; struct hostent *h = NULL; int no_resolve = 1; retstr[0] = L'\0'; if ((a->addrtype == ADDRTYPE_INET && a->length == 4) #ifdef AF_INET6 || (a->addrtype == ADDRTYPE_INET6 && a->length == 16) #endif ) { int af = AF_INET; #ifdef AF_INET6 if (a->addrtype == ADDRTYPE_INET6) af = AF_INET6; #endif if (!no_resolve) { #ifdef HAVE_GETIPNODEBYADDR int err; h = getipnodebyaddr(&a->data, a->length, af, &err); if (h) { StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name); freehostent(h); } else h = gethostbyaddr(&a->data, a->length, af); if (h) { StringCbPrintf(retstr, sizeof(retstr), L"%S", h->h_name); } #endif if (h) goto _copy_string; } if (no_resolve || !h) { #ifdef HAVE_INET_NTOP char buf[46]; const char *name = inet_ntop(a->addrtype, &a->data, buf, sizeof(buf)); if (name) { StringCbPrintf(retstr, sizeof(retstr), L"%S", name); goto _copy_string; } #else if (a->addrtype == ADDRTYPE_INET) { khm_ui_4 addr = a->data; StringCbPrintf(retstr, sizeof(retstr), L"%d.%d.%d.%d", (int) (addr & 0xff), (int) ((addr >> 8) & 0xff), (int) ((addr >> 16)& 0xff), (int) ((addr >> 24)& 0xff)); goto _copy_string; } #endif } } { wchar_t tmpfmt[128]; LoadString(hResModule, IDS_UNK_ADDR_FMT, tmpfmt, sizeof(tmpfmt)/sizeof(wchar_t)); StringCbPrintf(retstr, sizeof(retstr), tmpfmt, a->addrtype); } _copy_string: StringCbCopy(buf, cbbuf, retstr); }