]> andersk Git - libfaim.git/commitdiff
- Thu Sep 21 00:24:36 UTC 2000
authormid <mid>
Thu, 21 Sep 2000 00:52:15 +0000 (00:52 +0000)
committermid <mid>
Thu, 21 Sep 2000 00:52:15 +0000 (00:52 +0000)
   - Add socks5 proxy support (not tested real well, worked the
       few times a tried).
   - Added proxy support to faimtest.

CHANGES
aim_conn.c
faim/aim.h
utils/faimtest/faimtest.c

diff --git a/CHANGES b/CHANGES
index 3411e2774c72a56e838806d0b103085e428f834e..f1ce549df33253232f1d13e6b5d94fc8cb655b11 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
 
 No release numbers
 ------------------
+ - Thu Sep 21 00:24:36 UTC 2000
+   - Add socks5 proxy support (not tested real well, worked the 
+       few times a tried).
+   - Added proxy support to faimtest.
+
  - Tue Sep 19 03:10:07 UTC 2000
    - Add aim_setuserinterests() and aim_setdirectoryinfo()
    - Add ICQ away status
index 16ab711c5be8bac8e2e7f7bec093ff5f61cfbcd4..f35b7f93110f21731a4bad6c3197f050727a213d 100644 (file)
@@ -161,6 +161,154 @@ faim_internal struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess,
   return cur;
 }
 
