commit d87932a2245d39df5da701ce024a6c8731cb4ec3 Author: PreacherDHM Date: Thu Mar 12 11:00:23 2026 -0700 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc3fd6a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +.cache +bin + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4ab9072 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.30.0) + +project(sshGameServer VERSION 0.1) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_COLOR_DIAGNOSTICS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_subdirectory(source) +add_subdirectory(external) diff --git a/README.md b/README.md new file mode 100644 index 0000000..87fdea1 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# sshGameServer +This is a test diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 0000000..f517f42 --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,3 @@ +# ADD Externals HERE +# add_subdirectory(external) + diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..d0f1726 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,12 @@ +# ADD SOURCES HERE +set(SOURCE_FILES + main.c +) + +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +target_link_libraries( + ${PROJECT_NAME} + ssh + tart +) diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..a90089c --- /dev/null +++ b/source/main.c @@ -0,0 +1,403 @@ +/* ############################################################################# + * # sshGameServer + * This is a test + * + * AUTHER: PreacherDHM + * DATE: 07/03/26 + * ############################################################################# + */ +/* This is a sample implementation of a libssh based SSH server */ +/* +Copyright 2003-2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ARGP_H +#include +#endif +#include +#include +#include + + +#ifndef BUF_SIZE +#define BUF_SIZE 2049 +#endif + +#ifndef KEYS_FOLDER +#ifdef _WIN32 +#define KEYS_FOLDER +#else +#define KEYS_FOLDER "/etc/ssh/" +#endif +#endif + +#define USER "myuser" +#define PASSWORD "mypassword" + + + +static int authenticated=0; +static int tries = 0; +static int error = 0; +static ssh_channel chan[30] ={NULL}; + +typedef struct { + ssh_session session; + int id; +} ud; + +static int auth_none(ssh_session session, + const char *user, + void *userdata) +{ + ssh_string banner = NULL; + + (void)user; /* unused */ + (void)userdata; /* unused */ + + //ssh_set_auth_methods(session, + // SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); + + banner = ssh_string_from_char("Loggin To your skelvetty acount!\n"); + if (banner != NULL) { + ssh_send_issue_banner(session, banner); + } + ssh_string_free(banner); + + authenticated ++; + return SSH_AUTH_SUCCESS; +} + +static int auth_password(ssh_session session, const char *user, + const char *password, void *userdata){ + (void)userdata; + printf("Authenticating user %s pwd %s\n",user, password); + if(strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){ + authenticated = 1; + printf("Authenticated\n"); + return SSH_AUTH_SUCCESS; + } + if (tries >= 3){ + printf("Too many authentication tries\n"); + ssh_disconnect(session); + error = 1; + return SSH_AUTH_DENIED; + } + tries++; + return SSH_AUTH_DENIED; +} + +#ifdef WITH_GSSAPI +static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){ + ssh_gssapi_creds creds = ssh_gssapi_get_creds(session); + (void)userdata; + printf("Authenticating user %s with gssapi principal %s\n",user, principal); + if (creds != NULL) + printf("Received some gssapi credentials\n"); + else + printf("Not received any forwardable creds\n"); + printf("authenticated\n"); + authenticated = 1; + return SSH_AUTH_SUCCESS; +} +#endif + +static int pty_request(ssh_session session, ssh_channel channel, const char *term, + int x,int y, int px, int py, void *userdata){ + (void) session; + (void) channel; + (void) term; + (void) x; + (void) y; + (void) px; + (void) py; + (void) userdata; + printf("Allocated terminal\n"); + return 0; +} + +static int shell_request(ssh_session session, ssh_channel channel, void *userdata){ + (void)session; + (void)channel; + (void)userdata; + printf("Allocated shell\n"); + return 0; +} +struct ssh_channel_callbacks_struct channel_cb = { + .channel_pty_request_function = pty_request, + .channel_shell_request_function = shell_request +}; + +static ssh_channel new_session_channel(ssh_session session, void *userdata){ + (void) session; + (void) userdata; + printf("Allocated session channel for id %d\n", *(int*)userdata); + *(ssh_channel*)userdata = ssh_channel_new(session); + ssh_callbacks_init(&channel_cb); + ssh_set_channel_callbacks(*(ssh_channel*)userdata, &channel_cb); + return *(ssh_channel*)userdata; +} + + +#ifdef HAVE_ARGP_H +const char *argp_program_version = "libssh server example " +SSH_STRINGIFY(LIBSSH_VERSION); +const char *argp_program_bug_address = ""; + +/* Program documentation. */ +static char doc[] = "libssh -- a Secure Shell protocol implementation"; + +/* A description of the arguments we accept. */ +static char args_doc[] = "BINDADDR"; + +/* The options we understand. */ +static struct argp_option options[] = { + { + .name = "port", + .key = 'p', + .arg = "PORT", + .flags = 0, + .doc = "Set the port to bind.", + .group = 0 + }, + { + .name = "hostkey", + .key = 'k', + .arg = "FILE", + .flags = 0, + .doc = "Set the host key.", + .group = 0 + }, + { + .name = "rsakey", + .key = 'r', + .arg = "FILE", + .flags = 0, + .doc = "Set the rsa key (deprecated alias for 'k').", + .group = 0 + }, + { + .name = "verbose", + .key = 'v', + .arg = NULL, + .flags = 0, + .doc = "Get verbose output.", + .group = 0 + }, + { + .name = "config", + .key = 'f', + .arg = "FILE", + .flags = 0, + .doc = "Configuration file to use.", + .group = 0 + }, + {NULL, 0, NULL, 0, NULL, 0} +}; + +/* Parse a single option. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state) { + /* Get the input argument from argp_parse, which we + * know is a pointer to our arguments structure. + */ + ssh_bind sshbind = state->input; + + switch (key) { + case 'p': + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg); + break; + case 'r': + case 'k': + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg); + break; + case 'v': + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3"); + break; + case 'f': + ssh_bind_options_parse_config(sshbind, arg); + break; + case ARGP_KEY_ARG: + if (state->arg_num >= 1) { + /* Too many arguments. */ + argp_usage (state); + } + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg); + break; + case ARGP_KEY_END: + if (state->arg_num < 1) { + /* Not enough arguments. */ + argp_usage (state); + } + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +/* Our argp parser. */ +static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL}; +#endif /* HAVE_ARGP_H */ + +void* Handel_Client(void* d) { + ud data = *(ud*)d; + char buf[BUF_SIZE]; + int r; + int i; + ssh_event mainloop; + ssh_session session = data.session; + ssh_channel c; + + struct ssh_server_callbacks_struct cb = { + .userdata = (void*)&c, + .auth_none_function = auth_none, + .auth_password_function = auth_password, + .channel_open_request_session_function = new_session_channel, + }; + + ssh_callbacks_init(&cb); + ssh_set_server_callbacks(session, &cb); + + if (ssh_handle_key_exchange(session)) { + printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); + return NULL; + } + + ssh_set_auth_methods(session, SSH_AUTH_METHOD_NONE); + + mainloop = ssh_event_new(); + ssh_event_add_session(mainloop, session); + + while (!(authenticated && c != NULL)){ + if(error) + break; + r = ssh_event_dopoll(mainloop, -1); + if (r == SSH_ERROR){ + printf("Error : %s\n",ssh_get_error(session)); + ssh_disconnect(session); + return NULL; + } + } + + char sendBuf[1024] = {0}; + int counter = 0; + if(error){ + printf("Error, exiting loop\n"); + } else + printf("Authenticated and got a channel\n"); + // GameInit() + do{ + i = 1; + snprintf(sendBuf, 1024, "Counter: %d, id: %d\r", counter, data.id); + char kittyBuffer[30] = {0}; + sprintf(kittyBuffer, "\e[>%d", 0b1000); + if (ssh_channel_write(c, kittyBuffer, 30) == SSH_ERROR) { + printf("error writing to channel\n"); + return NULL; + } + i = ssh_channel_read_nonblocking(c, buf, sizeof(buf)-1, 0); + counter++; + // code go here + // GameUpdate() + // code go here + if (ssh_channel_write(c, sendBuf, 1024) == SSH_ERROR) { + printf("error writing to channel\n"); + return NULL; + } + if(i>0) { + + buf[i] = '\0'; + printf("%s", buf); + fflush(stdout); + if(buf[0] == '\x03') { + ssh_disconnect(data.session); + ssh_free(data.session); + authenticated--; + //ssh_channel_close(c); + //ssh_channel_free(c); + return 0; + } + + //if (buf[0] == '\x0d') { + // if (ssh_channel_write(chan, "\n", 1) == SSH_ERROR) { + // printf("error writing to channel\n"); + // return 1; + // } + + // printf("\n"); + //} + } + } while (true); + + return 0; +} +int main(int argc, char **argv){ + ssh_session session; + ssh_bind sshbind; + + int port = 2222; + int r =0; + + sshbind=ssh_bind_new(); + + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, "./rsa.key"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port); + //ssh_bind_set_blocking(sshbind, 0); + +#ifdef HAVE_ARGP_H + /* + * Parse our arguments; every option seen by parse_opt will + * be reflected in arguments. + */ + argp_parse (&argp, argc, argv, 0, 0, sshbind); +#else + (void) argc; + (void) argv; +#endif + + while(sshbind) { + + if(ssh_bind_listen(sshbind)<0){ + printf("Error listening to socket: %s\n",ssh_get_error(sshbind)); + return 1; + } + session=ssh_new(); + r=ssh_bind_accept(sshbind,session); + if(r==SSH_ERROR){ + printf("error accepting a connection : %s\n",ssh_get_error(sshbind)); + return 1; + } + ud d = {session, authenticated}; + + pthread_t thread_id; + if(pthread_create(&thread_id, NULL, Handel_Client, (void*)&d) < 0) { + ssh_disconnect(session); + } + } + // GameEnd() + //ssh_disconnect(session); + //ssh_bind_free(sshbind); + //ssh_finalize(); + return 0; +} + +