Unmantained Guida [RELEASE]Authenticator

Una guida contrassegnata come Unmantained contiene informazioni su un argomento obsoleto, non più utile o files non aggiornati da parte del creatore.
Stato
Discussione chiusa ad ulteriori risposte.

Ryosaku

Utente Emerald
19 Febbraio 2010
1,604
36
837
631
Ultima modifica da un moderatore:
Hola a tutti, dato che RoyalSword è stato chiuso oggi per vari motivi, vi rilascio una cosetta che potrebbe tornare utile a molti.
In questo thread vi presento l'authenticator!

Cos'è l'authenticator?
Non è altro che un sistema di autenticazione aggiuntivo al classico nome utente & password, che però richiede un dato dinamico ossia che cambia sempre.

Metin2, come molti altri mmorpg, ne ha già un incorporato (la famosa colonna securitycode presente sulla tabella account) solo che reversare l'algoritmo con il quale viene calcolato il codice è un po' un suicidio.
Figuratevi poi ricreare un tool in grado di restituirvelo :asd:
La cosa migliore sarebbe usare quello (magari a qualcuno verrà lo spunto di sistemarlo leggendo questo thread) ma io sono qui a proporvene uno alternativo.

Informazioni importanti da conoscere
Questo sistema si appoggia ad una pagina PHP (penso di aver detto già parecchio no? :asd:) ed ovviamente per essere valido il client non deve essere violabile (o comunque molto difficile da violare :asd:).

