/* не забываем, что cash_request_OUT_front проверяет формат amount, * можно ли делать запрос указанному юзеру, есть ли у юзера * обещанные суммы на сумму amount, есть ли нужное кол-во DC у отправителя, * является ли отправитель майнером * * */ func (p *Parser) CashRequestInFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // code может быть чем угодно, т.к. отправитель шлет в сеть лишь хэш // нигде, кроме cash_request_in_front, code не используется // if ( !check_input_data ($this->tx_data['code'], 'cash_code') ) // return 'cash_request_in_front code'; verifyData := map[string]string{"cash_request_id": "bigint"} err = p.CheckInputData(verifyData) if err != nil { return p.ErrInfo(err) } var to_user_id, cTime int64 var status string var hash_code []byte err = p.QueryRow(p.FormatQuery("SELECT to_user_id, status, hash_code, time FROM cash_requests WHERE id = ?"), p.TxMaps.Int64["cash_request_id"]).Scan(&to_user_id, &status, &hash_code, &cTime) if err != nil && err != sql.ErrNoRows { return p.ErrInfo(err) } // ID cash_requests юзер указал сам, значит это может быть случайное число. // проверим, является получателем наш юзер if to_user_id != p.TxUserID { return p.ErrInfo("to_user_id!=user_id") } // должно быть pending if status != "pending" { return p.ErrInfo("status!=pending") } // проверим код if !bytes.Equal(utils.DSha256(p.TxMaps.String["code"]), utils.BinToHex(hash_code)) { return p.ErrInfo("code!=hash_code") } var txTime int64 if p.BlockData != nil { // тр-ия пришла в блоке txTime = p.BlockData.Time } else { txTime = time.Now().Unix() // просто на всякий случай небольшой запас } // запрос может быть принят, только если он был отправлен не позднее чем через cash_request_time сек назад if cTime < txTime-p.Variables.Int64["cash_request_time"] { return p.ErrInfo(fmt.Sprintf("%d < %d - %d", cTime, txTime, p.Variables.Int64["cash_request_time"])) } forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["cash_request_id"], p.TxMap["code"]) CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } return nil }
func (c *Controller) ESignUp() (string, error) { c.r.ParseForm() email := c.r.FormValue("email") password := c.r.FormValue("password") if len(password) > 50 || len(password) < 1 { return "", errors.New(c.Lang["invalid_pass"]) } existsEmail, err := c.Single("SELECT id FROM e_users WHERE email = ?", email).Int64() if err != nil { return "", utils.ErrInfo(err) } if existsEmail > 0 { return "", errors.New(c.Lang["exists_email"]) } salt := utils.RandSeq(32) passAndSalt := utils.DSha256(password + salt) userId, err := c.ExecSqlGetLastInsertId("INSERT INTO e_users ( email, password, ip, salt ) VALUES ( ?, ?, ?, ? )", "id", email, passAndSalt, c.r.RemoteAddr, salt) if err != nil { return "", utils.ErrInfo(err) } c.sess.Set("e_user_id", userId) return utils.JsonAnswer("success", "success").String(), nil }
func (c *Controller) Login() (string, error) { var pool_tech_works int funcMap := template.FuncMap{ "noescape": func(s string) template.HTML { return template.HTML(s) }, } data, err := static.Asset("static/templates/login.html") if err != nil { return "", err } modal, err := static.Asset("static/templates/modal.html") if err != nil { return "", err } t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data))) t = template.Must(t.Parse(string(modal))) b := new(bytes.Buffer) // есть ли установочный пароль и был ли начально записан ключ var setupPassword bool if !c.Community { setupPassword_, err := c.Single("SELECT setup_password FROM config").String() if err != nil { return "", err } myKey, err := c.GetMyPublicKey(c.MyPrefix) if err != nil { return "", err } if len(myKey) == 0 && (len(setupPassword_) > 0 || setupPassword_ == string(utils.DSha256(""))) { setupPassword = true } } //fmt.Println(c.Lang) // проверим, не идут ли тех. работы на пуле if len(c.NodeConfig["pool_admin_user_id"]) > 0 && c.NodeConfig["pool_admin_user_id"] != utils.Int64ToStr(c.UserId) && c.NodeConfig["pool_tech_works"] == "1" && c.Community { pool_tech_works = 1 } else { pool_tech_works = 0 } err = t.ExecuteTemplate(b, "login", &loginStruct{ Lang: c.Lang, MyModalIdName: "myModalLogin", UserID: c.UserId, PoolTechWorks: pool_tech_works, SetupPassword: setupPassword, Community: c.Community, Desktop: utils.Desktop(), Mobile: utils.Mobile()}) if err != nil { return "", err } return b.String(), nil }
func (c *Controller) BlockExplorer() (string, error) { var err error blockId := int64(utils.StrToFloat64(c.Parameters["blockId"])) start := int64(utils.StrToFloat64(c.Parameters["start"])) var data, sql string if start > 0 || (start == 0 && blockId == 0) { if start == 0 && blockId == 0 { data += "<h3>Latest Blocks</h3>" sql = ` SELECT data, hash FROM block_chain ORDER BY id DESC LIMIT 15` } else { sql = ` SELECT data, hash FROM block_chain ORDER BY id ASC LIMIT ` + utils.Int64ToStr(start-1) + `, 100` } data += `<table class="table"><tr><th>Block</th><th>Hash</th><th>Time</th><th><nobr>User id</nobr></th><th><nobr>Miner id</nobr></th><th>Level</th><th>Transactions</th></tr>` blocksChain, err := c.GetAll(sql, -1) if err != nil { return "", utils.ErrInfo(err) } for _, blockData := range blocksChain { hash := utils.BinToHex([]byte(blockData["hash"])) binaryData := []byte(blockData["data"]) parser := new(dcparser.Parser) parser.DCDB = c.DCDB parser.BinaryData = binaryData err = parser.ParseDataLite() parser.BlockData.Sign = utils.BinToHex(parser.BlockData.Sign) minerId, err := c.GetMinerId(parser.BlockData.UserId) if err != nil { return "", utils.ErrInfo(err) } data += fmt.Sprintf(`<tr><td><a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">%d</a></td><td>%s</td><td><nobr><span class='unixtime'>%d</span></nobr></td><td>%d</td><td>%d</td><td>%d</td><td>`, parser.BlockData.BlockId, parser.BlockData.BlockId, hash, parser.BlockData.Time, parser.BlockData.UserId, minerId, parser.BlockData.Level) data += utils.IntToStr(len(parser.TxMapArr)) data += "</td></tr>" } data += "</table>" } else if blockId > 0 { data += `<table class="table">` blockChain, err := c.OneRow("SELECT data, hash, cur_0l_miner_id, max_miner_id FROM block_chain WHERE id = ?", blockId).String() if err != nil { return "", utils.ErrInfo(err) } binToHexArray := []string{"sign", "public_key", "encrypted_message", "comment", "bin_public_keys"} hash := utils.BinToHex([]byte(blockChain["hash"])) binaryData := blockChain["data"] parser := new(dcparser.Parser) parser.DCDB = c.DCDB parser.BinaryData = []byte(binaryData) err = parser.ParseDataLite() if err != nil { return "", utils.ErrInfo(err) } parser.BlockData.Sign = utils.BinToHex(parser.BlockData.Sign) previous := parser.BlockData.BlockId - 1 next := parser.BlockData.BlockId + 1 levelsRange := utils.GetBlockGeneratorMinerIdRange(utils.StrToInt64(blockChain["cur_0l_miner_id"]), utils.StrToInt64(blockChain["max_miner_id"])) minerId, err := c.GetMinerId(parser.BlockData.UserId) if err != nil { return "", utils.ErrInfo(err) } _, _, _, CurrentUserId, _, _, _ := c.TestBlock() maxMinerId, err := c.Single("SELECT max(miner_id) FROM miners").Int64() if err != nil { return "", utils.ErrInfo(err) } currentMinerId, err := c.Single("SELECT miner_id FROM miners_data WHERE user_id = ?", CurrentUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } NextBlockLevelsRange := utils.GetBlockGeneratorMinerIdRange(currentMinerId, maxMinerId) data += fmt.Sprintf(`<tr><td><strong>Raw data</strong></td><td><a href='ajax?controllerName=getBlock&id=%d&download=1' target='_blank'>Download</a></td></tr>`, parser.BlockData.BlockId) data += fmt.Sprintf(`<tr><td><strong>Block_id</strong></td><td>%d (<a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">Previous</a> / <a href="#" onclick="dc_navigate('blockExplorer', {'blockId':%d})">Next</a> )</td></tr>`, parser.BlockData.BlockId, previous, next) data += fmt.Sprintf(`<tr><td><strong>Hash</strong></td><td>%s</td></tr>`, hash) data += fmt.Sprintf(`<tr><td><strong>Time</strong></td><td><span class='unixtime'>%d</span> / %d</td></tr>`, parser.BlockData.Time, parser.BlockData.Time) data += fmt.Sprintf(`<tr><td><strong>User_id</strong></td><td>%d</td></tr>`, parser.BlockData.UserId) data += fmt.Sprintf(`<tr><td><strong>Miner_Id</strong></td><td>%d</td></tr>`, minerId) data += fmt.Sprintf(`<tr><td><strong>Level</strong></td><td>%d (%v) next: %v</td></tr>`, parser.BlockData.Level, levelsRange, NextBlockLevelsRange) data += fmt.Sprintf(`<tr><td><strong>Sign</strong></td><td>%s</td></tr>`, parser.BlockData.Sign) if len(parser.TxMapArr) > 0 { data += `<tr><td><strong>Transactions</strong></td><td><div><pre style='width: 700px'>` for i := 0; i < len(parser.TxMapArr); i++ { for k, data_ := range parser.TxMapArr[i] { if utils.InSliceString(k, binToHexArray) { parser.TxMapArr[i][k] = utils.BinToHex(data_) } if k == "file" { parser.TxMapArr[i][k] = []byte("file size: " + utils.IntToStr(len(data_))) } else if k == "code" { parser.TxMapArr[i][k] = utils.DSha256(data_) } else if k == "secret" { parser.TxMapArr[i][k] = utils.BinToHex(data_) } data += fmt.Sprintf("%v : %s\n", k, parser.TxMapArr[i][k]) } data += "\n\n" } data += "</pre></div></td></tr>" } data += "</table>" } // пока панель тут myNotice := make(map[string]string) if c.SessUserId > 0 { myNotice, err = c.GetMyNoticeData(c.SessUserId, c.SessUserId, c.MyPrefix, c.Lang) if err != nil { return "", utils.ErrInfo(err) } } TemplateStr, err := makeTemplate("block_explorer", "blockExplorer", &BlockExplorerPage{ Lang: c.Lang, CurrencyList: c.CurrencyListCf, MyNotice: myNotice, Data: data, Start: start, BlockId: blockId, PoolAdmin: c.PoolAdmin, SessRestricted: c.SessRestricted, UserId: c.SessUserId}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func NodeVoting(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "NodeVoting" d := new(daemon) d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } d.goRoutineName = GoroutineName d.chAnswer = chAnswer d.chBreaker = chBreaker if utils.Mobile() { d.sleepTime = 3600 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } err = d.notMinerSetSleepTime(1800) if err != nil { log.Error("%v", err) return } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } err, restart := d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } // берем данные, которые находятся на голосовании нодов rows, err := d.Query(d.FormatQuery(` SELECT miners_data.user_id, http_host as host, face_hash, profile_hash, photo_block_id, photo_max_miner_id, miners_keepers, id as vote_id, miner_id FROM votes_miners LEFT JOIN miners_data ON votes_miners.user_id = miners_data.user_id WHERE cron_checked_time < ? AND votes_end = 0 AND type = 'node_voting' `), utils.Time()-consts.CRON_CHECKED_TIME_SEC) if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if ok := rows.Next(); ok { var vote_id, miner_id int64 var user_id, host, row_face_hash, row_profile_hash, photo_block_id, photo_max_miner_id, miners_keepers string err = rows.Scan(&user_id, &host, &row_face_hash, &row_profile_hash, &photo_block_id, &photo_max_miner_id, &miners_keepers, &vote_id, &miner_id) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // проверим, не нужно нам выйти, т.к. обновилась версия софта if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { rows.Close() utils.Sleep(1) break } minersIds := utils.GetMinersKeepers(photo_block_id, photo_max_miner_id, miners_keepers, true) myUsersIds, err := d.GetMyUsersIds(true, true) myMinersIds, err := d.GetMyMinersIds(myUsersIds) // нет ли нас среди тех, кто должен скачать фото к себе и проголосовать var intersectMyMiners []int64 for _, id := range minersIds { if utils.InSliceInt64(int64(id), myMinersIds) { intersectMyMiners = append(intersectMyMiners, int64(id)) } } var vote int64 if len(intersectMyMiners) > 0 { var downloadError bool var faceHash, profileHash string var faceFile, profileFile []byte // копируем фото к себе profilePath := *utils.Dir + "/public/profile_" + user_id + ".jpg" _, err = utils.DownloadToFile(host+"/public/"+user_id+"_user_profile.jpg", profilePath, 60, chBreaker, chAnswer, GoroutineName) if err != nil { log.Error("%s", utils.ErrInfo(err)) downloadError = true } facePath := *utils.Dir + "/public/face_" + user_id + ".jpg" _, err = utils.DownloadToFile(host+"/public/"+user_id+"_user_face.jpg", facePath, 60, chBreaker, chAnswer, GoroutineName) if err != nil { log.Error("%s", utils.ErrInfo(err)) downloadError = true } if !downloadError { // хэши скопированных фото profileFile, err = ioutil.ReadFile(profilePath) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } profileHash = string(utils.DSha256(profileFile)) log.Info("%v", "profileHash", profileHash) faceFile, err = ioutil.ReadFile(facePath) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } faceHash = string(utils.DSha256(faceFile)) log.Info("%v", "faceHash", faceHash) } // проверяем хэш. Если сходится, то голосуем за, если нет - против и размер не должен быть более 200 Kb. if profileHash == row_profile_hash && faceHash == row_face_hash && len(profileFile) < 204800 && len(faceFile) < 204800 { vote = 1 } else { log.Error("%s %s %s %s %d %d", profileHash, row_face_hash, faceHash, row_profile_hash, len(profileFile), len(faceFile)) vote = 0 // если хэш не сходится, то удаляем только что скаченное фото os.Remove(profilePath) os.Remove(facePath) } // проходимся по всем нашим майнерам, если это пул и по одному, если это сингл-мод for _, myMinerId := range intersectMyMiners { myUserId, err := d.Single("SELECT user_id FROM miners_data WHERE miner_id = ?", myMinerId).Int64() if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } curTime := utils.Time() forSign := fmt.Sprintf("%v,%v,%v,%v,%v", utils.TypeInt("VotesNodeNewMiner"), curTime, myUserId, vote_id, vote) binSign, err := d.GetBinSign(forSign, myUserId) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } data := utils.DecToBin(utils.TypeInt("VotesNodeNewMiner"), 1) data = append(data, utils.DecToBin(curTime, 4)...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(vote_id))...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(vote))...) data = append(data, utils.EncodeLengthPlusData([]byte(binSign))...) err = d.InsertReplaceTxInQueue(data) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } } // отмечаем, чтобы больше не брать эту строку err = d.ExecSql("UPDATE votes_miners SET cron_checked_time = ? WHERE id = ?", utils.Time(), vote_id) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } rows.Close() d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
func (c *Controller) CheckSetupPassword() (string, error) { c.r.ParseForm() password, err := c.Single(`SELECT setup_password FROM config WHERE setup_password = ?`, utils.DSha256(c.r.FormValue("password"))).String() if err != nil { return "", err } if len(password) > 0 && !c.Community { userId, err := c.GetMyUserId("") if err != nil { return "", err } publicKey, err := c.GetUserPublicKey(userId) if err != nil { return "", err } c.sess.Set("user_id", userId) c.sess.Set("public_key", string(utils.BinToHex(publicKey))) log.Debug("public_key check: %s", string(utils.BinToHex(publicKey))) return "ok", nil } return "", nil }
func (t *TcpServer) Type11() { /* Получаем данные от send_to_pool */ log.Debug("Type11") // размер данных buf := make([]byte, 4) _, err := t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %d", size) if size < 32<<20 { // сами данные log.Debug("read data") binaryData := make([]byte, size) //binaryData, err = ioutil.ReadAll(t.Conn) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } //log.Debug("binaryData %x", binaryData) userId := utils.BinToDec(utils.BytesShift(&binaryData, 5)) log.Debug("userId %d", userId) // проверим, есть ли такой юзер на пуле inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64() if inPool <= 0 { log.Error("%v", utils.ErrInfo("inPool<=0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } log.Debug("inPool %d", inPool) filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)) log.Debug("filesSign %x", filesSign) forSign := "" var files []string for i := 0; i < 3; i++ { size := utils.DecodeLength(&binaryData) log.Debug("size %d", size) data := utils.BytesShift(&binaryData, size) //log.Debug("data %x", data) fileType := utils.BinToDec(utils.BytesShift(&data, 1)) log.Debug("fileType %d", fileType) var name string switch fileType { case 0: name = utils.Int64ToStr(userId) + "_user_face.jpg" case 1: name = utils.Int64ToStr(userId) + "_user_profile.jpg" case 2: name = utils.Int64ToStr(userId) + "_user_video.mp4" /*case 3: name = utils.Int64ToStr(userId)+"_user_video.webm" case 4: name = utils.Int64ToStr(userId)+"_user_video.ogv"*/ } forSign = forSign + string(utils.DSha256((data))) + "," log.Debug("forSign %s", forSign) err = ioutil.WriteFile(os.TempDir()+"/"+name, data, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } files = append(files, name) log.Debug("files %d", files) if len(binaryData) == 0 { break } } if len(forSign) == 0 { log.Error("%v", utils.ErrInfo("len(forSign) == 0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if len(files) == 3 { forSign = forSign[:len(forSign)-1] } // проверим подпись publicKey, err := t.GetUserPublicKey(userId) resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true) if err != nil { log.Error("%v", utils.ErrInfo(err)) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if resultCheckSign { for i := 0; i < len(files); i++ { utils.CopyFileContents(os.TempDir()+"/"+files[i], *utils.Dir+"/public/"+files[i]) } } else { for i := 0; i < len(files); i++ { os.Remove(os.TempDir() + "/" + files[i]) } } // и возвращаем статус _, err = t.Conn.Write(utils.DecToBin(1, 1)) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } } else { log.Error("%v", utils.ErrInfo("size>32mb")) } }
func (c *Controller) UploadVideo() (string, error) { if c.SessRestricted != 0 { return "", utils.ErrInfo(errors.New("Permission denied")) } var binaryVideo []byte c.r.ParseMultipartForm(32 << 20) file, _, err := c.r.FormFile("file") if err != nil { return "", utils.ErrInfo(err) } videoBuffer := new(bytes.Buffer) _, err = io.Copy(videoBuffer, file) if err != nil { return "", utils.ErrInfo(err) } defer file.Close() binaryVideo = videoBuffer.Bytes() fmt.Println(c.r.MultipartForm.File["file"][0].Filename) fmt.Println(c.r.MultipartForm.File["file"][0].Header.Get("Content-Type")) fmt.Println(c.r.MultipartForm.Value["type"][0]) var contentType, videoType string if _, ok := c.r.MultipartForm.File["file"]; ok { contentType = c.r.MultipartForm.File["file"][0].Header.Get("Content-Type") } if _, ok := c.r.MultipartForm.Value["type"]; ok { videoType = c.r.MultipartForm.Value["type"][0] } end := "mp4" switch contentType { case "video/mp4", "video/quicktime": end = "mp4" case "video/ogg": end = "ogv" case "video/webm": end = "webm" case "video/3gpp": fmt.Println("3gpp") conn, err := net.DialTimeout("tcp", "3gp.dcoin.club:8099", 5*time.Second) if err != nil { return "", utils.ErrInfo(err) } defer conn.Close() conn.SetReadDeadline(time.Now().Add(240 * time.Second)) conn.SetWriteDeadline(time.Now().Add(240 * time.Second)) // в 4-х байтах пишем размер данных, которые пошлем далее size := utils.DecToBin(len(videoBuffer.Bytes()), 4) _, err = conn.Write(size) if err != nil { return "", utils.ErrInfo(err) } // далее шлем сами данные _, err = conn.Write(videoBuffer.Bytes()) if err != nil { return "", utils.ErrInfo(err) } // в ответ получаем размер данных, которые нам хочет передать сервер buf := make([]byte, 4) n, err := conn.Read(buf) if err != nil { return "", utils.ErrInfo(err) } log.Debug("dataSize buf: %x / get: %v", buf, n) // и если данных менее 10мб, то получаем их dataSize := utils.BinToDec(buf) var binaryBlock []byte log.Debug("dataSize: %v", dataSize) if dataSize < 10485760 && dataSize > 0 { binaryBlock = make([]byte, dataSize) //binaryBlock, err = ioutil.ReadAll(conn) _, err = io.ReadFull(conn, binaryBlock) if err != nil { return "", utils.ErrInfo(err) } log.Debug("len(binaryBlock):", len(binaryBlock)) binaryVideo = binaryBlock } } log.Debug(videoType, end) var name string if videoType == "user_video" { name = "public/" + utils.Int64ToStr(c.SessUserId) + "_user_video." + end } else { x := strings.Split(videoType, "-") if len(x) < 2 { if err != nil { return "", utils.ErrInfo(err) } } name = "public/" + utils.Int64ToStr(c.SessUserId) + "_promised_amount_" + x[1] + "." + end } log.Debug(*utils.Dir + "/" + name) err = ioutil.WriteFile(*utils.Dir+"/"+name, binaryVideo, 0644) if err != nil { return "", utils.ErrInfo(err) } return utils.JsonAnswer(string(utils.DSha256(binaryVideo)), "success").String(), nil }
// Шаг 1 - выбор либо стандартных настроек (sqlite и блокчейн с сервера) либо расширенных - pg/mysql и загрузка с нодов func (c *Controller) InstallStep1() (string, error) { c.r.ParseForm() installType := c.r.FormValue("type") url := c.r.FormValue("url") setupPassword := c.r.FormValue("setup_password") userId := utils.StrToInt64(c.r.FormValue("user_id")) firstLoad := c.r.FormValue("first_load") dbType := c.r.FormValue("db_type") dbHost := c.r.FormValue("host") dbPort := c.r.FormValue("port") dbName := c.r.FormValue("db_name") dbUsername := c.r.FormValue("username") dbPassword := c.r.FormValue("password") sqliteDbUrl := c.r.FormValue("sqlite_db_url") keyPassword := c.r.FormValue("key_password") if installType == "standard" { dbType = "sqlite" } else { if len(url) == 0 { url = consts.BLOCKCHAIN_URL } } if _, err := os.Stat(*utils.Dir + "/config.ini"); os.IsNotExist(err) { ioutil.WriteFile(*utils.Dir+"/config.ini", []byte(``), 0644) } confIni, err := config.NewConfig("ini", *utils.Dir+"/config.ini") //confIni.Set("sql_log", "1") confIni.Set("error_log", "1") confIni.Set("log_level", "DEBUG") confIni.Set("log", "0") confIni.Set("log_block_id_begin", "0") confIni.Set("log_block_id_end", "0") confIni.Set("bad_tx_log", "1") confIni.Set("nodes_ban_exit", "0") confIni.Set("log_tables", "") confIni.Set("log_fns", "") confIni.Set("sign_hash", "ip") if len(sqliteDbUrl) > 0 && dbType == "sqlite" { utils.SqliteDbUrl = sqliteDbUrl } if dbType == "sqlite" { confIni.Set("db_type", "sqlite") confIni.Set("db_user", "") confIni.Set("db_host", "") confIni.Set("db_port", "") confIni.Set("db_password", "") confIni.Set("db_name", "") } else if dbType == "postgresql" || dbType == "mysql" { confIni.Set("db_type", dbType) confIni.Set("db_user", dbUsername) confIni.Set("db_host", dbHost) confIni.Set("db_port", dbPort) confIni.Set("db_password", dbPassword) confIni.Set("db_name", dbName) } err = confIni.SaveConfigFile(*utils.Dir + "/config.ini") if err != nil { return "", err } log.Debug("sqliteDbUrl: %s", sqliteDbUrl) go func() { configIni, err = confIni.GetSection("default") if dbType == "sqlite" && len(sqliteDbUrl) > 0 { if utils.DB != nil && utils.DB.DB != nil { utils.DB.Close() log.Debug("DB CLOSE") } for i := 0; i < 5; i++ { log.Debug("sqliteDbUrl %v", sqliteDbUrl) _, err := utils.DownloadToFile(sqliteDbUrl, *utils.Dir+"/litedb.db", 3600, nil, nil, "install") if err != nil { log.Error("%v", utils.ErrInfo(err)) } if err == nil { break } } if err != nil { panic(err) os.Exit(1) } utils.DB, err = utils.NewDbConnect(configIni) log.Debug("DB OPEN") log.Debug("%v", utils.DB) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } else { utils.DB, err = utils.NewDbConnect(configIni) } c.DCDB = utils.DB if c.DCDB.DB == nil { err = fmt.Errorf("utils.DB == nil") log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } if dbType != "sqlite" || len(sqliteDbUrl) == 0 { schema_ := &schema.SchemaStruct{} schema_.DCDB = c.DCDB schema_.DbType = dbType schema_.PrefixUserId = 0 schema_.GetSchema() err = c.DCDB.ExecSql(`INSERT INTO admin (user_id) VALUES (1)`) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } //if len(userId)>0 { err = c.DCDB.ExecSql("INSERT INTO my_table (user_id, key_password) VALUES (?, ?)", userId, keyPassword) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } //} log.Debug("setupPassword: (%s) / (%s)", setupPassword, utils.DSha256(setupPassword)) if len(setupPassword) > 0 { setupPassword = string(utils.DSha256(setupPassword)) } err = c.DCDB.ExecSql("INSERT INTO config (sqlite_db_url, first_load_blockchain, first_load_blockchain_url, setup_password, auto_reload, chat_enabled) VALUES (?, ?, ?, ?, ?, ?)", sqliteDbUrl, firstLoad, url, setupPassword, 259200, 1) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } count, err := c.Single(`SELECT count(*) FROM payment_systems`).Int64() if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } if count == 0 { err = c.DCDB.ExecSql("INSERT INTO payment_systems (name)VALUES ('Adyen'),('Alipay'),('Amazon Payments'),('AsiaPay'),('Atos'),('Authorize.Net'),('BIPS'),('BPAY'),('Braintree'),('CentUp'),('Chargify'),('Citibank'),('ClickandBuy'),('Creditcall'),('CyberSource'),('DataCash'),('DigiCash'),('Digital River'),('Dwolla'),('ecoPayz'),('Edy'),('Elavon'),('Euronet Worldwide'),('eWAY'),('Flooz'),('Fortumo'),('Google'),('GoCardless'),('Heartland Payment Systems'),('HSBC'),('iKobo'),('iZettle'),('IP Payments'),('Klarna'),('Live Gamer'),('Mobilpenge'),('ModusLink'),('MPP Global Solutions'),('Neteller'),('Nochex'),('Ogone'),('Paymate'),('PayPal'),('Payoneer'),('PayPoint'),('Paysafecard'),('PayXpert'),('Payza'),('Peppercoin'),('Playspan'),('Popmoney'),('Realex Payments'),('Recurly'),('RBK Money'),('Sage Group'),('Serve'),('Skrill (Moneybookers)'),('Stripe'),('Square, Inc.'),('TFI Markets'),('TIMWE'),('Use My Services (UMS)'),('Ukash'),('V.me by Visa'),('VeriFone'),('Vindicia'),('WebMoney'),('WePay'),('Wirecard'),('Western Union'),('WorldPay'),('Yandex money'),('Qiwi'),('OK Pay'),('Bitcoin'),('Perfect Money')") if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } count, err = c.Single(`SELECT count(*) FROM my_notifications`).Int64() if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } if count == 0 { err = c.DCDB.ExecSql(`INSERT INTO my_notifications (name, email, sms, mobile) VALUES ('admin_messages',1,1,1),('change_in_status',1,0,0),('dc_came_from',1,0,1),('dc_sent',1,0,0),('incoming_cash_requests',1,1,1),('new_version',1,1,1),('node_time',0,0,0),('system_error',1,1,0),('update_email',1,0,0),('update_primary_key',1,0,0),('update_sms_request',1,0,0),('voting_results',1,0,0),('voting_time',1,0,0)`) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } err = c.DCDB.ExecSql(`INSERT INTO cf_lang (id, name) VALUES (1, 'English (US)'), (2, 'Afrikaans'), (3, 'Kiswahili'), (4, 'Türkçe'), (5, 'עברית'), (6, 'العربية'), (7, 'Español'), (8, 'Français (Canada)'), (9, 'Guarani'), (10, 'Português (Brasil)'), (11, 'Azərbaycan dili'), (12, 'Bahasa Indonesia'), (13, 'Bahasa Melayu'), (14, 'Basa Jawa'), (15, 'Bisaya'), (16, 'Filipino'), (17, 'Tiếng Việt'), (18, 'Հայերեն'), (19, 'اردو'), (20, 'हिन्दी'), (21, 'বাংলা'), (22, 'ਪੰਜਾਬੀ'), (23, 'தமிழ்'), (24, 'తెలుగు'), (25, 'ಕನ್ನಡ'), (26, 'മലയാളം'), (27, 'සිංහල'), (28, 'ภาษาไทย'), (29, '한국어'), (30, '中文(台灣)'), (31, '中文(简体)'), (32, '中文(香港)'), (33, '日本語'), (35, 'Čeština'), (36, 'Magyar'), (37, 'Polski'), (38, 'Română'), (39, 'Slovenčina'), (40, 'Slovenščina'), (41, 'Български'), (42, 'Русский'), (43, 'Українська'), (45, 'Bosanski'), (46, 'Català'), (47, 'Cymraeg'), (48, 'Dansk'), (49, 'Deutsch'), (50, 'Eesti'), (51, 'English (UK)'), (52, 'Español (España)'), (53, 'Euskara'), (54, 'Français (France)'), (55, 'Galego'), (56, 'Hrvatski'), (57, 'Italiano'), (58, 'Latviešu'), (59, 'Lietuvių'), (60, 'Nederlands'), (61, 'Norsk (bokmål)'), (62, 'Português (Portugal)'), (63, 'Shqip'), (64, 'Suomi'), (65, 'Svenska'), (66, 'Ελληνικά'), (67, 'Македонски'), (68, 'Српски');`) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } err = c.DCDB.ExecSql(`INSERT INTO install (progress) VALUES ('complete')`) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } }() utils.Sleep(3) // даем время обновиться config.ini, чтобы в content выдался не installStep0, а updatingBlockchain TemplateStr, err := makeTemplate("install_step_1", "installStep1", &installStep1Struct{ Lang: c.Lang}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) Upgrade6() (string, error) { log.Debug("Upgrade6") var hostType string hostData, err := c.OneRow("SELECT http_host, tcp_host FROM " + c.MyPrefix + "my_table").String() if err != nil { return "", utils.ErrInfo(err) } // в режиме пула выдаем только хост ноды log.Debug("c.Community: %v", c.Community) log.Debug("c.PoolAdminUserId: %v", c.PoolAdminUserId) if c.Community /*&& len(data["http_host"]) == 0 && len(data["tcp_host"]) == 0*/ { hostType = "pool" hostData, err = c.OneRow("SELECT http_host, tcp_host FROM miners_data WHERE user_id = ?", c.PoolAdminUserId).String() if err != nil { return "", utils.ErrInfo(err) } if len(hostData) == 0 { hostData["http_host"] = "null http_host in miners_data" hostData["tcp_host"] = "null tcp_host in miners_data" } } else { // если смогли подключиться из вне ip, err := utils.GetHttpTextAnswer("http://api.ipify.org") if err != nil { return "", utils.ErrInfo(err) } /*httpHost, err := c.Single("SELECT http_host FROM "+c.MyPrefix+"my_table").String() if err!=nil { return "", utils.ErrInfo(err) } port := "8089" if len(httpHost) > 0 { re := regexp.MustCompile(`https?:\/\/(?:[0-9a-z\_\.\-]+):([0-9]+)`) match := re.FindStringSubmatch(httpHost) if len(match) != 0 { port = match[1]; } }*/ conn, err := net.DialTimeout("tcp", ip+":8089", 3*time.Second) log.Debug("ip: %v", ip) if err != nil { // если не смогли подключиться, то в JS будем искать рабочий пул и региться на нем. и дадим юзеру указать другие хост:ip hostType = "findPool" } else { hostType = "normal" defer conn.Close() hostData["http_host"] = ip + ":8089" hostData["tcp_host"] = ip + ":8088" } } // проверим, есть ли необработанные ключи в локальной табле nodePrivateKey, err := c.Single("SELECT private_key FROM " + c.MyPrefix + "my_node_keys WHERE block_id = 0").String() if err != nil { return "", utils.ErrInfo(err) } if len(nodePrivateKey) == 0 { // сгенерим ключ для нода priv, pub := utils.GenKeys() err = c.ExecSql("INSERT INTO "+c.MyPrefix+"my_node_keys ( public_key, private_key ) VALUES ( [hex], ? )", pub, priv) if err != nil { return "", utils.ErrInfo(err) } nodePrivateKey = priv } var profileHash, faceHash, videoHash string if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg"); err == nil { file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg") if err != nil { return "", utils.ErrInfo(err) } faceHash = string(utils.DSha256(file)) } if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg"); err == nil { file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg") if err != nil { return "", utils.ErrInfo(err) } profileHash = string(utils.DSha256(file)) } if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4"); err == nil { file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4") if err != nil { return "", utils.ErrInfo(err) } videoHash = string(utils.DSha256(file)) } text, err := utils.GetHttpTextAnswer("http://dcoin.club/pools") if err != nil { return "", utils.ErrInfo(err) } var pools_ []string err = json.Unmarshal([]byte(text), &pools_) if err != nil { return "", utils.ErrInfo(err) } log.Debug("pools: %v", pools_) rows, err := c.Query(c.FormatQuery(` SELECT user_id, http_host FROM miners_data WHERE user_id IN (` + strings.Join(pools_, ",") + `)`)) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() pools := make(map[string]string) for rows.Next() { var user_id, http_host string err = rows.Scan(&user_id, &http_host) if err != nil { return "", utils.ErrInfo(err) } pools[user_id] = http_host } poolsJs := "" for userId, httpHost := range pools { poolsJs = poolsJs + "[" + userId + ",'" + httpHost + "']," } poolsJs = poolsJs[:len(poolsJs)-1] videoUrlId, err := c.Single("SELECT video_url_id FROM " + c.MyPrefix + "my_table").String() if err != nil { return "", utils.ErrInfo(err) } saveAndGotoStep := strings.Replace(c.Lang["save_and_goto_step"], "[num]", "8", -1) upgradeMenu := utils.MakeUpgradeMenu(6) TemplateStr, err := makeTemplate("upgrade_6", "upgrade6", &upgrade6Page{ Alert: c.Alert, Lang: c.Lang, SaveAndGotoStep: saveAndGotoStep, UpgradeMenu: upgradeMenu, ShowSignData: c.ShowSignData, SignData: "", CountSignArr: c.CountSignArr, HttpHost: hostData["http_host"], TcpHost: hostData["tcp_host"], Community: c.Community, HostType: hostType, ProfileHash: profileHash, FaceHash: faceHash, VideoHash: videoHash, NodePrivateKey: nodePrivateKey, Pools: template.JS(poolsJs), UserId: c.SessUserId, VideoUrlId: videoUrlId, Mobile: utils.Mobile()}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (t *TcpServer) Type12() { /* Получаем данные от send_promised_amount_to_pool */ log.Debug("Type12") // размер данных buf := make([]byte, 4) _, err := t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %d", size) if size < 32<<20 { // сами данные log.Debug("read data") binaryData := make([]byte, size) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } //log.Debug("binaryData %x", binaryData) userId := utils.BinToDec(utils.BytesShift(&binaryData, 5)) currencyId := utils.BinToDec(utils.BytesShift(&binaryData, 1)) log.Debug("userId %d", userId) log.Debug("currencyId %d", currencyId) // проверим, есть ли такой юзер на пуле inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64() if inPool <= 0 { log.Error("%v", utils.ErrInfo("inPool<=0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } log.Debug("inPool %d", inPool) filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)) log.Debug("filesSign %x", filesSign) size := utils.DecodeLength(&binaryData) log.Debug("size %d", size) data := utils.BytesShift(&binaryData, size) //log.Debug("data %x", data) fileType := utils.BinToDec(utils.BytesShift(&data, 1)) log.Debug("fileType %d", fileType) fileName := utils.Int64ToStr(userId) + "_promised_amount_" + utils.Int64ToStr(currencyId) + ".mp4" forSign := string(utils.DSha256((data))) log.Debug("forSign %s", forSign) err = ioutil.WriteFile(os.TempDir()+"/"+fileName, data, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } if len(forSign) == 0 { log.Error("%v", utils.ErrInfo("len(forSign) == 0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } // проверим подпись publicKey, err := t.GetUserPublicKey(userId) resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true) if err != nil { log.Error("%v", utils.ErrInfo(err)) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if resultCheckSign { utils.CopyFileContents(os.TempDir()+"/"+fileName, *utils.Dir+"/public/"+fileName) } else { os.Remove(os.TempDir() + "/" + fileName) } // и возвращаем статус _, err = t.Conn.Write(utils.DecToBin(1, 1)) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } } else { log.Error("%v", utils.ErrInfo("size>32mb")) } }
func (c *Controller) CashRequestOut() (string, error) { txType := "CashRequestOut" txTypeId := utils.TypeInt(txType) timeNow := utils.Time() cashRequestsStatus := map[string]string{"my_pending": c.Lang["local_pending"], "pending": c.Lang["pending"], "approved": c.Lang["approved"], "rejected": c.Lang["rejected"]} jsonCurrencyWallets := "" var availableCurrency []int64 // список отравленных нами запросов myCashRequests, err := c.GetAll("SELECT * FROM "+c.MyPrefix+"my_cash_requests WHERE to_user_id != ?", -1, c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } // получаем список кошельков, на которых есть FC rows, err := c.Query(c.FormatQuery("SELECT amount, currency_id, last_update FROM wallets WHERE user_id = ? AND currency_id < 1000"), c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var amount float64 var currency_id, last_update int64 err = rows.Scan(&amount, ¤cy_id, &last_update) if err != nil { return "", utils.ErrInfo(err) } if currency_id == 1 { continue } profit, err := c.CalcProfitGen(currency_id, amount, c.SessUserId, last_update, timeNow, "wallets") if err != nil { return "", utils.ErrInfo(err) } amount += profit jsonCurrencyWallets += fmt.Sprintf(`"%d":["%s","%v"],`, currency_id, c.CurrencyList[currency_id], amount) availableCurrency = append(availableCurrency, currency_id) } jsonCurrencyWallets = jsonCurrencyWallets[:len(jsonCurrencyWallets)-1] //jsonCurrencyWallets = "\"" log.Debug("jsonCurrencyWallets", jsonCurrencyWallets) code := utils.Md5(utils.RandSeq(50)) hashCode := utils.DSha256(code) TemplateStr, err := makeTemplate("cash_request_out", "cashRequestOut", &cashRequestOutPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, SignData: "", CurrencyList: c.CurrencyList, PaymentSystems: c.PaymentSystems, JsonCurrencyWallets: jsonCurrencyWallets, CashRequestsStatus: cashRequestsStatus, AvailableCurrency: availableCurrency, MinPromisedAmount: c.Variables.Int64["min_promised_amount"], MyCashRequests: myCashRequests, Code: string(code), HashCode: string(hashCode), MaxLength: 200}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) Check_sign() (string, error) { var checkError bool c.r.ParseForm() n := []byte(c.r.FormValue("n")) e := []byte(c.r.FormValue("e")) sign := []byte(c.r.FormValue("sign")) setupPassword := c.r.FormValue("setup_password") private_key := c.r.FormValue("private_key") if !utils.CheckInputData(n, "hex") { return `{"result":"incorrect n"}`, nil } if !utils.CheckInputData(e, "hex") { return `{"result":"incorrect e"}`, nil } if !utils.CheckInputData(string(sign), "hex_sign") { return `{"result":"incorrect sign"}`, nil } allTables, err := c.DCDB.GetAllTables() if err != nil { return "{\"result\":0}", err } var hash []byte log.Debug("configIni[sign_hash] %s", configIni["sign_hash"]) log.Debug("c.r.RemoteAddr %s", c.r.RemoteAddr) log.Debug("c.r.Header.Get(User-Agent) %s", c.r.Header.Get("User-Agent")) RemoteAddr := utils.RemoteAddrFix(c.r.RemoteAddr) re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(RemoteAddr) if len(match) != 0 { RemoteAddr = match[1] } log.Debug("RemoteAddr %s", RemoteAddr) hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) if len(c.CommunityUsers) > 0 { // в цикле проверяем, кому подойдет присланная подпись for _, userId := range c.CommunityUsers { myPrefix := utils.Int64ToStr(userId) + "_" if !utils.InSliceString(myPrefix+"my_keys", allTables) { continue } // получим открытый ключ юзера publicKey, err := c.DCDB.GetMyPublicKey(myPrefix) if err != nil { return "{\"result\":0}", err } // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("publicKey: %x\n", publicKey) log.Debug("myPrefix: ", myPrefix) log.Debug("sign: %s\n", sign) log.Debug("hash: %s\n", hash) log.Debug("forSign: ", forSign) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true) if err != nil { continue } // если подпись верная, значит мы нашли юзера, который эту подпись смог сделать if resultCheckSign { myUserId := userId // убираем ограниченный режим c.sess.Delete("restricted") c.sess.Set("user_id", myUserId) log.Debug("c.sess.Set(user_id) %d", myUserId) public_key, err := c.DCDB.GetUserPublicKey(myUserId) if err != nil { return "{\"result\":0}", err } // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(utils.BinToHex([]byte(public_key)))) log.Debug("string(utils.BinToHex([]byte(public_key))) %s", string(utils.BinToHex([]byte(public_key)))) adminUSerID, err := c.DCDB.GetAdminUserId() if err != nil { return "{\"result\":0}", err } if adminUSerID == myUserId { c.sess.Set("admin", 1) } return "{\"result\":1}", nil } } log.Debug("restricted test") // если дошли досюда, значит ни один ключ не подошел и даем возможность войти в ограниченном режиме publicKey := utils.MakeAsn1(n, e) userId_, err := c.DCDB.GetUserIdByPublicKey(publicKey) userId := utils.StrToInt64(userId_) if err != nil { return "{\"result\":0}", err } log.Debug("userId:", userId) // юзер с таким ключем есть в БД if userId > 0 { // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("forSign", forSign) log.Debug("publicKey %x\n", utils.HexToBin(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if resultCheckSign { // если юзер смог подписать наш хэш, значит у него актуальный праймари ключ c.sess.Set("user_id", userId) log.Debug("c.sess.Set(user_id) %d", userId) // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(publicKey)) // возможно в табле my_keys старые данные, но если эта табла есть, то нужно добавить туда ключ if utils.InSliceString(utils.Int64ToStr(userId)+"_my_keys", allTables) { curBlockId, err := c.DCDB.GetBlockId() if err != nil { return "{\"result\":0}", err } err = c.DCDB.InsertIntoMyKey(utils.Int64ToStr(userId)+"_", publicKey, utils.Int64ToStr(curBlockId)) if err != nil { return "{\"result\":0}", err } c.sess.Delete("restricted") } else { c.sess.Set("restricted", int64(1)) log.Debug("c.sess.Set(restricted) 1") } return "{\"result\":1}", nil } else { return "{\"result\":0}", nil } } } else { // получим открытый ключ юзера publicKey, err := c.DCDB.GetMyPublicKey("") if err != nil { return "{\"result\":0}", err } // Если ключ еще не успели установить if len(publicKey) == 0 { // пока не собрана цепочка блоков не даем ввести ключ infoBlock, err := c.DCDB.GetInfoBlock() if err != nil { return "{\"result\":0}", err } // если последний блок не старше 2-х часов wTime := int64(2) if c.ConfigIni["test_mode"] == "1" { wTime = 2 * 365 * 24 } log.Debug("%v/%v/%v", time.Now().Unix(), utils.StrToInt64(infoBlock["time"]), wTime) if (time.Now().Unix() - utils.StrToInt64(infoBlock["time"])) < 3600*wTime { // проверим, верный ли установочный пароль, если он, конечно, есть setupPassword_, err := c.Single("SELECT setup_password FROM config").String() if err != nil { return "{\"result\":0}", err } if len(setupPassword_) > 0 && setupPassword_ != string(utils.DSha256(setupPassword)) { log.Debug(setupPassword_, string(utils.DSha256(setupPassword)), setupPassword) return "{\"result\":0}", nil } publicKey := utils.MakeAsn1(n, e) log.Debug("new key", string(publicKey)) userId, err := c.GetUserIdByPublicKey(publicKey) if err != nil { return "{\"result\":0}", err } // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) if err != nil { return "{\"result\":0}", err } log.Debug("forSign", forSign) log.Debug("publicKey %x\n", utils.HexToBin(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if !resultCheckSign { return "{\"result\":0}", nil } if len(userId) > 0 { err := c.InsertIntoMyKey("", publicKey, "0") if err != nil { return "{\"result\":0}", err } minerId, err := c.GetMinerId(utils.StrToInt64(userId)) if err != nil { return "{\"result\":0}", err } //myUserId, err := c.GetMyUserId("") //if myUserId > 0 { if minerId > 0 { err = c.ExecSql("UPDATE my_table SET user_id = ?, miner_id = ?, status = 'miner'", userId, minerId) if err != nil { return "{\"result\":0}", err } } else { err = c.ExecSql("UPDATE my_table SET user_id = ?, status = 'user'", userId) if err != nil { return "{\"result\":0}", err } } //} else { // c.ExecSql("INSERT INTO my_table (user_id, status) VALUES (?, 'user')", userId) //} // возможно юзер хочет сохранить свой ключ if len(private_key) > 0 { c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key) } } else { checkError = true } } else { checkError = true } } else { log.Debug("RemoteAddr %s", RemoteAddr) hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("forSign", forSign) log.Debug("publicKey %x\n", string(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if !resultCheckSign { return "{\"result\":0}", nil } } if checkError { return "{\"result\":0}", nil } else { myUserId, err := c.DCDB.GetMyUserId("") if myUserId == 0 { myUserId = -1 } if err != nil { return "{\"result\":0}", err } c.sess.Delete("restricted") c.sess.Set("user_id", myUserId) // если уже пришел блок, в котором зареган ключ юзера if myUserId != -1 { public_key, err := c.DCDB.GetUserPublicKey(myUserId) if err != nil { return "{\"result\":0}", err } // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(utils.BinToHex(public_key))) // возможно юзер хочет сохранить свой ключ if len(private_key) > 0 { c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key) } AdminUserId, err := c.DCDB.GetAdminUserId() if err != nil { return "{\"result\":0}", err } if AdminUserId == myUserId { c.sess.Set("admin", int64(1)) } return "{\"result\":1}", nil } } } return "{\"result\":0}", nil }
func (c *Controller) GenerateNewPrimaryKey() (string, error) { c.r.ParseForm() password := c.r.FormValue("password") priv, pub := utils.GenKeys() if len(password) > 0 { log.Debug("priv:", priv) encKey, err := utils.Encrypt(utils.Md5("11"), []byte(priv)) log.Debug("priv encKey:", encKey) if err != nil { return "", utils.ErrInfo(err) } priv = base64.StdEncoding.EncodeToString(encKey) log.Debug("priv ENC:", priv) //priv = string(encKey) } json, err := json.Marshal(map[string]string{"private_key": priv, "public_key": pub, "password_hash": string(utils.DSha256(password))}) if err != nil { return "", utils.ErrInfo(err) } log.Debug("%v", json) return string(json), nil }
func (c *Controller) Upgrade7() (string, error) { log.Debug("Upgrade7") txType := "NewMiner" txTypeId := utils.TypeInt(txType) timeNow := utils.Time() // Формируем контент для подписи myTable, err := c.OneRow("SELECT user_id, race, country, geolocation, http_host, tcp_host, face_coords, profile_coords, video_url_id, video_type FROM " + c.MyPrefix + "my_table").String() if err != nil { return "", utils.ErrInfo(err) } if len(myTable["video_url_id"]) == 0 { myTable["video_url_id"] = "null" } if len(myTable["video_type"]) == 0 { myTable["video_type"] = "null" } var profileHash, faceHash string if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg"); err == nil { file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg") if err != nil { return "", utils.ErrInfo(err) } faceHash = string(utils.DSha256(file)) } if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg"); err == nil { file, err := ioutil.ReadFile(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg") if err != nil { return "", utils.ErrInfo(err) } profileHash = string(utils.DSha256(file)) } latitude := "0" longitude := "0" if len(myTable["geolocation"]) > 0 { x := strings.Split(myTable["geolocation"], ", ") latitude = x[0] longitude = x[1] } // проверим, есть ли не обработанные ключи в локальной табле nodePublicKey, err := c.Single("SELECT public_key FROM " + c.MyPrefix + "my_node_keys WHERE block_id = 0").String() if err != nil { return "", utils.ErrInfo(err) } if len(nodePublicKey) == 0 { // сгенерим ключ для нода priv, pub := utils.GenKeys() err = c.ExecSql("INSERT INTO "+c.MyPrefix+"my_node_keys ( public_key, private_key ) VALUES ( [hex], ? )", pub, priv) if err != nil { return "", utils.ErrInfo(err) } } else { nodePublicKey = string(utils.BinToHex([]byte(nodePublicKey))) } saveAndGotoStep := strings.Replace(c.Lang["save_and_goto_step"], "[num]", "9", -1) upgradeMenu := utils.MakeUpgradeMenu(7) var noExistsMp4 bool if _, err := os.Stat(*utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4"); os.IsNotExist(err) { noExistsMp4 = true } TemplateStr, err := makeTemplate("upgrade_7", "upgrade7", &upgrade7Page{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, NoExistsMp4: noExistsMp4, SignData: fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v", txTypeId, timeNow, c.SessUserId, myTable["race"], myTable["country"], latitude, longitude, myTable["http_host"], myTable["tcp_host"], faceHash, profileHash, myTable["face_coords"], myTable["profile_coords"], myTable["video_type"], myTable["video_url_id"], nodePublicKey), SaveAndGotoStep: saveAndGotoStep, UpgradeMenu: upgradeMenu, Latitude: latitude, Longitude: longitude, NodePublicKey: nodePublicKey, ProfileHash: profileHash, FaceHash: faceHash, Data: myTable, MyTable: myTable, Mobile: utils.Mobile()}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (t *TcpServer) Type6() { /** - проверяем, находится ли отправитель на одном с нами уровне - получаем block_id, user_id, mrkl_root, signature - если хэш блока меньше того, что есть у нас в табле testblock, то смотртим, есть ли такой же хэш тр-ий, - если отличается, то загружаем блок от отправителя - если не отличается, то просто обновляем хэш блока у себя данные присылает демон testblockDisseminator */ currentBlockId, err := t.GetBlockId() if err != nil { log.Error("%v", utils.ErrInfo(err)) return } if currentBlockId == 0 { log.Debug("%v", utils.ErrInfo("currentBlockId == 0")) return } buf := make([]byte, 4) _, err = t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %v", size) if size < 10485760 { binaryData := make([]byte, size) //binaryData, err = ioutil.ReadAll(t.Conn) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("binaryData: %x", binaryData) newTestblockBlockId := utils.BinToDecBytesShift(&binaryData, 4) newTestblockTime := utils.BinToDecBytesShift(&binaryData, 4) newTestblockUserId := utils.BinToDecBytesShift(&binaryData, 4) newTestblockMrklRoot := utils.BinToHex(utils.BytesShift(&binaryData, 32)) newTestblockSignatureHex := utils.BinToHex(utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData))) log.Debug("newTestblockBlockId: %v", newTestblockBlockId) log.Debug("newTestblockTime: %v", newTestblockTime) log.Debug("newTestblockUserId: %v", newTestblockUserId) log.Debug("newTestblockMrklRoot: %s", newTestblockMrklRoot) log.Debug("newTestblockSignatureHex: %s", newTestblockSignatureHex) if !utils.CheckInputData(newTestblockBlockId, "int") { log.Debug("%v", utils.ErrInfo("incorrect newTestblockBlockId")) return } if !utils.CheckInputData(newTestblockTime, "int") { log.Debug("%v", utils.ErrInfo("incorrect newTestblockTime")) return } if !utils.CheckInputData(newTestblockUserId, "int") { log.Debug("%v", utils.ErrInfo("incorrect newTestblockUserId")) return } if !utils.CheckInputData(newTestblockMrklRoot, "sha256") { log.Debug("%v", utils.ErrInfo("incorrect newTestblockMrklRoot")) return } /* * Проблема одновременных попыток локнуть. Надо попробовать без локов * */ //t.DbLockGate("6") exists, err := t.Single(` SELECT block_id FROM testblock WHERE status = 'active' `).Int64() if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } if exists == 0 { t.PrintSleep(utils.ErrInfo("null testblock"), 0) return } //prevBlock, myUserId, myMinerId, currentUserId, level, levelsRange, err := t.TestBlock() prevBlock, _, _, _, level, levelsRange, err := t.TestBlock() if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } nodesIds := utils.GetOurLevelNodes(level, levelsRange) log.Debug("nodesIds: %v ", nodesIds) log.Debug("prevBlock: %v ", prevBlock) log.Debug("level: %v ", level) log.Debug("levelsRange: %v ", levelsRange) log.Debug("newTestblockBlockId: %v ", newTestblockBlockId) // проверим, верный ли ID блока if newTestblockBlockId != prevBlock.BlockId+1 { t.PrintSleep(utils.ErrInfo(fmt.Sprintf("newTestblockBlockId != prevBlock.BlockId+1 %d!=%d+1", newTestblockBlockId, prevBlock.BlockId)), 1) return } // проверим, есть ли такой майнер minerId, err := t.Single("SELECT miner_id FROM miners_data WHERE user_id = ?", newTestblockUserId).Int64() if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } if minerId == 0 { t.PrintSleep(utils.ErrInfo("minerId == 0"), 0) return } log.Debug("minerId: %v ", minerId) // проверим, точно ли отправитель с нашего уровня if !utils.InSliceInt64(minerId, nodesIds) { t.PrintSleep(utils.ErrInfo("!InSliceInt64(minerId, nodesIds)"), 0) return } // допустимая погрешность во времени генерации блока maxErrorTime := t.variables.Int64["error_time"] // получим значения для сна sleep, err := t.GetGenSleep(prevBlock, level) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } // исключим тех, кто сгенерил блок слишком рано if prevBlock.Time+sleep-newTestblockTime > maxErrorTime { t.PrintSleep(utils.ErrInfo("prevBlock.Time + sleep - newTestblockTime > maxErrorTime"), 0) return } // исключим тех, кто сгенерил блок с бегущими часами if newTestblockTime > utils.Time() { t.PrintSleep(utils.ErrInfo("newTestblockTime > Time()"), 0) return } // получим хэш заголовка newHeaderHash := utils.DSha256(fmt.Sprintf("%v,%v,%v", newTestblockUserId, newTestblockBlockId, prevBlock.HeadHash)) myTestblock, err := t.OneRow(` SELECT block_id, user_id, hex(mrkl_root) as mrkl_root, hex(signature) as signature FROM testblock WHERE status = 'active' `).String() if len(myTestblock) > 0 { if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } // получим хэш заголовка myHeaderHash := utils.DSha256(fmt.Sprintf("%v,%v,%v", myTestblock["user_id"], myTestblock["block_id"], prevBlock.HeadHash)) // у кого меньше хэш, тот и круче hash1 := big.NewInt(0) hash1.SetString(string(newHeaderHash), 16) hash2 := big.NewInt(0) hash2.SetString(string(myHeaderHash), 16) log.Debug("%v", hash1.Cmp(hash2)) //if HexToDecBig(newHeaderHash) > string(myHeaderHash) { if hash1.Cmp(hash2) == 1 { t.PrintSleep(utils.ErrInfo(fmt.Sprintf("newHeaderHash > myHeaderHash (%s > %s)", newHeaderHash, myHeaderHash)), 0) return } /* т.к. на данном этапе в большинстве случаев наш текущий блок будет заменен, * то нужно парсить его, рассылать другим нодам и дождаться окончания проверки */ err = t.ExecSql("UPDATE testblock SET status = 'pending'") if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } } // если отличается, то загружаем недостающии тр-ии от отправителя if string(newTestblockMrklRoot) != myTestblock["mrkl_root"] { log.Debug("download new tx") sendData := "" // получим все имеющиеся у нас тр-ии, которые еще не попали в блоки txArray, err := t.GetMap(`SELECT hex(hash) as hash, data FROM transactions`, "hash", "data") if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } for hash, _ := range txArray { sendData += hash } err = utils.WriteSizeAndData([]byte(sendData), t.Conn) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } /* в ответ получаем: BLOCK_ID 4 TIME 4 USER_ID 5 SIGN от 128 до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT Размер всех тр-ий, размер 1 тр-ии, тело тр-ии. Хэши три-ий (порядок тр-ий) */ buf := make([]byte, 4) _, err = t.Conn.Read(buf) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } dataSize := utils.BinToDec(buf) log.Debug("dataSize %d", dataSize) // и если данных менее 10мб, то получаем их if dataSize < 10485760 { binaryData := make([]byte, dataSize) //binaryData, err = ioutil.ReadAll(t.Conn) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } // Разбираем полученные бинарные данные newTestblockBlockId := utils.BinToDecBytesShift(&binaryData, 4) newTestblockTime := utils.BinToDecBytesShift(&binaryData, 4) newTestblockUserId := utils.BinToDecBytesShift(&binaryData, 5) newTestblockSignature := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)) log.Debug("newTestblockBlockId %v", newTestblockBlockId) log.Debug("newTestblockTime %v", newTestblockTime) log.Debug("newTestblockUserId %v", newTestblockUserId) log.Debug("newTestblockSignature %x", newTestblockSignature) // недостающие тр-ии length := utils.DecodeLength(&binaryData) // размер всех тр-ий txBinary := utils.BytesShift(&binaryData, length) for { // берем по одной тр-ии length := utils.DecodeLength(&txBinary) // размер всех тр-ий if length == 0 { break } log.Debug("length %d", length) tx := utils.BytesShift(&txBinary, length) log.Debug("tx %x", tx) txArray[string(utils.Md5(tx))] = string(tx) } // порядок тр-ий var orderHashArray []string for { orderHashArray = append(orderHashArray, string(utils.BinToHex(utils.BytesShift(&binaryData, 16)))) if len(binaryData) == 0 { break } } // сортируем и наши и полученные транзакции var transactions []byte for _, txMd5 := range orderHashArray { transactions = append(transactions, utils.EncodeLengthPlusData([]byte(txArray[txMd5]))...) } // формируем блок, который далее будем тщательно проверять /* Заголовок (от 143 до 527 байт ) TYPE (0-блок, 1-тр-я) 1 BLOCK_ID 4 TIME 4 USER_ID 5 LEVEL 1 SIGN от 128 до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT Далее - тело блока (Тр-ии) */ newBlockIdBinary := utils.DecToBin(newTestblockBlockId, 4) timeBinary := utils.DecToBin(newTestblockTime, 4) userIdBinary := utils.DecToBin(newTestblockUserId, 5) levelBinary := utils.DecToBin(level, 1) newBlockHeader := utils.DecToBin(0, 1) // 0 - это блок newBlockHeader = append(newBlockHeader, newBlockIdBinary...) newBlockHeader = append(newBlockHeader, timeBinary...) newBlockHeader = append(newBlockHeader, userIdBinary...) newBlockHeader = append(newBlockHeader, levelBinary...) // $level пишем, чтобы при расчете времени ожидания в следующем блоке не пришлось узнавать, какой был max_miner_id newBlockHeader = append(newBlockHeader, utils.EncodeLengthPlusData(newTestblockSignature)...) newBlockHex := utils.BinToHex(append(newBlockHeader, transactions...)) // и передаем блок для обратотки через демон queue_parser_testblock // т.к. есть запросы к log_time_, а их можно выполнять только по очереди err = t.ExecSql(`DELETE FROM queue_testblock WHERE hex(head_hash) = ?`, newHeaderHash) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } log.Debug("INSERT INTO queue_testblock (head_hash, data) VALUES (%s, %s)", newHeaderHash, newBlockHex) err = t.ExecSql(`INSERT INTO queue_testblock (head_hash, data) VALUES ([hex], [hex])`, newHeaderHash, newBlockHex) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } } } else { // если всё нормально, то пишем в таблу testblock новые данные exists, err := t.Single(`SELECT block_id FROM testblock`).Int64() if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } if exists == 0 { err = t.ExecSql(`INSERT INTO testblock (block_id, time, level, user_id, header_hash, signature, mrkl_root) VALUES (?, ?, ?, ?, [hex], [hex], [hex])`, newTestblockBlockId, newTestblockTime, level, newTestblockUserId, string(newHeaderHash), newTestblockSignatureHex, string(newTestblockMrklRoot)) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } } else { err = t.ExecSql(` UPDATE testblock SET time = ?, user_id = ?, header_hash = [hex], signature = [hex] `, newTestblockTime, newTestblockUserId, string(newHeaderHash), string(newTestblockSignatureHex)) if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } } } err = t.ExecSql("UPDATE testblock SET status = 'active'") if err != nil { t.PrintSleep(utils.ErrInfo(err), 0) return } //t.DbUnlockGate("6") } }