Example #1
0
static void CheckOSStatusOrRaise(OSStatus err){
  if(err != 0){
    CFStringRef description = SecCopyErrorMessageString(err, NULL);

    CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(description), kCFStringEncodingUTF8);
    char *buffer = malloc(bufferSize + 1);
    CFStringGetCString(description, buffer, bufferSize + 1, kCFStringEncodingUTF8);
    CFRelease(description);

    VALUE exceptionString = rb_enc_str_new(buffer, strlen(buffer), rb_utf8_encoding());
    free(buffer);
    VALUE exception = Qnil;

    switch(err){
      case errSecAuthFailed:
        exception = rb_obj_alloc(rb_eKeychainAuthFailedError);
        break;
      case errSecNoSuchKeychain:
        exception = rb_obj_alloc(rb_eKeychainNoSuchKeychainError);
        break;
      case errSecDuplicateItem:
        exception = rb_obj_alloc(rb_eKeychainDuplicateItemError);
        break;
      default:
        exception = rb_obj_alloc(rb_eKeychainError);
    }
    rb_funcall(exception, rb_intern("initialize"), 2,exceptionString, INT2FIX(err));
    rb_exc_raise(exception);
  }
}
char *get_error(OSStatus status) {
    char *buf = malloc(128);
    CFStringRef str = SecCopyErrorMessageString(status, NULL);
    int success = CFStringGetCString(str, buf, 128, kCFStringEncodingUTF8);
    if (success) {
        strncpy(buf, "Unknown error", 128);
    }
    return buf;
}
/* Shorthand for throwing an OSXKeychainException from an OSStatus.
 *
 * Parameters:
 *	env		The JNI environment.
 *	status	The non-error status returned from a keychain call.
 */
void throw_osxkeychainexception(JNIEnv* env, OSStatus status) {
	CFStringRef errorMessage = SecCopyErrorMessageString(status, NULL);
	throw_exception(
		env,
		OSXKeychainException,
		CFStringGetCStringPtr(errorMessage, kCFStringEncodingMacRoman)
	);
	CFRelease(errorMessage);
}
Example #4
0
void gnc_keyring_set_password (const gchar *access_method,
                               const gchar *server,
                               guint32 port,
                               const gchar *service,
                               const gchar *user,
                               const gchar* password)
{

#ifdef HAVE_GNOME_KEYRING
    GnomeKeyringResult  gkr_result;
    guint32 item_id = 0;

    gkr_result = gnome_keyring_set_network_password_sync
                 (NULL, user, NULL, server, service,
                  access_method, NULL, port, password, &item_id);

    if (gkr_result != GNOME_KEYRING_RESULT_OK)
    {
        PWARN ("Gnome-keyring error: %s",
               gnome_keyring_result_to_message(gkr_result));
        PWARN ("The user will be prompted for a password again next time.");
    }
#endif /* HAVE_GNOME_KEYRING */
#ifdef HAVE_OSX_KEYCHAIN
    OSStatus status;
    SecKeychainItemRef *itemRef = NULL;

    /* mysql and postgres aren't valid protocols on Mac OS X.
     * So we use the security domain parameter to allow us to
     * distinguish between these two.
     */
    // FIXME I'm not sure this works if a password was already in the keychain
    //       I may have to do a lookup first and if it exists, run some update
    //       update function instead
    status = SecKeychainAddInternetPassword ( NULL, /* keychain */
             strlen(server), server,                /* servername */
             strlen(access_method), access_method,  /* securitydomain */
             strlen(user), user,                    /* acountname */
             strlen(service), service,              /* path */
             port,                                  /* port */
             kSecProtocolTypeAny,                   /* protocol */
             kSecAuthenticationTypeDefault,         /* auth type */
             strlen(password), password,            /* passworddata */
             itemRef );

    if ( status != noErr )
    {
        CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
        const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
                                    GetApplicationTextEncoding());
        PWARN ( "OS X keychain error: %s", resultstring );
        PWARN ( "The user will be prompted for a password again next time." );
        CFRelease ( osx_resultstring );
    }
