Skip to content

Commit

Permalink
Merge pull request #1764 from wayneeseguin/features/osx-ssl-certs
Browse files Browse the repository at this point in the history
add rvm osx-ssl-certs
  • Loading branch information
mpapis committed Apr 9, 2013
2 parents aedb24d + 0285f8f commit 7fe6ada
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 43 deletions.
49 changes: 49 additions & 0 deletions help/osx-ssl-certs.md
@@ -0,0 +1,49 @@
# OSX OpenSSL Certificates handling.

## Synopsis

rvm osx-ssl-certs status [<ruby>|all]
rvm [--silent] osx-ssl-certs update [<ruby>|all]
rvm osx-ssl-certs cron [status|install|uninstall]

## Description

Apple OS X comes with old version of OpenSSL, to keep you secure RVM installs newer version.
RVM also allows specifying custom version of OpenSSL and binary rubies linked to custom locations.
Taken this all into account most likely your Ruby is using outdated certificates.
To solve this problem `rvm osx-ssl-certs` will find all locations for certificates.
You can check status, update certificates manually or schedule an automated update.

## Arguments
`rvm osx-ssl-certs`:

* `status` => Show certificates status for current Ruby,
* `<ruby>` => Status of a specific Ruby certificates,
* `all` => Status of all installed Rubies certificate paths.
* `update` => Update SSL certificates for current Ruby,
* `<ruby>` => Update a specific Ruby certificates,
* `all` => Update all installed Rubies certificate paths.
* `cron` => Manage cron job for daily updates,
* `status` => Show if the cron job is installed,
* `install` => Install the cron job,
* `uninstall` => Uninstall the cron job.

## Examples

Show the status for all installed rubies

rvm osx-ssl-certs status all

Update certificates for current ruby OpenSSL

rvm osx-ssl-certs status all

Schedule daily update of certificates

rvm osx-ssl-certs cron install

## Reporting bugs

Please report issues to https://github.com/wayneeseguin/rvm/issues

In case of security issues use rvm-internal@googlegroups.com
5 changes: 3 additions & 2 deletions scripts/cli
Expand Up @@ -248,7 +248,7 @@ __rvm_parse_args()
rvm_remove_flag=1
;;

rtfm|RTFM|rvmrc|usage|help|inspect|list|ls|info|strings|get|current|docs|alias|rubygems|cleanup|tools|disk-usage|snapshot|repair|migrate|downgrade|upgrade|cron|group|switch|which|config-get|requirements|autolibs)
rtfm|RTFM|rvmrc|usage|help|inspect|list|ls|info|strings|get|current|docs|alias|rubygems|cleanup|tools|disk-usage|snapshot|repair|migrate|downgrade|upgrade|cron|group|switch|which|config-get|requirements|autolibs|osx-ssl-certs)
case "$rvm_token" in
(downgrade) rvm_action="upgrade" ;;
(ls) rvm_action="list" ;;
Expand Down Expand Up @@ -983,7 +983,8 @@ Please do one of the following:
__rvm_run_script "$rvm_action" "${rvm_ruby_args[@]}"
;;

autolibs|upgrade) # file action
autolibs|osx-ssl-certs|upgrade)
# file action params
__rvm_run_wrapper "$rvm_action" "$rvm_action" "${rvm_ruby_args[@]}"
;;

Expand Down
1 change: 1 addition & 0 deletions scripts/functions/build
Expand Up @@ -3,6 +3,7 @@
source "$rvm_scripts_path/functions/autolibs"
source "$rvm_scripts_path/functions/build_config"
source "$rvm_scripts_path/functions/build_requirements"
source "$rvm_scripts_path/functions/osx-ssl-certs"

# show the user selected compiler or return 1
__rvm_selected_compiler()
Expand Down
41 changes: 0 additions & 41 deletions scripts/functions/build_requirements
Expand Up @@ -31,47 +31,6 @@ rvm_requiremnts_fail_or_run_action()
true # for osx
}

requirements_osx_update_openssl_cert_old() [[ "$cert_file" -ot /Library/Keychains/System.keychain ||
"$cert_file" -ot /System/Library/Keychains/SystemRootCertificates.keychain
]]

requirements_osx_update_openssl_cert_run()
{
rvm_log "Updating certificates in '$cert_file'."
mkdir -p "$ssl_dir"
security find-certificate -a -p /Library/Keychains/System.keychain > "$cert_file"
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$cert_file"
"${ssl_binary%/openssl}/c_rehash" "$ssl_dir"
}

