rcommandclient.java

来自「apache推出的net包」· Java 代码 · 共 393 行 · 第 1/2 页

JAVA
393
字号
/* * Copyright 2001-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.net.bsd;import java.io.IOException;import java.io.InputStream;import java.net.BindException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import org.apache.commons.net.io.SocketInputStream;/*** * RCommandClient is very similar to * {@link org.apache.commons.net.bsd.RExecClient}, * from which it is derived, and implements the rcmd() facility that * first appeared in 4.2BSD Unix.  rcmd() is the facility used by the rsh * (rshell) and other commands to execute a command on another machine * from a trusted host without issuing a password.  The trust relationship * between two machines is established by the contents of a machine's * /etc/hosts.equiv file and a user's .rhosts file.  These files specify * from which hosts and accounts on those hosts rcmd() requests will be * accepted.  The only additional measure for establishing trust is that * all client connections must originate from a port between 512 and 1023. * Consequently, there is an upper limit to the number of rcmd connections * that can be running simultaneously.   The required ports are reserved * ports on Unix systems, and can only be bound by a * process running with root permissions (to accomplish this rsh, rlogin, * and related commands usualy have the suid bit set).  Therefore, on a * Unix system, you will only be able to successfully use the RCommandClient * class if the process runs as root.  However, there is no such restriction * on Windows95 and some other systems.  The security risks are obvious. * However, when carefully used, rcmd() can be very useful when used behind * a firewall. * <p> * As with virtually all of the client classes in org.apache.commons.net, this * class derives from SocketClient.  But it overrides most of its connection * methods so that the local Socket will originate from an acceptable * rshell port.  The way to use RCommandClient is to first connect * to the server, call the {@link #rcommand  rcommand() } method, * and then * fetch the connection's input, output, and optionally error streams. * Interaction with the remote command is controlled entirely through the * I/O streams.  Once you have finished processing the streams, you should * invoke {@link org.apache.commons.net.bsd.RExecClient#disconnect disconnect() } *  to clean up properly. * <p> * By default the standard output and standard error streams of the * remote process are transmitted over the same connection, readable * from the input stream returned by * {@link org.apache.commons.net.bsd.RExecClient#getInputStream getInputStream() } * .  However, it is * possible to tell the rshd daemon to return the standard error * stream over a separate connection, readable from the input stream * returned by {@link org.apache.commons.net.bsd.RExecClient#getErrorStream getErrorStream() } * .  You * can specify that a separate connection should be created for standard * error by setting the boolean <code> separateErrorStream </code> * parameter of {@link #rcommand  rcommand() } to <code> true </code>. * The standard input of the remote process can be written to through * the output stream returned by * {@link org.apache.commons.net.bsd.RExecClient#getOutputStream getOutputStream() } * . * <p> * <p> * @author Daniel F. Savarese * @see org.apache.commons.net.SocketClient * @see RExecClient * @see RLoginClient ***/public class RCommandClient extends RExecClient{    /***     * The default rshell port.  Set to 514 in BSD Unix.     ***/    public static final int DEFAULT_PORT = 514;    /***     * The smallest port number an rcmd client may use.  By BSD convention     * this number is 512.     ***/    public static final int MIN_CLIENT_PORT = 512;    /***     * The largest port number an rcmd client may use.  By BSD convention     * this number is 1023.     ***/    public static final int MAX_CLIENT_PORT = 1023;    // Overrides method in RExecClient in order to implement proper    // port number limitations.    InputStream _createErrorStream() throws IOException    {        int localPort;        ServerSocket server;        Socket socket;        localPort = MAX_CLIENT_PORT;        server = null; // Keep compiler from barfing        for (localPort = MAX_CLIENT_PORT; localPort >= MIN_CLIENT_PORT; --localPort)        {            try            {                server = _socketFactory_.createServerSocket(localPort, 1,                         getLocalAddress());            }            catch (SocketException e)            {                continue;            }            break;        }        if (localPort < MIN_CLIENT_PORT)            throw new BindException("All ports in use.");        _output_.write(Integer.toString(server.getLocalPort()).getBytes());        _output_.write('\0');        _output_.flush();        socket = server.accept();        server.close();        if (isRemoteVerificationEnabled() && !verifyRemote(socket))        {            socket.close();            throw new IOException(                "Security violation: unexpected connection attempt by " +                socket.getInetAddress().getHostAddress());        }        return (new SocketInputStream(socket, socket.getInputStream()));    }    /***     * The default RCommandClient constructor.  Initializes the     * default port to <code> DEFAULT_PORT </code>.     ***/    public RCommandClient()    {        setDefaultPort(DEFAULT_PORT);    }    /***     * Opens a Socket connected to a remote host at the specified port and     * originating from the specified local address using a port in a range     * acceptable to the BSD rshell daemon.     * Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_  _connectAction_() }     * is called to perform connection initialization actions.     * <p>     * @param host  The remote host.     * @param port  The port to connect to on the remote host.     * @param localAddr  The local address to use.     * @exception SocketException If the socket timeout could not be set.     * @exception BindException If all acceptable rshell ports are in use.     * @exception IOException If the socket could not be opened.  In most     *  cases you will only want to catch IOException since SocketException is     *  derived from it.     ***/    public void connect(InetAddress host, int port, InetAddress localAddr)    throws SocketException, BindException, IOException    {        int localPort;        localPort = MAX_CLIENT_PORT;        for (localPort = MAX_CLIENT_PORT; localPort >= MIN_CLIENT_PORT; --localPort)        {            try            {                _socket_ =                    _socketFactory_.createSocket(host, port, localAddr, localPort);            }            catch (SocketException e)            {                continue;            }            break;        }

⌨️ 快捷键说明

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