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

📄 smbtransport.java

📁 java ftp 操作代码,程序可以直接运行
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* jcifs smb client library in Java
 * Copyright (C) 2005  "Michael B. Allen" <jcifs at samba dot org>
 *                  "Eric Glass" <jcifs at samba dot org>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package jcifs.smb;

import java.io.*;
import java.net.*;
import java.util.*;

import jcifs.*;
import jcifs.netbios.*;
import jcifs.util.*;
import jcifs.util.transport.*;

public class SmbTransport extends Transport implements SmbConstants {

    static final byte[] BUF = new byte[0xFFFF];
    static final SmbComNegotiate NEGOTIATE_REQUEST = new SmbComNegotiate();
    static LogStream log = LogStream.getInstance();

    static synchronized SmbTransport getSmbTransport( UniAddress address, int port ) {
        return getSmbTransport( address, port, LADDR, LPORT );
    }
    static synchronized SmbTransport getSmbTransport( UniAddress address, int port,
                                    InetAddress localAddr, int localPort ) {
        SmbTransport conn;

        synchronized( CONNECTIONS ) {
            if( SSN_LIMIT != 1 ) {
                ListIterator iter = CONNECTIONS.listIterator();
                while( iter.hasNext() ) {
                    conn = (SmbTransport)iter.next();
                    if( conn.matches( address, port, localAddr, localPort ) &&
                            ( SSN_LIMIT == 0 || conn.sessions.size() < SSN_LIMIT )) {
                        return conn;
                    }
                }
            }

            conn = new SmbTransport( address, port, localAddr, localPort );
            CONNECTIONS.add( 0, conn );
        }

        return conn;
    }

    class ServerData {
        byte flags;
        int flags2;
        int maxMpxCount;
        int maxBufferSize;
        int sessionKey;
        int capabilities;
        String oemDomainName;
        int securityMode;
        int security;
        boolean encryptedPasswords;
        boolean signaturesEnabled;
        boolean signaturesRequired;
        int maxNumberVcs;
        int maxRawSize;
        long serverTime;
        int serverTimeZone;
        int encryptionKeyLength;
        byte[] encryptionKey;
    }

    InetAddress localAddr;
    int localPort;
    UniAddress address;
    Socket socket;
    int port, mid;
    OutputStream out;
    InputStream in;
    byte[] sbuf = new byte[255]; /* small local buffer */
    SmbComBlankResponse key = new SmbComBlankResponse();
    long sessionExpiration = System.currentTimeMillis() + SO_TIMEOUT;
    LinkedList referrals = new LinkedList();
    SigningDigest digest = null;
    LinkedList sessions = new LinkedList();
    ServerData server = new ServerData();
    /* Negotiated values */
    int flags2 = FLAGS2;
    int maxMpxCount = MAX_MPX_COUNT;
    int snd_buf_size = SND_BUF_SIZE;
    int rcv_buf_size = RCV_BUF_SIZE;
    int capabilities = CAPABILITIES;
    int sessionKey = 0x00000000;
    boolean useUnicode = USE_UNICODE;
    String tconHostName;

    SmbTransport( UniAddress address, int port, InetAddress localAddr, int localPort ) {
        this.address = address;
        this.port = port;
        this.localAddr = localAddr;
        this.localPort = localPort;
    }

    synchronized SmbSession getSmbSession() {
        return getSmbSession( new NtlmPasswordAuthentication( null, null, null ));
    }
    synchronized SmbSession getSmbSession( NtlmPasswordAuthentication auth ) {
        SmbSession ssn;
        long now;

        ListIterator iter = sessions.listIterator();
        while( iter.hasNext() ) {
            ssn = (SmbSession)iter.next();
            if( ssn.matches( auth )) {
                ssn.auth = auth;
                return ssn;
            }
        }

                                        /* logoff old sessions */
        if (SO_TIMEOUT > 0 && sessionExpiration < (now = System.currentTimeMillis())) {
            sessionExpiration = now + SO_TIMEOUT;
            iter = sessions.listIterator();
            while( iter.hasNext() ) {
                ssn = (SmbSession)iter.next();
                if( ssn.expiration < now ) {
                    ssn.logoff( false );
                }
            }
        }

        ssn = new SmbSession( address, port, localAddr, localPort, auth );
        ssn.transport = this;
        sessions.add( ssn );

        return ssn;
    }
    boolean matches( UniAddress address, int port, InetAddress localAddr, int localPort ) {
        return address.equals( this.address ) &&
                    (port == 0 || port == this.port ||
                            /* port 139 is ok if 445 was requested */
                            (port == 445 && this.port == 139)) &&
                    (localAddr == this.localAddr ||
                            (localAddr != null &&
                                    localAddr.equals( this.localAddr ))) &&
                    localPort == this.localPort;
    }
    boolean hasCapability( int cap ) throws SmbException {
        try {
            connect( RESPONSE_TIMEOUT );
        } catch( IOException ioe ) {
            throw new SmbException( "", ioe );
        }
        return (capabilities & cap) == cap;
    }
    boolean isSignatureSetupRequired( NtlmPasswordAuthentication auth ) {
        return ( flags2 & ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES ) != 0 &&
                digest == null &&
                auth != NtlmPasswordAuthentication.NULL &&
                NtlmPasswordAuthentication.NULL.equals( auth ) == false;
    }

