[PATCH] Add readonly mode to scp, sftp_server

Gary Fernandez GaryF at livevault.com
Wed Nov 6 02:33:00 EST 2002


This patch adds a readonly mode to scp and sftp_server.  This allows clients
to only read files from the server, but not to write them.

Patch is based on OpenSSH 3.4p1

*** scp.c@@\main\1 Tue Oct  1 17:25:16 2002
--- scp.c Wed Oct  2 06:05:14 2002
***************
*** 122,127 ****
--- 122,130 ----
  /* This is set to zero if the progressmeter is not desired. */
  int showprogress = 1;
  
+ /* deny client write operations */
+ int readonly = 0;
+ 
  /* This is the program to execute for the secured connection. ("ssh" or
-S) */
  char *ssh_program = _PATH_SSH_PROGRAM;
  
***************
*** 307,312 ****
--- 310,319 ----
  		exit(errs != 0);
  	}
  	if (tflag) {
+	if (readonly) {
+          	run_err("permission denied");
+         		exit(1);
+         }
  		/* Receive data. */
  		sink(argc, argv);
  		exit(errs != 0);

*** sftp-server.c@@\main\1 Tue Oct  1 17:27:26 2002
--- sftp-server.c Tue Nov  5 10:07:54 2002
***************
*** 52,57 ****
--- 52,60 ----
  /* Version of client */
  int version;
  
+ /* deny client write operations */
+ int readonly = 0;
+ 
  /* portable attibutes, etc. */
  
  typedef struct Stat Stat;
***************
*** 390,395 ****
--- 393,404 ----
  	pflags = get_int();		/* portable flags */
  	a = get_attrib();
  	flags = flags_from_portable(pflags);
+ 	if (((flags & O_ACCMODE) == O_RDWR) ||
+ 		((flags & O_ACCMODE) == O_WRONLY)) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
  	TRACE("open id %u name %s flags %d mode 0%o", id, name, pflags,
mode);
  	fd = open(name, flags, mode);
***************
*** 587,592 ****
--- 596,606 ----
  	id = get_int();
  	name = get_string(NULL);
  	a = get_attrib();
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	TRACE("setstat id %u name %s", id, name);
  	if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
  		ret = truncate(name, a->size);
***************
*** 802,807 ****
--- 816,826 ----
  
  	id = get_int();
  	name = get_string(NULL);
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	TRACE("remove id %u name %s", id, name);
  	ret = unlink(name);
  	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
***************
*** 820,825 ****
--- 839,849 ----
  	id = get_int();
  	name = get_string(NULL);
  	a = get_attrib();
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
  	    a->perm & 0777 : 0777;
  	TRACE("mkdir id %u name %s mode 0%o", id, name, mode);
***************
*** 838,843 ****
--- 862,872 ----
  
  	id = get_int();
  	name = get_string(NULL);
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	TRACE("rmdir id %u name %s", id, name);
  	ret = rmdir(name);
  	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
***************
*** 881,886 ****
--- 910,920 ----
  	id = get_int();
  	oldpath = get_string(NULL);
  	newpath = get_string(NULL);
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	TRACE("rename id %u old %s new %s", id, oldpath, newpath);
  	/* fail if 'newpath' exists */
  	if (stat(newpath, &st) == -1) {
***************
*** 927,932 ****
--- 970,980 ----
  	id = get_int();
  	oldpath = get_string(NULL);
  	newpath = get_string(NULL);
+ 	if (readonly) {
+ 		status = SSH2_FX_PERMISSION_DENIED;
+ 		send_status(id, status);
+ 		return;
+ 	}
  	TRACE("symlink id %u old %s new %s", id, oldpath, newpath);
  	/* fail if 'newpath' exists */
  	if (stat(newpath, &st) == -1) {




More information about the openssh-unix-dev mailing list