Skip to content

Commit 625283f

Browse files
committed
✨ Add iscsi stringprep profile
This isn't used by IMAP at all, and never will be. But once the generic StringPrep algorithm is in place, this is trivial to add. So it is added for completeness and to test the stringprep code better.
1 parent 58f562b commit 625283f

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

lib/net/imap/stringprep.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class IMAP < Protocol
99
# codepoint table defined in the RFC-3454 appendices is matched by a Regexp
1010
# defined in this module.
1111
module StringPrep
12+
autoload :ISCSI, File.expand_path("stringprep/iscsi", __dir__)
1213
autoload :NamePrep, File.expand_path("stringprep/nameprep", __dir__)
1314
autoload :SASLprep, File.expand_path("stringprep/saslprep", __dir__)
1415
autoload :Tables, File.expand_path("stringprep/tables", __dir__)

lib/net/imap/stringprep/iscsi.rb

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# frozen_string_literal: true
2+
3+
module Net
4+
class IMAP
5+
module StringPrep
6+
7+
# Defined in RFC3722[https://tools.ietf.org/html/rfc3722], the +iSCSI+
8+
# profile of "Stringprep" is used to:
9+
# >>>
10+
# prepare internationalized iSCSI names to increase the likelihood that
11+
# name input and comparison work in ways that make sense for typical
12+
# users throughout the world.
13+
#
14+
# ...
15+
#
16+
# The goal, then, is to generate iSCSI names that can be transcribed and
17+
# entered by users, and also compared byte-for-byte, with minimal
18+
# confusion. To attain these goals, iSCSI names are generalized using a
19+
# normalized character set (converted to lower case or equivalent), with
20+
# no white space allowed, and very limited punctuation.
21+
#
22+
# - The intended applicability of the profile: internationalized iSCSI
23+
# names.
24+
# - The character repertoire that is the input and output to
25+
# stringprep: Unicode 3.2, specified in section 3.
26+
# - The mappings used: specified in section 4.
27+
# - The Unicode normalization used: specified in section 5.
28+
# - The characters that are prohibited as output: specified in section 6.
29+
#
30+
# This profile MUST be used with the iSCSI protocol.
31+
module ISCSI
32+
33+
STRINGPREP_PROFILE = "iSCSI"
34+
35+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §2
36+
UNASSIGNED_TABLE = "A.1"
37+
38+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §3
39+
MAPPING_TABLES = %w[B.1 B.2].freeze
40+
41+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §5
42+
NORMALIZATION = :nfkc
43+
44+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §6
45+
PROHIBITED_TABLES = %w[C.1.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9].freeze
46+
47+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §6.1:
48+
# >>>
49+
# 6.1. Inappropriate Characters from Common Input Mechanisms
50+
#
51+
# u+3002 is used as if it were u+002e in many domain name input
52+
# mechanisms used by applications, particularly in Asia. The character
53+
# u+3002 MUST NOT be used in an iSCSI name.
54+
#
55+
# 3002; ideographic full stop
56+
INAPPROPRIATE_FROM_COMMON_INPUT_MECHANISMS = /\u{3002}/.freeze
57+
58+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §6.2:
59+
# >>>
60+
# 6.2. Currently-prohibited ASCII characters
61+
#
62+
# Some of the ASCII characters that are currently prohibited in iSCSI
63+
# names by [RFC3721] are also used in protocol elements such as URIs.
64+
# Some examples are described in [RFC2396] and [RFC2732]. Note that
65+
# there are many other RFCs that define additional URI schemes.
66+
#
67+
# The other characters in the range U+0000 to U+007F that are not
68+
# currently allowed are prohibited in iSCSI names to reserve them for
69+
# future use in protocol elements. Note that the dash (U+002D), dot
70+
# (U+002E), and colon (U+003A) are not prohibited.
71+
#
72+
# The following characters MUST NOT be used in iSCSI names:
73+
#
74+
# 0000-002C; [ASCII CONTROL CHARACTERS and SPACE through ,]
75+
# 002F; [ASCII /]
76+
# 003B-0040; [ASCII ; through @]
77+
# 005B-0060; [ASCII [ through `]
78+
# 007B-007F; [ASCII { through DEL]
79+
PROHIBITED_ASCII = /[\x00-\x2c\x2f\x3b-\x40\x5b-\x60\x7B-\x7f]/.freeze
80+
81+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §6.2:
82+
# In addition, this profile adds the following prohibitions. The full
83+
# set of prohibited characters are those from the tables above plus
84+
# those listed individually below.
85+
PROHIBITED_REGEXP = [
86+
PROHIBITED_ASCII,
87+
INAPPROPRIATE_FROM_COMMON_INPUT_MECHANISMS,
88+
]
89+
.map(&:source).join
90+
.then { /[#{_1}]/ }
91+
.freeze
92+
93+
# From RFC3722[https://www.rfc-editor.org/rfc/rfc3722.html] §7
94+
CHECK_BIDI = true
95+
96+
module_function
97+
98+
def stringprep_iscsi(string, **opts)
99+
StringPrep.stringprep(
100+
string,
101+
unassigned: UNASSIGNED_TABLE,
102+
maps: MAPPING_TABLES,
103+
prohibited: [*PROHIBITED_TABLES, PROHIBITED_REGEXP],
104+
normalization: NORMALIZATION,
105+
bidi: CHECK_BIDI,
106+
profile: STRINGPREP_PROFILE,
107+
**opts,
108+
)
109+
end
110+
111+
end
112+
113+
end
114+
end
115+
end

test/net/imap/test_stringprep_profiles.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
class StringPrepProfilesTest < Test::Unit::TestCase
77
include Net::IMAP::StringPrep
88
include Net::IMAP::StringPrep::Trace
9+
include Net::IMAP::StringPrep::ISCSI
910

1011
def test_trace_profile_prohibit_ctrl_chars
1112
assert_raise(ProhibitedCodepoint) {
@@ -22,4 +23,14 @@ def test_trace_profile_prohibit_tagging_chars
2223
}
2324
end
2425

26+
def test_iscsi_profile_case_maps
27+
assert_equal "hêllω-woŗλd", stringprep_iscsi("HÊlLΩ-WoŖΛd")
28+
end
29+
30+
def test_iscsi_profile_prohibit_ideographic_full_stop
31+
assert_raise(ProhibitedCodepoint) {
32+
stringprep_iscsi "hello\u{3002}world"
33+
}
34+
end
35+
2536
end

0 commit comments

Comments
 (0)