#endif /* HAVE_OSX_KEYCHAIN */
}
Example #5
0
CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
    /* OS X creates a completely different structure with one dictionary for each certificate */
    CFIndex ix, count = SecTrustGetCertificateCount(trust);

    CFMutableArrayRef properties = CFArrayCreateMutable(kCFAllocatorDefault, count,
                                                        &kCFTypeArrayCallBacks);

    for (ix = 0; ix < count; ix++) {
        CFMutableDictionaryRef certDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
                                                                    &kCFTypeDictionaryValueCallBacks);
        /* Populate the certificate title */
        SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, ix);
        if (cert) {
            CFStringRef subjectSummary = SecCertificateCopySubjectSummary(cert);
            if (subjectSummary) {
                CFDictionaryAddValue(certDict, kSecPropertyTypeTitle, subjectSummary);
                CFRelease(subjectSummary);
            }
        }

        /* Populate a revocation reason if the cert was revoked */
        unsigned int numStatusCodes;
        CSSM_RETURN *statusCodes = NULL;
        statusCodes = copyCssmStatusCodes(trust, (uint32_t)ix, &numStatusCodes);
        if (statusCodes) {
            int32_t reason = statusCodes[numStatusCodes];  // stored at end of status codes array
            if (reason > 0) {
                CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason);
                if (cfreason) {
                    CFDictionarySetValue(certDict, kSecTrustRevocationReason, cfreason);
                    CFRelease(cfreason);
                }
            }
            free(statusCodes);
        }

        /* Populate the error in the leaf dictionary */
        if (ix == 0) {
            OSStatus error = errSecSuccess;
            (void)SecTrustGetCssmResultCode(trust, &error);
            CFStringRef errorStr = SecCopyErrorMessageString(error, NULL);
            if (errorStr) {
                CFDictionarySetValue(certDict, kSecPropertyTypeError, errorStr);
                CFRelease(errorStr);
            }
        }

        CFArrayAppendValue(properties, certDict);
        CFRelease(certDict);
    }

    return properties;
}
void printErrorStatusMsg(const char *func, OSStatus status)
{
  CFStringRef error;
  error = SecCopyErrorMessageString(status, NULL);
  if (error)
    {
      warnx("%s failed: %s", func, CFStringGetCStringPtr(error, kCFStringEncodingUTF8));
      CFRelease(error);
    }
  else
    warnx("%s failed: %X", func, (int)status);
}
Example #7
0
static int chk_status(OSStatus status, const char *msg) {
    if (status != errSecSuccess) {
        CFStringRef rs = SecCopyErrorMessageString(status, 0);
        if (rs) {
            if (CFStringGetCString(rs, buf, sizeof(buf), kCFStringEncodingUTF8)) {
                CFRelease(rs);
                Rf_error("Unable to %s password: %s", msg, buf);
            }
            CFRelease(rs);
        }
        Rf_error("Unable to %s password, system error code %d", msg, (int)status);
        return 1;
    }
    return 0;
}
bool
mongoc_stream_tls_secure_transport_handshake (mongoc_stream_t *stream,
                                              const char *host,
                                              int *events,
                                              bson_error_t *error)
{
   OSStatus ret = 0;
   CFStringRef err;
   char *err_str;
   mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream;
   mongoc_stream_tls_secure_transport_t *secure_transport =
      (mongoc_stream_tls_secure_transport_t *) tls->ctx;

   ENTRY;
   BSON_ASSERT (secure_transport);

   ret = SSLHandshake (secure_transport->ssl_ctx_ref);
   /* Weak certificate validation requested, eg: none */

   if (ret == errSSLServerAuthCompleted) {
      ret = errSSLWouldBlock;
   }

   if (ret == noErr) {
      RETURN (true);
   }

   if (ret == errSSLWouldBlock) {
      *events = POLLIN | POLLOUT;
   } else {
      *events = 0;
      err = SecCopyErrorMessageString (ret, NULL);
      err_str = _mongoc_cfstringref_to_cstring (err);
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "TLS handshake failed: %s (%d)",
                      err_str,
                      ret);

      bson_free (err_str);
      CFRelease (err);
   }

   RETURN (false);
}
Example #9
0
int stransport_error(OSStatus ret)
{
	CFStringRef message;

	if (ret == noErr || ret == errSSLClosedGraceful) {
		giterr_clear();
		return 0;
	}

#if !TARGET_OS_IPHONE
	message = SecCopyErrorMessageString(ret, NULL);
	GITERR_CHECK_ALLOC(message);

	giterr_set(GITERR_NET, "SecureTransport error: %s", CFStringGetCStringPtr(message, kCFStringEncodingUTF8));
	CFRelease(message);
#else
    giterr_set(GITERR_NET, "SecureTransport error: OSStatus %d", (unsigned int)ret);
#endif

	return -1;
}
Example #10
0
gboolean gnc_keyring_get_password ( GtkWidget *parent,
                                    const gchar *access_method,
                                    const gchar *server,
                                    guint32 port,
                                    const gchar *service,
                                    gchar **user,
                                    gchar **password)
{
    gboolean password_found = FALSE;
#ifdef HAVE_GNOME_KEYRING
    GnomeKeyringResult  gkr_result;
    GList *found_list = NULL;
    GnomeKeyringNetworkPasswordData *found;
#endif
#ifdef HAVE_OSX_KEYCHAIN
    void *password_data;
    UInt32 password_length;
    OSStatus status;
#endif

    g_return_val_if_fail (user != NULL, FALSE);
    g_return_val_if_fail (password != NULL, FALSE);

    *password = NULL;

#ifdef HAVE_GNOME_KEYRING
    gkr_result = gnome_keyring_find_network_password_sync
                 ( *user, NULL, server, service,
                   access_method, NULL, port, &found_list );

    if (gkr_result == GNOME_KEYRING_RESULT_OK)
    {
        found = (GnomeKeyringNetworkPasswordData *) found_list->data;
        if (found->password)
            *password = g_strdup(found->password);
        password_found = TRUE;
    }
    else
        PWARN ("Gnome-keyring access failed: %s.",
               gnome_keyring_result_to_message(gkr_result));

    gnome_keyring_network_password_list_free(found_list);
#endif /* HAVE_GNOME_KEYRING */

#ifdef HAVE_OSX_KEYCHAIN
    /* mysql and postgres aren't valid protocols on Mac OS X.
     * So we use the security domain parameter to allow us to
     * distinguish between these two.
     */
    if (*user != NULL)
    {
        status = SecKeychainFindInternetPassword( NULL,
                 strlen(server), server,
                 strlen(access_method), access_method,
                 strlen(*user), *user,
                 strlen(service), service,
                 port,
                 kSecProtocolTypeAny,
                 kSecAuthenticationTypeDefault,
                 &password_length, &password_data,
                 NULL);

        if ( status == noErr )
        {
            *password = g_strndup(password_data, password_length);
            password_found = TRUE;
            SecKeychainItemFreeContent(NULL, password_data);
        }
        else
        {
            CFStringRef osx_resultstring = SecCopyErrorMessageString( status, NULL );
            const gchar *resultstring = CFStringGetCStringPtr(osx_resultstring,
                                        GetApplicationTextEncoding());
            PWARN ( "OS X keychain error: %s", resultstring );
            CFRelease ( osx_resultstring );
        }
    }
#endif /* HAVE_OSX_KEYCHAIN */

    if ( !password_found )
    {
        /* If we got here, either no proper password store is
         * available on this system, or we couldn't retrieve
         * a password from it. In both cases, just ask the user
         * to enter one
         */
        gchar *db_path, *heading;

        if ( port == 0 )
            db_path = g_strdup_printf ( "%s://%s/%s", access_method, server, service );
        else
            db_path = g_strdup_printf ( "%s://%s:%d/%s", access_method, server, port, service );
        heading = g_strdup_printf ( /* Translators: %s is a path to a database or any other url,
                 like mysql://[email protected]/somedb, http://www.somequotes.com/thequotes */
                      _("Enter a user name and password to connect to: %s"),
                      db_path );

        password_found = gnc_get_username_password ( parent, heading,
                         *user, NULL,
                         user, password );
        g_free ( db_path );
        g_free ( heading );

        if ( password_found )
        {
            /* User entered new user/password information
             * Let's try to add it to a password store.
             */
            gchar *newuser = g_strdup( *user );
            gchar *newpassword = g_strdup( *password );
            gnc_keyring_set_password ( access_method,
                                       server,
                                       port,
                                       service,
                                       newuser,
                                       newpassword );
            g_free ( newuser );
            g_free ( newpassword );
        }
    }

    return password_found;
}
Example #11
0
CFStringRef AppleCryptoNative_SecCopyErrorMessageString(int32_t osStatus)
{
    return SecCopyErrorMessageString(osStatus, NULL);
}
Example #12
0
static int importKeychainToX509_STORE(X509_STORE* verifyStore, char* err, size_t err_len) {
    int status = 1;
    CFArrayRef result = NULL;
    OSStatus osStatus;

    // This copies all the certificates trusted by the system (regardless of what
    // keychain they're
    // attached to) into a CFArray.
    if ((osStatus = SecTrustCopyAnchorCertificates(&result)) != 0) {
        CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL);
        snprintf(err,
                 err_len,
                 "Error enumerating certificates: %s",
                 CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
        CFRelease(statusString);
        status = 0;
        goto CLEANUP;
    }

    CFDataRef rawData = NULL;
    X509* x509Cert = NULL;

    for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
        SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(result, i);

        rawData = SecCertificateCopyData(cert);
        if (!rawData) {
            snprintf(err, err_len, "Error enumerating certificates");
            status = 0;
            goto CLEANUP;
        }
        const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData);

        // Parse an openssl X509 object from each returned certificate
        x509Cert = d2i_X509(NULL, &rawDataPtr, CFDataGetLength(rawData));
        if (!x509Cert) {
            snprintf(err,
                     err_len,
                     "Error parsing X509 certificate from system keychain: %s",
                     ERR_reason_error_string(ERR_peek_last_error()));
            status = 0;
            goto CLEANUP;
        }

        // Add the parsed X509 object to the X509_STORE verification store
        if (X509_STORE_add_cert(verifyStore, x509Cert) != 1) {
            int check_error_status = checkX509_STORE_error(err, err_len);
            if (!check_error_status) {
                status = check_error_status;
                goto CLEANUP;
            }
        }
        CFRelease(rawData);
        rawData = NULL;
        X509_free(x509Cert);
        x509Cert = NULL;
    }

CLEANUP:
    if (result != NULL) {
        CFRelease(result);
    }
    if (rawData != NULL) {
        CFRelease(rawData);
    }
    if (x509Cert != NULL) {
        X509_free(x509Cert);
    }
    return status;
}