KIM ui plugin support and gui selection harness
authorAlexandra Ellwood <lxs@mit.edu>
Fri, 19 Sep 2008 21:51:03 +0000 (21:51 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Fri, 19 Sep 2008 21:51:03 +0000 (21:51 +0000)
ticket: 6055

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20740 dc483132-0cff-0310-8789-dd5450dbe970

16 files changed:
src/include/kim/kim_library.h
src/include/kim/kim_ui_plugin.h
src/kim/lib/kim_error_code.et
src/kim/lib/kim_library.c
src/kim/lib/kim_library_private.h
src/kim/lib/kim_private.h
src/kim/lib/kim_string.c
src/kim/lib/kim_ui.c [new file with mode: 0644]
src/kim/lib/kim_ui_cli.c [new file with mode: 0644]
src/kim/lib/kim_ui_cli_private.h [new file with mode: 0644]
src/kim/lib/kim_ui_gui.c [new file with mode: 0644]
src/kim/lib/kim_ui_gui_private.h [new file with mode: 0644]
src/kim/lib/kim_ui_plugin.c [new file with mode: 0644]
src/kim/lib/kim_ui_plugin_private.h [new file with mode: 0644]
src/kim/lib/kim_ui_private.h [new file with mode: 0644]
src/kim/lib/mac/kim_os_library.c

index 104c1b391819242ff81c4a1ec96c655a8f6d4a6d..7888961846889a517296cea75b0b9fcc16f3a324 100644 (file)
 
 #include <kim/kim.h>
 
+#define KIM_UI_ENVIRONMENT_NONE 0
+#define KIM_UI_ENVIRONMENT_AUTO 1
+#define KIM_UI_ENVIRONMENT_GUI  2
+#define KIM_UI_ENVIRONMENT_CLI  3
+
+typedef int kim_ui_environment;
+
+
+kim_error kim_library_set_ui_environment (kim_ui_environment in_ui_environment);
+
+kim_ui_environment kim_library_ui_environment (void);
+
 
 kim_error kim_library_set_allow_home_directory_access (kim_boolean in_allow_access);
 
 kim_boolean kim_library_allow_home_directory_access (void);
 
+
 kim_error kim_library_set_allow_automatic_prompting (kim_boolean in_allow_automatic_prompting);
 
 kim_boolean kim_library_allow_automatic_prompting (void);
index a56a3604c50c6b431c6e25c07598ea9d3862b0a8..d7fd6e1b76a2b899240dbbbc15b0d36eb9493ce7 100644 (file)
 extern "C" {
 #endif
 
-typedef struct kim_ui_plugin_ftable_v1 {
+/*
+ * The function table / structure which a KIM ui plugin module must export 
+ * as "kim_ui_0".  If the interfaces work correctly, future versions of the 
+ * table will add either more callbacks or more arguments to callbacks, and 
+ * in both cases we'll be able to wrap the v0 functions.
+ */
+/* extern kim_ui_plugin_ftable_v0 kim_ui_0; */
+
+    
+typedef struct kim_ui_plugin_ftable_v0 {
     int minor_version;         /* currently 0 */
     
     /* Called before other calls to allow the UI to initialize.
-     * Return an error if you can't display your UI in this environment. */
-    kim_error (*init)(void         **out_context,
-                      kim_identity   in_identity);
+     * Return an error if you can't display your UI in this environment. 
+     * To allow your plugin to be called from multiple threads, pass back
+     * state associated with this instance of your UI in out_context.  
+     * The same context pointer will be provided to all plugin calls for
+     * this ui. */
+    kim_error (*init) (void **out_context);
     
     /* Present UI to select which identity to use.
      * If this UI calls into KIM to get new credentials it may 
      * call acquire_new_credentials below. */
-    kim_error (*select_identity)(void                *in_context,
-                                 kim_selection_hints  in_hints,
-                                 kim_identity_t      *out_identity);
+    kim_error (*select_identity) (void                *in_context,
+                                  kim_selection_hints  in_hints,
+                                  kim_identity        *out_identity);
     
     /* Present UI to display authentication to the user */
-    typedef kim_error (*auth_prompt) (void              *in_context,
-                                      kim_prompt_type    in_type,
-                                      kim_string         in_title,
-                                      kim_string         in_message,
-                                      kim_string         in_description,
-                                      char             **out_reply);
+    kim_error (*auth_prompt) (void              *in_context,
+                              kim_identity       in_identity,
+                              kim_prompt_type    in_type,
+                              kim_string         in_title,
+                              kim_string         in_message,
+                              kim_string         in_description,
+                              char             **out_reply);
     
     /* Prompt to change the identity's password. 
      * May be combined with an auth prompt if additional auth is required,
@@ -58,29 +71,29 @@ typedef struct kim_ui_plugin_ftable_v1 {
      * If in_old_password_expired is true, this callback is in response
      * to an expired password error.  If this is the case the same context
      * which generated the error will be used for this callback. */
-    kim_error (*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 (*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);
     
     /* Display an error to the user; may be called after any of the prompts */
-    kim_error (*display_error)(void       *in_context,
-                               kim_error   in_error,
-                               kim_string  in_error_message,
-                               kim_string  in_error_description);
+    kim_error (*display_error) (void         *in_context,
+                                kim_identity  in_identity,
+                                kim_error     in_error,
+                                kim_string    in_error_message,
+                                kim_string    in_error_description);
     
     /* Free strings returned by the UI */
-    void (*free_string)(void *in_context,
-                        char *io_string);
+    void (*free_string) (void *in_context,
+                         char *io_string);
     
     /* Called after the last prompt (even on error) to allow the UI to
-     * free allocated resources. */
-    kim_error (*fini)(void         *io_context,
-                      kim_identity  in_identity);
+     * free allocated resources associated with its context. */
+    kim_error (*fini) (void *io_context);
 
-} kim_ui_plugin_ftable_v1;
+} kim_ui_plugin_ftable_v0;
 
     
 #ifdef __cplusplus
index 381f6d28c0394216f48a3c9675622e6c036ce15f..5082a1b807f3a41fe8b80a1b3fa9ed86ae72a174 100644 (file)
@@ -48,8 +48,7 @@ index 75
 error_code KIM_CAPS_LOCK_ERR,                     "Password Incorrect (check your Caps Lock)"
 error_code KIM_USER_CANCELED_ERR,                 "The user cancelled the operation"
 error_code KIM_NO_SERVER_ERR,                     "KerberosAgent is not responding"
-error_code KIM_NO_GUI_ERR,                        "Unable to display a graphical user interface from this environment"
-error_code KIM_NO_CLI_ERR,                        "Unable to display a command line user interface from this environment"
+error_code KIM_NO_UI_ERR,                         "Unable to display a user interface from this environment"
 
 index 100
 # Preferences Errors
index 215e6edf7e43c377ec13543eaf385d39646bf924..287ff3c63fadb288abf85d5b1314344088a5c030 100644 (file)
 
 static k5_mutex_t g_allow_home_directory_access_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 static k5_mutex_t g_allow_automatic_prompting_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
+static k5_mutex_t g_ui_environment_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 
 kim_boolean g_allow_home_directory_access = TRUE;
 kim_boolean g_allow_automatic_prompting = TRUE;
+kim_ui_environment g_ui_environment = KIM_UI_ENVIRONMENT_AUTO;
 
 MAKE_INIT_FUNCTION(kim_thread_init);
 MAKE_FINI_FUNCTION(kim_thread_fini);
@@ -57,6 +59,10 @@ static int kim_thread_init (void)
         err = k5_mutex_finish_init (&g_allow_automatic_prompting_mutex);
     }
     
+    if (!err) {
+        err = k5_mutex_finish_init (&g_ui_environment_mutex);
+    }
+    
     return err;
 }
 
@@ -70,6 +76,7 @@ static void kim_thread_fini (void)
     
     k5_mutex_destroy (&g_allow_home_directory_access_mutex);
     k5_mutex_destroy (&g_allow_automatic_prompting_mutex);
+    k5_mutex_destroy (&g_ui_environment_mutex);
 }
 
 #pragma mark -- Allow Home Directory Access --
