diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/admin/application_settings_controller.rb | 3 | ||||
-rw-r--r-- | app/helpers/application_settings_helper.rb | 28 | ||||
-rw-r--r-- | app/models/application_setting.rb | 62 | ||||
-rw-r--r-- | app/models/key.rb | 37 | ||||
-rw-r--r-- | app/views/admin/application_settings/_form.html.haml | 42 |
5 files changed, 62 insertions, 110 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 8cc7111033f..8367c22d1ca 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -66,8 +66,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end end - params[:application_setting][:allowed_key_types]&.delete('') - enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources) params[:application_setting][:disabled_oauth_sign_in_sources] = @@ -85,7 +83,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController def visible_application_setting_attributes ApplicationSettingsHelper.visible_attributes + [ :domain_blacklist_file, - allowed_key_types: [], disabled_oauth_sign_in_sources: [], import_sources: [], repository_storages: [], diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 75d090359d0..0c74d464601 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -81,18 +81,16 @@ module ApplicationSettingsHelper end end - def allowed_key_types_checkboxes(help_block_id) - Gitlab::SSHPublicKey.technology_names.map do |type| - checked = current_application_settings.allowed_key_types.include?(type) - checkbox_id = "allowed_key_types-#{type}" - - label_tag(checkbox_id, class: checked ? 'active' : nil) do - check_box_tag('application_setting[allowed_key_types][]', type, checked, - autocomplete: 'off', - 'aria-describedby' => help_block_id, - id: checkbox_id) + type.upcase - end + def key_restriction_options_for_select(type) + bit_size_options = Gitlab::SSHPublicKey.supported_sizes(type).map do |bits| + ["Must be at least #{bits} bits", bits] end + + [ + ['Are allowed', 0], + *bit_size_options, + ['Are forbidden', ApplicationSetting::FORBIDDEN_KEY_VALUE] + ] end def repository_storages_options_for_select @@ -127,6 +125,9 @@ module ApplicationSettingsHelper :domain_blacklist_enabled, :domain_blacklist_raw, :domain_whitelist_raw, + :dsa_key_restriction, + :ecdsa_key_restriction, + :ed25519_key_restriction, :email_author_in_body, :enabled_git_access_protocol, :gravatar_enabled, @@ -155,10 +156,6 @@ module ApplicationSettingsHelper :metrics_port, :metrics_sample_interval, :metrics_timeout, - :minimum_dsa_bits, - :minimum_ecdsa_bits, - :minimum_ed25519_bits, - :minimum_rsa_bits, :password_authentication_enabled, :performance_bar_allowed_group_id, :performance_bar_enabled, @@ -174,6 +171,7 @@ module ApplicationSettingsHelper :repository_storages, :require_two_factor_authentication, :restricted_visibility_levels, + :rsa_key_restriction, :send_user_confirmation_email, :sentry_dsn, :sentry_enabled, diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 988ee4802b9..0f9053262c2 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -13,6 +13,15 @@ class ApplicationSetting < ActiveRecord::Base [\r\n] # any number of newline characters }x + # Setting a key restriction to `-1` means that all keys of this type are + # forbidden. + FORBIDDEN_KEY_VALUE = -1 + SUPPORTED_KEY_TYPES = %i[rsa dsa ecdsa ed25519].freeze + + def self.supported_key_restrictions(type) + [0, *Gitlab::SSHPublicKey.supported_sizes(type), FORBIDDEN_KEY_VALUE] + end + serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize @@ -20,7 +29,6 @@ class ApplicationSetting < ActiveRecord::Base serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiveRecordSerialize - serialize :allowed_key_types, Array # rubocop:disable Cop/ActiveRecordSerialize cache_markdown_field :sign_in_text cache_markdown_field :help_page_text @@ -147,23 +155,11 @@ class ApplicationSetting < ActiveRecord::Base presence: true, numericality: { greater_than_or_equal_to: 0 } - validates :allowed_key_types, presence: true - - validates :minimum_rsa_bits, - presence: true, - inclusion: { in: Gitlab::SSHPublicKey.allowed_sizes('rsa') } - - validates :minimum_dsa_bits, - presence: true, - inclusion: { in: Gitlab::SSHPublicKey.allowed_sizes('dsa') } - - validates :minimum_ecdsa_bits, - presence: true, - inclusion: { in: Gitlab::SSHPublicKey.allowed_sizes('ecdsa') } - - validates :minimum_ed25519_bits, - presence: true, - inclusion: { in: Gitlab::SSHPublicKey.allowed_sizes('ed25519') } + SUPPORTED_KEY_TYPES.each do |type| + validates :"#{type}_key_restriction", + presence: true, + inclusion: { in: ApplicationSetting.supported_key_restrictions(type) } + end validates_each :restricted_visibility_levels do |record, attr, value| value&.each do |level| @@ -189,14 +185,6 @@ class ApplicationSetting < ActiveRecord::Base end end - validates_each :allowed_key_types do |record, attr, value| - value&.each do |type| - unless Gitlab::SSHPublicKey.allowed_type?(type) - record.errors.add(attr, "'#{type}' is not a valid SSH key type") - end - end - end - before_validation :ensure_uuid! before_save :ensure_runners_registration_token @@ -240,7 +228,6 @@ class ApplicationSetting < ActiveRecord::Base { after_sign_up_text: nil, akismet_enabled: false, - allowed_key_types: Gitlab::SSHPublicKey.technology_names, container_registry_token_expire_delay: 5, default_artifacts_expire_in: '30 days', default_branch_protection: Settings.gitlab['default_branch_protection'], @@ -250,6 +237,9 @@ class ApplicationSetting < ActiveRecord::Base default_group_visibility: Settings.gitlab.default_projects_features['visibility_level'], disabled_oauth_sign_in_sources: [], domain_whitelist: Settings.gitlab['domain_whitelist'], + dsa_key_restriction: 0, + ecdsa_key_restriction: 0, + ed25519_key_restriction: 0, gravatar_enabled: Settings.gravatar['enabled'], help_page_text: nil, help_page_hide_commercial_content: false, @@ -268,10 +258,7 @@ class ApplicationSetting < ActiveRecord::Base max_attachment_size: Settings.gitlab['max_attachment_size'], password_authentication_enabled: Settings.gitlab['password_authentication_enabled'], performance_bar_allowed_group_id: nil, - minimum_rsa_bits: 1024, - minimum_dsa_bits: 1024, - minimum_ecdsa_bits: 256, - minimum_ed25519_bits: 256, + rsa_key_restriction: 0, plantuml_enabled: false, plantuml_url: nil, project_export_enabled: true, @@ -446,6 +433,19 @@ class ApplicationSetting < ActiveRecord::Base usage_ping_can_be_configured? && super end + def allowed_key_types + SUPPORTED_KEY_TYPES.select do |type| + key_restriction_for(type) != FORBIDDEN_KEY_VALUE + end + end + + def key_restriction_for(type) + attr_name = "#{type}_key_restriction" + + # rubocop:disable GitlabSecurity/PublicSend + has_attribute?(attr_name) ? public_send(attr_name) : FORBIDDEN_KEY_VALUE + end + private def ensure_uuid! diff --git a/app/models/key.rb b/app/models/key.rb index 27c91679ec9..2334603b58b 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -24,7 +24,7 @@ class Key < ActiveRecord::Base uniqueness: true, presence: { message: 'cannot be generated' } - validate :key_meets_minimum_bit_length, :key_type_is_allowed + validate :key_meets_restrictions delegate :name, :email, to: :user, prefix: true @@ -100,37 +100,24 @@ class Key < ActiveRecord::Base self.fingerprint = public_key.fingerprint end - def key_meets_minimum_bit_length - case public_key.type - when :rsa - if public_key.bits < current_application_settings.minimum_rsa_bits - errors.add(:key, "length must be at least #{current_application_settings.minimum_rsa_bits} bits") - end - when :dsa - if public_key.bits < current_application_settings.minimum_dsa_bits - errors.add(:key, "length must be at least #{current_application_settings.minimum_dsa_bits} bits") - end - when :ecdsa - if public_key.bits < current_application_settings.minimum_ecdsa_bits - errors.add(:key, "elliptic curve size must be at least #{current_application_settings.minimum_ecdsa_bits} bits") - end - when :ed25519 - if public_key.bits < current_application_settings.minimum_ed25519_bits - errors.add(:key, "length must be at least #{current_application_settings.minimum_ed25519_bits} bits") - end + def key_meets_restrictions + restriction = current_application_settings.key_restriction_for(public_key.type) + + if restriction == ApplicationSetting::FORBIDDEN_KEY_VALUE + errors.add(:key, forbidden_key_type_message) + elsif public_key.bits < restriction + errors.add(:key, "must be at least #{restriction} bits") end end - def key_type_is_allowed - unless current_application_settings.allowed_key_types.include?(public_key.type.to_s) - allowed_types = - current_application_settings + def forbidden_key_type_message + allowed_types = + current_application_settings .allowed_key_types .map(&:upcase) .to_sentence(last_word_connector: ', or ', two_words_connector: ' or ') - errors.add(:key, "type is not allowed. Must be #{allowed_types}") - end + "type is forbidden. Must be #{allowed_types}" end def notify_user diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 1cda98ffea8..fd083c03633 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -57,42 +57,12 @@ %span.help-block#clone-protocol-help Allow only the selected protocols to be used for Git access. - .form-group - = f.label :allowed_key_types, 'Allowed SSH keys', class: 'control-label col-sm-2' - .col-sm-10 - = hidden_field_tag 'application_setting[allowed_key_types][]', nil, id: 'allowed_key_types-none' - - allowed_key_types_checkboxes('allowed-key-types-help').each do |key_type_checkbox| - .checkbox= key_type_checkbox - %span.help-block#allowed-key-types-help - Only SSH keys with allowed algorithms can be uploaded. - - .form-group - = f.label :minimum_rsa_bits, 'Minimum RSA key length', class: 'control-label col-sm-2' - .col-sm-10 - = f.select :minimum_rsa_bits, Gitlab::SSHPublicKey.allowed_sizes('rsa'), {}, class: 'form-control' - .help-block - The minimum length for user RSA SSH keys (in bits) - - .form-group - = f.label :minimum_dsa_bits, 'Minimum DSA key length', class: 'control-label col-sm-2' - .col-sm-10 - = f.select :minimum_dsa_bits, Gitlab::SSHPublicKey.allowed_sizes('dsa'), {}, class: 'form-control' - .help-block - The minimum length for user DSA SSH keys (in bits) - - .form-group - = f.label :minimum_ecdsa_bits, 'Minimum ECDSA key length', class: 'control-label col-sm-2' - .col-sm-10 - = f.select :minimum_ecdsa_bits, Gitlab::SSHPublicKey.allowed_sizes('ecdsa'), {}, class: 'form-control' - .help-block - The minimum elliptic curve size for user ECDSA SSH keys (in bits) - - .form-group - = f.label :minimum_ed25519_bits, 'Minimum ED25519 key length', class: 'control-label col-sm-2' - .col-sm-10 - = f.select :minimum_ed25519_bits, Gitlab::SSHPublicKey.allowed_sizes('ed25519'), {}, class: 'form-control' - .help-block - The minimum length for user ED25519 SSH keys (in bits) + - ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type| + - field_name = :"#{type}_key_restriction" + .form-group + = f.label field_name, "#{type.upcase} SSH keys", class: 'control-label col-sm-2' + .col-sm-10 + = f.select field_name, key_restriction_options_for_select(type), {}, class: 'form-control' %fieldset %legend Account and Limit Settings |