1. I noticed you have a interface for RTP authentication can I create a class that implements authentition using my rules? Using this I might be able to avoid number 2.
Sure, here are the two interfaces that need to be implemented:
Code:
public interface IAuthenticate
{
public static final int PASSWORDFILEFORMAT_UNKNOWN = 0;
public static final int PASSWORDFILEFORMAT_CLEAR = 1;
public abstract void init(AuthenticationItem authenticationItem);
}
public interface IAuthenticateRTSP
{
public abstract boolean authenticateRTSP(RTPSession rtspSession, RTSPRequestMessage req, RTSPResponseMessages resp);
}
And here is the code for the basic authentication type:
Code:
public class AuthenticateBasic implements IAuthenticate, IAuthenticateRTSP
{
private AuthenticationItem authenticationItem = null;
private boolean isAuthenticated = false;
private String realm = null;
private File passwordFile = null;
public void init(AuthenticationItem authenticationItem)
{
this.authenticationItem = authenticationItem;
realm = this.authenticationItem.getProperties().getPropertyStr("realm", realm);
String passwordFileStr = this.authenticationItem.getProperties().getPropertyStr("passwordFile", null);
if (passwordFileStr != null)
{
passwordFileStr = SystemUtils.expandEnvironmentVariables(passwordFileStr);
passwordFile = new File(passwordFileStr);
}
}
private String getAuthString()
{
String ret = "Basic";
if (this.realm != null)
ret += " realm=\""+this.realm+"\"";
return ret;
}
public boolean authenticateRTSP(RTPSession rtspSession, RTSPRequestMessage req, RTSPResponseMessages resp)
{
if (isAuthenticated)
return true;
boolean isValid = false;
String inAuthStr = req.getHeader("authorization");
if (inAuthStr != null)
{
inAuthStr = inAuthStr.trim();
if (inAuthStr.toLowerCase().startsWith("basic "))
inAuthStr = inAuthStr.substring(6);
inAuthStr = inAuthStr.trim();
byte[] authBytes = Base64.decode(inAuthStr);
String authStr = new String(authBytes);
String username = null;
String password = null;
int cindex = authStr.indexOf(":");
if (cindex >= 0)
{
username = authStr.substring(0, cindex);
password = authStr.substring(cindex+1);
}
else
username = authStr;
//System.out.println("AuthenticateBasic.authenticateRTSP: "+username+":"+password);
AuthenticationPasswordFile filePtr = AuthenticationPasswordFiles.getInstance().getPasswordFile(passwordFile);
if (filePtr != null)
{
if (username != null && password != null)
{
String authPassword = filePtr.getPassword(username);
if (authPassword.equals(password))
{
isValid = true;
isAuthenticated = true;
}
}
else
{
if (filePtr.userExists(username) && filePtr.getPassword(username) == null)
{
isValid = true;
isAuthenticated = true;
}
}
}
else
WMSLoggerFactory.getLogger(AuthenticationPasswordFile.class).warn("AuthenticateBasic.authenticateRTSP: Password file not found: "+passwordFile);
}
if (!isValid)
{
RTPRequestStatus status = new RTPRequestStatus();
RTSPStatics.setStatus(status, 401);
RTSPResponseMessage message = new RTSPResponseMessage();
message.setResponseCode(status.getResponseCode());
message.setResponseMessage(status.getResponseMessage());
message.setHeader("WWW-Authenticate", getAuthString());
message.setCSeq(req.getCSeq());
message.setSession(rtspSession.getSessionId());
resp.addMessage(message);
}
return isValid;
}
}
1b. Since the onConnect is not called are the other event based triggers called? I need to be able to track then the session started / ended and the IOStats for the session.
No, there really isn't a great way to track these sessions yet. I will consider adding this API.
3. Do you automatically also look from a stream with .sdp appended or do the users have to add the .sdp extension?
The users have to add the .sdp extension. Nothing is automatically appended. There are encoders that do not require or use a .sdp extension. QuickTime Broadcaster is the only encoder that I know of that automatically adds the .sdp extension. Wirecast does not.
Charlie