⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stun.c

📁 linphone的最新版本
💻 C
📖 第 1 页 / 共 5 页
字号:
      username->sizeValue = l;   memcpy(username->value,buffer,l);   username->value[l]=0;	   /* if (verbose) ortp_message("stun: computed username=%s\n", username.value ); */}voidstunCreatePassword(const StunAtrString *username, StunAtrString* password){   char hmac[20];   char key[] = "Fluffy";   /* char buffer[STUN_MAX_STRING]; */   computeHmac(hmac, username->value, strlen(username->value), key, strlen(key));   toHex(hmac, 20, password->value);   password->sizeValue = 40;   password->value[40]=0;	   /* ortp_message("stun: password=%s\n", password->value ); */}UInt64stunGetSystemTimeSecs(void){   UInt64 time=0;#if	defined(_WIN32) || defined(_WIN32_WCE)   SYSTEMTIME t;   /*  CJ TODO - this probably has bug on wrap around every 24 hours */   GetSystemTime( &t );   time = (t.wHour*60+t.wMinute)*60+t.wSecond; #else   struct timeval now;   gettimeofday( &now , NULL );   /* assert( now ); */   time = now.tv_sec;#endif   return time;}/* returns TRUE if it scucceeded */bool_t stunParseHostName( char* peerName,                   UInt32* ip,                   UInt16* portVal,                   UInt16 defaultPort ){   struct in_addr sin_addr;       char host[512];   char* port = NULL;   int portNum = defaultPort;   char* sep;   struct hostent* h;   strncpy(host,peerName,512);   host[512-1]='\0';	   /* pull out the port part if present. */   sep = strchr(host,':');	   if ( sep == NULL )   {      portNum = defaultPort;   }   else   {      char* endPtr=NULL;      *sep = '\0';      port = sep + 1;      /* set port part */      		      portNum = strtol(port,&endPtr,10);		      if ( endPtr != NULL )      {         if ( *endPtr != '\0' )         {            portNum = defaultPort;         }      }   }       if ( portNum < 1024 ) return FALSE;   if ( portNum >= 0xFFFF ) return FALSE;	   /* figure out the host part */	#if	defined(_WIN32) || defined(_WIN32_WCE)   /* assert( strlen(host) >= 1 ); */   if ( isdigit( host[0] ) )   {      /* assume it is a ip address */      unsigned long a = inet_addr(host);      /* cerr << "a=0x" << hex << a << dec ); */		      *ip = ntohl( a );   }   else   {      /* assume it is a host name */      h = gethostbyname( host );		      if ( h == NULL )      {         /*int err = getErrno();*/         /* ortp_message("stun: error was %i\n", err); */         /* std::cerr << "error was " << err << std::endl; */         /* assert( err != WSANOTINITIALISED ); */			         *ip = ntohl( 0x7F000001L );			         return FALSE;      }      else      {         sin_addr = *(struct in_addr*)h->h_addr;         *ip = ntohl( sin_addr.s_addr );      }   }	#else   h = gethostbyname( host );   if ( h == NULL )   {      /* 	 int err = getErrno();	 ortp_message("stun: error was %i\n", err);      */      *ip = ntohl( 0x7F000001L );      return FALSE;   }   else   {      sin_addr = *(struct in_addr*)h->h_addr;      *ip = ntohl( sin_addr.s_addr );   }#endif	   *portVal = portNum;	   return TRUE;}bool_tstunParseServerName( char* name, StunAddress4 *addr){   /* assert(name); */	   /* TODO - put in DNS SRV stuff. */	   bool_t ret = stunParseHostName( name, &addr->addr, &addr->port, 3478);    if ( ret != TRUE )    {       addr->port=0xFFFF;   }	   return ret;}static voidstunCreateErrorResponse(StunMessage *response, int cl, int number, const char* msg){   response->msgHdr.msgType = BindErrorResponseMsg;   response->hasErrorCode = TRUE;   response->errorCode.errorClass = cl;   response->errorCode.number = number;   strcpy(response->errorCode.reason, msg);}#if 0static voidstunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg){   response.msgHdr.msgType = SharedSecretErrorResponseMsg;   response.hasErrorCode = TRUE;   response.errorCode.errorClass = cl;   response.errorCode.number = number;   strcpy(response.errorCode.reason, msg);}#endifstatic voidstunCreateSharedSecretResponse(const StunMessage *request, const StunAddress4 *source, StunMessage *response){   response->msgHdr.msgType = SharedSecretResponseMsg;   response->msgHdr.id = request->msgHdr.id;	   response->hasUsername = TRUE;   stunCreateUserName( source, &response->username);	   response->hasPassword = TRUE;   stunCreatePassword( &response->username, &response->password);}/* This funtion takes a single message sent to a stun server, parses   and constructs an apropriate repsonse - returns TRUE if message is   valid */bool_tstunServerProcessMsg( char* buf,                      unsigned int bufLen,                      StunAddress4 *from,                       StunAddress4 *secondary,                      StunAddress4 *myAddr,                      StunAddress4 *altAddr,                       StunMessage *resp,                      StunAddress4 *destination,                      StunAtrString *hmacPassword,                      bool_t* changePort,                      bool_t* changeIp,                      bool_t verbose){   int i;   StunMessage req;   StunAddress4 mapped;   StunAddress4 respondTo;   UInt32 flags;   bool_t ok;   /* set up information for default response */	   memset( &req, 0 , sizeof(req) );   memset( resp, 0 , sizeof(*resp) );	   *changeIp = FALSE;   *changePort = FALSE;	   ok = stunParseMessage( buf,bufLen, &req, verbose);      if (!ok)      /* Complete garbage, drop it on the floor */   {      if (verbose) ortp_error("stun: Request did not parse");      return FALSE;   }   if (verbose) ortp_message("stun: Request parsed ok");	   mapped = req.mappedAddress.ipv4;   respondTo = req.responseAddress.ipv4;   flags = req.changeRequest.value;	   if (req.msgHdr.msgType==SharedSecretRequestMsg)   {         if(verbose) ortp_message("stun: Received SharedSecretRequestMsg on udp. send error 433.");         /* !cj! - should fix so you know if this came over TLS or UDP */         stunCreateSharedSecretResponse(&req, from, resp);         /* stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS"); */         return TRUE;			   }   else if (req.msgHdr.msgType==BindRequestMsg)   {         if (!req.hasMessageIntegrity)         {            if (verbose) ortp_message("stun: BindRequest does not contain MessageIntegrity");				            if (0) /* !jf! mustAuthenticate */            {               if(verbose) ortp_message("stun: Received BindRequest with no MessageIntegrity. Sending 401.");               stunCreateErrorResponse(resp, 4, 1, "Missing MessageIntegrity");               return TRUE;            }         }         else         {            if (!req.hasUsername)            {               if (verbose) ortp_message("stun: No UserName. Send 432.");               stunCreateErrorResponse(resp, 4, 32, "No UserName and contains MessageIntegrity");               return TRUE;            }            else            {               if (verbose) ortp_message("stun: Validating username: %s", req.username.value );               /* !jf! could retrieve associated password from provisioning here */               if (strcmp(req.username.value, "test") == 0)               {                  if (0)                  {                     /* !jf! if the credentials are stale */                     stunCreateErrorResponse(resp, 4, 30, "Stale credentials on BindRequest");                     return TRUE;                  }                  else                  {                     unsigned char hmac[20];                     if (verbose) ortp_message("stun: Validating MessageIntegrity");                     /* need access to shared secret */#ifndef NOSSL                     {                        unsigned int hmacSize=20;                        HMAC(EVP_sha1(),                              "1234", 4,                              (const unsigned char*) buf, bufLen-20-4,                              hmac, &hmacSize);                        /*HMAC(EVP_sha1(),                              "1234", 4,                              reinterpret_cast<const unsigned char*>(buf), bufLen-20-4,                              hmac, &hmacSize);                        //assert(hmacSize == 20);			*/                     }#endif							                     if (memcmp(buf, hmac, 20) != 0)                     {                        if (verbose) ortp_warning("stun: MessageIntegrity is bad. Sending ");                        stunCreateErrorResponse(resp, 4, 3, "Unknown username. Try test with password 1234");                        return TRUE;                     }							                     /* need to compute this later after message is filled in */                     resp->hasMessageIntegrity = TRUE;                     /* assert(req.hasUsername); */                     resp->hasUsername = TRUE;                     resp->username = req.username; /* copy username in */                  }               }               else               {                  if (verbose) ortp_message("stun: Invalid username: %s Send 430", req.username.value);                }            }         }			         /* TODO !jf! should check for unknown attributes here and send 420 listing the            unknown attributes. */			         if ( respondTo.port == 0 )         {            /* respondTo = from; */            memcpy(&respondTo, from, sizeof(StunAddress4));         }         if ( mapped.port == 0 )          {            /* mapped = from; */            memcpy(&mapped, from, sizeof(StunAddress4));         }         *changeIp   = ( flags & ChangeIpFlag )?TRUE:FALSE;         *changePort = ( flags & ChangePortFlag )?TRUE:FALSE;			         if (verbose)         {            ortp_message("stun: Request is valid:\n");            ortp_message("stun: \t flags= %i\n", flags );            ortp_message("stun: \t changeIp= %i\n", *changeIp );            ortp_message("stun: \t changePort=%i\n", *changePort );            ortp_message("stun: \t from= %i\n", from->addr );            ortp_message("stun: \t respond to= %i\n", respondTo.addr );            ortp_message("stun: \t mapped= %i\n", mapped.addr );         }				         /* form the outgoing message */         resp->msgHdr.msgType = BindResponseMsg;         for (i=0; i<16; i++ )         {            resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i];         }		         if ( req.xorOnly == FALSE )         {            resp->hasMappedAddress = TRUE;            resp->mappedAddress.ipv4.port = mapped.port;            resp->mappedAddress.ipv4.addr = mapped.addr;         }         if (1) /* do xorMapped address or not */         {            UInt16 id16;            UInt32 id32;            resp->hasXorMappedAddress = TRUE;            id16 = req.msgHdr.id.octet[7]<<8                | req.msgHdr.id.octet[6];            id32 = req.msgHdr.id.octet[7]<<24                |  req.msgHdr.id.octet[6]<<16                |  req.msgHdr.id.octet[5]<<8                | req.msgHdr.id.octet[4];            resp->xorMappedAddress.ipv4.port = mapped.port^id16;            resp->xorMappedAddress.ipv4.addr = mapped.addr^id32;         }                  resp->hasSourceAddress = TRUE;         resp->sourceAddress.ipv4.port = (*changePort) ? altAddr->port : myAddr->port;         resp->sourceAddress.ipv4.addr = (*changeIp)   ? altAddr->addr : myAddr->addr;			         resp->hasChangedAddress = TRUE;         resp->changedAddress.ipv4.port = altAddr->port;         resp->changedAddress.ipv4.addr = altAddr->addr;	         if ( secondary->port != 0 )         {            resp->hasSecondaryAddress = TRUE;            resp->secondaryAddress.ipv4.port = secondary->port;            resp->secondaryAddress.ipv4.addr = secondary->addr;         }                  if ( req.hasUsername && req.username.sizeValue > 0 )          {            /* copy username in */            resp->hasUsername = TRUE;            /* assert( req.username.sizeValue % 4 == 0 ); */            /* assert( req.username.sizeValue < STUN_MAX_STRING ); */            memcpy( resp->username.value, req.username.value, req.username.sizeValue );            resp->username.sizeValue = req.username.sizeValue;         }		         if (1) /* add ServerName */         {            const char serverName[] = "Vovida.org " STUN_VERSION; /* must pad to mult of 4 */            resp->hasServerName = TRUE;                        /* assert( sizeof(serverName) < STUN_MAX_STRING ); */            /* cerr << "sizeof serverName is "  << sizeof(serverName) ); */            /* assert( sizeof(serverName)%4 == 0 ); */            memcpy( resp->serverName.value, serverName, sizeof(serverName));            resp->serverName.sizeValue = sizeof(serverName);         }                  if ( req.hasMessageIntegrity & req.hasUsername )           {            /* this creates the password that will be used in the HMAC when then */            /* messages is sent */            stunCreatePassword( &req.username, hmacPassword );         }				         if (req.hasUsername && (req.username.sizeValue > 64 ) )         {            UInt32 source;            /* assert( sizeof(int) == sizeof(UInt32) ); */					            sscanf(req.username.value, "%x", &source);            resp->hasReflectedFrom = TRUE;            resp->reflectedFrom.ipv4.port = 0;            resp->reflectedFrom.ipv4.addr = source;         }				         destination->port = respondTo.port;         destination->addr = respondTo.addr;			         return TRUE;		   }   else   {         if (verbose) ortp_error("stun: Unknown or unsupported request ");         return FALSE;   }	   /* assert(0); */   return FALSE;}bool_tstunInitServer(StunServerInfo *info, const StunAddress4 *myAddr, const StunAddress4 *altAddr, int startMediaPort, bool_t verbose ){   /* assert( myAddr.port != 0 ); */   /* assert( altAddr.port!= 0 ); */   /* assert( myAddr.addr  != 0 ); */   /* assert( altAddr.addr != 0 ); */	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -