from cffi import FFI ffibuilder = FFI() # Definitions selectively copied from . # Add more if necessary. ffibuilder.cdef(r""" # define KV5M_DATA ... typedef int32_t krb5_int32; typedef krb5_int32 krb5_error_code; typedef krb5_error_code krb5_magic; struct _krb5_context; typedef struct _krb5_context* krb5_context; struct _krb5_auth_context; typedef struct _krb5_auth_context * krb5_auth_context; struct _krb5_ccache; typedef struct _krb5_ccache *krb5_ccache; typedef struct krb5_principal_data { ...; } krb5_principal_data; typedef krb5_principal_data * krb5_principal; typedef const krb5_principal_data *krb5_const_principal; typedef struct _krb5_creds { krb5_principal client; krb5_principal server; ...; } krb5_creds; typedef struct _krb5_data { krb5_magic magic; unsigned int length; char *data; } krb5_data; typedef struct krb5_replay_data { ...; } krb5_replay_data; krb5_error_code krb5_init_context(krb5_context * context); void krb5_free_context(krb5_context context); krb5_error_code krb5_auth_con_init( krb5_context context, krb5_auth_context *auth_context); krb5_error_code krb5_auth_con_setflags( krb5_context context, krb5_auth_context auth_context, krb5_int32 flags); krb5_error_code krb5_auth_con_free( krb5_context context, krb5_auth_context auth_context); krb5_error_code krb5_cc_new_unique(krb5_context context, const char *type, const char *hint, krb5_ccache *id); krb5_error_code krb5_cc_default(krb5_context context, krb5_ccache *ccache); krb5_error_code krb5_cc_resolve( krb5_context context, const char * name, krb5_ccache * cache); krb5_error_code krb5_cc_initialize(krb5_context context, krb5_ccache cache, krb5_principal principal); krb5_error_code krb5_cc_get_principal(krb5_context context, krb5_ccache cache, krb5_principal *principal); krb5_error_code krb5_cc_store_cred( krb5_context context, krb5_ccache cache, krb5_creds *creds); krb5_error_code krb5_cc_close(krb5_context context, krb5_ccache cache); krb5_error_code krb5_cc_destroy(krb5_context context, krb5_ccache cache); krb5_error_code krb5_build_principal(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, ...); krb5_error_code krb5_parse_name(krb5_context context, const char *name, krb5_principal *principal_out); void krb5_free_principal(krb5_context context, krb5_principal val); krb5_error_code krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data *pcreddata, krb5_creds ***pppcreds, krb5_replay_data *outdata); krb5_error_code krb5_fwd_tgt_creds( krb5_context context, krb5_auth_context auth_context, const char * rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data * outbuf); void krb5_free_tgt_creds(krb5_context context, krb5_creds ** tgts); void krb5_free_data_contents(krb5_context context, krb5_data * val); krb5_error_code krb5_unparse_name( krb5_context context, krb5_const_principal principal, char **name); void krb5_free_unparsed_name(krb5_context context, char *val); const char * krb5_get_error_message(krb5_context ctx, krb5_error_code code); void krb5_free_error_message(krb5_context ctx, const char * msg); """) ffibuilder.set_source( "_krb5", """ #include """, libraries=['krb5'], extra_link_args=['-fsanitize=address', '-static-libasan'], ) if __name__ == '__main__': ffibuilder.compile(verbose=True)