/* * Send an udp datagram to specified peer. */ void send_udp (unsigned char *data, size_t len, struct peer *p, unsigned char flags) { unsigned char outpkt[MAXPKT]; unsigned char *outbuf=outpkt+1; int olen; struct sockaddr_in *destination=&(p->in_a); unsigned char *crc; if (len + 8 - 1 > MAXPKT) { len = MAXPKT - 8 + 1; vc_printlog(2,"Warning: Cropping down packet size to %d", len); } if (encryption_disabled || (flags==CMD_CHALLENGE || flags==CMD_LOGIN || flags==CMD_DENY || flags==CMD_AUTH_OK || flags == CMD_KEEPALIVE)){ memcpy(outbuf,data,len); olen=len; }else{ unsigned char *tail = outbuf + len; crc = crc32(data,len); memcpy(tail,crc,4); free(crc); set_timestamp(tail + 4); olen = data_encrypt_decrypt(data, outbuf, len, p->key, tail); olen+=12; } outpkt[0]=flags; sendto(nfd, outpkt, olen + 1, 0, (struct sockaddr *) destination, sizeof(struct sockaddr_in)); vc_printlog(4,"UDP Sent %dB datagram.",olen+1); }
/* * Send a virtual frame to the vde_plug process associated * with the peer */ void send_vdeplug(const char *data, size_t len, struct peer *p) { static unsigned int outbuf[MAXPKT]; static int outp=0; static u_int16_t outlen; if(len<=0) return; if(outp==0 && (len >=2) ){ outlen=2; outlen+=(unsigned char)data[1]; outlen+=((unsigned char)(data[0]))<<8; } if(len>=outlen){ vde_send(p->plug,data,outlen,0); send_vdeplug(data+outlen,len-outlen, p); return; } memcpy(outbuf+outp,data,len); outp+=len; if(outp>=outlen){ vde_send(p->plug,(char *)outbuf,outlen,0); } vc_printlog(3,"VDE - Sent a %dB datagram.",outlen); }
/* * Send an udp datagram to specified peer. */ void send_udp (unsigned char *data, size_t len, struct peer *p, unsigned char flags) { unsigned char outpkt[MAXPKT]; unsigned char *outbuf=outpkt+1; int olen; struct sockaddr_in *destination=&(p->in_a); unsigned char *crc; if (encryption_disabled || (flags==CMD_CHALLENGE || flags==CMD_LOGIN || flags==CMD_DENY || flags==CMD_AUTH_OK || flags == CMD_KEEPALIVE)){ memcpy(outbuf,data,len); olen=len; }else{ if(flags==PKT_DATA){ set_timestamp(data+len); len+=8; crc = crc32(data,len); memcpy(data+len,crc,4); free(crc); len+=4; } olen = data_encrypt(data,outbuf,len,p); } outpkt[0]=flags; sendto(nfd, outpkt, olen + 1, 0, (struct sockaddr *) destination, sizeof(struct sockaddr_in)); vc_printlog(4,"UDP Sent %dB datagram.",olen+1); }
void vde_plug(struct peer *p, char *plugname) { p->plug=vde_open(plugname,"vde_cryptcab",&open_args); if(!p->plug) { perror ("libvdeplug"); exit(1); } vc_printlog(3,"Socket to local switch created: fd=%d",vde_datafd(p->plug)); }
void disable_encryption(void) { encryption_disabled = 1; vc_printlog(3,"Encryption Disabled."); }
/* * Main. */ int main(int argc, char **argv, char **env) { int c; char *programname=argv[0]; char *plugname="/tmp/vde.ctl"; char *remotehost = NULL; char *remoteusr = NULL; char *pre_shared = NULL; enum e_enc_type enc_type = ENC_SSH; unsigned short udp_port = PORTNO; unsigned short remoteport = PORTNO; unsigned char keepalives=0; char *scp_extra_options; int daemonize = 0; scp_extra_options=getenv("SCP_EXTRA_OPTIONS"); while (1) { int option_index = 0; char *ctl_socket; const char sepusr='******'; const char sepport=':'; char *pusr,*pport, *vvv=NULL; static struct option long_options[] = { {"sock", 1, 0, 's'}, {"vdesock", 1, 0, 's'}, {"unix", 1, 0, 's'}, {"localport", 1, 0, 'p'}, {"connect",1,0,'c'}, {"preshared ",1,0,'P'}, {"noencrypt",0,0,'x'}, {"keepalive",0,0,'k'}, {"verbose",optional_argument,0,'v'}, {"help",0,0,'h'}, {"daemon",0,0,'d'}, {0, 0, 0, 0} }; c = GETOPT_LONG (argc, argv, "s:p:c:P:hv::xkd", long_options, &option_index); if (c == -1) break; switch (c) { case 's': plugname=strdup(optarg); break; case 'v': verbose=1; if(optarg) vvv=strdup(optarg); while(vvv && *vvv++ == 'v') verbose++; break; case 'x': enc_type = ENC_NOENC; break; case 'c': ctl_socket=strdup(optarg); pusr=strchr(ctl_socket,sepusr); pport=strchr(ctl_socket,sepport); if( ( pusr != strrchr(ctl_socket,sepusr)) || (pport != strrchr(ctl_socket,sepport)) || (pport && pusr>pport) ) Usage(programname); if(!pusr && !pport){ remoteusr=NULL; remoteport=PORTNO; remotehost=strdup(ctl_socket); break; } if(!pport){ remoteusr=(char *)strndup(ctl_socket,pusr-ctl_socket); remotehost=(char *)strndup(pusr+1,strlen(ctl_socket)-strlen(remoteusr)-1); remoteport=PORTNO; break; } if(!pusr){ remoteusr=NULL; remotehost=(char *)strndup(ctl_socket,pport-ctl_socket); remoteport=atoi((char *)strndup(pport+1,strlen(ctl_socket)-strlen(remotehost)-1)); break; } remoteusr=(char *)strndup(ctl_socket,pusr-ctl_socket); remotehost=(char *)strndup(pusr+1,pport-pusr-1); remoteport=atoi((char *)strndup(pport+1,strlen(ctl_socket)-strlen(remotehost)-strlen(remoteusr)-2)); break; case 'p': udp_port=atoi(optarg); break; case 'P': pre_shared=strdup(optarg); fprintf(stderr,"Using pre-shared key %s\n",pre_shared); enc_type = ENC_PRESHARED; break; case 'k': keepalives=1; break; case 'd': daemonize=1; break; case 'h': default: Usage(programname); } } if(optind < argc) Usage(programname); if (keepalives && remotehost==NULL){ fprintf(stderr,"\nkeepalive option is valid in client mode only.\n\n"); Usage(programname); } if (pre_shared && enc_type == ENC_NOENC){ fprintf(stderr,"\nWarning: Not using pre-shared key mode, encryption disabled.\n\n"); pre_shared = NULL; } vc_printlog(1,"Verbosity: %d", verbose); chksum_crc32gentab(); switch(enc_type){ case ENC_NOENC: vc_printlog(1,"Encryption Disabled."); break; case ENC_PRESHARED: vc_printlog(1,"Using pre-shared key %s",pre_shared); break; case ENC_SSH: vc_printlog(1,"Using ssh key exchange for authentication"); break; } if (daemonize) { if (fork() == 0) { setsid(); close(STDIN_FILENO); close(STDOUT_FILENO); if (fork() > 0) exit(0); } else exit(0); } if(!remotehost){ cryptcab_server(plugname, udp_port, enc_type, pre_shared); } else { cryptcab_client(plugname, udp_port, enc_type, pre_shared, remoteusr, remotehost, remoteport, keepalives, scp_extra_options); } exit(0); }