Funzionamento
Al momento dell'autenticazione il client avvierà in automatico una richiesta alla pagina PHP in questione. Farà un check sull'esistenza dei dati, e se positiva genererà un codice di 6 cifre in modo casuale.
Questo codice verrà poi passato al client (tramite modulo urllib) e lo confronterà con quello scritto dal giocatore.
Ovviamente il giocatore lo riceverà via mail. Fico no? :asd:
Con il settaggio attuale, il codice verrà richiesto ad ogni cambio di IP (quindi ogni qualvolta un giocatore effettuerà il login con l'IP differente :D).

Consigli
I consigli che vi do sono solo due.
1- Posizionate la pagina PHP sul vostro server (dovrete quindi installare apache) evitando quindi downtime del vostro dominio web e quindi scocciature di mancata esecuzione di login ai giocatori.
2- Inviate e-mail via SMTP, le mail inviate tramite funzione PHP non arrivano a tutti i servizi.

Download
Script PHP parte server:
PHP Mozilla Pastebin - collaborative debugging tool
PHP code - 91 lines - codepad
PHP:
 IlContabile's authenticator - Pastebin.com[/URL]

Qui invece potete trovare il download della classe PHPMailer che ho utilizzato per inviare email via SMTP:
[URL]https://github.com/Synchro/PHPMailer[/URL]

Parte database:
Dovete creare delle colonne con queste caratteristiche nella tabella account:
[PHP]
  `content_shield_status` tinyint(1) unsigned NOT NULL DEFAULT '1',
  `content_shield_ip` varchar(15) NOT NULL DEFAULT '0.0.0.0',
La colonna status definisce se l'authenticator sarà attivo per quell'account, o no.
La colonna IP invece serve a mantenere in memoria l'ultimo IP che ha effettuato il login.

Script PYTHON parte client:
File intrologin.py
In testa aggiungere il codice:
PHP:
import urllib

In seguito sotto:
PHP:
# DA SOSTITUIRE ALLA FUNZIONE CONNECT
    def Connect(self, id, pwd):
        login = str(id)
        password = str(pwd)
        contentshield = urllib.urlopen("http://www.royalsword.org/contentshield.php?mode=trytologin&login=%s&password=%s" % (login, password)).read()
        data = contentshield.split("#")
        
        if data[0]=="****************":
            self.PopupNotifyMessage("Server non raggiungibile")
        elif data[0]=="ERROR":
            self.PopupNotifyMessage("Dati errati")
        elif data[0]=="BANNED":
            self.PopupNotifyMessage(locale.LOGIN_FAILURE_BLOCK_ID)
        elif data[0]=="PASS":
            if constInfo.SEQUENCE_PACKET_ENABLE:
                net.SetPacketSequenceMode()
            if IsLoginDelay():
                loginDelay = GetLoginDelay()
                self.connectingDialog = ConnectingDialog()
                self.connectingDialog.Open(loginDelay)
                self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown)
                self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey)
                self.isNowCountDown = TRUE
            else:
                self.stream.popupWindow.Close()
                self.stream.popupWindow.Open(locale.LOGIN_CONNETING, self.SetPasswordEditLineFocus, locale.UI_CANCEL)
            
            self.stream.SetLoginInfo(id, pwd)
            self.stream.Connect()
        else:
            self.OnContentRequest(data[1], data[0], id, pwd)

    def OnContentRequest(self, data, code, id, pwd):
        if self.connectingDialog:
            self.connectingDialog.Close()
        self.connectingDialog = None
        
        self.matrixInputChanceCount = 1
        
        self.stream.popupWindow.Close()
        
        inputDialog = uiCommon.InputDialogWithDescription2()
        inputDialog.SetMaxLength(6)
        inputDialog.SetAcceptEvent(lambda arg=TRUE: self.__OnAcceptContentShieldData(code, id, pwd))
        inputDialog.SetCancelEvent(ui.__mem_func__(self.__OnCancelMatrixCardData))
        inputDialog.SetTitle("Authenticator")
        inputDialog.SetDescription1("Inserisci il codice ricevuto via mail in data:")
        inputDialog.SetDescription2("%s" % data)
        
        inputDialog.Open()
        self.inputDialog = inputDialog

    def __OnAcceptContentShieldData(self, code, id, pwd):
        text = int(self.inputDialog.GetText())
        code = int(code)
        if self.inputDialog:
            self.inputDialog.Hide()
        self.PopupNotifyMessage(locale.LOGIN_PROCESSING)
        
        if text==code:
            if constInfo.SEQUENCE_PACKET_ENABLE:
                net.SetPacketSequenceMode()
            if IsLoginDelay():
                loginDelay = GetLoginDelay()
                self.connectingDialog = ConnectingDialog()
                self.connectingDialog.Open(loginDelay)
                self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown)
                self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey)
                self.isNowCountDown = TRUE
            else:
                self.stream.popupWindow.Close()
                self.stream.popupWindow.Open(locale.LOGIN_CONNETING, self.SetPasswordEditLineFocus, locale.UI_CANCEL)
            
            self.stream.SetLoginInfo(id, pwd)
            self.stream.Connect()
            
            updatedata = urllib.urlopen("http://www.royalsword.org/contentshield.php?mode=updateip&login=%s&password=%s" % (id, pwd)).read()
            if updatedata=="UPDATED":
                print("Authenticator: IP updated\n")
        else:
            self.PopupNotifyMessage("Codice errato!", self.__ExitGame)

Modificate il sito che richiama la pagina, modificate i dati nella pagina PHP, e siete apposto :)
Se ci sono errori ditemelo che correggo.
Uno screen del sistema in esecuzione:
 
il sistema era molto bello sopratutto se delle persone ti scovavano la password,il problema quando giocavo io e che usavo due pc,ovvero un pò giocavo su uno e un pò sull'altro e quindi mi chiedeva semprl'autotenticazione (o come si scrive) e dovevo sepre andare all'email,cosa noiosa per me,xò bravo per averlo postato ;)
 
Hola a tutti, dato che RoyalSword è stato chiuso oggi per vari motivi, vi rilascio una cosetta che potrebbe tornare utile a molti.
In questo thread vi presento l'authenticator!

Cos'è l'authenticator?
Non è altro che un sistema di autenticazione aggiuntivo al classico nome utente & password, che però richiede un dato dinamico ossia che cambia sempre.

Metin2, come molti altri mmorpg, ne ha già un incorporato (la famosa colonna securitycode presente sulla tabella account) solo che reversare l'algoritmo con il quale viene calcolato il codice è un po' un suicidio.
Figuratevi poi ricreare un tool in grado di restituirvelo :asd:
La cosa migliore sarebbe usare quello (magari a qualcuno verrà lo spunto di sistemarlo leggendo questo thread) ma io sono qui a proporvene uno alternativo.

Informazioni importanti da conoscere
Questo sistema si appoggia ad una pagina PHP (penso di aver detto già parecchio no? :asd:) ed ovviamente per essere valido il client non deve essere violabile (o comunque molto difficile da violare :asd:).

Funzionamento
Al momento dell'autenticazione il client avvierà in automatico una richiesta alla pagina PHP in questione. Farà un check sull'esistenza dei dati, e se positiva genererà un codice di 6 cifre in modo casuale.
Questo codice verrà poi passato al client (tramite modulo urllib) e lo confronterà con quello scritto dal giocatore.
Ovviamente il giocatore lo riceverà via mail. Fico no? :asd:

Consigli
I consigli che vi do sono solo due.
1- Posizionate la pagina PHP sul vostro server (dovrete quindi installare apache) evitando quindi downtime del vostro dominio web e quindi scocciature di mancata esecuzione di login ai giocatori.
2- Inviate e-mail via SMTP, le mail inviate tramite funzione PHP non arrivano a tutti i servizi.

Download
Script PHP parte server:
PHP Mozilla Pastebin - collaborative debugging tool
PHP code - 91 lines - codepad
PHP:
 IlContabile's authenticator - Pastebin.com[/URL]

Qui invece potete trovare il download della classe PHPMailer che ho utilizzato per inviare email via SMTP:
[URL]https://github.com/Synchro/PHPMailer[/URL]

Script PYTHON parte client:
File intrologin.py
In testa aggiungere il codice:
[PHP]
import urllib

In seguito sotto:
PHP:
# DA SOSTITUIRE ALLA FUNZIONE CONNECT
    def Connect(self, id, pwd):
        login = str(id)
        password = str(pwd)
        contentshield = urllib.urlopen("http://www.royalsword.org/contentshield.php?mode=trytologin&login=%s&password=%s" % (login, password)).read()
        data = contentshield.split("#")
        
        if data[0]=="****************":
            self.PopupNotifyMessage("Server non raggiungibile")
        elif data[0]=="ERROR":
            self.PopupNotifyMessage("Dati errati")
        elif data[0]=="BANNED":
            self.PopupNotifyMessage(locale.LOGIN_FAILURE_BLOCK_ID)
        elif data[0]=="PASS":
            if constInfo.SEQUENCE_PACKET_ENABLE:
                net.SetPacketSequenceMode()
            if IsLoginDelay():
                loginDelay = GetLoginDelay()
                self.connectingDialog = ConnectingDialog()
                self.connectingDialog.Open(loginDelay)
                self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown)
                self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey)
                self.isNowCountDown = TRUE
            else:
                self.stream.popupWindow.Close()
                self.stream.popupWindow.Open(locale.LOGIN_CONNETING, self.SetPasswordEditLineFocus, locale.UI_CANCEL)
            
            self.stream.SetLoginInfo(id, pwd)
            self.stream.Connect()
        else:
            self.OnContentRequest(data[1], data[0], id, pwd)

    def OnContentRequest(self, data, code, id, pwd):
        if self.connectingDialog:
            self.connectingDialog.Close()
        self.connectingDialog = None
        
        self.matrixInputChanceCount = 1
        
        self.stream.popupWindow.Close()
        
        inputDialog = uiCommon.InputDialogWithDescription2()
        inputDialog.SetMaxLength(6)
        inputDialog.SetAcceptEvent(lambda arg=TRUE: self.__OnAcceptContentShieldData(code, id, pwd))
        inputDialog.SetCancelEvent(ui.__mem_func__(self.__OnCancelMatrixCardData))
        inputDialog.SetTitle("Authenticator")
        inputDialog.SetDescription1("Inserisci il codice ricevuto via mail in data:")
        inputDialog.SetDescription2("%s" % data)
        
        inputDialog.Open()
        self.inputDialog = inputDialog

    def __OnAcceptContentShieldData(self, code, id, pwd):
        text = int(self.inputDialog.GetText())
        code = int(code)
        if self.inputDialog:
            self.inputDialog.Hide()
        self.PopupNotifyMessage(locale.LOGIN_PROCESSING)
        
        if text==code:
            if constInfo.SEQUENCE_PACKET_ENABLE:
                net.SetPacketSequenceMode()
            if IsLoginDelay():
                loginDelay = GetLoginDelay()
                self.connectingDialog = ConnectingDialog()
                self.connectingDialog.Open(loginDelay)
                self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown)
                self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey)
                self.isNowCountDown = TRUE
            else:
                self.stream.popupWindow.Close()
                self.stream.popupWindow.Open(locale.LOGIN_CONNETING, self.SetPasswordEditLineFocus, locale.UI_CANCEL)
            
            self.stream.SetLoginInfo(id, pwd)
            self.stream.Connect()
            
            updatedata = urllib.urlopen("http://www.royalsword.org/contentshield.php?mode=updateip&login=%s&password=%s" % (id, pwd)).read()
            if updatedata=="UPDATED":
                print("Authenticator: IP updated\n")
        else:
            self.PopupNotifyMessage("Codice errato!", self.__ExitGame)