requirements_osx_update_openssl_cert()
{
[[ "Darwin" == "$(uname)" ]] || return 0

case "${rvm_autolibs_flag_number}" in
(0)
rvm_debug "Skipping update of certificates in '$cert_file'."
return 0
;;
esac

typeset ssl_binary ssl_dir cert_file
ssl_binary="${1:-$(which openssl)}"
ssl_dir="$( "${ssl_binary}" version -d | awk -F'"' '{print $2}' )" #' fix formating
cert_file="${ssl_dir}/cert.pem"

if
requirements_osx_update_openssl_cert_old
then
rvm_requiremnts_fail_or_run_action 2 \
"Skipping update of certificates in '$cert_file'." \
requirements_osx_update_openssl_cert_run ||
return $?
else
rvm_log "Certificates in '$cert_file' already are up to date."
fi
}

__rvm_requirements_load()
{
if
Expand Down
117 changes: 117 additions & 0 deletions scripts/functions/osx-ssl-certs
@@ -0,0 +1,117 @@
#!/usr/bin/env bash

requirements_osx_update_openssl_cert_old() [[ "$cert_file" -ot /Library/Keychains/System.keychain ||
"$cert_file" -ot /System/Library/Keychains/SystemRootCertificates.keychain
]]

requirements_osx_update_openssl_cert_run()
{
rvm_log "Updating certificates in '$cert_file'."
mkdir -p "$ssl_dir"
security find-certificate -a -p /Library/Keychains/System.keychain > "$cert_file"
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$cert_file"
}

requirements_osx_update_openssl_cert()
{
[[ "Darwin" == "$(uname)" ]] || return 0

case "${rvm_autolibs_flag_number}" in
(0)
rvm_debug "Skipping update of certificates in '$cert_file'."
return 0
;;
esac

typeset ssl_binary ssl_dir cert_file
ssl_binary="${1:-$(which openssl)}"
cert_file="$( __rvm_osx_ssl_certs_file_from_openssl "${ssl_binary}" )"
ssl_dir="${cert_file%/*}"

if
requirements_osx_update_openssl_cert_old
then
rvm_requiremnts_fail_or_run_action 2 \
"Skipping update of certificates in '$cert_file'." \
requirements_osx_update_openssl_cert_run ||
return $?
else
rvm_log "Certificates in '$cert_file' already are up to date."
fi
}

__rvm_osx_ssl_certs_update_for_path()
{
typeset ssl_dir cert_file
cert_file="$( __rvm_osx_ssl_certs_file_for_ruby )"
ssl_dir="${cert_file%/*}"

if (( ${rvm_silent_flag:-0} == 0 ))
then printf "%b" "Updating certificates for ${cert_file}: "
fi
if
requirements_osx_update_openssl_cert_old
then
if
requirements_osx_update_openssl_cert_run
then
if (( ${rvm_silent_flag:-0} == 0 ))
then printf "%b" "Updated.\n"
fi
else
typeset result=$?
if (( ${rvm_silent_flag:-0} == 0 ))
then printf "%b" "Failed.\n"
else printf "%b" "Updating certificates for ${cert_file}: Failed.\n"
fi
return $result
fi
else
if (( ${rvm_silent_flag:-0} == 0 ))
then printf "%b" "Already are up to date.\n"
fi
fi
}

__rvm_osx_ssl_certs_status_for_path()
{
typeset ssl_dir cert_file
cert_file="$1"
ssl_dir="${cert_file%/*}"

printf "%b" "Certificates for ${cert_file}: "
if requirements_osx_update_openssl_cert_old
then printf "%b" "Old.\n"
else printf "%b" "Up to date.\n"
fi
}

__rvm_osx_ssl_certs_file_for_ruby()
{
"${1:-ruby}" -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE'
}

__rvm_osx_ssl_certs_file_from_openssl()
{
"${1:-openssl}" version -d | awk -F'"' '{print $2"/cert.pem"}'
}

__rvm_cron_find()
{
EDITOR=\cat crontab -e 2>/dev/null | GREP_OPTIONS="" \grep "$1" >/dev/null || return $?
}

__rvm_cron_uninstall()
{
EDITOR=\cat crontab -e 2>/dev/null | GREP_OPTIONS="" \grep -v "$1" | crontab -
}

__rvm_cron_install()
{
{
EDITOR=\cat crontab -e 2>/dev/null
echo "@daily $1"
} | crontab -
}

export RVM_OSX_SSL_UPDATER="$rvm_path/bin/rvm --silent osx-ssl-certs update all"
149 changes: 149 additions & 0 deletions scripts/osx-ssl-certs
@@ -0,0 +1,149 @@
#!/usr/bin/env bash

source "$rvm_scripts_path/functions/osx-ssl-certs"

__rvm_osx_ssl_certs_run_select_rubies()
{
case "$2" in
(all)
__rvm_read_lines __rubies < <(
__rvm_cd "$rvm_rubies_path"
find . -maxdepth 1 -mindepth 1 -type d 2>/dev/null | cut -c 3-
)
;;
(*,*)
__rvm_custom_separated_array __rubies , "$2"
;;
("")
__rubies=( "${GEM_HOME##*/}" )
;;
(*)
__rubies=( "$2" )
;;
esac
}

__rvm_osx_ssl_certs_run_filter_and_run()
{
for __ruby in "${__rubies[@]}"
do
rvm_debug "${__ruby} # getting cert file"
__path="$( __rvm_with "${__ruby}" "__rvm_osx_ssl_certs_file_for_ruby" )"
[[ " ${__paths[*]} " =~ " ${__path} " ]] || __paths+=( "${__path}" )
done

for __path in "${__paths[@]}"
do
rvm_debug "${__path} # updating certs"
"$1" "${__path}"
done
}

__rvm_osx_ssl_certs_run()
{
typeset __ruby __path
typeset -a __rubies __paths
__rubies=()
__paths=()

__rvm_osx_ssl_certs_run_select_rubies "$@"
__rvm_osx_ssl_certs_run_filter_and_run "$@"
}

__rvm_osx_ssl_certs_status()
{
__rvm_osx_ssl_certs_run __rvm_osx_ssl_certs_status_for_path "$1"
}

__rvm_osx_ssl_certs_update()
{
__rvm_osx_ssl_certs_run __rvm_osx_ssl_certs_update_for_path "$1"
}

__rvm_osx_ssl_certs_cron_status()
{
if __rvm_cron_find "$RVM_OSX_SSL_UPDATER"
then rvm_log "Automatic certs updating installed."
else rvm_warn "Automatic certs updating not installed."
fi
}

__rvm_osx_ssl_certs_cron_install()
{
if
__rvm_cron_find "$RVM_OSX_SSL_UPDATER"
then
__rvm_cron_uninstall "$RVM_OSX_SSL_UPDATER" ||
{
typeset result=$?
rvm_error "Automatic certs updating failed uninstalling."
return $result
}
fi
if
__rvm_cron_install "$RVM_OSX_SSL_UPDATER"
then
rvm_log "Automatic certs updating installed."
else
typeset result=$?
rvm_error "Automatic certs updating failed installing."
return $result
fi
}

__rvm_osx_ssl_certs_cron_uninstall()
{
if
__rvm_cron_find "$RVM_OSX_SSL_UPDATER"
then
if
__rvm_cron_uninstall "$RVM_OSX_SSL_UPDATER"
then
rvm_log "Automatic certs updating uninstalled."
else
typeset result=$?
rvm_error "Automatic certs updating failed uninstalling."
return $result
fi
else
rvm_log "Automatic certs updating already uninstalled."
fi
}

__rvm_osx_ssl_certs_cron()
{
typeset cron_action="${1:-status}"
shift 1
case "${cron_action}" in
(status|install|uninstall)
__rvm_osx_ssl_certs_cron_${cron_action}
;;
(help)
rvm_help osx-ssl-certs cron "$@"
;;
(*)
rvm_error_help "Unknown subcommand '$*' for osx-ssl-certs cron" osx-ssl-certs cron "$@"
return 1
;;
esac
}

__rvm_osx_ssl_certs()
{
typeset action="${1:-status}"
shift 1
case "${action}" in
(status|update|cron)
__rvm_osx_ssl_certs_${action} "$@"
;;
(help)
rvm_help osx-ssl-certs "$@"
;;
(*)
rvm_error_help "Unknown subcommand '$*' for osx-ssl-certs" osx-ssl-certs "$@"
return 1
;;
esac
}

__rvm_osx_ssl_certs "${args[@]}"

0 comments on commit 7fe6ada

Please sign in to comment.