@@ -38,6 +38,7 @@ const {
3838 ErrnoException,
3939 ExceptionWithHostPort,
4040 codes : {
41+ ERR_ACCESS_DENIED ,
4142 ERR_BUFFER_OUT_OF_BOUNDS ,
4243 ERR_INVALID_ARG_TYPE ,
4344 ERR_INVALID_FD_TYPE ,
@@ -81,6 +82,7 @@ const {
8182
8283const dc = require ( 'diagnostics_channel' ) ;
8384const udpSocketChannel = dc . channel ( 'udp.socket' ) ;
85+ const permission = require ( 'internal/process/permission' ) ;
8486
8587const BIND_STATE_UNBOUND = 0 ;
8688const BIND_STATE_BINDING = 1 ;
@@ -327,12 +329,9 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) {
327329 else
328330 address = '::' ;
329331 }
330-
331- // Resolve address first
332- state . handle . lookup ( address , ( err , ip ) => {
332+ const afterDns = ( err , ip ) => {
333333 if ( ! state . handle )
334334 return ; // Handle has been closed in the mean time
335-
336335 if ( err ) {
337336 state . bindState = BIND_STATE_UNBOUND ;
338337 this . emit ( 'error' , err ) ;
@@ -361,7 +360,7 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) {
361360 this . emit ( 'error' , ex ) ;
362361 } ) ;
363362 } else {
364- const err = state . handle . bind ( ip , port || 0 , flags ) ;
363+ const err = state . handle . bind ( ip , port || 0 , flags , false ) ;
365364 if ( err ) {
366365 const ex = new ExceptionWithHostPort ( err , 'bind' , ip , port ) ;
367366 state . bindState = BIND_STATE_UNBOUND ;
@@ -372,7 +371,22 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) {
372371
373372 startListening ( this ) ;
374373 }
375- } ) ;
374+ } ;
375+ if ( permission . isEnabled ( ) ) {
376+ const resource = `${ address } /${ port || '*' } ` ;
377+ if ( ! permission . has ( 'net.udp' , resource ) ) {
378+ process . nextTick ( ( ) => {
379+ afterDns ( new ERR_ACCESS_DENIED (
380+ `bind to ${ resource } ` ,
381+ 'NetUDP' ,
382+ resource ,
383+ ) ) ;
384+ } ) ;
385+ return this ;
386+ }
387+ }
388+ // Resolve address first
389+ state . handle . lookup ( address , afterDns ) ;
376390
377391 return this ;
378392} ;
@@ -413,13 +427,38 @@ function _connect(port, address, callback) {
413427 this . once ( 'connect' , callback ) ;
414428
415429 const afterDns = ( ex , ip ) => {
430+ if ( ! ex && ! address && permission . isEnabled ( ) ) {
431+ const resource = `${ ip } /${ port } ` ;
432+ if ( ! permission . has ( 'net.udp' , resource ) ) {
433+ ex = new ERR_ACCESS_DENIED (
434+ `connect to ${ resource } ` ,
435+ 'NetUDP' ,
436+ resource ,
437+ ) ;
438+ }
439+ }
416440 defaultTriggerAsyncIdScope (
417441 this [ async_id_symbol ] ,
418442 doConnect ,
419443 ex , this , ip , address , port , callback ,
420444 ) ;
421445 } ;
422-
446+ // If the address which is allowed is a domain,
447+ // we should allow bind to all IPs this domain ponit to,
448+ // so we need check here instead of in afterDns
449+ if ( address && permission . isEnabled ( ) ) {
450+ const resource = `${ address } /${ port } ` ;
451+ if ( ! permission . has ( 'net.udp' , resource ) ) {
452+ process . nextTick ( ( ) => {
453+ afterDns ( new ERR_ACCESS_DENIED (
454+ `connect to ${ resource } ` ,
455+ 'NetUDP' ,
456+ resource ,
457+ ) ) ;
458+ } ) ;
459+ return ;
460+ }
461+ }
423462 state . handle . lookup ( address , afterDns ) ;
424463}
425464
@@ -430,7 +469,7 @@ function doConnect(ex, self, ip, address, port, callback) {
430469 return ;
431470
432471 if ( ! ex ) {
433- const err = state . handle . connect ( ip , port ) ;
472+ const err = state . handle . connect ( ip , port , false ) ;
434473 if ( err ) {
435474 ex = new ExceptionWithHostPort ( err , 'connect' , address , port ) ;
436475 }
@@ -663,6 +702,17 @@ Socket.prototype.send = function(buffer,
663702 }
664703
665704 const afterDns = ( ex , ip ) => {
705+ // If we have not checked before dns, check it now
706+ if ( ! ex && ! connected && ! address && permission . isEnabled ( ) ) {
707+ const resource = `${ ip } /${ port } ` ;
708+ if ( ! permission . has ( 'net.udp' , resource ) ) {
709+ ex = new ERR_ACCESS_DENIED (
710+ `send to ${ resource } ` ,
711+ 'NetUDP' ,
712+ resource ,
713+ ) ;
714+ }
715+ }
666716 defaultTriggerAsyncIdScope (
667717 this [ async_id_symbol ] ,
668718 doSend ,
@@ -671,6 +721,19 @@ Socket.prototype.send = function(buffer,
671721 } ;
672722
673723 if ( ! connected ) {
724+ if ( address && permission . isEnabled ( ) ) {
725+ const resource = `${ address } /${ port } ` ;
726+ if ( ! permission . has ( 'net.udp' , resource ) ) {
727+ process . nextTick ( ( ) => {
728+ afterDns ( new ERR_ACCESS_DENIED (
729+ `send to ${ resource } ` ,
730+ 'NetUDP' ,
731+ resource ,
732+ ) ) ;
733+ } ) ;
734+ return ;
735+ }
736+ }
674737 state . handle . lookup ( address , afterDns ) ;
675738 } else {
676739 afterDns ( null , null ) ;
@@ -703,7 +766,7 @@ function doSend(ex, self, ip, list, address, port, callback) {
703766
704767 let err ;
705768 if ( port )
706- err = state . handle . send ( req , list , list . length , port , ip , ! ! callback ) ;
769+ err = state . handle . send ( req , list , list . length , port , ip , ! ! callback , false ) ;
707770 else
708771 err = state . handle . send ( req , list , list . length , ! ! callback ) ;
709772
0 commit comments