From b8576883ad47d041e176d8de0f1990297762b208 Mon Sep 17 00:00:00 2001 From: Chteufleur Date: Thu, 15 Sep 2016 09:32:11 +0200 Subject: [PATCH] Add In-Band Registration for gateway authentication. --- database/database.go | 15 ++++++++ xmpp/commands.go | 83 ++++++++++++++++++++++++-------------------- xmpp/xmpp.go | 47 ++++++++++++++++++++++++- 3 files changed, 107 insertions(+), 38 deletions(-) diff --git a/database/database.go b/database/database.go index 2433737..92fd1bf 100644 --- a/database/database.go +++ b/database/database.go @@ -87,6 +87,10 @@ func (newLine *DatabaseLine) UpdateLine() bool { if newLine.Debug { debug = 1 } + if newLine.SteamPwd == "" { + oldLine := GetLine(newLine.Jid) + newLine.SteamPwd = oldLine.SteamPwd + } _, err = stmt.Exec(newLine.SteamLogin, newLine.SteamPwd, debug, newLine.Jid) if err != nil { log.Printf("%sError on updating SQL statement", LogError, err) @@ -96,6 +100,17 @@ func (newLine *DatabaseLine) UpdateLine() bool { return true } +func (dbUser *DatabaseLine) UpdateUser() bool { + isUserRegistred := GetLine(dbUser.Jid) != nil + var isSqlSuccess bool + if isUserRegistred { + isSqlSuccess = dbUser.UpdateLine() + } else { + isSqlSuccess = dbUser.AddLine() + } + return isSqlSuccess +} + func RemoveLine(jid string) bool { // Update Steam login and password to blank before deleting, // because it is not really deleted in the SQLite file. diff --git a/xmpp/commands.go b/xmpp/commands.go index de9615c..f4b56a8 100644 --- a/xmpp/commands.go +++ b/xmpp/commands.go @@ -30,7 +30,7 @@ func execDiscoCommand(iq *xmpp.Iq) { discoItem := &xmpp.DiscoItems{Node: xmpp.NodeAdHocCommand} jidBareFrom := strings.SplitN(iq.From, "/", 2)[0] - jidBareTo := strings.SplitN(iq.To, "/", 2)[0] + jidBareTo := strings.SplitN(iq.To, "/", 2)[0] dbUser := database.GetLine(jidBareFrom) if jidBareTo == jid.Domain { @@ -71,6 +71,8 @@ func execDisco(iq *xmpp.Iq) { if jidBareTo == jid.Domain { discoInfo.Identity = append(discoInfo.Identity, *identityGateway) discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NodeAdHocCommand}) + discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSJabberClient}) + discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSRegister}) } else { discoInfo.Identity = append(discoInfo.Identity, *identityClients) discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSChatStatesNotification}) @@ -114,16 +116,9 @@ func execCommandAdHoc(iq *xmpp.Iq) { } else if adHoc.Node == CommandGetIdentifiants { // Command Auth Code - cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocForm, Title: "Steam Account Info", Instructions: "Please provide your Steam login and password."} - note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo, Value: "Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database."} - - field := &xmpp.AdHocField{Var: "login", Label: "Steam Login", Type: xmpp.TypeAdHocFieldTextSingle} - cmdXForm.Fields = append(cmdXForm.Fields, *field) - field = &xmpp.AdHocField{Var: "password", Label: "Steam Password", Type: xmpp.TypeAdHocFieldTextPrivate} - cmdXForm.Fields = append(cmdXForm.Fields, *field) - + cmdXForm := getXFormRegistration("") cmd.XForm = *cmdXForm - cmd.Note = *note + } else if adHoc.Node == CommandDisconnectSteam { cmd.Status = xmpp.StatusAdHocCompleted cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Force Steam deconnexion"} @@ -225,33 +220,9 @@ func execCommandAdHoc(iq *xmpp.Iq) { note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo} // Command Auth Code - steamLogin := "" - steamPwd := "" - fields := adHoc.XForm.Fields - for _, field := range fields { - if field.Var == "login" { - steamLogin = field.Value - } else if field.Var == "password" { - steamPwd = field.Value - } - } - if steamLogin != "" && steamPwd != "" { - // Succeded - jidBare := strings.SplitN(iq.From, "/", 2)[0] - dbUser := new(database.DatabaseLine) - dbUser.Jid = jidBare - dbUser.SteamLogin = steamLogin - dbUser.SteamPwd = steamPwd - dbUser.Debug = false - - isUserRegistred := database.GetLine(dbUser.Jid) != nil - var isSqlSuccess bool - if isUserRegistred { - isSqlSuccess = dbUser.UpdateLine() - } else { - isSqlSuccess = dbUser.AddLine() - } - if isSqlSuccess { + dbUser := getUser(adHoc.XForm.Fields, iq) + if dbUser != nil { + if dbUser.UpdateUser() { AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug) note.Value = "Command succeded !" } else { @@ -275,3 +246,41 @@ func execCommandAdHoc(iq *xmpp.Iq) { comp.Out <- reply } } + +func getXFormRegistration(steamLogin string) *xmpp.AdHocXForm { + cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocForm, Title: "Steam Account Info", Instructions: "Please provide your Steam login and password (Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database)."} + + field := &xmpp.AdHocField{Var: "login", Label: "Steam Login", Type: xmpp.TypeAdHocFieldTextSingle} + field.Value = steamLogin + cmdXForm.Fields = append(cmdXForm.Fields, *field) + field = &xmpp.AdHocField{Var: "password", Label: "Steam Password", Type: xmpp.TypeAdHocFieldTextPrivate} + cmdXForm.Fields = append(cmdXForm.Fields, *field) + + return cmdXForm +} + +func getUser(fields []xmpp.AdHocField, iq *xmpp.Iq) *database.DatabaseLine { + // Command Auth Code + steamLogin := "" + steamPwd := "" + for _, field := range fields { + if field.Var == "login" { + steamLogin = field.Value + } else if field.Var == "password" { + steamPwd = field.Value + } + } + if steamLogin != "" { + // Succeded + jidBare := strings.SplitN(iq.From, "/", 2)[0] + dbUser := new(database.DatabaseLine) + dbUser.Jid = jidBare + dbUser.SteamLogin = steamLogin + dbUser.SteamPwd = steamPwd + dbUser.Debug = false + + return dbUser + } else { + return nil + } +} diff --git a/xmpp/xmpp.go b/xmpp/xmpp.go index eb2a6fd..14af997 100644 --- a/xmpp/xmpp.go +++ b/xmpp/xmpp.go @@ -116,6 +116,51 @@ func mainXMPP() { sendNotSupportedFeature(v) } + case xmpp.NSRegister: + if jidBareTo == jid.Domain { + reply := v.Response(xmpp.IQTypeResult) + jidBareFrom := strings.SplitN(v.From, "/", 2)[0] + registerQuery := &xmpp.RegisterQuery{} + + if v.Type == xmpp.IQTypeGet { + registerQuery.Instructions = "Please provide your Steam login and password (Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database)." + + dbUser := database.GetLine(jidBareFrom) + if dbUser != nil { + // User already registered + registerQuery.Registered = &xmpp.RegisterRegistered{} + registerQuery.Username = dbUser.SteamLogin + registerQuery.XForm = *getXFormRegistration(dbUser.SteamLogin) + } else { + registerQuery.XForm = *getXFormRegistration("") + } + reply.PayloadEncode(cmd) + + } else if v.Type == xmpp.IQTypeSet { + v.PayloadDecode(registerQuery) + + if registerQuery.Remove != nil { + RemoveUser(jidBareFrom) + } else { + dbUser := getUser(registerQuery.XForm.Fields, v) + if dbUser != nil { + if dbUser.UpdateUser() { + AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug) + } else { + reply.Type = xmpp.IQTypeError + reply.Error = xmpp.NewErrorWithCode("406", "modify", xmpp.ErrorNotAcceptable, "") + } + } else { + reply.Type = xmpp.IQTypeError + reply.Error = xmpp.NewErrorWithCode("409", "cancel", xmpp.ErrorConflict, "") + } + } + } + comp.Out <- reply + } else { + sendNotSupportedFeature(v) + } + default: sendNotSupportedFeature(v) } @@ -138,7 +183,7 @@ func must(v interface{}, err error) interface{} { func sendNotSupportedFeature(iq *xmpp.Iq) { reply := iq.Response(xmpp.IQTypeError) - reply.PayloadEncode(xmpp.NewError("cancel", xmpp.FeatureNotImplemented, "")) + reply.PayloadEncode(xmpp.NewError("cancel", xmpp.ErrorFeatureNotImplemented, "")) comp.Out <- reply }