@@ -108,75 +108,107 @@ public static void main(String[] args) throws Exception {
108108 @ Override
109109 public void handle (String target , Request baseRequest , HttpServletRequest request , HttpServletResponse response )
110110 throws IOException {
111+ var host = request .getHeader ("Host" );
112+ var maven = config .location (host );
113+ var user = Passwd .user (request .getHeader ("Authorization" ));
114+
115+ logger .info ("request: {} {}@{}{} from {}:{} ({}), real: {}, cf: {} / {}, agent: {}" , request .getMethod (), user ,
116+ host , target , request .getRemoteAddr (), request .getRemotePort (), request .getRemoteHost (),
117+ Utils .toString (request .getHeaders ("X-Fowarded-For" )), request .getHeader ("CF-Connecting-IP" ),
118+ request .getHeader ("True-Client-IP" ), request .getHeader ("User-Agent" ));
119+
120+ // CF-Connecting-IP and X-Forwarded-For :blobfox_3c:
121+ if (!checkPreconditions (user , baseRequest , request , response )) {
122+ logger .info ("invalid: {} {}@{}{} from {}:{} ({})" , request .getMethod (), user , host , target ,
123+ request .getRemoteAddr (), request .getRemotePort (), request .getRemoteHost ());
124+ user .close ();
125+ return ;
126+ }
127+
128+ logger .info ("authenticated: {} {}@{}{} from {}:{} ({})" , request .getMethod (), user , host , target ,
129+ request .getRemoteAddr (), request .getRemotePort (), request .getRemoteHost ());
130+
131+ var path = maven .resolve ('.' + target );
132+ if (Files .exists (path ) && !target .contains ("SNAPSHOT" )
133+ && !target .regionMatches (target .lastIndexOf ('/' ) + 1 , "maven-metadata" , 0 , 14 )) {
134+ response .setStatus (HttpServletResponse .SC_CONFLICT );
135+ response .getWriter ().println ("File cannot be replaced or deleted once uploaded." );
136+
137+ logger .info ("attempted replacing: {} {}@{}{}" , request .getMethod (), user , host , target );
138+ return ;
139+ }
140+ var parent = path .getParent ();
141+ if (Files .exists (parent ) && !Files .isDirectory (parent )) {
142+ response .setStatus (HttpServletResponse .SC_CONFLICT );
143+ response .getWriter ().println ("Package is a file." );
144+
145+ logger .info ("package is a file: {} {}@{}{}" , request .getMethod (), user , host , target );
146+ return ;
147+ }
148+
149+ Files .createDirectories (parent );
150+ try (var srvIn = request .getInputStream ()) {
151+ Files .copy (srvIn , path , StandardCopyOption .REPLACE_EXISTING );
152+ }
153+
154+ logger .info ("successful upload: {} {}@{}{}" , request .getMethod (), user , host , target );
155+ response .setStatus (HttpServletResponse .SC_CREATED );
156+ }
157+
158+ private boolean checkPreconditions (Passwd .User user , Request baseRequest , HttpServletRequest request ,
159+ HttpServletResponse response ) throws IOException {
111160 boolean taint = "http" .equals (request .getHeader ("X-Forwarded-Proto" ));
112161 // No point in executing on any other.
113162 baseRequest .setHandled (true );
114163 if (!"PUT" .equalsIgnoreCase (request .getMethod ())) {
115164 response .setStatus (HttpServletResponse .SC_NOT_IMPLEMENTED );
116- return ;
165+ return false ;
117166 }
118167 int contentLength = request .getContentLength ();
119168 // Ignore any upload that is too small or is too large (24M)
120169 if (contentLength < 0 ) {
121170 response .setStatus (HttpServletResponse .SC_LENGTH_REQUIRED );
122- return ;
171+ return false ;
123172 }
124173 if (contentLength > 1024 * 1024 * 24 ) {
125174 response .setStatus (HttpServletResponse .SC_REQUEST_ENTITY_TOO_LARGE );
126- return ;
175+ return false ;
127176 }
128177
129178 var host = request .getHeader ("Host" );
130179 var maven = config .location (host );
131180 // Check to see if the host is valid.
132181 if (maven == null ) {
133182 response .setStatus (HttpServletResponse .SC_NOT_FOUND );
134- return ;
183+ return false ;
135184 }
136185 // Check to see if the IP was banned from uploading.
137186 // if(checkObject(baseRequest.getRemoteInetSocketAddress().getAddress())) {
138187 // response.setStatus(HttpServletResponse.SC_FORBIDDEN);
139188 // return;
140189 // }
141- var authorization = request .getHeader ("Authorization" );
142- if (authorization == null || !authorization .startsWith ("Basic " ) || checkObject (authorization )) {
190+ if (checkObject (request .getHeader ("Authorization" ))) {
143191 response .setStatus (HttpServletResponse .SC_UNAUTHORIZED );
144192 response .getWriter ().println ("Unacceptable Authorization Method" );
145- return ;
193+ return false ;
146194 }
147195
148196 try {
149- if (!Passwd .authorized (config , host , authorization , nonce , taint )) {
197+ if (!Passwd .authorized (config , host , user , nonce , taint )) {
150198 response .setStatus (HttpServletResponse .SC_UNAUTHORIZED );
151199 response .getWriter ().println ("Invalid credentials." );
152- return ;
200+ return false ;
153201 }
154202 } catch (InterruptedException e ) {
155203 throw new RuntimeException (e );
156204 }
157205 if (taint ) {
158206 response .setStatus (HttpServletResponse .SC_FORBIDDEN );
159207 response .getWriter ().println ("Use HTTPS next time. Password invalidated, contact sysadmin." );
160- return ;
208+ return false ;
161209 }
162- var path = maven .resolve ('.' + target );
163- if (Files .exists (path ) && !target .contains ("SNAPSHOT" )
164- && !target .regionMatches (target .lastIndexOf ('/' ) + 1 , "maven-metadata" , 0 , 14 )) {
165- response .setStatus (HttpServletResponse .SC_CONFLICT );
166- response .getWriter ().println ("File cannot be replaced or deleted once uploaded." );
167- return ;
168- }
169- var parent = path .getParent ();
170- if (Files .exists (parent ) && !Files .isDirectory (parent )) {
171- response .setStatus (HttpServletResponse .SC_CONFLICT );
172- response .getWriter ().println ("Package is a file." );
173- return ;
174- }
175- Files .createDirectories (parent );
176- try (var srvIn = request .getInputStream ()) {
177- Files .copy (srvIn , path , StandardCopyOption .REPLACE_EXISTING );
178- }
179- response .setStatus (HttpServletResponse .SC_CREATED );
210+
211+ return true ;
180212 }
181213
182214 /**
0 commit comments