    void ssn139() throws IOException {
        Name calledName = new Name( address.firstCalledName(), 0x20, null );
        do {
            if (localAddr == null) {
                socket = new Socket( address.getHostAddress(), 139 );
            } else {
                socket = new Socket( address.getHostAddress(), 139, localAddr, localPort );
            }
            socket.setSoTimeout( SO_TIMEOUT );
            out = socket.getOutputStream();
            in = socket.getInputStream();

            SessionServicePacket ssp = new SessionRequestPacket( calledName,
                    NbtAddress.getLocalName() );
            out.write( sbuf, 0, ssp.writeWireFormat( sbuf, 0 ));
            if (readn( in, sbuf, 0, 4 ) < 4) {
                throw new SmbException( "EOF during NetBIOS session request" );
            }
            switch( sbuf[0] & 0xFF ) {
                case SessionServicePacket.POSITIVE_SESSION_RESPONSE:
                    if( log.level > 2 )
                        log.println( "session established ok with " + address );
                    return;
                case SessionServicePacket.NEGATIVE_SESSION_RESPONSE:
                    int errorCode = (int)( in.read() & 0xFF );
                    switch (errorCode) {
                        case NbtException.CALLED_NOT_PRESENT:
                        case NbtException.NOT_LISTENING_CALLED:
                            socket.close();
                            break;
                        default:
                            disconnect( true );
                            throw new NbtException( NbtException.ERR_SSN_SRVC, errorCode );
                    }
                    break;
                case -1:
                    disconnect( true );
                    throw new NbtException( NbtException.ERR_SSN_SRVC,
                            NbtException.CONNECTION_REFUSED );
                default:
                    disconnect( true );
                    throw new NbtException( NbtException.ERR_SSN_SRVC, 0 );
            }
        } while(( calledName.name = address.nextCalledName()) != null );

        throw new IOException( "Failed to establish session with " + address );
    }
    private void negotiate( int port, ServerMessageBlock resp ) throws IOException {
        /* We cannot use Transport.sendrecv() yet because
         * the Transport thread is not setup until doConnect()
         * returns and we want to supress all communication
         * until we have properly negotiated.
         */
        synchronized (sbuf) {
            /* If jcifs.netbios.hostname is set this *probably* means there
             * is a policy regarding which hosts a user can connect from. This
             * requires communicating over port 139 rather than 445.
             */
            if (NETBIOS_HOSTNAME != null && NETBIOS_HOSTNAME.equals( "" ) == false) {
                port = 139;
            }
            if (port == 139) {
                ssn139();
            } else {
                if (port == 0)
                    port = DEFAULT_PORT; // 445
                if (localAddr == null) {
                    socket = new Socket( address.getHostAddress(), port );
                } else {
                    socket = new Socket( address.getHostAddress(), port, localAddr, localPort );
                }
                socket.setSoTimeout( SO_TIMEOUT );
                out = socket.getOutputStream();
                in = socket.getInputStream();
            }

            if (++mid == 32000) mid = 1;
            NEGOTIATE_REQUEST.mid = mid;
            int n = NEGOTIATE_REQUEST.encode( sbuf, 4 );
            Encdec.enc_uint32be( n & 0xFFFF, sbuf, 0 ); /* 4 byte ssn msg header */
            out.write( sbuf, 0, 4 + n );
            out.flush();
            /* Note the Transport thread isn't running yet so we can
             * read from the socket here.
             */
            if (peekKey() == null) /* try to read header */
                throw new IOException( "transport closed in negotiate" );
            int size = Encdec.dec_uint16be( sbuf, 2 );
            if (size < 33 || (4 + size) > sbuf.length ) {
                throw new IOException( "Invalid payload size: " + size );
            }
            readn( in, sbuf, 4 + 32, size - 32 );
            resp.decode( sbuf, 4 );
        }
    }
    public void connect() throws SmbException {
        try {
            super.connect( RESPONSE_TIMEOUT );
        } catch( TransportException te ) {
            throw new SmbException( "", te );
        }
    }
    protected void doConnect() throws IOException {
        /*
         * Negotiate Protocol Request / Response
         */

        SmbComNegotiateResponse resp = new SmbComNegotiateResponse( server );
        try {
            negotiate( port, resp );
        } catch( ConnectException ce ) {
            port = (port == 0 || port == DEFAULT_PORT) ? 139 : DEFAULT_PORT;
            negotiate( port, resp );
        }

        if( resp.dialectIndex > 10 ) {
            throw new SmbException( "This client does not support the negotiated dialect." );
        }

        /* Adjust negotiated values */

        tconHostName = address.getHostName();
        if (server.signaturesRequired || (server.signaturesEnabled && SIGNPREF)) {
            flags2 |= ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES;
        } else {
            flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_SECURITY_SIGNATURES;
        }
        maxMpxCount = Math.min( maxMpxCount, server.maxMpxCount );
        if (maxMpxCount < 1) maxMpxCount = 1;
        snd_buf_size = Math.min( snd_buf_size, server.maxBufferSize );
        capabilities &= server.capabilities;
        if ((capabilities & ServerMessageBlock.CAP_UNICODE) == 0) {
            // server doesn't want unicode
            if (FORCE_UNICODE) {
                capabilities |= ServerMessageBlock.CAP_UNICODE;
            } else {
                useUnicode = false;
                flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_UNICODE;
            }
        }
    }
    protected void doDisconnect( boolean hard ) throws IOException {
        ListIterator iter = sessions.listIterator();
        while (iter.hasNext()) {
            SmbSession ssn = (SmbSession)iter.next();
            ssn.logoff( hard );
        }
        socket.shutdownOutput();
        out.close();
        in.close();
        socket.close();
        digest = null;
    }

⌨️ 快捷键说明

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