void vfree(vchar_t *var) { if (var == NULL) return; if (var->v) (void)racoon_free(var->v); (void)racoon_free(var); return; }
void lcconf_setchroot(char* chroot) { if (lcconf->chroot) { racoon_free(lcconf->chroot); lcconf->chroot = NULL; } lcconf->chroot = chroot; }
int lcconf_setpath(char* path, unsigned int path_type) { if (path_type >= LC_PATHTYPE_MAX) return -1; if (lcconf->pathinfo[path_type]) racoon_free(lcconf->pathinfo[path_type]); lcconf->pathinfo[path_type] = path; return 0; }
void flushlcconf() { int i; setdefault(); myaddr_flush(); for (i = 0; i < LC_PATHTYPE_MAX; i++) { if (lcconf->pathinfo[i]) { racoon_free(lcconf->pathinfo[i]); lcconf->pathinfo[i] = NULL; } } }
/* * schedule handler * OUT: * time to block until next event. * if no entry, NULL returned. */ struct timeval * schedular() { time_t now, delta; struct sched *p, *next = NULL; if (slept_at || woke_at) { plog(LLV_DEBUG, LOCATION, NULL, "ignoring schedular until power-mgmt event is handled.\n"); return NULL; } now = current_time(); for (p = TAILQ_FIRST(&sctree); p; p = next) { /* if the entry has been dead, remove it */ if (p->dead) goto next_schedule; /* if the time hasn't come, proceed to the next entry */ if (now < p->xtime) { next = TAILQ_NEXT(p, chain); continue; } /* mark it with dead. and call the function. */ p->dead = 1; if (p->func != NULL && !terminated) (p->func)(p->param); next_schedule: next = TAILQ_NEXT(p, chain); TAILQ_REMOVE(&sctree, p, chain); racoon_free(p); } p = TAILQ_FIRST(&sctree); if (p == NULL) return NULL; now = current_time(); delta = p->xtime - now; timeout.tv_sec = delta < 0 ? 0 : delta; timeout.tv_usec = 0; return &timeout; }
void plogdump_asl (aslmsg msg, int pri, const char *fmt, ...) { caddr_t buf; size_t buflen = 512; va_list args; char *level; switch (pri) { case ASL_LEVEL_INFO: level = ASL_STRING_INFO; break; case ASL_LEVEL_NOTICE: level = ASL_STRING_NOTICE; break; case ASL_LEVEL_WARNING: level = ASL_STRING_WARNING; break; case ASL_LEVEL_ERR: level = ASL_STRING_ERR; break; case ASL_LEVEL_DEBUG: level = ASL_STRING_DEBUG; break; default: return; } asl_set(msg, ASL_KEY_LEVEL, level); buf = racoon_malloc(buflen); if (buf) { buf[0] = '\0'; va_start(args, fmt); vsnprintf(buf, buflen, fmt, args); // asl_set(msg, ASL_KEY_MESSAGE, buf); va_end(args); racoon_free(buf); } }
void flushlcconf() { int i; setdefault(); clear_myaddr(&lcconf->myaddrs); for (i = 0; i < LC_PATHTYPE_MAX; i++) { if (lcconf->pathinfo[i]) { racoon_free(lcconf->pathinfo[i]); lcconf->pathinfo[i] = NULL; } } for (i = 0; i < LC_IDENTTYPE_MAX; i++) { if (lcconf->ident[i]) vfree(lcconf->ident[i]); lcconf->ident[i] = NULL; } }
void plogdump_func(int pri, void *data, size_t len, const char *fmt, ...) { caddr_t buf; size_t buflen; int i, j; va_list args; char fmt_buf[512]; /* * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes * + 2 newline + '\0' */ buflen = (len * 2) + (len / 4) + (len / 32) + 3; buf = racoon_malloc(buflen); i = 0; j = 0; while (j < len) { if (j % 32 == 0) buf[i++] = '\n'; else if (j % 4 == 0) buf[i++] = ' '; snprintf(&buf[i], buflen - i, "%02x", ((unsigned char *)data)[j] & 0xff); i += 2; j++; } if (buflen - i >= 2) { buf[i++] = '\n'; buf[i] = '\0'; } fmt_buf[0] = '\n'; va_start(args, fmt); vsnprintf(fmt_buf, sizeof(fmt_buf), fmt, args); va_end(args); plog(pri, "%s %s", fmt_buf, buf); racoon_free(buf); }
struct timeval * schedular() { time_t now, delta; struct sched *p, *next = NULL; now = current_time(); for (p = TAILQ_FIRST(&sctree); p; p = next) { /* if the entry has been daed, remove it */ if (p->dead) goto next_schedule; /* if the time hasn't come, proceed to the next entry */ if (now < p->xtime) { next = TAILQ_NEXT(p, chain); continue; } /* mark it with dead. and call the function. */ p->dead = 1; if (p->func != NULL) (p->func)(p->param); next_schedule: next = TAILQ_NEXT(p, chain); TAILQ_REMOVE(&sctree, p, chain); racoon_free(p); } p = TAILQ_FIRST(&sctree); if (p == NULL) return NULL; now = current_time(); delta = p->xtime - now; timeout.tv_sec = delta < 0 ? 0 : delta; timeout.tv_usec = 0; return &timeout; }
void gssapi_free_state(struct ph1handle *iph1) { struct gssapi_ph1_state *gps; OM_uint32 maj_stat, min_stat; gps = gssapi_get_state(iph1); if (gps == NULL) return; gssapi_set_state(iph1, NULL); if (gps->gss_cred != GSS_C_NO_CREDENTIAL) { maj_stat = gss_release_cred(&min_stat, &gps->gss_cred); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "releasing credentials\n"); } racoon_free(gps); }
vchar_t * vmalloc(size_t size) { vchar_t *var; if ((var = (vchar_t *)racoon_malloc(sizeof(*var))) == NULL) return NULL; var->l = size; if (size == 0) { var->v = NULL; } else { var->v = (caddr_t)racoon_calloc(1, size); if (var->v == NULL) { (void)racoon_free(var); return NULL; } } return var; }
static void setdefault() { lcconf->uid = 0; lcconf->gid = 0; { int i = 0; for (; i < LC_PATHTYPE_MAX; i++) { if (lcconf->pathinfo[i]) { racoon_free(lcconf->pathinfo[i]); lcconf->pathinfo[i] = NULL; } } } lcconf_setchroot(NULL); lcconf->port_isakmp = PORT_ISAKMP; lcconf->port_isakmp_natt = PORT_ISAKMP_NATT; lcconf->default_af = AF_INET; lcconf->pad_random = LC_DEFAULT_PAD_RANDOM; lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN; lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE; lcconf->pad_strict = LC_DEFAULT_PAD_STRICT; lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL; lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER; lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL; lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND; lcconf->secret_size = LC_DEFAULT_SECRETSIZE; lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1; lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE; lcconf->strict_address = FALSE; lcconf->complex_bundle = TRUE; /*XXX FALSE;*/ lcconf->gss_id_enc = LC_GSSENC_UTF16LE; /* Windows compatibility */ lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL; lcconf->pfkey_buffer_size = LC_DEFAULT_PFKEY_BUFFER_SIZE; }
int admin_handler() { int so2; struct sockaddr_storage from; socklen_t fromlen = sizeof(from); struct admin_com com; char *combuf = NULL; pid_t pid = -1; int len, error = -1; so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen); if (so2 < 0) { plog(LLV_ERROR, LOCATION, NULL, "failed to accept admin command: %s\n", strerror(errno)); return -1; } /* get buffer length */ while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) { if (errno == EINTR) continue; plog(LLV_ERROR, LOCATION, NULL, "failed to recv admin command: %s\n", strerror(errno)); goto end; } /* sanity check */ if (len < sizeof(com)) { plog(LLV_ERROR, LOCATION, NULL, "invalid header length of admin command\n"); goto end; } /* get buffer to receive */ if ((combuf = racoon_malloc(com.ac_len)) == 0) { plog(LLV_ERROR, LOCATION, NULL, "failed to alloc buffer for admin command\n"); goto end; } /* get real data */ while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) { if (errno == EINTR) continue; plog(LLV_ERROR, LOCATION, NULL, "failed to recv admin command: %s\n", strerror(errno)); goto end; } if (com.ac_cmd == ADMIN_RELOAD_CONF) { /* reload does not work at all! */ signal_handler(SIGHUP); goto end; } error = admin_process(so2, combuf); end: (void)close(so2); if (combuf) racoon_free(combuf); /* exit if child's process. */ if (pid == 0 && !f_foreground) exit(error); return error; }
int checklaunchd() { launch_data_t checkin_response = NULL; #ifdef LION_TEST launch_data_t checkin_request = NULL; #endif launch_data_t sockets_dict, listening_fd_array; launch_data_t listening_fd; struct sockaddr_storage fdsockaddr; socklen_t fdsockaddrlen = sizeof(fdsockaddr); int socketct; int i; int listenerct; int returnval = 0; int fd; /* check in with launchd */ #ifdef LION_TEST if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { #else if ((checkin_response = launch_socket_service_check_in()) == NULL) { #endif plog(ASL_LEVEL_ERR, "failed to launch_socket_service_check_in.\n"); goto done; } #ifdef LION_TEST if ((checkin_response = launch_msg(checkin_request)) == NULL) { plog(ASL_LEVEL_ERR, "failed to launch_msg.\n"); goto done; } #endif if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { plog(ASL_LEVEL_ERR, "launch_data_get_type error %d\n", launch_data_get_errno(checkin_response)); goto done; } if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){ plog(ASL_LEVEL_ERR, "failed to launch_data_dict_lookup.\n"); goto done; } if ( !(socketct = launch_data_dict_get_count(sockets_dict))){ plog(ASL_LEVEL_ERR, "launch_data_dict_get_count returns no socket defined.\n"); goto done; } if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){ plog(ASL_LEVEL_ERR, "failed to launch_data_dict_lookup.\n"); goto done; } listenerct = launch_data_array_get_count(listening_fd_array); for (i = 0; i < listenerct; i++) { listening_fd = launch_data_array_get_index(listening_fd_array, i); fd = launch_data_get_fd( listening_fd ); if ( getsockname( fd , (struct sockaddr *)&fdsockaddr, &fdsockaddrlen)){ continue; } /* Is this the VPN control socket? */ if ( fdsockaddr.ss_family == AF_UNIX && (!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path)))) { plog(ASL_LEVEL_INFO, "found launchd socket.\n"); returnval = fd; break; } } // TODO: check if we have any leaked fd if ( listenerct == i){ plog(ASL_LEVEL_ERR, "failed to find launchd socket\n"); returnval = 0; } done: if (checkin_response) launch_data_free(checkin_response); return(returnval); } void vpncontrol_handler(void *unused) { struct sockaddr_storage from; socklen_t fromlen = sizeof(from); int sock; struct vpnctl_socket_elem *sock_elem; sock_elem = racoon_malloc(sizeof(struct vpnctl_socket_elem)); if (sock_elem == NULL) { plog(ASL_LEVEL_ERR, "memory error: %s\n", strerror(errno)); return; //%%%%%% terminate } LIST_INIT(&sock_elem->bound_addresses); sock_elem->sock = accept(lcconf->sock_vpncontrol, (struct sockaddr *)&from, &fromlen); if (sock_elem->sock < 0) { plog(ASL_LEVEL_ERR, "failed to accept vpn_control command: %s\n", strerror(errno)); racoon_free(sock_elem); return; //%%%%% terminate } LIST_INSERT_HEAD(&lcconf->vpnctl_comm_socks, sock_elem, chain); sock_elem->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, sock_elem->sock, 0, dispatch_get_main_queue()); if (sock_elem->source == NULL) { plog(ASL_LEVEL_ERR, "could not create comm socket source."); racoon_free(sock_elem); return; //%%%%% terminate } dispatch_source_set_event_handler(sock_elem->source, ^{ vpncontrol_comm_handler(sock_elem); }); sock = sock_elem->sock; dispatch_source_t the_source = sock_elem->source; dispatch_source_set_cancel_handler(sock_elem->source, ^{ close(sock); dispatch_release(the_source); /* Release the source on cancel */ });
/* * handling to receive Notification payload */ static int isakmp_info_recv_n(struct ph1handle *iph1, rc_vchar_t *msg) { struct isakmp_pl_n *n = NULL; unsigned int type; rc_vchar_t *pbuf; struct isakmp_parse_t *pa, *pap; char *spi; if (!(pbuf = isakmp_parse(msg))) return -1; pa = (struct isakmp_parse_t *)pbuf->v; for (pap = pa; pap->type; pap++) { switch (pap->type) { case ISAKMP_NPTYPE_HASH: /* do something here */ break; case ISAKMP_NPTYPE_NONCE: /* send to ack */ break; case ISAKMP_NPTYPE_N: n = (struct isakmp_pl_n *)pap->ptr; break; default: rc_vfree(pbuf); return -1; } } rc_vfree(pbuf); if (!n) return -1; type = get_uint16(&n->type); switch (type) { case ISAKMP_NTYPE_CONNECTED: case ISAKMP_NTYPE_RESPONDER_LIFETIME: case ISAKMP_NTYPE_REPLAY_STATUS: /* do something */ break; case ISAKMP_NTYPE_INITIAL_CONTACT: info_recv_initialcontact(iph1); break; case ISAKMP_NTYPE_R_U_THERE: isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n, ((struct isakmp *)msg->v)->msgid); break; case ISAKMP_NTYPE_R_U_THERE_ACK: isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n, ((struct isakmp *)msg->v)->msgid); break; default: { uint32_t msgid = ((struct isakmp *)msg->v)->msgid; struct ph2handle *iph2; /* XXX there is a potential of dos attack. */ if (msgid == 0) { /* delete ph1 */ plog(PLOG_PROTOERR, PLOGLOC, 0, "delete phase1 handle.\n"); return -1; } else { iph2 = getph2bymsgid(iph1, msgid); if (iph2 == NULL) { plog(PLOG_PROTOERR, PLOGLOC, 0, "unknown notify message, " "no phase2 handle found.\n"); } else { /* delete ph2 */ unbindph12(iph2); remph2(iph2); delph2(iph2); } } } break; } /* get spi and allocate */ if (get_uint16(&n->h.len) < sizeof(*n) + n->spi_size) { plog(PLOG_PROTOERR, PLOGLOC, 0, "invalid spi_size in notification payload.\n"); return -1; } spi = val2str((char *)(n + 1), n->spi_size); plog(PLOG_DEBUG, PLOGLOC, 0, "notification message %d:%s, " "doi=%d proto_id=%d spi=%s(size=%d).\n", type, s_isakmp_notify_msg(type), get_uint32(&n->doi), n->proto_id, spi, n->spi_size); racoon_free(spi); return(0); }
/* get local address against the destination. */ struct sockaddr * getlocaladdr(struct sockaddr *remote, struct sockaddr *hint, int lport) { struct sockaddr *local; socklen_t local_len = sizeof(struct sockaddr_storage); int s; /* for dummy connection */ extern struct rcf_interface *rcf_interface_head; if (hint && hint->sa_family == remote->sa_family) { local = rcs_sadup(hint); goto got; } /* allocate buffer */ if ((local = racoon_calloc(1, local_len)) == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get address buffer.\n"); goto err; } /* get real interface received packet */ if ((s = socket(remote->sa_family, SOCK_DGRAM, 0)) < 0) { plog(PLOG_INTERR, PLOGLOC, NULL, "socket (%s)\n", strerror(errno)); goto err; } if ((rcf_interface_head->application_bypass != RCT_BOOL_OFF) && (setsockopt_bypass(s, remote->sa_family) < 0)) { close(s); goto err; } if (connect(s, remote, SOCKADDR_LEN(remote)) < 0) { plog(PLOG_INTERR, PLOGLOC, NULL, "connect (%s)\n", strerror(errno)); close(s); goto err; } if (getsockname(s, local, &local_len) < 0) { plog(PLOG_INTERR, PLOGLOC, NULL, "getsockname (%s)\n", strerror(errno)); close(s); goto err; } close(s); got: /* specify local port */ local->sa_family = remote->sa_family; switch (remote->sa_family) { case AF_INET: ((struct sockaddr_in *)local)->sin_port = htons(lport); break; #ifdef INET6 case AF_INET6: ((struct sockaddr_in6 *)local)->sin6_port = htons(lport); break; #endif default: plog(PLOG_INTERR, PLOGLOC, NULL, "getlocaladdr: unexpected address family (%d)\n", remote->sa_family); goto err; } return local; err: if (local != NULL) racoon_free(local); return NULL; }