Join us on Discord!
You can help CodeWalrus stay online by donating here.
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - ACagliano

#1
Update 10.0

HASHLIB has been renamed to CryptX and the entire project has been split up along functional lines into 3 libraries: HASHLIB, ENCRYPT, and ENCODEX. HASHLIB provides hashing, hmac, and related functionality (like hash-based mask generation, hmac-pbkdf, etc). ENCRYPT provides the secure RNG, AES, and RSA. ENCODEX provides an ASN.1 parser, Base 64 encoding/decoding, and BPP encoding/decoding.

Documentation is no longer in the git repository or in the artifacts on github and is now available as a docusite on github: https://acagliano.github.io/cryptx/index.html

Download: https://github.com/acagliano/cryptx/releases/latest
#2
Update v9.3
https://github.com/acagliano/hashlib/releases/tag/v9.3

Major Changes to AES implementation
  • aes_loadkey() is now aes_init()
  • Most of the cipher initialization now happens via the aes_init() function, including the nonce, the cipher mode, and the padding mode, and other functionalities.
  • Cipher configuration parameters passed as flags bitwise-OR'd together.
  • Padding in CBC mode is now added internally within the last block of encryption. Callable functions for padding are no longer used and have been removed.
  • Cipher state "contexts" loaded with init() are stateful and one-directional.Once a context is used for encryption or decryption, attempting to use it for the opposite operation will return an error. Two-way communication now needs two contexts initialized with the same key and parameters, but the correct nonce.
  • Encrypt and decrypt are now chainable operations. This means that `aes_encrypt(msg1+msg2)` is functionally-identical to `aes_encrypt(msg1) + aes_encrypt(msg2)`, once padding is cleared (if applicable). Same is true for decrypt.

New API for AES
aes_init(aes_ctx* ctx, const void* key, size_t keylen, const void* iv, uint24_t flags);
aes_encrypt(aes_ctx* ctx, void* plaintext, size_t len, void* ciphertext);
aes_decrypt(aes_ctx* ctx, void* ciphertext, size_t len, void* plaintext);

Arguments for Flags
// cipher mode (2-bit flag)
AES_MODE_CBC     // default
AES_MODE_CTR

// padding mode (2-bit flag)
PAD_PKCS7        // default
PAD_ISO2

// CTR mode nonce length (4-bit flag)
AES_CTR_NONCELEN(len)     // default = 8 bytes

// CTR mode counter length (4-bit flag)
AES_CTR_COUNTERLEN(len)     // default = 8 bytes


// Ex1: Set CTR mode, with 8 byte nonce length and 4 byte counter length
aes_init(&ctx, key, sizeof key, iv, AES_MODE_CTR | AES_CTR_NONCELEN(8) | AES_CTR_COUNTERLEN(4));

// Ex2: Set CBC mode, with padding mode ISO-9797 M2
aes_init(&ctx, key, sizeof key, iv, AES_MODE_CBC | PAD_ISO2);

Test away!
#3
Update and API revision

HASHLIB's API got a bit of a facelift recently with the function set changing nomenclature depending on what function is being served by the group of functions. No longer are hashlib functions prefixed with hashlib_, they are prefixed with a class-esque namespace indicating what they do. Like so:

Invocations of the Secure RNG within HASHLIB look like this:
csrand_init();     initializes the entropy source internally
csrand_get();      returns a random 32-bit unsigned int     
csrand_fill();     fills a buffer to a size with random bytes
Invocations of Hashing look like this:
hash_ctx hash;
uint8_t out[32];
hash_init(&hash, ALG_NAME)     initializes a context of type ALG_NAME
hash_update(&hash, data, len)
hash_final(&hash, out)
hash_mgf1(..., ALG_NAME)

