mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-21 12:09:48 -05:00
Dockerize service
This commit is contained in:
parent
e64fb2d9a0
commit
f1473cff46
7 changed files with 80 additions and 22 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Dockerfile
|
||||||
|
node_modules
|
16
Dockerfile
Normal file
16
Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from golang:1.17-alpine3.14
|
||||||
|
|
||||||
|
workdir /app
|
||||||
|
copy go.mod go.sum /app
|
||||||
|
run go mod download
|
||||||
|
|
||||||
|
copy . /app
|
||||||
|
run go build -o /app/aim
|
||||||
|
|
||||||
|
EXPOSE 5190
|
||||||
|
ARG OSCAR_HOST
|
||||||
|
ARG OSCAR_PORT
|
||||||
|
ARG OSCAR_BOS_HOST
|
||||||
|
ARG OSCAR_BOS_PORT
|
||||||
|
|
||||||
|
cmd /app/aim
|
58
main.go
58
main.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
@ -24,13 +25,53 @@ import (
|
||||||
"github.com/uptrace/bun/extra/bundebug"
|
"github.com/uptrace/bun/extra/bundebug"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var (
|
||||||
SRV_HOST = "0.0.0.0"
|
OSCAR_HOST = "0.0.0.0"
|
||||||
SRV_PORT = "5190"
|
OSCAR_PORT = "5190"
|
||||||
SRV_ADDRESS = SRV_HOST + ":" + SRV_PORT
|
OSCAR_ADDRESS = OSCAR_HOST + ":" + OSCAR_PORT
|
||||||
|
OSCAR_BOS_HOST = OSCAR_HOST
|
||||||
|
OSCAR_BOS_PORT = OSCAR_PORT
|
||||||
|
OSCAR_BOS_ADDRESS = OSCAR_BOS_HOST + ":" + OSCAR_BOS_PORT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if oscarHost, ok := os.LookupEnv("OSCAR_HOST"); ok {
|
||||||
|
OSCAR_HOST = oscarHost
|
||||||
|
}
|
||||||
|
var oscarHost string
|
||||||
|
flag.StringVar(&oscarHost, "host", OSCAR_HOST, "Server hostname")
|
||||||
|
|
||||||
|
if oscarPort, ok := os.LookupEnv("OSCAR_PORT"); ok {
|
||||||
|
OSCAR_PORT = oscarPort
|
||||||
|
}
|
||||||
|
var oscarPort string
|
||||||
|
flag.StringVar(&oscarPort, "port", OSCAR_PORT, "Server port")
|
||||||
|
|
||||||
|
if oscarBOSHost, ok := os.LookupEnv("OSCAR_BOS_HOST"); ok {
|
||||||
|
OSCAR_BOS_HOST = oscarBOSHost
|
||||||
|
}
|
||||||
|
var oscarBOSHost string
|
||||||
|
flag.StringVar(&oscarBOSHost, "boshost", OSCAR_BOS_HOST, "BOS hostname")
|
||||||
|
|
||||||
|
if oscarBOSPort, ok := os.LookupEnv("OSCAR_BOS_PORT"); ok {
|
||||||
|
OSCAR_BOS_PORT = oscarBOSPort
|
||||||
|
}
|
||||||
|
var oscarBOSPort string
|
||||||
|
flag.StringVar(&oscarBOSPort, "bosport", OSCAR_BOS_PORT, "BOS port")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
OSCAR_HOST = oscarHost
|
||||||
|
OSCAR_PORT = oscarPort
|
||||||
|
OSCAR_ADDRESS = OSCAR_HOST + ":" + OSCAR_PORT
|
||||||
|
|
||||||
|
OSCAR_BOS_HOST = oscarBOSHost
|
||||||
|
OSCAR_BOS_PORT = oscarBOSPort
|
||||||
|
OSCAR_BOS_ADDRESS = OSCAR_BOS_HOST + ":" + OSCAR_BOS_PORT
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// Set up the DB
|
// Set up the DB
|
||||||
sqldb, err := sql.Open(sqliteshim.ShimName, "file:aim.db")
|
sqldb, err := sql.Open(sqliteshim.ShimName, "file:aim.db")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -53,7 +94,7 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
listener, err := net.Listen("tcp", SRV_ADDRESS)
|
listener, err := net.Listen("tcp", OSCAR_ADDRESS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error listening: ", err.Error())
|
fmt.Println("Error listening: ", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -71,11 +112,11 @@ func main() {
|
||||||
go onlineRoutine(db)
|
go onlineRoutine(db)
|
||||||
|
|
||||||
serviceManager := NewServiceManager()
|
serviceManager := NewServiceManager()
|
||||||
serviceManager.RegisterService(0x01, &services.GenericServiceControls{OnlineCh: onlineCh})
|
serviceManager.RegisterService(0x01, &services.GenericServiceControls{OnlineCh: onlineCh, ServerHostname: OSCAR_ADDRESS})
|
||||||
serviceManager.RegisterService(0x02, &services.LocationServices{OnlineCh: onlineCh})
|
serviceManager.RegisterService(0x02, &services.LocationServices{OnlineCh: onlineCh})
|
||||||
serviceManager.RegisterService(0x03, &services.BuddyListManagement{})
|
serviceManager.RegisterService(0x03, &services.BuddyListManagement{})
|
||||||
serviceManager.RegisterService(0x04, &services.ICBM{CommCh: commCh})
|
serviceManager.RegisterService(0x04, &services.ICBM{CommCh: commCh})
|
||||||
serviceManager.RegisterService(0x17, &services.AuthorizationRegistrationService{})
|
serviceManager.RegisterService(0x17, &services.AuthorizationRegistrationService{BOSAddress: OSCAR_BOS_ADDRESS})
|
||||||
|
|
||||||
handleCloseFn := func(ctx context.Context, session *oscar.Session) {
|
handleCloseFn := func(ctx context.Context, session *oscar.Session) {
|
||||||
log.Printf("%v disconnected", session.RemoteAddr())
|
log.Printf("%v disconnected", session.RemoteAddr())
|
||||||
|
@ -174,7 +215,8 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fmt.Println("OSCAR listening on " + SRV_ADDRESS)
|
fmt.Println("OSCAR listening on " + OSCAR_ADDRESS)
|
||||||
|
fmt.Println("OSCAR BOS set to " + OSCAR_BOS_ADDRESS)
|
||||||
for {
|
for {
|
||||||
conn, err := listener.Accept()
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"aim-oscar/oscar"
|
"aim-oscar/oscar"
|
||||||
"aim-oscar/util"
|
"aim-oscar/util"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -53,9 +52,9 @@ func OnlineNotification(sm *SessionManager) (chan *models.User, routineFn) {
|
||||||
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
||||||
|
|
||||||
tlvs := []*oscar.TLV{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
||||||
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
||||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // External IP
|
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(OSCAR_HOST)))), // TODO: External IP of the client?
|
||||||
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
||||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
||||||
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"aim-oscar/oscar"
|
"aim-oscar/oscar"
|
||||||
"aim-oscar/util"
|
"aim-oscar/util"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -62,9 +61,9 @@ func (g *GenericServiceControls) HandleSNAC(ctx context.Context, db *bun.DB, sna
|
||||||
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
||||||
|
|
||||||
tlvs := []*oscar.TLV{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
||||||
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
||||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(g.ServerHostname)))), // External IP
|
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(g.ServerHostname)))), // todo: External IP of the client?
|
||||||
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
||||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
||||||
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
||||||
|
@ -143,9 +142,9 @@ func (g *GenericServiceControls) HandleSNAC(ctx context.Context, db *bun.DB, sna
|
||||||
}
|
}
|
||||||
|
|
||||||
tlvs := []*oscar.TLV{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(0x01, util.Dword(0)), // User Class
|
oscar.NewTLV(0x01, util.Dword(0)), // User Class
|
||||||
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
||||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(g.ServerHostname)))), // External IP
|
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(g.ServerHostname)))), // External IP of the client?
|
||||||
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
||||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
||||||
oscar.NewTLV(0x01e, util.Dword(0x0)), // Unknown value
|
oscar.NewTLV(0x01e, util.Dword(0x0)), // Unknown value
|
||||||
|
|
|
@ -103,7 +103,7 @@ func (s *LocationServices) HandleSNAC(ctx context.Context, db *bun.DB, snac *osc
|
||||||
tlvs := []*oscar.TLV{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(1, util.Dword(0)), // user class
|
oscar.NewTLV(1, util.Dword(0)), // user class
|
||||||
oscar.NewTLV(6, util.Dword(uint32(requestedUser.Status))), // user status
|
oscar.NewTLV(6, util.Dword(uint32(requestedUser.Status))), // user status
|
||||||
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // user external IP
|
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(OSCAR_HOST)))), // user external IP
|
||||||
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(requestedUser.LastActivityAt).Seconds()))), // idle time
|
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(requestedUser.LastActivityAt).Seconds()))), // idle time
|
||||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // TODO: signon time
|
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // TODO: signon time
|
||||||
oscar.NewTLV(0x05, util.Dword(uint32(requestedUser.CreatedAt.Unix()))), // member since
|
oscar.NewTLV(0x05, util.Dword(uint32(requestedUser.CreatedAt.Unix()))), // member since
|
||||||
|
|
|
@ -27,7 +27,7 @@ type AuthorizationCookie struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorizationRegistrationService struct {
|
type AuthorizationRegistrationService struct {
|
||||||
ServerHostname string
|
BOSAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthenticateFLAPCookie(ctx context.Context, db *bun.DB, flap *oscar.FLAP) (*models.User, error) {
|
func AuthenticateFLAPCookie(ctx context.Context, db *bun.DB, flap *oscar.FLAP) (*models.User, error) {
|
||||||
|
@ -176,7 +176,7 @@ func (a *AuthorizationRegistrationService) HandleSNAC(ctx context.Context, db *b
|
||||||
// Send BOS response + cookie
|
// Send BOS response + cookie
|
||||||
authSnac := oscar.NewSNAC(0x17, 0x3)
|
authSnac := oscar.NewSNAC(0x17, 0x3)
|
||||||
authSnac.Data.WriteBinary(usernameTLV)
|
authSnac.Data.WriteBinary(usernameTLV)
|
||||||
authSnac.Data.WriteBinary(oscar.NewTLV(0x5, []byte(a.ServerHostname)))
|
authSnac.Data.WriteBinary(oscar.NewTLV(0x5, []byte(a.BOSAddress)))
|
||||||
|
|
||||||
cookie, err := json.Marshal(AuthorizationCookie{
|
cookie, err := json.Marshal(AuthorizationCookie{
|
||||||
UIN: user.UIN,
|
UIN: user.UIN,
|
||||||
|
|
Loading…
Reference in a new issue