summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/mcast-raw.c21
-rw-r--r--src/bin/mcast.c26
-rw-r--r--src/bin/supersu.c35
-rw-r--r--src/libexec/socks4a-proxy.c105
4 files changed, 187 insertions, 0 deletions
diff --git a/src/bin/mcast-raw.c b/src/bin/mcast-raw.c
new file mode 100644
index 0000000..81913d3
--- /dev/null
+++ b/src/bin/mcast-raw.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int main(int argc,char *argv[]) {
+ int s=socket(AF_INET,SOCK_RAW,atoi(argv[2]));
+ char packet[1501];//mtu of an interface. including headers though. meh.
+ int n;
+ struct ip_mreq mreq;
+ struct sockaddr_in sa;
+ int one = sizeof(struct sockaddr_in);
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ mreq.imr_multiaddr.s_addr=inet_addr(argv[1]);
+ mreq.imr_interface.s_addr=htonl(INADDR_ANY);
+ setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
+ while((n=recvfrom(s,packet,sizeof(packet),0,(struct sockaddr *)&sa,&one)) > 0) {
+ printf("%s ",inet_ntoa(sa.sin_addr));
+ fflush(stdout);
+ write(1,packet,n);
+ }
+}
diff --git a/src/bin/mcast.c b/src/bin/mcast.c
new file mode 100644
index 0000000..e48c504
--- /dev/null
+++ b/src/bin/mcast.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int main(int argc,char *argv[]) {
+ int s=socket(AF_INET,SOCK_DGRAM,0);
+ char packet[1501];//mtu of an interface. including headers though. meh.
+ int n;
+ struct ip_mreq mreq;
+ struct sockaddr_in sa;
+ int one = sizeof(struct sockaddr_in);
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ memset(&sa,0,sizeof(struct sockaddr_in));
+ sa.sin_addr.s_addr=htonl(INADDR_ANY);
+ sa.sin_port=htons(atoi(argv[2]));
+ sa.sin_family=AF_INET;
+ bind(s,(struct sockaddr *)&sa,sizeof(struct sockaddr_in));
+ mreq.imr_multiaddr.s_addr=inet_addr(argv[1]);
+ mreq.imr_interface.s_addr=htonl(INADDR_ANY);
+ setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
+ while((n=recvfrom(s,packet,sizeof(packet),0,(struct sockaddr *)&sa,&one)) > 0) {
+ printf("%s ",inet_ntoa(sa.sin_addr));
+ fflush(stdout);
+ write(1,packet,n);
+ }
+}
diff --git a/src/bin/supersu.c b/src/bin/supersu.c
new file mode 100644
index 0000000..d3f7fec
--- /dev/null
+++ b/src/bin/supersu.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+
+int main(int argc,char *argv[]) {
+ int i;
+ if(argc < 4) {
+ fprintf(stderr,"usage: %s uid gid [secondary_gids] absolute-path-of-executable\n",argv[0]);
+ return 0;
+ }
+ if(getuid() && geteuid()) {
+ fprintf(stderr,"supersu: uid: %d, euid: %d... I have no idea how this is supposed to work. oh well.\n",getuid(),geteuid());
+ }
+ int groups[argc-2];
+ int ngroups=0;
+ char **name;
+ int here=0;
+ for(i=2;i<argc;i++) {
+ if(argv[i][0]=='/') {
+ here=i;
+ break;
+ }
+ }
+ if(here == 0) {
+ fprintf(stderr,"%s: I didn't find an absolute-path in the argument list.\n",argv[0]);
+ return 0;
+ }
+ ngroups=argc-(argc-here)-2;
+ for(i=2;i<here;i++) {
+ groups[i-2]=atoi(argv[i]);
+ }
+ name=argv+i;
+ setgroups(ngroups,groups);
+ setgid(atoi(argv[2]));
+ setuid(atoi(argv[1]));
+ execv(*name,name);
+}
diff --git a/src/libexec/socks4a-proxy.c b/src/libexec/socks4a-proxy.c
new file mode 100644
index 0000000..a179d40
--- /dev/null
+++ b/src/libexec/socks4a-proxy.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <syslog.h>
+#include <netdb.h>
+
+int main(int argc,char *argv[]) {
+ unsigned char vn;//version
+ unsigned char cd;//command
+ unsigned short dstport;
+ unsigned int dstip;
+ unsigned char in;
+ int i;
+ int status;
+ char *name[5];
+ char user[256];
+ char sport[10];//10 is more than enough. it is converted from a short with %d
+ char host[256];//https://blogs.msdn.microsoft.com/oldnewthing/20120412-00/?p=7873/
+ read(0,&vn,1);
+ //fprintf(stderr,"version number: %d\n",vn);
+ if(vn != 4) {
+ //fprintf(stderr,"received wrong version number. needs to be 4.\n");
+ write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8);//the decaf0coffee is supposed to be ignored by clients.
+ return 1;
+ }
+ read(0,&cd,1);
+ //fprintf(stderr,"command code: %d\n",cd);
+ if(cd != 1) {
+ //fprintf(stderr,"only going to implement command code 1 (connect) atm.\n");
+ write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8);//the response is in the same format as the request. vn+cd+port+ip
+ return 2;
+ }
+ read(0,&dstport,2);
+ //fprintf(stderr,"dstport: %d\n",ntohs(dstport));
+ read(0,&dstip,4);
+ //fprintf(stderr,"dstip: %d\n",ntohl(dstip));
+ for(i=0;i<254;i++) {
+ read(0,user+i,1);
+ if(!user[i]) break;//we read a null, let's hop out.
+ }
+ if(user[i]) {//we didn't read the whole thing. truncate and just ignore the rest.
+ user[i]=0;
+ while(read(0,&in,1) > 0) {
+ if (in == 0) break;
+ }
+ }
+ //fprintf(stderr,"user: %s\n",user);
+ //do some sort of auth here...
+ //pass it off to a script?
+ if(argc>2) {//we have an argument for the script to run auth against.
+ //what do we need to pass? the port we're on, the port they connected from
+ switch(fork()) {
+ case -1:
+ return errno;
+ case 0://child.
+ name[0]=argv[2];
+ name[1]=user;
+ name[2]=0;
+ execv(name[0],name);
+ return errno;
+ default:
+ break;
+ }
+ wait(&status);
+ }
+ if(WEXITSTATUS(status)) {//anything but 0 is an error.
+ write(1,"\x00\x5b\xde\xca\xf0\xc0\xff\xee",8);
+ return 3;
+ }
+ if(ntohl(dstip) < 256) { //this should match for an address that is 0.0.0.x where x could be anything.
+ //do what we did for user, but with a hostname now.
+ for(i=0;i<254;i++) {
+ read(0,host+i,1);
+ if(!host[i]) break;
+ }
+ if(host[i]) {//we didn't read the whole thing. truncate and just ignore the rest.
+ host[i]=0;
+ while(read(0,&in,1) > 0) {
+ if (in == 0) break;
+ }
+ }
+ //fprintf(stderr,"host: %s\n",host);
+ }
+ struct sockaddr_in6 sa6;
+ unsigned int sl=sizeof(sa6);
+ char h[NI_MAXHOST], s[NI_MAXSERV];
+ if(getpeername(argc>1?atoi(argv[1]):0,(struct sockaddr *)&sa6,&sl) == -1) return 1;
+ if(getnameinfo((struct sockaddr *)&sa6,sl,h,sizeof(h),s,sizeof(s),NI_NUMERICHOST|NI_NUMERICSERV)) return 2;
+
+ syslog(LOG_WARNING,"proxy request: %s@%s:%s => %s:%d",user,h,s,host,ntohs(dstport));
+ //fprintf(stderr,"got passed all that shit...\n");
+ write(1,"\x00\x5a\xde\xca\xf0\xc0\xff\xee",8);
+ snprintf(sport,sizeof(sport)-1,"%u",ntohs(dstport));//%u because ports are unsigned.
+ name[0]=argc>1?argv[1]:"/usr/pkg/bin/nc";//if you want the arguments in a different order either change this sauce or use a script.
+ name[1]=host;//WARNING: these two arguments aren't sanitized. they may contain flags set by the proxy's user that could wreak havok!
+ name[2]=sport;//not sure how many programs can be messed up using just a number though.
+ name[3]=0;
+ //fprintf(stderr,"running: %s %s %s %s\n",name[0],name[1],name[2],name[3]);
+ execv(name[0],name);
+ //fprintf(stderr,"execv failed. :/");
+ //perror("execv");
+ return errno;//if we get here something failed so we might as well return errno.
+}