Files
skevity/source/ssh_server_client.c

376 lines
9.3 KiB
C

/* #############################################################################
* # sshGameServer
* This is a test
*
* AUTHER: PreacherDHM
* DATE: 07/03/26
* #############################################################################
*/
/* This is a sample implementation of a libssh based SSH server */
#include "ssh_server_client.h"
#include "client_source/client.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
#include <pthread.h>
#include <signal.h>
#include <threads.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef DOCKER
#define RSA_LOCATION "./id_rsa"
#else
#define RSA_LOCATION "/root/.ssh/id_rsa"
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 32
#endif
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
int client_stop_thread = 0;
static int authenticated=0;
static int tries = 0;
static int error = 0;
static ssh_channel chan[30] ={NULL};
typedef struct {
ssh_session session;
ServerConfig* config;
} 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 shell_resize(ssh_session s, ssh_channel ch, int width, int height,
int pxwidth, int pwheight, void* userdata) {
client* cli = (client*)userdata;
cli->resize = 1;
cli->newHeight = height;
cli->newWidth = width;
printf("setting Size to %d,%d\n", cli->newWidth, cli->newHeight);
return 0;
}
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;
client* cli = (client*)userdata;
cli->resize = 1;
cli->newHeight = y;
cli->newWidth = x;
printf("setting Size to %d,%d\n", cli->newWidth, cli->newHeight);
printf("Terminal is %s\n", term);
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,
// .channel_pty_window_change_function = shell_resize,
//
//};
static ssh_channel new_session_channel(ssh_session session, void *userdata){
(void) session;
(void) userdata;
client* c = (client*)userdata;
ssh_channel* cli = &c->channel;
printf("Allocated session channel for id %d\n", *(int*)userdata);
*cli = ssh_channel_new(session);
ssh_callbacks_init(&c->channel_cb);
ssh_set_channel_callbacks(*cli, &c->channel_cb);
return *cli;
}
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;
client* cli = (client*)malloc(sizeof(client));
printf("og cliet addres %d\n", cli);
cli->server_cb = (struct ssh_server_callbacks_struct){
.userdata = cli,
.auth_none_function = auth_none,
.auth_password_function = auth_password,
.channel_open_request_session_function = new_session_channel,
};
cli->channel_cb = (struct ssh_channel_callbacks_struct){
.userdata = cli,
.channel_pty_request_function = pty_request,
.channel_shell_request_function = shell_request,
.channel_pty_window_change_function = shell_resize,
};
ssh_callbacks_init(&cli->server_cb);
ssh_set_server_callbacks(session, &cli->server_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 && cli->channel != 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 = (char*)malloc(30);
int sendBuffSize = 30;
int counter = 0;
if(error){
printf("Error, exiting loop\n");
} else
printf("Authenticated and got a channel\n");
// Data Init
data.config->cbs.init_var = cli;
data.config->cbs.run_var = cli;
data.config->cbs.stop_var = cli;
data.config->cbs.ssh_init(cli);
cli->term = (ssh_terminal_data) {
.inputBuffer = buf,
.outputBuffer = sendBuf,
.inputSize = sizeof(buf),
.outputSize = &sendBuffSize,
.channel = cli->channel,
};
do{ // Update
i = 1;
i = ssh_channel_read_nonblocking(cli->channel, buf, sizeof(buf)-1, 0);
// code go here
if(data.config->cbs.ssh_run(&cli->term,cli) == 0) {
// code go here
//if (ssh_channel_write(c, tb.outputBuffer, *tb.outputSize) == 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') {
data.config->cbs.ssh_stop(cli);
ssh_channel_close(cli->channel);
ssh_channel_free(cli->channel);
return 0;
}
}
if(cli->resize > 0) {
printf("running resize %d,%d\n", cli->newWidth, cli->newHeight);
client_resize(cli->newWidth, cli->newHeight, cli);
cli->resize = 0;
}
//memset(buf,0,BUF_SIZE);
} while (!client_stop_thread);
data.config->cbs.ssh_stop(cli);
ssh_channel_close(cli->channel);
ssh_channel_free(cli->channel);
return 0;
}
void stop_server(int arg) {
printf("\nstopping server\n");
client_stop_thread = 1;
sleep(1);
exit(1);
}
int ssh_start(ServerConfig* conf){
ssh_session session;
ssh_bind sshbind;
signal(SIGSTOP, stop_server);
signal(SIGINT, stop_server);
signal(SIGTERM, stop_server);
int port = 2222;// conf->port;
int r =0;
sshbind=ssh_bind_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, RSA_LOCATION);
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port);
while(sshbind && !client_stop_thread){ //&& !client_stop_thread) {
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, conf};
d.config->stop = &client_stop_thread;
for(int i = 0; i < 12; i++) {
if(conf->clients[i] == 0) {
if(pthread_create(&conf->clients[i], NULL, Handel_Client, (void*)&d) < 0) {
ssh_disconnect(session);
}
conf->threadCount++;
break;
}
}
}
//for(int i = 0; i < 12; i++) {
// if(conf->clients[i] != 0) {
// printf("working on thread %d\n", i);
// sleep(1);
// pthread_cancel(conf->clients[i]);
// }
//}
printf("Done\n");
ssh_disconnect(session);
ssh_bind_free(sshbind);
ssh_finalize();
return 0;
}