/* * responder is kicked by initiator. Check whether we already have * a channel (in _any_ state) to the initiator. */ int isadb_is_outstanding_init_req (isakmp_hdr *hdr, struct sockaddr_in *src) { unsigned char cookie[COOKIE_LEN]; SA *node; #if 0 if(dblist == NULL) return(0); gen_cookie(src, cookie); for(node = dblist; node != NULL; node = node->next){ if((bcmp((char *)node->my_cookie, cookie, COOKIE_LEN) == 0) && (node->condition != SA_COND_DEAD)){ switch(node->state){ /* * if the initiator went down and forget that we had this * existing ISAKP SA we should delete it and start again */ case OAK_QM_AUTH_AWAIT: case OAK_QM_IDLE: isadb_delete_entry(node); return(0); default: return(1); } } } #endif return(0); }
SA *isadb_get_entry_by_addr (struct sockaddr_in *from) { unsigned char hash[COOKIE_LEN]; SA *node; gen_cookie(from, hash); for(node = dblist; node; node = node->next){ if(!bcmp((char *)hash, (char *)node->my_cookie, COOKIE_LEN)){ return(node); } } return(NULL); }
static int get_kamcmd_list(int s) { struct binrpc_cmd cmd; int cookie; unsigned char reply_buf[MAX_REPLY_SIZE]; unsigned char* msg_body; struct binrpc_parse_ctx in_pkt; int ret; cmd.method="system.listMethods"; cmd.argc=0; cookie=gen_cookie(); if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){ if (ret==-1) goto error_send; else goto binrpc_err; } /* read reply */ memset(&in_pkt, 0, sizeof(in_pkt)); if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt, &msg_body))<0){ goto error; } switch(in_pkt.type){ case BINRPC_FAULT: if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){ goto error; } break; case BINRPC_REPL: rpc_no=100; /* default cmd list */ if ((rpc_array=parse_reply_body(&rpc_no, &in_pkt, msg_body, in_pkt.tlen))==0) goto error; break; default: fprintf(stderr, "ERROR: not a reply\n"); goto error; } return 0; binrpc_err: error_send: error: return -1; }
int binrpc_send_command_ex( struct binrpc_handle* handle, struct binrpc_pkt *pkt, struct binrpc_response_handle *resp_handle) { int cookie; cookie = gen_cookie(); if (send_binrpc_cmd(handle, pkt, cookie) < 0) { return FATAL_ERROR; } /* read reply */ memset(&resp_handle->in_pkt, 0, sizeof(resp_handle->in_pkt)); if (get_reply(handle, cookie, resp_handle) < 0) { return FATAL_ERROR; } /* normal exit */ return 0; }
/* * for the initiator. He's kicked by the kernel. Check whether * we're already working on this kernel request. */ int isadb_is_outstanding_kernel_req (struct sockaddr_in *dst, unsigned short type) { unsigned char cookie[COOKIE_LEN]; SA *node; if(dblist == NULL) return(0); gen_cookie(dst, cookie); for(node = dblist; node != NULL; node = node->next){ /* * check whether we're communicating with this guy already and * whether the SA is not flagged for deletion, if so, are we already * going to negotiate for this type? */ if((bcmp((char *)node->my_cookie, cookie, COOKIE_LEN) == 0) && (node->condition != SA_COND_DEAD)){ switch(type){ case PROTO_IPSEC_AH: if(node->outstanding_sa & PROTO_IPSEC_AH_MASK) return(-1); node->outstanding_sa |= PROTO_IPSEC_AH_MASK; break; case PROTO_IPSEC_ESP: if(node->outstanding_sa & PROTO_IPSEC_ESP_MASK) return(-1); node->outstanding_sa |= PROTO_IPSEC_ESP_MASK; break; default: return(-1); } return(1); } } return(0); }
static int run_binrpc_cmd(int s, struct binrpc_cmd * cmd, char* fmt) { int cookie; unsigned char reply_buf[MAX_REPLY_SIZE]; unsigned char* msg_body; struct binrpc_parse_ctx in_pkt; int ret; cookie=gen_cookie(); if ((ret=send_binrpc_cmd(s, cmd, cookie))<0){ if (ret==-1) goto error_send; else goto binrpc_err; } /* read reply */ memset(&in_pkt, 0, sizeof(in_pkt)); if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt, &msg_body))<0){ switch(ret){ case -1: goto error_read; case -2: goto error_parse; case -3: goto error_cookie; case -4: goto error_toobig; } goto error; } switch(in_pkt.type){ case BINRPC_FAULT: if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){ goto error; } break; case BINRPC_REPL: if (print_body(&in_pkt, msg_body, in_pkt.tlen, fmt)<0){ goto error; } break; default: fprintf(stderr, "ERROR: not a reply\n"); goto error; } if (verbose) printf(".\n"); /* normal exit */ return 0; binrpc_err: fprintf(stderr, "ERROR while building the packet: %s\n", binrpc_error(ret)); goto error; error_parse: fprintf(stderr, "ERROR while parsing the reply: %s\n", binrpc_error(binrpc_errno)); goto error; error_cookie: fprintf(stderr, "ERROR: cookie does not match\n"); goto error; error_toobig: fprintf(stderr, "ERROR: reply too big\n"); goto error; error_send: fprintf(stderr, "ERROR: send packet failed: %s (%d)\n", strerror(errno), errno); goto error; error_read: fprintf(stderr, "ERROR: read reply failed: %s (%d)\n", strerror(errno), errno); goto error; error: return -1; }
/* retrieve the counters names and group list */ static int get_counters_list(int s) { struct binrpc_cmd cmd; int cookie; unsigned char reply_buf[MAX_REPLY_SIZE]; unsigned char* msg_body; struct binrpc_parse_ctx in_pkt; struct cnt_var_grp* grp; struct cnt_var_grp* last_grp; str grp_name; str var_name; int r; int ret; cmd.method="cnt.grps_list"; cmd.argc=0; if (!is_rpc_cmd(cmd.method)) goto error; cookie=gen_cookie(); if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){ if (ret==-1) goto error_send; else goto binrpc_err; } /* read reply */ memset(&in_pkt, 0, sizeof(in_pkt)); if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt, &msg_body))<0){ goto error; } switch(in_pkt.type){ case BINRPC_FAULT: if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){ goto error; } break; case BINRPC_REPL: cnt_grps_no=20; /* default counter list */ if ((cnt_grps_array=parse_reply_body(&cnt_grps_no, &in_pkt, msg_body, in_pkt.tlen))==0) goto error; break; default: fprintf(stderr, "ERROR: not a reply\n"); goto error; } /* get the config groups */ last_grp=0; for (r=0; r<cnt_grps_no; r++){ grp_name.s=0; grp_name.len=0; if (cnt_grps_array[r].type!=BINRPC_T_STR) continue; grp_name=cnt_grps_array[r].u.strval; /* check for duplicates */ for (grp=cnt_grp_lst; grp; grp=grp->next){ if (grp->grp_name.len==grp_name.len && memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){ break; /* found */ } } if (grp==0){ /* not found => create a new one */ grp=malloc(sizeof(*grp)); if (grp==0) goto error_mem; memset(grp, 0, sizeof(*grp)); grp->grp_name=grp_name; if (last_grp){ last_grp->next=grp; last_grp=grp; }else{ cnt_grp_lst=grp; last_grp=cnt_grp_lst; } } } /* gets vars per group */ for (grp=cnt_grp_lst; grp; grp=grp->next){ cmd.method="cnt.var_list"; cmd.argv[0].type=BINRPC_T_STR; cmd.argv[0].u.strval=grp->grp_name; cmd.argc=1; if (!is_rpc_cmd(cmd.method)) goto error; cookie=gen_cookie(); if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){ if (ret==-1) goto error_send; else goto binrpc_err; } /* read reply */ memset(&in_pkt, 0, sizeof(in_pkt)); if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt, &msg_body))<0){ goto error; } switch(in_pkt.type){ case BINRPC_FAULT: if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){ goto error; } break; case BINRPC_REPL: grp->cnt_vars_no=100; /* default counter list */ if ((grp->cnt_vars_array=parse_reply_body(&grp->cnt_vars_no, &in_pkt, msg_body, in_pkt.tlen))==0) goto error; break; default: fprintf(stderr, "ERROR: not a reply\n"); goto error; } grp->var_no = 0; grp->var_names=malloc(sizeof(str)*grp->cnt_vars_no); if (grp->var_names==0) goto error_mem; memset(grp->var_names, 0, sizeof(str)*grp->cnt_vars_no); for (r=0; r<grp->cnt_vars_no; r++) { if (grp->cnt_vars_array[r].type!=BINRPC_T_STR) continue; var_name=grp->cnt_vars_array[r].u.strval; grp->var_names[grp->var_no] = var_name; grp->var_no++; } } return 0; binrpc_err: error_send: error: error_mem: return -1; }
/* retrieve the cfg vars and group list */ static int get_cfgvars_list(int s) { struct binrpc_cmd cmd; int cookie; unsigned char reply_buf[MAX_REPLY_SIZE]; unsigned char* msg_body; struct binrpc_parse_ctx in_pkt; struct cfg_var_grp* grp; struct cfg_var_grp* last_grp; char* p; char* end; str grp_name; str var_name; int r; int ret; cmd.method="cfg.list"; cmd.argc=0; if (!is_rpc_cmd(cmd.method)) goto error; cookie=gen_cookie(); if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){ if (ret==-1) goto error_send; else goto binrpc_err; } /* read reply */ memset(&in_pkt, 0, sizeof(in_pkt)); if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt, &msg_body))<0){ goto error; } switch(in_pkt.type){ case BINRPC_FAULT: if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){ goto error; } break; case BINRPC_REPL: cfg_vars_no=100; /* default cmd list */ if ((cfg_vars_array=parse_reply_body(&cfg_vars_no, &in_pkt, msg_body, in_pkt.tlen))==0) goto error; break; default: fprintf(stderr, "ERROR: not a reply\n"); goto error; } /* get the config groups */ last_grp=0; for (r=0; r<cfg_vars_no; r++){ grp_name.s=0; grp_name.len=0; if (cfg_vars_array[r].type!=BINRPC_T_STR) continue; grp_name.s=cfg_vars_array[r].u.strval.s; end=cfg_vars_array[r].u.strval.len+grp_name.s; /* parse <grp>: <var_name>*/ for (p=grp_name.s; p<end; p++){ if (*p==':'){ grp_name.len=(int)(long)(p-grp_name.s); break; } } for (grp=cfg_grp_lst; grp; grp=grp->next){ if (grp->grp_name.len==grp_name.len && memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){ break; /* found */ } } if (grp==0){ /* not found => create a new one */ grp=malloc(sizeof(*grp)); if (grp==0) goto error_mem; memset(grp, 0, sizeof(*grp)); grp->grp_name=grp_name; if (last_grp){ last_grp->next=grp; last_grp=grp; }else{ cfg_grp_lst=grp; last_grp=cfg_grp_lst; } } grp->var_no++; } /* alloc the var arrays per group */ for (grp=cfg_grp_lst; grp; grp=grp->next){ grp->var_names=malloc(sizeof(str)*grp->var_no); if (grp->var_names==0) goto error_mem; memset(grp->var_names, 0, sizeof(str)*grp->var_no); grp->var_no=0; } /* reparse to get the var names per group */ for (r=0; r<cfg_vars_no; r++){ grp_name.s=0; grp_name.len=0; var_name.s=0; var_name.len=0; if (cfg_vars_array[r].type!=BINRPC_T_STR) continue; grp_name.s=cfg_vars_array[r].u.strval.s; end=cfg_vars_array[r].u.strval.len+grp_name.s; /* parse <grp>: <var_name>*/ for (p=grp_name.s; p<end; p++){ if (*p==':'){ grp_name.len=(int)(long)(p-grp_name.s); p++; for (; p<end && *p==' '; p++); var_name.s=p; var_name.len=(int)(long)(end-p); if (var_name.len==0) break; for (grp=cfg_grp_lst; grp; grp=grp->next){ if (grp->grp_name.len==grp_name.len && memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){ /* add var */ grp->var_names[grp->var_no]=var_name; grp->var_no++; } } break; } } } return 0; binrpc_err: error_send: error: error_mem: return -1; }