mirror of
https://port.numenaute.org/aleajactaest/bazar_alea.git
synced 2024-10-04 15:58:31 +00:00
update xmpp sasl
This commit is contained in:
parent
981a05cb14
commit
72ad3bf8e5
1 changed files with 140 additions and 5 deletions
|
@ -39,10 +39,40 @@ enum XMPPState {
|
||||||
WAIT_TLS, # Wait TLS Done
|
WAIT_TLS, # Wait TLS Done
|
||||||
MISSING_TLS, # Missing feature TLS -> wait 30min and retry
|
MISSING_TLS, # Missing feature TLS -> wait 30min and retry
|
||||||
STARTED_TLS, # TLS connection is done
|
STARTED_TLS, # TLS connection is done
|
||||||
|
SELECT_MECHANISM_AUTHENTICATE,
|
||||||
|
AUTHENTICATE_STEP_PLAIN, # Select mechanism authenticate PLAIN
|
||||||
AUTHENTICATE_STEP_1, # Launch authenticate
|
AUTHENTICATE_STEP_1, # Launch authenticate
|
||||||
AUTHENTICATE_STEP_2, # Launch authenticate
|
AUTHENTICATE_STEP_2, # Launch authenticate
|
||||||
AUTHENTICATE_STEP_3, # Launch authenticate
|
AUTHENTICATE_STEP_3, # Launch authenticate
|
||||||
|
AUTHENTICATE_CHECK_RESULT, # Last time check result
|
||||||
|
AUTHENTICATE_FAILURE,
|
||||||
|
AUTHENTICATE_SUCCESS,
|
||||||
AUTHENTICATED, # We finished authenticate
|
AUTHENTICATED, # We finished authenticate
|
||||||
|
NOT_AUTHORIZED, # Not Authorize
|
||||||
|
ACCOUNT_DISABLED, # Account Disable
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ResultAuthenticate {
|
||||||
|
NONE, # Authenticate not started
|
||||||
|
DONE, # Authenticate finished and done
|
||||||
|
ABORT, # Authenticate finished with error (try other method)
|
||||||
|
NEXT, # Authenticate need execute other step
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SASLReturn {
|
||||||
|
SUCCESS,
|
||||||
|
ABORTED,
|
||||||
|
ACCOUNT_DISABLED,
|
||||||
|
CREDENTIALS_EXPIRED,
|
||||||
|
ENCRYPTION_REQUIRED,
|
||||||
|
INCORRECT_ENCODING,
|
||||||
|
INVALID_AUTHZID,
|
||||||
|
INVALID_MECHANISM,
|
||||||
|
MALFORMED_REQUEST,
|
||||||
|
MECHANISM_TOO_WEAK,
|
||||||
|
NOT_AUTHORIZED,
|
||||||
|
TEMPORARY_AUTH_FAILURE,
|
||||||
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
@export var server_xmpp_name:String = "localhost":
|
@export var server_xmpp_name:String = "localhost":
|
||||||
|
@ -98,6 +128,8 @@ func get_locale() -> String:
|
||||||
|
|
||||||
const MAX_WAIT_CONNECTING:float = 60.0
|
const MAX_WAIT_CONNECTING:float = 60.0
|
||||||
const MAX_WAIT_MISSING_TLS:float = 1800.0
|
const MAX_WAIT_MISSING_TLS:float = 1800.0
|
||||||
|
const MAX_WAIT_ACCOUNT_DISABLED:float = 900.0
|
||||||
|
const MAX_WAIT_NOT_AUTHORIZED:float = 18000.0
|
||||||
|
|
||||||
var try_connect:int = 0
|
var try_connect:int = 0
|
||||||
var count_connecting_time:float = MAX_WAIT_CONNECTING
|
var count_connecting_time:float = MAX_WAIT_CONNECTING
|
||||||
|
@ -108,6 +140,10 @@ var tgt_peer = null
|
||||||
var status:StreamState = StreamState.END
|
var status:StreamState = StreamState.END
|
||||||
var xmpp_state = XMPPState.NONE
|
var xmpp_state = XMPPState.NONE
|
||||||
var authentication_methods = []
|
var authentication_methods = []
|
||||||
|
var selected_mechanism_authenticate:String = ""
|
||||||
|
var order_preference_mechanism_authenticate: Array = ['PLAIN']
|
||||||
|
var banned_mechanism_authenticate:Array = []
|
||||||
|
|
||||||
|
|
||||||
func reinit_stream():
|
func reinit_stream():
|
||||||
if ssl_peer != null:
|
if ssl_peer != null:
|
||||||
|
@ -140,6 +176,16 @@ func _process(delta) -> void:
|
||||||
xmpp_state = XMPPState.NONE
|
xmpp_state = XMPPState.NONE
|
||||||
else:
|
else:
|
||||||
count_connecting_time += delta
|
count_connecting_time += delta
|
||||||
|
elif xmpp_state == XMPPState.NOT_AUTHORIZED:
|
||||||
|
if count_connecting_time >= MAX_WAIT_NOT_AUTHORIZED:
|
||||||
|
xmpp_state = XMPPState.NONE
|
||||||
|
else:
|
||||||
|
count_connecting_time += delta
|
||||||
|
elif xmpp_state == XMPPState.ACCOUNT_DISABLED:
|
||||||
|
if count_connecting_time >= MAX_WAIT_ACCOUNT_DISABLED:
|
||||||
|
xmpp_state = XMPPState.NONE
|
||||||
|
else:
|
||||||
|
count_connecting_time += delta
|
||||||
elif xmpp_state == XMPPState.NONE:
|
elif xmpp_state == XMPPState.NONE:
|
||||||
if count_connecting_time >= MAX_WAIT_CONNECTING:
|
if count_connecting_time >= MAX_WAIT_CONNECTING:
|
||||||
xmpp_state = XMPPState.TRY_CONNECT_SERVER
|
xmpp_state = XMPPState.TRY_CONNECT_SERVER
|
||||||
|
@ -217,10 +263,14 @@ func _process(delta) -> void:
|
||||||
else:
|
else:
|
||||||
count_connecting_time = 0
|
count_connecting_time = 0
|
||||||
xmpp_state = XMPPState.MISSING_TLS
|
xmpp_state = XMPPState.MISSING_TLS
|
||||||
else:
|
elif response.begins_with("failure"):
|
||||||
send_msg_error.emit(tr("TlS negotiation failed."))
|
send_msg_error.emit(tr("TlS negotiation failed."))
|
||||||
count_connecting_time = 0
|
count_connecting_time = 0
|
||||||
xmpp_state = XMPPState.MISSING_TLS
|
xmpp_state = XMPPState.MISSING_TLS
|
||||||
|
else:
|
||||||
|
send_msg_error.emit(tr("TlS negotiation failed. (unknow return)"))
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.MISSING_TLS
|
||||||
elif xmpp_state == XMPPState.WAIT_TLS:
|
elif xmpp_state == XMPPState.WAIT_TLS:
|
||||||
if tcp_peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
if tcp_peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||||
xmpp_state = XMPPState.NONE
|
xmpp_state = XMPPState.NONE
|
||||||
|
@ -264,18 +314,27 @@ func _process(delta) -> void:
|
||||||
if analyze_feature_mechanisms(response):
|
if analyze_feature_mechanisms(response):
|
||||||
if authentication_methods.size() > 0:
|
if authentication_methods.size() > 0:
|
||||||
count_connecting_time = MAX_WAIT_CONNECTING
|
count_connecting_time = MAX_WAIT_CONNECTING
|
||||||
xmpp_state = XMPPState.AUTHENTICATE_STEP_1
|
xmpp_state = XMPPState.SELECT_MECHANISM_AUTHENTICATE
|
||||||
#send_msg_debug.emit("AUTHENTICATE_STEP_1")
|
#send_msg_debug.emit("AUTHENTICATE_STEP_1")
|
||||||
# elif response.begins_with("<success"):
|
# elif response.begins_with("<success"):
|
||||||
# stream_status = self.StreamState.STANZA
|
# stream_status = self.StreamState.STANZA
|
||||||
if xmpp_state == XMPPState.AUTHENTICATE_STEP_1:
|
if xmpp_state == XMPPState.SELECT_MECHANISM_AUTHENTICATE:
|
||||||
|
select_mechanism_authenticate(authentication_methods)
|
||||||
|
if selected_mechanism_authenticate == "NONE":
|
||||||
|
send_msg_error.emit("Stream: Impossible to find mechanism to authenticate")
|
||||||
|
xmpp_state = XMPPState.NONE
|
||||||
|
count_connecting_time = 0
|
||||||
|
return
|
||||||
|
elif selected_mechanism_authenticate == "PLAIN":
|
||||||
|
xmpp_state = XMPPState.AUTHENTICATE_STEP_PLAIN
|
||||||
|
if xmpp_state == XMPPState.AUTHENTICATE_STEP_PLAIN:
|
||||||
if tcp_peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
if tcp_peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
||||||
xmpp_state = XMPPState.NONE
|
xmpp_state = XMPPState.NONE
|
||||||
count_connecting_time = 0
|
count_connecting_time = 0
|
||||||
return
|
return
|
||||||
if count_connecting_time >= MAX_WAIT_CONNECTING:
|
if count_connecting_time >= MAX_WAIT_CONNECTING:
|
||||||
count_connecting_time = 0
|
count_connecting_time = 0
|
||||||
negotiate_ssl_sasl(authentication_methods)
|
negotiate_ssl_authenticate_plain()
|
||||||
else:
|
else:
|
||||||
count_connecting_time += delta
|
count_connecting_time += delta
|
||||||
if (ssl_peer.has_method("poll")):
|
if (ssl_peer.has_method("poll")):
|
||||||
|
@ -284,9 +343,59 @@ func _process(delta) -> void:
|
||||||
var response = ssl_peer.get_string(ssl_peer.get_available_bytes())
|
var response = ssl_peer.get_string(ssl_peer.get_available_bytes())
|
||||||
send_msg_debug.emit("Stream: response: " + response)
|
send_msg_debug.emit("Stream: response: " + response)
|
||||||
response = remove_stream_header(response)
|
response = remove_stream_header(response)
|
||||||
if response.begins_with("<success"):
|
var res:SASLReturn = get_result_authenticate(response)
|
||||||
|
if res == SASLReturn.SUCCESS:
|
||||||
count_connecting_time = 0
|
count_connecting_time = 0
|
||||||
xmpp_state = XMPPState.AUTHENTICATED
|
xmpp_state = XMPPState.AUTHENTICATED
|
||||||
|
elif res == SASLReturn.NOT_AUTHORIZED:
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.NOT_AUTHORIZED
|
||||||
|
elif res == SASLReturn.ACCOUNT_DISABLED:
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.ACCOUNT_DISABLED
|
||||||
|
elif res == SASLReturn.NOT_AUTHORIZED:
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.SELECT_MECHANISM_AUTHENTICATE
|
||||||
|
banned_mechanism_authenticate.append(selected_mechanism_authenticate)
|
||||||
|
elif res == SASLReturn.INVALID_MECHANISM:
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.SELECT_MECHANISM_AUTHENTICATE
|
||||||
|
banned_mechanism_authenticate.append(selected_mechanism_authenticate)
|
||||||
|
else:
|
||||||
|
count_connecting_time = 0
|
||||||
|
xmpp_state = XMPPState.SELECT_MECHANISM_AUTHENTICATE
|
||||||
|
banned_mechanism_authenticate.append(selected_mechanism_authenticate)
|
||||||
|
|
||||||
|
|
||||||
|
func get_result_authenticate(response:String) -> SASLReturn:
|
||||||
|
response = remove_stream_header(response)
|
||||||
|
if response.begins_with("<success"):
|
||||||
|
count_connecting_time = 0
|
||||||
|
return SASLReturn.SUCCESS
|
||||||
|
elif response.begins_with("<failure"):
|
||||||
|
if response.contains("<aborted/>"):
|
||||||
|
return SASLReturn.ABORTED
|
||||||
|
elif response.contains("<account-disabled/>"):
|
||||||
|
return SASLReturn.ACCOUNT_DISABLED
|
||||||
|
if response.contains("<credentials-expired/>"):
|
||||||
|
return SASLReturn.CREDENTIALS_EXPIRED
|
||||||
|
if response.contains("<encryption-required/>"):
|
||||||
|
return SASLReturn.ENCRYPTION_REQUIRED
|
||||||
|
if response.contains("<incorrect-encoding/>"):
|
||||||
|
return SASLReturn.INCORRECT_ENCODING
|
||||||
|
if response.contains("<invalid-authzid/>"):
|
||||||
|
return SASLReturn.INVALID_AUTHZID
|
||||||
|
if response.contains("<invalid-mechanism/>"):
|
||||||
|
return SASLReturn.INVALID_MECHANISM
|
||||||
|
if response.contains("<malformed-request/>"):
|
||||||
|
return SASLReturn.MALFORMED_REQUEST
|
||||||
|
if response.contains("<mechanism-too-weak/>"):
|
||||||
|
return SASLReturn.MECHANISM_TOO_WEAK
|
||||||
|
if response.contains("<not-authorized/>"):
|
||||||
|
return SASLReturn.NOT_AUTHORIZED
|
||||||
|
if response.contains("<temporary-auth-failure/>"):
|
||||||
|
return SASLReturn.TEMPORARY_AUTH_FAILURE
|
||||||
|
return SASLReturn.UNKNOWN
|
||||||
|
|
||||||
|
|
||||||
func analyze_error(response:String) -> bool:
|
func analyze_error(response:String) -> bool:
|
||||||
|
@ -373,6 +482,32 @@ func send_ssl_initialize_xmpp() -> void:
|
||||||
send_ssl_string(message)
|
send_ssl_string(message)
|
||||||
|
|
||||||
|
|
||||||
|
func select_mechanism_authenticate(authentication_methods : Array) -> void:
|
||||||
|
selected_mechanism_authenticate = "NONE"
|
||||||
|
for item in order_preference_mechanism_authenticate:
|
||||||
|
if banned_mechanism_authenticate.has(item):
|
||||||
|
continue
|
||||||
|
elif authentication_methods.has(item):
|
||||||
|
selected_mechanism_authenticate = item
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
func negotiate_ssl_authenticate_plain() -> void:
|
||||||
|
send_msg_debug.emit("Stream: sending request for plain")
|
||||||
|
var msg:PackedByteArray = PackedByteArray()
|
||||||
|
msg.push_back(0)
|
||||||
|
var t = account_name.split("@")[0]
|
||||||
|
msg += t.to_ascii_buffer()
|
||||||
|
#msg += conv_string_to_PackedByteArray(account_name.split("@")[0])
|
||||||
|
msg.push_back(0)
|
||||||
|
msg += password.to_ascii_buffer()
|
||||||
|
var auth_account:String = Marshalls.raw_to_base64(msg)
|
||||||
|
var request_sasl:String = "<auth" + \
|
||||||
|
" xmlns='urn:ietf:params:xml:ns:xmpp-sasl'" + \
|
||||||
|
" mechanism='PLAIN'" + \
|
||||||
|
" >" + auth_account + "</auth>"
|
||||||
|
send_ssl_string(request_sasl)
|
||||||
|
|
||||||
|
|
||||||
func negotiate_ssl_sasl(authentication_methods : Array) -> bool:
|
func negotiate_ssl_sasl(authentication_methods : Array) -> bool:
|
||||||
if ( authentication_methods.has("PLAIN")):
|
if ( authentication_methods.has("PLAIN")):
|
||||||
|
|
Loading…
Reference in a new issue