IIS FTPで一時的にフォルダを公開する
ユーザー認証はしない(anonymous)けど、接続元IPを限定することによって、ある程度のセキュリティは維持でき、一定時間が過ぎると仮想ディレクトリごと削除する。そんな機能が必要になったので、適当に作ってみました。やってみると、意外と難しくない。というか、Microsoft製品のAPIって良くできているなぁと改めて思うほど。
// ftpvdir.cs - A sample code for creating FTP virtual directory using System; using System.Collections; using System.IO; using System.DirectoryServices; using System.Security.AccessControl; using System.Reflection; using System.Net; using System.Net.Sockets; class FtpVDirTest { public static void Main(string[] args) { if(args.Length < 3) { Console.WriteLine("ftpvdir <VDIR> <PDIR> <GRANT_PEER_ADDRESS>"); return; } CreateWriteOnlyFtpDirectory(args[0], args[1], IPAddress.Parse(args[2])); Console.WriteLine("Hit any key to close {0}.", args[0]); Console.ReadKey(); DeleteFtpDirectory(args[0]); } static string IIS_FTP_ROOT = "IIS://localhost/msftpsvc/1/Root"; static string IIS_FTP_SCHEMA = "IIsFtpVirtualDir"; static void CreateWriteOnlyFtpDirectory(string virtualDirName, string physhicalDirPath, IPAddress userIpAddress) { string ipWithMask; if(userIpAddress.AddressFamily == AddressFamily.InterNetwork) ipWithMask = userIpAddress.ToString() + ", 255.255.255.255"; else if(userIpAddress.AddressFamily == AddressFamily.InterNetworkV6) ipWithMask = userIpAddress.ToString() + "::1/64"; else throw new ArgumentException("Unsupported Address family: {0}", userIpAddress.AddressFamily.ToString()); DirectoryEntry ftpRoot = new DirectoryEntry(IIS_FTP_ROOT); ftpRoot.RefreshCache(); DirectoryEntry deNewVDir = ftpRoot.Children.Add(virtualDirName, IIS_FTP_SCHEMA); deNewVDir.Properties["Path"].Insert(0, physhicalDirPath); // READ=1, WRITE=2, READWRITE=3 deNewVDir.Properties["AccessFlags"].Insert(0, 2); // Grant only accesses from the specified peer object ipSecurity = deNewVDir.Properties["IPSecurity"][0]; SetProperty(ipSecurity, "GrantByDefault", false); SetProperty(ipSecurity, "IPGrant", new object[] {ipWithMask}); deNewVDir.Properties["IPSecurity"][0] = ipSecurity; deNewVDir.CommitChanges(); ftpRoot.CommitChanges(); deNewVDir.CommitChanges(); ftpRoot.CommitChanges(); deNewVDir.Close(); ftpRoot.Close(); } static void DeleteFtpDirectory(string virtualDirName) { DirectoryEntry ftpRoot = new DirectoryEntry(IIS_FTP_ROOT); ftpRoot.RefreshCache(); DirectoryEntry vDir = ftpRoot.Children.Find(virtualDirName, IIS_FTP_SCHEMA); ftpRoot.Children.Remove(vDir); ftpRoot.CommitChanges(); vDir.Close(); ftpRoot.Close(); } static object SetProperty(object obj, string name, object val) { return obj.GetType().InvokeMember( name, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new object[] {val}); } }
このコードは、
ftpvdir hogehoge c:\foobar 192.168.11.56
とやると、localhost上に、192.168.11.56からしかアクセスできないFTPの仮想フォルダhogehogeを作成します。
C++スーパープログラマになるための学習項目リスト
4月は新入社員の季節です。うちの会社にも一人だけですが、中途採用の社員が入ってくる(C/C++の若干の知識あり)ので、その人に何を教えるべきか考えています。下記は個人的に教えたいなぁと考えている項目。
- ポータブルなコード
- マクロ
- 64bit
- intよりsize_t
- 国際化(文字列の扱い、ローカライズなど)
- セキュリティ
- バッファオーバーラン
- 機密情報の取り扱い(memsetなど)
- 暗号について
- 暗号乱数について
- C言語に戻る
- 関数ポインタ
- 呼び出し規約
- DLL/Shared Object
- カプセル化
- 設計
- Design by Contract
- 森を見て木を見る
- 嘘つきになる
- 例外
- 例外について
- 従来のエラー処理よりも例外の方が良い理由
- RAII
- AutoPtr
- スレッド
- CreateThread, _beginthreadex
- CoInitialize
- 原子性(Atomicity)/競合状態
- Mutex
- Win32スレッドの基礎 WaitFor*Object(s)
- CriticalSection
- Semaphore
- Interlocked API
- Event
- template
- STL
- コンパイル時計算性/定数性/インライン
- traits
- concept