1 module hunt.proton.engine.Sasl;
2 
3 import hunt.proton.engine.SaslListener;
4 import std.concurrency : initOnce;
5 /*
6  * hunt-proton: AMQP Protocol library for D programming language.
7  *
8  * Copyright (C) 2018-2019 HuntLabs
9  *
10  * Website: https://www.huntlabs.net/
11  *
12  * Licensed under the Apache-2.0 License.
13  *
14  */
15 
16 import hunt.Enum;
17 import hunt.String;
18 
19 enum SaslState
20 {
21     /** Pending configuration by application */
22     PN_SASL_CONF,
23     /** Pending SASL Init */
24     PN_SASL_IDLE,
25     /** negotiation in progress */
26     PN_SASL_STEP,
27     /** negotiation completed successfully */
28     PN_SASL_PASS,
29     /** negotiation failed */
30     PN_SASL_FAIL
31 }
32 
33 class SaslOutcome
34 {
35     /** negotiation not completed */
36     //enum {
37     //    PN_SASL_NONE = (cast(byte)-1),
38     //    /** authentication succeeded */
39     //    PN_SASL_OK = (cast(byte)0),
40     //    /** failed due to bad credentials */
41     //    PN_SASL_AUTH = (cast(byte)1),
42     //    /** failed due to a system error */
43     //    PN_SASL_SYS = (cast(byte)2),
44     //    /** failed due to unrecoverable error */
45     //    PN_SASL_PERM = (cast(byte)3),
46     //    PN_SASL_TEMP = (cast(byte)4),
47     //    PN_SASL_SKIPPED = (cast(byte)5);
48     //}
49     static SaslOutcome  PN_SASL_NONE() {
50         __gshared SaslOutcome  inst;
51         return initOnce!inst(new SaslOutcome(cast(byte)-1));
52     }
53 
54     static SaslOutcome  PN_SASL_OK() {
55         __gshared SaslOutcome  inst;
56         return initOnce!inst(new SaslOutcome(cast(byte)0));
57     }
58 
59     static SaslOutcome  PN_SASL_AUTH() {
60         __gshared SaslOutcome  inst;
61         return initOnce!inst(new SaslOutcome(cast(byte)1));
62     }
63 
64     static SaslOutcome  PN_SASL_SYS() {
65         __gshared SaslOutcome  inst;
66         return initOnce!inst(new SaslOutcome(cast(byte)2));
67     }
68 
69     static SaslOutcome  PN_SASL_PERM() {
70         __gshared SaslOutcome  inst;
71         return initOnce!inst(new SaslOutcome(cast(byte)3));
72     }
73 
74     static SaslOutcome  PN_SASL_TEMP() {
75         __gshared SaslOutcome  inst;
76         return initOnce!inst(new SaslOutcome(cast(byte)4));
77     }
78 
79     static SaslOutcome  PN_SASL_SKIPPED() {
80         __gshared SaslOutcome  inst;
81         return initOnce!inst(new SaslOutcome(cast(byte)5));
82     }
83 
84     private  byte _code;
85 
86     /** failed due to transient error */
87 
88     this(byte code)
89     {
90         _code = code;
91     }
92 
93     public byte getCode()
94     {
95         return _code;
96     }
97 
98     override
99     bool opEquals(Object o)
100     {
101         SaslOutcome other = cast(SaslOutcome)o;
102         if(other !is null)
103         {
104             if (other.getCode() == this.getCode())
105             {
106                 return true;
107             }
108         }
109         return false;
110     }
111 
112     public static SaslOutcome[] values ()
113     {
114         return [PN_SASL_NONE ,PN_SASL_OK ,PN_SASL_AUTH,PN_SASL_SYS,PN_SASL_PERM,PN_SASL_TEMP,PN_SASL_SKIPPED];
115     }
116 }
117 
118 interface Sasl
119 {
120 
121 
122 
123 
124 
125 
126     //public static SaslOutcome PN_SASL_NONE = SaslOutcome.PN_SASL_NONE;
127     //public static SaslOutcome PN_SASL_OK = SaslOutcome.PN_SASL_OK;
128     //public static SaslOutcome PN_SASL_AUTH = SaslOutcome.PN_SASL_AUTH;
129     //public static SaslOutcome PN_SASL_SYS = SaslOutcome.PN_SASL_SYS;
130     //public static SaslOutcome PN_SASL_PERM = SaslOutcome.PN_SASL_PERM;
131     //public static SaslOutcome PN_SASL_TEMP = SaslOutcome.PN_SASL_TEMP;
132     //public static SaslOutcome PN_SASL_SKIPPED = SaslOutcome.PN_SASL_SKIPPED;
133 
134     /**
135      * Access the current state of the layer.
136      *
137      * @return The state of the sasl layer.
138      */
139     SaslState getState();
140 
141     /**
142      * Set the acceptable SASL mechanisms for the layer.
143      *
144      * @param mechanisms a list of acceptable SASL mechanisms
145      */
146     void setMechanisms(string [] mechanisms);
147 
148     /**
149      * Retrieve the list of SASL mechanisms provided by the remote.
150      *
151      * @return the SASL mechanisms advertised by the remote
152      */
153     string[] getRemoteMechanisms();
154 
155     /**
156      * Set the remote hostname to indicate the host being connected to when
157      * sending a SaslInit to the server.
158      */
159     void setRemoteHostname(string hostname);
160 
161     /**
162      * Retrieve the hostname indicated by the client when sending its SaslInit.
163      *
164      * @return the hostname indicated by the remote client, or null if none specified.
165      */
166     string getHostname();
167 
168     /**
169      * Determine the size of the bytes available via recv().
170      *
171      * Returns the size in bytes available via recv().
172      *
173      * @return The number of bytes available, zero if no available data.
174      */
175     int pending();
176 
177     /**
178      * Read challenge/response/additional data sent from the peer.
179      *
180      * Use pending to determine the size of the data.
181      *
182      * @param bytes written with up to size bytes of inbound data.
183      * @param offset the offset in the array to begin writing at
184      * @param size maximum number of bytes that bytes can accept.
185      * @return The number of bytes written to bytes, or an error code if {@literal < 0}.
186      */
187     int recv(byte[] bytes, int offset, int size);
188 
189     /**
190      * Send challenge/response/additional data to the peer.
191      *
192      * @param bytes The challenge/response data.
193      * @param offset the point within the array at which the data starts at
194      * @param size The number of data octets in bytes.
195      * @return The number of octets read from bytes, or an error code if {@literal < 0}
196      */
197     int send(byte[] bytes, int offset, int size);
198 
199 
200     /**
201      * Set the outcome of SASL negotiation
202      *
203      * Used by the server to set the result of the negotiation process.
204      *
205      * @param outcome the outcome of the SASL negotiation
206      */
207     void done(SaslOutcome outcome);
208 
209 
210     /**
211      * Configure the SASL layer to use the "PLAIN" mechanism.
212      *
213      * A utility function to configure a simple client SASL layer using
214      * PLAIN authentication.
215      *
216      * @param username credential for the PLAIN authentication
217      *                     mechanism
218      * @param password credential for the PLAIN authentication
219      *                     mechanism
220      */
221     void plain(String username, String password);
222 
223     /**
224      * Retrieve the outcome of SASL negotiation.
225      */
226     SaslOutcome getOutcome();
227 
228     void client();
229     void server();
230 
231     /**
232      * Set whether servers may accept incoming connections
233      * that skip the SASL layer negotiation.
234      */
235     void allowSkip(bool allowSkip);
236 
237     /**
238      * Adds a listener to receive notice of frames having arrived.
239      */
240     void setListener(SaslListener saslListener);
241 }