mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2026-01-30 06:00:34 +03:00
Fix old kernel versions builders
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
FROM ubuntu:14.04
|
|
||||||
|
|
||||||
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
|
|
||||||
|
|
||||||
RUN wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.0.101.tar.xz -O kernel.tar.xz
|
|
||||||
RUN tar -xf kernel.tar.xz
|
|
||||||
RUN rm -f kernel.tar.xz
|
|
||||||
RUN /bin/bash -c "mv linux-* linux"
|
|
||||||
|
|
||||||
WORKDIR /linux
|
|
||||||
RUN make defconfig
|
|
||||||
RUN make -j$(nproc)
|
|
||||||
1
.github/workflows/test.yml
vendored
1
.github/workflows/test.yml
vendored
@@ -106,7 +106,6 @@ jobs:
|
|||||||
- 4.19.322
|
- 4.19.322
|
||||||
- 4.4.302
|
- 4.4.302
|
||||||
- 3.10.108
|
- 3.10.108
|
||||||
- 3.0.101
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|||||||
2
Kbuild
2
Kbuild
@@ -1,3 +1,3 @@
|
|||||||
obj-m := kyoutubeUnblock.o
|
obj-m := kyoutubeUnblock.o
|
||||||
kyoutubeUnblock-objs := src/kytunblock.o src/mangle.o src/quic.o src/quic_crypto.o src/utils.o src/kargs.o src/tls.o src/getopt.o src/inet_ntop.o src/args.o deps/cyclone/aes.o deps/cyclone/cpu_endian.o deps/cyclone/ecb.o deps/cyclone/gcm.o deps/cyclone/hkdf.o deps/cyclone/hmac.o deps/cyclone/sha256.o
|
kyoutubeUnblock-objs := src/kytunblock.o src/mangle.o src/quic.o src/quic_crypto.o src/utils.o src/tls.o src/getopt.o src/inet_ntop.o src/args.o deps/cyclone/aes.o deps/cyclone/cpu_endian.o deps/cyclone/ecb.o deps/cyclone/gcm.o deps/cyclone/hkdf.o deps/cyclone/hmac.o deps/cyclone/sha256.o
|
||||||
ccflags-y := -std=gnu99 -DKERNEL_SPACE -Wno-error -Wno-declaration-after-statement -I$(src)/src -I$(src)/deps/cyclone/include
|
ccflags-y := -std=gnu99 -DKERNEL_SPACE -Wno-error -Wno-declaration-after-statement -I$(src)/src -I$(src)/deps/cyclone/include
|
||||||
|
|||||||
105
src/kargs.c
105
src/kargs.c
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
youtubeUnblock - https://github.com/Waujito/youtubeUnblock
|
|
||||||
|
|
||||||
Copyright (C) 2024-2025 Vadim Vetrov <vetrovvd@gmail.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include <linux/moduleparam.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "args.h"
|
|
||||||
#include "logging.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defined in kyoutubeUnblock.c
|
|
||||||
*/
|
|
||||||
extern struct spinlock hot_config_spinlock;
|
|
||||||
extern atomic_t hot_config_counter;
|
|
||||||
extern atomic_t hot_config_rep;
|
|
||||||
extern struct mutex config_free_mutex;
|
|
||||||
|
|
||||||
#define MAX_ARGC 1024
|
|
||||||
static char *argv[MAX_ARGC];
|
|
||||||
|
|
||||||
static int params_set(const char *cval, const struct kernel_param *kp) {
|
|
||||||
int ret;
|
|
||||||
ret = mutex_trylock(&config_free_mutex);
|
|
||||||
if (ret == 0)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
|
|
||||||
int cv_len = strlen(cval);
|
|
||||||
if (cv_len >= 1 && cval[cv_len - 1] == '\n') {
|
|
||||||
cv_len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ytb_prefix = "youtubeUnblock ";
|
|
||||||
int ytbp_len = strlen(ytb_prefix);
|
|
||||||
int len = cv_len + ytbp_len;
|
|
||||||
|
|
||||||
char *val = kmalloc(len + 1, GFP_KERNEL); // 1 for null-terminator
|
|
||||||
strncpy(val, ytb_prefix, ytbp_len);
|
|
||||||
strncpy(val + ytbp_len, cval, cv_len);
|
|
||||||
val[len] = '\0';
|
|
||||||
|
|
||||||
int argc = 0;
|
|
||||||
argv[argc++] = val;
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
if (val[i] == ' ') {
|
|
||||||
val[i] = '\0';
|
|
||||||
|
|
||||||
// safe because of null-terminator
|
|
||||||
if (val[i + 1] != ' ' && val[i + 1] != '\0') {
|
|
||||||
argv[argc++] = val + i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&hot_config_spinlock);
|
|
||||||
// lock netfilter youtubeUnblock
|
|
||||||
atomic_set(&hot_config_rep, 1);
|
|
||||||
spin_unlock(&hot_config_spinlock);
|
|
||||||
|
|
||||||
// lock config hot replacement process until all
|
|
||||||
// netfilter callbacks keep running
|
|
||||||
while (atomic_read(&hot_config_counter) > 0) {}
|
|
||||||
|
|
||||||
ret = yparse_args(argc, argv);
|
|
||||||
|
|
||||||
spin_lock(&hot_config_spinlock);
|
|
||||||
// relaunch youtubeUnblock
|
|
||||||
atomic_set(&hot_config_rep, 0);
|
|
||||||
spin_unlock(&hot_config_spinlock);
|
|
||||||
|
|
||||||
kfree(val);
|
|
||||||
|
|
||||||
mutex_unlock(&config_free_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int params_get(char *buffer, const struct kernel_param *kp) {
|
|
||||||
size_t len = print_config(buffer, 4000);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct kernel_param_ops params_ops = {
|
|
||||||
.set = params_set,
|
|
||||||
.get = params_get,
|
|
||||||
};
|
|
||||||
|
|
||||||
module_param_cb(parameters, ¶ms_ops, NULL, 0664);
|
|
||||||
103
src/kytunblock.c
103
src/kytunblock.c
@@ -63,12 +63,85 @@ MODULE_DESCRIPTION("Linux kernel module for youtubeUnblock");
|
|||||||
static struct socket *rawsocket;
|
static struct socket *rawsocket;
|
||||||
static struct socket *raw6socket;
|
static struct socket *raw6socket;
|
||||||
|
|
||||||
DEFINE_SPINLOCK(hot_config_spinlock);
|
static DEFINE_SPINLOCK(hot_config_spinlock);
|
||||||
DEFINE_MUTEX(config_free_mutex);
|
static DEFINE_MUTEX(config_free_mutex);
|
||||||
atomic_t hot_config_counter = ATOMIC_INIT(0);
|
static atomic_t hot_config_counter = ATOMIC_INIT(0);
|
||||||
// boolean flag for hot config replacement
|
// boolean flag for hot config replacement
|
||||||
// if 1, youtubeUnblock should stop processing
|
// if 1, youtubeUnblock should stop processing
|
||||||
atomic_t hot_config_rep = ATOMIC_INIT(0);
|
static atomic_t hot_config_rep = ATOMIC_INIT(0);
|
||||||
|
|
||||||
|
#define MAX_ARGC 1024
|
||||||
|
static char *argv[MAX_ARGC];
|
||||||
|
|
||||||
|
static int params_set(const char *cval, const struct kernel_param *kp) {
|
||||||
|
int ret;
|
||||||
|
ret = mutex_trylock(&config_free_mutex);
|
||||||
|
if (ret == 0)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
|
||||||
|
int cv_len = strlen(cval);
|
||||||
|
if (cv_len >= 1 && cval[cv_len - 1] == '\n') {
|
||||||
|
cv_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ytb_prefix = "youtubeUnblock ";
|
||||||
|
int ytbp_len = strlen(ytb_prefix);
|
||||||
|
int len = cv_len + ytbp_len;
|
||||||
|
|
||||||
|
char *val = kmalloc(len + 1, GFP_KERNEL); // 1 for null-terminator
|
||||||
|
strncpy(val, ytb_prefix, ytbp_len);
|
||||||
|
strncpy(val + ytbp_len, cval, cv_len);
|
||||||
|
val[len] = '\0';
|
||||||
|
|
||||||
|
int argc = 0;
|
||||||
|
argv[argc++] = val;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (val[i] == ' ') {
|
||||||
|
val[i] = '\0';
|
||||||
|
|
||||||
|
// safe because of null-terminator
|
||||||
|
if (val[i + 1] != ' ' && val[i + 1] != '\0') {
|
||||||
|
argv[argc++] = val + i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&hot_config_spinlock);
|
||||||
|
// lock netfilter youtubeUnblock
|
||||||
|
atomic_set(&hot_config_rep, 1);
|
||||||
|
spin_unlock(&hot_config_spinlock);
|
||||||
|
|
||||||
|
// lock config hot replacement process until all
|
||||||
|
// netfilter callbacks keep running
|
||||||
|
while (atomic_read(&hot_config_counter) > 0) {}
|
||||||
|
|
||||||
|
ret = yparse_args(argc, argv);
|
||||||
|
|
||||||
|
spin_lock(&hot_config_spinlock);
|
||||||
|
// relaunch youtubeUnblock
|
||||||
|
atomic_set(&hot_config_rep, 0);
|
||||||
|
spin_unlock(&hot_config_spinlock);
|
||||||
|
|
||||||
|
kfree(val);
|
||||||
|
|
||||||
|
mutex_unlock(&config_free_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int params_get(char *buffer, const struct kernel_param *kp) {
|
||||||
|
size_t len = print_config(buffer, 4000);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct kernel_param_ops params_ops = {
|
||||||
|
.set = params_set,
|
||||||
|
.get = params_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_param_cb(parameters, ¶ms_ops, NULL, 0664);
|
||||||
|
|
||||||
|
|
||||||
static int open_raw_socket(void) {
|
static int open_raw_socket(void) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -475,16 +548,22 @@ static struct nf_hook_ops ykb_hook_ops[] = {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
static const size_t ykb_hooks_sz = sizeof(ykb_hook_ops) / sizeof(struct nf_hook_ops);
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||||
static int ykb_net_init(struct net *net)
|
static int ykb_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
return nf_register_net_hooks(net, ykb_hook_ops, sizeof(ykb_hook_ops));
|
int ret;
|
||||||
|
ret = nf_register_net_hooks(net, ykb_hook_ops, ykb_hooks_sz);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ykb_net_exit(struct net *net)
|
static void ykb_net_exit(struct net *net)
|
||||||
{
|
{
|
||||||
nf_unregister_net_hooks(net, ykb_hook_ops, sizeof(ykb_hook_ops));
|
nf_unregister_net_hooks(net, ykb_hook_ops, ykb_hooks_sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations ykb_pernet_ops = {
|
static struct pernet_operations ykb_pernet_ops = {
|
||||||
@@ -504,12 +583,14 @@ static int __init ykb_init(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = init_config(&config);
|
ret = init_config(&config);
|
||||||
if (ret < 0) goto err;
|
if (ret < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ret = open_raw_socket();
|
ret = open_raw_socket();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
lgerror(ret, "ipv4 rawsocket initialization failed!");
|
lgerror(ret, "ipv4 rawsocket initialization failed!");
|
||||||
goto err;
|
goto err_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
@@ -523,7 +604,7 @@ static int __init ykb_init(void) {
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||||
ret = register_pernet_subsys(&ykb_pernet_ops);
|
ret = register_pernet_subsys(&ykb_pernet_ops);
|
||||||
#else
|
#else
|
||||||
ret = nf_register_hooks(ykb_hook_ops, sizeof(ykb_hook_ops));
|
ret = nf_register_hooks(ykb_hook_ops, ykb_hooks_sz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -539,6 +620,8 @@ err_close_sock:
|
|||||||
#endif
|
#endif
|
||||||
err_close4_sock:
|
err_close4_sock:
|
||||||
close_raw_socket();
|
close_raw_socket();
|
||||||
|
err_config:
|
||||||
|
free_config(config);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -558,7 +641,7 @@ static void __exit ykb_destroy(void) {
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||||
unregister_pernet_subsys(&ykb_pernet_ops);
|
unregister_pernet_subsys(&ykb_pernet_ops);
|
||||||
#else
|
#else
|
||||||
nf_unregister_hooks(ykb_hook_ops, sizeof(ykb_hook_ops));
|
nf_unregister_hooks(ykb_hook_ops, ykb_hooks_sz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ int process_packet(const struct packet_data *pd) {
|
|||||||
lgtrace_write();
|
lgtrace_write();
|
||||||
|
|
||||||
lgtrace_wr("Transport payload: [ ");
|
lgtrace_wr("Transport payload: [ ");
|
||||||
for (int i = 0; i < min(16, transport_payload_len); i++) {
|
for (int i = 0; i < min((int)16, (int)transport_payload_len); i++) {
|
||||||
lgtrace_wr("%02x ", transport_payload[i]);
|
lgtrace_wr("%02x ", transport_payload[i]);
|
||||||
}
|
}
|
||||||
lgtrace_wr("]");
|
lgtrace_wr("]");
|
||||||
@@ -224,7 +224,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
|
|
||||||
size_t fake_len = section->fake_sni_pkt_sz;
|
size_t fake_len = section->fake_sni_pkt_sz;
|
||||||
if (section->synfake_len)
|
if (section->synfake_len)
|
||||||
fake_len = min(section->synfake_len, fake_len);
|
fake_len = min((int)section->synfake_len, (int)fake_len);
|
||||||
|
|
||||||
|
|
||||||
size_t payload_len = iph_len + tcph_len + fake_len;
|
size_t payload_len = iph_len + tcph_len + fake_len;
|
||||||
@@ -279,7 +279,6 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
|
|||||||
|
|
||||||
if (vrd.target_sni) {
|
if (vrd.target_sni) {
|
||||||
lgdebug("Target SNI detected: %.*s", vrd.sni_len, vrd.sni_ptr);
|
lgdebug("Target SNI detected: %.*s", vrd.sni_len, vrd.sni_ptr);
|
||||||
size_t sni_offset = vrd.sni_ptr - data;
|
|
||||||
size_t target_sni_offset = vrd.target_sni_ptr - data;
|
size_t target_sni_offset = vrd.target_sni_ptr - data;
|
||||||
|
|
||||||
size_t payload_len = raw_payload_len;
|
size_t payload_len = raw_payload_len;
|
||||||
|
|||||||
@@ -366,8 +366,6 @@ int parse_quic_decrypted(
|
|||||||
const uint8_t *curptr = decrypted_message;
|
const uint8_t *curptr = decrypted_message;
|
||||||
ssize_t curptr_len = decrypted_message_len;
|
ssize_t curptr_len = decrypted_message_len;
|
||||||
ssize_t fret;
|
ssize_t fret;
|
||||||
int ret;
|
|
||||||
struct tls_verdict tlsv = {0};
|
|
||||||
struct quic_frame_crypto fr_cr;
|
struct quic_frame_crypto fr_cr;
|
||||||
|
|
||||||
uint8_t *crypto_message = calloc(AVAILABLE_MTU, 1);
|
uint8_t *crypto_message = calloc(AVAILABLE_MTU, 1);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int bruteforce_analyze_sni_str(
|
|||||||
|
|
||||||
for (struct domains_list *sne = section->sni_domains; sne != NULL;
|
for (struct domains_list *sne = section->sni_domains; sne != NULL;
|
||||||
sne = sne->next) {
|
sne = sne->next) {
|
||||||
max_domain_len = max(sne->domain_len, max_domain_len);
|
max_domain_len = max((int)sne->domain_len, max_domain_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t buf_size = max_domain_len + dlen + 1;
|
size_t buf_size = max_domain_len + dlen + 1;
|
||||||
@@ -274,7 +274,7 @@ struct tls_verdict analyze_tls_data(
|
|||||||
if (tls_vmajor != 0x03) break;
|
if (tls_vmajor != 0x03) break;
|
||||||
message_ptr++;
|
message_ptr++;
|
||||||
|
|
||||||
uint8_t tls_vminor = *message_ptr;
|
// uint8_t tls_vminor = *message_ptr;
|
||||||
message_ptr++;
|
message_ptr++;
|
||||||
|
|
||||||
uint16_t message_length = ntohs(*(const uint16_t *)message_ptr);
|
uint16_t message_length = ntohs(*(const uint16_t *)message_ptr);
|
||||||
@@ -283,7 +283,7 @@ struct tls_verdict analyze_tls_data(
|
|||||||
|
|
||||||
const uint8_t *tls_message_data = message_ptr;
|
const uint8_t *tls_message_data = message_ptr;
|
||||||
// Since real length may be truncated use minimum of two
|
// Since real length may be truncated use minimum of two
|
||||||
size_t tls_message_length = min(message_length, data_end - message_ptr);
|
size_t tls_message_length = min((int)message_length, (int)(data_end - message_ptr));
|
||||||
|
|
||||||
if (tls_content_type != TLS_CONTENT_TYPE_HANDSHAKE)
|
if (tls_content_type != TLS_CONTENT_TYPE_HANDSHAKE)
|
||||||
goto nextMessage;
|
goto nextMessage;
|
||||||
|
|||||||
Reference in New Issue
Block a user