Пример #1
0
func rm(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get currentDir
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// get len args for rmdir
	lenArgs, _ := r.ReadByte()

	// only does something if more than "rmdir" is called, as above
	for i := 1; i < int(lenArgs); i++ {

		targetPath, _ := r.ReadString('\n')
		targetPath = strings.TrimSpace(targetPath)

		if !path.IsAbs(targetPath) {
			targetPath = path.Join(currentDir, targetPath)
		}

		fmt.Printf("\tUser %d called rm on: \"%s\"\n", uuid, targetPath)

		src, err := os.Stat(md.getPath() + "files" + targetPath)

		hidden := utils.IsHidden(targetPath)
		if hidden {
			fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", targetPath)
		}

		if !hidden && err == nil && !src.IsDir() && checkBase(uuid, targetPath, "w", md) {
			os.Remove(md.getPath() + "files" + targetPath)
		}
	}
	return nil
}
Пример #2
0
func rmdir(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get currentDir
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// get len args for rmdir
	lenArgs, _ := r.ReadByte()

	// only does something if more than "rmdir" is called, as above
	for i := 1; i < int(lenArgs); i++ {

		targetPath, _ := r.ReadString('\n')
		targetPath = strings.TrimSpace(targetPath)

		if !path.IsAbs(targetPath) {
			targetPath = path.Join(currentDir, targetPath)
		}

		fmt.Printf("\tUser %d called rmdir on: \"%s\"\n", uuid, targetPath)

		// this will only remove a dir that is empty, else it does nothing
		// BUG-NOTE: this command will also currently delete files (there is not
		// a different command to rmdir an rm in golang), so a check to make sure
		// the targetPath is a dir should take place (sample code for checking if
		// a path is a dir or a file is found in "cd" below).
		// NOTE: a nice to have would be a recursive remove similar to rm -rf,
		// but this is not needed

		src, err := os.Stat(md.getPath() + "files" + targetPath)

		hidden := utils.IsHidden(targetPath)
		if hidden {
			fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", targetPath)
		}

		if !hidden && err == nil && src.IsDir() && checkBase(uuid, targetPath, "w", md) {
			fi, _ := ioutil.ReadDir(md.getPath() + "files" + targetPath)
			if len(fi) == 1 {

				os.Remove(md.getPath() + "files" + targetPath + "/.perm")
			}
			os.Remove(md.getPath() + "files" + targetPath)
		}
	}
	return nil
}
Пример #3
0
func mkdir(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get currentDir
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// get lenArgs for mkdir
	lenArgs, _ := r.ReadByte()

	// if no more than "mkdir" is sent, nothing will happen
	// if errors occur, the dir will just not be made
	for i := 1; i < int(lenArgs); i++ {

		// for each arg, get the target path
		targetPath, _ := r.ReadString('\n')
		targetPath = strings.TrimSpace(targetPath)

		if !path.IsAbs(targetPath) {
			targetPath = path.Join(currentDir, targetPath)
		}

		fmt.Printf("\tUser %d called mkdir \"%s\"\n", uuid, targetPath)

		hidden := utils.IsHidden(targetPath)
		if hidden {
			fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", targetPath)
		}

		if !hidden && checkBase(uuid, targetPath, "w", md) {

			os.Mkdir(md.getPath()+"files"+targetPath, 0777)

			permissions := []bool{false, false, false, false, false, false}
			var groups []uint64

			err := createPerm(md.getPath()+"files"+targetPath, uuid, groups, permissions)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Пример #4
0
func request(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	//get currentDir
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// receive filename from client
	filename, _ := r.ReadString('\n')
	filename = strings.TrimSpace(filename)

	// Cleans the filepath for proper access use

	if !path.IsAbs(filename) {
		filename = path.Join(currentDir, filename)
	}

	fmt.Printf("\tUser %d called request on: \"%s\"\n", uuid, currentDir+filename)

	// check if the filename exists
	src, err := os.Stat(md.getPath() + "files" + filename)

	hidden := utils.IsHidden(filename)
	if hidden {
		fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", filename)
	}

	if err != nil || hidden { // not a path ie. not a dir OR a file

		fmt.Println("\tFile \"" + filename + "\" does not exist")

		// notify the client that it is not existant with code "2"
		w.WriteByte(1)
		w.Flush()
		return nil

	} else if src.IsDir() { // notify the client that the file exists with code "1"

		fmt.Println("\tPath \"" + filename + "\" is a directory")

		// notify that is a dir
		w.WriteByte(2)
		w.Flush()
		return nil

	} else if !checkFile(uuid, filename, "x", md) {

		fmt.Println("\tUnauthorised access to request file")
		w.WriteByte(3)
		w.Flush()
		return nil

	} else {

		fmt.Println("\tFile \"" + filename + "\" exists")

		// notify success
		w.WriteByte(4)
		w.Flush()
	}

	hash, unid, protected, _, _, _, err := getFile(md.getPath() + "files" + filename)

	if protected {
		w.WriteByte(1)
		w.Flush()
	} else {
		w.WriteByte(2)
		w.Flush()
	}

	md.stnodeDB.View(func(tx *bolt.Tx) error {
		// Assume bucket exists and has keys
		b := tx.Bucket([]byte("stnodes"))

		v := b.Get([]byte(unid))

		if v == nil {

			fmt.Println("\tNo stnode matching UNID: " + unid)
			w.WriteByte(1)
			w.Flush()
			return nil
		}

		w.WriteByte(2)
		w.Flush()

		var tmpStnode utils.Stnode
		json.Unmarshal(v, &tmpStnode)

		fmt.Println("\tGot details for stnode: protocol: " + tmpStnode.Protocol + ", address: " + tmpStnode.NAddress)

		w.WriteString(hash + "\n")
		w.WriteString(tmpStnode.Protocol + "\n")
		w.WriteString(tmpStnode.NAddress + "\n")
		w.Flush()

		return nil
	})

	return nil
}
Пример #5
0
func cd(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get current dir and target path
	currentDir, _ := r.ReadString('\n')
	targetPath, _ := r.ReadString('\n')

	currentDir = strings.TrimSpace(currentDir)
	targetPath = strings.TrimSpace(targetPath)

	if !path.IsAbs(targetPath) {
		targetPath = path.Join(currentDir, targetPath)
	}

	fmt.Printf("\tUser %d called cd \"%s\"\n", uuid, targetPath)

	// check if the source dir exist
	src, err := os.Stat(md.getPath() + "files" + targetPath)

	hidden := utils.IsHidden(targetPath)
	if hidden {
		fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", targetPath)

	}

	if err != nil || hidden { // not a path ie. not a dir OR a file

		fmt.Println("\tPath is not a directory")

		// notify the client that it is not a dir with error code "1"
		w.WriteByte(1)
		w.Flush()

	} else { // is a path, but is it a dir or a file?

		// check if the source is indeed a directory or not
		if !src.IsDir() {

			fmt.Println("\tPath is not a directory")

			// notify the client that it is not a dir with error code "1"
			w.WriteByte(1)
			w.Flush()

		} else if !checkEntry(uuid, targetPath, "x", md) { // success!

			fmt.Println("\tAccess denied to dir " + targetPath)
			// notify success to client (no specific code, just not 1 or 0)
			w.WriteByte(2)
			w.Flush()

		} else {

			// create a clean path that the user can display on the cmd line
			fmt.Printf("\tPath \"%s\" is a directory\n", targetPath)

			w.WriteByte(3)
			w.Flush()

			// send the new path back to the user
			w.WriteString(targetPath + "\n")
			w.Flush()
		}
	}
	return nil
}
Пример #6
0
// Case commands for Mdserv
func ls(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get current dir
	// NOTE: here and in other locations, trimming whitespace may be more desirable
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// get the length of arguments to the ls command
	inArgs, _ := r.ReadByte()

	lenArgs := int(inArgs)
	verbose, _ := r.ReadByte()

	if verbose == 1 {
		lenArgs = lenArgs - 1
		fmt.Printf("\tUser %d called verbose ls\n", uuid)
	}

	// the message which will be returned to the user, each entry will be
	// comma separated for the client to interpret

	if lenArgs == 1 {

		fmt.Printf("\tUser %d called ls on: \"%s\"\n", uuid, currentDir)
	}

	// if only the ls command was called
	if lenArgs == 1 && checkEntry(uuid, currentDir, "r", md) {

		files, err := ioutil.ReadDir(md.getPath() + "files" + currentDir)
		if err != nil {
			w.Flush()
		}

		if currentDir == "/" || currentDir == "" {
			w.WriteByte(uint8(len(files)))
			w.Flush()
		} else {
			w.WriteByte(uint8(len(files) - 1))
			w.Flush()
		}

		// iterate over the files, and comma separate them while appending to msg
		for _, file := range files {
			if !utils.IsHidden(file.Name()) {
				targetPath := path.Join(currentDir, file.Name())
				prefix := ""
				ownerStr := ""
				if verbose == 1 {
					src, err := os.Stat(md.getPath() + "files" + targetPath)
					if err == nil && !src.IsDir() {
						//fmt.Println("Looking for path: " + md.getPath() + "files" + path.Join(currentDir, file.Name()))

						_, _, _, owner, _, permissions, err := getFile(md.getPath() + "files" + path.Join(currentDir, file.Name()))
						//fmt.Printf("filestats: %d, %v, %v\n", owner, groups, permissions)

						if err != nil {

							fmt.Println("\t\tError finding .permissions for path: " + path.Join(currentDir, file.Name()))
							return nil

						}

						//fmt.Printf("File read stats %v\n", permissions)

						ownerStr = "  " + strconv.FormatUint(owner, 10)
						prefix = "-"
						for _, b := range permissions {
							if b {
								prefix = prefix + "r--"
							} else {
								prefix = prefix + "---"
							}
						}
					} else if err == nil && src.IsDir() {

						//fmt.Println("Looking for path: " + md.getPath() + "files" + path.Join(currentDir, file.Name(), ".perm"))

						owner, _, permissions, err := getPerm(path.Join(md.getPath(), "files", currentDir, file.Name()))
						if err != nil {

							fmt.Println("\t\tError finding .permissions for path: " + path.Join(currentDir, file.Name()))
							return nil

						} else {

							ownerStr = "  " + strconv.FormatUint(owner, 10)
							prefix = "d"
							for i, b := range permissions {
								if b && i%3 == 0 {
									prefix = prefix + "r"
								} else if b && i%3 == 1 {
									prefix = prefix + "w"
								} else if b && i%3 == 2 {
									prefix = prefix + "x"
								} else {
									prefix = prefix + "-"
								}
							}
						}
					}
					prefix = prefix + ownerStr + "\t"
				}

				//fmt.Printf("Writing %d of %d = %s\n", i, len(files), file.Name())
				w.WriteString(prefix + file.Name() + "\n")
				w.Flush()
			}
		}
		return nil
	} else if lenArgs == 1 {
		w.WriteByte(0)
		w.Flush()
		return nil
	}

	// loop for dealing with one or more args

	for j := 1; j < lenArgs; j++ {

		// reading in this arg
		targetPath, _ := r.ReadString('\n')
		targetPath = strings.TrimSpace(targetPath)

		if !path.IsAbs(targetPath) {
			targetPath = path.Join(currentDir, targetPath)
		}

		fmt.Printf("\tUser %d called ls on: \"%s\"\n", uuid, targetPath)

		files, err := ioutil.ReadDir(md.getPath() + "files" + targetPath)

		if err != nil {

			hidden := utils.IsHidden(targetPath)
			if hidden {
				fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", targetPath)
			}

			// if it is not a directory, skip it and try the next arg
			w.WriteByte(0)
			w.Flush()
			continue

		} else if checkEntry(uuid, targetPath, "r", md) {

			if targetPath == "/" || targetPath == "" {
				w.WriteByte(uint8(len(files) + 1))
				w.Flush()
			} else {

				//		fmt.Printf("Num writes = %d\n", len(files))
				w.WriteByte(uint8(len(files)))
				w.Flush()
			}

			//	fmt.Println("Writing header: " + targetPath + ":")
			w.WriteString(targetPath + ":" + "\n")
			w.Flush()
			for _, file := range files {
				if !utils.IsHidden(file.Name()) {

					prefix := ""
					ownerStr := ""
					if verbose == 1 {
						src, err := os.Stat(md.getPath() + "files" + targetPath + "/" + file.Name())
						//				fmt.Println("IN VERBOSE: " + md.getPath() + "files" + targetPath + file.Name())

						if err == nil && !src.IsDir() {
							//					fmt.Println("Looking for file1 path: " + md.getPath() + "files" + path.Join(targetPath, file.Name()))

							_, _, _, owner, _, permissions, err := getFile(md.getPath() + "files" + path.Join(targetPath, file.Name()))
							if err != nil {

								fmt.Println("\t\tError finding .permissions for path: " + path.Join(targetPath, file.Name()))
								break

							}
							ownerStr = "  " + strconv.FormatUint(owner, 10)

							prefix = "-"
							for _, b := range permissions {
								if b {
									prefix = prefix + "r--"
								} else {
									prefix = prefix + "---"
								}
							}
						} else if err == nil && src.IsDir() {

							//					fmt.Println("Looking for perm1 path: " + md.getPath() + "files" + path.Join(targetPath, file.Name(), ".perm"))

							owner, _, permissions, err := getPerm(md.getPath() + "files" + path.Join(targetPath, file.Name()))
							if err != nil {

								fmt.Println("\t\tError finding .permissions for path: " + path.Join(targetPath, file.Name()))
								break

							} else {
								ownerStr = "  " + strconv.FormatUint(owner, 10)
								prefix = "d"
								for i, b := range permissions {
									if b && i%3 == 0 {
										prefix = prefix + "r"
									} else if b && i%3 == 1 {
										prefix = prefix + "w"
									} else if b && i%3 == 2 {
										prefix = prefix + "x"
									} else {
										prefix = prefix + "-"
									}
								}
							}
						}
						prefix = prefix + ownerStr + "\t"

					}

					//			fmt.Printf("Writing %d of %d = %s = %s\n", i, len(files), file.Name(), prefix)
					w.WriteString(prefix + file.Name() + "\n")
					w.Flush()
				}
			}
		} else {
			w.WriteByte(0)
			w.Flush()
		}
	}

	// print for terminal's sake
	return nil
}
Пример #7
0
func send(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get current dir
	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	// receive filename from client
	filename, _ := r.ReadString('\n')
	filename = strings.TrimSpace(filename)

	// clean the path
	if !path.IsAbs(filename) {
		filename = path.Join(currentDir, filename)
	}

	fmt.Printf("\tUser %d called send to \"%s\"\n", uuid, currentDir+filename)

	// check if the filename exists already
	_, err = os.Stat(md.getPath() + "files" + filename)

	hidden := utils.IsHidden(filename)
	if hidden {
		fmt.Printf("\tCall to hidden filepath \"%s\" is not permitted\n", filename)
	}

	if !checkBase(uuid, filename, "w", md) {

		fmt.Println("\tUser does not have permission to send to this directory.")
		w.WriteByte(3)
		w.Flush()

		return nil

	} else if err != nil && !hidden { // not a path ie. not a dir OR a file

		fmt.Println("\tFile \"" + filename + "\" does not already exist here")

		// notify the client that it is not already on system
		w.WriteByte(2)
		w.Flush()

	} else { // notify the client that the file exists with error code "1"

		fmt.Println("\tFile already exists in this directory")
		w.WriteByte(1)
		w.Flush()

		return nil
	}

	// is the user encrypting the file?
	protected := false
	enc, _ := r.ReadByte()
	if enc == 1 { // we are encrypting

		protected = true
		fmt.Println("\tReceiving encrypted file")
		// send the pubkeys of users here

		// get lenArgs
		lenArgs, _ := r.ReadByte()

		for i := 0; i < int(lenArgs); i++ {

			md.userDB.View(func(tx *bolt.Tx) error {

				b := tx.Bucket([]byte("users"))

				// get the proposed uuid for a user
				tmpUuid, _ := r.ReadString('\n')
				tmpUuid = strings.TrimSpace(tmpUuid)
				uuidUint64, _ := strconv.ParseUint(tmpUuid, 10, 64)

				v := b.Get(itob(uuidUint64))

				if v == nil {

					fmt.Println("\tNo user profile matching UUID: " + tmpUuid)
					w.WriteString("INV" + "\n")
					w.Flush()
					return nil
				}

				var tmpUser utils.User
				json.Unmarshal(v, &tmpUser)

				fmt.Println("\tFound user: "******"\n")
				w.Write([]byte(tmpUser.Pubkey.N.String() + "\n"))
				w.Write([]byte(strconv.Itoa(tmpUser.Pubkey.E) + "\n"))
				w.Flush()

				return nil
			})

		}

	} else if enc == 2 {

		//invalid cmd on client side
		return nil
		// else we are not
	}

	// get the hash of the file
	hash := utils.ReadHashAsString(r)

	var success byte
	var unid string

	md.stnodeDB.View(func(tx *bolt.Tx) error {
		// Assume bucket exists and has keys
		b := tx.Bucket([]byte("stnodes"))

		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {

			w.WriteByte(1) // got a stnode
			w.Flush()

			var tmpStnode utils.Stnode
			json.Unmarshal(v, &tmpStnode)

			fmt.Println("\tGot details for stnode: protocol: " + tmpStnode.Protocol + ", address: " + tmpStnode.NAddress)

			w.WriteString(tmpStnode.Protocol + "\n")
			w.WriteString(tmpStnode.NAddress + "\n")
			unid = tmpStnode.Unid
			w.Flush()

			success, _ = r.ReadByte()
			if success != 1 {
				fmt.Println("\tSuccessful send to stnode from client")
				return nil
			}
		}

		w.WriteByte(2) // no more stnodes
		w.Flush()

		return nil
	})

	if success != 2 {
		fmt.Println("\tNo stnodes were available to the client")
		return nil
	}

	success, _ = r.ReadByte()
	if success != 1 {
		fmt.Println("\tError on client side sending file to stnode")
		return nil
	}

	permissions := []bool{false, false}
	var groups []uint64
	err = createFile(md.getPath()+"files"+filename, hash, unid, protected, uuid, groups, permissions)
	if err != nil {
		panic(err)
	}

	return nil
}
Пример #8
0
func deny(uuid uint64, conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	currentDir, _ := r.ReadString('\n')
	currentDir = strings.TrimSpace(currentDir)

	flag, _ := r.ReadString('\n')
	flag = strings.TrimSpace(flag)
	if flag == "INV" {
		fmt.Printf("\t\tInvalid flag from user %d\n", uuid)
		return nil
	}
	lenArgs, _ := r.ReadByte()

	targetPath, _ := r.ReadString('\n')
	targetPath = strings.TrimSpace(targetPath)

	if !path.IsAbs(targetPath) {
		targetPath = path.Join(currentDir, targetPath)
	}

	fmt.Printf("\tUser %d called deny %s on: \"%s\"\n", uuid, flag, targetPath)

	src, err := os.Stat(md.getPath() + "files" + targetPath)
	if err != nil || utils.IsHidden(targetPath) {
		// exists, not hidden path

		fmt.Printf("\tUser %d call to deny %s on: \"%s\" was invalid: target does not exist\n", uuid, flag, targetPath)
		return nil
	}

	var groups []uint64

	if src.IsDir() {
		addPerms, _ := r.ReadString('\n')
		addPerms = strings.TrimSpace(addPerms)

		for i := 4; i < int(lenArgs); i++ {
			group, _ := r.ReadString('\n')
			gid, err := strconv.ParseUint(strings.TrimSpace(group), 10, 64)
			if err != nil {
				continue
			}
			groups = append(groups, gid)
		}

		if checkEntry(uuid, targetPath, "owner", md) {

			owner, existingGroups, permissions, err := getPerm(md.getPath() + "files" + targetPath)
			if err != nil {
				fmt.Println("\t\tError: no .perm file exists at \"" + md.getPath() + "files" + targetPath + "/.perm\"")
				return nil
			}

			switch flag {
			case "-g":
				fmt.Printf("\tDenying groups ")
				for _, g := range groups {
					for i, gr := range existingGroups {
						if g == gr {
							existingGroups = append(existingGroups[:i], existingGroups[i+1:]...)
							fmt.Printf("%d, ", g)
							break
						}
					}
				}
				fmt.Print("for: ")

				if strings.Contains(addPerms, "r") {
					permissions[0] = false
					fmt.Print("r")

				}
				if strings.Contains(addPerms, "w") {
					permissions[1] = false
					fmt.Print("w")

				}
				if strings.Contains(addPerms, "x") {
					permissions[2] = false
					fmt.Print("x")

				}
				fmt.Println(" to " + targetPath)

			case "-w":

				fmt.Printf("\tDenying world for: ")

				if strings.Contains(addPerms, "r") {
					permissions[3] = false
					fmt.Print("r")

				}
				if strings.Contains(addPerms, "w") {
					permissions[4] = false
					fmt.Print("w")

				}
				if strings.Contains(addPerms, "x") {
					permissions[5] = false
					fmt.Print("x")

				}
				fmt.Println(" to " + targetPath)
			}

			err = createPerm(md.getPath()+"files"+targetPath, owner, existingGroups, permissions)
			if err != nil {
				fmt.Println("\t\tError: there was an issue setting .perm for \"" + md.getPath() + "files" + targetPath + "/.perm\"\n\t\tCould not set new permissions")
			}
		}

	} else {

		for i := 3; i < int(lenArgs); i++ {
			group, _ := r.ReadString('\n')
			gid, err := strconv.ParseUint(strings.TrimSpace(group), 10, 64)
			if err != nil {
				continue
			}
			groups = append(groups, gid)
		}

		if checkFile(uuid, targetPath, "x", md) {
			hash, stnode, protected, owner, existingGroups, permissions, err := getFile(md.getPath() + "files" + targetPath)
			if err != nil {
				fmt.Println("\t\tError: no permissions could be read for file: \"" + md.getPath() + "files" + targetPath + "\"\n\t\tCould not set new permissions")
				return nil
			}

			switch flag {
			case "-g":
				fmt.Printf("\tDenying groups ")

				for _, g := range groups {
					for i, gr := range existingGroups {
						if g == gr {
							existingGroups = append(existingGroups[:i], existingGroups[i+1:]...)
							fmt.Printf("%d, ", g)
							break
						}
					}
				}
				fmt.Println("for request access to " + targetPath)

				permissions[0] = false

			case "-w":
				fmt.Println("\tDenying world for request access to " + targetPath)
				permissions[1] = false
			}

			err = createFile(md.getPath()+"files"+targetPath, hash, stnode, protected, owner, existingGroups, permissions)
			if err != nil {
				fmt.Println("\t\tError re-writing permissions for file: " + targetPath)
			}
		}
	}
	return nil
}