Experimental ssh stuff. I doubt this is going to work.

This commit is contained in:
Andrew Pamment 2016-08-07 09:54:37 +10:00
parent 9125a69aa0
commit 04e352eae6
3 changed files with 253 additions and 64 deletions

181
bbs.c
View File

@ -20,7 +20,7 @@ struct bbs_config conf;
struct user_record *gUser;
int gSocket;
int sshBBS;
int usertimeout;
int timeoutpaused;
@ -145,11 +145,19 @@ void s_printf(char *fmt, ...) {
}
void s_putchar(char c) {
write(gSocket, &c, 1);
if (sshBBS) {
putchar(c);
} else {
write(gSocket, &c, 1);
}
}
void s_putstring(char *c) {
write(gSocket, c, strlen(c));
if (sshBBS) {
printf("%s", c);
} else {
write(gSocket, c, strlen(c));
}
}
void s_displayansi_p(char *file) {
@ -194,31 +202,35 @@ char s_getchar() {
int len;
do {
len = read(gSocket, &c, 1);
if (sshBBS) {
len = read(stdin, &c, 1);
} else {
len = read(gSocket, &c, 1);
}
if (len == 0) {
disconnect("Socket Closed");
}
while (c == 255) {
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
} else if (c == 255) {
usertimeout = 10;
return c;
}
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
}
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
if (!sshBBS) {
while (c == 255) {
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
} else if (c == 255) {
usertimeout = 10;
return c;
}
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
}
len = read(gSocket, &c, 1);
if (len == 0) {
disconnect("Socket Closed");
}
}
}
}
if (c == '\r') {
@ -298,8 +310,10 @@ void disconnect(char *calledby) {
}
dolog("Node %d disconnected (%s)", mynode, calledby);
sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, mynode);
remove(buffer);
close(gSocket);
remove(buffer);
if (!sshBBS) {
close(gSocket);
}
exit(0);
}
@ -456,7 +470,7 @@ void automessage_display() {
s_getc();
}
void runbbs(int socket, char *ip) {
void runbbs_real(int socket, char *ip, int ssh) {
char buffer[256];
char password[17];
@ -476,10 +490,17 @@ void runbbs(int socket, char *ip) {
ipaddress = ip;
write(socket, iac_echo, 3);
write(socket, iac_sga, 3);
gUser = NULL;
if (!ssh) {
write(socket, iac_echo, 3);
write(socket, iac_sga, 3);
gUser = NULL;
sshBBS = 0;
} else {
sshBBS = 1;
}
gSocket = socket;
s_printf("Magicka BBS v%d.%d (%s), Loading...\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_STR);
@ -506,7 +527,9 @@ void runbbs(int socket, char *ip) {
if (mynode == 0) {
s_printf("Sorry, all nodes are in use. Please try later\r\n");
close(socket);
if (!ssh) {
close(socket);
}
exit(1);
}
@ -527,42 +550,70 @@ void runbbs(int socket, char *ip) {
s_displayansi("issue");
s_printf("\e[0mEnter your Login Name or NEW to create an account\r\n");
s_printf("Login:> ");
if (!ssh) {
s_printf("\e[0mEnter your Login Name or NEW to create an account\r\n");
s_printf("Login:> ");
s_readstring(buffer, 25);
s_readstring(buffer, 25);
if (strcasecmp(buffer, "new") == 0) {
user = new_user();
} else {
s_printf("\r\nPassword:> ");
s_readpass(password, 16);
user = check_user_pass(buffer, password);
if (user == NULL) {
s_printf("\r\nIncorrect Login.\r\n");
disconnect("Incorrect Login");
}
if (strcasecmp(buffer, "new") == 0) {
user = new_user();
} else {
s_printf("\r\nPassword:> ");
s_readpass(password, 16);
user = check_user_pass(buffer, password);
if (user == NULL) {
s_printf("\r\nIncorrect Login.\r\n");
disconnect("Incorrect Login");
}
for (i=1;i<=conf.nodes;i++) {
sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i);
if (stat(buffer, &s) == 0) {
nodefile = fopen(buffer, "r");
if (!nodefile) {
dolog("Error opening nodefile!");
disconnect("Error opening nodefile!");
}
fgets(buffer, 256, nodefile);
for (i=1;i<=conf.nodes;i++) {
sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i);
if (stat(buffer, &s) == 0) {
nodefile = fopen(buffer, "r");
if (!nodefile) {
dolog("Error opening nodefile!");
disconnect("Error opening nodefile!");
}
fgets(buffer, 256, nodefile);
if (strcasecmp(user->loginname, buffer) == 0) {
fclose(nodefile);
s_printf("\r\nYou are already logged in.\r\n");
disconnect("Already Logged in");
if (strcasecmp(user->loginname, buffer) == 0) {
fclose(nodefile);
s_printf("\r\nYou are already logged in.\r\n");
disconnect("Already Logged in");
}
fclose(nodefile);
}
fclose(nodefile);
}
}
}
}
}
} else {
if (gUser != NULL) {
user = gUser;
s_printf("\e[0mWelcome back %s. Press enter to log in...\r\n", gUser->loginname);
s_getc();
for (i=1;i<=conf.nodes;i++) {
sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i);
if (stat(buffer, &s) == 0) {
nodefile = fopen(buffer, "r");
if (!nodefile) {
dolog("Error opening nodefile!");
disconnect("Error opening nodefile!");
}
fgets(buffer, 256, nodefile);
if (strcasecmp(user->loginname, buffer) == 0) {
fclose(nodefile);
s_printf("\r\nYou are already logged in.\r\n");
disconnect("Already Logged in");
}
fclose(nodefile);
}
}
} else {
gUser = new_user();
user = gUser;
}
}
sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, mynode);
nodefile = fopen(buffer, "w");
if (!nodefile) {
@ -649,3 +700,11 @@ void runbbs(int socket, char *ip) {
dolog("%s is logging out, on node %d", user->loginname, mynode);
disconnect("Log out");
}
void runbbs(int socket, char *ip) {
runbbs_real(socket, ip, 0);
}
void runbbs_ssh(char *ip) {
runbbs_real(-1, ip, 1);
}

View File

@ -110,8 +110,9 @@ void chat_system(struct user_record *user) {
char *message;
char *sep;
char *target;
memset(inputbuffer, 0, 80);
if (conf.irc_server == NULL) {
memset(inputbuffer, 0, 80);
if (conf.irc_server == NULL) {
s_putstring("\r\nSorry, Chat is not supported on this system.\r\n");
return;
}

131
main.c
View File

@ -17,8 +17,14 @@
extern struct bbs_config conf;
extern struct user_record *gUser;
int ssh_pid = -1;
void sigterm_handler(int s)
{
if (ssh_pid != -1) {
kill(ssh_pid, SIGTERM);
}
remove(conf.pid_file);
exit(0);
}
@ -376,12 +382,85 @@ int ssh_authenticate(ssh_session p_ssh_session) {
} while(1);
}
char *ssh_getip(ssh_session session) {
struct sockaddr_storage tmp;
struct sockaddr_in *sock;
unsigned int len = 100;
char ip[100] = "\0";
getpeername(ssh_get_fd(session), (struct sockaddr*)&tmp, &len);
sock = (struct sockaddr_in *)&tmp;
inet_ntop(AF_INET, &sock->sin_addr, ip, len);
return strdup(ip);
}
static int ssh_copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
ssh_channel chan = (ssh_channel)userdata;
char buf[2048];
int sz = 0;
if(!chan) {
close(fd);
return -1;
}
if(revents & POLLIN) {
sz = read(fd, buf, 2048);
if(sz > 0) {
ssh_channel_write(chan, buf, sz);
}
}
if(revents & POLLHUP) {
ssh_channel_close(chan);
sz = -1;
}
return sz;
}
static int ssh_copy_chan_to_fd(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata) {
int fd = *(int*)userdata;
int sz;
(void)session;
(void)channel;
(void)is_stderr;
sz = write(fd, data, len);
return sz;
}
static void ssh_chan_close(ssh_session session, ssh_channel channel, void *userdata) {
int fd = *(int*)userdata;
(void)session;
(void)channel;
close(fd);
}
struct ssh_channel_callbacks_struct ssh_cb = {
.channel_data_function = ssh_copy_chan_to_fd,
.channel_eof_function = ssh_chan_close,
.channel_close_function = ssh_chan_close,
.userdata = NULL
};
void serverssh(int port) {
ssh_session p_ssh_session;
ssh_bind p_ssh_bind;
int err;
int pid;
int shell;
int fd;
ssh_channel chan = 0;
int bbs_pid;
char *ip;
ssh_event event;
short events;
err = ssh_init();
if (err == -1) {
fprintf(stderr, "Error starting SSH server.\n");
@ -458,8 +537,45 @@ void serverssh(int port) {
exit(-1);
}
ip = ssh_getip(p_ssh_session);
bbs_pid = forkpty(&fd, NULL, NULL, NULL);
if (bbs_pid == 0) {
runbbs_ssh(ip);
exit(0);
}
free(ip);
ssh_cb.userdata = &fd;
ssh_callbacks_init(&ssh_cb);
ssh_set_channel_callbacks(chan, &cb);
events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
event = ssh_event_new();
if(event == NULL) {
ssh_finalize();
exit(0);
}
if(ssh_event_add_fd(event, fd, events, ssh_copy_fd_to_chan, chan) != SSH_OK) {
ssh_finalize();
exit(0);
}
if(ssh_event_add_session(event, p_ssh_session) != SSH_OK) {
ssh_finalize();
exit(0);
}
do {
ssh_event_dopoll(event, 1000);
} while(!ssh_channel_is_closed(chan));
ssh_event_remove_fd(event, fd);
ssh_event_remove_session(event, p_ssh_session);
ssh_event_free(event);
}
ssh_finalize();
exit(0);
} else if (pid > 0) {
@ -494,6 +610,19 @@ void server(int port) {
exit(1);
}
if (conf.ssh_server) {
// fork ssh server
ssh_pid = fork();
if (ssh_pid > 0) {
serverssh(conf.ssh_port);
exit(0);
}
if (ssh_pid != 0) {
fprintf(stderr, "Error forking ssh server.");
}
}
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
remove(conf.pid_file);