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

167
bbs.c
View File

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

129
main.c
View File

@ -17,8 +17,14 @@
extern struct bbs_config conf; extern struct bbs_config conf;
extern struct user_record *gUser; extern struct user_record *gUser;
int ssh_pid = -1;
void sigterm_handler(int s) void sigterm_handler(int s)
{ {
if (ssh_pid != -1) {
kill(ssh_pid, SIGTERM);
}
remove(conf.pid_file); remove(conf.pid_file);
exit(0); exit(0);
} }
@ -376,12 +382,85 @@ int ssh_authenticate(ssh_session p_ssh_session) {
} while(1); } 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) { void serverssh(int port) {
ssh_session p_ssh_session; ssh_session p_ssh_session;
ssh_bind p_ssh_bind; ssh_bind p_ssh_bind;
int err; int err;
int pid; int pid;
int shell;
int fd;
ssh_channel chan = 0; ssh_channel chan = 0;
int bbs_pid;
char *ip;
ssh_event event;
short events;
err = ssh_init(); err = ssh_init();
if (err == -1) { if (err == -1) {
fprintf(stderr, "Error starting SSH server.\n"); fprintf(stderr, "Error starting SSH server.\n");
@ -458,8 +537,45 @@ void serverssh(int port) {
exit(-1); 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); exit(0);
} else if (pid > 0) { } else if (pid > 0) {
@ -494,6 +610,19 @@ void server(int port) {
exit(1); 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); socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) { if (socket_desc == -1) {
remove(conf.pid_file); remove(conf.pid_file);