#include #include #include #include #include #include #include #include static void readfile(const char *fn, krb5_data *data) { struct stat sb; ssize_t ret; int fd; fd = open(fn, O_RDONLY); if (fd < 0) err(1, "open"); ret = fstat(fd, &sb); if (ret < 0) err(1, "fstat"); data->length = sb.st_size; data->data = malloc(sb.st_size); if (data->data == NULL) err(1, "malloc"); ret = read(fd, data->data, data->length); if (ret < 0) err(1, "read"); else if (ret != data->length) errx(1, "read complete early"); close(fd); } static void writefile(const char *fn, krb5_data *data) { ssize_t ret; int fd; fd = open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) err(1, "open"); ret = write(fd, data->data, data->length); if (ret < 0) err(1, "write"); else if (ret != data->length) errx(1, "write complete early"); close(fd); } static void decrypt_krb5_data(krb5_context context, const char *name, krb5_keyusage usage, const krb5_data *encdata, krb5_data *data) { krb5_error_code ret; krb5_keytab keytab; krb5_keytab_entry entry; krb5_kt_cursor cursor; int ok = 0; ret = krb5_kt_resolve(context, name, &keytab); if (ret) krb5_err(context, 1, ret, "resolving keytab %s", name); ret = krb5_kt_start_seq_get(context, keytab, &cursor); if(ret) krb5_err(context, 1, ret, "krb5_kt_start_seq_get %s", name); while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){ krb5_crypto crypto; ret = krb5_crypto_init(context, &entry.keyblock, 0, &crypto); if (ret) krb5_err(context, 1, ret, "krb5_crypto_init"); ret = krb5_decrypt_ivec(context, crypto, usage, encdata->data, encdata->length, data, NULL); if (ret == 0) { char *principal; krb5_unparse_name(context, entry.principal, &principal); printf("%s\n", principal); ok = 1; } krb5_kt_free_entry(context, &entry); krb5_crypto_destroy(context, crypto); if (ok) break; } ret = krb5_kt_end_seq_get(context, keytab, &cursor); if(ret) krb5_err(context, 1, ret, "krb5_kt_end_seq_get %s", name); krb5_kt_close(context, keytab); if (!ok) krb5_errx(context, 1, "didn't decrypt ok"); } int main(int argc, char **argv) { krb5_context context; krb5_error_code ret; krb5_data encdata, data; ret = krb5_init_context(&context); if (ret) errx(1, "krb5_init_context: %d\n", ret); if (argc != 4) errx(1, "argc != 4"); readfile(argv[2], &encdata); decrypt_krb5_data(context, argv[1], 2, &encdata, &data); writefile(argv[3], &data); return 0; }