src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java
@@ -241,4 +241,59 @@ return mdString.equals(response); } public static void main(String[] args) throws NoSuchAlgorithmException { String realm = "4401000000"; String username = "44010000001110008008"; String nonce = "0074b397f86fc263b1b7f9eb72553267"; String uri = "sip:44010000002000000001@4401000000"; // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 String qop = null; // 客户端随机数,这是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。 // 这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护 //String cNonce = authHeader.getCNonce(); // nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量 int nc = -1; String ncStr = new DecimalFormat("00000000").format(nc); // String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16)); MessageDigest messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM); String A1 = username + ":" + realm + ":" + "crservice@123"; String A2 = "REGISTER" + ":" + uri.toString(); byte mdbytes[] = messageDigest.digest(A1.getBytes()); String HA1 = toHexString(mdbytes); System.out.println("A1: " + A1); System.out.println("A2: " + A2); mdbytes = messageDigest.digest(A2.getBytes()); String HA2 = toHexString(mdbytes); System.out.println("HA1: " + HA1); System.out.println("HA2: " + HA2); String cnonce = null; System.out.println("nonce: " + nonce); System.out.println("nc: " + ncStr); System.out.println("cnonce: " + cnonce); System.out.println("qop: " + qop); String KD = HA1 + ":" + nonce; if (qop != null && qop.equals("auth") ) { if (nc != -1) { KD += ":" + ncStr; } if (cnonce != null) { KD += ":" + cnonce; } KD += ":" + qop; } KD += ":" + HA2; System.out.println("KD: " + KD); mdbytes = messageDigest.digest(KD.getBytes()); String mdString = toHexString(mdbytes); System.out.println("mdString: " + mdString); String response = "fdb1608a7a3b96f0598f40b8ba78d6a9"; System.out.println("response: " + response); } } src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
@@ -89,7 +89,7 @@ } // 未携带授权头或者密码错误 回复401 if (authorhead == null || !passwordCorrect) { if (authorhead == null ) { if (authorhead == null) { logger.info("[{}] 未携带授权头 回复401", requestAddress); @@ -98,9 +98,13 @@ } response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getSipDomain()); } }else { if (!passwordCorrect){ // 注册失败 response = getMessageFactory().createResponse(Response.FORBIDDEN, request); response.setReasonPhrase("wrong password"); }else { // 携带授权头并且密码正确 else if (passwordCorrect) { response = getMessageFactory().createResponse(Response.OK, request); // 添加date头 SIPDateHeader dateHeader = new SIPDateHeader(); @@ -157,6 +161,8 @@ device.setTransport(isTcp ? "TCP" : "UDP"); } } } getServerTransaction(evt).sendResponse(response); // 注册成功 // 保存到redis src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.service.IStreamProxyService; src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
@@ -41,7 +41,7 @@ private String streamIp; private long updateTime; private String updateTime; @JSONField(name = "hls.fileBufSize") private String hlsFileBufSize; @@ -732,11 +732,11 @@ this.shellPhell = shellPhell; } public long getUpdateTime() { public String getUpdateTime() { return updateTime; } public void setUpdateTime(long updateTime) { public void setUpdateTime(String updateTime) { this.updateTime = updateTime; } src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -24,7 +24,7 @@ @Update(value = {" <script>" + "UPDATE device_channel " + "SET updateTime=datetime('now','localtime'))" + "SET updateTime=datetime('now','localtime')" + "<if test=\"name != null\">, name='${name}'</if>" + "<if test=\"manufacture != null\">, manufacture='${manufacture}'</if>" + "<if test=\"model != null\">, model='${model}'</if>" + src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.*; @SuppressWarnings("rawtypes") @@ -22,6 +23,7 @@ @Autowired private DeviceChannelMapper deviceChannelMapper; private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * 开始播放时将流存入redis @@ -91,7 +93,7 @@ */ @Override public boolean updateMediaInfo(ZLMServerConfig ZLMServerConfig) { ZLMServerConfig.setUpdateTime(System.currentTimeMillis()); ZLMServerConfig.setUpdateTime(format.format(new Date(System.currentTimeMillis()))); return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX, ZLMServerConfig); }