module Net::IMAP::SASL::GS2Header

def gs2_authzid

If +#authzid+ is empty or +nil+, an empty string is returned.

+gs2-authzid+ header, when +#authzid+ is not empty.
The {RFC5801 §4}[https://www.rfc-editor.org/rfc/rfc5801#section-4]
def gs2_authzid
  return "" if authzid.nil? || authzid == ""
  "a=#{gs2_saslname_encode(authzid)}"
end

def gs2_cb_flag; "n" end


binding must override this method.
The default always returns "+n+". A mechanism that supports channel

The selected channel binding follows "+p=+".
"+p+":: The client requires channel binding.
but thinks the server does not.
"+y+":: The client does support channel binding
"+n+":: The client doesn't support channel binding.

+gs2-cb-flag+:
The {RFC5801 §4}[https://www.rfc-editor.org/rfc/rfc5801#section-4]
def gs2_cb_flag; "n" end

def gs2_header

"+F,+".
flag. A class for a nonstandard GSSAPI mechanism should prefix with
the SASL mechanisms using GS2 are "standard", we don't include that
indicate that the GSS mechanism is not "standard", but since all of
Note: the actual GS2 header includes an optional flag to
>>>

+gs2-header+, which prefixes the #initial_client_response.
The {RFC5801 §4}[https://www.rfc-editor.org/rfc/rfc5801#section-4]
def gs2_header
  "#{gs2_cb_flag},#{gs2_authzid},"
end

def gs2_saslname_encode(str)

Encodes +str+ to match RFC5801_SASLNAME.
def gs2_saslname_encode(str)
  str = str.encode("UTF-8")
  # Regexp#match raises "invalid byte sequence" for invalid UTF-8
  NO_NULL_CHARS.match str or
    raise ArgumentError, "invalid saslname: %p" % [str]
  str
    .gsub(?=, "=3D")
    .gsub(?,, "=2C")
end