static int test_delchar(ibuf s) { /* Delete the last '!' from the string. */ ibuf_delchar(s); /* Make sure it was deleted correctly. */ if (strcmp(ibuf_get(s), "hello world") != 0) { debug("test_delchar: Mismatch, expected \"hello world\", got: %s\n", ibuf_get(s)); return 1; } /* Wipe the string via delchar, testing ibuf_length simultaneously */ while (ibuf_length(s) > 0) { ibuf_delchar(s); } /* Make sure s is now an empty string. */ if (strcmp(ibuf_get(s), "") != 0) { debug("test_delchar: Expected empty string, got: %s\n", ibuf_get(s)); return 2; } debug("test_delchar: Succeeded.\n"); return 0; }
int ikev2_msg_send(struct iked *env, struct iked_message *msg) { struct ibuf *buf = msg->msg_data; u_int32_t natt = 0x00000000; struct ike_header *hdr; if (buf == NULL || (hdr = ibuf_seek(msg->msg_data, msg->msg_offset, sizeof(*hdr))) == NULL) return (-1); log_info("%s: %s from %s to %s, %ld bytes", __func__, print_map(hdr->ike_exchange, ikev2_exchange_map), print_host(&msg->msg_local, NULL, 0), print_host(&msg->msg_peer, NULL, 0), ibuf_length(buf)); if (msg->msg_natt || (msg->msg_sa && msg->msg_sa->sa_natt)) { if (ibuf_prepend(buf, &natt, sizeof(natt)) == -1) { log_debug("%s: failed to set NAT-T", __func__); return (-1); } } if ((sendto(msg->msg_fd, ibuf_data(buf), ibuf_size(buf), 0, (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen)) == -1) { log_warn("%s: sendto", __func__); return (-1); } return (0); }
/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int status_bar_regex_input(struct sviewer *sview, int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Recieve a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ if (regex_last != NULL) { ibuf_free(regex_last); } regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; source_search_regex(sview, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; } else { ibuf_delchar(regex_cur); source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); }; if (done) { ibuf_free(regex_cur); regex_cur = NULL; if_set_focus(CGDB); } return 0; }
int ikev2_msg_send(struct iked *env, struct iked_message *msg) { struct iked_sa *sa = msg->msg_sa; struct ibuf *buf = msg->msg_data; u_int32_t natt = 0x00000000; int isnatt = 0; struct ike_header *hdr; struct iked_message *m; if (buf == NULL || (hdr = ibuf_seek(msg->msg_data, msg->msg_offset, sizeof(*hdr))) == NULL) return (-1); isnatt = (msg->msg_natt || (msg->msg_sa && msg->msg_sa->sa_natt)); log_info("%s: %s from %s to %s, %ld bytes%s", __func__, print_map(hdr->ike_exchange, ikev2_exchange_map), print_host(&msg->msg_local, NULL, 0), print_host(&msg->msg_peer, NULL, 0), ibuf_length(buf), isnatt ? ", NAT-T" : ""); if (isnatt) { if (ibuf_prepend(buf, &natt, sizeof(natt)) == -1) { log_debug("%s: failed to set NAT-T", __func__); return (-1); } msg->msg_offset += sizeof(natt); } if ((sendto(msg->msg_fd, ibuf_data(buf), ibuf_size(buf), 0, (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen)) == -1) { log_warn("%s: sendto", __func__); return (-1); } if (!sa) return (0); if ((m = ikev2_msg_copy(env, msg)) == NULL) { log_debug("%s: failed to copy a message", __func__); return (-1); } m->msg_exchange = hdr->ike_exchange; if (hdr->ike_flags & IKEV2_FLAG_RESPONSE) { TAILQ_INSERT_TAIL(&sa->sa_responses, m, msg_entry); timer_initialize(env, &m->msg_timer, ikev2_msg_response_timeout, m); timer_register(env, &m->msg_timer, IKED_RESPONSE_TIMEOUT); } else { TAILQ_INSERT_TAIL(&sa->sa_requests, m, msg_entry); timer_initialize(env, &m->msg_timer, ikev2_msg_retransmit_timeout, m); timer_register(env, &m->msg_timer, IKED_RETRANSMIT_TIMEOUT); } return (0); }
int ca_setreq(struct iked *env, struct iked_sa *sa, struct iked_static_id *localid, uint8_t type, uint8_t *data, size_t len, enum privsep_procid procid) { struct iovec iov[4]; int iovcnt = 0; struct iked_static_id idb; struct iked_id id; int ret = -1; /* Convert to a static Id */ bzero(&id, sizeof(id)); if (ikev2_policy2id(localid, &id, 1) != 0) return (-1); bzero(&idb, sizeof(idb)); idb.id_type = id.id_type; idb.id_offset = id.id_offset; idb.id_length = ibuf_length(id.id_buf); memcpy(&idb.id_data, ibuf_data(id.id_buf), ibuf_length(id.id_buf)); iov[iovcnt].iov_base = &idb; iov[iovcnt].iov_len = sizeof(idb); iovcnt++; iov[iovcnt].iov_base = &sa->sa_hdr; iov[iovcnt].iov_len = sizeof(sa->sa_hdr); iovcnt++; iov[iovcnt].iov_base = &type; iov[iovcnt].iov_len = sizeof(type); iovcnt++; iov[iovcnt].iov_base = data; iov[iovcnt].iov_len = len; iovcnt++; if (proc_composev(&env->sc_ps, procid, IMSG_CERTREQ, iov, iovcnt) == -1) goto done; sa_stateflags(sa, IKED_REQ_CERTREQ); ret = 0; done: ibuf_release(id.id_buf); return (ret); }
size_t cipher_keylength(struct iked_cipher *encr) { if (encr->encr_fixedkey) return (encr->encr_fixedkey); /* Might return zero */ return (ibuf_length(encr->encr_key)); }
int ca_setcert(struct iked *env, struct iked_sahdr *sh, struct iked_id *id, u_int8_t type, u_int8_t *data, size_t len, enum privsep_procid procid) { struct iovec iov[4]; int iovcnt = 0; struct iked_static_id idb; /* Must send the cert and a valid Id to the ca process */ if (procid == PROC_CERT) { if (id == NULL || id->id_type == IKEV2_ID_NONE || ibuf_length(id->id_buf) > IKED_ID_SIZE) return (-1); bzero(&idb, sizeof(idb)); /* Convert to a static Id */ idb.id_type = id->id_type; idb.id_offset = id->id_offset; idb.id_length = ibuf_length(id->id_buf); memcpy(&idb.id_data, ibuf_data(id->id_buf), ibuf_length(id->id_buf)); iov[iovcnt].iov_base = &idb; iov[iovcnt].iov_len = sizeof(idb); iovcnt++; } iov[iovcnt].iov_base = sh; iov[iovcnt].iov_len = sizeof(*sh); iovcnt++; iov[iovcnt].iov_base = &type; iov[iovcnt].iov_len = sizeof(type); iovcnt++; iov[iovcnt].iov_base = data; iov[iovcnt].iov_len = len; iovcnt++; if (proc_composev_imsg(&env->sc_ps, procid, -1, IMSG_CERT, -1, iov, iovcnt) == -1) return (-1); return (0); }
static int status_bar_normal_input(int key) { /* Flag to indicate we're done with status mode, need to switch back */ int done = 0; /* The goal of this state is to recieve a command from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Found a command */ if_run_command(src_win, cur_sbc); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(cur_sbc) == 0) { done = 1; } else { ibuf_delchar(cur_sbc); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(cur_sbc, keycode[i]); } else { ibuf_addchar(cur_sbc, key); } update_status_win(); break; }; if (done) { ibuf_free(cur_sbc); cur_sbc = NULL; if_set_focus(CGDB); } return 0; }
static void if_run_command(struct sviewer *sview, struct ibuf *ibuf_command) { char *command = ibuf_get(ibuf_command); /* refresh and return if the user entered no data */ if (ibuf_length(ibuf_command) == 0) { if_draw(); return; } if (command_parse_string(command)) { if_display_message("Unknown command: ", 0, "%s", command); } else { update_status_win(); } if_draw(); }
int dsa_init(struct iked_dsa *dsa, const void *buf, size_t len) { int ret; if (dsa->dsa_hmac) { if (!HMAC_Init_ex(dsa->dsa_ctx, ibuf_data(dsa->dsa_keydata), ibuf_length(dsa->dsa_keydata), dsa->dsa_priv, NULL)) return (-1); return (0); } if (dsa->dsa_sign) ret = EVP_SignInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL); else { if ((ret = _dsa_verify_init(dsa, buf, len)) != 0) return (ret); ret = EVP_VerifyInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL); } return (ret ? 0 : -1); }
int a2_handle_data( struct annotate_two *a2, struct state_machine *sm, const char *data, const size_t size, char *gui_data, size_t *gui_size, struct tgdb_list *command_list){ int i, counter = 0; /* track state to find next file and line number */ for(i = 0; i < size; ++i){ switch(data[i]){ /* Ignore all car returns outputted by gdb */ case '\r': break; case '\n': switch(sm->tgdb_state){ case DATA: sm->tgdb_state = NEW_LINE; break; case NEW_LINE: sm->tgdb_state = NEW_LINE; data_process(a2, '\n', gui_data, &counter, command_list); break; case CONTROL_Z: sm->tgdb_state = DATA; data_process(a2, '\n', gui_data, &counter, command_list); data_process(a2, '\032', gui_data, &counter, command_list); break; case ANNOTATION: /* Found an annotation */ sm->tgdb_state = NL_DATA; tgdb_parse_annotation(a2, ibuf_get ( sm->tgdb_buffer ), ibuf_length ( sm->tgdb_buffer ), command_list); ibuf_clear ( sm->tgdb_buffer ); break; case NL_DATA: sm->tgdb_state = NEW_LINE; break; default: logger_write_pos ( logger, __FILE__, __LINE__, "Bad state transition"); break; } /* end switch */ break; case '\032': switch(sm->tgdb_state){ case DATA: sm->tgdb_state = DATA; data_process(a2, '\032', gui_data, &counter, command_list); break; case NEW_LINE: sm->tgdb_state = CONTROL_Z; break; case NL_DATA: sm->tgdb_state = CONTROL_Z; break; case CONTROL_Z: sm->tgdb_state = ANNOTATION; break; case ANNOTATION: ibuf_addchar ( sm->tgdb_buffer, data[i] ); break; default: logger_write_pos ( logger, __FILE__, __LINE__, "Bad state transition"); break; } /* end switch */ break; default: switch(sm->tgdb_state){ case DATA: data_process(a2, data[i], gui_data, &counter, command_list); break; case NL_DATA: sm->tgdb_state = DATA; data_process(a2, data[i], gui_data, &counter, command_list); break; case NEW_LINE: sm->tgdb_state = DATA; data_process(a2, '\n', gui_data, &counter, command_list); data_process(a2, data[i], gui_data, &counter, command_list); break; case CONTROL_Z: sm->tgdb_state = DATA; data_process(a2, '\n', gui_data, &counter, command_list); data_process(a2, '\032', gui_data, &counter, command_list); data_process(a2, data[i], gui_data, &counter, command_list); break; case ANNOTATION: ibuf_addchar ( sm->tgdb_buffer, data[i] ); break; default: logger_write_pos ( logger, __FILE__, __LINE__, "Bad state transition"); break; } /* end switch */ break; } /* end switch */ } /* end for */ gui_data[counter] = '\0'; *gui_size = counter; return 0; }
static int highlight_node ( struct list_node *node ) { struct tokenizer *t = tokenizer_init (); int ret; struct ibuf *ibuf = ibuf_init (); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); /* Initialize */ node->buf.length = 0; node->buf.tlines = NULL; node->buf.max_width = 0; if ( tokenizer_set_file ( t, node->path, node->language ) == -1 ) { if_print_message ("%s:%d tokenizer_set_file error", __FILE__, __LINE__); return -1; } while ( ( ret = tokenizer_get_token ( t ) ) > 0 ) { enum tokenizer_type e = tokenizer_get_packet_type ( t ); /*if_print_message ( "TOKEN(%d:%s)\n", e, tokenizer_get_printable_enum ( e ) );*/ switch ( e ) { case TOKENIZER_KEYWORD: ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_KEYWORD ); ibuf_add ( ibuf, tokenizer_get_data ( t ) ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_TYPE: ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TYPE ); ibuf_add ( ibuf, tokenizer_get_data ( t ) ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_LITERAL: ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_LITERAL ); ibuf_add ( ibuf, tokenizer_get_data ( t ) ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_NUMBER: ibuf_add ( ibuf, tokenizer_get_data ( t ) ); break; case TOKENIZER_COMMENT: ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_COMMENT ); ibuf_add ( ibuf, tokenizer_get_data ( t ) ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_DIRECTIVE: ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_DIRECTIVE ); ibuf_add ( ibuf, tokenizer_get_data ( t ) ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_TEXT: ibuf_add ( ibuf, tokenizer_get_data ( t ) ); break; case TOKENIZER_NEWLINE: node->buf.length++; node->buf.tlines = realloc ( node->buf.tlines, sizeof ( char *) * node->buf.length ); node->buf.tlines[node->buf.length-1] = strdup ( ibuf_get ( ibuf ) ); if ( ibuf_length ( ibuf ) > node->buf.max_width ) node->buf.max_width = ibuf_length ( ibuf ); ibuf_clear ( ibuf ); ibuf_addchar ( ibuf, HL_CHAR ); ibuf_addchar ( ibuf, HLG_TEXT ); break; case TOKENIZER_ERROR: ibuf_add ( ibuf, tokenizer_get_data ( t ) ); break; default: return -1; break; } } return 0; }
void hash_init(struct iked_hash *hash) { HMAC_Init_ex(hash->hash_ctx, hash->hash_key->buf, ibuf_length(hash->hash_key), hash->hash_priv, NULL); }
/* Please forgive me for adding all the comment below. This function * has some strange bahaviors that I thought should be well explained. */ void rlctx_send_user_command(char *line) { char *cline; int length; char *rline_prompt; tgdb_request_ptr request_ptr; if (line == NULL) { /* NULL line means rl_callback_read_char received EOF */ ibuf_add(current_line, "quit"); } else { /* Add the line passed in to the current line */ ibuf_add(current_line, line); } /* Get current line, and current line length */ cline = ibuf_get(current_line); length = ibuf_length(current_line); /* Check to see if the user is escaping the line, to use a * multi line command. If so, return so that the user can * continue the command. This data should not go into the history * buffer, or be sent to gdb yet. * * Also, notice the length > 0 condition. (length == 0) can happen * when the user simply hits Enter on the keyboard. */ if (length > 0 && cline[length - 1] == '\\') { /* The \ char is for continuation only, it is not meant to be sent * to GDB as a character. */ ibuf_delchar(current_line); /* Only need to change the prompt the first time the \ char is used. * Doing it a second time would erase the real rline_last_prompt, * since the prompt has already been set to "". */ if (!rline_last_prompt) { rline_get_prompt(rline, &rline_prompt); rline_last_prompt = strdup(rline_prompt); /* GDB set's the prompt to nothing when doing continuation. * This is here just for compatibility. */ rline_set_prompt(rline, ""); } return; } /* If here, a full command has been sent. Restore the prompt. */ if (rline_last_prompt) { rline_set_prompt(rline, rline_last_prompt); free(rline_last_prompt); rline_last_prompt = NULL; } /* Don't add the enter command to the history */ if (length > 0) rline_add_history(rline, cline); request_ptr = tgdb_request_run_console_command(tgdb, cline); if (!request_ptr) logger_write_pos(logger, __FILE__, __LINE__, "rlctx_send_user_command\n"); /* Send this command to TGDB */ handle_request(tgdb, request_ptr); ibuf_clear(current_line); }
int ca_reload(struct iked *env) { struct ca_store *store = env->sc_priv; uint8_t md[EVP_MAX_MD_SIZE]; char file[PATH_MAX]; struct iovec iov[2]; struct dirent *entry; STACK_OF(X509_OBJECT) *h; X509_OBJECT *xo; X509 *x509; DIR *dir; int i, len, iovcnt = 0; /* * Load CAs */ if ((dir = opendir(IKED_CA_DIR)) == NULL) return (-1); while ((entry = readdir(dir)) != NULL) { if ((entry->d_type != DT_REG) && (entry->d_type != DT_LNK)) continue; if (snprintf(file, sizeof(file), "%s%s", IKED_CA_DIR, entry->d_name) == -1) continue; if (!X509_load_cert_file(store->ca_calookup, file, X509_FILETYPE_PEM)) { log_warn("%s: failed to load ca file %s", __func__, entry->d_name); ca_sslerror(__func__); continue; } log_debug("%s: loaded ca file %s", __func__, entry->d_name); } closedir(dir); /* * Load CRLs for the CAs */ if ((dir = opendir(IKED_CRL_DIR)) == NULL) return (-1); while ((entry = readdir(dir)) != NULL) { if ((entry->d_type != DT_REG) && (entry->d_type != DT_LNK)) continue; if (snprintf(file, sizeof(file), "%s%s", IKED_CRL_DIR, entry->d_name) == -1) continue; if (!X509_load_crl_file(store->ca_calookup, file, X509_FILETYPE_PEM)) { log_warn("%s: failed to load crl file %s", __func__, entry->d_name); ca_sslerror(__func__); continue; } /* Only enable CRL checks if we actually loaded a CRL */ X509_STORE_set_flags(store->ca_cas, X509_V_FLAG_CRL_CHECK); log_debug("%s: loaded crl file %s", __func__, entry->d_name); } closedir(dir); /* * Save CAs signatures for the IKEv2 CERTREQ */ ibuf_release(env->sc_certreq); if ((env->sc_certreq = ibuf_new(NULL, 0)) == NULL) return (-1); h = store->ca_cas->objs; for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); if (xo->type != X509_LU_X509) continue; x509 = xo->data.x509; len = sizeof(md); ca_subjectpubkey_digest(x509, md, &len); log_debug("%s: %s", __func__, x509->name); if (ibuf_add(env->sc_certreq, md, len) != 0) { ibuf_release(env->sc_certreq); return (-1); } } if (ibuf_length(env->sc_certreq)) { env->sc_certreqtype = IKEV2_CERT_X509_CERT; iov[0].iov_base = &env->sc_certreqtype; iov[0].iov_len = sizeof(env->sc_certreqtype); iovcnt++; iov[1].iov_base = ibuf_data(env->sc_certreq); iov[1].iov_len = ibuf_length(env->sc_certreq); iovcnt++; log_debug("%s: loaded %zu ca certificate%s", __func__, ibuf_length(env->sc_certreq) / SHA_DIGEST_LENGTH, ibuf_length(env->sc_certreq) == SHA_DIGEST_LENGTH ? "" : "s"); (void)proc_composev(&env->sc_ps, PROC_IKEV2, IMSG_CERTREQ, iov, iovcnt); } /* * Load certificates */ if ((dir = opendir(IKED_CERT_DIR)) == NULL) return (-1); while ((entry = readdir(dir)) != NULL) { if ((entry->d_type != DT_REG) && (entry->d_type != DT_LNK)) continue; if (snprintf(file, sizeof(file), "%s%s", IKED_CERT_DIR, entry->d_name) == -1) continue; if (!X509_load_cert_file(store->ca_certlookup, file, X509_FILETYPE_PEM)) { log_warn("%s: failed to load cert file %s", __func__, entry->d_name); ca_sslerror(__func__); continue; } log_debug("%s: loaded cert file %s", __func__, entry->d_name); } closedir(dir); h = store->ca_certs->objs; for (i = 0; i < sk_X509_OBJECT_num(h); i++) { xo = sk_X509_OBJECT_value(h, i); if (xo->type != X509_LU_X509) continue; x509 = xo->data.x509; (void)ca_validate_cert(env, NULL, x509, 0); } if (!env->sc_certreqtype) env->sc_certreqtype = store->ca_pubkey.id_type; log_debug("%s: local cert type %s", __func__, print_map(env->sc_certreqtype, ikev2_cert_map)); iov[0].iov_base = &env->sc_certreqtype; iov[0].iov_len = sizeof(env->sc_certreqtype); if (iovcnt == 0) iovcnt++; (void)proc_composev(&env->sc_ps, PROC_IKEV2, IMSG_CERTREQ, iov, iovcnt); return (0); }
int ikev2_msg_authverify(struct iked *env, struct iked_sa *sa, struct iked_auth *auth, uint8_t *buf, size_t len, struct ibuf *authmsg) { uint8_t *key, *psk = NULL; ssize_t keylen; struct iked_id *id; struct iked_dsa *dsa = NULL; int ret = -1; uint8_t keytype; if (sa->sa_hdr.sh_initiator) id = &sa->sa_rcert; else id = &sa->sa_icert; if ((dsa = dsa_verify_new(auth->auth_method, sa->sa_prf)) == NULL) { log_debug("%s: invalid auth method", __func__); return (-1); } switch (auth->auth_method) { case IKEV2_AUTH_SHARED_KEY_MIC: if (!auth->auth_length) { log_debug("%s: no pre-shared key found", __func__); goto done; } if ((keylen = ikev2_psk(sa, auth->auth_data, auth->auth_length, &psk)) == -1) { log_debug("%s: failed to get PSK", __func__); goto done; } key = psk; keytype = 0; break; default: if (!id->id_type || !ibuf_length(id->id_buf)) { log_debug("%s: no cert found", __func__); goto done; } key = ibuf_data(id->id_buf); keylen = ibuf_size(id->id_buf); keytype = id->id_type; break; } log_debug("%s: method %s keylen %zd type %s", __func__, print_map(auth->auth_method, ikev2_auth_map), keylen, print_map(id->id_type, ikev2_cert_map)); if (dsa_setkey(dsa, key, keylen, keytype) == NULL || dsa_init(dsa, buf, len) != 0 || dsa_update(dsa, ibuf_data(authmsg), ibuf_size(authmsg))) { log_debug("%s: failed to compute digital signature", __func__); goto done; } if ((ret = dsa_verify_final(dsa, buf, len)) == 0) { log_debug("%s: authentication successful", __func__); sa_state(env, sa, IKEV2_STATE_AUTH_SUCCESS); sa_stateflags(sa, IKED_REQ_AUTHVALID); } else { log_debug("%s: authentication failed", __func__); sa_state(env, sa, IKEV2_STATE_AUTH_REQUEST); } done: free(psk); dsa_free(dsa); return (ret); }
struct ibuf * ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa, struct ibuf *msg, struct ibuf *src) { ssize_t ivlen, encrlen, integrlen, blocklen, outlen, tmplen; uint8_t pad = 0, *ptr; struct ibuf *integr, *encr, *tmp = NULL, *out = NULL; off_t ivoff, encroff, integroff; if (sa == NULL || sa->sa_encr == NULL || sa->sa_integr == NULL) { log_debug("%s: invalid SA", __func__); print_hex(ibuf_data(src), 0, ibuf_size(src)); goto done; } if (!sa->sa_hdr.sh_initiator) { encr = sa->sa_key_iencr; integr = sa->sa_key_iauth; } else { encr = sa->sa_key_rencr; integr = sa->sa_key_rauth; } blocklen = cipher_length(sa->sa_encr); ivlen = cipher_ivlength(sa->sa_encr); ivoff = 0; integrlen = hash_length(sa->sa_integr); integroff = ibuf_size(src) - integrlen; encroff = ivlen; encrlen = ibuf_size(src) - integrlen - ivlen; if (encrlen < 0 || integroff < 0) { log_debug("%s: invalid integrity value", __func__); goto done; } log_debug("%s: IV length %zd", __func__, ivlen); print_hex(ibuf_data(src), 0, ivlen); log_debug("%s: encrypted payload length %zd", __func__, encrlen); print_hex(ibuf_data(src), encroff, encrlen); log_debug("%s: integrity checksum length %zd", __func__, integrlen); print_hex(ibuf_data(src), integroff, integrlen); /* * Validate packet checksum */ if ((tmp = ibuf_new(NULL, ibuf_length(integr))) == NULL) goto done; hash_setkey(sa->sa_integr, integr->buf, ibuf_length(integr)); hash_init(sa->sa_integr); hash_update(sa->sa_integr, ibuf_data(msg), ibuf_size(msg) - integrlen); hash_final(sa->sa_integr, tmp->buf, &tmplen); if (memcmp(tmp->buf, ibuf_data(src) + integroff, integrlen) != 0) { log_debug("%s: integrity check failed", __func__); goto done; } log_debug("%s: integrity check succeeded", __func__); print_hex(tmp->buf, 0, tmplen); ibuf_release(tmp); tmp = NULL; /* * Decrypt the payload and strip any padding */ if ((encrlen % blocklen) != 0) { log_debug("%s: unaligned encrypted payload", __func__); goto done; } cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr)); cipher_setiv(sa->sa_encr, ibuf_data(src) + ivoff, ivlen); cipher_init_decrypt(sa->sa_encr); if ((out = ibuf_new(NULL, cipher_outlength(sa->sa_encr, encrlen))) == NULL) goto done; if ((outlen = ibuf_length(out)) != 0) { cipher_update(sa->sa_encr, ibuf_data(src) + encroff, encrlen, ibuf_data(out), &outlen); ptr = ibuf_seek(out, outlen - 1, 1); pad = *ptr; } log_debug("%s: decrypted payload length %zd/%zd padding %d", __func__, outlen, encrlen, pad); print_hex(ibuf_data(out), 0, ibuf_size(out)); if (ibuf_setsize(out, outlen) != 0) goto done; ibuf_release(src); return (out); done: ibuf_release(tmp); ibuf_release(out); ibuf_release(src); return (NULL); }
struct ibuf * ikev2_msg_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf *src) { size_t len, encrlen, integrlen, blocklen, outlen; uint8_t *buf, pad = 0, *ptr; struct ibuf *encr, *dst = NULL, *out = NULL; buf = ibuf_data(src); len = ibuf_size(src); log_debug("%s: decrypted length %zu", __func__, len); print_hex(buf, 0, len); if (sa == NULL || sa->sa_encr == NULL || sa->sa_integr == NULL) { log_debug("%s: invalid SA", __func__); goto done; } if (sa->sa_hdr.sh_initiator) encr = sa->sa_key_iencr; else encr = sa->sa_key_rencr; blocklen = cipher_length(sa->sa_encr); integrlen = hash_length(sa->sa_integr); encrlen = roundup(len + sizeof(pad), blocklen); pad = encrlen - (len + sizeof(pad)); /* * Pad the payload and encrypt it */ if (pad) { if ((ptr = ibuf_advance(src, pad)) == NULL) goto done; arc4random_buf(ptr, pad); } if (ibuf_add(src, &pad, sizeof(pad)) != 0) goto done; log_debug("%s: padded length %zu", __func__, ibuf_size(src)); print_hex(ibuf_data(src), 0, ibuf_size(src)); cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr)); cipher_setiv(sa->sa_encr, NULL, 0); cipher_init_encrypt(sa->sa_encr); if ((dst = ibuf_dup(sa->sa_encr->encr_iv)) == NULL) goto done; if ((out = ibuf_new(NULL, cipher_outlength(sa->sa_encr, encrlen))) == NULL) goto done; outlen = ibuf_size(out); cipher_update(sa->sa_encr, ibuf_data(src), encrlen, ibuf_data(out), &outlen); if (outlen && ibuf_add(dst, ibuf_data(out), outlen) != 0) goto done; if ((ptr = ibuf_advance(dst, integrlen)) == NULL) goto done; explicit_bzero(ptr, integrlen); log_debug("%s: length %zu, padding %d, output length %zu", __func__, len + sizeof(pad), pad, ibuf_size(dst)); print_hex(ibuf_data(dst), 0, ibuf_size(dst)); ibuf_release(src); ibuf_release(out); return (dst); done: ibuf_release(src); ibuf_release(out); ibuf_release(dst); return (NULL); }
/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int gdb_input_regex_input(struct scroller *scr, int key) { int regex_icase = cgdbrc_get_int(CGDBRC_IGNORECASE); /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Receive a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ ibuf_free(regex_last); regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; scr_search_regex(scr, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; scr_search_regex(scr, "", 2, regex_direction_cur, regex_icase); } else { ibuf_delchar(regex_cur); scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); }; if (done) { gdb_scroller->in_search_mode = 0; ibuf_free(regex_cur); regex_cur = NULL; sbc_kind = SBC_NORMAL; if_set_focus(GDB); } return 0; }