微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 FTP 列表返回错误回复代码 425

如何解决为什么我的 FTP 列表返回错误回复代码 425

我正在尝试连接到 z/OS 系统并获取数据集列表。当我执行 listFiles() 命令时,出现 425 错误。我查了一下错误,IBM 网站 https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cs3cod0/ftp425-04.htm

"The session is protected by a security mechanism and the protection level for the data connection is Clear. The minimum data connection protection required by the server is Safe or Private."  

我提供了密码,并且使用 TLS 和证书登录。如果我添加 ftp.execPBSZ(0);ftp.execPROT("P");它给了我一个无法识别的 SSL 消息。我在登录之前和之后都试过这些,没关系。

如何执行 ftp.listFiles(*) 并获取有效的文件列表。

来自我的 pom.xml 的片段

        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.7</version>
        </dependency>

我的 Java 代码

    private int testConnectivity(Configuration configuration) {
        int systemExitCode = 0;
        FTPSClient ftp;
        try {
            ftp = new FTPSClient(false,getSelfSignedCertificate(configuration));
            try {
                ftp.connect(configuration.getzOsstagingHostName(),configuration.getzOsstagingHostFtpPort());
                logger.info(ftp.getReplyString());
                int reply = ftp.getReplyCode();
                logger.info("ftp.getReplyCode =" + reply);
                if (!FTPReply.isPositiveCompletion(reply)) {
                    // Bad reply code.
                    ftp.disconnect();
                    logger.error("FTP server refused connection."); 
                    ftp.disconnect();
                } else {
                    logger.info("FTP: connected to " + configuration.getzOsstagingHostName() + ":"
                            + configuration.getzOsstagingHostFtpPort());
                    ftp.enterLocalPassiveMode();
                    ftp.login(configuration.getzOsstagingUserId(),configuration.getzOsstagingUserPassword());
                    logger.info("Login completed\n" + ftp.getStatus());
//(1)                   
//(1)                   ftp.execPBSZ(0);ftp.execPROT("P");
                    ftp.enterLocalPassiveMode();
                    logger.info("PWD=" + ftp.printWorkingDirectory());
                    ftp.enterLocalPassiveMode();
                    FTPFile[] ftpFiles = ftp.listFiles("*");
                    logger.info("REPLY after list: "+Arrays.stream(ftp.getReplyStrings()).collect(Collectors.joining("\n")));
                    for (FTPFile file : ftpFiles) {
                        logger.info("FTP File: " + ftpFiles);
                    }
                    ftp.disconnect();
                }
            } catch (IOException e) {
                logger.error("Error connecting to z/OS host" + configuration.getzOsstagingHostName() + ":"
                        + configuration.getzOsstagingHostFtpPort(),e);
                systemExitCode = 1;
            }
        } catch (KeyManagementException | CertificateException | KeyStoreException | NoSuchAlgorithmException
                | IOException e1) {
            systemExitCode = 1;
            logger.error("An error occurred getting a certifcate for host",e1);
        }
        return systemExitCode;
    }

    private SSLContext getSelfSignedCertificate(Configuration configuration) throws CertificateException,KeyStoreException,NoSuchAlgorithmException,IOException,KeyManagementException {
        File crtFile = new File(configuration.getzOsstagingHostCertificateFileName());
        Certificate certificate = CertificateFactory.getInstance("X.509")
                .generateCertificate(new FileInputStream(crtFile));

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null,null);
        keyStore.setCertificateEntry("server",certificate);

        TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null,trustManagerFactory.getTrustManagers(),null);
        return sslContext;
    }

注意。如果我取消注释标有 (1) 的行,我会得到

javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
    at sun.security.ssl.SSLSocketInputRecord.handleUnkNownRecord(SSLSocketInputRecord.java:448) ~[?:1.8.0_271]
    at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:174) ~[?:1.8.0_271]
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:110) ~[?:1.8.0_271]
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1279) ~[?:1.8.0_271]
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1188) ~[?:1.8.0_271]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:401) ~[?:1.8.0_271]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373) ~[?:1.8.0_271]
    at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:642) ~[commons-net-3.7.jar:3.7]
    at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:790) ~[commons-net-3.7.jar:3.7]
    at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3456) ~[commons-net-3.7.jar:3.7]
    at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3386) ~[commons-net-3.7.jar:3.7]
    at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:3063) ~[commons-net-3.7.jar:3.7]
    at com.mycompany.myprod.sprint.App.testConnectivity(App.java:215) [classes/:?]
    at com.mycompany.myprod.sprint.App.<init>(App.java:90) [classes/:?]
    at com.mycompany.myprod.sprint.App.main(App.java:65) [classes/:?]

解决方法

问题是由于使用旧版本的 commons-net。我从 3.7 切换到 3.7.2,它就消失了。如果有人在看,我在登录后调用了 ftp.execPBSZ(0) 和 ftp.execPROT("P")。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。