4 Commits

Author SHA1 Message Date
staylightblow8
da2830c31e msg: fix some problem
Type: fix

Signed-off-by: staylightblow8 <liudf0716@gmail.com>
2023-11-04 11:51:43 +08:00
staylightblow8
aaeaa2203a instaloader: change working directory to instaloader
Signed-off-by: staylightblow8 <liudf0716@gmail.com>
2023-10-28 20:11:03 +08:00
staylightblow8
c895f221da plugin: add instaloader local redir service
Signed-off-by: staylightblow8 <liudf0716@gmail.com>
2023-10-28 12:06:34 +08:00
staylightblow8
be51233c04 plugin: add instaloder plugin to download instagram
Signed-off-by: staylightblow8 <liudf0716@gmail.com>
2023-10-22 21:43:52 +08:00
9 changed files with 508 additions and 145 deletions

View File

@@ -16,10 +16,15 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: prepare build environment
run: |
sudo apt-get update
sudo apt-get install -y libjson-c-dev libevent-dev libssl-dev
- name: compile xfrpc
run: |
mkdir build
cd build
cmake -D THIRDPARTY_STATIC_BUILD=ON ..
cmake ..
make

View File

@@ -83,7 +83,8 @@ set(src_xfrpc
)
set(src_xfrpc_plugins
plugins/telnetd.c)
plugins/telnetd.c
plugins/instaloader.c)
set(libs
ssl

View File

@@ -48,7 +48,6 @@
static const char *valid_types[] = {
"tcp",
"udp",
"mstsc",
"socks5",
"http",
"https",
@@ -239,11 +238,6 @@ validate_proxy(struct proxy_service *ps)
debug(LOG_ERR, "Proxy [%s] error: remote_port not found", ps->proxy_name);
return 0;
}
} else if (strcmp(ps->proxy_type, "mstsc") == 0) {
if (ps->remote_port == 0 || ps->local_port == 0) {
debug(LOG_ERR, "Proxy [%s] error: remote_port or local_port not found", ps->proxy_name);
return 0;
}
} else if (strcmp(ps->proxy_type, "tcp") == 0 || strcmp(ps->proxy_type, "udp") == 0) {
if (ps->remote_port == 0 || ps->local_port == 0 || ps->local_ip == NULL) {
debug(LOG_ERR, "Proxy [%s] error: remote_port or local_port or local_ip not found", ps->proxy_name);
@@ -318,13 +312,29 @@ process_plugin_conf(struct proxy_service *ps)
if (strcmp(ps->plugin, "telnetd") == 0) {
if (ps->local_port == 0)
ps->local_port = 23;
ps->local_port = XFRPC_PLUGIN_TELNETD_PORT;
if (ps->local_ip == NULL)
ps->local_ip = strdup("127.0.0.1");
if (ps->plugin_user !=NULL && ps->plugin_pwd != NULL) {
add_user_and_set_password (ps->plugin_user, ps->plugin_pwd);
}
} else if (strcmp(ps->plugin, "instaloader") == 0) {
if (ps->local_port == 0)
ps->local_port = XFRPC_PLUGIN_INSTALOADER_PORT;
if (ps->remote_port == 0)
ps->remote_port = XFRPC_PLUGIN_INSTALOADER_ROMOTE_PORT;
if (ps->local_ip == NULL)
ps->local_ip = strdup("127.0.0.1");
} else if (strcmp(ps->plugin, "instaloader_client") == 0) {
if (ps->local_port == 0)
ps->local_port = XFRPC_PLUGIN_INSTALOADER_PORT;
if (ps->remote_port == 0)
ps->remote_port == XFRPC_PLUGIN_INSTALOADER_ROMOTE_PORT;
if (ps->local_ip == NULL)
ps->local_ip = strdup("0.0.0.0");
} else {
debug(LOG_INFO, "plugin %s is not supportted", ps->plugin);
}
}
@@ -414,11 +424,6 @@ proxy_service_handler(void *user, const char *sect, const char *nm, const char *
ps->remote_port = DEFAULT_SOCKS5_PORT;
if (ps->group == NULL)
ps->group = strdup("chatgptd");
} else if (ps->proxy_type && strcmp(ps->proxy_type, "mstsc") == 0) {
// if ps->proxy_type is mstsc, and ps->local_port is not set, set it to 3389
// start a thread to listen on local_port, and forward data to remote_port
if (ps->local_port == 0)
ps->local_port = DEFAULT_MSTSC_PORT;
} else if (ps->proxy_type && strcmp(ps->proxy_type, "tcp") == 0) {
process_plugin_conf(ps);
}

View File

@@ -31,6 +31,10 @@
#define DEFAULT_MSTSC_PORT 3389
#define DEFAULT_SOCKS5_PORT 1980
#define XFRPC_PLUGIN_TELNETD_PORT 23
#define XFRPC_PLUGIN_INSTALOADER_PORT 10000
#define XFRPC_PLUGIN_INSTALOADER_ROMOTE_PORT 10001
#define FTP_RMT_CTL_PROXY_SUFFIX "_ftp_remote_ctl_proxy"
//client common config

334
msg.c
View File

@@ -20,8 +20,8 @@
\********************************************************************/
/** @file msg.c
@brief xfrpc client msg related
@author Copyright (C) 2016 Dengfeng Liu <liu_df@qq.com>
@brief xfrpc client msg related
@author Copyright (C) 2016 Dengfeng Liu <liu_df@qq.com>
*/
#include <string.h>
@@ -41,44 +41,45 @@
#include "client.h"
#include "utils.h"
#define JSON_MARSHAL_TYPE(jobj,key,jtype,item) \
json_object_object_add(jobj, key, json_object_new_##jtype((item)));
#define JSON_MARSHAL_TYPE(jobj, key, jtype, item) \
json_object_object_add(jobj, key, json_object_new_##jtype((item)));
#define SAFE_JSON_STRING(str_target) \
str_target?str_target:"\0"
str_target ? str_target : "\0"
const char msg_types[] = {TypeLogin,
TypeLoginResp,
TypeNewProxy,
TypeNewProxyResp,
TypeNewWorkConn,
TypeReqWorkConn,
TypeStartWorkConn,
TypePing,
TypePong,
TypeUDPPacket};
const char msg_types[] = {TypeLogin,
TypeLoginResp,
TypeNewProxy,
TypeNewProxyResp,
TypeNewWorkConn,
TypeReqWorkConn,
TypeStartWorkConn,
TypePing,
TypePong,
TypeUDPPacket};
char *
calc_md5(const char *data, int datalen)
{
unsigned char digest[16] = {0};
char *out = (char*)malloc(33);
char *out = (char *)malloc(33);
assert(out);
MD5_CTX md5;
MD5_Init(&md5);
MD5_Update(&md5, data, datalen);
MD5_Final(digest, &md5);
for (int n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 3, "%02x", (unsigned int)digest[n]);
}
return out;
for (int n = 0; n < 16; ++n)
{
snprintf(&(out[n * 2]), 3, "%02x", (unsigned int)digest[n]);
}
return out;
}
static void
static void
fill_custom_domains(struct json_object *j_ctl_req, const char *custom_domains)
{
struct json_object *jarray_cdomains = json_object_new_array();
@@ -86,7 +87,8 @@ fill_custom_domains(struct json_object *j_ctl_req, const char *custom_domains)
char *tmp = strdup(custom_domains);
assert(tmp);
char *tok = tmp, *end = tmp;
while (tok != NULL) {
while (tok != NULL)
{
strsep(&end, ",");
int dname_len = strlen(tok) + 1;
@@ -99,15 +101,16 @@ fill_custom_domains(struct json_object *j_ctl_req, const char *custom_domains)
tok = end;
}
SAFE_FREE(tmp);
json_object_object_add(j_ctl_req, "custom_domains", jarray_cdomains);
}
struct work_conn *
new_work_conn() {
new_work_conn()
{
struct work_conn *work_c = calloc(1, sizeof(struct work_conn));
assert(work_c);
if (work_c)
if (work_c)
work_c->run_id = NULL;
return work_c;
@@ -122,28 +125,31 @@ get_auth_key(const char *token, long int *timestamp)
snprintf(seed, 128, "%s%ld", token, *timestamp);
else
snprintf(seed, 128, "%ld", *timestamp);
return calc_md5(seed, strlen(seed));
}
size_t
size_t
login_request_marshal(char **msg)
{
size_t nret = 0;
struct json_object *j_login_req = json_object_new_object();
if (j_login_req == NULL)
return 0;
struct login *lg = get_common_login_config();
if (!lg)
{
json_object_put(j_login_req);
return 0;
}
SAFE_FREE(lg->privilege_key);
struct common_conf *cf = get_common_config();
char *auth_key = get_auth_key(cf->auth_token, &lg->timestamp);
lg->privilege_key = strdup(auth_key);
assert(lg->privilege_key);
JSON_MARSHAL_TYPE(j_login_req, "version", string, lg->version);
JSON_MARSHAL_TYPE(j_login_req, "hostname", string, SAFE_JSON_STRING(lg->hostname));
JSON_MARSHAL_TYPE(j_login_req, "os", string, lg->os);
@@ -155,10 +161,11 @@ login_request_marshal(char **msg)
JSON_MARSHAL_TYPE(j_login_req, "run_id", string, SAFE_JSON_STRING(lg->run_id));
JSON_MARSHAL_TYPE(j_login_req, "pool_count", int, lg->pool_count);
json_object_object_add(j_login_req, "metas", NULL);
const char *tmp = NULL;
tmp = json_object_to_json_string(j_login_req);
if (tmp && strlen(tmp) > 0) {
if (tmp && strlen(tmp) > 0)
{
nret = strlen(tmp);
*msg = strdup(tmp);
assert(*msg);
@@ -168,54 +175,66 @@ login_request_marshal(char **msg)
return nret;
}
int
new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
int new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
{
const char *tmp = NULL;
int nret = 0;
int nret = 0;
char *path = NULL;
char *delimiter = ",";
char *save = NULL;
struct json_object *j_np_req = json_object_new_object();
if ( ! j_np_req)
if (!j_np_req)
return 0;
JSON_MARSHAL_TYPE(j_np_req, "proxy_name", string, np_req->proxy_name);
// if proxy_type is socks5, set the proxy_type to tcp
if (strcmp(np_req->proxy_type, "socks5") == 0 || strcmp(np_req->proxy_type, "mstsc") == 0) {
if (strcmp(np_req->proxy_type, "socks5") == 0 || strcmp(np_req->proxy_type, "mstsc") == 0)
{
JSON_MARSHAL_TYPE(j_np_req, "proxy_type", string, "tcp");
} else {
}
else
{
JSON_MARSHAL_TYPE(j_np_req, "proxy_type", string, np_req->proxy_type);
}
JSON_MARSHAL_TYPE(j_np_req, "use_encryption", boolean, np_req->use_encryption);
JSON_MARSHAL_TYPE(j_np_req, "use_compression", boolean, np_req->use_compression);
// if proxy_type is tcp, http, https and socks5, set group and group_key to j_np_req
if (strcmp(np_req->proxy_type, "tcp") == 0 ||
strcmp(np_req->proxy_type, "http") == 0 ||
strcmp(np_req->proxy_type, "https") == 0 ||
strcmp(np_req->proxy_type, "socks5") == 0) {
if (np_req->group) {
if (strcmp(np_req->proxy_type, "tcp") == 0 ||
strcmp(np_req->proxy_type, "http") == 0 ||
strcmp(np_req->proxy_type, "https") == 0 ||
strcmp(np_req->proxy_type, "socks5") == 0)
{
if (np_req->group)
{
JSON_MARSHAL_TYPE(j_np_req, "group", string, np_req->group);
}
if (np_req->group_key) {
if (np_req->group_key)
{
JSON_MARSHAL_TYPE(j_np_req, "group_key", string, np_req->group_key);
}
}
if (is_ftp_proxy(np_req)) {
if (is_ftp_proxy(np_req))
{
JSON_MARSHAL_TYPE(j_np_req, "remote_data_port", int, np_req->remote_data_port);
}
if (np_req->custom_domains) {
if (np_req->custom_domains)
{
fill_custom_domains(j_np_req, np_req->custom_domains);
json_object_object_add(j_np_req, "remote_port", NULL);
} else {
}
else
{
json_object_object_add(j_np_req, "custom_domains", NULL);
if (np_req->remote_port != -1) {
if (np_req->remote_port != -1)
{
JSON_MARSHAL_TYPE(j_np_req, "remote_port", int, np_req->remote_port);
} else {
}
else
{
json_object_object_add(j_np_req, "remote_port", NULL);
}
}
@@ -223,23 +242,28 @@ new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
JSON_MARSHAL_TYPE(j_np_req, "subdomain", string, SAFE_JSON_STRING(np_req->subdomain));
json_object *j_location_array = json_object_new_array();
if (np_req->locations) {
if (np_req->locations)
{
json_object_object_add(j_np_req, "locations", j_location_array);
path = strtok_r(np_req->locations, delimiter, &save);
while (path) {
while (path)
{
json_object_array_add(j_location_array, json_object_new_string(path));
path = strtok_r(NULL, delimiter, &save);
}
} else {
}
else
{
json_object_object_add(j_np_req, "locations", NULL);
}
JSON_MARSHAL_TYPE(j_np_req, "host_header_rewrite", string, SAFE_JSON_STRING(np_req->host_header_rewrite));
JSON_MARSHAL_TYPE(j_np_req, "http_user", string, SAFE_JSON_STRING(np_req->http_user));
JSON_MARSHAL_TYPE(j_np_req, "http_pwd", string, SAFE_JSON_STRING(np_req->http_pwd));
tmp = json_object_to_json_string(j_np_req);
if (tmp && strlen(tmp) > 0) {
if (tmp && strlen(tmp) > 0)
{
nret = strlen(tmp);
*msg = strdup(tmp);
assert(*msg);
@@ -249,18 +273,18 @@ new_proxy_service_marshal(const struct proxy_service *np_req, char **msg)
return nret;
}
int
new_work_conn_marshal(const struct work_conn *work_c, char **msg)
int new_work_conn_marshal(const struct work_conn *work_c, char **msg)
{
const char *tmp = NULL;
int nret = 0;
struct json_object *j_new_work_conn = json_object_new_object();
if (! j_new_work_conn)
if (!j_new_work_conn)
return 0;
JSON_MARSHAL_TYPE(j_new_work_conn, "run_id", string, SAFE_JSON_STRING(work_c->run_id));
tmp = json_object_to_json_string(j_new_work_conn);
if (tmp && strlen(tmp) > 0) {
if (tmp && strlen(tmp) > 0)
{
nret = strlen(tmp);
*msg = strdup(tmp);
assert(*msg);
@@ -278,7 +302,7 @@ new_proxy_resp_unmarshal(const char *jres)
struct json_object *j_np_res = json_tokener_parse(jres);
if (j_np_res == NULL)
return NULL;
struct new_proxy_response *npr = calloc(1, sizeof(struct new_proxy_response));
assert(npr);
@@ -287,24 +311,43 @@ new_proxy_resp_unmarshal(const char *jres)
npr->run_id = strdup(json_object_get_string(npr_run_id));
struct json_object *npr_proxy_remote_addr = NULL;
if (! json_object_object_get_ex(j_np_res, "remote_addr", &npr_proxy_remote_addr))
if (!json_object_object_get_ex(j_np_res, "remote_addr", &npr_proxy_remote_addr))
{
free(npr->run_id);
free(npr);
npr = NULL;
goto END_ERROR;
}
const char *remote_addr = json_object_get_string(npr_proxy_remote_addr);
char *port = strrchr(remote_addr, ':');
if (port) {
if (port)
{
port++;
npr->remote_port = atoi(port);
}
struct json_object *npr_proxy_name = NULL;
if (! json_object_object_get_ex(j_np_res, "proxy_name", &npr_proxy_name))
if (!json_object_object_get_ex(j_np_res, "proxy_name", &npr_proxy_name))
{
free(npr->run_id);
free(npr);
npr = NULL;
goto END_ERROR;
}
npr->proxy_name = strdup(json_object_get_string(npr_proxy_name));
assert(npr->proxy_name);
struct json_object *npr_error = NULL;
if(! json_object_object_get_ex(j_np_res, "error", &npr_error))
if (!json_object_object_get_ex(j_np_res, "error", &npr_error))
{
free(npr->run_id);
free(npr->proxy_name);
free(npr);
npr = NULL;
goto END_ERROR;
}
npr->error = strdup(json_object_get_string(npr_error));
assert(npr->error);
@@ -320,25 +363,43 @@ login_resp_unmarshal(const char *jres)
struct json_object *j_lg_res = json_tokener_parse(jres);
if (j_lg_res == NULL)
return NULL;
struct login_resp *lr = calloc(1, sizeof(struct login_resp));
assert(lr);
struct json_object *l_version = NULL;
if (! json_object_object_get_ex(j_lg_res, "version", &l_version))
if (!json_object_object_get_ex(j_lg_res, "version", &l_version))
{
free(lr);
lr = NULL;
goto END_ERROR;
}
lr->version = strdup(json_object_get_string(l_version));
assert(lr->version);
struct json_object *l_run_id = NULL;
if (! json_object_object_get_ex(j_lg_res, "run_id", &l_run_id))
if (!json_object_object_get_ex(j_lg_res, "run_id", &l_run_id))
{
free(lr->version);
free(lr);
lr = NULL;
goto END_ERROR;
}
lr->run_id = strdup(json_object_get_string(l_run_id));
assert(lr->run_id);
struct json_object *l_error = NULL;
if(! json_object_object_get_ex(j_lg_res, "error", &l_error))
if (!json_object_object_get_ex(j_lg_res, "error", &l_error))
{
free(lr->version);
free(lr->run_id);
free(lr);
lr = NULL;
goto END_ERROR;
}
lr->error = strdup(json_object_get_string(l_error));
assert(lr->error);
@@ -358,8 +419,12 @@ start_work_conn_resp_unmarshal(const char *resp_msg)
assert(sr);
struct json_object *pn = NULL;
if(! json_object_object_get_ex(j_start_w_res, "proxy_name", &pn))
if (!json_object_object_get_ex(j_start_w_res, "proxy_name", &pn))
{
free(sr);
sr = NULL;
goto START_W_C_R_END;
}
sr->proxy_name = strdup(json_object_get_string(pn));
assert(sr->proxy_name);
@@ -377,22 +442,35 @@ control_response_unmarshal(const char *jres)
return NULL;
struct control_response *ctl_res = calloc(sizeof(struct control_response), 1);
assert(ctl_res);
struct json_object *jtype = NULL;
if(! json_object_object_get_ex(j_ctl_res, "type", &jtype))
if (!json_object_object_get_ex(j_ctl_res, "type", &jtype))
{
free(ctl_res);
ctl_res = NULL;
goto END_ERROR;
ctl_res->type = json_object_get_int(jtype);
struct json_object *jcode = NULL;
if(! json_object_object_get_ex(j_ctl_res, "code", &jcode))
goto END_ERROR;
ctl_res->code = json_object_get_int(jcode);
struct json_object *jmsg = NULL;
if(json_object_object_get_ex(j_ctl_res, "msg", &jmsg)) {
ctl_res->msg = strdup(json_object_get_string(jmsg));
assert(ctl_res->msg);
}
ctl_res->type = json_object_get_int(jtype);
struct json_object *jcode = NULL;
if (!json_object_object_get_ex(j_ctl_res, "code", &jcode))
{
free(ctl_res);
ctl_res = NULL;
goto END_ERROR;
}
ctl_res->code = json_object_get_int(jcode);
struct json_object *jmsg = NULL;
if (!json_object_object_get_ex(j_ctl_res, "msg", &jmsg))
{
free(ctl_res);
ctl_res = NULL;
goto END_ERROR;
}
ctl_res->msg = strdup(json_object_get_string(jmsg));
assert(ctl_res->msg);
END_ERROR:
json_object_put(j_ctl_res);
@@ -404,29 +482,11 @@ control_response_free(struct control_response *res)
{
if (!res)
return;
SAFE_FREE(res->msg);
SAFE_FREE(res);
}
int
msg_type_valid_check(char msg_type)
{
int i = 0;
for(i = 0; i<(sizeof(msg_types) / sizeof(*msg_types)); i++) {
if (msg_types[i] == msg_type)
return 1;
}
return 0;
}
char *
get_msg_type(uint8_t type)
{
return NULL;
}
// marshal udp packet msg
int
new_udp_packet_marshal(const struct udp_packet *udp, char **msg)
@@ -439,7 +499,8 @@ new_udp_packet_marshal(const struct udp_packet *udp, char **msg)
assert(content);
json_object_object_add(j_udp, "c", content);
if (udp->laddr) {
if (udp->laddr)
{
// laddr is a struct, parse it to json object and add to j_udp
struct json_object *j_laddr = json_object_new_object();
assert(j_laddr);
@@ -453,14 +514,17 @@ new_udp_packet_marshal(const struct udp_packet *udp, char **msg)
json_object *j_laddr_zone = json_object_new_string("");
assert(j_laddr_zone);
json_object_object_add(j_laddr, "Zone", j_laddr_zone);
} else {
}
else
{
// laddr is NULL, add null to j_udp
struct json_object *j_laddr = json_object_new_object();
assert(j_laddr);
json_object_object_add(j_udp, "l", j_laddr);
}
if (udp->raddr) {
if (udp->raddr)
{
// raddr is a struct, parse it to json object and add to j_udp
struct json_object *j_raddr = json_object_new_object();
assert(j_raddr);
@@ -474,11 +538,13 @@ new_udp_packet_marshal(const struct udp_packet *udp, char **msg)
json_object *j_raddr_zone = json_object_new_string("");
assert(j_raddr_zone);
json_object_object_add(j_raddr, "Zone", j_raddr_zone);
} else {
}
else
{
// raddr is NULL, add null to j_udp
struct json_object *j_raddr = json_object_new_object();
assert(j_raddr);
json_object_object_add(j_udp, "r", j_raddr);
json_object_object_add(j_udp, "r", j_raddr);
}
// convert json to string msg
@@ -494,7 +560,7 @@ udp_packet_free(struct udp_packet *udp)
{
if (!udp)
return;
SAFE_FREE(udp->content);
SAFE_FREE(udp->laddr->addr);
SAFE_FREE(udp->laddr->zone);
@@ -508,7 +574,7 @@ udp_packet_free(struct udp_packet *udp)
// unmarshal udp packet msg
struct udp_packet *
udp_packet_unmarshal (const char *msg)
udp_packet_unmarshal(const char *msg)
{
struct json_object *j_udp = json_tokener_parse(msg);
if (j_udp == NULL)
@@ -517,23 +583,37 @@ udp_packet_unmarshal (const char *msg)
assert(udp);
struct json_object *j_content = NULL;
if(! json_object_object_get_ex(j_udp, "c", &j_content))
if (!json_object_object_get_ex(j_udp, "c", &j_content))
{
goto END_ERROR;
}
udp->content = strdup(json_object_get_string(j_content));
assert(udp->content);
struct json_object *j_laddr = NULL;
if(! json_object_object_get_ex(j_udp, "l", &j_laddr))
if (!json_object_object_get_ex(j_udp, "l", &j_laddr))
{
goto END_ERROR;
}
struct json_object *j_laddr_ip = NULL;
if(! json_object_object_get_ex(j_laddr, "IP", &j_laddr_ip))
if (!json_object_object_get_ex(j_laddr, "IP", &j_laddr_ip))
{
goto END_ERROR;
}
struct json_object *j_laddr_port = NULL;
if(! json_object_object_get_ex(j_laddr, "Port", &j_laddr_port))
if (!json_object_object_get_ex(j_laddr, "Port", &j_laddr_port))
{
goto END_ERROR;
}
struct json_object *j_laddr_zone = NULL;
if(! json_object_object_get_ex(j_laddr, "Zone", &j_laddr_zone))
if (!json_object_object_get_ex(j_laddr, "Zone", &j_laddr_zone))
{
goto END_ERROR;
}
udp->laddr = calloc(sizeof(struct udp_addr), 1);
assert(udp->laddr);
udp->laddr->addr = strdup(json_object_get_string(j_laddr_ip));
@@ -543,17 +623,29 @@ udp_packet_unmarshal (const char *msg)
assert(udp->laddr->zone);
struct json_object *j_raddr = NULL;
if(! json_object_object_get_ex(j_udp, "r", &j_raddr))
if (!json_object_object_get_ex(j_udp, "r", &j_raddr))
{
goto END_ERROR;
}
struct json_object *j_raddr_ip = NULL;
if(! json_object_object_get_ex(j_raddr, "IP", &j_raddr_ip))
if (!json_object_object_get_ex(j_raddr, "IP", &j_raddr_ip))
{
goto END_ERROR;
}
struct json_object *j_raddr_port = NULL;
if(! json_object_object_get_ex(j_raddr, "Port", &j_raddr_port))
if (!json_object_object_get_ex(j_raddr, "Port", &j_raddr_port))
{
goto END_ERROR;
}
struct json_object *j_raddr_zone = NULL;
if(! json_object_object_get_ex(j_raddr, "Zone", &j_raddr_zone))
if (!json_object_object_get_ex(j_raddr, "Zone", &j_raddr_zone))
{
goto END_ERROR;
}
udp->raddr = calloc(sizeof(struct udp_addr), 1);
assert(udp->raddr);
udp->raddr->addr = strdup(json_object_get_string(j_raddr_ip));

3
msg.h
View File

@@ -110,7 +110,6 @@ struct start_work_conn_resp {
int new_udp_packet_marshal(const struct udp_packet *udp, char **msg);
int new_proxy_service_marshal(const struct proxy_service *np_req, char **msg);
int msg_type_valid_check(char msg_type);
char *calc_md5(const char *data, int datalen);
char *get_auth_key(const char *token, long int *timestamp);
size_t login_request_marshal(char **msg);
@@ -132,6 +131,4 @@ void udp_packet_free(struct udp_packet *udp);
void control_response_free(struct control_response *res);
char *get_msg_type(uint8_t type);
#endif //_MSG_H_

247
plugins/instaloader.c Normal file
View File

@@ -0,0 +1,247 @@
#include <json-c/json.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <event2/http.h>
#include "../common.h"
#include "../debug.h"
#include "../config.h"
#include "instaloader.h"
struct instaloader_param {
char action[10];
char profile[100];
};
// define instaloader worker function
static void *
instaloader_worker(void *param)
{
struct instaloader_param *p = (struct instaloader_param *)param;
debug(LOG_DEBUG, "instaloader: action: %s, profile: %s\n", p->action, p->profile);
char cmd[512] = {0};
// create directory instaloader and change current directory to it
snprintf(cmd, sizeof(cmd), "mkdir -p instaloader && cd instaloader");
debug(LOG_DEBUG, "instaloader: cmd: %s\n", cmd);
system(cmd);
if (strcmp(p->action, "download") == 0) {
// download profile
snprintf(cmd, sizeof(cmd), "instaloader --no-captions --no-metadata-json --no-compress-json --no-pictures %s", p->profile);
debug(LOG_DEBUG, "instaloader: cmd: %s\n", cmd);
// use popen to execute cmd and get its output
FILE *fp = popen(cmd, "r");
if (fp == NULL) {
debug(LOG_ERR, "instaloader: popen failed\n");
free(param);
return NULL;
}
char buf[512] = {0};
while (fgets(buf, sizeof(buf), fp) != NULL) {
debug(LOG_DEBUG, "instaloader: %s", buf);
memset(buf, 0, sizeof(buf));
}
pclose(fp);
} else if (strcmp(p->action, "stop") == 0) {
// stop instaloader
debug(LOG_DEBUG, "instaloader: exit the program \n");
exit(0);
} else {
debug(LOG_ERR, "instaloader: unknown action: %s\n", p->action);
}
// free param
free(param);
return 0;
}
static int
parse_instaloader_command(char *json_data, struct instaloader_param *param)
{
// parse json data with json-c to param
json_object *jobj = json_tokener_parse(json_data);
if (jobj == NULL) {
debug(LOG_ERR, "instaloader: json_tokener_parse failed\n");
return -1;
}
// get action
json_object *jaction = NULL;
if (!json_object_object_get_ex(jobj, "action", &jaction)) {
debug(LOG_ERR, "instaloader: json_object_object_get_ex failed\n");
json_object_put(jobj);
return -1;
}
strcpy(param->action, json_object_get_string(jaction));
if (strcmp(param->action, "stop") == 0) {
json_object_put(jobj);
return 0;
}
// get profile
json_object *jprofile = NULL;
if (!json_object_object_get_ex(jobj, "profile", &jprofile)) {
debug(LOG_ERR, "instaloader: json_object_object_get_ex failed\n");
json_object_put(jobj);
return -1;
}
strcpy(param->profile, json_object_get_string(jprofile));
// free json object
json_object_put(jobj);
return 0;
}
static void
instaloader_response(struct evhttp_request *req, char *result)
{
struct evbuffer *resp = evbuffer_new();
evbuffer_add_printf(resp, "{\"status\": \"%s\"}", result);
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "application/json");
evhttp_send_reply(req, HTTP_OK, "OK", resp);
}
// define instaloader read callback function
static void
instaloader_read_cb(struct evhttp_request *req, void *args)
{
#define BUFF_LEN 4096
// read data from bufferevent
char data[BUFF_LEN] = {0};
struct evbuffer *input = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(input);
assert(len < BUFF_LEN);
if (len >= BUFF_LEN) {
debug(LOG_ERR, "instaloader: data length is too long\n");
instaloader_response(req, "data length is too long");
return;
}
debug(LOG_DEBUG, "instaloader: data: %s\n", data);
// parse http post and get its json data
evbuffer_copyout(input, data, len);
debug(LOG_DEBUG, "instaloader: data: %s\n", data);
struct instaloader_param *param = (struct instaloader_param *)malloc(sizeof(struct instaloader_param));
assert(param != NULL);
memset(param, 0, sizeof(struct instaloader_param));
int nret = parse_instaloader_command(data, param);
if (nret != 0) {
debug(LOG_ERR, "instaloader: parse_command failed\n");
free(param);
instaloader_response(req, "failed to parse command");
return;
}
// create a thread
pthread_t thread;
// create a thread attribute
pthread_attr_t attr;
// initialize thread attribute
pthread_attr_init(&attr);
// set thread attribute to detach
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// create a thread
pthread_create(&thread, &attr, instaloader_worker, param);
// destroy thread attribute
pthread_attr_destroy(&attr);
instaloader_response(req, "ok");
}
// define instaloader http post callback function
static void
http_post_cb(struct evhttp_request *req, void *arg)
{
// check http request method
if (evhttp_request_get_command(req) != EVHTTP_REQ_POST) {
debug(LOG_ERR, "instaloader: http request method is not POST\n");
evhttp_send_error(req, HTTP_BADMETHOD, "Method Not Allowed");
return;
}
// Check the HTTP request content type
const char *content_type = evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type");
if (content_type == NULL || strcmp(content_type, "application/json") != 0) {
debug(LOG_ERR, "instaloader: http request content type is not application/json\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
// get json data from http request
instaloader_read_cb(req, arg);
}
// define instaloader service
static void *
instaloader_service(void *local_port)
{
uint16_t port = *(uint16_t *)local_port;
free(local_port);
// Initialize libevent
struct event_base *base = event_base_new();
if (!base) {
debug(LOG_ERR, "instaloader: Failed to initialize libevent\n");
return NULL;
}
// Create a new HTTP server
struct evhttp *http = evhttp_new(base);
if (!http) {
debug(LOG_ERR, "Failed to create HTTP server\n");
return NULL;
}
if (evhttp_bind_socket(http, "0.0.0.0", port) != 0) {
debug(LOG_ERR, "Failed to bind HTTP server to port %d\n", port);
return NULL;
}
debug(LOG_DEBUG, "instaloader: start instaloader service on port %d\n", port);
// Set up a callback function for handling HTTP requests
evhttp_set_cb(http, "/", http_post_cb, NULL);
// Start the event loop
event_base_dispatch(base);
// Clean up
evhttp_free(http);
event_base_free(base);
return NULL;
}
int
start_instaloader_service(uint16_t local_port)
{
uint16_t *p = (uint16_t *)malloc(sizeof(uint16_t));
assert(p != NULL);
*p = local_port;
// create a thread
pthread_t thread;
// create a thread attribute
pthread_attr_t attr;
// initialize thread attribute
pthread_attr_init(&attr);
// set thread attribute to detach
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// create a thread
pthread_create(&thread, &attr, instaloader_service, (void *)p);
// destroy thread attribute
pthread_attr_destroy(&attr);
return 0;
}

6
plugins/instaloader.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _INSTALOADER_H_
#define _INSTALOADER_H_
int start_instaloader_service(uint16_t local_port);
#endif

18
xfrpc.c
View File

@@ -49,6 +49,7 @@
#include "config.h"
#include "plugins/telnetd.h"
#include "plugins/instaloader.h"
static void start_xfrpc_local_service()
{
@@ -57,12 +58,17 @@ static void start_xfrpc_local_service()
struct proxy_service *ps, *ps_tmp;
struct proxy_service *all_ps = get_all_proxy_services();
HASH_ITER(hh, all_ps, ps, ps_tmp) {
if (ps->proxy_type && strcmp(ps->proxy_type, "mstsc") == 0) {
// start tcp_redir for it
start_tcp_redir_service(ps);
}
if (ps->plugin && strcmp(ps->plugin, "telnetd") == 0) {
simple_telnetd_start(ps->local_port);
if (ps->plugin) {
if (strcmp(ps->plugin, "telnetd") == 0) {
simple_telnetd_start(ps->local_port);
} else if (strcmp(ps->plugin, "instaloader") == 0) {
// start instaloader service
start_instaloader_service(ps->local_port);
} else if (strcmp(ps->plugin, "instaloader_redir") == 0) {
start_tcp_redir_service(ps);
} else {
debug(LOG_ERR, "start_xfrpc_local_service: unknown plugin %s\n", ps->plugin);
}
}
}