/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #include #include typedef struct { const char *magic; aslclient asl_context; int got_error; } *test_ui_context; const char *magic = "test_ui_context_magic"; /* ------------------------------------------------------------------------ */ static void test_ui_vlog (test_ui_context in_context, const char *in_format, va_list in_args) { if (!in_context) { asl_log (NULL, NULL, ASL_LEVEL_ERR, "NULL context!"); } else if (strcmp (in_context->magic, magic)) { asl_log (NULL, NULL, ASL_LEVEL_ERR, "Magic mismatch. Context corrupted!"); } else { asl_vlog (in_context->asl_context, NULL, ASL_LEVEL_NOTICE, in_format, in_args); } } /* ------------------------------------------------------------------------ */ static void test_ui_log_ (void *in_context, const char *in_function, const char *in_format, ...) { test_ui_context context = in_context; char *format = NULL; va_list args; asprintf (&format, "%s: %s", in_function, in_format); va_start (args, in_format); test_ui_vlog (context, format, args); va_end (args); free (format); } #define test_ui_log(context, format, ...) test_ui_log_(context, __FUNCTION__, format, ## __VA_ARGS__) #pragma mark - /* ------------------------------------------------------------------------ */ static kim_error test_ui_init (void **out_context) { kim_error err = KIM_NO_ERROR; test_ui_context context = NULL; if (!err) { context = malloc (sizeof (*context)); if (!context) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { context->got_error = 0; context->magic = magic; context->asl_context = asl_open (NULL, "com.apple.console", ASL_OPT_NO_DELAY | ASL_OPT_STDERR); if (!context->asl_context) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { test_ui_log (context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (NULL, "returning %d: %s", err, estring); kim_string_free (&estring); } if (!err) { *out_context = context; context = NULL; } free (context); return err; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_enter_identity (void *in_context, kim_options io_options, kim_identity *out_identity, kim_boolean *out_change_password) { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; test_ui_log (in_context, "entering..."); if (!err) { test_ui_context context = in_context; if (context->got_error > 1) { test_ui_log (in_context, "\tfailed twice, giving up..."); context->got_error = 0; err = KIM_USER_CANCELED_ERR; } } if (!err) { err = kim_options_set_lifetime (io_options, 1800); } if (!err) { err = kim_options_set_renewal_lifetime (io_options, 3600); } if (!err) { err = kim_identity_create_from_string (&identity, "nobody@TEST-KERBEROS-1.5"); } if (!err) { *out_identity = identity; identity = NULL; *out_change_password = 0; } kim_identity_free (&identity); if (!err) { test_ui_log (in_context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (in_context, "returning %d: %s", err, estring); kim_string_free (&estring); } return err; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_select_identity (void *in_context, kim_selection_hints io_hints, kim_identity *out_identity, kim_boolean *out_change_password) { kim_error err = KIM_NO_ERROR; kim_identity identity = NULL; kim_options options = NULL; test_ui_log (in_context, "entering..."); if (!err) { test_ui_context context = in_context; if (context->got_error > 1) { test_ui_log (in_context, "\tfailed twice, giving up..."); context->got_error = 0; err = KIM_USER_CANCELED_ERR; } } if (!err) { err = kim_selection_hints_get_options (io_hints, &options); } if (!err && !options) { err = kim_options_create (&options); } if (!err) { err = kim_options_set_lifetime (options, 1800); } if (!err) { err = kim_options_set_renewal_lifetime (options, 3600); } if (!err) { err = kim_selection_hints_set_options (io_hints, options); } if (!err) { err = kim_identity_create_from_string (&identity, "nobody@TEST-KERBEROS-1.5"); } if (!err) { *out_identity = identity; identity = NULL; *out_change_password = 0; } kim_options_free (&options); kim_identity_free (&identity); if (!err) { test_ui_log (in_context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (in_context, "returning %d: %s", err, estring); kim_string_free (&estring); } return err; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_auth_prompt (void *in_context, kim_identity in_identity, kim_prompt_type in_type, kim_boolean in_allow_save_reply, kim_boolean in_hide_reply, kim_string in_title, kim_string in_message, kim_string in_description, char **out_reply, kim_boolean *out_save_reply) { kim_error err = KIM_NO_ERROR; kim_string string = NULL; char *reply = NULL; test_ui_log (in_context, "entering..."); if (!err) { err = kim_identity_get_display_string (in_identity, &string); } if (!err) { test_ui_log (in_context, "\tidentity = %s", string); test_ui_log (in_context, "\ttype = %d", in_type); test_ui_log (in_context, "\tallow_save_reply = %d", in_allow_save_reply); test_ui_log (in_context, "\thide_reply = %d", in_hide_reply); test_ui_log (in_context, "\ttitle = %s", in_title); test_ui_log (in_context, "\tmessage = %s", in_message); test_ui_log (in_context, "\tdescription = %s", in_description); reply = strdup ("ydobon"); if (!reply) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { test_ui_context context = in_context; if (context->got_error > 1) { test_ui_log (in_context, "\tfailed twice, giving up..."); context->got_error = 0; err = KIM_USER_CANCELED_ERR; } } if (!err) { *out_reply = reply; reply = NULL; *out_save_reply = 0; } free (reply); kim_string_free (&string); if (!err) { test_ui_log (in_context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (in_context, "returning %d: %s", err, estring); kim_string_free (&estring); } return err; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_change_password (void *in_context, kim_identity in_identity, kim_boolean in_old_password_expired, char **out_old_password, char **out_new_password, char **out_verify_password) { kim_error err = KIM_NO_ERROR; kim_string string = NULL; char *old_password = NULL; char *new_password = NULL; char *vfy_password = NULL; test_ui_log (in_context, "entering..."); if (!err) { err = kim_identity_get_display_string (in_identity, &string); } if (!err) { test_ui_log (in_context, "\tidentity = %s", string); test_ui_log (in_context, "\told_password_expired = %d", in_old_password_expired); old_password = strdup ("ydobon"); new_password = strdup ("foo"); vfy_password = strdup ("foo"); if (!old_password || !new_password || !vfy_password) { err = KIM_OUT_OF_MEMORY_ERR; } } if (!err) { test_ui_context context = in_context; if (context->got_error > 1) { test_ui_log (in_context, "\tfailed twice, giving up..."); context->got_error = 0; err = KIM_USER_CANCELED_ERR; } } if (!err) { *out_old_password = old_password; old_password = NULL; *out_new_password = new_password; new_password = NULL; *out_verify_password = vfy_password; vfy_password = NULL; } free (old_password); free (new_password); free (vfy_password); kim_string_free (&string); if (!err) { test_ui_log (in_context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (in_context, "returning %d: %s", err, estring); kim_string_free (&estring); } return err; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_handle_error (void *in_context, kim_identity in_identity, kim_error in_error, kim_string in_error_message, kim_string in_error_description) { kim_error err = KIM_NO_ERROR; kim_string string = NULL; test_ui_log (in_context, "entering..."); if (!err) { err = kim_identity_get_display_string (in_identity, &string); } if (!err) { test_ui_context context = in_context; test_ui_log (in_context, "\tidentity = %s", string); test_ui_log (in_context, "\terror = %d", in_error); test_ui_log (in_context, "\tmessage = %s", in_error_message); test_ui_log (in_context, "\tdescription = %s", in_error_description); context->got_error++; } kim_string_free (&string); if (!err) { test_ui_log (in_context, "returning with no error."); } else { kim_string estring = NULL; kim_string_create_for_last_error (&estring, err); test_ui_log (in_context, "returning %d: %s", err, estring); kim_string_free (&estring); } return err; } /* ------------------------------------------------------------------------ */ static void test_ui_free_string (void *in_context, char **io_string) { /* strings zeroed by caller so just print pointer value */ test_ui_log (in_context, "freeing string %p", *io_string); free (*io_string); *io_string = NULL; } /* ------------------------------------------------------------------------ */ static kim_error test_ui_fini (void *io_context) { kim_error err = KIM_NO_ERROR; test_ui_log (io_context, "deallocating..."); if (io_context) { test_ui_context context = io_context; asl_close (context->asl_context); free (context); } return err; } /* ------------------------------------------------------------------------ */ kim_ui_plugin_ftable_v0 kim_ui_0 = { 0, test_ui_init, test_ui_enter_identity, test_ui_select_identity, test_ui_auth_prompt, test_ui_change_password, test_ui_handle_error, test_ui_free_string, test_ui_fini };