⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbtransport.java

📁 java ftp 操作代码,程序可以直接运行
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    protected void makeKey( Request request ) throws IOException {
        /* The request *is* the key */
        if (++mid == 32000) mid = 1;
        ((ServerMessageBlock)request).mid = mid;
    }
    protected Request peekKey() throws IOException {
        int n;
        do {
            if ((n = readn( in, sbuf, 0, 4 )) < 4)
                return null;
        } while (sbuf[0] == (byte)0x85);  /* Dodge NetBIOS keep-alive */
                                                   /* read smb header */
        if ((n = readn( in, sbuf, 4, 32 )) < 32)
            return null;
        if (log.level > 2) {
            log.println( "New data read: " + this );
            jcifs.util.Hexdump.hexdump( log, sbuf, 4, 32 );
        }

        for ( ;; ) {
            /* 01234567
             * 00SSFSMB
             * 0 - 0's
             * S - size of payload
             * FSMB - 0xFF SMB magic #
             */

            if (sbuf[0] == (byte)0x00 &&
                        sbuf[1] == (byte)0x00 &&
                        sbuf[4] == (byte)0xFF &&
                        sbuf[5] == (byte)'S' &&
                        sbuf[6] == (byte)'M' &&
                        sbuf[7] == (byte)'B') {
                break; /* all good */
            }
                                        /* out of phase maybe? */
                          /* inch forward 1 byte and try again */
            for (int i = 0; i < 35; i++) {
                sbuf[i] = sbuf[i + 1];
            }
            int b;
            if ((b = in.read()) == -1) return null;
            sbuf[35] = (byte)b;
        }

        key.mid = Encdec.dec_uint16le( sbuf, 34 );

        /* Unless key returned is null or invalid Transport.loop() always
         * calls doRecv() after and no one else but the transport thread
         * should call doRecv(). Therefore it is ok to expect that the data
         * in sbuf will be preserved for copying into BUF in doRecv().
         */

        return key;
    }

    protected void doSend( Request request ) throws IOException {
        synchronized (BUF) {
            ServerMessageBlock smb = (ServerMessageBlock)request;
            int n = smb.encode( BUF, 4 );
            Encdec.enc_uint32be( n & 0xFFFF, BUF, 0 ); /* 4 byte session message header */
            if (log.level > 3) {
                do {
                    log.println( smb );
                } while (smb instanceof AndXServerMessageBlock &&
                        (smb = ((AndXServerMessageBlock)smb).andx) != null);
                if (log.level > 5) {
                    Hexdump.hexdump( log, BUF, 4, n );
                }
            }
            out.write( BUF, 0, 4 + n );
        }
    }
    protected void doSend0( Request request ) throws IOException {
        try {
            doSend( request );
        } catch( IOException ioe ) {
            if (log.level > 2)
                ioe.printStackTrace( log );
            try {
                disconnect( true );
            } catch( IOException ioe2 ) {
                ioe2.printStackTrace( log );
            }
            throw ioe;
        }
    }

    protected void doRecv( Response response ) throws IOException {
        ServerMessageBlock resp = (ServerMessageBlock)response;
        resp.useUnicode = useUnicode;

        synchronized (BUF) {
            System.arraycopy( sbuf, 0, BUF, 0, 4 + HEADER_LENGTH );
            int size = Encdec.dec_uint16be( BUF, 2 );
            if (size < (HEADER_LENGTH + 1) || (4 + size) > rcv_buf_size ) {
                throw new IOException( "Invalid payload size: " + size );
            }
            if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX) {
                SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp;
                int off = HEADER_LENGTH;
                                    /* WordCount thru dataOffset always 27 */
                readn( in, BUF, 4 + off, 27 ); off += 27;
                resp.decode( BUF, 4 );
                if (r.dataLength > 0) {
                    readn( in, BUF, 4 + off, r.dataOffset - off);   /* pad */
                    readn( in, r.b, r.off, r.dataLength );  /* read direct */
                }
            } else {
                readn( in, BUF, 4 + 32, size - 32 );
                resp.decode( BUF, 4 );
                if (resp instanceof SmbComTransactionResponse) {
                    ((SmbComTransactionResponse)resp).nextElement();
                }
            }

            /* Verification fails (w/ W2K3 server at least) if status is not 0. This
             * suggests MS doesn't compute the signature (correctly) for error responses
             * (perhaps for DOS reasons).
             */
            if (digest != null && resp.errorCode == 0) {
                digest.verify( BUF, 4, resp );
            }
        }
    }
    protected void doSkip() throws IOException {
        int size = Encdec.dec_uint16be( sbuf, 2 );
        if (size < 33 || (4 + size) > rcv_buf_size ) {
            /* log message? */
            in.skip( in.available() );
        } else {
            in.skip( size - 32 );
        }
    }
    void checkStatus( ServerMessageBlock req, ServerMessageBlock resp ) throws SmbException {
        resp.errorCode = SmbException.getStatusByCode( resp.errorCode );
        switch( resp.errorCode ) {
            case NtStatus.NT_STATUS_OK:
                break;
            case NtStatus.NT_STATUS_ACCESS_DENIED:
            case NtStatus.NT_STATUS_WRONG_PASSWORD:
            case NtStatus.NT_STATUS_LOGON_FAILURE:
            case NtStatus.NT_STATUS_ACCOUNT_RESTRICTION:
            case NtStatus.NT_STATUS_INVALID_LOGON_HOURS:
            case NtStatus.NT_STATUS_INVALID_WORKSTATION:
            case NtStatus.NT_STATUS_PASSWORD_EXPIRED:
            case NtStatus.NT_STATUS_ACCOUNT_DISABLED:
            case NtStatus.NT_STATUS_ACCOUNT_LOCKED_OUT:
            case NtStatus.NT_STATUS_TRUSTED_DOMAIN_FAILURE:
                throw new SmbAuthException( resp.errorCode );
            case NtStatus.NT_STATUS_PATH_NOT_COVERED:
                if( req.auth == null ) {
                    throw new SmbException( resp.errorCode, null );
                }
                DfsReferral dr = getDfsReferral( req.auth, req.path );
                referrals.add( dr );
                throw dr;
            case 0x80000005:  /* STATUS_BUFFER_OVERFLOW */
                break; /* normal for DCERPC named pipes */
            default:
                throw new SmbException( resp.errorCode, null );
        }
        if (resp.verifyFailed) {
            throw new SmbException( "Signature verification failed." );
        }
    }
    void send( ServerMessageBlock request, ServerMessageBlock response ) throws SmbException {

        connect(); /* must negotiate before we can test flags2, useUnicode, etc */

        request.flags2 |= flags2;
        request.useUnicode = useUnicode;
        request.response = response; /* needed by sign */
        if (request.digest == null)
            request.digest = digest; /* for sign called in encode */

        try {
            if (response == null) {
                doSend0( request );
                return;
            } else if (request instanceof SmbComTransaction) {
                response.command = request.command;
                SmbComTransaction req = (SmbComTransaction)request;
                SmbComTransactionResponse resp = (SmbComTransactionResponse)response;

                req.maxBufferSize = snd_buf_size;
                resp.reset();

                try {
                    BufferCache.getBuffers( req, resp );

                    /* 
                     * First request w/ interim response
                     */ 

                    req.nextElement();
                    if (req.hasMoreElements()) {
                        SmbComBlankResponse interim = new SmbComBlankResponse();
                        super.sendrecv( req, interim, RESPONSE_TIMEOUT );
                        if (interim.errorCode != 0) {
                            checkStatus( req, interim );
                        }
                        req.nextElement();
                    } else {
                        makeKey( req );
                    }

                    synchronized (response_map) {
                        response.received = false;
                        resp.isReceived = false;
                        try {
                            response_map.put( req, resp );

                            /* 
                             * Send multiple fragments
                             */

                            do {
                                doSend0( req );
                            } while( req.hasMoreElements() && req.nextElement() != null );

                            /* 
                             * Receive multiple fragments
                             */

                            long timeout = RESPONSE_TIMEOUT;
                            resp.expiration = System.currentTimeMillis() + timeout;
                            while( resp.hasMoreElements() ) {
                                response_map.wait( timeout );
                                timeout = resp.expiration - System.currentTimeMillis();
                                if (timeout <= 0) {
                                    throw new TransportException( this +
                                            " timedout waiting for response to " +
                                            req );
                                }
                            }
                            if (response.errorCode != 0) {
                                checkStatus( req, resp );
                            }
                        } catch( InterruptedException ie ) {
                            throw new TransportException( ie );
                        } finally {
                            response_map.remove( req );
                        }
                    }
                } finally {
                    BufferCache.releaseBuffer( req.txn_buf );
                    BufferCache.releaseBuffer( resp.txn_buf );
                }

            } else {
                response.command = request.command;
                super.sendrecv( request, response, RESPONSE_TIMEOUT );
            }
        } catch( SmbException se ) {
            throw se;
        } catch( IOException ioe ) {
            throw new SmbException( "", ioe );
        }

        checkStatus( request, response );
    }
    public String toString() {
        return super.toString() + "[" + address + ":" + port + "]";
    }

    /* DFS */

    DfsReferral getDfsReferral( NtlmPasswordAuthentication auth,
                String path ) throws SmbException {
        String subpath, node, host;
        DfsReferral dr = new DfsReferral();
        int p, n, i, s;
        UniAddress addr;

        SmbTree ipc = getSmbSession( auth ).getSmbTree( "IPC$", null );
        Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse();
        ipc.send( new Trans2GetDfsReferral( path ), resp );

        subpath = path.substring( 0, resp.pathConsumed );
        node = resp.referral.node;
        if( subpath.charAt( 0 ) != '\\' ||
                (i = subpath.indexOf( '\\', 1 )) < 2 ||
                (p = subpath.indexOf( '\\', i + 1 )) < (i + 2) ||
                node.charAt( 0 ) != '\\' ||
                (s = node.indexOf( '\\', 1 )) < 2) {
            throw new SmbException( "Invalid DFS path: " + path );
        }
        if ((n = node.indexOf( '\\', s + 1 )) == -1) {
            n = node.length();
        }

        dr.path = subpath.substring( p );
        dr.node = node.substring( 0, n );
        dr.nodepath = node.substring( n );
        dr.server = node.substring( 1, s );
        dr.share = node.substring( s + 1, n );
        dr.resolveHashes = auth.hashesExternal;
                        /* NTLM HTTP Authentication must be re-negotiated
                         * with challenge from 'server' to access DFS vol. */
        return dr;
    }
    DfsReferral lookupReferral( String unc ) {
        synchronized( referrals ) {
            DfsReferral dr;
            ListIterator iter = referrals.listIterator();
            int i, len;

            while( iter.hasNext() ) {
                dr = (DfsReferral)iter.next();
                len = dr.path.length();
                for( i = 0; i < len && i < unc.length(); i++ ) {
                    if( dr.path.charAt( i ) != unc.charAt( i )) {
                        break;
                    }
                }
                if( i == len && (len == unc.length() || unc.charAt( len ) == '\\')) {
                    return dr;
                }
            }
        }

        return null;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -