コード例 #1
0
ファイル: e_sign_login.go プロジェクト: dzyk/dcoin-go
func (c *Controller) ESignLogin() (string, error) {

	c.w.Header().Set("Access-Control-Allow-Origin", "*")

	var hash []byte
	loginCode := utils.RandSeq(20)

	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)

	err := c.DCDB.ExecSql(`DELETE FROM e_authorization WHERE hex(hash) = ?`, hash)
	if err != nil {
		return "", err
	}
	err = c.DCDB.ExecSql(`INSERT INTO e_authorization (hash, data) VALUES ([hex], ?)`, hash, loginCode)
	if err != nil {
		return "", err
	}
	log.Debug("loginCode %v", loginCode)
	return "\"" + loginCode + "\"", nil
}
コード例 #2
0
ファイル: e_check_sign.go プロジェクト: dzyk/dcoin-go
func (c *Controller) ECheckSign() (string, error) {

	c.w.Header().Set("Access-Control-Allow-Origin", "*")

	c.r.ParseForm()
	userId := utils.StrToInt64(c.r.FormValue("user_id"))
	sign := []byte(c.r.FormValue("sign"))
	if !utils.CheckInputData(string(sign), "hex_sign") {
		return `{"result":"incorrect sign"}`, nil
	}
	if !utils.CheckInputData(userId, "int") {
		return `{"result":"incorrect user_id"}`, nil
	}

	var publicKey []byte
	if userId == 0 {
		n := []byte(c.r.FormValue("n"))
		e := []byte(c.r.FormValue("e"))
		if !utils.CheckInputData(n, "hex") {
			return `{"result":"incorrect n"}`, nil
		}
		if !utils.CheckInputData(e, "hex") {
			return `{"result":"incorrect e"}`, nil
		}
		log.Debug("n %v / e %v", n, e)
		publicKey = utils.MakeAsn1(n, e)
		log.Debug("publicKey %s", publicKey)
	}

	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)
	forSign, err := c.Single(`SELECT data FROM e_authorization WHERE hex(hash) = ?`, hash).String()
	if err != nil {
		return "{\"result\":0}", err
	}

	if userId > 0 {
		publicKey_, err := c.GetUserPublicKey(userId)
		publicKey = []byte(publicKey_)
		if err != nil {
			return "{\"result\":0}", err
		}
		if len(publicKey_) == 0 {
			return "{\"result\":0}", utils.ErrInfo("len(publicKey_) == 0")
		}
	} else {
		userId_, err := c.GetUserIdByPublicKey(publicKey)
		userId = utils.StrToInt64(userId_)
		publicKey = utils.HexToBin(publicKey)
		log.Debug("userId %d", userId)
		if err != nil {
			return "{\"result\":0}", err
		}
		if userId == 0 {
			return "{\"result\":0}", utils.ErrInfo("userId == 0")
		}
	}

	log.Debug("userId %v", userId)
	log.Debug("publicKey %x", publicKey)
	log.Debug("forSign %v", forSign)
	log.Debug("sign %s", sign)

	// проверим подпись
	resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(sign), true)
	if err != nil {
		return "{\"result\":0}", err
	}
	log.Debug("resultCheckSign %v", resultCheckSign)
	if resultCheckSign {
		// если это первый запрос, то создаем запись в табле users
		eUserId, err := c.Single(`SELECT id	FROM e_users WHERE user_id = ?`, userId).Int64()
		if err != nil {
			return "{\"result\":0}", err
		}
		if eUserId == 0 {
			eUserId, err = c.ExecSqlGetLastInsertId(`INSERT INTO e_users (user_id) VALUES (?)`, "id", userId)
			if err != nil {
				return "{\"result\":0}", err
			}
		}
		if len(c.r.FormValue("user_id")) > 0 {
			token := utils.RandSeq(30)
			err = c.ExecSql(`INSERT INTO e_tokens (token, user_id) VALUES (?, ?)`, token, eUserId)
			if err != nil {
				return "{\"result\":0}", err
			}
			log.Debug(`{"result":"1", "token":"` + token + `"}`)

			return `{"result":"1", "token":"` + token + `"}`, nil
		} else {
			c.sess.Set("e_user_id", eUserId)
			return `{"result":1}`, nil
		}
	} else {
		return "{\"result\":0}", nil
	}
}
コード例 #3
0
ファイル: check_sign.go プロジェクト: dzyk/dcoin-go
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
}
コード例 #4
0
ファイル: sign_up_in_pool.go プロジェクト: dzyk/dcoin-go
func (c *Controller) SignUpInPool() (string, error) {

	c.w.Header().Set("Access-Control-Allow-Origin", "*")

	if !c.Community {
		return "", utils.JsonAnswer("Not pool", "error").Error()
	}

	c.r.ParseForm()

	var userId int64
	var codeSign string
	if c.SessUserId <= 0 {
		// запрос пришел с десктопного кошелька юзера
		codeSign = c.r.FormValue("code_sign")
		if !utils.CheckInputData(codeSign, "hex_sign") {
			return "", utils.JsonAnswer("Incorrect code_sign", "error").Error()
		}
		userId = utils.StrToInt64(c.r.FormValue("user_id"))
		if !utils.CheckInputData(userId, "int64") {
			return "", utils.JsonAnswer("Incorrect userId", "error").Error()
		}
		// получим данные для подписи
		var hash []byte

		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)

		forSign, err := c.GetDataAuthorization(hash)
		log.Debug("forSign: %v", forSign)
		publicKey, err := c.GetUserPublicKey(userId)
		log.Debug("publicKey: %x", publicKey)
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
		// проверим подпись
		resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin([]byte(codeSign)), true)
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
		if !resultCheckSign {
			return "", utils.JsonAnswer("Incorrect codeSign", "error").Error()
		}
	} else {
		// запрос внутри пула
		userId = c.SessUserId
	}
	/*e:=c.r.FormValue("e")
	n:=c.r.FormValue("n")
	if len(e) == 0 || len(n) == 0 {
		result, _ := json.Marshal(map[string]string{"error": c.Lang["pool_error"]})
		return "", errors.New(string(result))
	}*/
	email := c.r.FormValue("email")
	if !utils.ValidateEmail(email) {
		return "", utils.JsonAnswer("Incorrect email", "error").Error()
	}
	nodePrivateKey := c.r.FormValue("node_private_key")
	if !utils.CheckInputData(nodePrivateKey, "private_key") {
		return "", utils.JsonAnswer("Incorrect private_key", "error").Error()
	}
	//publicKey := utils.MakeAsn1([]byte(n), []byte(e))
	log.Debug("3")

	// если мест в пуле нет, то просто запишем юзера в очередь
	pool_max_users, err := c.Single("SELECT pool_max_users FROM config").Int()
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	if len(c.CommunityUsers) >= pool_max_users {
		err = c.ExecSql("INSERT INTO pool_waiting_list ( email, time, user_id ) VALUES ( ?, ?, ? )", email, utils.Time(), userId)
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
		return "", utils.JsonAnswer(c.Lang["pool_is_full"], "error").Error()
	}

	// регистрируем юзера в пуле
	// вначале убедимся, что такой user_id у нас уже не зареган
	community, err := c.Single("SELECT user_id FROM community WHERE user_id  =  ?", userId).Int64()
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	if community != 0 {
		return utils.JsonAnswer(c.Lang["pool_user_id_is_busy"], "success").String(), nil
	}
	err = c.ExecSql("INSERT INTO community ( user_id ) VALUES ( ? )", userId)
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}

	schema_ := &schema.SchemaStruct{}
	schema_.DCDB = c.DCDB
	schema_.DbType = c.ConfigIni["db_type"]
	schema_.PrefixUserId = int(userId)
	schema_.GetSchema()

	prefix := utils.Int64ToStr(userId) + "_"
	minerId, err := c.GetMinerId(userId)
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	if minerId > 0 {
		err = c.ExecSql("INSERT INTO "+prefix+"my_table ( user_id, miner_id, status, email ) VALUES  (?, ?, ?, ?)", userId, minerId, "miner", email)
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
	} else {
		err = c.ExecSql("INSERT INTO "+prefix+"my_table ( user_id, status, email ) VALUES (?, ?, ?)", userId, "miner", email)
		if err != nil {
			return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
		}
	}

	publicKey, err := c.GetUserPublicKey(userId)
	err = c.ExecSql("INSERT INTO "+prefix+"my_keys ( public_key, status ) VALUES ( [hex], 'approved' )", utils.BinToHex(publicKey))
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	nodePublicKey, err := utils.GetPublicFromPrivate(nodePrivateKey)
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}
	err = c.ExecSql("INSERT INTO "+prefix+"my_node_keys ( private_key, public_key ) VALUES ( ?, [hex] )", nodePrivateKey, nodePublicKey)
	if err != nil {
		return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error()
	}

	c.sess.Delete("restricted")
	return utils.JsonAnswer(c.Lang["pool_sign_up_success"], "success").String(), nil
}