Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
1 result

Target

Select target project
  • amine.chbari.etu/red5-server-GL
1 result
Select Git revision
  • master
1 result
Show changes
Commits on Source (9)
......@@ -15,8 +15,17 @@ import org.slf4j.LoggerFactory;
public class DerbyLogInterceptor {
private DerbyLogInterceptor(){
// private constructor
}
protected static Logger log = LoggerFactory.getLogger(DerbyLogInterceptor.class);
protected static String logtext = "Derby log: {}";
private static ThreadLocal<StringBuilder> local = new ThreadLocal<>();
public static OutputStream handleDerbyLogFile() {
......@@ -24,7 +33,7 @@ public class DerbyLogInterceptor {
@Override
public void write(byte[] b) throws IOException {
log.info("Derby log: {}", new String(b));
log.info(logtext, new String(b));
}
@Override
......@@ -35,10 +44,10 @@ public class DerbyLogInterceptor {
}
//look for LF
if (i == 10) {
log.info("Derby log: {}", sb.toString());
log.info(logtext, sb.toString());
sb.delete(0, sb.length() - 1);
} else {
log.trace("Derby log: {}", i);
log.trace(logtext, i);
sb.append(new String(intToDWord(i)));
}
local.set(sb);
......
......@@ -49,7 +49,7 @@ public class LoggerContextFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
ServletContext servletContext = config.getServletContext();
contextName = servletContext.getContextPath().replaceAll("/", "");
contextName = servletContext.getContextPath().replace("/", "");
if ("".equals(contextName)) {
contextName = "root";
}
......@@ -75,6 +75,7 @@ public class LoggerContextFilter implements Filter {
((LoggingContextSelector) selector).removeLocalContext();
}
// This method is empty because this java class is to be extended
public void destroy() {
}
}
......@@ -47,6 +47,49 @@ public class CoreHandler implements IScopeHandler, CoreHandlerMXBean {
return connect(conn, scope, null);
}
/** Auxiliary function to connect
*
* Creates a client if needed then sets the client on the connection
*
* @param client
* the connected client
* @param clientRegistry
* the client's registry
* @param conn
* Client connection
* @param params
* Parameters passed from client side with connect call
* @return the connection with an updated client
*/
private IConnection connectionHandleClient(IClient client, IClientRegistry clientRegistry, IConnection conn, Object[] params) {
if (client == null) {
if (!clientRegistry.hasClient(conn.getSessionId())) {
if (conn instanceof RTMPTConnection) {
log.debug("Creating new client for RTMPT connection");
// create a new client using the session id as the client's id
client = new Client(conn.getSessionId(), (ClientRegistry) clientRegistry);
clientRegistry.addClient(client);
// set the client on the connection
conn.setClient(client);
} else if (conn instanceof RTMPConnection) {
log.debug("Creating new client for RTMP connection");
// this is a new connection, create a new client to hold it
client = clientRegistry.newClient(params);
// set the client on the connection
conn.setClient(client);
}
} else {
client = clientRegistry.lookupClient(conn.getSessionId());
conn.setClient(client);
}
} else {
// set the client on the connection
conn.setClient(client);
}
return conn;
}
/**
* Connects client to the scope
*
......@@ -80,30 +123,10 @@ public class CoreHandler implements IScopeHandler, CoreHandlerMXBean {
log.debug("Client registry: {}", (clientRegistry == null ? "is null" : "not null"));
if (clientRegistry != null) {
IClient client = conn.getClient();
if (client == null) {
if (!clientRegistry.hasClient(id)) {
if (conn instanceof RTMPTConnection) {
log.debug("Creating new client for RTMPT connection");
// create a new client using the session id as the client's id
client = new Client(id, (ClientRegistry) clientRegistry);
clientRegistry.addClient(client);
// set the client on the connection
conn.setClient(client);
} else if (conn instanceof RTMPConnection) {
log.debug("Creating new client for RTMP connection");
// this is a new connection, create a new client to hold it
client = clientRegistry.newClient(params);
// set the client on the connection
conn.setClient(client);
}
} else {
client = clientRegistry.lookupClient(id);
conn.setClient(client);
}
} else {
// set the client on the connection
conn.setClient(client);
}
// call connectionHandleClient to handle all the cases for this connection
conn = connectionHandleClient(client, clientRegistry, conn, params);
// assign connection to client
conn.initialize(client);
// we could checked for banned clients here
......
......@@ -9,6 +9,7 @@ package org.red5.server;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5;
import org.red5.server.exception.LaunchErrorException;
import org.slf4j.Logger;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.context.support.FileSystemXmlApplicationContext;
......@@ -21,28 +22,27 @@ import org.springframework.context.support.FileSystemXmlApplicationContext;
*/
public class Launcher {
private static final String l_root = "red5.root";
/**
* Launch Red5 under it's own classloader
*
* @throws Exception
* @throws LaunchErrorException
* on error
*/
public void launch() throws Exception {
System.out.printf("Root: %s%nDeploy type: %s%n", System.getProperty("red5.root"), System.getProperty("red5.deployment.type"));
public void launch() throws LaunchErrorException {
System.out.printf("Root: %s%nDeploy type: %s%n", System.getProperty(l_root), System.getProperty("red5.deployment.type"));
// check for the logback disable flag
boolean useLogback = Boolean.valueOf(System.getProperty("useLogback", "true"));
if (useLogback) {
// check for context selector in system properties
if (System.getProperty("logback.ContextSelector") == null) {
// check for context selector in system properties
if (useLogback && System.getProperty("logback.ContextSelector") == null) {
// set our selector
System.setProperty("logback.ContextSelector", "org.red5.logging.LoggingContextSelector");
}
}
Red5LoggerFactory.setUseLogback(useLogback);
// install the slf4j bridge (mostly for JUL logging)
SLF4JBridgeHandler.install();
// log stdout and stderr to slf4j
//SysOutOverSLF4J.sendSystemOutAndErrToSLF4J();
// get the first logger
Logger log = Red5LoggerFactory.getLogger(Launcher.class);
// version info banner
......@@ -53,10 +53,14 @@ public class Launcher {
// create red5 app context
@SuppressWarnings("resource")
FileSystemXmlApplicationContext root = new FileSystemXmlApplicationContext(new String[] { "classpath:/red5.xml" }, false);
// set the current threads classloader as the loader for the factory/appctx
root.setClassLoader(Thread.currentThread().getContextClassLoader());
root.setId("red5.root");
root.setBeanName("red5.root");
try {
// set the current threads classloader as the loader for the factory/appctx
root.setClassLoader(Thread.currentThread().getContextClassLoader());
} catch (Exception e) {
throw new LaunchErrorException("possible mismatch between the classloader used to launch the application and the one expected by the context ", e);
}
root.setId(l_root);
root.setBeanName(l_root);
// refresh must be called before accessing the bean factory
log.trace("Refreshing root server context");
root.refresh();
......
......@@ -170,12 +170,12 @@ public class PersistableAttributeStore extends AttributeStore implements IPersis
public void serialize(Output output) throws IOException {
Map<String, Object> persistentAttributes = new HashMap<String, Object>();
for (Map.Entry<String, Object> entry : getAttributes().entrySet()) {
final String name = entry.getKey();
if (name.startsWith(IPersistable.TRANSIENT_PREFIX)) {
final String keyName = entry.getKey();
if (keyName.startsWith(IPersistable.TRANSIENT_PREFIX)) {
continue;
}
persistentAttributes.put(name, entry.getValue());
persistentAttributes.put(keyName, entry.getValue());
}
Serializer.serialize(output, persistentAttributes);
}
......@@ -248,17 +248,15 @@ public class PersistableAttributeStore extends AttributeStore implements IPersis
/** {@inheritDoc} */
@Override
public boolean setAttributes(Map<String, Object> values) {
boolean success = super.setAttributes(values);
modified();
return success;
return super.setAttributes(values);
}
/** {@inheritDoc} */
@Override
public boolean setAttributes(IAttributeStore values) {
boolean success = super.setAttributes(values);
modified();
return success;
return super.setAttributes(values);
}
/**
......
/*
* RED5 Open Source Media Server - https://github.com/Red5/ Copyright 2006-2023 by respective authors (see below). All rights reserved. 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.red5.server.exception;
/**
* Couldn't launch the server
*
*/
public class LaunchErrorException extends Exception{
/**
* this is serial Version is required from the owner developer that owns the right to initialize it
*/
// private static final long serialVersionUID = /* TODO */;
public LaunchErrorException(String message, Throwable cause) {
super(message, cause);
}
}
\ No newline at end of file
......@@ -63,6 +63,35 @@ public class InboundHandshake extends RTMPHandshake {
return decodeClientRequest1(in);
}
/**
* encrypts the response to the client request C1
* this was duplicated code 176 - 195 and 241 - 259 from original file
* regroup it in one method
*/
public void encrypt_rtmpe(byte handshaketype, int DIGEST_LENGTH, byte[] signatureResp, byte[] digestresp){
switch (handshakeType) {
case RTMPConnection.RTMP_ENCRYPTED_XTEA:
log.debug("RTMPE type 8 XTEA");
// encrypt signatureResp
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptXtea(signatureResp, i, digestresp[i] % 15);
}
break;
case RTMPConnection.RTMP_ENCRYPTED_BLOWFISH:
log.debug("RTMPE type 9 Blowfish");
// encrypt signatureResp
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptBlowfish(signatureResp, i, digestresp[i] % 15);
}
break;
}
}
/**
* Decodes the first client request (C1) and returns a server response (S0S1).
*
......@@ -173,26 +202,8 @@ public class InboundHandshake extends RTMPHandshake {
calculateHMAC_SHA256(c1, 0, (Constants.HANDSHAKE_SIZE - DIGEST_LENGTH), digestResp, DIGEST_LENGTH, signatureResponse, 0);
log.debug("Signature response: {}", Hex.encodeHexString(signatureResponse));
if (useEncryption()) {
switch (handshakeType) {
case RTMPConnection.RTMP_ENCRYPTED:
log.debug("RTMPE type 6");
// we dont encrypt signatureResp for type 6
break;
case RTMPConnection.RTMP_ENCRYPTED_XTEA:
log.debug("RTMPE type 8 XTEA");
// encrypt signatureResp
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptXtea(signatureResponse, i, digestResp[i] % 15);
}
break;
case RTMPConnection.RTMP_ENCRYPTED_BLOWFISH:
log.debug("RTMPE type 9 Blowfish");
// encrypt signatureResp
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptBlowfish(signatureResponse, i, digestResp[i] % 15);
}
break;
}
// replace the switch block with called function
encrypt_rtmpe(handshakeType, DIGEST_LENGTH, signatureResponse, digestResp);
}
// copy signature into C1 as S2
System.arraycopy(signatureResponse, 0, c1, (Constants.HANDSHAKE_SIZE - DIGEST_LENGTH), DIGEST_LENGTH);
......@@ -238,25 +249,9 @@ public class InboundHandshake extends RTMPHandshake {
calculateHMAC_SHA256(s1, digestPosServer, DIGEST_LENGTH, GENUINE_FP_KEY, GENUINE_FP_KEY.length, digest, 0);
calculateHMAC_SHA256(c2, 0, Constants.HANDSHAKE_SIZE - DIGEST_LENGTH, digest, DIGEST_LENGTH, signature, 0);
if (useEncryption()) {
switch (handshakeType) {
case RTMPConnection.RTMP_ENCRYPTED:
log.debug("RTMPE type 6");
break;
case RTMPConnection.RTMP_ENCRYPTED_XTEA:
log.debug("RTMPE type 8 XTEA");
// encrypt signature
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptXtea(signature, i, digest[i] % 15);
}
break;
case RTMPConnection.RTMP_ENCRYPTED_BLOWFISH:
log.debug("RTMPE type 9 Blowfish");
// encrypt signature
for (int i = 0; i < DIGEST_LENGTH; i += 8) {
encryptBlowfish(signature, i, digest[i] % 15);
}
break;
}
// replace the switch block with called function
encrypt_rtmpe(handshakeType, DIGEST_LENGTH, signature, digest);
// update 'encoder / decoder state' for the RC4 keys both parties *pretend* as if handshake part 2 (1536 bytes) was encrypted
// effectively this hides / discards the first few bytes of encrypted session which is known to increase the secure-ness of RC4
// RC4 state is just a function of number of bytes processed so far that's why we just run 1536 arbitrary bytes through the keys below
......