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

📄 smbtransport.java

📁 实现网上邻居需要的jar库;可以使用库中的接口实现文件共享的功能
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        if (log.level >= 4) {
            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 ) & 0xFFFF;

        /* 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 >= 4) {
                do {
                    log.println( smb );
                } while (smb instanceof AndXServerMessageBlock &&
                        (smb = ((AndXServerMessageBlock)smb).andx) != null);
                if (log.level >= 6) {
                    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;
        resp.extendedSecurity = (capabilities & CAP_EXTENDED_SECURITY) == CAP_EXTENDED_SECURITY;

        synchronized (BUF) {
            System.arraycopy( sbuf, 0, BUF, 0, 4 + HEADER_LENGTH );
            int size = Encdec.dec_uint16be( BUF, 2 ) & 0xFFFF;
            if (size < (HEADER_LENGTH + 1) || (4 + size) > rcv_buf_size ) {
                throw new IOException( "Invalid payload size: " + size );
            }
            int errorCode = Encdec.dec_uint32le( BUF, 9 ) & 0xFFFFFFFF;
            if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX &&
                        (errorCode == 0 ||
                        errorCode == 0x80000005)) { // overflow indicator normal for pipe
                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 );
            }

            if (log.level >= 4) {
                log.println( response );
                if (log.level >= 6) {
                    Hexdump.hexdump( log, BUF, 4, size );
                }
            }
        }
    }
    protected void doSkip() throws IOException {
        int size = Encdec.dec_uint16be( sbuf, 2 ) & 0xFFFF;
        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[] drs = getDfsReferrals(req.auth, req.path, 1);
                if (0 == drs.length) {
                    /* Nov 12, 2008: liuqiang from rst.ricoh.com claims this
                     * stops AIOBE in certain cases.
                     */
                    throw new SmbException(resp.errorCode, null);   
                }
                SmbFile.dfs.insert(req.path, drs[0]);
                throw drs[0];
            case 0x80000005:  /* STATUS_BUFFER_OVERFLOW */
                break; /* normal for DCERPC named pipes */
            case NtStatus.NT_STATUS_MORE_PROCESSING_REQUIRED:
                break; /* normal for NTLMSSP */
            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( InterruptedException ie ) {
            throw new SmbException( ie.getMessage(), ie );
        } catch( IOException ioe ) {
            throw new SmbException( ioe.getMessage(), ioe );
        }

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

    /* DFS */

    /* Split DFS path like \fs1.example.com\root5\link2\foo\bar.txt into at
     * most 3 components (not including the first index which is always empty):
     * result[0] = ""
     * result[1] = "fs1.example.com"
     * result[2] = "root5"
     * result[3] = "link2\foo\bar.txt"
     */
    void dfsPathSplit(String path, String[] result)
    {
        int ri = 0, rlast = result.length - 1;
        int i = 0, b = 0, len = path.length();

        do {
            if (ri == rlast) {
                result[rlast] = path.substring(b);
                return;
            }
            if (i == len || path.charAt(i) == '\\') {
                result[ri++] = path.substring(b, i);
                b = i + 1;
            }
        } while (i++ < len);

        while (ri < result.length) {
            result[ri++] = "";
        }
    }
    DfsReferral[] getDfsReferrals(NtlmPasswordAuthentication auth,
                String path,
                int rn) throws SmbException {
        SmbTree ipc = getSmbSession( auth ).getSmbTree( "IPC$", null );
        Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse();
        ipc.send( new Trans2GetDfsReferral( path ), resp );

        if (rn == 0 || resp.numReferrals < rn) {
            rn = resp.numReferrals;
        }

        DfsReferral[] drs = new DfsReferral[rn];
        String[] arr = new String[4];
        long expiration = System.currentTimeMillis() + Dfs.TTL * 1000;

        for (int di = 0; di < drs.length; di++) {
            DfsReferral dr = new DfsReferral();
                        /* NTLM HTTP Authentication must be re-negotiated
                         * with challenge from 'server' to access DFS vol. */
            dr.resolveHashes = auth.hashesExternal;
            dr.ttl = resp.referrals[di].ttl;
            dr.expiration = expiration;
            if (path.equals("")) {
                dr.server = resp.referrals[di].path.substring(1).toLowerCase();
            } else {
                dfsPathSplit(resp.referrals[di].node, arr);
                dr.server = arr[1];
                dr.share = arr[2];
                dr.path = arr[3];
            }
            dr.pathConsumed = resp.pathConsumed;
            drs[di] = dr;
        }

        return drs;
    }
    FileEntry[] getDfsRoots(String domainName, NtlmPasswordAuthentication auth) throws IOException {
        MsrpcDfsRootEnum rpc;
        DcerpcHandle handle = null;

        /* Procedure:
         * Lookup a DC in the target domain
         * Ask the DC for a referral for the domain (e.g. "\example.com")
         * Do NetrDfsEnumEx on the server returned in the referral to
         * get roots in target domain
         */

        UniAddress dc = UniAddress.getByName(domainName);
        SmbTransport trans = SmbTransport.getSmbTransport(dc, 0);
        DfsReferral[] dr = trans.getDfsReferrals(auth, "\\" + domainName, 1);

        handle = DcerpcHandle.getHandle("ncacn_np:" +
                    UniAddress.getByName(dr[0].server).getHostAddress() +
                    "[\\PIPE\\netdfs]", auth);
        try {
            rpc = new MsrpcDfsRootEnum(domainName);
            handle.sendrecv(rpc);
            if (rpc.retval != 0)
                throw new SmbException(rpc.retval, true);
            return rpc.getEntries();
        } finally {
            try {
                handle.close();
            } catch(IOException ioe) {
                if (log.level >= 4)
                    ioe.printStackTrace(log);
            }
        }
    }
}

⌨️ 快捷键说明

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