int mysocket::connect(const char *host,int port,int host_type,int protocol) { struct hostent he_b; char he_strb[2048]; int he_errno; int rc = 0; struct hostent *he_x; int work_type=m_protocol; if(protocol!=-1) work_type=protocol; switch(work_type){ case TCP_MODEL: close(); if((new_socket=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){ // new_socket=-1; return 0; } addr.sin_family=AF_INET; addr.sin_port=htons(port); #ifdef USEDNSCACHE addr.sin_addr.s_addr=m_dns_cache.GetName(host); if(addr.sin_addr.s_addr==0) return 0; #else if(host_type==ADDR_NAME){ #ifdef WIN32 if((h=gethostbyname(host))==NULL){ ::close2(new_socket); new_socket=INVALID_SOCKET; return 0; } // memcpy(&addr.sin_addr,h->h_addr,MIN(h->h_length,sizeof(addr.sin_addr))); addr.sin_addr=*((struct in_addr *)h->h_addr); #else rc = gethostbyname_r(host, &he_b, he_strb, sizeof(he_strb), &he_x, &he_errno); if(rc!=0){ ::close2(new_socket); new_socket=-1; return 0; } addr.sin_addr=*((struct in_addr *)he_b.h_addr); #endif }else if(host_type==ADDR_IP) addr.sin_addr.s_addr=inet_addr(host); #endif memset(&(addr.sin_zero),0,8); if(::connect(new_socket,(struct sockaddr *)(&addr),sizeof(struct sockaddr),time_value)<0){ //::close2(new_socket); //new_socket=-1; return 0; } // printf("socket=%d\n",new_socket); break; case UDP_MODEL: if(new_socket<=0) if((new_socket=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) return 0; addr.sin_family=AF_INET; addr.sin_port=htons(port); #ifdef USEDNSCACHE addr.sin_addr.s_addr=m_dns_cache.GetName(host); if(addr.sin_addr.s_addr==0) return 0; #else #ifdef _WIN32 if((h=gethostbyname(host))==NULL){ ::close2(new_socket); new_socket=-1; return 0; } addr.sin_addr=*((struct in_addr *)h->h_addr); #else rc = gethostbyname_r(host, &he_b, he_strb, sizeof(he_strb), &he_x, &he_errno); if(rc!=0){ ::close2(new_socket); new_socket=-1; return 0; } addr.sin_addr=*((struct in_addr *)he_b.h_addr); #endif #endif // addr_addr.sin_addr.s_addr=inet_addr(host); memset(&(addr.sin_zero),0,8); break; case SSL_MODEL: if(connect(host,port,host_type,TCP)<=0) return -1; #ifdef USE_SSL return sslutil_connect(); #endif break; default: return -6;//protocol is error } return 1; }
static int control_channel_handler(int connfd) { char *password; data_endpoint_t *ep; sslutil_connection_t ssl_conn; linfo("Connection handler started. Initiating SSL handshake."); ssl_conn = sslutil_connect(connfd, server); if (ssl_conn == 0) { linfo("Unable to start SSL session"); return EXIT_SSL_ERROR; } if (!ivpn_protocol_handshake(ssl_conn)) return EXIT_PROTO_ERROR; linfo ("IVPN Protocol handshake completed successfully."); ep = start_data_endpoint(NULL); assert(ep != 0); if (relinquish_superuser(NULL) == 0) { lerr("Unable to relinquish privileges. Quitting."); return EXIT_FAILURE; } usleep(100000); // 100 ms password = get_password("Password:"******"Authentication failed."); return EXIT_AUTH_ERROR; } memset(password, 0, strlen(password)); // clear plain text password linfo ("Authenticated with server. Data port is %u", ep->peer_port); ep->peer_ip = inet_addr(get_ip_from_name(server)); if (write(ep->write_fd, &ep->peer_ip, sizeof(ep->peer_ip)) == -1 || write(ep->write_fd, &ep->peer_port, sizeof(ep->peer_port)) == -1) { lerr("Unable to write to UDP process pipe. Quitting.", strerror(errno)); return EXIT_FAILURE; } usleep(100000); // 100 ms while (1) { char command[64]; fprintf(stdout, "ivpn> "); fflush(stdout); if (fgets(command, sizeof(command) - 1, stdin) == 0) { linfo("End of input. Terminating..."); break; } if (strcmp(command, "quit\n") == 0) { linfo("Quit command. Terminating..."); break; } if (strcmp(command, "changekey\n") == 0) { char key[IVPN_KEY_LENGTH]; linfo("Performing key change."); generate_true_random(key, sizeof(key)); /* send key to local UDP process first */ if (write(ep->write_fd, key, sizeof(key)) != sizeof(key)) { lerr("Unable to send key to local UDP process : %s. Quitting...", strerror(errno)); break; } else { linfo("New key sent to local UDP process"); } /* send key to VPN server */ cm_setkey_t *cm = create_cm_setkey(key); if (cm == 0) { lerr ("Unable to generate command for sending to VPN server. Quitting..."); break; } if (send_control_message(ssl_conn, (cm_header_t *)cm) == 0) { lerr ("Unable to sending command to VPN server. Quitting..."); break; } cm_header_t *rsp = recv_control_message(ssl_conn); if (rsp == 0) { lerr ("Unable to receive command from VPN server. Quitting..."); break; } if (rsp->cm_type == CM_TYPE_OK) { linfo("Setting new key in server succeeded"); } else { lerr("Setting new key in server failed. Quitting..."); break; } } } return 0; }
BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { char *p; int len = 4; extern pstring user_socket_options; /* 445 doesn't have session request */ if (cli->port == 445) return True; /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number * of bytes which follow. The cli_send_smb() function knows * about this and accounts for those four bytes. * CRH. */ len -= 4; _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); #ifdef WITH_SSL retry: #endif /* WITH_SSL */ cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) return False; if (CVAL(cli->inbuf,0) == 0x84) { /* C. Hoch 9/14/95 Start */ /* For information, here is the response structure. * We do the byte-twiddling to for portability. struct RetargetResponse{ unsigned char type; unsigned char flags; int16 length; int32 ip_addr; int16 port; }; */ int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); /* SESSION RETARGET */ putip((char *)&cli->dest_ip,cli->inbuf+4); cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); if (cli->fd == -1) return False; DEBUG(3,("Retargeted\n")); set_socket_options(cli->fd,user_socket_options); /* Try again */ { static int depth; BOOL ret; if (depth > 4) { DEBUG(0,("Retarget recursion - failing\n")); return False; } depth++; ret = cli_session_request(cli, calling, called); depth--; return ret; } } /* C. Hoch 9/14/95 End */ #ifdef WITH_SSL if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if (!sslutil_fd_is_ssl(cli->fd)){ if (sslutil_connect(cli->fd) == 0) goto retry; } } #endif /* WITH_SSL */ if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,4); return False; } return(True); }