View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.net.tftp;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.commons.net.tftp.TFTPServer.ServerMode;
25  
26  import junit.framework.TestCase;
27  
28  /**
29   * Some basic tests to ensure that the TFTP Server is honoring its read/write mode, and preventing
30   * files from being read or written from outside of the assigned roots.
31   * 
32   * @author <A HREF="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</A>
33   * 
34   */
35  public class TFTPServerPathTest extends TestCase
36  {
37      String filePrefix = "tftp-";
38      File serverDirectory = new File(System.getProperty("java.io.tmpdir"));
39  
40      public void testReadOnly() throws IOException
41      {
42          // Start a read-only server
43          TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
44                  ServerMode.GET_ONLY, null, null);
45  
46          // Create our TFTP instance to handle the file transfer.
47          TFTPClient tftp = new TFTPClient();
48          tftp.open();
49          tftp.setSoTimeout(2000);
50  
51          // make a file to work with.
52          File file = new File(serverDirectory, filePrefix + "source.txt");
53          file.createNewFile();
54  
55          // Read the file from the tftp server.
56          File out = new File(serverDirectory, filePrefix + "out");
57  
58          // cleanup old failed runs
59          out.delete();
60          assertTrue("Couldn't clear output location", !out.exists());
61  
62          FileOutputStream output = new FileOutputStream(out);
63  
64          tftp.receiveFile(file.getName(), TFTP.BINARY_MODE, output, "localhost", 6900);
65          output.close();
66  
67          assertTrue("file not created", out.exists());
68  
69          out.delete();
70  
71          FileInputStream fis = new FileInputStream(file);
72          try
73          {
74              tftp.sendFile(out.getName(), TFTP.BINARY_MODE, fis, "localhost", 6900);
75              fail("Server allowed write");
76          }
77          catch (IOException e)
78          {
79              // expected path
80          }
81          fis.close();
82          file.delete();
83          tftpS.shutdown();
84      }
85  
86      public void testWriteOnly() throws IOException
87      {
88          // Start a write-only server
89          TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
90                  ServerMode.PUT_ONLY, null, null);
91  
92          // Create our TFTP instance to handle the file transfer.
93          TFTPClient tftp = new TFTPClient();
94          tftp.open();
95          tftp.setSoTimeout(2000);
96  
97          // make a file to work with.
98          File file = new File(serverDirectory, filePrefix + "source.txt");
99          file.createNewFile();
100 
101         File out = new File(serverDirectory, filePrefix + "out");
102 
103         // cleanup old failed runs
104         out.delete();
105         assertTrue("Couldn't clear output location", !out.exists());
106 
107         FileOutputStream output = new FileOutputStream(out);
108 
109         try
110         {
111             tftp.receiveFile(file.getName(), TFTP.BINARY_MODE, output, "localhost", 6900);
112             fail("Server allowed read");
113         }
114         catch (IOException e)
115         {
116             // expected path
117         }
118         output.close();
119         out.delete();
120 
121         FileInputStream fis = new FileInputStream(file);
122         tftp.sendFile(out.getName(), TFTP.BINARY_MODE, fis, "localhost", 6900);
123 
124         fis.close();
125 
126         assertTrue("file not created", out.exists());
127 
128         // cleanup
129         file.delete();
130         out.delete();
131         tftpS.shutdown();
132     }
133 
134     public void testWriteOutsideHome() throws IOException
135     {
136         // Start a server
137         TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
138                 ServerMode.GET_AND_PUT, null, null);
139 
140         // Create our TFTP instance to handle the file transfer.
141         TFTPClient tftp = new TFTPClient();
142         tftp.open();
143 
144         File file = new File(serverDirectory, filePrefix + "source.txt");
145         file.createNewFile();
146 
147         assertFalse("test construction error", new File(serverDirectory, "../foo").exists());
148 
149         FileInputStream fis = new FileInputStream(file);
150         try
151         {
152             tftp.sendFile("../foo", TFTP.BINARY_MODE, fis, "localhost", 6900);
153             fail("Server allowed write!");
154         }
155         catch (IOException e)
156         {
157             // expected path
158         }
159 
160         fis.close();
161 
162         assertFalse("file created when it should not have been",
163                 new File(serverDirectory, "../foo").exists());
164 
165         // cleanup
166         file.delete();
167 
168         tftpS.shutdown();
169     }
170     
171     
172 }