Modificate il sito che richiama la pagina, modificate i dati nella pagina PHP, e siete apposto :)

è un sistema ottimo, ma credo che nessuno lo userà, poichè è una rottura di cog**oni andare ogni volta a cercare nell'email. Proporrei invece di fare una cosa semplice: Generare un nuovo codice solo dopo 24 ore dall'ultima volta. Credo che tu sia già in grado di farlo, quindi non sto qui a spiegarti :asd:
 
Ti basta modificare lo script PHP, ora come ora io ho fatto effettuare una nuova generazione di codice solo al cambio di IP ;)
 
ah guarda,mi dispiace tanto,comunque io ci giocavo ero Sk3ind3vast,quello che all'inizio aveva proposto di creare la gilda al liv 40 e te ti sei rifiutato dicendo scrivilo sul forum,scrivilo sul forum e tanto non verrà mai accettata,poi lo scritto e tutti hanno accettato ma al liv 100,beh hai scritto che hai accettato tutte le richieste,ma la mia mai,me ne ero andato solo xk volevo fare una gilda in royalsword e non ho potuto,comque era fatto +- bene,ma secondo me non dovresti dare i file cosi,comunque finisco di spammare,scusa
 
ah guarda,mi dispiace tanto,comunque io ci giocavo ero Sk3ind3vast,quello che all'inizio aveva proposto di creare la gilda al liv 40 e te ti sei rifiutato dicendo scrivilo sul forum,scrivilo sul forum e tanto non verrà mai accettata,poi lo scritto e tutti hanno accettato ma al liv 100,beh hai scritto che hai accettato tutte le richieste,ma la mia mai,me ne ero andato solo xk volevo fare una gilda in royalsword e non ho potuto,comque era fatto +- bene,ma secondo me non dovresti dare i file cosi,comunque finisco di spammare,scusa

Una proposta/suggerimento si chiama appositamente così perchè non deve diventare un'obbligo d'implementazione.
Se poi voi volete che ogni cosa sia implementata è un altro paio di maniche, qui non vi verrà mai incontro nessuno.
Le ragioni di scarto le abbiamo sempre date, non potete certo pretendere l'implementazione di tutto quel che dite.
In ogni caso torniamo al thread, ormai è questione chiusa :D
 
Stato
Discussione chiusa ad ulteriori risposte.
Indietro
Top Bottom