X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/5ad62c80ee213c7ff7aff6f0f67109c880e39c70..80d71456cf13400f1bb97be03a29f9b085fd3309:/authd/providers/opm.c diff --git a/authd/providers/opm.c b/authd/providers/opm.c index ca3cfd2b..54ae6c2d 100644 --- a/authd/providers/opm.c +++ b/authd/providers/opm.c @@ -26,6 +26,8 @@ #include "notice.h" #include "provider.h" +#include // TCP_NODELAY + #define SELF_PID (opm_provider.id) #define OPM_READSIZE 128 @@ -236,7 +238,6 @@ accept_opm(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, voi } break; } -#ifdef RB_IPV6 case AF_INET6: { struct sockaddr_in6 *s = (struct sockaddr_in6 *)&localaddr, *c = (struct sockaddr_in6 *)&auth->c_addr; @@ -248,7 +249,6 @@ accept_opm(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, voi } break; } -#endif default: warn_opers(L_CRIT, "OPM: unknown address type in listen function"); exit(EX_PROVIDER_ERROR); @@ -283,7 +283,6 @@ opm_connected(rb_fde_t *F, int error, void *data) goto end; break; -#ifdef RB_IPV6 case AF_INET6: if(!proxy->ipv6) /* Welp, too bad */ @@ -294,7 +293,6 @@ opm_connected(rb_fde_t *F, int error, void *data) goto end; break; -#endif default: goto end; } @@ -303,15 +301,13 @@ opm_connected(rb_fde_t *F, int error, void *data) end: rb_close(scan->F); - rb_dlinkFindDelete(scan, &lookup->scans); + rb_dlinkDelete(&scan->node, &lookup->scans); rb_free(scan); } static void socks4_connected(struct opm_scan *scan) { - struct auth_client *auth = scan->auth; - struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); uint8_t sendbuf[9]; /* Size we're building */ uint8_t *c = sendbuf; @@ -333,13 +329,9 @@ static void socks5_connected(struct opm_scan *scan) { struct auth_client *auth = scan->auth; - struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); uint8_t sendbuf[25]; /* Size we're building */ uint8_t *c = sendbuf; - auth = scan->auth; - lookup = get_provider_data(auth, SELF_PID); - /* Build the version header and socks request * version header (3 bytes): version, number of auth methods, auth type (0 for none) * connect req (3 bytes): version, command (1 = connect), reserved (0) @@ -353,13 +345,11 @@ socks5_connected(struct opm_scan *scan) memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_addr.s_addr), 4); c += 4; /* Address */ memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_port), 2); c += 2; /* Port */ break; -#ifdef RB_IPV6 case AF_INET6: *(c++) = '\x04'; /* Address type (4 = IPv6) */ memcpy(c, ((struct sockaddr_in6 *)&scan->listener->addr)->sin6_addr.s6_addr, 16); c += 16; /* Address */ memcpy(c, &(((struct sockaddr_in6 *)&scan->listener->addr)->sin6_port), 2); c += 2; /* Port */ break; -#endif default: return; } @@ -376,10 +366,7 @@ socks5_connected(struct opm_scan *scan) static void http_connect_connected(struct opm_scan *scan) { - struct auth_client *auth = scan->auth; - struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); char sendbuf[128]; /* A bit bigger than we need but better safe than sorry */ - char *c = sendbuf; /* Simple enough to build */ snprintf(sendbuf, sizeof(sendbuf), "CONNECT %s:%hu HTTP/1.0\r\n\r\n", scan->listener->ip, scan->listener->port); @@ -409,7 +396,6 @@ establish_connection(struct auth_client *auth, struct opm_proxy *proxy) lrb_assert(lookup != NULL); -#ifdef RB_IPV6 if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6) { if(proxy->proto == PROTO_SOCKS4) @@ -421,7 +407,6 @@ establish_connection(struct auth_client *auth, struct opm_proxy *proxy) listener = &listeners[LISTEN_IPV6]; } else -#endif listener = &listeners[LISTEN_IPV4]; if(listener->F == NULL) @@ -474,7 +459,7 @@ create_listener(const char *ip, uint16_t port) rb_fde_t *F; int opt = 1; - if(!rb_inet_pton_sock(ip, (struct sockaddr *)&addr)) + if(!rb_inet_pton_sock(ip, &addr)) { warn_opers(L_CRIT, "OPM: got a bad listener: %s:%hu", ip, port); exit(EX_PROVIDER_ERROR); @@ -482,7 +467,6 @@ create_listener(const char *ip, uint16_t port) SET_SS_PORT(&addr, htons(port)); -#ifdef RB_IPV6 if(GET_SS_FAMILY(&addr) == AF_INET6) { struct sockaddr_in6 *a1, *a2; @@ -501,7 +485,6 @@ create_listener(const char *ip, uint16_t port) } } else -#endif { struct sockaddr_in *a1, *a2; @@ -563,6 +546,7 @@ create_listener(const char *ip, uint16_t port) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { opm_cancel(auth); + /* auth is now invalid as we have no reference */ } /* Copy data */ @@ -603,44 +587,40 @@ static void opm_initiate(struct auth_client *auth, uint32_t provider) { struct opm_lookup *lookup = get_provider_data(auth, SELF_PID); - uint32_t rdns_pid, ident_pid; lrb_assert(provider != SELF_PID); lrb_assert(!is_provider_done(auth, SELF_PID)); lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0); - if(lookup == NULL || lookup->in_progress) + if (lookup == NULL || lookup->in_progress) { /* Nothing to do */ return; - else if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && - (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) - /* Don't start until ident and rdns are finished (or not loaded) */ - return; - else + } else if (run_after_provider(auth, "rdns") && run_after_provider(auth,"ident")) { + /* Start scanning if ident and rdns are finished, or not loaded. */ opm_scan(auth); + } } static bool opm_start(struct auth_client *auth) { - uint32_t rdns_pid, ident_pid; - lrb_assert(get_provider_data(auth, SELF_PID) == NULL); - if(!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0) + if (!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0) { /* Nothing to do... */ + provider_done(auth, SELF_PID); return true; + } + + auth_client_ref(auth); set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct opm_lookup))); - if((!get_provider_id("rdns", &rdns_pid) || is_provider_done(auth, rdns_pid)) && - (!get_provider_id("ident", &ident_pid) || is_provider_done(auth, ident_pid))) - { - /* Don't start until ident and rdns are finished (or not loaded) */ + if (run_after_provider(auth, "rdns") && run_after_provider(auth, "ident")) { + /* Start scanning if ident and rdns are finished, or not loaded. */ opm_scan(auth); } - set_provider_running(auth, SELF_PID); return true; } @@ -668,6 +648,8 @@ opm_cancel(struct auth_client *auth) set_provider_data(auth, SELF_PID, NULL); set_provider_timeout_absolute(auth, SELF_PID, 0); provider_done(auth, SELF_PID); + + auth_client_unref(auth); } } @@ -681,6 +663,7 @@ opm_destroy(void) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { opm_cancel(auth); + /* auth is now invalid as we have no reference */ } } @@ -723,6 +706,7 @@ set_opm_enabled(const char *key __unused, int parc __unused, const char **parv) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { opm_cancel(auth); + /* auth is now invalid as we have no reference */ } } } @@ -805,7 +789,8 @@ create_opm_scanner(const char *key __unused, int parc __unused, const char **par if(find_proxy_scanner(proxy->proto, proxy->port) != NULL) { warn_opers(L_CRIT, "OPM: got a duplicate scanner: %s (port %hu)", parv[0], proxy->port); - exit(EX_PROVIDER_ERROR); + rb_free(proxy); + return; } rb_dlinkAdd(proxy, &proxy->node, &proxy_scanners); @@ -847,6 +832,8 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par if(lookup == NULL) continue; + auth_client_ref(auth); + RB_DLINK_FOREACH(ptr, lookup->scans.head) { struct opm_scan *scan = ptr->data; @@ -854,7 +841,7 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par if(scan->proxy->port == proxy->port && scan->proxy->proto == proxy->proto) { /* Match */ - rb_dlinkFindDelete(scan, &lookup->scans); + rb_dlinkDelete(&scan->node, &lookup->scans); rb_free(scan); if(rb_dlink_list_length(&lookup->scans) == 0) @@ -863,9 +850,11 @@ delete_opm_scanner(const char *key __unused, int parc __unused, const char **par break; } } + + auth_client_unref(auth); } - rb_dlinkFindDelete(proxy, &proxy_scanners); + rb_dlinkDelete(&proxy->node, &proxy_scanners); rb_free(proxy); if(rb_dlink_list_length(&proxy_scanners) == 0) @@ -888,6 +877,7 @@ delete_opm_scanner_all(const char *key __unused, int parc __unused, const char * RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) { opm_cancel(auth); + /* auth is now invalid as we have no reference */ } opm_enable = false; @@ -899,10 +889,8 @@ delete_opm_listener_all(const char *key __unused, int parc __unused, const char if(listeners[LISTEN_IPV4].F != NULL) rb_close(listeners[LISTEN_IPV4].F); -#ifdef RB_IPV6 if(listeners[LISTEN_IPV6].F != NULL) rb_close(listeners[LISTEN_IPV6].F); -#endif memset(&listeners, 0, sizeof(listeners)); }