# Copyright © 2020 Gregor Reitzenstein # Licensed under the MIT License: # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @0x81ac94a588025602; # ============================================================================== # SASL Notes: # # - TLS and SASL security layers may not be both installed # - A SASL security layer takes effect on the first octet following the outcome # message in data being sent by the server and on the first octet sent after # receipt of the outcome message in data being sent by the client. # - Multiple authentication is currently NOT supported. # ============================================================================== struct AuthMessage { union { discover @0 :Void; # Message sent by a client to discover the list of available mechanisms. # MUST NOT be sent during an ongoing authentication exchange. mechanisms @1 :List(Text); # Message sent by a server as reply to a `Discover` message supplying # the list of available mechanisms in the current context. request @2 :Request; # Authentication initiation sent by the client. challenge @3 :Data; # Challenge sent by the server to the client response @4 :Data; # Response sent by the client to the server outcome @5 :Outcome; # Final outcome sent by the server abort @6 :Void; # Abort the current exchange. This may be sent by both client and server # at any point during the exchange. It MUST not be sent by a server # after sending an outcome or by a client after receiving an outcome. # A server receiving an abort after sending an outcome but before # receiving any non-authentication message MUST respect the abort. } } struct Request { mechanism @0 :Text; # The SASL mechanism name. initialResponse :union { # A client may send some intial data when requesting an auth exchange. # According to RFC4422 section 4.3a an implementation MUST to be able to # distinguish between an empty initial reponse and no initial response. none @1 :Void; # No initial reponse is being sent. # The lowest numbered field in an union is the default value in Cap'n # Proto. initial @2 :Data; # A response may be any sequence of octets, including zero-length # sequences and zero-valued octets. } } struct Outcome { enum Result { # Result code of the outcome successful @0; unwilling @1; # Generic "I'm sorry dave, I can't do that" response. MAY be set for any # reason, all reasons or no reason at all. # A server SHOULD set the `action` and `helpText` fields as appropiate. # This code SHOULD only be sent if no other value is more fitting. invalidCredentials @2; # The exchange was valid, but the provided credentials are invalid. This # may mean that the authcid is not known to the server or that the # password/certificate/key/etc. is not correct. unauthorized @3; # The given authcid is not authorized to act as the requested authzid. # This MAY also be returned for the cases `authzid == NULL` or # `authzid == authcid`, for example because login is disabled for that # authcid. malformedAuthZid @4; # The provided authzid is malformed in some way. failed @5; # A generic failed result. A server sending this result MUST set the # `action` field to indicate whether this is a temporary or permanent # failure and SHOULD set `helpText` to a human-readable error message. } enum Action { # In case of a unsuccessful outcome, how should a client proceed? unset @0; # Not a unsuccessful outcome, or the server doesn't know either. # Also, the default value tryAgain @1; # A client should just try again, potentially after prompting the user # to enter their credentials again. wait @2; # The client should wait and try again later. This MAY mean that # whatever failure happened was temporary or the server is applying # rate-limiting to the connection. permanent @3; # The issue appears to the server as being permanent. Another try is # very likely to return the exact same result. In most cases the user # should notify the responsible system administrator. } result @0 :Result; # Result code action @1 :Action; # Hints for the client how to proceed in case of an error helpText @2 :Text; # Human-readable further information in case of an error additionalData :union { # Additional data that may be sent by the server to the client after a # successful authentication exchange. none @3 :Void; # No additional data is being sent. This MUST be set on unsuccessful # outcomes. additional @4 :Data; # Additional data may be any sequence of octets, including zero-length # sequences and zero-value octets. } }