FTP upload - Protection Buffer Size parsing exception error

Hello.

We are trying to setup a config that would upload a zip file to a FTP server.
The server is using FTPES protocol, and is accepting data channel protection level set to 'private'. 
We are hitting an error in the Apache FTP library when trying to parse the Protection Buffer Size.
We suspect that the value "PBZ=0." we get from the server, is ill-formatted somehow, or gets misread by the client. We would be happy if we could get some additional insight from you in order to track down what the problem is.

The call stack we get when the build runner fails looks like this:

 java.lang.NumberFormatException: For input string: "0."
   at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
   at java.base/java.lang.Long.parseLong(Long.java:692)
   at java.base/java.lang.Long.parseLong(Long.java:817)
   at org.apache.commons.net.ftp.FTPSClient.parsePBSZ(FTPSClient.java:495)
   at jetbrains.buildServer.deployer.agent.ftp.FtpBuildProcessAdapter.enableDataChannelProtection(FtpBuildProcessAdapter.java:218)
   at jetbrains.buildServer.deployer.agent.ftp.FtpBuildProcessAdapter.runProcess(FtpBuildProcessAdapter.java:121)
   at jetbrains.buildServer.deployer.agent.SyncBuildProcessAdapter.start(SyncBuildProcessAdapter.java:65)
   at jetbrains.buildServer.agent.impl.buildStages.runnerStages.start.CallRunnerStage.doBuildStage(CallRunnerStage.java:60)
   at jetbrains.buildServer.agent.impl.buildStages.RunnerStagesExecutor$1.callStage(RunnerStagesExecutor.java:27)
   at jetbrains.buildServer.agent.impl.buildStages.RunnerStagesExecutor$1.callStage(RunnerStagesExecutor.java:18)
   at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.callRunStage(StagesExecutor.java:76)
   at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.doStages(StagesExecutor.java:35)
   at jetbrains.buildServer.agent.impl.buildStages.RunnerStagesExecutor.doStages(RunnerStagesExecutor.java:18)
   at jetbrains.buildServer.agent.impl.buildStages.startStages.steps.RunnerContextExecutor.executeBuildStepStages(RunnerContextExecutor.java:45)
   at jetbrains.buildServer.agent.impl.buildStages.startStages.steps.RunAllBuildStepsStage.runBuildStep(RunAllBuildStepsStage.java:190)
   at jetbrains.buildServer.agent.impl.buildStages.startStages.steps.RunAllBuildStepsStage.runStep(RunAllBuildStepsStage.java:176)
   at jetbrains.buildServer.agent.impl.buildStages.startStages.steps.RunAllBuildStepsStage.executeBuildRunners(RunAllBuildStepsStage.java:126)
   at jetbrains.buildServer.agent.impl.buildStages.startStages.steps.RunAllBuildStepsStage.doBuildStage(RunAllBuildStepsStage.java:58)
   at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor$1.callStage(BuildStagesExecutor.java:33)
   at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor$1.callStage(BuildStagesExecutor.java:24)
   at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.callRunStage(StagesExecutor.java:76)
   at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.doStages(StagesExecutor.java:35)
   at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor.doStages(BuildStagesExecutor.java:24)
   at jetbrains.buildServer.agent.impl.BuildRunActionImpl.doStages(BuildRunActionImpl.java:97)
   at jetbrains.buildServer.agent.AgentOperationModeEx.executeRunnerStages(AgentOperationModeEx.java:36)
   at jetbrains.buildServer.agent.impl.BuildRunActionImpl.runBuild(BuildRunActionImpl.java:68)
   at jetbrains.buildServer.agent.impl.BuildAgentImpl.doActualBuild(BuildAgentImpl.java:346)
   at jetbrains.buildServer.agent.impl.BuildAgentImpl.access$100(BuildAgentImpl.java:62)
   at jetbrains.buildServer.agent.impl.BuildAgentImpl$1.run(BuildAgentImpl.java:295)
   at java.base/java.lang.Thread.run(Thread.java:829)

When using curl, it seems to work fine. Excerpt from the log looks like this:

curl -v --ftp-ssl --insecure --user *****:***** ftp://ftps.*****.com:21
*  Trying xxx.xxx.x.xxx:21...
* TCP_NODELAY set
* Connected to ftps.*****.com (xxx.xxx.x.xxx) port 21 (#0)
< 220 Wing FTP Server ready...
> AUTH SSL
< 234 AUTH command OK. Initializing SSL connection.
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* subject: CN=*.*****.com
* start date: Nov 12 00:00:00 2023 GMT
* expire date: Nov 11 23:59:59 2024 GMT
* issuer: C=LU; O=CentralNic Luxembourg S?rl; CN=GlobeSSL DV CA
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> USER *****
< 331 Password required for *****
> PASS ********
< 230 User *****logged in.
> PBSZ 0
< 200 Command okay. PBSZ=0.
> PROT P
< 200 Data channel will be encrypted.
> PWD
< 257 “/” is current directory.
* Entry path is ‘/’
* Request has same path as previous transfer
> EPSV
* Connect data stream passively

Thanks 
Sandro

0
3 comments

Hi Sandro, 

It sounds like a bug. Could you please upload the entire build log downloaded from the UI along with the teamcity-agent.log from the corresponding agent to https://uploads.jetbrains.com/? Let me know the upload ID once it is done.

0

Hello. Uploaded it now. The ID is: 2024_06_25_WQvq9R6Z6xdoUrBHCVWSH2

0

Hi Sandro, 

It looks like a bug in the Apache Commons library. The FTPSClient.parsePBSZ method captures a dot in your server's reply. See https://github.com/apache/commons-net/blob/2ae653682d939e19fb8b21e5311b2c9563972938/src/main/java/org/apache/commons/net/ftp/FTPSClient.java#L948

I'm not entirely sure that Apache would consider it a bug, though, as your FTP server's reply format is a bit unusual—or rather, it's a rare enough format for Apache not to expect it. 

> PBSZ 0
< 200 Command okay. PBSZ=0.

A more common reply from FTP servers looks like this:

Command:  PBSZ 0
Response: 200 PBSZ=0

I suggest checking your FTP server configuration. Maybe it's possible to adjust the reply format. 

Alternatively, you can use a command line build step in TeamCity with the scp/sftp commands as a workaround. 

0

Please sign in to leave a comment.