+/*
+ * An extrememly quick and dirty SOCKS5 interface. 
+ */
+static int aim_proxyconnect(struct aim_session_t *sess, 
+                           char *host, unsigned short port,
+                           int *statusret)
+{
+  int fd = -1;
+
+  if (strlen(sess->socksproxy.server)) { /* connecting via proxy */
+    int i;
+    unsigned char buf[512];
+    struct sockaddr_in sa;
+    struct hostent *hp;
+    char *proxy;
+    unsigned short proxyport = 1080;
+
+    for(i=0;i<(int)strlen(sess->socksproxy.server);i++) {
+      if (sess->socksproxy.server[i] == ':') {
+       proxyport = atoi(&(sess->socksproxy.server[i+1]));
+       break;
+      }
+    }
+    proxy = (char *)malloc(i+1);
+    strncpy(proxy, sess->socksproxy.server, i);
+    proxy[i] = '\0';
+
+    if (!(hp = gethostbyname(proxy))) {
+      printf("proxyconnect: unable to resolve proxy name\n");
+      *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+      return -1;
+    }
+    free(proxy);
+
+    memset(&sa.sin_zero, 0, 8);
+    sa.sin_port = htons(proxyport);
+    memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+    sa.sin_family = hp->h_addrtype;
+  
+    fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+    if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+      printf("proxyconnect: unable to connect to proxy\n");
+      close(fd);
+      return -1;
+    }
+
+    i = 0;
+    buf[0] = 0x05; /* SOCKS version 5 */
+    if (strlen(sess->socksproxy.username)) {
+      buf[1] = 0x02; /* two methods */
+      buf[2] = 0x00; /* no authentication */
+      buf[3] = 0x02; /* username/password authentication */
+      i = 4;
+    } else {
+      buf[1] = 0x01;
+      buf[2] = 0x00;
+      i = 3;
+    }
+
+    if (write(fd, buf, i) < i) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+
+    if (read(fd, buf, 2) < 2) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+
+    if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
+      *statusret = EINVAL;
+      close(fd);
+      return -1;
+    }
+
+    /* check if we're doing username authentication */
+    if (buf[1] == 0x02) {
+      i  = aimutil_put8(buf, 0x01); /* version 1 */
+      i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
+      i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
+      i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
+      i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
+      if (write(fd, buf, i) < i) {
+       *statusret = errno;
+       close(fd);
+       return -1;
+      }
+      if (read(fd, buf, 2) < 2) {
+       *statusret = errno;
+       close(fd);
+       return -1;
+      }
+      if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
+       *statusret = EINVAL;
+       close(fd);
+       return -1;
+      }
+    }
+
+    i  = aimutil_put8(buf, 0x05);
+    i += aimutil_put8(buf+i, 0x01); /* CONNECT */
+    i += aimutil_put8(buf+i, 0x00); /* reserved */
+    i += aimutil_put8(buf+i, 0x03); /* address type: host name */
+    i += aimutil_put8(buf+i, strlen(host));
+    i += aimutil_putstr(buf+i, host, strlen(host));
+    i += aimutil_put16(buf+i, port);
+
+    if (write(fd, buf, i) < i) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+    if (read(fd, buf, 10) < 10) {
+      *statusret = errno;
+      close(fd);
+      return -1;
+    }
+    if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
+      *statusret = EINVAL;
+      close(fd);
+      return -1;
+    }
+
+  } else { /* connecting directly */
+    struct sockaddr_in sa;
+    struct hostent *hp;
+
+    if (!(hp = gethostbyname(host))) {
+      *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+      return -1;
+    }
+
+    memset(&sa.sin_zero, 0, 8);
+    sa.sin_port = htons(port);
+    memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+    sa.sin_family = hp->h_addrtype;
+  
+    fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+    if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+      close(fd);
+      fd = -1;
+    }
+  }
+  return fd;
+}
+
 /*
  * aim_newconn(type, dest)
  *
@@ -214,31 +362,19 @@ faim_export struct aim_conn_t *aim_newconn(struct aim_session_t *sess,
   strncpy(host, dest, i);
   host[i] = '\0';
 
-  hp = gethostbyname(host);
-  free(host);
-
-  if (hp == NULL) {
-    connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR);
-    faim_mutex_unlock(&connstruct->active);
-    return connstruct;
-  }
-
-  memset(&sa.sin_zero, 0, 8);
-  sa.sin_port = htons(port);
-  memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
-  sa.sin_family = hp->h_addrtype;
-  
-  connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
-  ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
-  if(ret < 0) {
+  if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) {
     connstruct->fd = -1;
     connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
+    free(host);
     faim_mutex_unlock(&connstruct->active);
     return connstruct;
-  }
+  } else
+    connstruct->fd = ret;
   
   faim_mutex_unlock(&connstruct->active);
 
+  free(host);
+
   return connstruct;
 }
 
@@ -372,6 +508,32 @@ faim_export int aim_conn_setlatency(struct aim_conn_t *conn, int newval)
   return 0;
 }
 
+/*
+ * Call this with your SOCKS5 proxy server parameters before
+ * the first call to aim_newconn().  If called with all NULL
+ * args, it will clear out a previously set proxy.  
+ *
+ * Set username and password to NULL if not applicable.
+ *
+ */
+faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password)
+{
+  /* clear out the proxy info */
+  if (!server || !strlen(server)) {
+    memset(sess->socksproxy.server, 0, sizeof(sess->socksproxy.server));
+    memset(sess->socksproxy.username, 0, sizeof(sess->socksproxy.username));
+    memset(sess->socksproxy.password, 0, sizeof(sess->socksproxy.password));
+    return;
+  }
+
+  strncpy(sess->socksproxy.server, server, sizeof(sess->socksproxy.server));
+  if (username && strlen(username)) 
+    strncpy(sess->socksproxy.username, username, sizeof(sess->socksproxy.username));
+  if (password && strlen(password))
+    strncpy(sess->socksproxy.password, password, sizeof(sess->socksproxy.password));
+  return;
+}
+
 faim_export void aim_session_init(struct aim_session_t *sess)
 {
   if (!sess)
index 8e3ea20e4d1e5bc97836d7475a550f064cc0ad77..1ba146edeb05353d2605ea1053c58736bd4c9702 100644 (file)
@@ -331,6 +331,12 @@ struct aim_session_t {
   faim_mutex_t snac_hash_locks[FAIM_SNAC_HASH_SIZE];
   u_long snac_nextid;
 
+  struct {
+    char server[128];
+    char username[128];
+    char password[128];
+  } socksproxy;
+
   struct aim_msgcookie_t *msgcookies;
 };
 
@@ -492,6 +498,7 @@ faim_export struct aim_conn_t *aim_select(struct aim_session_t *, struct timeval
 faim_export int aim_conn_isready(struct aim_conn_t *);
 faim_export int aim_conn_setstatus(struct aim_conn_t *, int);
 faim_export void aim_session_init(struct aim_session_t *);
+faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password);
 
 /* aim_misc.c */
 
index 6d3da9e1a2691fb2029f6eed6e00c9a80871a73b..7106502b1129e9b6f09b8f1d75f3bffa2334006d 100644 (file)
@@ -141,6 +141,7 @@ int main(void)
   struct aim_session_t aimsess;
   struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
   int keepgoing = 1;
+  char *proxy, *proxyusername, *proxypass;
 
   int selstat = 0;
 
@@ -153,6 +154,10 @@ int main(void)
 
   server = getenv("AUTHSERVER");
 
+  proxy = getenv("SOCKSPROXY");
+  proxyusername = getenv("SOCKSNAME");
+  proxypass = getenv("SOCKSPASS");
+
 #ifdef _WIN32
   if (initwsa() != 0) {
     printf("faimtest: could not initialize windows sockets\n");
@@ -162,6 +167,9 @@ int main(void)
 
   aim_session_init(&aimsess);
 
+  if (proxy)
+    aim_setupproxy(&aimsess, proxy, proxyusername, proxypass);
+
   authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
 
   if (authconn == NULL) {
This page took 0.3811 seconds and 5 git commands to generate.