@@ -215,3 +222,63 @@ kim_boolean kim_library_allow_automatic_prompting (void)
     
     return allow_automatic_prompting;
 }
+
+#pragma mark -- UI Environment --
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_library_set_ui_environment (kim_ui_environment in_ui_environment)
+{
+    kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
+    kim_error mutex_err = KIM_NO_ERROR;
+    
+    if (!err) {
+        mutex_err = k5_mutex_lock (&g_ui_environment_mutex);
+        if (mutex_err) { err = mutex_err; }
+    }
+    
+    if (!err) {
+        g_ui_environment = in_ui_environment;
+    }
+    
+    if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_library_get_ui_environment (kim_ui_environment *out_ui_environment)
+{
+    kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
+    kim_error mutex_err = KIM_NO_ERROR;
+    
+    if (!err && !out_ui_environment) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        mutex_err = k5_mutex_lock (&g_ui_environment_mutex);;
+        if (mutex_err) { err = mutex_err; }
+    }
+    
+    if (!err) {
+        *out_ui_environment = g_ui_environment;
+    }
+    
+    if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_ui_environment kim_library_ui_environment (void)
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_ui_environment ui_environment = KIM_UI_ENVIRONMENT_AUTO;
+    
+    err = kim_library_get_ui_environment (&ui_environment);
+    
+    if (!err && ui_environment == KIM_UI_ENVIRONMENT_AUTO) {
+        ui_environment = kim_os_library_get_ui_environment ();
+    }
+    
+    return !err ? ui_environment : KIM_UI_ENVIRONMENT_NONE;
+}
index 8c94ead07faa56b284860a9a5c9821956fb63006..435bb51d4ac9dd85916970d1fe25629e1de9025f 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <kim/kim.h>
 
