Example #1
0
/** @brief waits for a response of the scp server
 * @internal
 * @param response pointer where the response message must be
 * copied if any. This pointer must then be free'd.
 * @returns the return code.
 * @returns SSH_ERROR a error occured
 */
int ssh_scp_response(ssh_scp scp, char **response){
	unsigned char code;
	int r;
	char msg[128];
	r=channel_read(scp->channel,&code,1,0);
	if(r == SSH_ERROR)
		return SSH_ERROR;
	if(code == 0)
		return 0;
	if(code > 2){
		ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code);
		scp->state=SSH_SCP_ERROR;
		return SSH_ERROR;
	}
	r=ssh_scp_read_string(scp,msg,sizeof(msg));
	if(r==SSH_ERROR)
		return r;
	/* Warning */
	if(code == 1){
		ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg);
		ssh_log(scp->session,SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg);
		if(response)
			*response=strdup(msg);
		return 1;
	}
	if(code == 2){
		ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg);
		if(response)
			*response=strdup(msg);
		return 2;
	}
	/* Not reached */
	return SSH_ERROR;
}
Example #2
0
File: scp.c Project: Paxxi/libssh
/**
 * @brief Wait for a scp request (file, directory).
 *
 * @returns             SSH_SCP_REQUEST_NEWFILE:       The other side is sending
 *                                                     a file
 *                      SSH_SCP_REQUEST_NEWDIR:  The other side is sending
 *                                                     a directory
 *                      SSH_SCP_REQUEST_ENDDIR: The other side has
 *                                                     finished with the current
 *                                                     directory
 *                      SSH_SCP_REQUEST_WARNING: The other side sent us a warning
 *                      SSH_SCP_REQUEST_EOF: The other side finished sending us
 *                                           files and data.
 *                      SSH_ERROR:                     Some error happened
 *
 * @see ssh_scp_read()
 * @see ssh_scp_deny_request()
 * @see ssh_scp_accept_request()
 * @see ssh_scp_request_get_warning()
 */
int ssh_scp_pull_request(ssh_scp scp){
  char buffer[MAX_BUF_SIZE] = {0};
  char *mode=NULL;
  char *p,*tmp;
  uint64_t size;
  char *name=NULL;
  int err;
  if(scp==NULL)
      return SSH_ERROR;
  if(scp->state != SSH_SCP_READ_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state");
    return SSH_ERROR;
  }
  err=ssh_scp_read_string(scp,buffer,sizeof(buffer));
  if(err==SSH_ERROR){
	if(ssh_channel_is_eof(scp->channel)){
		scp->state=SSH_SCP_TERMINATED;
		return SSH_SCP_REQUEST_EOF;
	}
    return err;
  }
  p=strchr(buffer,'\n');
  if(p!=NULL)
	  *p='\0';
  SSH_LOG(SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer);
  switch(buffer[0]){
    case 'C':
      /* File */
    case 'D':
      /* Directory */
      p=strchr(buffer,' ');
      if(p==NULL)
        goto error;
      *p='\0';
      p++;
      //mode=strdup(&buffer[1]);
      scp->request_mode=ssh_scp_integer_mode(&buffer[1]);
      tmp=p;
      p=strchr(p,' ');
      if(p==NULL)
        goto error;
      *p=0;
      size = strtoull(tmp,NULL,10);
      p++;
      name=strdup(p);
      SAFE_FREE(scp->request_name);
      scp->request_name=name;
      if(buffer[0]=='C'){
        scp->filelen=size;
        scp->request_type=SSH_SCP_REQUEST_NEWFILE;
      } else {
        scp->filelen='0';
        scp->request_type=SSH_SCP_REQUEST_NEWDIR;
      }
      scp->state=SSH_SCP_READ_REQUESTED;
      scp->processed = 0;
      return scp->request_type;
      break;
    case 'E':
    	scp->request_type=SSH_SCP_REQUEST_ENDDIR;
    	ssh_channel_write(scp->channel,"",1);
    	return scp->request_type;
    case 0x1:
    	ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]);
    	scp->request_type=SSH_SCP_REQUEST_WARNING;
    	SAFE_FREE(scp->warning);
    	scp->warning=strdup(&buffer[1]);
    	return scp->request_type;
    case 0x2:
    	ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]);
    	return SSH_ERROR;
    case 'T':
      /* Timestamp */
    default:
      ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer);
      return SSH_ERROR;
  }

  /* a parsing error occured */
  error:
  SAFE_FREE(name);
  SAFE_FREE(mode);
  ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer);
  return SSH_ERROR;
}