struct TIC_POP *tic_GetPOP(struct TIC_conf *tic, const char *sId) { char buf[1024]; struct TIC_POP *pop; /* Get a Tunnel */ sock_printf(tic->sock, "pop show %s\n", sId); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return NULL; } /* 201 (start of info) ? */ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1') { dolog(LOG_ERR, "Couldn't show POP %s: %s.\n", sId, buf); return NULL; } /* Allocate a new struct */ pop = (struct TIC_POP *)malloc(sizeof(*pop)); if (!pop) { dolog(LOG_ERR, "Memory problem while getting POP\n"); return NULL; } memset(pop, 0, sizeof(*pop)); /* Gather the information */ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1) { /* 202 (end of list) ? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break; parseline(buf, ": ", pop_rules, pop); } /* All went okay? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') { dolog(LOG_INFO, "Succesfully retrieved POP information for %s\n", sId); return pop; } /* Free the structure, it is broken anyway */ tic_Free_POP(pop); dolog(LOG_ERR, "POP Get for %s went wrong: %s\n", sId, buf); return NULL; }
void *irc_handle_activity(void *vfd) { int fd = *((int *)vfd); char *buff; pthread_t tid; struct async_message_handle_ctx *data; while ((buff = sock_getline(fd)) != NULL) { /* respond to PING messages */ if (!strncmp(buff, "PING", 4)) { buff[1] = 'O'; send(fd, buff, strlen(buff), 0); send(fd, "\r\n", 2, 0); } /* bot it up! */ /* now, using async processing. can't miss those pings!! */ //irc_handle_message(buff, fd); data = malloc(sizeof(struct async_message_handle_ctx)); data->buff = strdup(buff); data->fd = fd; pthread_create(&tid, NULL, irc_handle_message_async, data); pthread_detach(tid); /* console server messages */ printf("%s\n", buff); /* free buffer */ sock_freebuff(buff); } return NULL; }
/** * Login to the master * * 0 on success **/ static int nol_s_master_login() { int len; int n; char str[128]; char *p; if (strlen("AUTH slave ")+strlen(opt_vals.master_user) +strlen(opt_vals.master_password)+3 >= 128) { syslog(LOG_ERR, "buffer exceeded"); return 1; } len = sprintf(str, "AUTH slave %s %s\n", opt_vals.master_user, opt_vals.master_password); if (send(srv.master_sock, str, len, MSG_NOSIGNAL) == -1) return 1; if ((len = sock_getline(srv.master_sock, str, 127)) > 0 && atoi(str) == 100) { syslog(LOG_INFO, "logged in to master"); return 0; } else syslog(LOG_WARNING, "master returned code %d", atoi(str)); return 1; }
int #else bool #endif tic_Login(struct TIC_conf *tic, const char *username, const char *password, const char *server) { char buf[1024], sSignature[33], sChallenge[1024]; int i; #ifndef _WIN32 struct utsname uts_name; #else OSVERSIONINFO osv; OSVERSIONINFOEX osvEx; char *platform = NULL; char version[100]; #endif D(dolog(LOG_DEBUG, "Trying to connect to TIC server %s\n", server)); /* Connect to the TIC server */ tic->sock = connect_client(server, TIC_PORT, AF_INET, SOCK_STREAM); if (!tic->sock) { dolog(LOG_ERR, "Couldn't connect to the TIC server %s\n", server); return false; } /* Fetch the welcome */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] != '2') { dolog(LOG_ERR, "TIC Server is currently not available\n"); #ifdef AICCU_PATCH return TKZAiccuErrNoTicConnection; //error tic server is not available #else return false; #endif } /* Send our client identification */ #ifndef _WIN32 uname(&uts_name); sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n", TIC_VERSION, TIC_CLIENT_NAME, TIC_CLIENT_VERSION, uts_name.sysname, uts_name.release); #else osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); osvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!GetVersionEx(&osv)) { platform = "Windows"; snprintf(version, sizeof(version), "%s", "Unknown"); } else { platform = (osv.dwPlatformId == VER_PLATFORM_WIN32s) ? "Win32s" : ((osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ? "Win9x" : ((osv.dwPlatformId == VER_PLATFORM_WIN32_NT) ? "WinNT" : "Windows")); if ( osv.dwMajorVersion < 5 || !GetVersionEx((OSVERSIONINFO *)&osvEx) || osvEx.wServicePackMajor <= 0) { snprintf(version, sizeof(version), "%d.%d.%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber); } else if (osvEx.wServicePackMinor <= 0) { snprintf(version, sizeof(version), "%d.%d.%d-SP%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber, osvEx.wServicePackMajor); } else { snprintf(version, sizeof(version), "%d.%d.%d-SP%d.%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber, osvEx.wServicePackMajor, osvEx.wServicePackMinor); } } sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n", TIC_VERSION, TIC_CLIENT_NAME, TIC_CLIENT_VERSION, platform, version); #endif /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] != '2') { dolog(LOG_ERR, "Couldn't pass client information: %s.\n", &buf[4]); #ifdef AICCU_PATCH return TKZAiccuErrClientNotUpToDate; //error, client ist not up-to-date #else return false; #endif } /* Request current time */ sock_printf(tic->sock, "get unixtime\n"); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] != '2') { dolog(LOG_ERR, "Time not available? %s\n", &buf[4]); return false; } /* Check if the time is correct */ i = tic_checktime(atoi(&buf[4])); if (i != 0) { char quitmsg[100]; dolog(LOG_ERR, "The clock is off by %d seconds, use NTP to sync it!\n", i); snprintf(quitmsg, sizeof(quitmsg), "Aborting: Clock is off by %d seconds\n", i); tic_Logout(tic, quitmsg); #ifdef AICCU_PATCH return TKZAiccuErrNoTimeSync; #else return false; #endif } #ifdef AICCU_GNUTLS /* Upgrade to TLS */ sock_printf(tic->sock, "starttls\n"); /* Fetch the welcome */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] == '2') { /* Go to TLS mode */ if (!sock_gotls(tic->sock)) return false; } else { if (g_aiccu->requiretls) { dolog(LOG_ERR, "TIC Server does not support TLS and TLS is required\n"); return false; } if (g_aiccu->verbose) dolog(LOG_WARNING, "TIC Server does not support TLS but TLS is not required, continuing\n"); } #endif /* Send our username */ sock_printf(tic->sock, "username %s\n", username); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] != '2') { dolog(LOG_ERR, "Username not accepted: %s.\n", &buf[4]); #ifdef AICCU_PATCH return TKZAiccuErrInvalidUser; // error, invalid username #else return false; #endif } /* Pick a challenge */ sock_printf(tic->sock, "challenge md5\n"); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return false; } if (buf[0] != '2') { dolog(LOG_ERR, "Challenge not correct: %s.\n", &buf[4]); return false; } /* Send the response */ /* sSignature = md5(challenge.md5(password)); */ MD5String(password, sSignature, sizeof(sSignature)); snprintf(sChallenge, sizeof(sChallenge), "%s%s", &buf[4], sSignature); MD5String(sChallenge, sSignature, sizeof(sSignature)); sock_printf(tic->sock, "authenticate md5 %s\n", sSignature); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { tic_Logout(tic, NULL); return false; } if (buf[0] != '2') { tic_Logout(tic, NULL); dolog(LOG_ERR, "Response not accepted: %s.\n", &buf[4]); #ifdef AICCU_PATCH return TKZAiccuErrInvalidPwd; // error, password not correct #else return false; #endif } /* Connect OK */ return true; }
struct TIC_Tunnel *tic_GetTunnel(struct TIC_conf *tic, const char *sId) { char buf[1024]; struct TIC_Tunnel *tun; /* Get a Tunnel */ sock_printf(tic->sock, "tunnel show %s\n", sId); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return NULL; } /* 201 (start of information) ? */ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1') { dolog(LOG_ERR, "Couldn't show tunnel %s: %s.\n", sId, buf); return NULL; } /* Allocate a new struct */ tun = (struct TIC_Tunnel *)malloc(sizeof(*tun)); if (!tun) { dolog(LOG_ERR, "Memory problem while getting tunnel %s\n", sId); return NULL; } memset(tun, 0, sizeof(*tun)); /* Gather the information */ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1) { /* 202 (end of list) ? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break; parseline(buf, ": ", tunnel_rules, tun); } /* All went okay? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') { struct in6_addr ipv6_ll, ipv6_local; char ll[100]; /* Log that the fetch was succesful */ #ifndef AICCU_PATCH dolog(LOG_INFO, "Succesfully retrieved tunnel information for %s\n", sId); #endif /* * Some TUN/TAP devices don't have any * link local addresses and we want multicast and MLD to work * thus we invent one based on the following: * * ipv6_us = 2001:0db8:1234:5678: : : :0001 * ipv6_ll = fe80: : : :0db8:1234:5678:0001 * * Thus we ignore the first 16bits, take the following 48 bits * and then add the last 16bits. * * As we are not 100% sure that this LL is unique we clear that bit. */ inet_pton(AF_INET6, tun->sIPv6_Local, &ipv6_local); /* Link Local (fe80::/64) */ ipv6_ll.s6_addr[ 0] = 0xfe; ipv6_ll.s6_addr[ 1] = 0x80; ipv6_ll.s6_addr[ 2] = 0x00; ipv6_ll.s6_addr[ 3] = 0x00; ipv6_ll.s6_addr[ 4] = 0x00; ipv6_ll.s6_addr[ 5] = 0x00; ipv6_ll.s6_addr[ 6] = 0x00; ipv6_ll.s6_addr[ 7] = 0x00; ipv6_ll.s6_addr[ 8] = ipv6_local.s6_addr[ 2] & 0xfc; /* Clear the LL Unique Bit */ ipv6_ll.s6_addr[ 9] = ipv6_local.s6_addr[ 3]; ipv6_ll.s6_addr[10] = ipv6_local.s6_addr[ 4]; ipv6_ll.s6_addr[11] = ipv6_local.s6_addr[ 5]; ipv6_ll.s6_addr[12] = ipv6_local.s6_addr[ 6]; ipv6_ll.s6_addr[13] = ipv6_local.s6_addr[ 7]; ipv6_ll.s6_addr[14] = ipv6_local.s6_addr[14]; ipv6_ll.s6_addr[15] = ipv6_local.s6_addr[15]; inet_ntop(AF_INET6, &ipv6_ll, ll, sizeof(ll)); if (tun->sIPv6_LinkLocal) free(tun->sIPv6_LinkLocal); tun->sIPv6_LinkLocal = strdup(ll); if ( strcmp(tun->sType, "ayiya") == 0 || strcmp(tun->sType, "l2tp") == 0) { tun->uses_tundev = 1; #ifdef NO_IFHEAD dolog(LOG_ERR, "This build doesn't support the Tun/TAP device and thus can't instantiate tunnels of type %s, please fix your OS and recompile\n", tun->sType); tic_Free_Tunnel(tun); return NULL; #endif } else tun->uses_tundev = 0; /* Need to override the local IPv4 address? */ #ifndef AICCU_PATCH if (g_aiccu->local_ipv4_override) { dolog(LOG_INFO, "Overriding Local IPv4 address from %s to %s\n", tun->sIPv4_Local, g_aiccu->local_ipv4_override); free(tun->sIPv4_Local); tun->sIPv4_Local = strdup(g_aiccu->local_ipv4_override); } #endif return tun; } /* Free the structure, it is broken anyway */ tic_Free_Tunnel(tun); dolog(LOG_ERR, "Tunnel Get for %s went wrong: %s\n", sId, buf); return NULL; }
struct TIC_sTunnel *tic_ListTunnels(struct TIC_conf *tic) { char buf[1024], buf2[1024]; struct TIC_sTunnel *start = NULL, *last = NULL, *tun = NULL; int i; /* Request a list of Tunnels */ sock_printf(tic->sock, "tunnel list\n"); /* Fetch the answer */ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1) { return NULL; } /* 201 (start of list) ? */ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1') { dolog(LOG_ERR, "Couldn't list tunnels: %s.\n", &buf[4]); return NULL; } /* Process all the lines */ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1) { /* 202 (end of list) ? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break; i = countfields(buf); if (i != 4) { dolog(LOG_ERR, "Wrong field format when listing tunnels\n"); break; } /* Allocate a new struct */ tun = (struct TIC_sTunnel *)malloc(sizeof(*tun)); if (!tun) { dolog(LOG_ERR, "Memory problem while listing tunnels\n"); break; } memset(tun, 0, sizeof(*tun)); /* Copy the fields into the struct */ if (!copyfield(buf, 1, buf2, sizeof(buf2))) break; tun->sId = strdup(buf2); if (!copyfield(buf, 2, buf2, sizeof(buf2))) break; tun->sIPv6 = strdup(buf2); if (!copyfield(buf, 3, buf2, sizeof(buf2))) break; tun->sIPv4 = strdup(buf2); if (!copyfield(buf, 4, buf2, sizeof(buf2))) break; tun->sPOPId = strdup(buf2); /* Add it into the list */ if (last) { last->next = tun; last = tun; } else { start = last = tun; } } /* All went okay? */ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') { return start; } /* Free the structure, it was broken anyway */ tic_Free_sTunnel(start); dolog(LOG_ERR, "Tunnel list went wrong: %s\n", &buf[4]); return NULL; }
void * nol_s_client_init(void *in) { int sock = (int)in; int n; int x; char *buf; struct client *this = 0; do { if (!(buf = malloc(256))) break; /* first authorize this client connection */ if ((n = sock_getline(sock, buf, 255)) <= 0) break; if (n != 6+TOKEN_SIZE || memcmp(buf, "AUTH ", 5) != 0) break; pthread_mutex_lock(&srv.pending_lk); for (x=0; x<srv.num_pending; x++) { if (memcmp(srv.pending[x]->token, buf+5, TOKEN_SIZE) == 0) { this = srv.pending[x]; if (x != srv.num_pending-1) srv.pending[x] = srv.pending[srv.num_pending-1]; srv.num_pending --; break; } } pthread_mutex_unlock(&srv.pending_lk); free(buf); buf = 0; if (!this) { send(sock, "200 Denied\n", 11, 0); break; } /* enter main loop */ nol_s_client_main(this, sock); } while (0); if (buf) free(buf); close(sock); /* remove this client from the client list, * if it's been added to it earlier */ if (this) { /* if a session was started but not stopped, we'll mark it as interrupted * right now */ if (this->session_id) { char *q = malloc(128); int sz; sz = sprintf(q, "UPDATE `nol_session` SET state='interrupted', latest=NOW() WHERE id=%ld", this->session_id); mysql_real_query(this->mysql, q, sz); free(q); } mysql_close(this->mysql); pthread_mutex_lock(&srv.clients_lk); for (x=0; x<srv.num_clients; x++) { if (srv.clients[x] == this) { if (x != srv.num_clients-1) { srv.clients[x] = srv.clients[srv.num_clients-1]; } if (srv.num_clients == 1) { free(srv.clients); srv.clients = 0; } else if (!(srv.clients = realloc(srv.clients, (srv.num_clients-1)*sizeof(struct client*)))) abort(); srv.num_clients--; break; } } pthread_mutex_unlock(&srv.clients_lk); ev_async_send(EV_DEFAULT_ &srv.client_status); nol_s_client_free(this); ev_async_send(EV_DEFAULT_ &srv.client_status); } return 0; }