Beispiel #1
0
func openAndParse(filename string, parser func(io.Reader) map[string]string) (map[string]string, error) {
	if f, err := os.Open(filename); err == nil {
		defer f.Close()
		return parser(f), nil
	} else {
		return nil, tools.NewError(err, "openAndParse", "os.Open")
	}
}
Beispiel #2
0
func (d *SubprocessData) SetupFile(filename string, read bool) (*os.File, error) {
	writer, e := OpenFileForRedirect(filename, read)
	if e != nil {
		return nil, tools.NewError(e, "SetupFile", "OpenFile")
	}

	d.closeAfterStart = append(d.closeAfterStart, writer)
	return writer, nil
}
Beispiel #3
0
func (s *Contester) GridfsCopy(request *contester_proto.CopyOperations, response *contester_proto.FileStats) error {
	var sandbox *Sandbox
	var err error
	if request.SandboxId != nil {
		sandbox, err = getSandboxById(s.Sandboxes, *request.SandboxId)
		if err != nil {
			return tools.NewError(err, "GridfsGet", "getSandboxById")
		}
		sandbox.Mutex.RLock()
		defer sandbox.Mutex.RUnlock()
	}

	s.mu.RLock()
	defer s.mu.RUnlock()

	if s.Storage == nil {
		return fmt.Errorf("can't gridfs.Copy if storage isn't set")
	}

	response.Entries = make([]*contester_proto.FileStat, 0, len(request.Entries))
	for _, item := range request.Entries {
		if item.LocalFileName == nil || item.RemoteLocation == nil {
			continue
		}

		resolved, _, err := resolvePath(s.Sandboxes, item.GetLocalFileName(), false)
		if err != nil {
			continue // TODO
		}

		stat, err := s.Storage.Copy(resolved, item.GetRemoteLocation(), item.GetUpload(),
			item.GetChecksum(), item.GetModuleType(), item.GetAuthorizationToken())

		if err != nil {
			log.Errorf("gridfs copy error: %+v", err)
			continue
		}

		if !item.GetUpload() && sandbox != nil {
			err = sandbox.Own(resolved)
			if err != nil {
				log.Errorf("sandbox.Own error: %+v", err)
				continue
			}
		}

		if stat != nil {
			response.Entries = append(response.Entries, stat)
		}
	}

	return nil
}
Beispiel #4
0
func (d *SubprocessData) SetupInputMemory(b []byte) (*os.File, error) {
	reader, writer, e := os.Pipe()
	if e != nil {
		return nil, tools.NewError(e, "SetupInputMemory", "os.Pipe")
	}
	d.closeAfterStart = append(d.closeAfterStart, reader)
	d.startAfterStart = append(d.startAfterStart, func() error {
		_, err := io.Copy(writer, bytes.NewBuffer(b))
		if err1 := writer.Close(); err == nil {
			err = err1
		}
		return err
	})
	return reader, nil
}
Beispiel #5
0
func (d *SubprocessData) SetupOutputMemory(b *bytes.Buffer) (*os.File, error) {
	reader, writer, e := os.Pipe()
	if e != nil {
		return nil, tools.NewError(e, "SetupOutputMemory", "os.Pipe")
	}

	d.closeAfterStart = append(d.closeAfterStart, writer)

	d.startAfterStart = append(d.startAfterStart, func() error {
		_, err := io.Copy(b, io.LimitReader(reader, MAX_MEM_OUTPUT))
		reader.Close()
		return err
	})
	return writer, nil
}
Beispiel #6
0
func (sub *Subprocess) CreateFrozen() (*SubprocessData, error) {
	d := &SubprocessData{}

	si := &syscall.StartupInfo{}
	si.Cb = uint32(unsafe.Sizeof(*si))
	si.Flags = win32.STARTF_FORCEOFFFEEDBACK | syscall.STARTF_USESHOWWINDOW
	si.ShowWindow = syscall.SW_SHOWMINNOACTIVE

	useCreateProcessWithLogonW := sub.NoJob || win32.IsWindows8OrGreater()

	if !useCreateProcessWithLogonW && sub.Options != nil && sub.Options.Desktop != "" {
		si.Desktop = syscall.StringToUTF16Ptr(sub.Options.Desktop)
	}

	ec := tools.ErrorContext("CreateFrozen")

	e := d.wAllRedirects(sub, si)
	if e != nil {
		return nil, e
	}

	pi := &syscall.ProcessInformation{}

	applicationName := win32.StringPtrToUTF16Ptr(sub.Cmd.ApplicationName)
	commandLine := win32.StringPtrToUTF16Ptr(sub.Cmd.CommandLine)
	environment := win32.ListToEnvironmentBlock(sub.Environment)
	currentDirectory := win32.StringPtrToUTF16Ptr(sub.CurrentDirectory)

	var syscallName string

	syscall.ForkLock.Lock()
	wSetInherit(si)

	if sub.Login != nil {
		if useCreateProcessWithLogonW {
			syscallName = "CreateProcessWithLogonW"
			e = win32.CreateProcessWithLogonW(
				syscall.StringToUTF16Ptr(sub.Login.Username),
				syscall.StringToUTF16Ptr("."),
				syscall.StringToUTF16Ptr(sub.Login.Password),
				win32.LOGON_WITH_PROFILE,
				applicationName,
				commandLine,
				win32.CREATE_SUSPENDED|syscall.CREATE_UNICODE_ENVIRONMENT,
				environment,
				currentDirectory,
				si,
				pi)
		} else {
			syscallName = "CreateProcessAsUser"
			e = win32.CreateProcessAsUser(
				sub.Login.HUser,
				applicationName,
				commandLine,
				nil,
				nil,
				true,
				win32.CREATE_NEW_PROCESS_GROUP|win32.CREATE_NEW_CONSOLE|win32.CREATE_SUSPENDED|
					syscall.CREATE_UNICODE_ENVIRONMENT|win32.CREATE_BREAKAWAY_FROM_JOB,
				environment,
				currentDirectory,
				si,
				pi)
		}
	} else {
		syscallName = "CreateProcess"
		e = syscall.CreateProcess(
			applicationName,
			commandLine,
			nil,
			nil,
			true,
			win32.CREATE_NEW_PROCESS_GROUP|win32.CREATE_NEW_CONSOLE|win32.CREATE_SUSPENDED|
				syscall.CREATE_UNICODE_ENVIRONMENT|win32.CREATE_BREAKAWAY_FROM_JOB,
			environment,
			currentDirectory,
			si,
			pi)
	}

	closeDescriptors(d.closeAfterStart)
	syscall.ForkLock.Unlock()

	if e != nil {
		if errno, ok := e.(syscall.Errno); ok && errno == syscall.Errno(136) {
			e = tools.NewError(e, ERR_USER)
		}
		return nil, ec.NewError(e, syscallName)
	}

	d.platformData.hProcess = pi.Process
	d.platformData.hThread = pi.Thread
	d.platformData.hJob = syscall.InvalidHandle

	for _, dll := range sub.Options.InjectDLL {
		if e = InjectDll(d, sub.Options.LoadLibraryW, dll); e != nil {
			break
		}
	}

	if e != nil {
		// Terminate process/thread here.
		d.platformData.terminateAndClose()
		return nil, ec.NewError(e, "InjectDll")
	}

	if sub.ProcessAffinityMask != 0 {
		e = win32.SetProcessAffinityMask(d.platformData.hProcess, sub.ProcessAffinityMask)
		if e != nil {
			d.platformData.terminateAndClose()

			return nil, ec.NewError(e, "SetProcessAffinityMask")
		}
	}

	if !sub.NoJob {
		e = CreateJob(sub, d)
		if e != nil {
			if sub.FailOnJobCreationFailure {
				d.platformData.terminateAndClose()

				return nil, ec.NewError(e, "CreateJob")
			}
			log.Error("CreateFrozen/CreateJob: %s", e)
		} else {
			e = win32.AssignProcessToJobObject(d.platformData.hJob, d.platformData.hProcess)
			if e != nil {
				syscall.CloseHandle(d.platformData.hJob)
				d.platformData.hJob = syscall.InvalidHandle
				if sub.FailOnJobCreationFailure {
					d.platformData.terminateAndClose()

					return nil, ec.NewError(e, "AssignProcessToJobObject")
				}
				log.Error("CreateFrozen/AssignProcessToJobObject: %s", e)
			}
		}
	}

	return d, nil
}