static char * list_initiator(xml_node_t *x) { char *msg = NULL, *attr, *prop = NULL; Boolean_t verbose = False; xml_node_t *init = NULL; /* ---- Optional arguments ---- */ if ((xml_find_value_str(x, XML_ELEMENT_NAME, &prop) == True) && (prop == NULL)) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME); return (msg); } (void) xml_find_value_boolean(x, XML_ELEMENT_VERBOSE, &verbose); buf_add_tag_and_attr(&msg, XML_ELEMENT_RESULT, "version='1.0'"); while ((init = xml_node_next(main_config, XML_ELEMENT_INIT, init)) != NULL) { if ((prop == NULL) || ((prop != NULL) && (strcmp(prop, init->x_value) == 0))) { buf_add_tag(&msg, XML_ELEMENT_INIT, Tag_Start); buf_add_tag(&msg, init->x_value, Tag_String); if (xml_find_value_str(init, XML_ELEMENT_INAME, &attr) == True) { xml_add_tag(&msg, XML_ELEMENT_INAME, attr); free(attr); } if (xml_find_value_str(init, XML_ELEMENT_CHAPSECRET, &attr) == True) { xml_add_tag(&msg, XML_ELEMENT_CHAPSECRET, attr); free(attr); } if (xml_find_value_str(init, XML_ELEMENT_CHAPNAME, &attr) == True) { xml_add_tag(&msg, XML_ELEMENT_CHAPNAME, attr); free(attr); } buf_add_tag(&msg, XML_ELEMENT_INIT, Tag_End); } } if (prop != NULL) free(prop); buf_add_tag(&msg, XML_ELEMENT_RESULT, Tag_End); return (msg); }
static int xml_add_mpi2 (gnutls_string * xmlkey, const uint8_t * data, size_t count, const char *tag) { char *p = NULL; size_t i; int rc = 0; if (!xmlkey || !data || !tag) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } p = gnutls_calloc (1, 2 * (count + 3)); if (!p) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < count; i++) sprintf (p + 2 * i, "%02X", data[i]); p[2 * count] = '\0'; rc = xml_add_tag (xmlkey, tag, p); gnutls_free (p); return rc; }
static int xml_add_userid (gnutls_string * xmlkey, int ext, const char *dn, cdk_pkt_userid_t id) { const char *s; char tmp[32]; int rc = 0; if (!xmlkey || !dn || !id) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } s = " <USERID>\n"; _gnutls_string_append_str (xmlkey, s); rc = xml_add_tag (xmlkey, "NAME", dn); if (rc) return rc; if (ext) { sprintf (tmp, "%d", id->is_primary); rc = xml_add_tag (xmlkey, "PRIMARY", tmp); if (rc) return rc; sprintf (tmp, "%d", id->is_revoked); rc = xml_add_tag (xmlkey, "REVOKED", tmp); if (rc) return rc; } s = " </USERID>\n"; _gnutls_string_append_str (xmlkey, s); return 0; }
static char * list_tpgt(xml_node_t *x) { char *msg = NULL, *prop = NULL; Boolean_t verbose = False; xml_node_t *tpgt = NULL, *ip = NULL; /* ---- Optional arguments ---- */ if ((xml_find_value_str(x, XML_ELEMENT_NAME, &prop) == True) && (prop == NULL)) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME); return (msg); } (void) xml_find_value_boolean(x, XML_ELEMENT_VERBOSE, &verbose); buf_add_tag_and_attr(&msg, XML_ELEMENT_RESULT, "version='1.0'"); while ((tpgt = xml_node_next(main_config, XML_ELEMENT_TPGT, tpgt)) != NULL) { if ((prop == NULL) || ((prop != NULL) && (strcmp(prop, tpgt->x_value) == 0))) { buf_add_tag(&msg, XML_ELEMENT_TPGT, Tag_Start); buf_add_tag(&msg, tpgt->x_value, Tag_String); while ((ip = xml_node_next(tpgt, XML_ELEMENT_IPADDR, ip)) != NULL) { xml_add_tag(&msg, ip->x_name, ip->x_value); } buf_add_tag(&msg, XML_ELEMENT_TPGT, Tag_End); } } buf_add_tag(&msg, XML_ELEMENT_RESULT, Tag_End); if (prop != NULL) free(prop); return (msg); }
/*ARGSUSED*/ static char * list_admin(xml_node_t *x) { char *msg = NULL; admin_table_t *p; xml_node_t *node = NULL; buf_add_tag_and_attr(&msg, XML_ELEMENT_RESULT, "version='1.0'"); buf_add_tag(&msg, XML_ELEMENT_ADMIN, Tag_Start); node = NULL; for (p = admin_prop_list; p->name != NULL; p++) { node = xml_node_next_child(main_config, p->name, NULL); if (node) { xml_add_tag(&msg, p->name, node->x_value); } } buf_add_tag(&msg, XML_ELEMENT_ADMIN, Tag_End); buf_add_tag(&msg, XML_ELEMENT_RESULT, Tag_End); return (msg); }
static char * list_targets(xml_node_t *x) { char *msg = NULL, *prop = NULL, *iname = NULL; xml_node_t *targ = NULL; Boolean_t luninfo = False, dostat = False; /* * It's okay to not supply a "name" element. That just means the * administrator wants a complete list of targets. However if a * "name" is supplied then there must be a value for that element. */ if ((xml_find_value_str(x, XML_ELEMENT_NAME, &prop) == True) && (prop == NULL)) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME); return (msg); } /* ---- optional arguments ---- */ (void) xml_find_value_boolean(x, XML_ELEMENT_LUNINFO, &luninfo); (void) xml_find_value_boolean(x, XML_ELEMENT_IOSTAT, &dostat); buf_add_tag_and_attr(&msg, XML_ELEMENT_RESULT, "version='1.0'"); while ((targ = xml_node_next(targets_config, XML_ELEMENT_TARG, targ)) != NULL) { if (targ->x_value == NULL) { xml_add_tag(&msg, XML_ELEMENT_TARG, "bogus entry"); continue; } if (xml_find_value_str(targ, XML_ELEMENT_INAME, &iname) == False) { xml_add_tag(&msg, XML_ELEMENT_TARG, "missing iscsi-name"); continue; } if (prop != NULL) { if (strcmp(prop, targ->x_value) == 0) { buf_add_tag(&msg, XML_ELEMENT_TARG, Tag_Start); buf_add_tag(&msg, targ->x_value, Tag_String); xml_add_tag(&msg, XML_ELEMENT_INAME, iname); if (luninfo == True) target_info(&msg, iname, targ); if (dostat == True) target_stat(&msg, iname, mgmt_full_phase_statistics); buf_add_tag(&msg, XML_ELEMENT_TARG, Tag_End); } } else { buf_add_tag(&msg, XML_ELEMENT_TARG, Tag_Start); buf_add_tag(&msg, targ->x_value, Tag_String); xml_add_tag(&msg, XML_ELEMENT_INAME, iname); if (dostat == True) target_stat(&msg, iname, mgmt_full_phase_statistics); if (luninfo == True) target_info(&msg, iname, targ); buf_add_tag(&msg, XML_ELEMENT_TARG, Tag_End); } free(iname); } buf_add_tag(&msg, XML_ELEMENT_RESULT, Tag_End); free(prop); return (msg); }
static void target_info(char **msg, char *targ_name, xml_node_t *tnode) { char path[MAXPATHLEN], lun_buf[16], *prop; xmlTextReaderPtr r; xml_node_t *lnode, /* list node */ *lnp, /* list node pointer */ *lun, *params; int xml_fd, lun_num; if ((lnode = xml_node_next(tnode, XML_ELEMENT_ACLLIST, NULL)) != NULL) { lnp = NULL; buf_add_tag(msg, XML_ELEMENT_ACLLIST, Tag_Start); while ((lnp = xml_node_next(lnode, XML_ELEMENT_INIT, lnp)) != NULL) xml_add_tag(msg, XML_ELEMENT_INIT, lnp->x_value); buf_add_tag(msg, XML_ELEMENT_ACLLIST, Tag_End); } if ((lnode = xml_node_next(tnode, XML_ELEMENT_TPGTLIST, NULL)) != NULL) { lnp = NULL; buf_add_tag(msg, XML_ELEMENT_TPGTLIST, Tag_Start); while ((lnp = xml_node_next(lnode, XML_ELEMENT_TPGT, lnp)) != NULL) xml_add_tag(msg, XML_ELEMENT_TPGT, lnp->x_value); buf_add_tag(msg, XML_ELEMENT_TPGTLIST, Tag_End); } if ((lnode = xml_node_next(tnode, XML_ELEMENT_ALIAS, NULL)) != NULL) xml_add_tag(msg, XML_ELEMENT_ALIAS, lnode->x_value); if ((lnode = xml_node_next(tnode, XML_ELEMENT_MAXRECV, NULL)) != NULL) xml_add_tag(msg, XML_ELEMENT_MAXRECV, lnode->x_value); if ((lnode = xml_node_next(tnode, XML_ELEMENT_LUNLIST, NULL)) == NULL) return; buf_add_tag(msg, XML_ELEMENT_LUNINFO, Tag_Start); lun = NULL; while ((lun = xml_node_next(lnode, XML_ELEMENT_LUN, lun)) != NULL) { if ((xml_find_value_int(lun, XML_ELEMENT_LUN, &lun_num)) == False) continue; (void) snprintf(path, sizeof (path), "%s/%s/%s%d", target_basedir, targ_name, PARAMBASE, lun_num); if ((xml_fd = open(path, O_RDONLY)) < 0) continue; if ((r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0)) == NULL) continue; params = NULL; while (xmlTextReaderRead(r) == 1) { if (xml_process_node(r, ¶ms) == False) break; } (void) close(xml_fd); xmlTextReaderClose(r); xmlFreeTextReader(r); buf_add_tag(msg, XML_ELEMENT_LUN, Tag_Start); snprintf(lun_buf, sizeof (lun_buf), "%d", lun_num); buf_add_tag(msg, lun_buf, Tag_String); if (xml_find_value_str(params, XML_ELEMENT_GUID, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_GUID, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_VID, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_VID, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_PID, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_PID, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_DTYPE, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_DTYPE, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_SIZE, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_SIZE, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_STATUS, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_STATUS, prop); free(prop); } if (xml_find_value_str(params, XML_ELEMENT_BACK, &prop) == True) { xml_add_tag(msg, XML_ELEMENT_BACK, prop); free(prop); } buf_add_tag(msg, XML_ELEMENT_LUN, Tag_End); xml_tree_free(params); } buf_add_tag(msg, XML_ELEMENT_LUNINFO, Tag_End); }
static int xml_add_sig (gnutls_string * xmlkey, int ext, cdk_pkt_signature_t sig) { const char *algo, *s; char tmp[32], keyid[16]; unsigned int kid[2]; int rc = 0; if (!xmlkey || !sig) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } s = " <SIGNATURE>\n"; _gnutls_string_append_str (xmlkey, s); sprintf (tmp, "%d", sig->version); rc = xml_add_tag (xmlkey, "VERSION", tmp); if (rc) return rc; if (ext) { sprintf (tmp, "%d", sig->sig_class); rc = xml_add_tag (xmlkey, "SIGCLASS", tmp); if (rc) return rc; } sprintf (tmp, "%d", sig->flags.expired); rc = xml_add_tag (xmlkey, "EXPIRED", tmp); if (rc) return rc; if (ext) { switch (sig->pubkey_algo) { case GCRY_PK_DSA: algo = "DSA"; break; case GCRY_PK_ELG: case GCRY_PK_ELG_E: algo = "ELG"; break; case GCRY_PK_RSA: case GCRY_PK_RSA_E: case GCRY_PK_RSA_S: algo = "RSA"; break; default: algo = "???"; /* unknown algorithm */ } rc = xml_add_tag (xmlkey, "PKALGO", algo); if (rc) return rc; switch (sig->digest_algo) { case GCRY_MD_SHA1: algo = "SHA1"; break; case GCRY_MD_RMD160: algo = "RMD160"; break; case GCRY_MD_MD5: algo = "MD5"; break; default: algo = "???"; } rc = xml_add_tag (xmlkey, "MDALGO", algo); if (rc) return rc; } sprintf (tmp, "%lu", sig->timestamp); rc = xml_add_tag (xmlkey, "CREATED", tmp); if (rc) return rc; cdk_sig_get_keyid (sig, kid); snprintf (keyid, 16, "%08lX%08lX", kid[0], kid[1]); rc = xml_add_tag (xmlkey, "KEYID", keyid); if (rc) return rc; s = " </SIGNATURE>\n"; _gnutls_string_append_str (xmlkey, s); return 0; }
static int xml_add_key (gnutls_string * xmlkey, int ext, cdk_pkt_pubkey_t pk, int sub) { const char *algo, *s; char keyid[16], fpr[41], tmp[32]; uint8_t fingerpr[20]; unsigned int kid[2]; int i = 0, rc = 0; if (!xmlkey || !pk) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } s = sub ? " <SUBKEY>\n" : " <MAINKEY>\n"; _gnutls_string_append_str (xmlkey, s); cdk_pk_get_keyid (pk, kid); snprintf (keyid, 16, "%08lX%08lX", kid[0], kid[1]); rc = xml_add_tag (xmlkey, "KEYID", keyid); if (rc) return rc; cdk_pk_get_fingerprint (pk, fingerpr); for (i = 0; i < 20; i++) sprintf (fpr + 2 * i, "%02X", fingerpr[i]); fpr[40] = '\0'; rc = xml_add_tag (xmlkey, "FINGERPRINT", fpr); if (rc) return rc; if (is_DSA (pk->pubkey_algo)) algo = "DSA"; else if (is_RSA (pk->pubkey_algo)) algo = "RSA"; else if (is_ELG (pk->pubkey_algo)) algo = "ELG"; else algo = "???"; rc = xml_add_tag (xmlkey, "PKALGO", algo); if (rc) return rc; sprintf (tmp, "%d", cdk_pk_get_nbits (pk)); rc = xml_add_tag (xmlkey, "KEYLEN", tmp); if (rc) return rc; sprintf (tmp, "%lu", pk->timestamp); rc = xml_add_tag (xmlkey, "CREATED", tmp); if (rc) return rc; if (pk->expiredate > 0) { sprintf (tmp, "%lu", (unsigned long) pk->expiredate); rc = xml_add_tag (xmlkey, "EXPIREDATE", tmp); if (rc) return rc; } sprintf (tmp, "%d", pk->is_revoked); rc = xml_add_tag (xmlkey, "REVOKED", tmp); if (rc) return rc; if (ext) { rc = xml_add_key_mpi (xmlkey, pk); if (rc) return rc; } s = sub ? " </SUBKEY>\n" : " </MAINKEY>\n"; _gnutls_string_append_str (xmlkey, s); return 0; }
/* * []---- * | sess_process -- handle messages from the connection(s) * []---- */ static void * sess_process(void *v) { iscsi_sess_t *s = (iscsi_sess_t *)v; iscsi_conn_t *c; iscsi_cmd_t *cmd; msg_t *m; Boolean_t process = True; mgmt_request_t *mgmt; name_request_t *nr; t10_cmd_t *t10_cmd; char **buf, local_buf[16]; int lun; extern void dataout_callback(t10_cmd_t *t, char *data, size_t *xfer); (void) pthread_mutex_lock(&s->s_mutex); s->s_state = SS_RUNNING; (void) pthread_mutex_unlock(&s->s_mutex); do { m = queue_message_get(s->s_sessq); switch (m->msg_type) { case msg_cmd_send: cmd = (iscsi_cmd_t *)m->msg_data; if (s->s_t10 == NULL) { /* * The value of 0x960 comes from T10. * See SPC-4, revision 1a, section 6.4.2, * table 87 * * XXX Need to rethink how I should do * the callback. */ s->s_t10 = t10_handle_create(s->s_t_name, T10_TRANS_ISCSI, s->s_conn_head->c_tpgt, s->s_conn_head->c_max_burst_len, s->s_t10q, dataout_callback); } if (t10_cmd_create(s->s_t10, cmd->c_lun, cmd->c_scb, cmd->c_scb_len, (transport_t)cmd, &t10_cmd) == False) { queue_prt(s->s_mgmtq, Q_SESS_ERRS, "SES%x FAILED to create cmd", s->s_num); /* * If the command create failed, the T10 layer * will attempt to create a sense buffer * telling the initiator what went wrong. If * that layer was unable to accomplish that * things are really bad and we need to just * close the connection. */ if (cmd->c_t10_cmd != NULL) { queue_message_set( cmd->c_allegiance->c_dataq, 0, msg_cmd_cmplt, t10_cmd); } else conn_state(cmd->c_allegiance, T11); } else { (void) pthread_mutex_lock( &cmd->c_allegiance->c_mutex); if (cmd->c_state != CmdCanceled) { cmd->c_t10_cmd = t10_cmd; (void) t10_cmd_send(s->s_t10, cmd->c_t10_cmd, cmd->c_data, cmd->c_data_len); } else { t10_cmd_state(t10_cmd, T10_Cmd_Event_Canceled); } (void) pthread_mutex_unlock( &cmd->c_allegiance->c_mutex); } break; case msg_cmd_data_out: cmd = (iscsi_cmd_t *)m->msg_data; if (s->s_t10 != NULL) (void) t10_cmd_data(s->s_t10, cmd->c_t10_cmd, cmd->c_offset_out, cmd->c_data, cmd->c_data_len); break; case msg_targ_inventory_change: if (s->s_t10 != NULL) (void) t10_task_mgmt(s->s_t10, InventoryChange, 0, 0); break; case msg_lu_capacity_change: lun = (int)(uintptr_t)m->msg_data; if (s->s_t10 != NULL) (void) t10_task_mgmt(s->s_t10, CapacityChange, lun, 0); break; case msg_reset_targ: if (s->s_t10 != NULL) (void) t10_task_mgmt(s->s_t10, ResetTarget, 0, 0); break; case msg_reset_lu: if (s->s_t10 != NULL) (void) t10_task_mgmt(s->s_t10, ResetLun, (int)(uintptr_t)m->msg_data, 0); break; case msg_shutdown: (void) pthread_mutex_lock(&s->s_mutex); s->s_state = SS_SHUTDOWN_START; (void) pthread_mutex_unlock(&s->s_mutex); /* * Shutdown rquest comming from a connection. Only * shutdown the STE if this is the last connection * for this session. */ c = (iscsi_conn_t *)m->msg_data; if (session_remove_connection(s, c) == True) { queue_prt(s->s_mgmtq, Q_SESS_NONIO, "SES%x Starting shutdown", s->s_num); /* * If this is the last connection for this * session send a message to the SAM-3 layer to * shutdown. */ if (s->s_t10 != NULL) { t10_handle_disable(s->s_t10); } queue_message_set(s->s_t10q, 0, msg_shutdown_rsp, 0); process = False; } else { /* * Since this isn't the last connection for * the session, acknowledge the connection * request now since it's references from * this session have been removed. */ queue_message_set(c->c_dataq, 0, msg_shutdown_rsp, (void *)False); } break; case msg_initiator_name: nr = (name_request_t *)m->msg_data; s->s_i_name = strdup(nr->nr_name); /* * Acknowledge the request by sending back an empty * message. */ queue_message_set(nr->nr_q, 0, msg_initiator_name, 0); break; case msg_initiator_alias: nr = (name_request_t *)m->msg_data; s->s_i_alias = strdup(nr->nr_name); /* * Acknowledge the request by sending back an empty * message. */ queue_message_set(nr->nr_q, 0, msg_initiator_alias, 0); break; case msg_target_name: nr = (name_request_t *)m->msg_data; s->s_t_name = strdup(nr->nr_name); /* * Acknowledge the request by sending back an empty * message. */ queue_message_set(nr->nr_q, 0, msg_target_name, 0); break; case msg_mgmt_rqst: mgmt = (mgmt_request_t *)m->msg_data; m->msg_data = NULL; (void) pthread_mutex_lock(&mgmt->m_resp_mutex); buf = mgmt->m_u.m_resp; if ((s->s_type == SessionNormal) && (mgmt->m_request == mgmt_full_phase_statistics) && (strcmp(s->s_t_name, mgmt->m_targ_name) == 0)) { buf_add_tag(buf, XML_ELEMENT_CONN, Tag_Start); buf_add_tag(buf, s->s_i_name, Tag_String); if (s->s_i_alias != NULL) { xml_add_tag(buf, XML_ELEMENT_ALIAS, s->s_i_alias); } /* * Need to loop through the connections * and create one time_connected tag for * each. This will be needed once MC/S support * is added. */ (void) snprintf(local_buf, sizeof (local_buf), "%d", mgmt->m_time - s->s_conn_head->c_up_at); xml_add_tag(buf, XML_ELEMENT_TIMECON, local_buf); buf_add_tag(buf, XML_ELEMENT_STATS, Tag_Start); t10_targ_stat(s->s_t10, buf); buf_add_tag(buf, XML_ELEMENT_STATS, Tag_End); buf_add_tag(buf, XML_ELEMENT_CONN, Tag_End); } (void) pthread_mutex_unlock(&mgmt->m_resp_mutex); queue_message_set(mgmt->m_q, 0, msg_mgmt_rply, 0); break; default: queue_prt(s->s_mgmtq, Q_SESS_ERRS, "SES%x Unknown msg type (%d) from Connection", s->s_num, m->msg_type); break; } queue_message_free(m); } while (process == True); return (NULL); }