Browse code

Initial implementation of sshchat client as a simple forwarder (with bugs)

Dario Rodriguez authored on 16/12/2015 21:52:13
Showing 5 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+myid
0 2
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+CC=gcc
2
+CFLAGS=-g -Wall -I../../webkernel/src
3
+LDFLAGS=
4
+
5
+all: sshchat
6
+
7
+sshchat: sshchat.o sbuf.o socklib.o
8
+	$(CC) sshchat.o sbuf.o socklib.o -o sshchat
9
+
10
+sbuf.o: ../../webkernel/src/sbuf.c
11
+	$(CC) $(CFLAGS) $(LDFLAGS) -c ../../webkernel/src/sbuf.c -o sbuf.o
12
+
13
+socklib.o: ../../webkernel/src/socklib.c
14
+	$(CC) $(CFLAGS) $(LDFLAGS) -c ../../webkernel/src/socklib.c -o socklib.o
15
+
16
+clean:
17
+	rm -f sshchat *.o
0 18
new file mode 100644
... ...
@@ -0,0 +1,138 @@
1
+/*
2
+ * sshchat.c
3
+ *
4
+ * Client component of sshchat, connects to server, identifies itself using ~/.sshchat file and forwards stdin/stdout.
5
+ *
6
+ * Author: Dario Rodriguez dario@softhome.net
7
+ * This program is licensed under the terms of the GPL v2.1+
8
+ */
9
+
10
+#include <stdlib.h>
11
+#include <stdio.h>
12
+#include <unistd.h>
13
+#include <string.h>
14
+#include <sys/types.h>
15
+#include <sys/stat.h>
16
+#include <fcntl.h>
17
+
18
+#include "socklib.h"
19
+#include "sbuf.h"
20
+
21
+#include "sshchat.h"
22
+
23
+#define MAXIDSIZE 128
24
+#define CONNTIMEOUT 2000
25
+#define SELECTTIMEOUT 1000
26
+
27
+#define BUFSIZE 16384
28
+
29
+#define INFD 0
30
+#define OUTFD 1
31
+
32
+int
33
+main(int argc, char *argv[])
34
+{
35
+	char id[MAXIDSIZE];
36
+	int fd,n;
37
+	char *ptr;
38
+	char *host,port;
39
+	long hostsize;
40
+	int socket;
41
+	sbuf *c2s,*s2c;
42
+	sselect *ssel;
43
+	int forcedexit;
44
+	int readfds[2];
45
+	int writefds[2];
46
+	int nreadfds;
47
+	int nwritefds;
48
+	int i;
49
+	int queued;
50
+	/* get the id */
51
+	if((fd=open(".sshchat",O_RDONLY))==-1)
52
+		return(-1); /* error */
53
+	if((n=read(fd,id,MAXIDSIZE))<1 || id[0]=='\n') {
54
+		close(fd),fd=-1;
55
+		return(-2); /* no id */
56
+	}
57
+	close(fd),fd=-1;
58
+	id[(n>=MAXIDSIZE)?MAXIDSIZE-1:n]='\0';
59
+	if((ptr=strchr(id,'\n'))!=NULL)
60
+		*ptr='\0';
61
+	/* open socket to server */
62
+	if((host=ipv4_genip("127.0.0.1",&hostsize))==NULL)
63
+		return(-3); /* couldn't resolv localhost */
64
+	if((port=ipv4_genport("sshchat",SERVERPORT))==-1) {
65
+		free(host),host=NULL;
66
+		return(-4); /* couldn't resolv port */
67
+	}
68
+	if((socket=ipv4_preconnect(host,hostsize,port))==-1) {
69
+		free(host),host=NULL;
70
+		return(-5); /* couldn't connect to localhost (1) */
71
+	}
72
+	if(ipv4_connect(socket,CONNTIMEOUT)==-1) {
73
+		free(host),host=NULL;
74
+		return(-6); /* couldn't connect to localhost (2) */
75
+	}
76
+	ipv4_postconnect(socket);
77
+	free(host),host=NULL,hostsize=0;
78
+	/* alloc I/O buffers */
79
+	if((c2s=sbuf_init(BUFSIZE))==NULL || (s2c=sbuf_init(BUFSIZE))==NULL) {
80
+		close(socket),socket=-1,sbuf_free(c2s),c2s=NULL;
81
+		return(-7); /* couldn't alloc buffers */
82
+	}
83
+	if((ssel=sselect_init())==NULL) {
84
+		close(socket),socket=-1,sbuf_free(c2s),c2s=NULL,sbuf_free(s2c),s2c=NULL;
85
+		return(-8); /* couldn't alloc select struct */
86
+	}
87
+	/* prefeed the identification */
88
+	sbuf_addstr(c2s,id);
89
+	sbuf_addstr(c2s,"\n");
90
+	/* forward data */
91
+	forcedexit=0;
92
+	while(!forcedexit) {
93
+		sselect_reset(ssel);
94
+		if(sbuf_count(c2s)<BUFSIZE)
95
+			sselect_addread(ssel,INFD,NULL);
96
+		if(sbuf_count(c2s)>0)
97
+			sselect_addwrite(ssel,socket,NULL);
98
+		if(sbuf_count(s2c)>0)
99
+			sselect_addwrite(ssel,OUTFD,NULL);
100
+		if(sbuf_count(s2c)<BUFSIZE)
101
+			sselect_addread(ssel,socket,NULL);
102
+		if(sselect_wait(ssel,SELECTTIMEOUT)<1)
103
+			continue;
104
+		nreadfds=sselect_getread(ssel,readfds,sizeof(readfds)/sizeof(readfds[1]));		
105
+		nwritefds=sselect_getwrite(ssel,writefds,sizeof(writefds)/sizeof(writefds[1]));		
106
+		for(i=0;i<nreadfds;i++) {
107
+			if(readfds[i]==INFD && sbuf_count(c2s)<BUFSIZE) {
108
+				if((queued=sock_queued(readfds[i]))==0) {
109
+					forcedexit=1;
110
+					break;
111
+				}
112
+				sbuf_discard(c2s);
113
+				sbuf_fill(c2s,INFD,queued);
114
+			}
115
+			if(readfds[i]==socket && sbuf_count(s2c)<BUFSIZE) {
116
+				if((queued=sock_queued(readfds[i]))==0) {
117
+					forcedexit=1;
118
+					break;
119
+				}
120
+				sbuf_discard(s2c);
121
+				sbuf_fill(s2c,socket,queued);
122
+			}
123
+		}
124
+		for(i=0;i<nwritefds;i++) {
125
+			if(writefds[i]==OUTFD && sbuf_count(s2c)>0)
126
+				sbuf_send(s2c,OUTFD,sbuf_count(s2c));
127
+			if(writefds[i]==socket && sbuf_count(c2s)>0)
128
+				sbuf_send(c2s,socket,sbuf_count(c2s));
129
+		}
130
+	}	
131
+	/* normal exit */
132
+	close(socket),socket=-1;
133
+	sbuf_free(c2s),c2s=NULL;
134
+	sbuf_free(s2c),s2c=NULL;
135
+	sselect_free(ssel),ssel=NULL;
136
+	return(0);
137
+}
138
+
0 139
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+/*
2
+ * sshchat.h
3
+ *
4
+ * Common constants for server and client parts of sshchat.
5
+ *
6
+ * Author: Dario Rodriguez dario@softhome.net
7
+ * This program is licensed under the terms of the GPL v2.1+
8
+ */
9
+
10
+#define SERVERPORT 4798
11
+
12
+
0 13
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+/*
2
+ * sshchatd.c
3
+ *
4
+ * Server component of sshchat, serves as mailbox for disconnected users.
5
+ *
6
+ * Author: Dario Rodriguez dario@softhome.net
7
+ * This program is licensed under the terms of the GPL v2.1+
8
+ */
9
+
10
+