static int init_read (Shishi * handle, const char *tktsfile, const char *systemcfgfile, const char *usercfgfile) { int rc = SHISHI_OK; /* XXX Is this the correct place for this? */ maybe_install_usercfg (handle); if (!systemcfgfile) systemcfgfile = shishi_cfg_default_systemfile (handle); if (*systemcfgfile) rc = shishi_cfg_from_file (handle, systemcfgfile); if (rc == SHISHI_FOPEN_ERROR) shishi_warn (handle, "%s: %s", systemcfgfile, strerror (errno)); if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR) return rc; if (!usercfgfile) usercfgfile = shishi_cfg_default_userfile (handle); if (*usercfgfile) rc = shishi_cfg_from_file (handle, usercfgfile); if (rc == SHISHI_FOPEN_ERROR) shishi_warn (handle, "%s: %s", usercfgfile, strerror (errno)); if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR) return rc; if (!tktsfile) tktsfile = shishi_tkts_default_file (handle); if (!handle->tkts) rc = shishi_tkts (handle, &handle->tkts); if (rc != SHISHI_OK) return rc; if (*tktsfile) rc = shishi_tkts_from_file (handle->tkts, tktsfile); if (rc == SHISHI_FOPEN_ERROR) shishi_verbose (handle, "%s: %s", tktsfile, strerror (errno)); if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR) return rc; if (VERBOSENOISE (handle)) shishi_cfg_print (handle, stderr); return SHISHI_OK; }
/** * shishi_keys_for_serverrealm_in_file * @handle: Shishi library handle create by shishi_init(). * @filename: file to read keys from. * @server: server name to get key for. * @realm: realm of server to get key for. * * Get keys that match specified @server and @realm from the key set * file @filename. * * Return value: Returns the key for specific server and realm, read * from the indicated file, or NULL if no key could be found or an * error encountered. **/ Shishi_key * shishi_keys_for_serverrealm_in_file (Shishi * handle, const char *filename, const char *server, const char *realm) { Shishi_key *key = NULL; FILE *fh; int res; fh = fopen (filename, "r"); if (fh == NULL) return NULL; res = SHISHI_OK; while (!feof (fh)) { res = shishi_key_parse (handle, fh, &key); if (res != SHISHI_OK || key == NULL) break; if (VERBOSENOISE (handle)) { printf ("Read key:\n"); shishi_key_print (handle, stdout, key); } if ((!server || (shishi_key_principal (key) && strcmp (server, shishi_key_principal (key)) == 0)) && (!realm || (shishi_key_realm (key) && strcmp (realm, shishi_key_realm (key)) == 0))) break; shishi_key_done (key); key = NULL; } res = fclose (fh); if (res != 0) return NULL; return key; }
/** * shishi_keys_add_keytab_mem: * @handle: shishi handle as allocated by shishi_init(). * @data: constant memory buffer with keytab of @len size. * @len: size of memory buffer with keytab data. * @keys: allocated key set to store keys in. * * Read keys from a MIT keytab data structure, and add them to the key * set. * * The format of keytab's is proprietary, and this function support * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos * Keytab Binary File Format in the Shishi manual for a description of * the reverse-engineered format. * * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not * represent a valid keytab structure, and %SHISHI_OK on success. **/ int shishi_keys_add_keytab_mem (Shishi * handle, const char *data, size_t len, Shishi_keys *keys) { int rc; uint16_t file_format_version; size_t entrystartpos; uint16_t num_components; /* sub 1 if version 0x501 */ size_t i; Shishi_key *key; if (VERBOSENOISE (handle)) { printf ("keytab len %d (0x%x)\n", len, len); _shishi_hexprint (data, len); } /* Check file format. */ file_format_version = (data[0] << 8) | data[1]; if (VERBOSENOISE (handle)) printf ("keytab file_format_version %04X\n", file_format_version); if (file_format_version != 0x0501 && file_format_version != 0x0502) return SHISHI_KEYTAB_ERROR; /* Check file integrity first, to avoid error-checking below. */ entrystartpos = 2; while (entrystartpos < len) { int32_t size = data[entrystartpos] << 24 | data[entrystartpos+1] << 16 | data[entrystartpos+2] << 8 | data[entrystartpos+3]; entrystartpos += 4; if (VERBOSENOISE (handle)) { printf ("keytab size %d (%x)\n", size, size); printf ("keytab pos %d < %d\n", entrystartpos + size, len); } if (entrystartpos + size > len) return SHISHI_KEYTAB_ERROR; /* Go to next entry... */ entrystartpos += size; } if (entrystartpos != len) return SHISHI_KEYTAB_ERROR; rc = shishi_key (handle, &key); if (rc != SHISHI_OK) return rc; entrystartpos = 2; while (entrystartpos < len) { size_t pos = entrystartpos; uint16_t size = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab size %d (%x)\n", size, size); /* Num_components */ num_components = data[pos] << 8 | data[pos+1]; pos += 2; if (file_format_version == 0x0501) num_components--; /* Realm */ { uint16_t realmlen = data[pos] << 8 | data[pos+1]; char *realm = xstrndup (&data[pos + 2], realmlen);; pos += 2 + realmlen; shishi_key_realm_set (key, realm); free (realm); } /* Principal components. */ { char *name = NULL; size_t namelen = 0; for (i = 0; i < num_components; i++) { size_t l; l = data[pos] << 8 | data[pos+1]; pos += 2; name = xrealloc (name, namelen + l + 1); memcpy (name + namelen, &data[pos], l); name[namelen + l] = '/'; namelen += l + 1; pos += l; } name[namelen - 1] = '\0'; shishi_key_principal_set (key, name); free (name); } /* Name_type */ { uint32_t name_type /* not present if version 0x501 */ = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab nametype %d (0x%08x)\n", name_type, name_type); } /* Timestamp */ { uint32_t timestamp = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab timestamp %u (0x%08ux)\n", timestamp, timestamp); } /* keyvno8 */ { uint8_t vno8 = data[pos++]; if (VERBOSENOISE (handle)) printf ("keytab kvno8 %d (0x%02x)\n", vno8, vno8); shishi_key_version_set (key, vno8); } /* key, keytype */ { uint32_t keytype = data[pos] << 8 | data[pos+1]; pos += 2; if (VERBOSENOISE (handle)) printf ("keytab keytype %d (0x%x)\n", keytype, keytype); shishi_key_type_set (key, keytype); } /* key, length and data */ { uint16_t keylen = data[pos] << 8 | data[pos+1]; pos += 2; if (VERBOSENOISE (handle)) printf ("keytab keylen %d (0x%x) eq? %d\n", keylen, keylen, shishi_key_length (key)); if (VERBOSENOISE (handle)) _shishi_hexprint (data + pos, keylen); shishi_key_value_set (key, data + pos); pos += keylen; } if (pos - entrystartpos < (size_t) size + 4) { uint32_t vno /* only present if >= 4 bytes left in entry */ = data[pos] << 24 | data[pos+1] << 16 | data[pos+2] << 8 | data[pos+3]; pos += 4; if (VERBOSENOISE (handle)) printf ("keytab kvno %d (0x%08x)\n", vno, vno); shishi_key_version_set (key, vno); } if (VERBOSECRYPTONOISE (handle)) shishi_key_print (handle, stdout, key); rc = shishi_keys_add (keys, key); if (rc != SHISHI_OK) goto done; /* Go to next entry... */ entrystartpos += size + 4; } rc = SHISHI_OK; done: shishi_key_done (key); return rc; }