+kim_ui_environment kim_os_library_get_ui_environment (void);
+
 kim_boolean kim_os_library_caller_is_server (void);
 
 #endif /* KIM_LIBRARY_PRIVATE_H */
index 428cf2b204ba1ccbf6eeb2dcf33198d4c3d93162..0a8cdbdfa67acf3990238991fae85cbf9ba43732 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $Header$
  *
- * Copyright 2006 Massachusetts Institute of Technology.
+ * Copyright 2006-2008 Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -33,6 +33,7 @@
 
 #include <kim/kim.h>
 #include <kim/kim_library.h>
+#include <kim/kim_ui_plugin.h>
 
 #include "kim_library_private.h"
 #include "kim_debug_private.h"
@@ -43,5 +44,9 @@
 #include "kim_preferences_private.h"
 #include "kim_selection_hints_private.h"
 #include "kim_string_private.h"
+#include "kim_ui_private.h"
+#include "kim_ui_gui_private.h"
+#include "kim_ui_cli_private.h"
+#include "kim_ui_plugin_private.h"
 
 #endif /* KIM_PRIVATE_H */
index 4e7356515f750ea41eef0fedc2c1b0e19359df71..94bdb7a89fe2becc9029b69d2f22b3ff58a9386a 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "kim_private.h"
 
