int login(T_Connect *conn,T_NetHead *NetHead) { int ret,crc; char tmp[200]; char *cp,*key; char tmp1[1024],cliaddr[20]; DWS dw; struct login_s logrec; ENIGMA egm; FILE *fd; T_SRV_Var *up; GDA *gp; //u_int e[RSALEN],m[RSALEN]; up=(T_SRV_Var *)conn->Var; gp=(GDA *)up->var; StrAddr(NetHead->O_NODE,cliaddr); ShowLog(5,"%s:TCB:%d Client IP Addr=%s,Net_login %s",__FUNCTION__,up->TCB_no,cliaddr,NetHead->data); net_dispack(&logrec,NetHead->data,login_type); strcpy(gp->devid,logrec.devid); sprintf(gp->ShowID,"%s:%s:%d",logrec.devid,cliaddr,up->TCB_no); mthr_showid_add(up->tid,gp->ShowID); conn->MTU=NetHead->ERRNO1; cp=getenv("KEYFILE"); if(!cp||!*cp) { strcpy(tmp1,"缺少环境变量 KEYFILE"); errret: ShowLog(1,"%s:Error %s",__FUNCTION__,tmp1); NetHead->ERRNO1=-1; NetHead->ERRNO2=-1; NetHead->PKG_REC_NUM=0; NetHead->data=tmp1; NetHead->PKG_LEN=strlen(NetHead->data); SendPack(conn,NetHead); return 0; // fail } /* read key */ crc=0; reopen: ret=initdw(cp,&dw); if(ret) { if((errno==24)&& (++crc<5)) { sleep(15); goto reopen; } sprintf(tmp1,"Init dw error %d",ret); goto errret; } crc=ssh_crc32((unsigned char *)logrec.devid,strlen(logrec.devid)); key=getdw(crc,&dw); if(!key) { freedw(&dw); sprintf(tmp1,"无效的 DEVID"); goto errret; } //ShowLog(5,"getdw key=%s",key); enigma1_init(egm,key); /* check CA */ memset(gp->operid,0,sizeof(gp->operid)); cp=getenv("CADIR"); if(!cp||!*cp) cp="."; if(strcmp(gp->devid,"REGISTER")) { strncpy(gp->operid,logrec.uid,sizeof(gp->operid)-1); sprintf(tmp,"%s/%s.CA",cp,logrec.devid); //ShowLog(5,"CAfile=%s,key=%s",tmp,key); fd=fopen(tmp,"r"); if(!fd) { if(errno==2) { crc=strlen(logrec.CA); frenz_encode(egm,logrec.CA,crc); byte_a64(tmp1,logrec.CA,crc); //ShowLog(5,"CA=%s",tmp1); fd=fopen(tmp,"w"); if(!fd) { sprintf(tmp1,"write %s err=%d",tmp,errno); err1: freedw(&dw); goto errret; } fprintf(fd,"%s\n",tmp1); fclose(fd); } else { sprintf(tmp1,"open CAfile %s err=%d",tmp,errno); goto err1; } } else { fgets(tmp1,sizeof(logrec.CA),fd); fclose(fd); TRIM(tmp1); ret=a64_byte(tmp,tmp1); frenz_decode(egm,tmp,ret); tmp[ret]=0; if(strcmp(tmp,logrec.CA)) { sprintf(tmp1,"CA 错误"); ShowLog(1,"%s:%s CA=%s log=%s len=%d",__FUNCTION__,tmp1,tmp,logrec.CA,ret); goto err1; } } } else { //未注册客户端注册 char *p; char *keyD; /* REGISTER label|CA|devfile|CHK_Code| */ ShowLog(2,"REGISTER %s",logrec.uid); if(!*logrec.uid) { sprintf(tmp1,"REGSTER is empty!"); goto err1; } //uid=devfile crc=0xFFFF&gencrc((unsigned char *)logrec.uid,strlen(logrec.uid)); //pwd=CHK_Code sscanf(logrec.pwd,"%04X",&ret); ret &= 0xFFFF; if(ret != crc) { sprintf(tmp1,"REGISTER:devfile CHK Code error! ");//, crc,ret); goto err1; } p=stptok(logrec.uid,logrec.devid,sizeof(logrec.devid),".");//logrec.devid=准备注册的DEVID crc=ssh_crc32((unsigned char *)logrec.devid,strlen(logrec.devid)); keyD=getdw(crc,&dw); if(!keyD) { sprintf(tmp1,"注册失败,%s:没有这个设备!", logrec.devid); goto err1; } enigma1_init(egm,keyD); sprintf(tmp,"%s/%s.CA",cp,logrec.devid); ShowLog(5,"REGISTER:%s",tmp); if(0!=(fd=fopen(tmp,"r"))) { fgets(tmp1,81,fd); fclose(fd); TRIM(tmp1); ret=a64_byte(tmp,tmp1); frenz_decode(egm,tmp,ret); tmp[ret]=0; if(strcmp(tmp,logrec.CA)) { sprintf(tmp1,"注册失败,%s 已被注册,使用中。", logrec.devid); goto err1; } } else if(errno != 2) { sprintf(tmp1,"CA 错误"); goto err1; } /*把设备特征码写入文件*/ fd=fopen(tmp,"w"); if(fd) { int len=strlen(logrec.CA); frenz_encode(egm,logrec.CA,len); byte_a64(tmp1,logrec.CA,len); fprintf(fd,"%s\n",tmp1); fclose(fd); } else ShowLog(1,"net_login:REGISTER open %s for write,err=%d,%s", tmp,errno,strerror(errno)); freedw(&dw); sprintf(tmp,"%s/%s",cp,logrec.uid); fd=fopen(tmp,"r"); if(!fd) { sprintf(tmp1,"REGISTER 打不开文件 %s err=%d,%s", logrec.CA,errno,strerror(errno)); goto errret; } fgets(logrec.uid,sizeof(logrec.uid),fd); TRIM(logrec.uid); ShowLog(2,"REGISTER open %s",tmp); fclose(fd); cp=tmp1; cp+=sprintf(cp,"%s|%s|", logrec.devid,logrec.uid); cp+=sprintf(cp,"%s|",rsecstrfmt(tmp,now_sec(),YEAR_TO_SEC)); NetHead->data=tmp1; NetHead->PKG_LEN=strlen(NetHead->data); NetHead->ERRNO1=0; NetHead->ERRNO2=0; NetHead->PKG_REC_NUM=0; SendPack(conn,NetHead); return -1; } //未注册客户端注册完成 freedw(&dw); up->poolno=get_scpool_no(NetHead->D_NODE); if(up->poolno<0) { sprintf(tmp1,"非法的D_NODE %d",NetHead->D_NODE); goto errret; } ret=get_s_connect(up->TCB_no,up->poolno,&gp->server,login_finish); if(ret==0) return login_finish(conn,NetHead); else if(ret==1) return -5; sprintf(tmp1,"错误的参数"); goto errret; }
static void cmnd_exec_login(struct connection *conn) { struct iscsi_login_req_hdr *req = (struct iscsi_login_req_hdr *)&conn->req.bhs; struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs; int stay = 0, nsg_disagree = 0; memset(rsp, 0, BHS_SIZE); if ((req->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_LOGIN_CMD || !(req->opcode & ISCSI_OP_IMMEDIATE)) { //reject } rsp->opcode = ISCSI_OP_LOGIN_RSP; rsp->max_version = ISCSI_VERSION; rsp->active_version = ISCSI_VERSION; rsp->itt = req->itt; if (/*req->max_version < ISCSI_VERSION ||*/ req->min_version > ISCSI_VERSION) { rsp->status_class = ISCSI_STATUS_INITIATOR_ERR; rsp->status_detail = ISCSI_STATUS_NO_VERSION; conn->state = STATE_EXIT; return; } switch (req->flags & ISCSI_FLG_CSG_MASK) { case ISCSI_FLG_CSG_SECURITY: log_debug(1, "Login request (security negotiation): %d", conn->state); rsp->flags = ISCSI_FLG_CSG_SECURITY; switch (conn->state) { case STATE_FREE: conn->state = STATE_SECURITY; login_start(conn); if (rsp->status_class) return; //else fall through case STATE_SECURITY: text_scan_security(conn); if (rsp->status_class) return; if (conn->auth_method != AUTH_NONE) { conn->state = STATE_SECURITY_AUTH; conn->auth_state = AUTH_STATE_START; } break; case STATE_SECURITY_AUTH: switch (cmnd_exec_auth(conn)) { case 0: break; default: case -1: goto init_err; case -2: goto auth_err; } break; default: goto init_err; } break; case ISCSI_FLG_CSG_LOGIN: log_debug(1, "Login request (operational negotiation): %d", conn->state); rsp->flags = ISCSI_FLG_CSG_LOGIN; switch (conn->state) { case STATE_FREE: conn->state = STATE_LOGIN; login_start(conn); if (!account_empty(conn->tid, AUTH_DIR_INCOMING)) goto auth_err; if (rsp->status_class) return; text_scan_login(conn); if (rsp->status_class) return; stay = text_check_param(conn); break; case STATE_LOGIN: text_scan_login(conn); if (rsp->status_class) return; stay = text_check_param(conn); break; default: goto init_err; } break; default: goto init_err; } if (rsp->status_class) return; if (conn->state != STATE_SECURITY_AUTH && req->flags & ISCSI_FLG_TRANSIT) { int nsg = req->flags & ISCSI_FLG_NSG_MASK; switch (nsg) { case ISCSI_FLG_NSG_LOGIN: switch (conn->state) { case STATE_SECURITY: case STATE_SECURITY_DONE: conn->state = STATE_SECURITY_LOGIN; login_security_done(conn); break; default: goto init_err; } break; case ISCSI_FLG_NSG_FULL_FEATURE: switch (conn->state) { case STATE_SECURITY: case STATE_SECURITY_DONE: if ((nsg_disagree = text_check_param(conn))) { conn->state = STATE_LOGIN; nsg = ISCSI_FLG_NSG_LOGIN; break; } conn->state = STATE_SECURITY_FULL; login_security_done(conn); break; case STATE_LOGIN: if (stay) nsg = ISCSI_FLG_NSG_LOGIN; else conn->state = STATE_LOGIN_FULL; break; default: goto init_err; } if (!stay && !nsg_disagree) { text_check_param(conn); login_finish(conn); } break; default: goto init_err; } rsp->flags |= nsg | (stay ? 0 : ISCSI_FLG_TRANSIT); } rsp->sid = conn->sid; rsp->stat_sn = cpu_to_be32(conn->stat_sn++); rsp->exp_cmd_sn = cpu_to_be32(conn->exp_cmd_sn); conn->max_cmd_sn = conn->exp_cmd_sn + 1; rsp->max_cmd_sn = cpu_to_be32(conn->max_cmd_sn); return; init_err: rsp->flags = 0; rsp->status_class = ISCSI_STATUS_INITIATOR_ERR; rsp->status_detail = ISCSI_STATUS_INIT_ERR; conn->state = STATE_EXIT; return; auth_err: rsp->flags = 0; rsp->status_class = ISCSI_STATUS_INITIATOR_ERR; rsp->status_detail = ISCSI_STATUS_AUTH_FAILED; conn->state = STATE_EXIT; return; }