|
Packit |
16808d |
|
|
Packit |
16808d |
/*
|
|
Packit |
16808d |
Clear Channel Sametime Proxy Utility
|
|
Packit |
16808d |
The Meanwhile Project
|
|
Packit |
16808d |
|
|
Packit |
16808d |
This is a tool which can act as a proxy between a client and a
|
|
Packit |
16808d |
sametime server, which will force all channels to be created without
|
|
Packit |
16808d |
any encryption method. This makes reverse-engineering much, much
|
|
Packit |
16808d |
easier.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
It also outputs the messages sent to and from the client to stdout
|
|
Packit |
16808d |
as hex pairs. If compiled with USE_HEXDUMP, output will be printed
|
|
Packit |
16808d |
via `hexdump -C`
|
|
Packit |
16808d |
|
|
Packit |
16808d |
All it really does is nab all Channel Create messages, strip the
|
|
Packit |
16808d |
offered ciphers portion from the message and replace it with an
|
|
Packit |
16808d |
empty ciphers list.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
Christopher O'Brien <siege@preoccupied.net>
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <netinet/in.h>
|
|
Packit |
16808d |
#include <netdb.h>
|
|
Packit |
16808d |
#include <stdlib.h>
|
|
Packit |
16808d |
#include <stdio.h>
|
|
Packit |
16808d |
#include <string.h>
|
|
Packit |
16808d |
#include <sys/socket.h>
|
|
Packit |
16808d |
#include <unistd.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <glib.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <mw_common.h>
|
|
Packit |
16808d |
#include <mw_message.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct proxy_side {
|
|
Packit |
16808d |
int sock;
|
|
Packit |
16808d |
GIOChannel *chan;
|
|
Packit |
16808d |
gint chan_io;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guchar *buf;
|
|
Packit |
16808d |
gsize buf_size;
|
|
Packit |
16808d |
gsize buf_recv;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void (*forward)(const guchar *buf, gsize len);
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static struct proxy_side client;
|
|
Packit |
16808d |
static struct proxy_side server;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void hexdump(const char *txt, const guchar *buf, gsize len) {
|
|
Packit |
16808d |
FILE *fp;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(txt) fprintf(stdout, "\n%s\n", txt);
|
|
Packit |
16808d |
fflush(stdout);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
fp = popen("hexdump -C", "w");
|
|
Packit |
16808d |
fwrite(buf, len, 1, fp);
|
|
Packit |
16808d |
fflush(fp);
|
|
Packit |
16808d |
pclose(fp);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void put_msg(struct mwMessage *msg, struct mwOpaque *o) {
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
mwMessage_put(b, msg);
|
|
Packit |
16808d |
mwPutBuffer_finalize(o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
mwOpaque_put(b, o);
|
|
Packit |
16808d |
mwOpaque_clear(o);
|
|
Packit |
16808d |
mwPutBuffer_finalize(o, b);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void side_buf_free(struct proxy_side *s) {
|
|
Packit |
16808d |
g_free(s->buf);
|
|
Packit |
16808d |
s->buf = NULL;
|
|
Packit |
16808d |
s->buf_size = 0;
|
|
Packit |
16808d |
s->buf_recv = 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void munge_redir() {
|
|
Packit |
16808d |
struct mwMessage *msg;
|
|
Packit |
16808d |
struct mwOpaque o = { 0, 0 };
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg = mwMessage_new(mwMessage_LOGIN_CONTINUE);
|
|
Packit |
16808d |
put_msg(msg, &o);
|
|
Packit |
16808d |
mwMessage_free(msg);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
server.forward(o.data, o.len);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void munge_create(struct proxy_side *side,
|
|
Packit |
16808d |
struct mwMsgChannelCreate *msg) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwOpaque o = { 0, 0 };
|
|
Packit |
16808d |
GList *l;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(l = msg->encrypt.items; l; l = l->next) {
|
|
Packit |
16808d |
mwEncryptItem_clear(l->data);
|
|
Packit |
16808d |
g_free(l->data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
g_list_free(msg->encrypt.items);
|
|
Packit |
16808d |
msg->encrypt.items = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg->encrypt.mode = 0x00;
|
|
Packit |
16808d |
msg->encrypt.extra = 0x00;
|
|
Packit |
16808d |
msg->encrypt.flag = FALSE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
put_msg(MW_MESSAGE(msg), &o);
|
|
Packit |
16808d |
side->forward(o.data, o.len);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void side_process(struct proxy_side *s, const guchar *buf, gsize len) {
|
|
Packit |
16808d |
struct mwOpaque o = { .len = len, .data = (guchar *) buf };
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
guint16 type;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! len) return;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(&o);
|
|
Packit |
16808d |
type = guint16_peek(b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
switch(type) {
|
|
Packit |
16808d |
case mwMessage_LOGIN_REDIRECT:
|
|
Packit |
16808d |
munge_redir();
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case mwMessage_CHANNEL_CREATE:
|
|
Packit |
16808d |
{
|
|
Packit |
16808d |
struct mwMessage *msg = mwMessage_get(b);
|
|
Packit |
16808d |
munge_create(s, (struct mwMsgChannelCreate *) msg);
|
|
Packit |
16808d |
mwMessage_free(msg);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
default:
|
|
Packit |
16808d |
{
|
|
Packit |
16808d |
struct mwPutBuffer *pb = mwPutBuffer_new();
|
|
Packit |
16808d |
struct mwOpaque po = { 0, 0 };
|
|
Packit |
16808d |
mwOpaque_put(pb, &o);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&po, pb);
|
|
Packit |
16808d |
s->forward(po.data, po.len);
|
|
Packit |
16808d |
mwOpaque_clear(&po);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define ADVANCE(b, n, count) { b += count; n -= count; }
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* handle input to complete an existing buffer */
|
|
Packit |
16808d |
static gsize side_recv_cont(struct proxy_side *s, const guchar *b, gsize n) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gsize x = s->buf_size - s->buf_recv;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n < x) {
|
|
Packit |
16808d |
memcpy(s->buf+s->buf_recv, b, n);
|
|
Packit |
16808d |
s->buf_recv += n;
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
memcpy(s->buf+s->buf_recv, b, x);
|
|
Packit |
16808d |
ADVANCE(b, n, x);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(s->buf_size == 4) {
|
|
Packit |
16808d |
struct mwOpaque o = { .len = 4, .data = s->buf };
|
|
Packit |
16808d |
struct mwGetBuffer *gb = mwGetBuffer_wrap(&o);
|
|
Packit |
16808d |
x = guint32_peek(gb);
|
|
Packit |
16808d |
mwGetBuffer_free(gb);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n < x) {
|
|
Packit |
16808d |
guchar *t;
|
|
Packit |
16808d |
x += 4;
|
|
Packit |
16808d |
t = (guchar *) g_malloc(x);
|
|
Packit |
16808d |
memcpy(t, s->buf, 4);
|
|
Packit |
16808d |
memcpy(t+4, b, n);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
side_buf_free(s);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
s->buf = t;
|
|
Packit |
16808d |
s->buf_size = x;
|
|
Packit |
16808d |
s->buf_recv = n + 4;
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
side_buf_free(s);
|
|
Packit |
16808d |
side_process(s, b, x);
|
|
Packit |
16808d |
ADVANCE(b, n, x);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
side_process(s, s->buf+4, s->buf_size-4);
|
|
Packit |
16808d |
side_buf_free(s);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return n;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* handle input when there's nothing previously buffered */
|
|
Packit |
16808d |
static gsize side_recv_empty(struct proxy_side *s, const guchar *b, gsize n) {
|
|
Packit |
16808d |
struct mwOpaque o = { .len = n, .data = (guchar *) b };
|
|
Packit |
16808d |
struct mwGetBuffer *gb;
|
|
Packit |
16808d |
gsize x;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n < 4) {
|
|
Packit |
16808d |
s->buf = (guchar *) g_malloc0(4);
|
|
Packit |
16808d |
memcpy(s->buf, b, n);
|
|
Packit |
16808d |
s->buf_size = 4;
|
|
Packit |
16808d |
s->buf_recv = n;
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gb = mwGetBuffer_wrap(&o);
|
|
Packit |
16808d |
x = guint32_peek(gb);
|
|
Packit |
16808d |
mwGetBuffer_free(gb);
|
|
Packit |
16808d |
if(! x) return n - 4;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n < (x + 4)) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
x += 4;
|
|
Packit |
16808d |
s->buf = (guchar *) g_malloc(x);
|
|
Packit |
16808d |
memcpy(s->buf, b, n);
|
|
Packit |
16808d |
s->buf_size = x;
|
|
Packit |
16808d |
s->buf_recv = n;
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
ADVANCE(b, n, 4);
|
|
Packit |
16808d |
side_process(s, b, x);
|
|
Packit |
16808d |
ADVANCE(b, n, x);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return n;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gsize side_recv(struct proxy_side *s, const guchar *b, gsize n) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n && (s->buf_size == 0) && (*b & 0x80)) {
|
|
Packit |
16808d |
ADVANCE(b, n, 1);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(n == 0) {
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(s->buf_size > 0) {
|
|
Packit |
16808d |
return side_recv_cont(s, b, n);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
return side_recv_empty(s, b, n);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void feed_buf(struct proxy_side *side, const guchar *buf, gsize n) {
|
|
Packit |
16808d |
guchar *b = (guchar *) buf;
|
|
Packit |
16808d |
gsize remain = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(side != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
while(n > 0) {
|
|
Packit |
16808d |
remain = side_recv(side, b, n);
|
|
Packit |
16808d |
b += (n - remain);
|
|
Packit |
16808d |
n = remain;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int read_recv(struct proxy_side *side) {
|
|
Packit |
16808d |
guchar buf[2048];
|
|
Packit |
16808d |
int len;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
len = read(side->sock, buf, 2048);
|
|
Packit |
16808d |
if(len > 0) feed_buf(side, buf, (gsize) len);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return len;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void done() {
|
|
Packit |
16808d |
close(client.sock);
|
|
Packit |
16808d |
close(server.sock);
|
|
Packit |
16808d |
exit(0);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gboolean read_cb(GIOChannel *chan,
|
|
Packit |
16808d |
GIOCondition cond,
|
|
Packit |
16808d |
gpointer data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct proxy_side *side = data;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(cond & G_IO_IN) {
|
|
Packit |
16808d |
ret = read_recv(side);
|
|
Packit |
16808d |
if(ret > 0) return TRUE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(side->sock) {
|
|
Packit |
16808d |
g_source_remove(side->chan_io);
|
|
Packit |
16808d |
close(side->sock);
|
|
Packit |
16808d |
side->sock = 0;
|
|
Packit |
16808d |
side->chan = NULL;
|
|
Packit |
16808d |
side->chan_io = 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
done();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return FALSE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void client_cb(const guchar *buf, gsize len) {
|
|
Packit |
16808d |
if(server.sock) {
|
|
Packit |
16808d |
hexdump("client -> server", buf, len);
|
|
Packit |
16808d |
write(server.sock, buf, len);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gboolean listen_cb(GIOChannel *chan,
|
|
Packit |
16808d |
GIOCondition cond,
|
|
Packit |
16808d |
gpointer data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct sockaddr_in rem;
|
|
Packit |
16808d |
guint len = sizeof(rem);
|
|
Packit |
16808d |
struct proxy_side *side = data;
|
|
Packit |
16808d |
int sock;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
sock = accept(side->sock, (struct sockaddr *) &rem, &len;;
|
|
Packit |
16808d |
g_assert(sock > 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_source_remove(side->chan_io);
|
|
Packit |
16808d |
side->sock = sock;
|
|
Packit |
16808d |
side->chan = g_io_channel_unix_new(sock);
|
|
Packit |
16808d |
side->chan_io = g_io_add_watch(side->chan, G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
Packit |
16808d |
read_cb, side);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return FALSE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void init_client(int port) {
|
|
Packit |
16808d |
/* start listening on the local port specifier */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct sockaddr_in sin;
|
|
Packit |
16808d |
int sock;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
Packit |
16808d |
g_assert(sock >= 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
memset(&sin, 0, sizeof(struct sockaddr_in));
|
|
Packit |
16808d |
sin.sin_family = PF_INET;
|
|
Packit |
16808d |
sin.sin_port = htons(port);
|
|
Packit |
16808d |
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
|
Packit |
16808d |
g_assert_not_reached();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(listen(sock, 1) < 0)
|
|
Packit |
16808d |
g_assert_not_reached();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
client.forward = client_cb;
|
|
Packit |
16808d |
client.sock = sock;
|
|
Packit |
16808d |
client.chan = g_io_channel_unix_new(sock);
|
|
Packit |
16808d |
client.chan_io = g_io_add_watch(client.chan, G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
Packit |
16808d |
listen_cb, &client);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void server_cb(const guchar *buf, gsize len) {
|
|
Packit |
16808d |
if(client.sock) {
|
|
Packit |
16808d |
hexdump("server -> client", buf, len);
|
|
Packit |
16808d |
write(client.sock, buf, len);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* address lookup used by init_sock */
|
|
Packit |
16808d |
static void init_sockaddr(struct sockaddr_in *addr,
|
|
Packit |
16808d |
const char *host, int port) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct hostent *hostinfo;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
addr->sin_family = AF_INET;
|
|
Packit |
16808d |
addr->sin_port = htons (port);
|
|
Packit |
16808d |
hostinfo = gethostbyname(host);
|
|
Packit |
16808d |
if(hostinfo == NULL) {
|
|
Packit |
16808d |
fprintf(stderr, "Unknown host %s.\n", host);
|
|
Packit |
16808d |
exit(1);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
addr->sin_addr = *(struct in_addr *) hostinfo->h_addr;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void init_server(const char *host, int port) {
|
|
Packit |
16808d |
/* connect to server on host/port */
|
|
Packit |
16808d |
struct sockaddr_in srvrname;
|
|
Packit |
16808d |
int sock;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
Packit |
16808d |
if(sock < 0) {
|
|
Packit |
16808d |
fprintf(stderr, "socket failure");
|
|
Packit |
16808d |
exit(1);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
init_sockaddr(&srvrname, host, port);
|
|
Packit |
16808d |
connect(sock, (struct sockaddr *)&srvrname, sizeof(srvrname));
|
|
Packit |
16808d |
|
|
Packit |
16808d |
server.forward = server_cb;
|
|
Packit |
16808d |
server.sock = sock;
|
|
Packit |
16808d |
server.chan = g_io_channel_unix_new(sock);
|
|
Packit |
16808d |
server.chan_io = g_io_add_watch(server.chan, G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
Packit |
16808d |
read_cb, &server);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int main(int argc, char *argv[]) {
|
|
Packit |
16808d |
char *host = NULL;
|
|
Packit |
16808d |
int client_port = 0, server_port = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
memset(&client, 0, sizeof(struct proxy_side));
|
|
Packit |
16808d |
memset(&server, 0, sizeof(struct proxy_side));
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(argc > 1) {
|
|
Packit |
16808d |
char *z;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
host = argv[1];
|
|
Packit |
16808d |
z = host;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
host = strchr(z, ':');
|
|
Packit |
16808d |
if(host) *host++ = '\0';
|
|
Packit |
16808d |
client_port = atoi(z);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
z = strchr(host, ':');
|
|
Packit |
16808d |
if(z) *z++ = '\0';
|
|
Packit |
16808d |
server_port = atoi(z);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(!host || !*host || !client_port || !server_port) {
|
|
Packit |
16808d |
fprintf(stderr,
|
|
Packit |
16808d |
( " Usage: %s local_port:remote_host:remote_port\n"
|
|
Packit |
16808d |
" Creates a locally-running sametime proxy which enforces"
|
|
Packit |
16808d |
" unencrypted channels\n" ),
|
|
Packit |
16808d |
argv[0]);
|
|
Packit |
16808d |
exit(1);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* @todo create signal handlers to cleanup sockets */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
init_client(client_port);
|
|
Packit |
16808d |
init_server(host, server_port);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_main_loop_run(g_main_loop_new(NULL, FALSE));
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|