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 }