Search in sources :

Example 1 with PRUDPPacketRequest

use of com.biglybt.net.udp.uc.PRUDPPacketRequest in project BiglyBT by BiglySoftware.

the class TRTrackerServerProcessorUDP method runSupport.

@Override
public void runSupport() {
    byte[] input_buffer = new byte[request_dg.getLength()];
    System.arraycopy(request_dg.getData(), 0, input_buffer, 0, input_buffer.length);
    int packet_data_length = input_buffer.length;
    String auth_user = null;
    byte[] auth_user_bytes = null;
    byte[] auth_hash = null;
    if (server.isTrackerPasswordEnabled()) {
        if (input_buffer.length < 17) {
            Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "TRTrackerServerProcessorUDP: " + "packet received but authorisation missing"));
            return;
        }
        packet_data_length -= 16;
        auth_user_bytes = new byte[8];
        auth_hash = new byte[8];
        System.arraycopy(input_buffer, packet_data_length, auth_user_bytes, 0, 8);
        int user_len = 0;
        while (user_len < 8 && auth_user_bytes[user_len] != 0) {
            user_len++;
        }
        auth_user = new String(auth_user_bytes, 0, user_len);
        System.arraycopy(input_buffer, packet_data_length + 8, auth_hash, 0, 8);
    }
    DataInputStream is = new DataInputStream(new ByteArrayInputStream(input_buffer, 0, packet_data_length));
    try {
        String client_ip_address = request_dg.getAddress().getHostAddress();
        PRUDPPacketRequest request = PRUDPPacketRequest.deserialiseRequest(null, is);
        Logger.log(new LogEvent(LOGID, "TRTrackerServerProcessorUDP: packet received: " + request.getString()));
        PRUDPPacket reply = null;
        TRTrackerServerTorrentImpl torrent = null;
        if (auth_user_bytes != null) {
            // user name is irrelevant as we only have one at the moment
            // <parg_home> so <new_packet> = <old_packet> + <user_padded_to_8_bytes> + <hash>
            // <parg_home> where <hash> = first 8 bytes of sha1(<old_packet> + <user_padded_to_8> + sha1(pass))
            // <XTF> Yes
            byte[] sha1_pw = null;
            if (server.hasExternalAuthorisation()) {
                try {
                    URL resource = new URL("udp://" + server.getHost() + ":" + server.getPort() + "/");
                    sha1_pw = server.performExternalAuthorisation(resource, auth_user);
                } catch (MalformedURLException e) {
                    Debug.printStackTrace(e);
                }
                if (sha1_pw == null) {
                    Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));
                    reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");
                }
            } else {
                sha1_pw = server.getPassword();
            }
            if (reply == null) {
                SHA1Hasher hasher = new SHA1Hasher();
                hasher.update(input_buffer, 0, packet_data_length);
                hasher.update(auth_user_bytes);
                hasher.update(sha1_pw);
                byte[] digest = hasher.getDigest();
                for (int i = 0; i < auth_hash.length; i++) {
                    if (auth_hash[i] != digest[i]) {
                        Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));
                        reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");
                        break;
                    }
                }
            }
        }
        int request_type = TRTrackerServerRequest.RT_UNKNOWN;
        if (reply == null) {
            if (server.isEnabled()) {
                try {
                    int type = request.getAction();
                    if (type == PRUDPPacketTracker.ACT_REQUEST_CONNECT) {
                        reply = handleConnect(client_ip_address, request);
                    } else if (type == PRUDPPacketTracker.ACT_REQUEST_ANNOUNCE) {
                        Object[] x = handleAnnounceAndScrape(client_ip_address, request, TRTrackerServerRequest.RT_ANNOUNCE);
                        if (x == null) {
                            throw (new Exception("Connection ID mismatch"));
                        }
                        reply = (PRUDPPacket) x[0];
                        torrent = (TRTrackerServerTorrentImpl) x[1];
                        request_type = TRTrackerServerRequest.RT_ANNOUNCE;
                    } else if (type == PRUDPPacketTracker.ACT_REQUEST_SCRAPE) {
                        Object[] x = handleAnnounceAndScrape(client_ip_address, request, TRTrackerServerRequest.RT_SCRAPE);
                        if (x == null) {
                            throw (new Exception("Connection ID mismatch"));
                        }
                        reply = (PRUDPPacket) x[0];
                        torrent = (TRTrackerServerTorrentImpl) x[1];
                        request_type = TRTrackerServerRequest.RT_SCRAPE;
                    } else {
                        reply = new PRUDPPacketReplyError(request.getTransactionId(), "unsupported action");
                    }
                } catch (Throwable e) {
                    // e.printStackTrace();
                    String error = e.getMessage();
                    if (error == null) {
                        error = e.toString();
                    }
                    reply = new PRUDPPacketReplyError(request.getTransactionId(), error);
                }
            } else {
                System.out.println("UDP Tracker: replying 'disabled' to " + client_ip_address);
                reply = new PRUDPPacketReplyError(request.getTransactionId(), "UDP Tracker disabled");
            }
        }
        if (reply != null) {
            InetAddress address = request_dg.getAddress();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream os = new DataOutputStream(baos);
            reply.serialise(os);
            byte[] output_buffer = baos.toByteArray();
            DatagramPacket reply_packet = new DatagramPacket(output_buffer, output_buffer.length, address, request_dg.getPort());
            socket.send(reply_packet);
            server.updateStats(request_type, torrent, input_buffer.length, output_buffer.length);
        }
    } catch (Throwable e) {
        Logger.log(new LogEvent(LOGID, "TRTrackerServerProcessorUDP: processing fails", e));
    } finally {
        try {
            is.close();
        } catch (Throwable e) {
        }
    }
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) PRUDPPacket(com.biglybt.net.udp.uc.PRUDPPacket) TRTrackerServerTorrentImpl(com.biglybt.core.tracker.server.impl.TRTrackerServerTorrentImpl) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DataInputStream(java.io.DataInputStream) PRUDPPacketRequest(com.biglybt.net.udp.uc.PRUDPPacketRequest) ByteArrayInputStream(java.io.ByteArrayInputStream)

Aggregations

LogEvent (com.biglybt.core.logging.LogEvent)1 TRTrackerServerTorrentImpl (com.biglybt.core.tracker.server.impl.TRTrackerServerTorrentImpl)1 PRUDPPacket (com.biglybt.net.udp.uc.PRUDPPacket)1 PRUDPPacketRequest (com.biglybt.net.udp.uc.PRUDPPacketRequest)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1