/* Due to the structure of the hash context, the following are
viable alternatives to hash_update and hash_final:
uint8_t out[32];
hash_ctx hash;
hash_init(&hash, SHA256);
hash.update(&hash.Hash, data, len);
hash.final(&hash.Hash, out);
Invocations of HMAC are set up and have the same alternatives as hashing:
hmac_init()
hmac_update()
hmac_final()

hmac_pbkdf2(..., ALG_NAME)
The AES cipher is invoked like so:
aes_loadkey()
aes_encrypt()
aes_decrypt()
The RSA cipher is invoked like so:
rsa_encrypt()
// The RSA encryptor takes a hash ID specifier so that, if other hashes
// are added at some point, they can be used with OAEP internal to RSA.
Digest operations look like this:
digest_tostring()
digest_compare()

The latest update is available here.
The header has some slight issues in the documentation... stay tuned for a 9.1 update for a fix, but everything works as of v9.
https://github.com/acagliano/hashlib/releases/latest

I am also opening the floor if anyone wants to contribute hashing algorithms. Fast hashes like sha512, sha1 welcome, as well as slower hashes like argon.
#4
Quote from: DJ Omnimaga on February 05, 2022, 06:27:57 PMI'm glad to see this worked on still :), I wonder how much of this will be of use for your other project TI-Trek? (eg server credentials)
TI-Trek does actually use HASHLIB for login, and TI-Trek is actually my method of testing it. TI-Trek's login process is like so:
  • Users register on the web deck (website). Doing so generates them a login token, which is a PBKDF2 key exported into an appvar. They place that appvar on their calculator.
  • Running the game with that appvar present imports the key to user settings and deletes the keyfile.
  • Login to the Trek server causes the server to generate an RSA keypair. The length of the key is configurable between 1024 and 2048. The public key is sent to the calculator. The public exponent is the standard 65537.
  • The calculator uses the SPRNG to generate an AES key that is 256-bits long. That key is encrypted with RSA and sent to the server.
  • The server decrypts that key and sets up an AES session.
  • The calculator AES-encrypts the login token, which the server decrypts to authenticate the user. An account with a matching token is logged into.
  • The AES session is then destroyed.
Because the RSA implementation only encrypts, you have to let the remote host, usually a more-powerful server, actually set up the RSA session, then the AES key goes from calculator to server. It's a bit of a caveat, since doing the necessary legwork to set up an RSA session on a calculator would be computationally intensive and take a long time. But, it is a fully secure construction.

But even apart from TI-Trek, I'm hoping other people will find use of this too. It certainly is of significant use to anyone doing networking who needs secure channels.
#5
    An eighth release of HASHLIB is now available for download. It adds two new implementations as well as some side-channel resistance enhancements. The new library release offers the following:
    • A hardware-based secure RNG
    • SHA-256 hash
    • SHA-256 HMAC
    • SHA-256 MGF1
    • PBKDF2 via SHA-256 HMAC
    • Advanced Encryption Standard (AES), for 128, 192, and 256 bit keys
    • automatic application and stripping of preferred AES padding schemes (ISO-9797 M2 or PKCS#7), where applicable
    • RSA public key encryption for public modulus between 1024 and 2048 bits
    • Automatic application and stripping of RSAEP-OAEP via PKCS#1 v2.2
    • Authentication of SSL certificates signed with RSA with SHA-256
    • Digest comparison function resistant to timing analysis
    • Digest to hex-string function

    In addition, the following measures were taken for side channel resistance:
    • All user-facing encryptor functions zero all memory from the start of the current stack frame to the bottom of the stack before handing back control, to prevent state leak.
    • All user-facing encryptor functions disable interrupts while running, which prevents the OS from responding to USB activity. This serves to stop attempts to map the contents of the device memory while sensitive functions are running.

    In addition, the documentation is split into a "Quick Reference" for general assistance, and a Cryptanalysis that provides more technical details (for peer-review).

    HASHLIB is still under analysis and peer-review to continue to harden it. Feel free to contribute suggestions for this.

https://github.com/acagliano/hashlib/releases/latest
#6
Update HASHLIB moves into RC-1

With all the thanks in the world to jacobly from Cemetech for the modular exponentiation function we needed for RSA, HASHLIB is now formally complete and in release candidate phase (apart from the possibility of adding ECDSA in the distant future) and has been released on github for testing.

As many of you may know and others will learn by reading this, HASHLIB contains the following crytographic implementations:

<> A secure PRNG that produces ~96 bits of entropy per 32-bit integer generated.
<> The SHA-256 cryptographic hash.
<> An implementation of Advanced Encryption Standard (AES), for 128, 192, and 256 bit keys.
<> An implementation of RSA encryption up to 2048 bits in key length.
<> An implementation of the appropriate padding schemes for the above encryptions.
<> An implementation of SSL signature verification using the RSA with SHA-256 signing algorithm.

Feel free to download and test against commonly used cryptography libraries and report back on compatibility or lack thereof.

https://github.com/acagliano/hashlib/releases/tag/v7-RC1
#7
UPDATE 0.0.103

The TI-Trek client now has full version matching capabilities. What this means is that when you connect to a TI-Trek server, you will automatically be served the client version that the server requires, which will be relaunched. You will also be automatically served the default (or custom, if supported) graphics pack for that version. No more user fussing over "do I have the right client version?" or "Do I have the right graphics pack?". The server will make sure you do. Also, if you are connecting to a server that needs an earlier version than you have, it will autodowngrade in that case. However, all servers will be hardcoded to not start if you are not requiring a minimum default of the first version that supports RSA (when implemented).

I will soon add the capability to the server to have the version(s) specified and to fetch the gfx and the client automatically into the correct directories to serve them.

#8
I posted about this a while ago on Cemetech and forgot to put it here as well, so here it is.

In addition to my other two big projects (TI-Trek and HASHLIB), I've also been working on another project. It started off as a Steam-style client for connecting to online games such as TI-Trek, but I soon decided it could serve a more targeted purpose. Thus, the project has been rebranded Vapor Package Manager, or VPM, for short.

BOS Package Manager (BPM) is beckadamtheinventor's project, so I will let him elaborate on that end of things, but I included it here and in the topic title to draw some attention to that existing as well.

This project will imitate the functionality of `apt-get`, `apt`, `Homebrew`, `Macports` or any other "package manager" you would have available to you on a *nix style system. It will be released as a Libload-lib with a few functions: `vpm_install(<package>, [options])`, `vpm_remove(<filename>, <filetype>)` and `vpm_reload(void)`. The install function will query the download server for a package with that name. The remove function will essentially just call ti_Delete. The reload function can be used to reload the program that is currently being executed without crashing (this reload mechanism is already implemented in the VAPOR client and it works pretty reliably).

On the host side, the download mirror consists of a directory, `packages` forked into `bpm` for BOS and `vpm` for VAPOR. In each, each available package is in a folder with the package name. For example, Project TI-Trek would be in a folder named `titrek`. That folder would contain any internal dependencies of the project--this is the main program, graphics packs, configurations...whatever is part of the project. The directory also contains a manifest file, manifest.json, in which the author name, description of the project, and external dependencies are listed. For example, for project TI-Trek, the manifest file might look like this:

# manifest.json
{
    "author": "acagliano",
    "description": "A multiplayer space-combat game",
    "pkg-depends": ["hashlib", "srldrvce", "clibs"]
}
When the client requests the package titrek, all internal dependencies are fetched. So TITREK.8xp and TrekGFX.8xv. It also parses the "pkg-depends" and fetches the contents of those packages, as well as any dependencies of those packages, constructing a dependency chain (with repetitive dependencies being pruned). So titrek would fetch hashlib which has no dependencies, srldrvce which has a dependency on usbdrvce (which has no dependencies), and clibs which contains the default toolchain libraries. All of the needed files will be streamed to your calculator, updating a manifest table on your calculator which contains the name, type, and SHA-256 of the downloaded program. Files will only be redownloaded if the SHA-256 of the file on the server does not match that in the local manifest.

I believe Beck will craft BPM to function similarly, but I will let him elaborate if he wishes.


---------
As for the other part of "VAPOR", Vapor Proxy Service (VPS), that is a network I have set up for people who want to host calculator game servers, or servers for other calculator utilities such as VPM, BPM, and more to do so. It's free, but I may throw ads on explainer pages for the hosted servers, just to help with the maintenance costs of the server (electricity, internet, domain name, you know the kind). VPS will also support opening a proxy connection between itself and your own server if you want to self-host, but also use some of the security features I plan to implement in VPS.

VPM and VPS will both support packet encryption via HASHLIB. And *if* beck does not support powmod for vint exponents (So I can RSADecrypt within hashlib) then I will also set up a host for the calculator to commune with that can validate SSL certificates that the calculator sends it (I will have to do some research on this).
#9
The Time Has Come!! for another progress update.

HASHLIB v6 is out on Github: https://github.com/acagliano/hashlib/releases/latest

Here's What's New:
(1) MGF1 hashing function is added. It uses SHA-256 and hashes a given length of data as well as a 4-byte counter.
(2) OAEP now uses MGF1 (as is standard) instead of cyclic SHA-256.
(3) SPRNG now minimizes entropy loss due to correlation (thanks, Zeroko!) and runs ~1.5x faster for generating large pools of random data. The entropy pool is reduced from 192 bytes to 119 bytes, but each time we update a byte in the pool from the entropy source, it is a composite of 7 distinct reads xor'd together.
(4) SPRNGRandom() rewritten in assembly. Thanks to jacobly for optimization and some small code corrections.
(5) SPRNG now uses FastMem for its SHA memory and entropy pool to accelerate even faster.
(6) AES ECB-mode single block encrypt/decrypt functions exposed to let skilled users construct their own cipher modes
Still waiting on vint powmod to be fixed in the bigintce library, and then RSA will be added for v7.
#10
For the past few months, I've been working with beckadamtheinventor and others on HASHLIB, a library that provides d*mn-near industry standard encryption for the TI-84+ CE. It is a Libload Library, meaning it works the same way as the other libraries distributed with the toolchain (GRAPHX, FILEIOC, etc). Simply send HASHLIB.8xv to your calculator, move the .lib and .h file to your $CEDEV/lib/libload and $CEDEV/include directories respectively, then `#include <hashlib.h>` in your C project source. At this point you can use any of the functions in hashlib in your code.

HASHLIB provides the following crypto standards:


(1) SHA-256 Hash
A rather fast implementation of the SHA-256 crypto hash. First written in C, myself and beck endeavored to rewrite it in EZ80 Assembly because the C version was quite slow. I started things off with a code of the Init, Update, and Final functions and a skeleton of the transform function. Beck "corrected" any mistakes I made due to my Asm knowledge being (1) rusty, and (2) from Z80 Asm, as well as optimized all of the functions, and wrote much of the transform math routines. The current SHA-256 implementation sports a speed increase of 9x over the C version, and can fully hash GRAPHX, the largest of the toolchain libraries, in ~1.5 seconds.

(2) An Entropy-Based Secure Random Number Generator
This PRNG, unlike the toolchain's default is not deterministic in nature. It works by polling every bit in the CE's unmapped memory, searching for a floating bit with the least bias, upon which it sets its state internally to read from the address containing that bit. An add entropy function can be called by the user, but is also called automatically every time a random number is generated. This function reads from the entropy source to a reserved pool 192 bytes large. Because the maximum bias accepted by the entropy source selection function is 75/25, this gives us an entropy of .811 bit per byte, which multiplies out to ~150 bits of entropy for the entire pool. Bear in mind that is the worst case entropy possible--the entropy source selected will likely be higher. This entropy goes into generating a 32-bit random number; the pool is hashed using SHA-256 and then xored cyclically into the random number. The PRNG passes all Dieharder tests when run on 16KB of data as well as 1MB of data.

(3) Advanced Encryption Standard, CBC Mode
As the above implies, HASHLIB provides routines for encrypting and decrypting data using the CBC mode AES block cipher. This implementation has support for 128, 192, and 256 bit keys. Additionally, the CBC-MAC protocol is also provided, which you can pass data to and generate a message authentication code one block size in length. The library provides a macro that takes a plaintext, padding scheme, an output buffer, and two AES key schedules (one for encryption, one for MAC), as well as an IV. It encrypts the plaintext using the IV and encryption key schedule (padding appropriately), then runs the CBC-MAC algorithm on the encryption output and the IV, using the MAC key schedule (the MAC variant of the CBC cipher does not take an IV, but rather initializes it to a constant value causing it to act more like a counter than a nonce), appending the output of that MAC function to the ciphertext, providing an authenticated encryption scheme derived from IPsec.

(4) RSA, Encryption Only
A WIP; This library will also provide support for public key encryption over RSA keys of a modulus length up to 2048 bits. It will depend on a BIGINT lib by beckadamtheinventor currently a WIP as well (which is why RSA is still not added). Because generating two random coprime prime numbers of the required size on a CE would likely take a very long time, I decided to implement the encryption part only. Use this implementation in a server-centric setup where a server generates an RSA keypair, sends the public key to your calculator, and then the calculator encrypts a shared secret for AES, sends that to the server, and then the two communicate using AES.

(5) Padding Schemes (and Strip Padding)
HASHLIB provides functions to implement the ISO, PKCS7, and ANSIX928 padding schemes for AES as well as OAEP for RSA. For those who don't know, the ISO scheme pads with the byte 0x80 and then the bytes 0x00 until the end of the block. The PKCS7 scheme pads with the size of the padding. The ANSIX scheme pads with randomness. For OAEP, the scheme is implemented as indicated by the standard (a Feistel network where the message is padded with zeros to the modulus length minus 16, a 16-byte salt is generated, hashed, and xored with the message. The encoded message is then hashed and xored with the salt, and the encoded message and encoded salt are the OAEP-encoded plaintext). However, rather than an expandable hashing oracle, SHA-256 is applied cyclically to the message. This was done predominantly to save space in the library by using an existing hash rather than adding a new one specifically for this purpose.

The "Strip Padding" functions all properly strip the padding, returning the unpadded plaintext into a provided buffer as well as the size of the unpadded data into a return value. The only padding scheme it cannot decipher is ANSIX; if you are using this padding mode, you will have to know the expected plaintext size.


Other Functions Provided:
(a) hashlib_CompareDigest(): buffer comparison function that is resistant to timing attacks (written by jacobly in ez80 Assembly)
(b) Base64 Encode/Decode: Added these planning to implement bcrypt, but when Blowfish was replaced with AES, decided to just leave them in.
(c) Macros to return the padded size of an AES/RSA plaintext, useful for allocating a buffer large enough.
(d) Context erase function. When you are done with an SHA, AES, or RSA context, you can pass it to this function to write zeroes to it, erasing all traces of cryptographic state.

Special thanks to:
(1) beckadamtheinventor: Converted many of my C routines into EZ80 Assembly for speed
(2) Zeroko: Provided useful information on extracting entropy from the CE
(3) jacobly: Rewriting hashlib_CompareDigest() in EZ80 Assembly
(4) B-Con crypto algorithms, which was my source for the base of the AES and SHA implementations.

Project Page: http://cagstech.com/tistuff/hashlib/
Github: https://github.com/acagliano/hashlib
#11
Updates

CLIENT
A few mostly silent updates have pushed our latest version to 0.0.99. This latest version has a few small tweaks.

1) Firstly, the program now implements a minor change to the SRLDRVCE implementation that is believed to fix issues with Windows... The fix was actually within the SRL/USB driver packages, so you will need to update those as well.
2) The text input routine now wraps if you overflow the first line. It should do so without text shadow or graphical glitches but if any occur please report back.

SERVER
1) A few bugs in TrekFilter resolved... TrekFilter now properly handles packets with invalid characters.
2) Client disconnect is mostly stable now... Rather than having the client send a Disconnect packet to trigger the user to disconnect, we simply detect the bridge disconnecting, trigger a custom exception that clears the socket and deletes the client from the dict. This also allows TrekFilter to interact similarly without triggering exceptions. Let me tell ya'll, I have come to love the `raise` command :p.

WEB DECK
1) The User Info and Interface tabs are combined into one tab, "Info and UI". This page contains your user information and lets you edit it, but it also can display your player stats, ship stats, and provides links to two tools, the model uploader and the asset pack maker.
2) The asset pack maker tool deploys convimg to assist users in generating their own asset packs, using the procedures outlined by convimg. You can upload replacement sprites of the same size or direct the tool to use the default. When every sprite is assigned to either custom or default, you can then build your appvar. The Web Deck implements lib-yaml to generate a well-formed YAML, and then runs convimg. This feature has been lightly tested, but to all potential users, feel free to have at it.
3) The ship model uploader tool is similar to the asset helper, in that it allows you to upload your own custom model to define your ship appearance. For now, I will ask people to not use this tool, as there is no size limiter yet. That is part of the purpose of the new 3D Modeling Contest I started in the Graphics section of this forum--to ascertain a good limiting size. The page also implements WebGL to render any existing model you may have uploaded onto the page for quick viewing. That render IS actually the file upload button.

Also, for anyone interested in testing out existing features, please note that in order to access the Web Deck, you must register first with the server using your calculator. This is a feature meant to prevent stray accounts from people who do not intend to play. I may ease that in the future for certain extenuating circumstances, but as of now it stands.

Also also, anyone who previously made an account on the system will need to do so again... during a config change, I deleted the accounts directories. Sorry.

Also also also, 3d frame compositing is planned to happen server side, with the server implementing opengl or pyglet to generate a frame for each client, a compressed RLET sprite, that is then rendered to the client through the standard graphx calls. As of right now that, as well as collision, are the main things that needs to be done before we are ready to start putting out actual playable releases rather than feature showcases.

Also also also also, for those unaware, the client-server will implement an auto-update functionality allowing clients to be served, and then subsequently install and reload, newer versions of the game upon connecting to the server without dealing with the hasstle of doing it manually.
#12
Updates! Updates! Updates!

Version 0.0.99pre is still under development, but here is a few highlights for development so far.

1. Packets for MODULE_STATE_CHANGE, ENGINE_MAXIMUMS, and SETSPEED are now implemented at least in part. They don't check for certain statuses that might prevent the actions yet, but they do update, relay their responses to their calc, and have the effects propagate to your on-calc GUI.

2. The engine/speed configuration interface is now implemented. Accessed by pressing [Log]. You can scroll between your available engines, move sliders around to change your speed, then press [Sto] to engage your new speed.

3. With Debug Mode enabled in the client settings, the calculator now prints the Control Code and size of every packet it receives to the log widget.

4. Server-side, TrekFilter is now formally implemented into the service. TrekFilter is a custom firewall I made for the service, programmed to understand its protocol better than a system firewall could, and able to interact with your system firewall through the use of custom fail2ban jails.

Here a screenshot showing new (and some old) progress.


Here is a link to the Documentation: http://titrek.us/components/downloads/usersguide.php
#13
Update

Began work on a system for rendering client-side particles in response to certain things that occur in the game. One of those particles I have implemented... it is a crack that appears on your screen when your hull integrity falls below a certain level and remains there until your ship is repaired. It is a mask type of image that renders on top of everything and consequently obfuscates the display (if on top of it), like an actual crack in the screen would.


#14
Quote from: Caleb Hansberry on September 29, 2020, 06:41:13 AMI love all the network backbone and security! Looks awesome and says great things about the CE's potential.
Thanks!

Update
The client can now send chat messages to the server.
The log display widget wraps text.
#15

Update - v0.0.95
Planned to make this the full combat beta, but some security enhancements to the server and the whole setup make it necessary to release a client and bridge update before then.


NEW FEATURE - Client-Side Server List
As of right now, the server to connect to (through the bridge) is no longer controlled by the bridge's config file... it's controlled by the calculator itself.

Slot 1 is set by default and cannot be edited. Slots 2-10 are blank and can be edited (so that the game can connect to other hosted instances of the server).

The client adds 2 new packets, CONNECT and DISCONNECT.
Connect: Instructs the bridge to open a tcp socket to the server or host name following the control code in the serial packet.
Disconnect: Instructs the bridge to close the current socket.
* So long as the calculator does not unplug or disconnect from the bridge, you can connect/disconnect/reconnect without needing to restart the bridge. *
* Special thanks to commandblockguy for implementing this change. *

NEW FEATURE - On-Calc Mini-Log
The calculator has a 4-line mini-log, with each log-line buffered to 50 characters. This log can display errors, info, debug messages, and server broadcasts. The widget has variable height based on how many of the 4 lines it needs to display, and also remains on the screen for a configurable time. Default is 100 ticks. Any time a new message is written to the log, the clock resets.

And here is the new Settings interface to change the log timeout:


NEW FEATURE - Server Supports SSL
This may have been posted in this thread earlier, but the server is written with an optional SSL context. This can be enabled in the server config. The actual handling of certificates and renewal is not something the server does, so anyone hosting an SSL instance will need to handle ensuring their SSL config is up to date. The SSL path is also configurable, it just needs to be readable by whatever user is running this service.
*As of right now, the bridge does not support SSL, so any SSL servers will be unable to be connected to.*

NEW FEATURE - Verification-Based Authentication
As an attempt to dissuade connections to this service that are not from the calculator, such as random port probes or script kiddies, the server now implements a code-based verification system. When a user registers an account, an 8-digit code is generated and written to the user's account file, as well as sent to the calculator for display. You will be required to log into the web deck and input your verification code before you will be able to log in to the game server. This will allow us to filter unsolicited connections, as well as remove any anomalous user accounts created.
Powered by EzPortal