/* 查找密文 */ static ngx_int_t ngx_rtmp_find_digest(ngx_buf_t *b, ngx_str_t *key, size_t base, ngx_log_t *log) { size_t n, offs; u_char digest[NGX_RTMP_HANDSHAKE_KEYLEN]; u_char *p; /* 获得密文偏移 */ offs = 0; for (n = 0; n < 4; ++n) { offs += b->pos[base + n]; } offs = (offs % 728) + base + 4; p = b->pos + offs; if (ngx_rtmp_make_digest(key, b, p, digest, log) != NGX_OK) { return NGX_ERROR; } /* 比较是否一致 */ if (ngx_memcmp(digest, p, NGX_RTMP_HANDSHAKE_KEYLEN) == 0) { return offs; } return NGX_ERROR; }
static ngx_int_t ngx_rtmp_handshake_parse_challenge(ngx_rtmp_session_t *s, ngx_str_t *peer_key, ngx_str_t *key) { ngx_buf_t *b; u_char *p; ngx_int_t offs; b = s->hs_buf; if (*b->pos != '\x03') { ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, "handshake: unexpected RTMP version: %i", (ngx_int_t)*b->pos); return NGX_ERROR; } ++b->pos; s->peer_epoch = 0; ngx_rtmp_rmemcpy(&s->peer_epoch, b->pos, 4); p = b->pos + 4; ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "handshake: peer version=%i.%i.%i.%i epoch=%uD", (ngx_int_t)p[3], (ngx_int_t)p[2], (ngx_int_t)p[1], (ngx_int_t)p[0], (uint32_t)s->peer_epoch); if (*(uint32_t *)p == 0) { s->hs_old = 1; return NGX_OK; } offs = ngx_rtmp_find_digest(b, peer_key, 772, s->connection->log); if (offs == NGX_ERROR) { offs = ngx_rtmp_find_digest(b, peer_key, 8, s->connection->log); } if (offs == NGX_ERROR) { ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, "handshake: digest not found"); s->hs_old = 1; return NGX_OK; } ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "handshake: digest found at pos=%i", offs); b->pos += offs; b->last = b->pos + NGX_RTMP_HANDSHAKE_KEYLEN; /* 获得密文 */ s->hs_digest = ngx_palloc(s->connection->pool, NGX_RTMP_HANDSHAKE_KEYLEN); if (ngx_rtmp_make_digest(key, b, NULL, s->hs_digest, s->connection->log) != NGX_OK) { return NGX_ERROR; } return NGX_OK; }
static ngx_int_t ngx_rtmp_write_digest(ngx_buf_t *b, ngx_str_t *key, size_t base, ngx_log_t *log) { size_t n, offs; u_char *p; offs = 0; for (n = 8; n < 12; ++n) { offs += b->pos[base + n]; } offs = (offs % 728) + base + 12; p = b->pos + offs; if (ngx_rtmp_make_digest(key, b, p, p, log) != NGX_OK) { return NGX_ERROR; } return NGX_OK; }
static ngx_int_t ngx_rtmp_handshake_create_response(ngx_rtmp_session_t *s) { ngx_buf_t *b; u_char *p; ngx_str_t key; b = s->hs_buf; b->pos = b->last = b->start + 1; ngx_rtmp_fill_random_buffer(b); if (s->hs_digest) { p = b->last - NGX_RTMP_HANDSHAKE_KEYLEN; key.data = s->hs_digest; key.len = NGX_RTMP_HANDSHAKE_KEYLEN; if (ngx_rtmp_make_digest(&key, b, p, p, s->connection->log) != NGX_OK) { return NGX_ERROR; } } return NGX_OK; }