Exemple #1
0
kim_ui_environment kim_os_library_get_ui_environment (void)
{
#ifdef KIM_BUILTIN_UI
    kim_boolean has_gui_access = 0;
    SessionAttributeBits sattrs = 0L;

    has_gui_access = ((SessionGetInfo (callerSecuritySession,
                                       NULL, &sattrs) == noErr) &&
                      (sattrs & sessionHasGraphicAccess));

    if (has_gui_access && kim_os_library_caller_uses_gui ()) {
        return KIM_UI_ENVIRONMENT_GUI;
    }

    {
        int fd_stdin = fileno (stdin);
        int fd_stdout = fileno (stdout);
        char *fd_stdin_name = ttyname (fd_stdin);

        /* Session info isn't reliable for remote sessions.
         * Check manually for terminal access with file descriptors */
        if (isatty (fd_stdin) && isatty (fd_stdout) && fd_stdin_name) {
            return KIM_UI_ENVIRONMENT_CLI;
        }
    }

    /* If we don't have a CLI but can talk to the GUI, use that */
    if (has_gui_access) {
        return KIM_UI_ENVIRONMENT_GUI;
    }

    kim_debug_printf ("kim_os_library_get_ui_environment(): no way to talk to the user.");
#endif
    return KIM_UI_ENVIRONMENT_NONE;
}
static kim_error kim_os_selection_hints_get_dictionary_identity (CFDictionaryRef  in_dictionary,
                                                                 kim_identity    *out_identity)
{
    kim_error err = KIM_NO_ERROR;
    CFStringRef identity_cfstr = NULL;
    kim_string identity_string = NULL;

    identity_cfstr = CFDictionaryGetValue (in_dictionary, KIM_IDENTITY_HINT);
    if (!identity_cfstr || CFGetTypeID (identity_cfstr) != CFStringGetTypeID ()) {
        kim_debug_printf ("%s: Malformed hints dictionary (invalid identity).", __FUNCTION__);
        err = check_error (KIM_PREFERENCES_READ_ERR);
    }

    if (!err) {
        err = kim_os_string_create_from_cfstring (&identity_string, identity_cfstr);
    }

    if (!err) {
        err = kim_identity_create_from_string (out_identity, identity_string);
    }

    kim_string_free (&identity_string);

    return check_error (err);
}
static kim_boolean kim_os_selection_hints_compare_hint (kim_string  in_string,
                                                        CFStringRef in_value)
{
    kim_boolean equal = 0;

    if (!in_string && !in_value) {
        equal = 1;

    } else if (in_string && in_value) {
        if (CFGetTypeID (in_value) == CFStringGetTypeID ()) {
            kim_comparison comparison;

            kim_error err = kim_os_string_compare_to_cfstring (in_string, in_value,
                                                               &comparison);

            if (!err && kim_comparison_is_equal_to (comparison)) {
                equal = 1;
            }
        } else {
            kim_debug_printf ("%s: Malformed string in hints dictionary.", __FUNCTION__);
        }
    }

    return equal;
}
static kim_error kim_ui_cli_read_string (kim_string   *out_string, 
                                         kim_boolean   in_hide_reply, 
                                         const char   *in_format, ...)
{
    kim_error err = KIM_NO_ERROR;
    krb5_context k5context = NULL;
    krb5_prompt prompts[1];
    char prompt_string [BUFSIZ];
    krb5_data reply_data;
    char reply_string [BUFSIZ];
    
    if (!err && !out_string) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !in_format ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    
    if (!err) {
        err = krb5_init_context (&k5context);
    }
    
    if (!err) {
        unsigned int count;
        va_list args;
        
        va_start (args, in_format);
        count = vsnprintf (prompt_string, sizeof (prompt_string), 
                                  in_format, args);
        va_end (args);
        
        if (count > sizeof (prompt_string)) {
            kim_debug_printf ("%s(): WARNING! Prompt should be %d characters\n", 
                              __FUNCTION__, count);
            prompt_string [sizeof (prompt_string) - 1] = '\0';
        }
    }
    
    if (!err) {
        /* Build the prompt structures */
        prompts[0].prompt        = prompt_string;
        prompts[0].hidden        = in_hide_reply;
        prompts[0].reply         = &reply_data;
        prompts[0].reply->data   = reply_string;
        prompts[0].reply->length = sizeof (reply_string);
        
        err = krb5_prompter_posix (k5context, NULL, NULL, NULL, 1, prompts);
        if (err == KRB5_LIBOS_PWDINTR || err == KRB5_LIBOS_CANTREADPWD) { 
            err = check_error (KIM_USER_CANCELED_ERR); 
        }
    }
    
    if (!err) {
        err = kim_string_create_from_buffer (out_string, 
                                             prompts[0].reply->data, 
                                             prompts[0].reply->length);
    }
    
    if (k5context) { krb5_free_context (k5context); }
    
    return check_error (err);
}
kim_error kim_os_selection_hints_forget_identity (kim_selection_hints in_selection_hints)
{
    kim_error err = KIM_NO_ERROR;
    CFArrayRef old_hints_array = NULL;
    CFMutableArrayRef new_hints_array = NULL;
    CFIndex count = 0;
    CFIndex i = 0;

    if (!err && !in_selection_hints) { err = check_error (KIM_NULL_PARAMETER_ERR); }

    if (!err) {
        err = kim_os_selection_hints_get_selection_hints_array (&old_hints_array);
    }

    if (!err) {
        new_hints_array = CFArrayCreateMutableCopy (kCFAllocatorDefault, 0,
                                                    old_hints_array);
        if (!new_hints_array) { err = KIM_OUT_OF_MEMORY_ERR; }
    }

    if (!err) {
        count = CFArrayGetCount (new_hints_array);
    }

    for (i = 0; !err && i < count; i++) {
        CFDictionaryRef dictionary = NULL;
        kim_boolean hints_equal = 0;

        dictionary = CFArrayGetValueAtIndex (new_hints_array, i);
        if (!dictionary) { err = KIM_OUT_OF_MEMORY_ERR; }

        if (!err && CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) {
            kim_debug_printf ("%s: Malformed entry in hints array.", __FUNCTION__);
            continue; /* skip entries which aren't dictionaries */
        }

        if (!err) {
            err = kim_os_selection_hints_compare_to_dictionary (in_selection_hints,
                                                                dictionary,
                                                                &hints_equal);
        }

        if (!err && hints_equal) {
            CFArrayRemoveValueAtIndex (new_hints_array, i);
            i--; /* back up one index so we don't skip */
            count = CFArrayGetCount (new_hints_array); /* count changed */
        }
    }

    if (!err) {
        err = kim_os_selection_hints_set_selection_hints_array (new_hints_array);
    }

    if (new_hints_array) { CFRelease (new_hints_array); }

    return check_error (err);
}
kim_error kim_os_selection_hints_lookup_identity (kim_selection_hints  in_selection_hints,
                                                  kim_identity        *out_identity)
{
    kim_error err = KIM_NO_ERROR;
    CFArrayRef hints_array = NULL;
    CFIndex i = 0;
    CFIndex count = 0;
    kim_boolean found = 0;
    CFDictionaryRef found_dictionary = NULL;

    if (!err && !in_selection_hints) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !out_identity      ) { err = check_error (KIM_NULL_PARAMETER_ERR); }

    if (!err) {
        err = kim_os_selection_hints_get_selection_hints_array (&hints_array);
    }

    if (!err && hints_array) {
        count = CFArrayGetCount (hints_array);
    }

    for (i = 0; !err && !found && i < count; i++) {
        CFDictionaryRef dictionary = NULL;

        dictionary = CFArrayGetValueAtIndex (hints_array, i);
        if (!dictionary) { err = KIM_OUT_OF_MEMORY_ERR; }

        if (!err && CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) {
            kim_debug_printf ("%s: Malformed entry in hints array.", __FUNCTION__);
            continue; /* skip entries which aren't dictionaries */
        }

        if (!err) {
            err = kim_os_selection_hints_compare_to_dictionary (in_selection_hints,
                                                                dictionary,
                                                                &found);
        }

        if (!err && found) {
            found_dictionary = dictionary;
        }
    }

    if (!err && found) {
        err = kim_os_selection_hints_get_dictionary_identity (found_dictionary,
                                                              out_identity);
    }

    if (hints_array) { CFRelease (hints_array); }

    return check_error (err);
}
Exemple #7
0
kim_error _check_error (kim_error  in_err,
                        kim_string in_function,
                        kim_string in_file,
                        int        in_line)
{
    if (in_err) {
        kim_debug_printf ("%s(): got %d ('%s') at %s: %d",
                          in_function, in_err, kim_error_message (in_err),
                          in_file, in_line);
    }

    return in_err;
}
Exemple #8
0
krb5_error_code kim_ui_prompter (krb5_context  in_krb5_context,
                                 void         *in_context,
                                 const char   *in_name,
                                 const char   *in_banner,
                                 int           in_num_prompts,
                                 krb5_prompt   in_prompts[])
{
    kim_error err = KIM_NO_ERROR;
    krb5_prompt_type *types = NULL;
    kim_ui_context *context = (kim_ui_context *) in_context;
    int i;

    if (!err && !in_krb5_context) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !in_context     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !in_prompts     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }

    if (!err) {
        types = krb5_get_prompt_types (in_krb5_context);
        if (!types) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    }

    for (i = 0; !err && i < in_num_prompts; i++) {
        char *reply = NULL;
        kim_prompt_type type = kim_ui_ptype2ktype (types[i]);
        kim_boolean got_saved_password = 0;

        if (type == kim_prompt_type_password) {
            /* Check for saved password on OSes that support it */
            kim_error terr = KIM_NO_ERROR;

            terr = kim_os_identity_get_saved_password (context->identity,
                                                       (kim_string *) &reply);
            if (!terr && reply) { got_saved_password = 1; }
        }

        if (!got_saved_password) {
            kim_boolean save_reply = FALSE;
            kim_boolean allow_save_password = kim_os_identity_allow_save_password ();

            context->prompt_count++;

            err = kim_ui_init_lazy (in_context);

            if (!err) {
                if (context->type == kim_ui_type_gui_plugin) {
                    err = kim_ui_plugin_auth_prompt (context,
                                                     context->identity,
                                                     type,
                                                     allow_save_password,
                                                     in_prompts[i].hidden,
                                                     in_name,
                                                     in_banner,
                                                     in_prompts[i].prompt,
                                                     &reply,
                                                     &save_reply);

#ifdef KIM_BUILTIN_UI
                } else if (context->type == kim_ui_type_gui_builtin) {
                    err = kim_os_ui_gui_auth_prompt (context,
                                                     context->identity,
                                                     type,
                                                     allow_save_password,
                                                     in_prompts[i].hidden,
                                                     in_name,
                                                     in_banner,
                                                     in_prompts[i].prompt,
                                                     &reply,
                                                     &save_reply);

                } else if (context->type == kim_ui_type_cli) {
                    err = kim_ui_cli_auth_prompt (context,
                                                  context->identity,
                                                  type,
                                                  allow_save_password,
                                                  in_prompts[i].hidden,
                                                  in_name,
                                                  in_banner,
                                                  in_prompts[i].prompt,
                                                  &reply,
                                                  &save_reply);
#endif /* KIM_BUILTIN_UI */

                } else {
                    err = check_error (KIM_NO_UI_ERR);
                }
            }

            if (!err && type == kim_prompt_type_password) {
                kim_string_free (&context->password_to_save);

                if (allow_save_password && save_reply) {
                    err = kim_string_copy (&context->password_to_save, reply);
                }
            }
        }

        if (!err) {
            uint32_t reply_len = strlen (reply);

            if ((reply_len + 1) > in_prompts[i].reply->length) {
                kim_debug_printf ("%s(): reply %d is too long (is %d, should be %d)\n",
                                  __FUNCTION__, i,
                                  reply_len, in_prompts[i].reply->length);
                reply_len = in_prompts[i].reply->length;
            }

            memmove (in_prompts[i].reply->data, reply, reply_len + 1);
            in_prompts[i].reply->length = reply_len;
        }

        /* Clean up reply buffer.  Saved passwords are allocated by KIM. */
        if (reply) {
           if (got_saved_password) {
               memset (reply, '\0', strlen (reply));
               kim_string_free ((kim_string *) &reply);
             } else {
                kim_ui_free_string (context, &reply);
            }
        }
    }

    return check_error (err);
}
kim_error kim_os_selection_hints_remember_identity (kim_selection_hints in_selection_hints,
                                                    kim_identity        in_identity)
{
    kim_error err = KIM_NO_ERROR;
    CFArrayRef old_hints_array = NULL;
    CFMutableArrayRef new_hints_array = NULL;
    CFIndex count = 0;
    CFIndex i = 0;
    kim_boolean hint_already_exists = 0;
    kim_boolean hints_array_changed = 0;

    if (!err && !in_selection_hints) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !in_identity       ) { err = check_error (KIM_NULL_PARAMETER_ERR); }

    if (!err) {
        err = kim_os_selection_hints_get_selection_hints_array (&old_hints_array);
    }

    if (!err) {
        if (old_hints_array) {
            new_hints_array = CFArrayCreateMutableCopy (kCFAllocatorDefault, 0,
                                                        old_hints_array);
        } else {
            new_hints_array = CFArrayCreateMutable (kCFAllocatorDefault, 0,
                                                    &kCFTypeArrayCallBacks);
        }
        if (!new_hints_array) { err = KIM_OUT_OF_MEMORY_ERR; }
    }

    if (!err) {
        count = CFArrayGetCount (new_hints_array);
    }

    for (i = 0; !err && i < count; i++) {
        CFDictionaryRef dictionary = NULL;
        kim_identity identity = NULL;
        kim_boolean hints_equal = 0;

        dictionary = CFArrayGetValueAtIndex (new_hints_array, i);
        if (!dictionary) { err = KIM_OUT_OF_MEMORY_ERR; }

        if (!err && CFGetTypeID (dictionary) != CFDictionaryGetTypeID ()) {
            kim_debug_printf ("%s: Malformed entry in hints array.", __FUNCTION__);
            continue; /* skip entries which aren't dictionaries */
        }

        if (!err) {
            err = kim_os_selection_hints_compare_to_dictionary (in_selection_hints,
                                                                dictionary,
                                                                &hints_equal);
        }

        if (!err && hints_equal) {
            kim_comparison comparison;

            err = kim_os_selection_hints_get_dictionary_identity (dictionary,
                                                                  &identity);

            if (!err) {
                err = kim_identity_compare (in_identity, identity, &comparison);
            }

            if (!err) {
                if (kim_comparison_is_equal_to (comparison) && !hint_already_exists) {
                    hint_already_exists = 1;
                } else {
                    CFArrayRemoveValueAtIndex (new_hints_array, i);
                    i--; /* back up one index so we don't skip */
                    count = CFArrayGetCount (new_hints_array); /* count changed */
                    hints_array_changed = 1;
                }
            }

            kim_identity_free (&identity);
        }
    }

    if (!err && !hint_already_exists) {
        CFDictionaryRef new_hint_dictionary = NULL;

        err = kim_os_selection_hints_create_dictionary (in_selection_hints,
                                                        in_identity,
                                                        &new_hint_dictionary);

        if (!err) {
            CFArrayInsertValueAtIndex (new_hints_array, 0, new_hint_dictionary);
            hints_array_changed = 1;
        }

        if (new_hint_dictionary) { CFRelease (new_hint_dictionary); }
    }

    if (!err && hints_array_changed) {
        err = kim_os_selection_hints_set_selection_hints_array (new_hints_array);
    }

    if (new_hints_array ) { CFRelease (new_hints_array); }
    if (old_hints_array ) { CFRelease (old_hints_array); }

    return check_error (err);
}