2015-07-25 18 views
14

Rastgele bayt oluşturmak için /dev/urandom okur bir proje üzerinde çalışırken, ben sadece bir dosya değil, bir aygıtın /dev/urandom olduğundan emin olmak için denetleyin önerildi.Belirli bir dosyanın PHP'den BSD/Linux üzerinde nasıl bir aygıt garanti edilmesi gerekir?

en basit yolu gibi bir şey gibi görünüyor:

/** 
* Is the given file a device? 
* 
* @param string|resource $file 
* @return boolean 
*/ 
function is_device($file) 
{ 
    if (is_resource($file)) { 
     $stat = fstat($file);    
    } elseif (is_readable($file) && !is_link($file)) { 
     $stat = stat($file); 
    } else { 
     return false; 
    } 
    return $stat['rdev'] !== 0; 
} 

Sorum şu iki yönlüdür:

  1. bu dosyanın bir cihaz olup olmadığını kontrol etmenin en iyi yolu var mı?
  2. Bu $stat['rdev'] !== 0 denetiminin başarısız olduğu durumlar var mı? Önemli

: Ben herhangi bir PECL uzantıları veya özel C kodu bağlı olmadan PHP olmalıdır gerekir çözüm. Proje a pure PHP 5 polyfill of PHP 7's random_bytes() and random_int() functions'dur ve Composer'ın başkasının PHP 5 projelerinde kurulabilir olması amaçlanmıştır.

+0

[Bunu gördünüz mü?] (Http://insanecoding.blogspot.com/2014/05/a-good-idea-with-bad-usage-devurandom.html) –

+0

Şu andaki resmi olmayan duruşum: "TOCTOU sorunları ve dosya tanımlayıcı tükenme saldırıları kapsam dışıdır. Dosya sisteminiz pürüzlü ise, PHP web uygulamanızın sizi kurtarmak için yapabileceği hiçbir şey yoktur. " –

cevap

4

Peki, filetype() kullanabilirsiniz. Eğer urandom üzerinde hızlı ll yaparsanız

, göreceksiniz:

ll /dev/urandom 
crw-rw-rw- 1 root root 1, 9 Jul 26 17:38 /dev/urandom 

beginnng de 'c' bir "karakter" filetype var demektir. Burada tüm farklı dosya türlerini kontrol edebilirsiniz:

https://en.wikipedia.org/wiki/Unix_file_types

bu

filetype("/dev/urandom"); 

çalıştırırsanız karakter filetype anlamına geri "Sözc'ü" almak anlamına gelir. Bu hile yapmalısınız.

+1

"openssl_random_pseudo_bytes() 'ı araştırmak için zaman ayırmalısınız." [Bu herkese tavsiye edeceğim ilk tercih değil] (https://github.com/paragonie/random_compat/blob/master/ERRATA.md). Söz konusu proje, PHP 7’nin random_bytes() ve 'random_int()' fonksiyonları için bir çokdüzeydir. –

2

Güncelleme

Benim asıl çözüm bu nedenle filetype() İhtiyacınız olan tek şey gibi görünüyor, filetype($filepath) === 'char' sadece bir yeniden düzenleme olduğu ortaya çıktı. @ FRYMASTER cevabı dayanarak


...

ben "char" arayan, PHP'nin stat() işlevin nasıl baktı ve this bulundu. Linux ve FreeBSD ikisi için için stat (2) manuel, hem de bir comment on PHP's manual for stat() ile birlikte

, aşağıdaki ile geldi:

 
function is_device($filepath) 
{ 
     if (! file_exists($filepath) OR (stripos(PHP_OS, 'Linux') === false && stripos(PHP_OS, 'BSD') === false)) 
     { 
       return false; 
     } 

     $mode = stat($filepath)['mode']; 
     return (020000 === ($mode & 0170000)); 
} 

Çalışır benim Linux sisteminde.

Güncelleme

Evet, stat($file)['rdev'] !== 0 başarısız olabilir (ikinci soruyu cevaplamak için). Bulduğumdan, işletim sistemi tarafından desteklenmiyorsa -1 döndürülebilir, hatta pozitif bir değer bile farklı bir cihaz türüne işaret edebilir.Değerleri de işletim sistemine bağlı gibi görünüyor.

+0

Libsodum'un çok benzer bir şey yaptığını görüyoruz: https://github.com/jedisct1/libsodium/blob/024b74c84995e68c804868b1189d75f571794ad7/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c#L118 –

+2

Ve bu ne 'filetype' olduğu ortaya çıktı.) 'char 'döndürmek için yapar. :) Sadece cevap güncellendi ... ki şimdi @frymaster'ın söylediği gibi. – Narf

+1

Bundan bir şeyler öğrendim! teşekkür ederim! – frymaster