-
 /* ------------------------------------------------------------------------ */
 
 kim_error kim_string_create_from_format (kim_string *out_string, 
diff --git a/src/kim/lib/kim_ui.c b/src/kim/lib/kim_ui.c
new file mode 100644 (file)
index 0000000..1ef3647
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * $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 "kim_private.h"
+
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_init (kim_ui_context *io_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        kim_ui_environment environment = kim_library_ui_environment ();
+
+        if (environment == KIM_UI_ENVIRONMENT_GUI) {
+            io_context->type = kim_ui_type_gui_plugin;
+            
+            err = kim_ui_plugin_init ((kim_ui_plugin_context *) &io_context->tcontext);
+        
+            if (err) { 
+                io_context->type = kim_ui_type_gui_builtin;
+                
+                err = kim_ui_gui_init ((kim_ui_gui_context *) &io_context->tcontext);
+            }
+
+        } else if (environment == KIM_UI_ENVIRONMENT_CLI) {
+            io_context->type = kim_ui_type_cli;
+            
+            err = kim_ui_cli_init ((kim_ui_cli_context *) &io_context->tcontext);  
+            
+        } else {
+            io_context->type = kim_ui_type_none;
+            
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }    
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_select_identity (kim_ui_context      *in_context,
+                                  kim_selection_hints  in_hints,
+                                  kim_identity        *out_identity)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_hints    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_context->type == kim_ui_type_gui_plugin) {
+            err = kim_ui_plugin_select_identity ((kim_ui_plugin_context) in_context->tcontext, 
+                                                 in_hints,
+                                                 out_identity);
+            
+        } else if (in_context->type == kim_ui_type_gui_builtin) {
+            err = kim_ui_gui_select_identity ((kim_ui_gui_context) in_context->tcontext, 
+                                              in_hints,
+                                              out_identity);
+            
+        } else if (in_context->type == kim_ui_type_cli) {
+            err = kim_ui_cli_select_identity ((kim_ui_cli_context) in_context->tcontext, 
+                                              in_hints,
+                                              out_identity);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_auth_prompt (kim_ui_context    *in_context,
+                              kim_identity       in_identity,
+                              kim_prompt_type    in_type,
+                              kim_string         in_title,
+                              kim_string         in_message,
+                              kim_string         in_description,
+                              char             **out_reply)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    /* in_title, in_message or in_description may be NULL */
+    
+    if (!err) {
+        if (in_context->type == kim_ui_type_gui_plugin) {
+            err = kim_ui_plugin_auth_prompt ((kim_ui_plugin_context) in_context->tcontext, 
+                                             in_identity, 
+                                             in_type,
+                                             in_title,
+                                             in_message,
+                                             in_description,
+                                             out_reply);
+
+        } else if (in_context->type == kim_ui_type_gui_builtin) {
+            err = kim_ui_gui_auth_prompt ((kim_ui_gui_context) in_context->tcontext, 
+                                          in_identity, 
+                                          in_type,
+                                          in_title,
+                                          in_message,
+                                          in_description,
+                                          out_reply);
+            
+        } else if (in_context->type == kim_ui_type_cli) {
+            err = kim_ui_cli_auth_prompt ((kim_ui_cli_context) in_context->tcontext, 
+                                          in_identity, 
+                                          in_type,
+                                          in_title,
+                                          in_message,
+                                          in_description,
+                                          out_reply);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_change_password (kim_ui_context  *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;
+    
+    if (!err && !in_context         ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_old_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_new_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_verify_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_context->type == kim_ui_type_gui_plugin) {
+            err = kim_ui_plugin_change_password ((kim_ui_plugin_context) in_context->tcontext, 
+                                                 in_identity, 
+                                                 in_old_password_expired,
+                                                 out_old_password,
+                                                 out_new_password,
+                                                 out_verify_password);
+            
+        } else if (in_context->type == kim_ui_type_gui_builtin) {
+            err = kim_ui_gui_change_password ((kim_ui_gui_context) in_context->tcontext, 
+                                              in_identity, 
+                                              in_old_password_expired,
+                                              out_old_password,
+                                              out_new_password,
+                                              out_verify_password);
+            
+        } else if (in_context->type == kim_ui_type_cli) {
+            err = kim_ui_cli_change_password ((kim_ui_cli_context) in_context->tcontext, 
+                                              in_identity, 
+                                              in_old_password_expired,
+                                              out_old_password,
+                                              out_new_password,
+                                              out_verify_password);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+        
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_display_error (kim_ui_context *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;
+    
+    if (!err && !in_context          ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_message    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_description) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_context->type == kim_ui_type_gui_plugin) {
+            err = kim_ui_plugin_display_error ((kim_ui_plugin_context) in_context->tcontext, 
+                                               in_identity, 
+                                               in_error,
+                                               in_error_message,
+                                               in_error_description);
+            
+        } else if (in_context->type == kim_ui_type_gui_builtin) {
+            err = kim_ui_gui_display_error ((kim_ui_gui_context) in_context->tcontext, 
+                                            in_identity, 
+                                            in_error,
+                                            in_error_message,
+                                            in_error_description);
+            
+        } else if (in_context->type == kim_ui_type_cli) {
+            err = kim_ui_cli_display_error ((kim_ui_cli_context) in_context->tcontext, 
+                                            in_identity, 
+                                            in_error,
+                                            in_error_message,
+                                            in_error_description);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void kim_ui_free_string (kim_ui_context *in_context,
+                         char           *io_string)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !io_string ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (in_context->type == kim_ui_type_gui_plugin) {
+            kim_ui_plugin_free_string ((kim_ui_plugin_context) in_context->tcontext, 
+                                       io_string);
+            
+        } else if (in_context->type == kim_ui_type_gui_builtin) {
+            kim_ui_gui_free_string ((kim_ui_gui_context) in_context->tcontext, 
+                                    io_string);
+            
+        } else if (in_context->type == kim_ui_type_cli) {
+            kim_ui_cli_free_string ((kim_ui_cli_context) in_context->tcontext, 
+                                    io_string);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_fini (kim_ui_context *io_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        if (io_context->type == kim_ui_type_gui_plugin) {
+            err = kim_ui_plugin_fini ((kim_ui_plugin_context *) &io_context->tcontext);
+            
+        } else if (io_context->type == kim_ui_type_gui_builtin) {
+            err = kim_ui_gui_fini ((kim_ui_gui_context *) &io_context->tcontext);
+            
+        } else if (io_context->type == kim_ui_type_cli) {
+            err = kim_ui_cli_fini ((kim_ui_cli_context *) &io_context->tcontext);
+            
+        } else {
+            err = check_error (KIM_NO_UI_ERR);
+        }
+    }
+    
+    return check_error (err);
+}
diff --git a/src/kim/lib/kim_ui_cli.c b/src/kim/lib/kim_ui_cli.c
new file mode 100644 (file)
index 0000000..d4ba76f
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * $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 "kim_private.h"
+
+
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_init (kim_ui_cli_context *out_context)
+{
+    return KIM_NO_ERROR;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_select_identity (kim_ui_cli_context   in_context,
+                                      kim_selection_hints  in_hints,
+                                      kim_identity        *out_identity)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_hints    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_auth_prompt (kim_ui_cli_context   in_context,
+                                  kim_identity         in_identity,
+                                  kim_prompt_type      in_type,
+                                  kim_string           in_title,
+                                  kim_string           in_message,
+                                  kim_string           in_description,
+                                  char               **out_reply)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    /* in_title, in_message or in_description may be NULL */
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_change_password (kim_ui_cli_context   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;
+    
+    if (!err && !in_context         ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_old_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_new_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_verify_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_display_error (kim_ui_cli_context 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;
+    
+    if (!err && !in_context          ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_message    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_description) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void kim_ui_cli_free_string (kim_ui_cli_context  in_context,
+                             char               *io_string)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !io_string ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        kim_string_free ((kim_string *) io_string);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_cli_fini (kim_ui_cli_context *io_context)
+{
+    return KIM_NO_ERROR;
+}
diff --git a/src/kim/lib/kim_ui_cli_private.h b/src/kim/lib/kim_ui_cli_private.h
new file mode 100644 (file)
index 0000000..cc5ff7f
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * $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.
+ */
+
+#ifndef KIM_UI_CLI_PRIVATE_H
+#define KIM_UI_CLI_PRIVATE_H
+
+#include <kim/kim.h>
+
+typedef void *kim_ui_cli_context;
+
+
+kim_error kim_ui_cli_init (kim_ui_cli_context *out_context);
+
+kim_error kim_ui_cli_select_identity (kim_ui_cli_context   in_context,
+                                      kim_selection_hints  in_hints,
+                                      kim_identity        *out_identity);
+
+kim_error kim_ui_cli_auth_prompt (kim_ui_cli_context   in_context,
+                                  kim_identity         in_identity,
+                                  kim_prompt_type      in_type,
+                                  kim_string           in_title,
+                                  kim_string           in_message,
+                                  kim_string           in_description,
+                                  char               **out_reply);
+
+kim_error kim_ui_cli_change_password (kim_ui_cli_context    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 kim_ui_cli_display_error (kim_ui_cli_context   in_context,
+                                    kim_identity         in_identity,
+                                    kim_error            in_error,
+                                    kim_string           in_error_message,
+                                    kim_string           in_error_description);
+
+void kim_ui_cli_free_string (kim_ui_cli_context  in_context,
+                             char               *io_string);
+
+kim_error kim_ui_cli_fini (kim_ui_cli_context *io_context);
+
+#endif /* KIM_UI_CLI_PRIVATE_H */
diff --git a/src/kim/lib/kim_ui_gui.c b/src/kim/lib/kim_ui_gui.c
new file mode 100644 (file)
index 0000000..56d0401
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * $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 "kim_private.h"
+
+
+struct kim_ui_gui_context {
+};
+
+
+/* ------------------------------------------------------------------------ */
+
+static void kim_ui_gui_context_free (kim_ui_gui_context *io_context)
+{
+    if (io_context && *io_context) { 
+        free (*io_context);
+        *io_context = NULL;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_ui_gui_context_allocate (kim_ui_gui_context *out_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_ui_gui_context context = NULL;
+    
+    if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        context = malloc (sizeof (*context));
+        if (!context) { err = KIM_OUT_OF_MEMORY_ERR; }
+    }
+    
+    if (!err) {
+        *out_context = context;
+        context = NULL;
+    }
+    
+    kim_ui_gui_context_free (&context);
+    
+    return check_error (err);    
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_init (kim_ui_gui_context *out_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_ui_gui_context context = NULL;
+    
+    if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        err = kim_ui_gui_context_allocate (&context);
+    }
+    
+    if (!err) {
+    }
+    
+    if (!err) {
+        *out_context = context;
+        context = NULL;
+    }
+    
+    kim_ui_gui_context_free (&context);
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_select_identity (kim_ui_gui_context   in_context,
+                                      kim_selection_hints  in_hints,
+                                      kim_identity        *out_identity)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_hints    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
+                                  kim_identity         in_identity,
+                                  kim_prompt_type      in_type,
+                                  kim_string           in_title,
+                                  kim_string           in_message,
+                                  kim_string           in_description,
+                                  char               **out_reply)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    /* in_title, in_message or in_description may be NULL */
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_change_password (kim_ui_gui_context   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;
+    
+    if (!err && !in_context         ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_old_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_new_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_verify_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_display_error (kim_ui_gui_context 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;
+    
+    if (!err && !in_context          ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_message    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_description) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void kim_ui_gui_free_string (kim_ui_gui_context  in_context,
+                             char               *io_string)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !io_string ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        kim_string_free ((kim_string *) io_string);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_gui_fini (kim_ui_gui_context *io_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err && *io_context) {
+    }
+    
+    if (!err) {
+        kim_ui_gui_context_free (io_context);
+    }
+    
+    
+    return check_error (err);
+}
diff --git a/src/kim/lib/kim_ui_gui_private.h b/src/kim/lib/kim_ui_gui_private.h
new file mode 100644 (file)
index 0000000..9ddffb1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $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.
+ */
+
+#ifndef KIM_UI_GUI_PRIVATE_H
+#define KIM_UI_GUI_PRIVATE_H
+
+#include <kim/kim.h>
+
+struct kim_ui_gui_context;
+typedef struct kim_ui_gui_context *kim_ui_gui_context;
+
+
+kim_error kim_ui_gui_init (kim_ui_gui_context *out_context);
+
+kim_error kim_ui_gui_select_identity (kim_ui_gui_context   in_context,
+                                      kim_selection_hints  in_hints,
+                                      kim_identity        *out_identity);
+
+kim_error kim_ui_gui_auth_prompt (kim_ui_gui_context   in_context,
+                                  kim_identity         in_identity,
+                                  kim_prompt_type      in_type,
+                                  kim_string           in_title,
+                                  kim_string           in_message,
+                                  kim_string           in_description,
+                                  char               **out_reply);
+
+kim_error kim_ui_gui_change_password (kim_ui_gui_context    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 kim_ui_gui_display_error (kim_ui_gui_context   in_context,
+                                    kim_identity         in_identity,
+                                    kim_error            in_error,
+                                    kim_string           in_error_message,
+                                    kim_string           in_error_description);
+
+void kim_ui_gui_free_string (kim_ui_gui_context  in_context,
+                             char               *io_string);
+
+kim_error kim_ui_gui_fini (kim_ui_gui_context *io_context);
+
+#endif /* KIM_UI_GUI_PRIVATE_H */
diff --git a/src/kim/lib/kim_ui_plugin.c b/src/kim/lib/kim_ui_plugin.c
new file mode 100644 (file)
index 0000000..5c5cc26
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * $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 "k5-int.h"
+
+#include "kim_private.h"
+
+
+#if TARGET_OS_MAC
+const char * const kim_ui_plugin_files[] = { "KerberosUI", NULL };
+static const char *kim_ui_plugin_dirs[] = { KRB5_KIM_UI_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/kimui", NULL };
+#else
+const char * const *kim_ui_plugin_files = NULL;
+static const char *kim_ui_plugin_dirs[] = { LIBDIR "/krb5/plugins/kimui", NULL };
+#endif
+
+
+struct kim_ui_plugin_context {
+    struct plugin_dir_handle plugins;
+    struct kim_ui_plugin_ftable_v0 *ftable;
+    void **ftables;
+    void *plugin_context;
+};
+
+
+/* ------------------------------------------------------------------------ */
+
+static void kim_ui_plugin_context_free (kim_ui_plugin_context *io_context)
+{
+    if (io_context && *io_context) { 
+        if ((*io_context)->ftables) {
+            krb5int_free_plugin_dir_data ((*io_context)->ftables);
+        }
+        if (PLUGIN_DIR_OPEN (&(*io_context)->plugins)) { 
+            krb5int_close_plugin_dirs (&(*io_context)->plugins); 
+        }
+        free (*io_context);
+        *io_context = NULL;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+
+static kim_error kim_ui_plugin_context_allocate (kim_ui_plugin_context *out_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_ui_plugin_context context = NULL;
+    
+    if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        context = malloc (sizeof (*context));
+        if (!context) { err = KIM_OUT_OF_MEMORY_ERR; }
+    }
+    
+    if (!err) {
+        PLUGIN_DIR_INIT(&context->plugins);
+        context->ftable = NULL;
+        context->ftables = NULL;
+        context->plugin_context = NULL;
+        
+        *out_context = context;
+        context = NULL;
+    }
+    
+    kim_ui_plugin_context_free (&context);
+    
+    return check_error (err);    
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_init (kim_ui_plugin_context *out_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    kim_ui_plugin_context context = NULL;
+    struct errinfo einfo;
+    
+    if (!err && !out_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        err = kim_ui_plugin_context_allocate (&context);
+    }
+    
+    if (!err) {
+        PLUGIN_DIR_INIT(&context->plugins);
+
+        err = krb5int_open_plugin_dirs (kim_ui_plugin_dirs, 
+                                        kim_ui_plugin_files, 
+                                        &context->plugins, &einfo);
+    }
+    
+    if (!err) {
+        err = krb5int_get_plugin_dir_data (&context->plugins,
+                                           "kim_ui_0",
+                                           &context->ftables, 
+                                           &einfo);
+    }
+    
+    if (!err && context->ftables) {
+        int i;
+        
+        for (i = 0; context->ftables[i]; i++) {
+            struct kim_ui_plugin_ftable_v0 *ftable = context->ftables[i];
+            context->plugin_context = NULL;
+            
+            err = ftable->init (&context->plugin_context);
+            
+            if (!err) {
+                context->ftable = ftable;
+                break; /* use first plugin that initializes correctly */
+            }
+            
+            err = KIM_NO_ERROR; /* ignore failed plugins */
+        }
+    }
+    
+    if (!err && !context->ftable) {
+        err = check_error (KRB5_PLUGIN_NO_HANDLE);
+    }
+        
+    if (!err) {
+        *out_context = context;
+        context = NULL;
+    }
+    
+    kim_ui_plugin_context_free (&context);
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_select_identity (kim_ui_plugin_context  in_context,
+                                         kim_selection_hints    in_hints,
+                                         kim_identity          *out_identity)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_hints    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        err = in_context->ftable->select_identity (in_context->plugin_context,
+                                                   in_hints, 
+                                                   out_identity);
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_auth_prompt (kim_ui_plugin_context  in_context,
+                                     kim_identity           in_identity,
+                                     kim_prompt_type        in_type,
+                                     kim_string             in_title,
+                                     kim_string             in_message,
+                                     kim_string             in_description,
+                                     char                 **out_reply)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_reply  ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    /* in_title, in_message or in_description may be NULL */
+    
+    if (!err) {
+        err = in_context->ftable->auth_prompt (in_context->plugin_context,
+                                               in_identity, 
+                                               in_type,
+                                               in_title,
+                                               in_message,
+                                               in_description,
+                                               out_reply);
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_change_password (kim_ui_plugin_context  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;
+    
+    if (!err && !in_context         ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_identity        ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_old_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_new_password   ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !out_verify_password) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        err = in_context->ftable->change_password (in_context->plugin_context,
+                                                   in_identity, 
+                                                   in_old_password_expired,
+                                                   out_old_password,
+                                                   out_new_password,
+                                                   out_verify_password);
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_display_error (kim_ui_plugin_context 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;
+    
+    if (!err && !in_context          ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_message    ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !in_error_description) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        err = in_context->ftable->display_error (in_context->plugin_context,
+                                                 in_identity, 
+                                                 in_error,
+                                                 in_error_message,
+                                                 in_error_description);
+    }
+    
+    return check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void kim_ui_plugin_free_string (kim_ui_plugin_context  in_context,
+                                char                  *io_string)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !in_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    if (!err && !io_string ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err) {
+        in_context->ftable->free_string (in_context->plugin_context, 
+                                         io_string);
+    }
+ }
+
+/* ------------------------------------------------------------------------ */
+
+kim_error kim_ui_plugin_fini (kim_ui_plugin_context *io_context)
+{
+    kim_error err = KIM_NO_ERROR;
+    
+    if (!err && !io_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
+    
+    if (!err && *io_context) {
+        err = (*io_context)->ftable->fini (&(*io_context)->plugin_context);
+    }
+    
+    if (!err) {
+        kim_ui_plugin_context_free (io_context);
+    }
+    
+    
+    return check_error (err);
+}
diff --git a/src/kim/lib/kim_ui_plugin_private.h b/src/kim/lib/kim_ui_plugin_private.h
new file mode 100644 (file)
index 0000000..b481665
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $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.
+ */
+
+#ifndef KIM_UI_PLUGIN_PRIVATE_H
+#define KIM_UI_PLUGIN_PRIVATE_H
+
+#include <kim/kim.h>
+
+struct kim_ui_plugin_context;
+typedef struct kim_ui_plugin_context *kim_ui_plugin_context;
+
+
+kim_error kim_ui_plugin_init (kim_ui_plugin_context *out_context);
+
+kim_error kim_ui_plugin_select_identity (kim_ui_plugin_context  in_context,
+                                         kim_selection_hints    in_hints,
+                                         kim_identity          *out_identity);
+
+kim_error kim_ui_plugin_auth_prompt (kim_ui_plugin_context   in_context,
+                                     kim_identity            in_identity,
+                                     kim_prompt_type         in_type,
+                                     kim_string              in_title,
+                                     kim_string              in_message,
+                                     kim_string              in_description,
+                                     char                  **out_reply);
+
+kim_error kim_ui_plugin_change_password (kim_ui_plugin_context    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 kim_ui_plugin_display_error (kim_ui_plugin_context   in_context,
+                                       kim_identity            in_identity,
+                                       kim_error               in_error,
+                                       kim_string              in_error_message,
+                                       kim_string              in_error_description);
+
+void kim_ui_plugin_free_string (kim_ui_plugin_context  in_context,
+                                char                  *io_string);
+
+kim_error kim_ui_plugin_fini (kim_ui_plugin_context *io_context);
+
+#endif /* KIM_UI_PLUGIN_PRIVATE_H */
diff --git a/src/kim/lib/kim_ui_private.h b/src/kim/lib/kim_ui_private.h
new file mode 100644 (file)
index 0000000..21183ef
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * $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.
+ */
+
+#ifndef KIM_UI_PRIVATE_H
+#define KIM_UI_PRIVATE_H
+
+#include <kim/kim.h>
+
+enum kim_ui_type {
+    kim_ui_type_gui_plugin,
+    kim_ui_type_gui_builtin,
+    kim_ui_type_cli,
+    kim_ui_type_none
+};
+
+/* declare struct on stack.  Deep contents will be freed by kim_ui_fini. */
+typedef struct kim_ui_context {
+    enum kim_ui_type type;
+    void *tcontext;
+} kim_ui_context;
+
+
+kim_error kim_ui_init (kim_ui_context *io_context);
+
+kim_error kim_ui_select_identity (kim_ui_context       *in_context,
+                                  kim_selection_hints   in_hints,
+                                  kim_identity        *out_identity);
+
+kim_error kim_ui_auth_prompt (kim_ui_context    *in_context,
+                              kim_identity       in_identity,
+                              kim_prompt_type    in_type,
+                              kim_string         in_title,
+                              kim_string         in_message,
+                              kim_string         in_description,
+                              char             **out_reply);
+
+kim_error kim_ui_change_password (kim_ui_context  *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 kim_ui_display_error (kim_ui_context *in_context,
+                                kim_identity    in_identity,
+                                kim_error       in_error,
+                                kim_string      in_error_message,
+                                kim_string      in_error_description);
+
+void kim_ui_free_string (kim_ui_context  *in_context,
+                         char            *io_string);
+
+kim_error kim_ui_fini (kim_ui_context *io_context);
+
+#endif /* KIM_UI_PRIVATE_H */
index c9f563454d447cb9085f3651e6acc4ab4886a6d4..43dd3d5c7d117503bb7d3e2ba14febb8b2735628 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <CoreFoundation/CoreFoundation.h>
+#include <Kerberos/kipc_session.h>
 #include "k5-int.h"
 #include "k5-thread.h"
 #include <krb5/krb5.h>
@@ -92,6 +93,24 @@ kim_error kim_os_library_unlock_for_bundle_lookup (void)
 
 /* ------------------------------------------------------------------------ */
 
+kim_ui_environment kim_os_library_get_ui_environment (void)
+{
+    kipc_session_attributes_t attributes = kipc_session_get_attributes ();
+    
+    if (attributes & kkipc_session_caller_uses_gui) {
+        return KIM_UI_ENVIRONMENT_GUI;
+    } else if (attributes & kkipc_session_has_cli_access) {
+        return KIM_UI_ENVIRONMENT_CLI;
+    } else if (attributes & kkipc_session_has_gui_access) {
+        return KIM_UI_ENVIRONMENT_GUI;
+    }
+    
+    kim_debug_printf ("kim_os_library_get_ui_environment(): no way to talk to the user.");
+    return KIM_UI_ENVIRONMENT_NONE;
+}
+
+/* ------------------------------------------------------------------------ */
+
 kim_boolean kim_os_library_caller_is_server (void)
 {
     CFBundleRef mainBundle = CFBundleGetMainBundle ();