Skrevet av Emne: IRC var en fiasko, men hva med SSH?  (Lest 12410 ganger)

Utlogget Cybersyn

  • n00b
  • *
  • Innlegg: 2
  • Karma: +1/-0
    • Vis profil
    • localhost
IRC var en fiasko, men hva med SSH?
« på: 22. Mars 2015, 16:51 pm »
  • [applaud]0
  • [smite]0
  • Det hadde vært kjekt å kunne holde øye med chatten selv om man ikke har en PC tilgjengelig. Tidligere fant vi ut at IRC ikke duger til dette (se Steng irc), men kanskje det hadde vært mulig med SSH?

    I stedet for å "lytte til" en IRC-server, vil serveren selv kjøre en SSH-server. Dette er kanskje tyngre for serveren, men til gjengjeld gir det serveren mer kontroll.

    Slik fungerer det i grove trekk:
    Man logger på SSH med Minecraft-brukernavnet sitt, men i stedet for å bekrefte at du er hvem du utgir deg for å være ved hjelp av Minecraft-passordet, utveksles det TLS-nøkkelpar. Dermed vil serveren (eller potensielle mellommenn) aldri få tak i Minecraft-passordet ditt.

    Nøkkelparet genereres av klienten. Det består av en privat nøkkel og en offentlig nøkkel. All kommunikasjon fra server til klient krypteres med den offentlige nøkkelen, og kan dekrypteres med den private nøkkelen. Det er også mulig (og anbefalt) å beskytte nøkkelen med et passord, slik at ingen kan utgi seg for å være deg selv om de får tak i den private nøkkelen.

    På samme måte har også serveren et eget nøkkelpar. Kommunikasjon fra klient til server krypteres med serverens offentlige nøkkel, og kan dekrypteres med serverens private nøkkel.

    Klientens offentlige nøkkel lastes opp til serveren og knyttes til brukernavnet ditt når du kjører en bestemt kommando med den offentlige nøkkelen som argument (når du er logget inn med Minecraft). Når du senere logger inn med SSH, sender serveren en melding kryptert med den offentlige nøkkelen knyttet til brukernavnet ditt. For å dekryptere denne medlingen, må klienten bruke den private nøkkelen. Hvis klienten klarer å dekryptere meldingen, betyr det at den har den riktige private nøkkelen, og dermed er det bekreftet at du er hvem du utgir deg for å være.

    Les mer:
    http://security.stackexchange.com/questions/20803

    Selvsagt skal ikke serveren kjøre en vanlig SSH-server som gir tilgang til hele systemet. SSH-serveren det er snakk om styres av en Bukkit plugin, og gir klienten tilgang til kun Minecraft chat og kommandoer.

    Det er også verdt å legge merke til at IRC-brukere regnes som en egen gruppe med separate permissions, mens SSH-brukerne er knyttet til og fungerer som vanlige Minecraft brukere.

    Supert om dette lar seg gjøre!
    « Siste redigering: 22. Mars 2015, 17:29 pm av BrutalOst »



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #1 på: 23. Mars 2015, 06:24 am »
  • [applaud]0
  • [smite]0
  • Får du dette til å fungere som beskrevet vil jeg selvsagt legge den inn. Jeg har et lite forbehold: Minecraft-serveren kjører som en ikke-privilegiert bruker, port 22 kan derfor ikke brukes. (Det er forøvrig allerede i bruk til management).

    En slik tjeneste må derfor kjøre på en annen port, f.eks. 2222. Dette bør uansett være konfigurerbart.

    Det ville også være praktisk å kunne legge inn en "banner" med informasjon før man logger inn, dette støttes av SSH-protokollen. Banneren bør da selvsagt ligge i en tekstfil så den kan oppdateres enkelt. Eksempel:
    Kode: [Velg]
    Velkommen til Minecraft.atc.no
    For informasjon om denne tjenesten, se http://mc.atc.no/ssh


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #2 på: 28. Mars 2015, 00:57 am »
  • [applaud]0
  • [smite]0
  • Jeg er usikker på hvordan jeg skal "lure" CraftBukkit/Spigot og plugins til å tro at SSH-brukere er ekte spillere. Det første jeg tenkte var å iscenesette events, men jeg vet ikke om CraftBukkit/Spigot lytter til sine egne events. Noen idéer? Jeg vil helst unngå workarounds som ProtocolLib.



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #3 på: 28. Mars 2015, 08:32 am »
  • [applaud]0
  • [smite]0
  • Jeg er usikker på hvordan jeg skal "lure" CraftBukkit/Spigot og plugins til å tro at SSH-brukere er ekte spillere. Det første jeg tenkte var å iscenesette events, men jeg vet ikke om CraftBukkit/Spigot lytter til sine egne events. Noen idéer? Jeg vil helst unngå workarounds som ProtocolLib.

    Jeg har aldri generert events, men jeg fant denne:
    https://github.com/Belphemur/CustomEvent/blob/master/src/main/java/be/Balor/Poc/EventManager.java

    Kode: [Velg]
    PluginManager pm = plugin.getServer().getPluginManager();
    Object listeners = getPrivateField(pm, "listeners");
    if (listeners instanceof EnumMap) {
        HashMap<Event.Type, SortedSet<RegisteredListener>> tmp = new HashMap<Event.Type, SortedSet<RegisteredListener>>(
    ((Map<Event.Type, SortedSet<RegisteredListener>>) listeners));
        tmp.put(Event.Type.valueOf(name), null);
        setPrivateField(pm, "listeners", tmp);
    } else
        ((Map<Event.Type, SortedSet<RegisteredListener>>) listeners).put(Event.Type.valueOf(name), null);
        setFieldAccessibility(pm, "listeners", false);
    }

    Den er nok litt ekstra innviklet ettersom det her er snakk om custom events, men jeg tipper du gjør noe lignende med standard events. I det minste så er vel dette et utgangspunkt for videre Googling :-)

    Umm.. her er en LANGT enklere løsning:

    Kode: [Velg]
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (command.getName().equals("test")) {
            TestEvent event = new TestEvent("TestEvent");
            event.setSender(sender.toString());
            this.getServer().getPluginManager().callEvent(event);
        }
        return false;
    }

    Ser ut som this.getServer().getPluginManager().callEvent(event); er alt som skal til...
    « Siste redigering: 28. Mars 2015, 08:37 am av Floyd-ATC »


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #4 på: 29. Mars 2015, 01:19 am »
  • [applaud]0
  • [smite]0
  • Ser ut som this.getServer().getPluginManager().callEvent(event); er alt som skal til...
    Men vil det få selve CraftBukkit til å tro at den kalles "fra innsiden"? Er det ikke bare plugins som lytter til events?

    Hvis det viser seg å virke, vil jeg jo kalle PlayerLoginEvent når en spiller logger inn. Må jeg implementere Player helt fra scratch? For man skal vel helst unngå å kompilere med craftbukkit.jar?



    Et annet problem er at SSH-serveren ikke varsler pluginen om inkommende data. Jeg har kommet opp med disse løsningene:
    • Hvert skall (hver tilkobling) spawner en tråd som kontinuerlig sjekker for inkommende data
    • Pluginen spawner én enkel tråd som kontinuerlig sjekker for inkommende data i alle skall
    • Pluginen sjekker for inkommende data i alle skall når den mottar ticks fra Bukkit/Spigot-API
    Jeg er ikke så veldig erfaren med flertrådet programmering, så jeg er usikker på hvilken løsning som veier minst.

    EDIT: Det er også verdt å nevne at det er Apache SSHD som styrer med SSH. SecureChat er bare et tynt lag som kobler Apache SSHD og Spigot sammen.
    « Siste redigering: 29. April 2015, 23:09 pm av BrutalOst »



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #5 på: 29. Mars 2015, 13:21 pm »
  • [applaud]0
  • [smite]0
  • Å implementere Player burde være helt unødvendig, det burde holde å definere en ny instans med innhold nok til å overbevise chat-relatert kode om at meldingen kom fra en spiller som bare tilfeldigvis ikke eksisterer noe sted.
    Kode: [Velg]
    Player p = new Player()
    Trenger du en spesiell variant av Player så lager du en klasse som arver fra Player og kun endrer de småtingene du vil ha annerledes. (Dette kalles "overloading" og er et av de viktigste prinsippene med OOP)

    Men... strengt tatt burde det ikke engang være nødvendig å ha en spiller som avsender, jeg har mange plugins som genererer chat-meldinger anonymt og det er trivielt å få slike meldinger til å se ut som de kommer fra en spiller.

    Serveren eller plugins kan ikke se forskjell på om en event ble generert av selve serveren eller av en plugin ettersom alt går via de samme API-kallene. Se på MultiCast, RegexFilter og WhoPlugin for eksempler på hvordan det ikke spiller noen rolle hvor meldingen egentlig kommer fra.


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #6 på: 29. Mars 2015, 14:34 pm »
  • [applaud]0
  • [smite]0
  • Å implementere Player burde være helt unødvendig, det burde holde å definere en ny instans med innhold nok til å overbevise chat-relatert kode om at meldingen kom fra en spiller som bare tilfeldigvis ikke eksisterer noe sted.
    Kode: [Velg]
    Player p = new Player()
    Man kan jo ikke instansiere en abstrakt klasse? CraftPlayer implementerer jo Player, men den er ikke en del av APIet.

    Men... strengt tatt burde det ikke engang være nødvendig å ha en spiller som avsender, jeg har mange plugins som genererer chat-meldinger anonymt og det er trivielt å få slike meldinger til å se ut som de kommer fra en spiller.

    Tanken er SSH-brukere også skal kunne utføre kommandoer.
    « Siste redigering: 29. Mars 2015, 14:45 pm av BrutalOst »



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #7 på: 29. Mars 2015, 14:48 pm »
  • [applaud]0
  • [smite]0
  • Man kan jo ikke instansiere en abstrakt klasse?
    Det var jeg ikke klar over, men det er vel fortsatt mulig å lage din egen klasse som arver fra den, og instansiere denne? Jeg er på tynn is her...

    Tanken er SSH-brukere også skal kunne utføre kommandoer uten at det settes opp egne permissions for dem.
    Hm. Ja det blir noe litt annet enn chat, men jeg husker jeg leste noe om det en gang også. Skal vi se... jo, jeg snublet nemlig over en plugin som er nødt til å gjøre dette:
    http://dev.bukkit.org/bukkit-plugins/sudo/

    En CommandSender er ikke nødvendigvis en Player, f.eks. hvis kommandoen kommer fra konsollet. Sudo beviser at det også er mulig å få det til å se ut som kommandoen kom fra en annen spiller som ikke egentlig er innlogget.


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #8 på: 29. Mars 2015, 20:18 pm »
  • [applaud]0
  • [smite]0
  • jo, jeg snublet nemlig over en plugin som er nødt til å gjøre dette:
    http://dev.bukkit.org/bukkit-plugins/sudo/

    Vet du hvor jeg kan finne kildekoden?



    Hva med en klasse som implementerer både OfflinePlayer og CommandSender (og noen spiller-relaterte småklasser)? Den kan "pakke inn" en instans av OfflinePlayer som hentes ved å kalle Bukkit.getServer().getOfflinePlayer(UUID) og omdirigere alle de uinteressante funksjonene til denne.



    Hvorfor i all verden implementerer ikke OfflinePlayer Permissible? Jeg må implementere Permissible. Til hvor kan jeg omdirigere Permissible-funksjoner? Har APIet funksjoner som behandler permissions uten et Permissible-objekt? Eller er det en annen måte å få tak i et Permissible-objekt?

    EDIT: Det ser ut som om PermissibleBase gjør det jeg ønsker
    « Siste redigering: 30. Mars 2015, 00:57 am av BrutalOst »



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #9 på: 30. Mars 2015, 06:18 am »
  • [applaud]0
  • [smite]0
  • Shat? Som i "dreit"? :D


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #10 på: 29. April 2015, 23:18 pm »
  • [applaud]0
  • [smite]0
  • Det ser ut som det er en bedre idé å implementere Player. Å bruke dekorasjonsmønsteret her vil medføre 500+ linjer med vedlikeholdsuvennlig kode. Å bruke refleksjon ser ut som en bedre idé, men siden jeg kommer fra C er jeg nødt til å være skeptisk til det. Tips?



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #11 på: 30. April 2015, 08:49 am »
  • [applaud]0
  • [smite]0
  • Her må jeg bare melde pass, så godt kjenner jeg hverken Java eller C/C++


    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #12 på: 30. April 2015, 16:25 pm »
  • [applaud]0
  • [smite]0
  • Dekoratørmønsteret:
    Kode: [Velg]
    Player proxy = new MyPlayer(getServer().getPlayer("eksempel"));

    class MyPlayer implements Player {
      Player inner;
      MyPlayer(Player inner) {
        this.inner = inner;
      }
      // interessant funksjon
      @Override
      void sendMessage(String msg) {
        // skriv til SSH-strøm
      }
      // uinteressant funksjon
      @Override
      boolean hasPermission(String perm) {
        return this.inner.hasPermission(perm);
      }
      // uinteressant funksjon ganger 100; 500 stygge linjer
    }

    Refleksjon:
    Kode: [Velg]
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    Player proxy = (Player) Proxy.newProxyInstance(Player.class.getClassLoader(), new Class[] { Player.class }, new MyInvocationHandler(getServer().getPlayer("eksempel")));

    class MyInvocationHandler implements InvocationHandler {
      Player inner;
      MyInvocationHandler(Player inner) {
        this.inner = inner;
      }
      @Override
      Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("sendMessage")) {
          // skriv til SSH-strøm
        }
        else {
          return method.invoke(inner, args);
        }
      }
    }
    « Siste redigering: 30. April 2015, 16:40 pm av BrutalOst »



    Utlogget Floyd-ATC

    • Livstidsdiktator
    • Administrator
    • Guru
    • *****
    • Innlegg: 542
    • Karma: +12/-0
      • MSN Messenger - floyd@atc.no
      • Vis profil
      • floyd.atc.no
      • E-post
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #13 på: 30. April 2015, 17:34 pm »
  • [applaud]0
  • [smite]0
  • Jeg forstår ikke hvorfor du må lage 500 x overrides, hele poenget med subclassing er da å gjenbruke superklassen sine metoder unntatt de du ønsker å overstyre? Jeg vet at dette skyldes at jeg ikke forstår hvordan Player-klassen fungerer, men kan du forklare det?




    -Floyd.

    --
    Det finnes 10 typer mennesker;
    de som forstår binærtall, de som ikke gjør det, og de som forstår Grey code.

    Utlogget Cybersyn

    • n00b
    • *
    • Innlegg: 2
    • Karma: +1/-0
      • Vis profil
      • localhost
    Sv: IRC var en fiasko, men hva med SSH?
    « Svar #14 på: 01. Mai 2015, 00:03 am »
  • [applaud]0
  • [smite]0
  • Da er det jo ikke rart du ikke forstår. Player er et interface, ser du. Alle metodene er abstrakte - tomme og ubrukelige. Klasser som arver fra et interface må implementere alle metodene. Det eneste Player selv inneholder, er regler for hvordan subklasser ser ut og oppfører seg.

    Player er en del av Bukkit, et API som er designet for å representere forskjellige implementeringer av Minecraft serveren (først og fremst, men ikke kun CraftBukkit). Bukkit har også regler for hvordan implementeringer skal se ut og oppføre seg. For eksempel bestemmer Bukkit at implementeringen må sørge for at Bukkit.getPlayer(UUID) returnerer et objekt som følger reglene til Player.

    I de fleste tilfeller representerer Bukkit CraftBukkit. Ved å fordøye kildekoden til CraftBukkit kan vi skimte at Bukkit.getPlayer(UUID) som regel er en instans av CraftPlayer, som implementerer Player. Men siden CraftPlayer ikke er en del av APIet har man ikke grunnlag for å vite dette, og det regnes som veldig dårlig idé å bruke funksjoner fra CraftBukkit uten at det foregår gjennom APIet.

    En annen ting å tenke på er at man aldri kaller konstruktøren til Player - Player er abstrakt og har ingen konstruktør. Man kaller APIet, som gir deg en instans av en ukjent klasse som implementerer Player. Derfor må man bruke en form for proxy for å omdirigere de interessante metodene fra Player-instansen. Oftest vil man bruke dekoratørmønsteret, men i tilfelle interfacet er stort, noe man trygt kan si at Player er, blir det forferdelig rotete å bruke dekoratørmønsteret.

    Javas refleksjon går ut på å bruke eller manipulere klasser på en måte som bestemmes ved runtime. Refleksjon er ikke mulig i programmeringsspråk som C og C++.

    Klokka er mye nå...

    Dokumentasjon på Player
    Kildekoden til Player
    Kildekoden til CraftPlayer
    « Siste redigering: 01. Mai 2015, 08:53 am av BrutalOst »