converted to git
[tridge/junkcode.git] / sockspy-spnego.c
1 #define _GNU_SOURCE
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <time.h>
7 #include <errno.h>
8 #include <sys/socket.h>
9 #include <netdb.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #include <sys/time.h>
15 #include <arpa/inet.h>
16 #include <netinet/in.h>
17
18 #define MAX(a,b) ((a)>(b)?(a):(b))
19
20 #define SEARCH "GSS-SPNEGO"
21 #define REPLACE "GSS-XXXXXX"
22
23 #define SEARCH2 "NTLMSSP"
24 #define REPLACE2 "NTLMXXX"
25
26 static void replace_str(char *buf, int n)
27 {
28         void *p;
29         p = memmem(buf, n, SEARCH, strlen(SEARCH));
30         if (p) {
31                 printf("Replaced %s with %s\n", SEARCH, REPLACE);
32                 memcpy(p, REPLACE, strlen(REPLACE));
33         }
34         p = memmem(buf, n, SEARCH2, strlen(SEARCH2));
35         if (p) {
36                 printf("Replaced %s with %s\n", SEARCH2, REPLACE2);
37                 memcpy(p, REPLACE2, strlen(REPLACE2));
38         }
39 }
40
41 /* open a socket to a tcp remote host with the specified port */
42 static int open_socket_out(const char *host, int port)
43 {
44         struct sockaddr_in sock_out;
45         int res;
46         struct hostent *hp;  
47         struct in_addr addr;
48
49         res = socket(PF_INET, SOCK_STREAM, 0);
50         if (res == -1) {
51                 return -1;
52         }
53
54         if (inet_pton(AF_INET, host, &addr) > 0) {
55                 memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
56         } else {
57                 hp = gethostbyname(host);
58                 if (!hp) {
59                         fprintf(stderr,"unknown host %s\n", host);
60                         return -1;
61                 }
62                 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
63         }
64
65         sock_out.sin_port = htons(port);
66         sock_out.sin_family = PF_INET;
67
68         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
69                 close(res);
70                 fprintf(stderr,"failed to connect to %s (%s)\n", 
71                         host, strerror(errno));
72                 return -1;
73         }
74
75         return res;
76 }
77
78
79 /*
80   open a socket of the specified type, port and address for incoming data
81 */
82 int open_socket_in(int port)
83 {
84         struct sockaddr_in sock;
85         int res;
86         int one=1;
87
88         memset(&sock,0,sizeof(sock));
89
90 #ifdef HAVE_SOCK_SIN_LEN
91         sock.sin_len = sizeof(sock);
92 #endif
93         sock.sin_port = htons(port);
94         sock.sin_family = AF_INET;
95
96         res = socket(AF_INET, SOCK_STREAM, 0);
97         if (res == -1) { 
98                 fprintf(stderr, "socket failed\n"); return -1; 
99                 return -1;
100         }
101
102         setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
103
104         if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
105                 return(-1); 
106         }
107
108         return res;
109 }
110
111 /* write to a file descriptor, making sure we get all the data out or
112  * die trying */
113 static void write_all(int fd, unsigned char *s, size_t n)
114 {
115         while (n) {
116                 int r;
117                 r = write(fd, s, n);
118                 if (r <= 0) {
119                         exit(1);
120                 }
121                 s += r;
122                 n -= r;
123         }
124 }
125
126 static void main_loop(int sock1, int sock2)
127 {
128         unsigned char buf[1024];
129         int log1, log2, i=0;
130
131         do {
132                 char *fname1, *fname2;
133                 asprintf(&fname1, "sockspy-in.%d", i);
134                 asprintf(&fname2, "sockspy-out.%d", i);
135                 log1 = open(fname1, O_WRONLY|O_CREAT|O_EXCL, 0644);
136                 log2 = open(fname2, O_WRONLY|O_CREAT|O_EXCL, 0644);
137                 free(fname1);
138                 free(fname2);
139                 i++;
140         } while (i<1000 && (log1 == -1 || log2 == -1));
141
142         if (log1 == -1 || log2 == -1) {
143                 fprintf(stderr,"Failed to open log files\n");
144                 return;
145         }
146
147         while (1) {
148                 fd_set fds;
149                 int ret;
150
151                 FD_ZERO(&fds);
152                 FD_SET(sock1, &fds);
153                 FD_SET(sock2, &fds);
154
155                 ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
156                 if (ret == -1 && errno == EINTR) continue;
157                 if (ret <= 0) break;
158
159                 if (FD_ISSET(sock1, &fds)) {
160                         int n = read(sock1, buf, sizeof(buf));
161                         if (n <= 0) break;
162
163                         replace_str(buf, n);
164
165                         write_all(sock2, buf, n);
166                         write_all(log1, buf, n);
167                 }
168
169                 if (FD_ISSET(sock2, &fds)) {
170                         int n = read(sock2, buf, sizeof(buf));
171                         if (n <= 0) break;
172
173                         replace_str(buf, n);
174
175                         write_all(sock1, buf, n);
176                         write_all(log2, buf, n);
177                 }
178         }       
179 }
180
181 int main(int argc, char *argv[])
182 {
183         int listen_port, dest_port;
184         char *host;
185         int sock_in;
186         int sock_out;
187         int listen_fd;
188         struct sockaddr addr;
189         int in_addrlen = sizeof(addr);
190
191         if (argc < 4) {
192                 printf("Usage: sockspy <inport> <host> <port>\n");
193                 exit(1);
194         }
195
196         listen_port = atoi(argv[1]);
197         host = argv[2];
198         dest_port = atoi(argv[3]);
199
200         listen_fd = open_socket_in(listen_port);
201
202         if (listen_fd == -1) {
203                 fprintf(stderr,"listen on port %d failed - %s\n", 
204                         listen_port, strerror(errno));
205                 exit(1);
206         }
207
208         if (listen(listen_fd, 5) == -1) {
209                 fprintf(stderr,"listen failed\n");
210                 exit(1);
211         }
212
213         sock_in = accept(listen_fd,&addr,&in_addrlen);
214
215         if (sock_in == -1) {
216                 fprintf(stderr,"accept on port %d failed - %s\n", 
217                         listen_port, strerror(errno));
218                 exit(1);
219         }
220
221         close(listen_fd);
222
223         sock_out = open_socket_out(host, dest_port);
224         if (sock_out == -1) {
225                 exit(1);
226         }
227
228         main_loop(sock_in, sock_out);
229         return 0;
230 }