/* Remove virtual IP interfaces from the system. */
void ssh_vxworks_virtual_adapter_uninit(void)
{
  VxWorksVa *va;
  int i;
  STATUS status;

  for (i = 0; i < vxworks_va_num; i++)
    {
      va = &vxworks_va_tab[i];

      if (!va->cookie)
        continue;

#if defined(WITH_IPV6) && defined(INET6)
      if (ip6Detach(i, vxworks_va_devname) != OK)
        SSH_TRACE(SSH_D_ERROR, ("%s: ip6Detach failed", va->name));
#endif /* defined(WITH_IPV6) && defined(INET6) */

      if (ipDetach(i, vxworks_va_devname) != OK)
        SSH_TRACE(SSH_D_ERROR, ("%s: ipDetach failed", va->name));

      if ((status = muxDevStop(va->cookie)) != OK)
        SSH_TRACE(
          SSH_D_ERROR,
          ("%s: muxDevStop failed, status %d", va->name, (int)status));

      if ((status = muxDevUnload(vxworks_va_devname, i)) != OK)
        SSH_TRACE(
          SSH_D_ERROR,
          ("%s: muxDevUnload failed, status %d", va->name, (int)status));

      va->cookie = NULL;
    }
}
Exemple #2
0
void signer_can_send(void *context)
{
    SshSigner signer = (SshSigner) context;

    static Boolean packet_already_sent = FALSE;

    SSH_ASSERT(signer != NULL);

    if (packet_already_sent)
        return;
    else
        packet_already_sent = TRUE;


    if (signer->packet_waiting)
    {
        /* send packet */
        SSH_TRACE(0, ("Sending signature to ssh2-client."));

        ssh_packet_wrapper_send_encode(signer->wrapper,
                                       SSH_AUTH_HOSTBASED_SIGNATURE,
                                       SSH_FORMAT_UINT32_STR,
                                       signer->packet_payload,
                                       signer->packet_payload_len,
                                       SSH_FORMAT_END);

        signer->packet_waiting = FALSE;
    }
}
/* Attach a virtual IP interface to the IPsec engine. */
void ssh_virtual_adapter_attach(
  SshInterceptor interceptor,
  SshInterceptorIfnum adapter_ifnum,
  SshVirtualAdapterPacketCB packet_cb,
  SshVirtualAdapterDetachCB detach_cb,
  void *adapter_context,
  SshVirtualAdapterStatusCB callback,
  void *context)
{
  VxWorksVa *va;
  SshVirtualAdapterDetachCB old_detach_cb;
  void *old_adapter_context;

  SSH_DEBUG(SSH_D_HIGHOK, ("attach ifnum %d", (int)adapter_ifnum));

  if (!(va = vxworks_va_find_va(adapter_ifnum)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to attach a nonexistent ifnum %d", (int)adapter_ifnum));

      if (callback)
        callback(
          SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
          adapter_ifnum,
          NULL,
          SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
          NULL,
          context);

      return;
    }

  if (va->detach_cb)
    {
      old_detach_cb = va->detach_cb;
      old_adapter_context = va->adapter_context;
      va->detach_cb = NULL;
      va->adapter_context = NULL;

      SSH_DEBUG(
        SSH_D_HIGHOK,
        ("calling detach_cb of %s, ifnum %d because of new attach",
         va->name, (int)va->ifnum));

      old_detach_cb(old_adapter_context);
    }

  va->adapter_context = adapter_context;
  va->packet_cb = packet_cb;
  va->detach_cb = detach_cb;
  va->interceptor = interceptor;
  va->attached = 1;

  SSH_DEBUG(
    SSH_D_HIGHOK, ("attached %s, ifnum %d", va->name, (int)va->ifnum));

  vxworks_va_report(va, SSH_VIRTUAL_ADAPTER_ERROR_OK, callback, context);
}
Exemple #4
0
void t_tcpc_tcp_callback(SshTcpError      error,
                         SshStream    stream,
                         void*                context)
{
  t_tcpc_context  pcontext = context;




  SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_tcp_callback"));

  switch (error)
    {
    case SSH_TCP_OK:
      pcontext->pstream = stream;
      ssh_stream_set_callback(pcontext->pstream,
                              t_tcpc_stream_callback,
                              pcontext);
      ssh_xregister_timeout(pcontext->timeout,
                            0,
                            t_tcpc_timeout_callback,
                            pcontext);
      break;
    case SSH_TCP_NEW_CONNECTION:
      ssh_tcp_destroy_listener(pcontext->ptcplistener);
      pcontext->ptcplistener = 0;
      pcontext->pstream = stream;
      ssh_stream_set_callback(pcontext->pstream,
                              t_tcpc_stream_callback,
                              pcontext);
      break;
    case SSH_TCP_NO_ADDRESS:
      SSH_NOTREACHED;
      break;
    case SSH_TCP_NO_NAME:
      SSH_NOTREACHED;
      break;
    case SSH_TCP_UNREACHABLE:
      SSH_NOTREACHED;
      break;
    case SSH_TCP_REFUSED:
      SSH_NOTREACHED;
      break;
    case SSH_TCP_TIMEOUT:
      SSH_NOTREACHED;
      break;
    case SSH_TCP_FAILURE:
      SSH_NOTREACHED;
      break;
    default:
      SSH_NOTREACHED;
      break;
    }
}
/* VA device send handler subroutine called through netJobAdd(). */
static void vxworks_va_send_sub(END_OBJ *end, M_BLK_ID m)
{
  VxWorksVa *va = (void *)end;
  SshInterceptorInternalPacket ipp;

  vxworks_va_sends_processed++;

  if (!va->attached)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: not attached, dropping packet", va->name));
      m_freem(m);
      return;
    }

  if (!va->packet_cb)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: no packet_cb, dropping packet", va->name));
      m_freem(m);
      return;
    }

  if (!(ipp =
        ssh_interceptor_packet_alloc_header(
          va->interceptor,
          SSH_PACKET_FROMPROTOCOL,
          SSH_PROTOCOL_ETHERNET,
          va->ifnum,
          SSH_INTERCEPTOR_INVALID_IFNUM)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("%s: out of interceptor headers, dropping packet", va->name));
      m_freem(m);
      return;
    }

  ipp->head = m;

  va->packet_cb(
    va->interceptor, (void *)ipp, va->adapter_context);
}
Exemple #6
0
void signer_received_eof(void *context)
{
    SshSigner signer = (SshSigner)context;

    /* Cancel self-destruct. */
    ssh_cancel_timeouts(signer_destroy_timeout, SSH_ALL_CONTEXTS);

    SSH_TRACE(0, ("EOF received from packetstream. Exiting."));

    signer_free_context(signer);

    exit(0);
}
/* VA device send handler. */
static STATUS vxworks_va_send(END_OBJ *end , M_BLK_ID m)
{
  VxWorksVa *va = (void *)end;

  SSH_DEBUG(SSH_D_LOWOK, ("send on %s", va->name));

  /* Submit the packet as netJob for two reasons: 1) to avoid
     executing engine code from other than tNetTask, and 2) to avoid
     recursive calls to in_arpinput(). Without terminating the call
     stack here, the latter would occur when sending the first IP
     packet to the VA. The packet would be buffered pending ARP in the
     OS stack and when the spoofed ARP response was given to the
     stack, in_arpinput() would call the intercepted output function
     which would cause another ARP request generated by the IPsec
     engine during flow creation and another spoofed ARP response and
     so the buffered packet would be sent again because it was not
     cleared in the stack before calling the output function. */

  /* Discard packet if too many messages pending */
  if (vxworks_va_sends_submitted - vxworks_va_sends_processed >=
      VXWORKS_VA_SENDS_MAX)
    {
      SSH_TRACE(
        SSH_D_ERROR, ("%s: too many netJobs, dropping packet", va->name));
      m_freem(m);
      return OK;
    }
  if (netJobAdd((FUNCPTR)vxworks_va_send_sub, (int)end, (int)m, 0, 0, 0) != OK)
    {
      SSH_TRACE(
        SSH_D_ERROR, ("%s: netJobAdd failed, dropping packet", va->name));
      m_freem(m);
      return OK;
    }
  vxworks_va_sends_submitted++;
  return OK;
}
/* Send a packet to the IP stack like it was received by the virtual
   IP interface indexed by pp->ifnum_in. */
void ssh_virtual_adapter_send(SshInterceptor interceptor,
			      SshInterceptorPacket pp)
{
  SshInterceptorInternalPacket ipp;
  VxWorksVa *va;
  M_BLK_ID m;

  if (!(va = vxworks_va_find_va(pp->ifnum_out)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to send to a nonexistent ifnum %d", (int)pp->ifnum_out));

      ssh_interceptor_packet_free(pp);
      return;
    }

  if (pp->protocol != SSH_PROTOCOL_ETHERNET)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: dropping non-ethernet packet", va->name));

      ssh_interceptor_packet_free(pp);
      return;
    }

  ipp = (void *)pp;
  m = ipp->head;
  ipp->head = NULL;
  ssh_interceptor_packet_free_header(ipp);

  SSH_DEBUG(
    SSH_D_LOWOK,
    ("feeding receive packet to %s, ifnum %d", va->name, (int)va->ifnum));

  END_RCV_RTN_CALL(&va->end, m);
}
Exemple #9
0
/* Callback, which notifies that packetstream has received EOF from
   the other side. */
void auth_hostbased_received_eof(void *context)
{
  SshClientHostbasedAuth state = (SshClientHostbasedAuth) context;
  
  SSH_TRACE(0, ("received EOF from ssh-signer2."));
  
  ssh_packet_wrapper_send_eof(state->wrapper);
  ssh_packet_wrapper_destroy(state->wrapper);
  state->wrapper = NULL;

  *(state->state_placeholder) = NULL;
  
  /* Send failure message up, and return. */
  (*state->completion)(SSH_AUTH_CLIENT_FAIL, state->user, NULL,
                       state->completion_context);
}
Exemple #10
0
void t_tcpc_timeout_callback(void *context)
{
  t_tcpc_context  pcontext = context;

  SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_timeout_callback"));

  if (! pcontext || !pcontext->pdata)
    return;

  ssh_buffer_append(pcontext->pbuffer,
                    pcontext->pdata,
                    strlen(pcontext->pdata));

  t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT,
                         pcontext);

  ssh_xregister_timeout(pcontext->timeout,
                        0,
                        t_tcpc_timeout_callback,
                        pcontext);
}
/* VA device load function. */
static END_OBJ *vxworks_va_load(char *init_string, void *arg)
{
  VxWorksVa *va;
  char *token, *last;
  int unit, end_initialized;

  if (!init_string)
    return NULL;

  /* Empty init string indicates driver name query */
  if (!*init_string)
    {
      strcpy(init_string, vxworks_va_devname);
      return NULL;
    }

  /* Otherwise begin loading */
  end_initialized = 0;

  /* Get VA pointer given by us to muxDevLoad() */
  va = arg;
  unit = (int)(va - vxworks_va_tab);

  /* Verify unit number in the beginning of the init string */
  if (!(token = strtok_r(init_string, ":", &last)) || atoi(token) != unit)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: bad unit number in init string", va->name));
      return NULL;
    }

  SSH_DEBUG(SSH_D_HIGHOK, ("loading %s", va->name));

  if (END_OBJ_INIT(&va->end, &va->end.devObject, vxworks_va_devname, unit,
                   &vxworks_va_funcs, vxworks_va_desc) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: END_OBJ_INIT failed", va->name));
      goto fail;
    }
  end_initialized = 1;

#if VXWORKS_NETVER < 55122
#ifdef INCLUDE_RFC_2233

  /* Initialize MIB-II entries (for RFC 2233 ifXTable) */
  if (!(va->end.pMib2Tbl =
        m2IfAlloc(M2_ifType_ethernet_csmacd,
                  va->enet_addr, sizeof va->enet_addr,
                  vxworks_va_mtu, vxworks_va_speed,
                  vxworks_va_devname, unit)))
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: m2IfAlloc failed", va->name));
      goto fail;
    }
        
    /* 
     * Set the RFC2233 flag bit in the END object flags field and
     * install the counter update routines.
     */
    m2IfPktCountRtnInstall(va->end.pMib2Tbl, m2If8023PacketCount);

    /*
     * Make a copy of the data in mib2Tbl struct as well. We do this
     * mainly for backward compatibility issues. There might be some
     * code that might be referencing the END pointer and might
     * possibly do lookups on the mib2Tbl, which will cause all sorts
     * of problems.
     */
    bcopy(&va->end.pMib2Tbl->m2Data.mibIfTbl,
          &va->end.mib2Tbl, sizeof va->end.mib2Tbl);

    /* Mark the device ready */
    END_OBJ_READY (&va->end,
                   IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST |
                   END_MIB_2233);

#else /* INCLUDE_RFC_2233 */

    /* Old RFC 1213 mib2 interface */
    if (END_MIB_INIT (&va->end, M2_ifType_ethernet_csmacd,
                      va->enet_addr, sizeof va->enet_addr,
                      vxworks_va_mtu, vxworks_va_speed) == ERROR)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: END_MIB_INIT failed", va->name));
      goto fail;
    }

    /* Mark the device ready */
    END_OBJ_READY (&va->end, IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);

#endif /* INCLUDE_RFC_2233 */
#else /* VXWORKS_NETVER < 55122 */

  if (endM2Init(&va->end, M2_ifType_ethernet_csmacd,
                va->enet_addr, sizeof va->enet_addr,
                vxworks_va_mtu, vxworks_va_speed,
                IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: endM2Init failed", va->name));
      goto fail;
    }

#endif /* VXWORKS_NETVER < 55122 */

  return &va->end;

 fail:
  if (end_initialized)
    END_OBJECT_UNLOAD(&va->end);
  return NULL;
}
/* Get information about a virtual IP interface. */
void ssh_virtual_adapter_get_status(
  SshInterceptor interceptor,
  SshInterceptorIfnum adapter_ifnum,
  SshVirtualAdapterStatusCB callback,
  void *context)
{
  VxWorksVa *va;
  int i;

  if (adapter_ifnum == SSH_INTERCEPTOR_INVALID_IFNUM)
    {
      SSH_DEBUG(SSH_D_HIGHOK, ("get status of all virtual adapters"));

      for (i = 0; i < vxworks_va_num; i++)
        {
          va = &vxworks_va_tab[i];

          if (!va->cookie)
            continue;

          SSH_DEBUG(
            SSH_D_HIGHOK,
            ("returning status of %s, ifnum %d", va->name, (int)va->ifnum));

          vxworks_va_report(
            va, SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE, callback, context);
        }

      SSH_DEBUG(SSH_D_HIGHOK, ("returning last status"));

      callback(
        SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
        SSH_INTERCEPTOR_INVALID_IFNUM,
        NULL,
        SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
        NULL,
        context);
      return;
    }
  else
    {
      SSH_DEBUG(SSH_D_HIGHOK, ("get status of ifnum %d", (int)adapter_ifnum));

      if (!(va = vxworks_va_find_va(adapter_ifnum)))
        {
          SSH_TRACE(
            SSH_D_ERROR,
            ("trying to get status of a nonexistent ifnum %d",
             (int)adapter_ifnum));

	  callback(
            SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
            adapter_ifnum,
            NULL, 
            SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
            NULL,
            context);
          return;
        }

      SSH_DEBUG(
        SSH_D_HIGHOK,
        ("returning status of %s, ifnum %d", va->name, (int)va->ifnum));

      vxworks_va_report(va, SSH_VIRTUAL_ADAPTER_ERROR_OK, callback, context);
    }
}
/* Configure a virtual IP interface. */
void ssh_virtual_adapter_configure(
  SshInterceptor interceptor,
  SshInterceptorIfnum adapter_ifnum,
  SshVirtualAdapterState adapter_state,
  SshUInt32 num_addresses,
  SshIpAddr addresses,
  SshVirtualAdapterParams params,
  SshVirtualAdapterStatusCB callback,
  void *context)
{
  VxWorksVa *va;
  char *addrstr;
  SshIpAddr ipaddr;
  int i, addrlen, mask, oldflags, newflags;
  int inet_up = 0;
#if defined(WITH_IPV6) && defined(INET6)
  int inet6_up = 0;
#endif /* defined(WITH_IPV6) && defined(INET6) */

  SSH_DEBUG(SSH_D_HIGHOK, ("configure ifnum %d", (int)adapter_ifnum));

  if (!(va = vxworks_va_find_va(adapter_ifnum)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to get status of a nonexistent ifnum %d",
         (int)adapter_ifnum));

      if (callback)
        callback(
          SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
          adapter_ifnum,
          NULL, 
          SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
          NULL,
          context);
      return;
    }

  /* Check addresses to determine IFF_INET_UP and IFF_INET6_UP status */
  if (adapter_state != SSH_VIRTUAL_ADAPTER_STATE_DOWN && addresses)
    {
      for (i = 0; i < num_addresses; i++)
        {
          ipaddr = &addresses[i];
          if (SSH_IP_IS4(ipaddr))
            inet_up = 1;
#if defined(WITH_IPV6) && defined(INET6)
          else if (SSH_IP_IS6(ipaddr))
            inet6_up = 1;
#endif /* defined(WITH_IPV6) && defined(INET6) */
        }          
    }

  /* Clear addresses if new addresses are being configured or
     interface is being turned off */
  if (addresses || adapter_state == SSH_VIRTUAL_ADAPTER_STATE_DOWN)
    {
      for (i = 0; i < va->ip4addr_num; i++)
        {
          addrstr = va->ip4addr_tab[i];

          SSH_DEBUG(
            SSH_D_MIDOK,
            ("deleting IPv4 address %s on %s, ifnum %d",
             addrstr, va->name, (int)va->ifnum));

          if (ifAddrDelete(va->name, addrstr) != OK)
            SSH_TRACE(
              SSH_D_ERROR,
              ("%s: deleting IPv4 address %s failed", va->name, addrstr));
        }
      va->ip4addr_num = 0;

      if (ifRouteDelete(vxworks_va_devname, va->end.devObject.unit) ==
          ERROR)
        SSH_TRACE(SSH_D_ERROR, ("%s: deleting IPv4 routes failed", va->name));

#if defined(WITH_IPV6) && defined(INET6)
      for (i = 0; i < va->ip6addr_num; i++)
        {
          addrstr = va->ip6addr_tab[i];

          SSH_DEBUG(
            SSH_D_MIDOK,
            ("deleting IPv6 address %s on %s, ifnum %d",
             addrstr, va->name, (int)va->ifnum));

          if (if6AddrDelete(va->name, addrstr) != OK)
            SSH_TRACE(
              SSH_D_ERROR,
              ("%s: deleting IPv6 address %s failed", va->name, addrstr));
        }
      va->ip6addr_num = 0;
#endif /* defined(WITH_IPV6) && defined(INET6) */
    }

  /* Set interface status. */
  if (ifFlagGet(va->name, &oldflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot get interface flags"));
      return;
    }
  newflags = oldflags;
  if (inet_up
#if defined(WITH_IPV6) && defined(INET6)
      || inet6_up
#endif /* defined(WITH_IPV6) && defined(INET6) */
      )
    newflags |= IFF_UP;
  else
    newflags &= ~IFF_UP;
#if VXWORKS_NETVER >= 55122
  if (inet_up)
    newflags |= IFF_INET_UP;
  else
    newflags &= ~IFF_INET_UP;
#if defined(WITH_IPV6) && defined(INET6)
  if (inet6_up)
    newflags |= IFF_INET6_UP;
  else
    newflags &= ~IFF_INET6_UP;
#endif /* defined(WITH_IPV6) && defined(INET6) */
#endif /* VXWORKS_NETVER >= 55122 */
  if (newflags != oldflags && ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      return;
    }

  /* Add addresses if the addresses parameter is non-NULL and
     interface is not being turned off */
  if (addresses && adapter_state != SSH_VIRTUAL_ADAPTER_STATE_DOWN)
    {
      for (i = 0; i < num_addresses; i++)
        {
          ipaddr = &addresses[i];

          if (SSH_IP_IS4(ipaddr))
            {
              if (va->ip4addr_num >=
                  sizeof va->ip4addr_tab / sizeof va->ip4addr_tab[0])
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: too many IPv4 addresses, ignoring some", va->name));
                  break;
                }

              addrstr = va->ip4addr_tab[va->ip4addr_num];
              addrlen = sizeof va->ip4addr_tab[va->ip4addr_num];

              ssh_ipaddr_print(ipaddr, addrstr, addrlen);

              SSH_DEBUG(
                SSH_D_MIDOK,
                ("adding IPv4 address %s on %s, ifnum %d",
                 addrstr, va->name, (int)va->ifnum));

              mask = ~((1 << (32 - SSH_IP_MASK_LEN(ipaddr))) - 1) & 0xffffffff;

              if (ifAddrAdd(va->name, addrstr, NULL, mask) != OK)
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: adding IPv4 address %s failed", va->name, addrstr));
                  continue;
                }
              va->ip4addr_num++;
            }
#if defined(WITH_IPV6) && defined(INET6)
          else if (SSH_IP_IS6(ipaddr))
            {
              if (va->ip6addr_num >=
                  sizeof va->ip6addr_tab / sizeof va->ip6addr_tab[0])
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: too many IPv6 addresses, ignoring some", va->name));
                  break;
                }

              addrstr = va->ip6addr_tab[va->ip6addr_num];
              addrlen = sizeof va->ip6addr_tab[va->ip6addr_num];

              ssh_ipaddr_print(ipaddr, addrstr, addrlen);

              SSH_DEBUG(
                SSH_D_MIDOK,
                ("adding IPv6 address %s on %s, ifnum %d",
                 addrstr, va->name, (int)va->ifnum));

              if (if6AddrAdd(va->name, addrstr, SSH_IP_MASK_LEN(ipaddr), 0)
                  != OK)
                {
                  SSH_TRACE(
                    SSH_D_ERROR,
                    ("%s: adding IPv6 address %s failed", va->name, addrstr));
                  continue;
                }
              va->ip6addr_num++;
            }
#endif /* defined(WITH_IPV6) && defined(INET6) */
        }
    }

  /* Change MTU */
  if (params && params->mtu > 0)
    MIB_VAR_UPDATE(va->end.pMib2Tbl, M2_varId_ifMtu, (ULONG)params->mtu);

  /* Toggle IFF_UP twice to cause an interface event with up-to-date
     addresses in effect. */
  if (ifFlagGet(va->name, &oldflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot get interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }
  newflags = oldflags ^ IFF_UP;
  if (ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }
  newflags ^= IFF_UP;
  if (ifFlagSet(va->name, newflags) != OK)
    {
      SSH_TRACE(SSH_D_ERROR, ("%s: cannot set interface flags"));
      vxworks_va_report(
        va, SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR, callback, context);
      return;
    }

  SSH_DEBUG(
    SSH_D_HIGHOK, ("configured %s, ifnum %d", va->name, (int)va->ifnum));

  vxworks_va_report(va, SSH_VIRTUAL_ADAPTER_ERROR_OK, callback, context);
}
/* Detach a virtual IP interface from the IPsec engine. */
void ssh_virtual_adapter_detach(
  SshInterceptor interceptor,
  SshInterceptorIfnum adapter_ifnum,
  SshVirtualAdapterStatusCB callback,
  void *context)
{
  VxWorksVa *va;
  SshVirtualAdapterDetachCB detach_cb;
  void *adapter_context;
  SshIpAddrStruct addr;

  SSH_DEBUG(SSH_D_HIGHOK, ("detach ifnum %d", (int)adapter_ifnum));

  if (!(va = vxworks_va_find_va(adapter_ifnum)))
    {
      SSH_TRACE(
        SSH_D_ERROR,
        ("trying to detach a nonexistent ifnum %d", (int)adapter_ifnum));

      if (callback)
        callback(
          SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
          adapter_ifnum,
          NULL,
          SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
          NULL,
          context);

      return;
    }

  detach_cb = va->detach_cb;
  adapter_context = va->adapter_context;

  va->detach_cb = NULL;
  va->adapter_context = NULL;
  va->interceptor = NULL;
  va->attached = 0;

  if (detach_cb)
    {
      SSH_DEBUG(
        SSH_D_HIGHOK,
        ("calling detach_cb of %s, ifnum %d", va->name, (int)va->ifnum));

      detach_cb(adapter_context);
    }

  SSH_IP_UNDEFINE(&addr);

  ssh_virtual_adapter_configure(
    interceptor,
    adapter_ifnum,
    SSH_VIRTUAL_ADAPTER_STATE_DOWN,
    0,
    &addr,
    NULL,
    NULL,
    NULL);

  SSH_DEBUG(
    SSH_D_HIGHOK, ("detached %s, ifnum %d", va->name, (int)va->ifnum));

  vxworks_va_report(va, SSH_VIRTUAL_ADAPTER_ERROR_OK, callback, context);
}
Exemple #15
0
/* Encodes terminal modes for the terminal referenced by fd in a
   portable manner, and appends the modes to a buffer being
   constructed. Stores constructed buffers len to buf_len. This call
   always succeeds, but if an error happens during encoding, buf will
   be empty and buf_len will be 0 */
void ssh_encode_tty_flags(int fd, unsigned char **buf, size_t *buf_len)
     /*void tty_make_modes(int fd)*/
{
  SshBuffer buffer;  
#ifdef USING_TERMIOS
  struct termios tio;
#endif
#ifdef USING_SGTTY
  struct sgttyb tio;
  struct tchars tiotc;
  struct ltchars tioltc;
  int tiolm;
#ifdef TIOCGSTAT
  struct tstatus tiots;
#endif /* TIOCGSTAT */
#endif /* USING_SGTTY */
  int baud;

  if (!isatty(fd))
    {
      SSH_TRACE(2, ("Not a tty. (fd = %d)", fd));
      *buf = ssh_xstrdup("");
      *buf_len = 0;
      return;
    }
  
  ssh_buffer_init(&buffer);

  /* Get the modes. */
#ifdef USING_TERMIOS
  if (tcgetattr(fd, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("tcgetattr: %.100s", strerror(errno));
      goto error;
    }
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  if (ioctl(fd, TIOCGETP, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETP, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGETC, &tiotc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETC, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCLGET, &tiolm) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCLGET, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGLTC, &tioltc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGLTC, ...): %.100s", strerror(errno));
      goto error;
    }
#ifdef TIOCGSTAT
  if (ioctl(fd, TIOCGSTAT, &tiots) < 0) 
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGSTAT, ...): %.100s", strerror(errno));
      goto error;
    }
#endif /* TIOCGSTAT */
  /* termio's ECHOE is really both LCRTBS and LCRTERA - so wire them
     together */
  if (tiolm & LCRTBS)
    tiolm |= LCRTERA;
#endif /* USING_SGTTY */

  /* Store input and output baud rates. */
  baud = speed_to_baud(cfgetospeed(&tio));
  PUT_CHAR(TTY_OP_OSPEED);
  PUT_UINT32(baud);
  baud = speed_to_baud(cfgetispeed(&tio));
  PUT_CHAR(TTY_OP_ISPEED);
  PUT_UINT32(baud);

  /* Store values of mode flags. */
#ifdef USING_TERMIOS
#define TTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(tio.c_cc[NAME]);
#define TTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((tio.FIELD & NAME) != 0);
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)
#endif /* USING_TERMIOS */

#ifdef USING_SGTTY
#define TTYCHAR(NAME, OP)
#define TTYMODE(NAME, FIELD, OP)
#define SGTTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(NAME);
#define SGTTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) != 0);
#define SGTTYMODEN(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) == 0);
#endif /* USING_SGTTY */

#include "sshttyflagsi.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

  /* Mark end of mode data. */
  PUT_CHAR(TTY_OP_END);

  *buf_len = ssh_buffer_len(&buffer);
  *buf = ssh_xmemdup(ssh_buffer_ptr(&buffer), *buf_len);
  ssh_buffer_uninit(&buffer);

  SSH_DEBUG_HEXDUMP(5, ("encoded tty-flags buffer"), *buf, *buf_len);
  
  return;

 error:
  ssh_buffer_uninit(&buffer);
  *buf = ssh_xstrdup("");
  *buf_len = 0;
}
Exemple #16
0
/* Callback, which is used to notify that our packetstream has a
   packet for us.*/
void auth_hostbased_received_packet(SshPacketType type,
                                    const unsigned char *packet,
                                    size_t packet_len,
                                    void *context)
{
  SshBuffer *b;

  SshClientHostbasedAuth state = (SshClientHostbasedAuth) context;
  
  switch(type)
    {
    case SSH_AUTH_HOSTBASED_PACKET:
      SSH_TRACE(2, ("ssh-signer returned SSH_AUTH_HOSTBASED_PACKET "\
                    "(this is an error)"));
      /* signer shouldn't send this to us, so this is an error.*/
      /* XXX */
      break;
    case SSH_AUTH_HOSTBASED_SIGNATURE:
      SSH_TRACE(2, ("ssh-signer returned SSH_AUTH_HOSTBASED_SIGNATURE"));
      /* We've got a signature. */
      b = ssh_buffer_allocate();


      /* Destroy wrapper (and signer) */
      ssh_packet_wrapper_send_eof(state->wrapper);
      ssh_packet_wrapper_destroy(state->wrapper);
      state->wrapper = NULL;
      
      ssh_encode_buffer(b,
                        /* public key algorithm (string) */
                        SSH_FORMAT_UINT32_STR,
                        state->pubkey_algorithm,
                        strlen(state->pubkey_algorithm),
                        /* public key (string) */
                        SSH_FORMAT_UINT32_STR, state->pubkeyblob,
                        state->pubkeyblob_len,
                        /* client host name (FQDN, string) */
                        SSH_FORMAT_UINT32_STR, state->local_host_name,
                        strlen(state->local_host_name),
                        /* user name at client side */
                        SSH_FORMAT_UINT32_STR, state->local_user_name,
                        strlen(state->local_user_name),
                        /* signature */
                        SSH_FORMAT_DATA, packet, packet_len,
                        SSH_FORMAT_END);

      /* Detach the state structure from the state_placeholder. */
      *state->state_placeholder = NULL;
  
      /* Call the authentication method completion procedure. */
      (*state->completion)(SSH_AUTH_CLIENT_SEND, state->user, b,
                           state->completion_context);

      /* Free the buffer */
      ssh_buffer_free(b);

      /* XXX Free the state. */

      break;
    case SSH_AUTH_HOSTBASED_ERROR:
      /* Destroy wrapper (and signer) */
      ssh_packet_wrapper_send_eof(state->wrapper);
      ssh_packet_wrapper_destroy(state->wrapper);
      state->wrapper = NULL;

      SSH_TRACE(0, ("ssh-signer returned SSH_AUTH_HOSTBASED_ERROR"));
      /* Send failure message to server, and return. */
      (*state->completion)(SSH_AUTH_CLIENT_FAIL, state->user, NULL,
                           state->completion_context);
      break;
    }
}
Exemple #17
0
void signer_received_packet(SshPacketType type,
                            const unsigned char *data, size_t len,
                            void *context)
{
    /* Received. */
    unsigned int msg_byte; /* This is unsigned int because
                            SSH_FORMAT_CHAR expects uint; caused a
                            rather nasty bug during development (I
                            used SshUInt8, which wasn't long
                            enough => ssh_decode_array blew the
                            stack).*/
    char *userauth_str, *hostbased_str, *recv_pubkey_alg, *recv_hostname;
    char *recv_username;
    unsigned char *recv_pubkeyblob;
    size_t recv_pubkeyblob_len;
    /* Dug up by us. */
    char *pubkey_alg, *hostname, *username;
    unsigned char *pubkeyblob;
    size_t pubkeyblob_len;
    size_t hostname_len;

    /* Internal stuff*/
    SshSigner signer = (SshSigner) context;
    char hostkeyfile[512];
    char *comment;
    SshPrivateKey privkey;
    size_t sig_len, length_return;
    unsigned char *signature_buffer;
    SshCryptoStatus result;
    SshUser real_user;

    SSH_TRACE(2, ("Packet received."));

    switch(type)
    {
    case SSH_AUTH_HOSTBASED_PACKET:
        /* Check packet out, and if it's ok, sign it and send
           signature to ssh2. */

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(3, ("packet:"), \
                          data, len);
#endif /* HEXDUMPS */

        if (ssh_decode_array(data, len,
                             /* session id */
                             SSH_FORMAT_UINT32_STR, NULL, NULL,
                             /* SSH_MSG_USERAUTH_REQUEST (must be checked)*/
                             SSH_FORMAT_CHAR, &msg_byte,
                             /* user name */
                             SSH_FORMAT_UINT32_STR, NULL, NULL,
                             /* service "ssh-userauth" (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &userauth_str, NULL,
                             /* "hostbased" (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &hostbased_str, NULL,
                             /* public key algorithm for hostkey (must
                                be checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_pubkey_alg, NULL,
                             /* public hostkey and certificates (must be
                                checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_pubkeyblob,
                             &recv_pubkeyblob_len,
                             /* client host name (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_hostname, NULL,
                             /* user name on client host (must be checked) */
                             SSH_FORMAT_UINT32_STR, &recv_username, NULL,
                             SSH_FORMAT_END) != len || len == 0)
        {
            /* There was an error. */
            SSH_TRACE(0, ("Invalid packet."));
            goto error;
        }

        /* Get pubkeyblob, pubkeyblob_len, pubkey_alg, hostname and
           username. */

        /* Dig up hosts publickey. */
        if(signer->config->public_host_key_file[0] != '/')
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                     signer->config->public_host_key_file);
        }
        else
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                     signer->config->public_host_key_file);
        }

        SSH_TRACE(2, ("place to look for public key: %s", hostkeyfile));

        /* This pubkey*-stuff is for the client _host's_ public
           hostkey. */
        /* Getting pubkeyblob, pubkeyblob_len */
        SSH_DEBUG(4, ("Reading pubkey-blob from %s...", hostkeyfile));
        if (ssh2_key_blob_read(signer->effective_user_data, hostkeyfile, NULL,
                               &pubkeyblob,
                               &pubkeyblob_len, NULL)
                != SSH_KEY_MAGIC_PUBLIC)
        {
            SSH_TRACE(1, ("Reading public key failed."));
            goto error;
        }

        SSH_DEBUG(4, ("done."));

        if ((pubkey_alg =
                    ssh_pubkeyblob_type(pubkeyblob, pubkeyblob_len))
                == NULL)
        {
            SSH_TRACE(1, ("Couldn't figure out public key algorithm."));
            goto error;
        }

        /* Getting hostname. */
        hostname = ssh_xmalloc(MAXHOSTNAMELEN + 1);
        ssh_tcp_get_host_name(hostname, MAXHOSTNAMELEN + 1);
        hostname_len = strlen(hostname);
        /* Sanity check */
        SSH_ASSERT(hostname_len + 2 < MAXHOSTNAMELEN);
        /* We want FQDN. */
        hostname[hostname_len] = '.';
        hostname[hostname_len + 1] = '\0';

        /* Getting username. */
        real_user = ssh_user_initialize(NULL, FALSE);
        username = ssh_xstrdup(ssh_user_name(real_user));
        ssh_user_free(real_user, FALSE);

        /* Check all parameters. */
        if (msg_byte != SSH_MSG_USERAUTH_REQUEST)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("msg_byte != SSH_MSG_USERAUTH_REQUEST " \
                          "(msg_byte = %d)", msg_byte));
            goto error;
        }
        if (strcmp(userauth_str, SSH_USERAUTH_SERVICE) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("userauth_str != \"ssh-userauth\" (it was '%s')", \
                          userauth_str));
            goto error;
        }
        if (strcmp(hostbased_str, SSH_AUTH_HOSTBASED) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("hostbased_str != \"hostbased\" (it was '%s')", \
                          hostbased_str));
            goto error;
        }
        /* XXX has to be change when adding support for multiple hostkeys */
        if (strcmp(recv_pubkey_alg, pubkey_alg) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client gave us invalid pubkey-algorithms for our " \
                          "hostkey."));
            goto error;
        }

        if (recv_pubkeyblob_len == pubkeyblob_len)
        {
            if (memcmp(recv_pubkeyblob, pubkeyblob, pubkeyblob_len) != 0)
            {
                SSH_TRACE(1, ("Invalid packet."));
                SSH_DEBUG(1, ("client gave us wrong (or corrupted) " \
                              "public key."));
#ifdef HEXDUMPS
                SSH_DEBUG_HEXDUMP(3, ("client gave us:"), \
                                  recv_pubkeyblob, pubkeyblob_len);
                SSH_DEBUG_HEXDUMP(3, ("our pubkey:"), \
                                  recv_pubkeyblob, pubkeyblob_len);
#endif /* HEXDUMPS */
                goto error;
            }
        }
        else
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client gave us wrong (or corrupted) public key. " \
                          "Lengths differ (received: %d ; ours: %d)", \
                          recv_pubkeyblob_len, pubkeyblob_len));
            goto error;
        }

        if (strcmp(recv_hostname, hostname) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Wethinks the client gave us the wrong hostname. " \
                          "(client's opinion: '%s' ours: '%s'", \
                          recv_hostname, hostname));
            goto error;
        }
        if (strcmp(recv_username, username) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client definitely gave us the wrong user name. " \
                          "(it says: '%s' we know: '%s')", recv_username, \
                          username));
            goto error;
        }

        /* Sign the packet and send it to client. */

        /* If we've gotten this far, the packet is ok, and it can be
           signed. */

        SSH_TRACE(0, ("Received packet ok."));
        if(signer->config->public_host_key_file[0] != '/')
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                     signer->config->host_key_file);
        }
        else
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                     signer->config->host_key_file);
        }

        SSH_TRACE(2, ("place to look for private key: %s", hostkeyfile));

        if ((privkey = ssh_privkey_read(signer->effective_user_data, hostkeyfile, "",
                                        &comment, NULL)) == NULL)
            ssh_fatal("ssh_privkey_read from %s failed.", hostkeyfile);

        /* Check how big a chunk our private key can sign (this is
           purely a sanity check, as both of our signature schemas do
           their own hashing) */
        sig_len = ssh_private_key_max_signature_input_len(privkey);

        SSH_TRACE(2, ("max input length for signing: %d", sig_len));

        if (sig_len == 0)
        {
            SSH_TRACE(0, ("private key not capable of signing! " \
                          "(definitely an error)"));
            goto error;
        }
        else if (sig_len != -1 && sig_len < len)
        {
            SSH_TRACE(0, ("private key can't sign our data. (too much " \
                          "data (data_len %d, max input len for signing " \
                          "%d))", len, sig_len));
            goto error;
        }

        /* Now check how much we much buffer we must allocate for the
           signature. */
        sig_len = ssh_private_key_max_signature_output_len(privkey);

        SSH_TRACE(2, ("max output length for signature: %d", sig_len));

        signature_buffer = ssh_xcalloc(sig_len, sizeof(unsigned char));

        /* Do the actual signing. */

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(5, ("Signing following data"),
                          data + 4, len - 4);
#endif /* HEXDUMPS */

        if ((result = ssh_private_key_sign(privkey,
                                           data,
                                           len,
                                           signature_buffer,
                                           sig_len,
                                           &length_return,
                                           signer->random_state))
                != SSH_CRYPTO_OK)
        {
            SSH_TRACE(0, ("ssh_private_key_sign() returned %d.", result));
            goto error;
        }

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(5, ("Signature"), signature_buffer, length_return);
#endif /* HEXDUMPS */
        /* Send it to client. */
        signer->packet_payload = signature_buffer;
        signer->packet_payload_len = length_return;
        signer->packet_waiting = TRUE;

        if (ssh_packet_wrapper_can_send(signer->wrapper))
            signer_can_send(signer);

        /* XXX free dynamically allocated data. */
        ssh_xfree(username);

        break;
    case SSH_AUTH_HOSTBASED_SIGNATURE:
        /* We shouldn't get this type of packet. This is an error.*/
        SSH_TRACE(0, ("client sent us SSH_AUTH_HOSTBASED_SIGNATURE. This " \
                      "is an error."));
        goto error;
        break;
    case SSH_AUTH_HOSTBASED_ERROR:
        /* We shouldn't be getting this either. This is an error. */
        SSH_TRACE(0, ("client sent us SSH_AUTH_HOSTBASED_SIGNATURE_ERROR. " \
                      "This is an error. (This message can be sent by " \
                      "ssh-signer2 only)"));
        goto error;
        break;
    }
    return;

    /* We come here after errors. */
error:
    /* Send error message to ssh2, and wait for ssh2 to send
       EOF. */
    ssh_packet_wrapper_send_encode(signer->wrapper, SSH_AUTH_HOSTBASED_ERROR,
                                   SSH_FORMAT_END);

    /* Init a 5 second timeout. If ssh2 hasn't disconnected at
       that time, close stream.*/
    ssh_register_timeout(5L, 0L, signer_destroy_timeout, signer);

    return;
}
Exemple #18
0
/* This function processes an rhosts-style file (.rhosts, .shosts, or
   /etc/hosts.equiv).  This returns true if authentication can be granted
   based on the file, and returns zero otherwise.  All I/O will be done
   using the given uid with userfile. */
Boolean check_rhosts_file(uid_t uid, const char *filename,
                          const char *hostname,
                          const char *ipaddr, const char *client_user,
                          const char *server_user, void *context)
{
  SshUserFile uf;
  char buf[1024]; /* Must not be larger than host, user, dummy below. */
  SshServer server = (SshServer) context;
  
  /* Open the .rhosts file. */
  uf = ssh_userfile_open(uid, filename, O_RDONLY, 0);
  if (uf == NULL)
    return FALSE; /* Cannot read the .rhosts - deny access. */

  /* Go through the file, checking every entry. */
  while (ssh_userfile_gets(buf, sizeof(buf), uf))
    {
      /* All three must be at least as big as buf to avoid overflows. */
      char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp, *c;
      int negated;
      
      for(cp = buf; *cp; cp++)
        {
          if (*cp < 32 && !isspace(*cp))
            {
              SSH_TRACE(2, ("Found control characters in '%s', rest of "\
                            "the file ignored", filename));
              ssh_userfile_close(uf);
              return FALSE;
            }
        }
      for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
        ;
      if ((c = strchr(cp, '#')) != NULL)
        *c = '\0';
      if (*cp == '#' || *cp == '\n' || !*cp)
        continue;

      /* NO_PLUS is supported at least on OSF/1.  We skip it (we don't ever
         support the plus syntax). */
      if (strncmp(cp, "NO_PLUS", 7) == 0)
        continue;

      /* This should be safe because each buffer is as big as the whole
         string, and thus cannot be overwritten. */
      switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy))
        {
        case 0:
          SSH_DEBUG(2, ("Found empty line in %.100s.", filename));
          continue; /* Empty line? */
        case 1:
          /* Host name only. */
          strncpy(userbuf, server_user, sizeof(userbuf));
          userbuf[sizeof(userbuf) - 1] = 0;
          break;
        case 2:
          /* Got both host and user name. */
          break;
        case 3:
          SSH_TRACE(2, ("Found garbage in %.100s.", filename));
          continue; /* Extra garbage */
        default:
          continue; /* Weird... */
        }

      host = hostbuf;
      user = userbuf;
      /* Truncate host and user name to 255 to avoid buffer overflows in system
         libraries */
      if (strlen(host) > 255)
        host[255] = '\0';
      if (strlen(user) > 255)
        user[255] = '\0';
      negated = 0;

      /* Process negated host names, or positive netgroups. */
      if (host[0] == '-')
        {
          negated = 1;
          host++;
        }
      else
        if (host[0] == '+')
          host++;

      if (user[0] == '-')
        {
          negated = 1;
          user++;
        }
      else
        if (user[0] == '+')
          user++;

      /* Check for empty host/user names (particularly '+'). */
      if (!host[0] || !user[0])
        { 
          /* We come here if either was '+' or '-'. */
          SSH_TRACE(2, ("Ignoring wild host/user names in %.100s.", \
                        filename));
          continue;
        }
          
#ifdef HAVE_INNETGR
      
      /* Verify that host name matches. */
      if (host[0] == '@')
        {
          if (!innetgr(host + 1, (char *)hostname, NULL, NULL) &&
              !innetgr(host + 1, (char *)ipaddr, NULL, NULL))
            continue;
        }
      else
        if (!casefold_equal(host, hostname) && strcmp(host, ipaddr) != 0)
          continue; /* Different hostname. */

      /* Verify that user name matches. */
      if (user[0] == '@')
        {
          if (!innetgr(user + 1, NULL, (char *)client_user, NULL))
            continue;
        }
      else
        if (strcmp(user, client_user) != 0)
          continue; /* Different username. */

#else /* HAVE_INNETGR */

      if (!casefold_equal(host, hostname) && strcmp(host, ipaddr) != 0)
        continue; /* Different hostname. */

      if (strcmp(user, client_user) != 0)
        continue; /* Different username. */

#endif /* HAVE_INNETGR */

      /* XXX sync with ssh_server_auth_check_host */
      /* XXX this function is a silly place for this. This should be
         in ssh_server_auth_hostbased_rhosts(), where these checks
         would be performed before coming here. */
      {
        Boolean perm_denied = FALSE;
        
        if (server->config->denied_shosts)
          {
            if (!ssh_match_host_in_list(server->common->remote_host,
                                        server->common->remote_ip,
                                        server->config->denied_shosts))
              perm_denied = TRUE;
          }
      
        if (!perm_denied && server->config->allowed_shosts)
          {
            if (!ssh_match_host_in_list(server->common->remote_host,
                                        server->common->remote_ip,
                                        server->config->allowed_shosts))
              perm_denied = FALSE;
            else
              perm_denied = TRUE;
          }      
      
        /* RequireReverseMapping */
        if (server->config->require_reverse_mapping)
          {
            if (strcmp(server->common->remote_host,
                       server->common->remote_ip) == 0)
              {
                /* If remote host's ip-address couldn't be mapped to a
                   hostname and RequireReverseMapping = 'yes', deny
                   connection.*/
                perm_denied = TRUE;
              }
          }

        if (perm_denied)
          {
            ssh_log_event(server->config->log_facility, SSH_LOG_WARNING,
                          "Use of %s denied for %s", filename, host);
            SSH_TRACE(2, ("Use of %s denied for %s", filename, host));
            continue;
          }
      }
      
      /* Found the user and host. */
      ssh_userfile_close(uf);

      /* If the entry was negated, deny access. */
      if (negated)
        {
          SSH_TRACE(2, ("Matched negative entry in %.100s.", \
                        filename));
          return FALSE;
        }

      /* Accept authentication. */
      return TRUE;
    }
     
  /* Authentication using this file denied. */
  ssh_userfile_close(uf);
  return FALSE;
}
static SshEngineActionRet
engine_packet_handler_rule_lookup(SshEngine engine,
				  SshEnginePacketContext pc)
{
  Boolean policy_lookups_disabled;
  unsigned char src_ip[SSH_IP_ADDR_SIZE], dst_ip[SSH_IP_ADDR_SIZE];
  SshUInt16 src_port, dst_port;
  size_t len = 0;

  /* Check whether policy lookups are allowed. */
  policy_lookups_disabled = engine->policy_lookups_disabled;






  if (policy_lookups_disabled)
    {
      SSH_ENGINE_MARK_STAT(pc, SSH_ENGINE_STAT_NOLOOKUP);
      return SSH_ENGINE_RET_DROP;
    }

  /* Look up matching policy rules, unless it has already been cached
     into the policy context. */
  if (pc->rule == NULL)
    {
      engine_packet_handler_lookup_prepare(pc,
					   src_ip, &src_port,
					   dst_ip, &dst_port,
					   &len);
      pc->rule = ssh_engine_rule_lookup(engine,
					engine->policy_rule_set,
					src_ip, dst_ip, len,
					pc->ipproto,
					src_port, dst_port,
					pc);

      /* Check if 'pc->pp' got freed by ssh_engine_rule_lookup() */
      if (pc->pp == NULL)
	{
	  SSH_ENGINE_MARK_STAT(pc, SSH_ENGINE_STAT_ERRORDROP);
	  return SSH_ENGINE_RET_ERROR;
	}

      if (pc->rule == NULL)
        {
          SSH_ENGINE_MARK_STAT(pc, SSH_ENGINE_STAT_NORULE);
          SSH_TRACE(SSH_D_HIGHOK,
                    ("no policy rule found, using default rule"));

          /* Select a default rule. */
	  if (pc->pp && (pc->pp->flags & SSH_ENGINE_P_FROMLOCAL) &&
              ((src_port == 68 && dst_port == 67 && SSH_IP_IS4(&pc->dst)) ||
               (src_port == 546 && dst_port == 547 && SSH_IP_IS6(&pc->dst)))
	      && pc->ipproto == SSH_IPPROTO_UDP)
	    {
	      /* Outgoing DHCP requests map to the default DHCP rule. A flow 
	       is always created for such packets because on some operating 
	       systems the DHCP response packet may be dropped when the 
	       policymanager is not loaded. */
	      pc->rule = SSH_IP_IS6(&pc->dst) ?
		engine->dhcp_ipv6_rule : engine->dhcp_ipv4_rule;
	    }
	  else if (engine->ipm_open || 
		   (engine->flags & SSH_ENGINE_DROP_IF_NO_IPM))
	    pc->rule = engine->drop_rule;
	  else
	    pc->rule = engine->pass_rule;
	}

      /* Increment the reference count of the rule. */
      pc->rule->refcnt++;
#ifdef SSH_IPSEC_STATISTICS
      pc->rule->stats.times_used++;
#endif /* SSH_IPSEC_STATISTICS */
    }

  SSH_ASSERT(pc->rule != NULL);

  return SSH_ENGINE_RET_OK;
}
Exemple #20
0
int main(int argc, char* argv[])
{
  t_tcpc_context  pcontext = 0;
  SshGetOptData   pgetoptdata = 0;
  int                             i;

  SSH_TRACE(SSH_D_MY, ("%s", "main"));

  pcontext = ssh_xmalloc(sizeof (*pcontext));
  memset(pcontext, 0, sizeof (*pcontext));

  pgetoptdata = ssh_xmalloc(sizeof (*pgetoptdata));
  memset(pgetoptdata, 0, sizeof (*pgetoptdata));

  ssh_getopt_init_data(pgetoptdata);
  pcontext->pport_or_service = "23242";

  while ((i = ssh_getopt(argc, argv, "p:h:d:D:G:t:", pgetoptdata)) != -1)
    {
      switch (i)
        {
        case 'p':
          pcontext->pport_or_service = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'h':
          pcontext->phost_name_or_address = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'd':
          pcontext->pdata = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'D':
          ssh_debug_set_module_level(SSH_DEBUG_MODULE, atoi(pgetoptdata->arg));
          break;
        case 'G':
          ssh_debug_set_global_level(atoi(pgetoptdata->arg));
          break;
        case 't':
          pcontext->timeout = atoi(pgetoptdata->arg);
          break;
        default:
          SSH_NOTREACHED;
          break;
        }
    }

  ssh_xfree(pgetoptdata);

  ssh_event_loop_initialize();

  pcontext->pbuffer = ssh_buffer_allocate();

  if (pcontext->phost_name_or_address)
    {
      ssh_tcp_connect(pcontext->phost_name_or_address,
                      pcontext->pport_or_service,
                      NULL,
                      t_tcpc_tcp_callback,
                      pcontext);
    }
  else
    {
      pcontext->ptcplistener =
        ssh_tcp_make_listener(SSH_IPADDR_ANY_IPV4,
                              pcontext->pport_or_service,
                              NULL,
                              t_tcpc_tcp_callback,
                              pcontext);
    }

  ssh_event_loop_run();
  ssh_name_server_uninit();
  ssh_event_loop_uninitialize();

  ssh_buffer_free(pcontext->pbuffer);
  ssh_xfree(pcontext);
  ssh_util_uninit();
  return 0;
}
Exemple #21
0
void t_tcpc_stream_callback(SshStreamNotification        notification,
                            void*                                 context)
{
  t_tcpc_context  pcontext = context;
  char                    buf[4096];
  int                             i;

  SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_stream_callback"));

  switch (notification)
    {
    case SSH_STREAM_INPUT_AVAILABLE:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_INPUT_AVAILABLE"));
      while ((i = ssh_stream_read(pcontext->pstream,
                                  buf,
                                  4096)) > 0)
        {
          buf[i] = 0;
          SSH_TRACE(SSH_D_MY, ("read: %s", buf));

          if (pcontext->phost_name_or_address)
            {
              ssh_buffer_append(pcontext->pbuffer,
                                buf,
                                i);
              t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT,
                                     pcontext);
            }
          else
            {
              SSH_TRACE(SSH_D_MY, ("output: %s", buf));
            }
        }
      break;
    case SSH_STREAM_CAN_OUTPUT:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_CAN_OUTPUT"));
      if (ssh_buffer_len(pcontext->pbuffer) > 0)
        {
          i = ssh_stream_write(pcontext->pstream,
                               ssh_buffer_ptr(pcontext->pbuffer),
                               ssh_buffer_len(pcontext->pbuffer));

          if (i > 0)
            {
              ssh_buffer_consume(pcontext->pbuffer,
                                 i);
            }
        }
      break;
    case SSH_STREAM_DISCONNECTED:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_DISCONNECTED"));
#if 0
      /* BUG BUG BUG */
      ssh_stream_destroy(pcontext->pstream);
#endif /* 0 */
      ssh_event_loop_abort();
      break;
    default:
      SSH_NOTREACHED;
      break;
    }
}
Exemple #22
0
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream,
                                          void *context)
{
  SshRemoteTcpForward fwd = (SshRemoteTcpForward)context;
  char ip[20], port[20];
  SshBuffer buffer;

  SSH_DEBUG(5, ("connection to forwarded TCP/IP port"));
  
  /* We should only receive new connection notifications. */
  if (error != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

  SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s",
                fwd->port, ip, port));
  ssh_log_event(fwd->common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Connection to forwarded port %s from %s:%s",
                fwd->port, fwd->common->remote_host, port);

  /* XXXXXXXX */
#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);

    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port " \
                            "%s refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);
    
        return;
      }
    signal(SIGCHLD, old_handler);
        
    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "Remote fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Register that we have an open channel. */
  ssh_common_new_channel(fwd->common);
  
  /* Send a request to open a channel and connect it to the given port. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                    fwd->address_to_bind, strlen(fwd->address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port),
                    SSH_FORMAT_UINT32_STR, ip, strlen(ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL,
                             ssh_channel_tcp_connection_destroy,
                             (void *)fwd->common, NULL, NULL);
  ssh_buffer_uninit(&buffer);
}  
Exemple #23
0
Boolean ssh_channel_remote_tcp_forward_request(const char *type,
                                               const unsigned char *data,
                                               size_t len,
                                               void *context)
{
  SshCommon common = (SshCommon)context;
  char *address_to_bind;
  SshUInt32 port;
  char port_string[20];
  SshRemoteTcpForward fwd;
  SshChannelTypeTcpForward ct;

  SSH_DEBUG(5, ("remote TCP/IP forwarding request received"));
  ssh_log_event(common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Remote TCP/IP forwarding request received from host \"%s\", "\
                "by authenticated user \"%s\".",
                common->remote_host,
                ssh_user_name(common->user_data));
  
  ct = ssh_channel_ftcp_ct(common);
  
  /* Don't allow a server to send remote forwarding requests to the client. */
  if (common->client)
    {
      ssh_warning("Remote TCP/IP forwarding request from server denied.");
      return FALSE;
    }
  
  /* Parse the request. */
  if (ssh_decode_array(data, len,
                       SSH_FORMAT_UINT32_STR, &address_to_bind, NULL,
                       SSH_FORMAT_UINT32, &port,
                       SSH_FORMAT_END) != len)
    {
      SSH_DEBUG(0, ("bad data"));
      return FALSE;
    }

  /* Convert port number to a string. */
  snprintf(port_string, sizeof(port_string), "%ld", (unsigned long) port);

  /* If user is not logged in as a privileged user, don't allow
     forwarding of privileged ports. */
  if (port < 1024)
    {
      if (ssh_user_uid(common->user_data))
        {
          SSH_TRACE(2, ("User \"%s\" not root, tried to forward " \
                        "privileged port %ld.",
                        ssh_user_name(common->user_data),
                        (unsigned long) port));
          ssh_log_event(common->config->log_facility,
                        SSH_LOG_WARNING,
                        "User \"%s\" not root, tried to forward " \
                        "privileged port %ld.",
                        ssh_user_name(common->user_data),
                        (unsigned long) port);
          return FALSE;
        }
      else
        {
          ssh_log_event(common->config->log_facility,
                        SSH_LOG_NOTICE,
                        "Privileged user \"%s\" forwarding a privileged port.",
                        ssh_user_name(common->user_data));
        }
    }

  if (port >= 65536)
    {
      SSH_TRACE(2, ("User \"%s\" tried to forward " \
                    "port above 65535 (%ld).",
                    ssh_user_name(common->user_data), (unsigned long) port));
      ssh_log_event(common->config->log_facility,
                    SSH_LOG_WARNING,
                    "User \"%s\" tried to forward " \
                    "port above 65535 (%ld).",
                    ssh_user_name(common->user_data), (unsigned long) port);
      return FALSE;
    }
  
      
  /* Create a socket listener. */
  fwd = ssh_xcalloc(1, sizeof(*fwd));
  fwd->listener = ssh_tcp_make_listener(address_to_bind, port_string,
                                        ssh_channel_ftcp_incoming_connection,
                                        (void *)fwd);
  if (fwd->listener == NULL)
    {
      ssh_debug("Creating remote listener for %s:%s failed.",
                address_to_bind, port_string);
      ssh_log_event(common->config->log_facility,
                    SSH_LOG_NOTICE,
                    "Creating remote listener for %s:%s failed.",
                    address_to_bind, port_string);
      
      ssh_xfree(address_to_bind);
      ssh_xfree(fwd);
      return FALSE;
    }

  /* Fill the remaining fields. */
  fwd->common = common;
  fwd->address_to_bind = address_to_bind;
  fwd->port = ssh_xstrdup(port_string);
  fwd->connect_to_host = NULL;
  fwd->connect_to_port = NULL;

  /* Add to list of forwardings. */
  fwd->next = ct->remote_forwards;
  ct->remote_forwards = fwd;

  ssh_log_event(common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Port %ld set up for remote forwarding.",
                (unsigned long) port);
  
  return TRUE;
}  
Exemple #24
0
void ssh_decode_tty_flags(int fd, unsigned char *buf, size_t buf_len)
{
  SshBuffer buffer;
  
#ifdef USING_TERMIOS
  struct termios tio;
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  struct sgttyb tio;
  struct tchars tiotc;
  struct ltchars tioltc;
  int tiolm;
#ifdef TIOCGSTAT
  struct tstatus tiots;
#endif /* TIOCGSTAT */
#endif
  int opcode, baud;

  if (!isatty(fd))
    {
      SSH_TRACE(2, ("Not a tty. (fd = %d)", fd));
      return;
    }

  if (buf_len == 0)
    return;
  
  SSH_DEBUG_HEXDUMP(5, ("received tty-flags buffer"), buf, buf_len);

  ssh_buffer_init(&buffer);

  ssh_buffer_append(&buffer, buf, buf_len);
  
  /* Get old attributes for the terminal.  We will modify these flags. 
     I am hoping that if there are any machine-specific modes, they will
     initially have reasonable values. */
#ifdef USING_TERMIOS
  if (tcgetattr(fd, &tio) < 0)
    return;
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  if (ioctl(fd, TIOCGETP, &tio) < 0)
    return;
  if (ioctl(fd, TIOCGETC, &tiotc) < 0)
    return;
  if (ioctl(fd, TIOCLGET, &tiolm) < 0)
    return;
  if (ioctl(fd, TIOCGLTC, &tioltc) < 0)
    return;
#ifdef TIOCGSTAT
  if (ioctl(fd, TIOCGSTAT, &tiots) < 0)
    return;
#endif /* TIOCGSTAT */
#endif /* USING_SGTTY */

  for (;;)
    {
      ssh_decode_buffer(&buffer,
                    SSH_FORMAT_CHAR, &opcode,
                    SSH_FORMAT_END);
      
      switch(opcode)
        {
        case TTY_OP_END:
          goto set;

        case TTY_OP_ISPEED:
          baud = GET_UINT32();
          if (cfsetispeed(&tio, baud_to_speed(baud)) < 0)
            ssh_warning("cfsetispeed failed for %d", baud);
          break;

        case TTY_OP_OSPEED:
          baud = GET_UINT32();
          if (cfsetospeed(&tio, baud_to_speed(baud)) < 0)
            ssh_warning("cfsetospeed failed for %d", baud);
          break;

#ifdef USING_TERMIOS
#define TTYCHAR(NAME, OP)                               \
        case OP:                                        \
          tio.c_cc[NAME] = GET_UINT32();                \
          break;
#define TTYMODE(NAME, FIELD, OP)                        \
        case OP:                                        \
          if (GET_UINT32())                     \
            tio.FIELD |= NAME;                          \
          else                                          \
            tio.FIELD &= ~NAME;                         \
          break;
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)
#endif /* USING_TERMIOS */

#ifdef USING_SGTTY
#define TTYCHAR(NAME, OP)
#define TTYMODE(NAME, FIELD, OP)
#define SGTTYCHAR(NAME, OP)                             \
        case OP:                                        \
          NAME = GET_UINT32();                  \
          break;
#define SGTTYMODE(NAME, FIELD, OP)                      \
        case OP:                                        \
          if (GET_UINT32())                     \
            FIELD |= NAME;                              \
          else                                          \
            FIELD &= ~NAME;                             \
          break;
#define SGTTYMODEN(NAME, FIELD, OP)                     \
        case OP:                                        \
          if (GET_UINT32())                     \
            FIELD &= ~NAME;                             \
          else                                          \
            FIELD |= NAME;                              \
          break;
#endif /* USING_SGTTY */

#include "sshttyflagsi.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

        default:
          SSH_TRACE(1, ("Ignoring unsupported tty mode opcode %d (0x%x)",
                        opcode, opcode));
          /* Opcodes 0 to 160 are defined to have a uint32 argument. */
          if (opcode >= 0 && opcode < 160)
            {
              (void)GET_UINT32();
              break;
            }
          /* It is a truly undefined opcode (160 to 255).  We have no idea
             about its arguments.  So we must stop parsing.  Note that some
             data may be left in the packet; hopefully there is nothing more
             coming after the mode data. */
          ssh_warning("ssh_decode_tty_flags: unknown opcode %d", opcode);
          goto set;
        }
    }

 set:
  /* Set the new modes for the terminal. */
#ifdef USING_TERMIOS
  if (tcsetattr(fd, TCSANOW, &tio) < 0)
    ssh_warning("Setting tty modes failed: %.100s", strerror(errno));
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  /* termio's ECHOE is really both LCRTBS and LCRTERA -
     so wire them together */
  if (tiolm & LCRTERA)
    tiolm |= LCRTBS;
  if (ioctl(fd, TIOCSETP, &tio) < 0
      || ioctl(fd, TIOCSETC, &tiotc) < 0
      || ioctl(fd, TIOCLSET, &tiolm) < 0
      || ioctl(fd, TIOCSLTC, &tioltc) < 0
#ifdef TIOCSSTAT
      || ioctl(fd, TIOCSSTAT, &tiots) < 0
#endif /* TIOCSSTAT */
     ) 
    ssh_warning("Setting tty modes failed: %.100s", strerror(errno));
#endif /* USING_SGTTY */
}
/* Add virtual IP interfaces to the system. */
void ssh_vxworks_virtual_adapter_init(void)
{
  VxWorksVa *va;
  STATUS status;
  int i, started, ip_attached;
  void *cookie;
  unsigned short if_index;

  vxworks_va_nettask = taskIdSelf();

  for (i = 0; i < vxworks_va_num; i++)
    {
      va = &vxworks_va_tab[i];
      started = 0;
      ip_attached = 0;

      memset(va, 0, sizeof *va);

      ssh_snprintf(va->name, sizeof va->name, "%s%d", vxworks_va_devname, i);

      memset(va->enet_addr, 0, sizeof va->enet_addr);
      memcpy(va->enet_addr, vxworks_va_oui, sizeof vxworks_va_oui);
      va->enet_addr[sizeof va->enet_addr - 1] = (unsigned char)i;

      if (!(cookie = muxDevLoad(i, vxworks_va_load, "", FALSE, va)))
        {
          SSH_TRACE(SSH_D_ERROR, ("%s: muxDevLoad failed", va->name));
          goto fail;
        }

      if ((status = muxDevStart(cookie)) != OK)
        {
          SSH_TRACE(
            SSH_D_ERROR,
            ("%s: muxDevStart failed, status %d", va->name, (int)status));
          goto fail;
        }
      started = 1;

      if (ipAttach(i, vxworks_va_devname) != OK)
        {
          SSH_TRACE(SSH_D_ERROR, ("%s: ipAttach failed", va->name));
          goto fail;
        }
      ip_attached = 1;

#if defined(WITH_IPV6) && defined(INET6)
      if (ip6Attach(i, vxworks_va_devname) != OK)
        {
          SSH_TRACE(SSH_D_ERROR, ("%s: ip6Attach failed", va->name));
          goto fail;
        }
#endif /* defined(WITH_IPV6) && defined(INET6) */

      if (!(if_index = ifNameToIfIndex(va->name)))
        {
          SSH_TRACE(
            SSH_D_ERROR,
            ("%s: cannot get interface index after IP attach", va->name));
          goto fail;
        }

      va->ifnum = if_index - 1;
      va->cookie = cookie;

      continue;

    fail:
      if (ip_attached)
        ipDetach(i, vxworks_va_devname);

      if (started)
        muxDevStop(cookie);

      if (cookie)
        muxDevUnload(vxworks_va_devname, i);
    }
}
Exemple #26
0
void ssh_client_auth_hostbased(SshAuthClientOperation op,
                               const char *user,
                               unsigned int packet_type,
                               SshBuffer *packet_in,
                               const unsigned char *session_id,
                               size_t session_id_len,
                               void **state_placeholder,
                               SshAuthClientCompletionProc completion,
                               void *completion_context,
                               void *method_context)
{
  SshClientHostbasedAuth state;
  SshClient client;
  SshStream stdio_stream;
  char hostkeyfile[512];
  /*  char *keytype;
  SshPublicKey pubkey;*/
  char **signer_argv;
  char config_filename[512];
  size_t hostname_len;
  
  SSH_DEBUG(6, ("auth_hostbased op = %d  user = %s", op, user));

  client = (SshClient)method_context;
  state = *state_placeholder;

  switch (op)
    {
      /* This operation is always non-interactive, as hostkeys
         shouldn't have passphrases. Check for it, though. XXX */
    case SSH_AUTH_CLIENT_OP_START_NONINTERACTIVE:
      /* XXX There is a bug in sshauthc.c (or
         elsewhere). Authentication methods, that are not allowed,
         should not be tried. Now it calls
         SSH_AUTH_CLIENT_OP_START_NONINTERACTIVE for every
         authentication method before checking.*/
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      break;
      
    case SSH_AUTH_CLIENT_OP_START:
      /* This is the first operation for doing hostbased authentication.
         We should not have any previous saved state when we come here. */
      SSH_ASSERT(*state_placeholder == NULL);

      /* Initialize a context. */
      state = ssh_xcalloc(1, sizeof(*state));

      state->session_id = session_id;
      state->session_id_len = session_id_len;
      state->user = ssh_xstrdup(user);

      /* We have to dig up the server configuration to get the place
         for the client host's publickey. This is a very kludgeish
         solution. XXX*/
      state->server_conf = ssh_server_create_config();
      
      /* Dig up hosts publickey. */
      
      snprintf(config_filename, sizeof(config_filename), "%s/%s",
               SSH_SERVER_DIR, SSH_SERVER_CONFIG_FILE);
      
      if (!ssh_config_read_file(client->user_data, state->server_conf,
                                NULL, config_filename, NULL))
        SSH_TRACE(2, ("Failed to read config file %s", \
                      config_filename));


      if(state->server_conf->public_host_key_file[0] != '/')
        {
          snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                   state->server_conf->public_host_key_file);
        }
      else
        {
          snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                   state->server_conf->public_host_key_file);  
        }

      /* This pubkey*-stuff is for the client _host's_ public
         hostkey. */
      SSH_DEBUG(4, ("Reading pubkey-blob from %s...", hostkeyfile));
      if (ssh2_key_blob_read(client->user_data, hostkeyfile, NULL,
                             &state->pubkeyblob,
                             &state->pubkeyblob_len, NULL) 
          != SSH_KEY_MAGIC_PUBLIC)
        {         
          goto error;
        }
      
      SSH_DEBUG(4, ("done."));
      if ((state->pubkey_algorithm =
           ssh_pubkeyblob_type(state->pubkeyblob,
                               state->pubkeyblob_len))
          == NULL)
        {
          goto error;
        }
      
      state->local_user_name = ssh_user_name(client->user_data);
      state->local_host_name = ssh_xmalloc(MAXHOSTNAMELEN + 1);
      ssh_tcp_get_host_name(state->local_host_name, MAXHOSTNAMELEN + 1);
      hostname_len = strlen(state->local_host_name);
      /* Sanity check */
      SSH_ASSERT(hostname_len + 2 < MAXHOSTNAMELEN);
      /* We want FQDN. */
      state->local_host_name[hostname_len] = '.';
      state->local_host_name[hostname_len + 1] = '\0';
      
      state->completion = completion;
      state->completion_context = completion_context;
      state->state_placeholder = state_placeholder;
      
      /* Assign the state to the placeholder that survives across
         calls.  (this is actually not needed, as hostbased
         authentication procedure is very simple. Just one packet from
         client to server, and server's response in one packet.) */
      *state_placeholder = state;

      /* Open a pipestream connection to ssh-signer. */
      switch (ssh_pipe_create_and_fork(&stdio_stream, NULL))
        {
        case SSH_PIPE_ERROR:
          /* Something went wrong. */
          ssh_warning("Couldn't create pipe to connect to %s.",
                      client->config->signer_path);
          goto error;
          break;
        case SSH_PIPE_CHILD_OK:
          /* Exec ssh-signer */
          SSH_TRACE(0, ("Child: Execing ssh-signer...(path: %s)", \
                        client->config->signer_path));

          signer_argv = ssh_xcalloc(2, sizeof(char *));
          signer_argv[0] = client->config->signer_path;
          signer_argv[1] = NULL;
          
          execvp(client->config->signer_path, signer_argv);
          fprintf(stderr, "Couldn't exec '%s' (System error message: %s)",
                  client->config->signer_path, strerror(errno));
          ssh_fatal("Executing ssh-signer failed.");
          break;
        case SSH_PIPE_PARENT_OK:
          state->wrapper = ssh_packet_wrap(stdio_stream,
                                           auth_hostbased_received_packet,
                                           auth_hostbased_received_eof,
                                           auth_hostbased_can_send,
                                           state);
          /* We don't check wrapper's validity, as ssh_packet_wrap
             should always succeed.*/
          break;
        }
      /* Here we continue as parent. */
      
      /* sign packet with ssh-signer (a suid-program). */
      if (ssh_packet_wrapper_can_send(state->wrapper))
        {
          ssh_client_auth_hostbased_send_to_signer(state);
        }
      /* If ssh_packet_wrapper_can_send returns FALSE,
         auth_hostbased_can_send will call the ...send_to_signer
         function above. */
      
      /* Rest is done in callbacks. */
      break;
      
    case SSH_AUTH_CLIENT_OP_CONTINUE:          
      SSH_TRACE(2, ("Invalid message. We didn't return " \
                    "SSH_AUTH_CLIENT_SEND_AND_CONTINUE at any stage!"));
      /* Send failure message.*/
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      return;

    case SSH_AUTH_CLIENT_OP_ABORT:
      /* Abort the authentication operation immediately. */
      /* XXX Destroy 'state'-object. */
      *state_placeholder = NULL;
      break;

    default:
      /* something weird is going on.. */
      ssh_fatal("ssh_client_auth_hostbased: unknown op %d", (int)op);
    }
  return;

 error:
  /* XXX Destroy state. */
  /* Send failure message.*/
  (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
  return;
}
Exemple #27
0
int main(int argc, char **argv)
{
    SshStream stdio_stream;
    SshSigner signer;
    char config_filename[512];
    char *temp_name;

#ifdef SLEEP_AFTER_STARTUP
    sleep(30);
#endif /* SLEEP_AFTER_STARTUP */

    /* Get program name (without path). */
    if ((temp_name = strrchr(argv[0], '/')) != NULL)
        progname = ssh_xstrdup(temp_name + 1);
    else
        progname = ssh_xstrdup(argv[0]);

    /* XXX there should be a way to give command-line parameters to this
       program, but, they should only be used if the uid is the same as
       euid. */
    ssh_event_loop_initialize();

    signer = ssh_xcalloc(1, sizeof(*signer));

#ifdef SIGNER_QUIET
    signer->quiet = TRUE;
#else /* SIGNER_QUIET */
    signer->quiet = FALSE;
#endif /* SIGNER_QUIET */
    ssh_debug_register_callbacks(signer_ssh_fatal, signer_ssh_warning,
                                 signer_ssh_debug, (void *)signer);
#ifdef SIGNER_DEBUG
    ssh_debug_set_global_level(5);
#endif /* SIGNER_DEBUG */

    /* Act as server. */
    signer->config = ssh_server_create_config();

    SSH_TRACE(2, ("public key file: %s", signer->config->public_host_key_file));
    SSH_TRACE(2, ("private key file: %s", signer->config->host_key_file));
    SSH_TRACE(2, ("randomseed file: %s", signer->config->random_seed_file));

    /* Initialize user context with euid. This is used to dig up the
       hostkey and such. */
    signer->effective_user_data = ssh_user_initialize_with_uid(geteuid(), FALSE);

    signer->random_state = ssh_randseed_open(signer->effective_user_data,
                           signer->config);

    /* XXX what about alternative config files? This should be possible
       to configure somehow. An option for configure is probably a good
       idea. */
    snprintf(config_filename, sizeof(config_filename), "%s/%s",
             SSH_SERVER_DIR, SSH_SERVER_CONFIG_FILE);

    if (!ssh_config_read_file(signer->effective_user_data, signer->config,
                              NULL, config_filename, NULL))
        ssh_warning("%s: Failed to read config file %s", argv[0],
                    config_filename);

    stdio_stream = ssh_stream_fd_wrap2(fileno(stdin), fileno(stdout),
                                       TRUE);

    signer->wrapper = ssh_packet_wrap(stdio_stream,
                                      signer_received_packet,
                                      signer_received_eof,
                                      signer_can_send,
                                      signer);

    ssh_event_loop_run();

    return 0;
}
Exemple #28
0
/* Tries to authenticate the user using the .shosts or .rhosts file.
   Returns true if authentication succeeds.  If config->ignore_rhosts
   is true, only /etc/hosts.equiv will be considered (.rhosts and
   .shosts are ignored), unless the user is root and
   config->ignore_root_rhosts isn't true. */
Boolean ssh_server_auth_hostbased_rhosts(SshUser user_data,
                                         const char *client_user,
                                         void *context)
{
  char buf[1024];
  const char *hostname, *ipaddr;
  struct stat st;
  static const char *rhosts_files[] = { ".shosts", ".rhosts", NULL };
  unsigned int rhosts_file_index;
  SshConfig config;
  SshServer server = (SshServer) context;
  SshUser effective_user_data =
    ssh_user_initialize_with_uid(geteuid(), FALSE);
  
  config = server->config;

  ssh_userfile_init(ssh_user_name(user_data), ssh_user_uid(user_data),
                    ssh_user_gid(user_data), NULL, NULL);

  /* Get the name, address, and port of the remote host.  */
  hostname = server->common->remote_host;
  ipaddr = server->common->remote_ip;

  /* Quick check: if the user has no .shosts or .rhosts files, return failure
     immediately without doing costly lookups from name servers. */
  for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
       rhosts_file_index++)
    {
      /* Check users .rhosts or .shosts. */
      snprintf(buf, sizeof(buf), "%.500s/%.100s", 
              ssh_user_dir(user_data), rhosts_files[rhosts_file_index]);
      if (ssh_userfile_stat(ssh_user_uid(user_data), buf, &st) >= 0)
        break;
    }

  if (!rhosts_files[rhosts_file_index] && 
      ssh_userfile_stat(ssh_user_uid(user_data), "/etc/hosts.equiv", &st) < 0 &&
      ssh_userfile_stat(ssh_user_uid(user_data), SSH_HOSTS_EQUIV, &st) < 0)
    return FALSE; /* The user has no .shosts or .rhosts file and there are no
                 system-wide files. */
  
  /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
  if (ssh_user_uid(user_data) != UID_ROOT)
    {
      if (check_rhosts_file(ssh_user_uid(effective_user_data), 
                            "/etc/hosts.equiv", hostname, ipaddr, client_user,
                            ssh_user_name(user_data), server))
        {
          SSH_TRACE(2, ("Accepted for %.100s [%.100s] by " \
                        "/etc/hosts.equiv.", hostname, ipaddr));
          return TRUE;
        }
      if (check_rhosts_file(ssh_user_uid(effective_user_data),
                            SSH_HOSTS_EQUIV, hostname, ipaddr, client_user,
                            ssh_user_name(user_data), server))
        {
          SSH_TRACE(2, ("Accepted for %.100s [%.100s] by %.100s.",  \
                            hostname, ipaddr, SSH_HOSTS_EQUIV));
          return TRUE;
        }
    }

  /* Check that the home directory is owned by root or the user, and is not 
     group or world writable. */
  if (ssh_userfile_stat(ssh_user_uid(user_data), ssh_user_dir(user_data),
                    &st) < 0)
    {
      ssh_log_event(config->log_facility, SSH_LOG_WARNING,
                    "hostbased-authentication (rhosts) refused for " \
                    "%.100: no home directory %.200s",
                    ssh_user_name(user_data),
                    ssh_user_dir(user_data));
      SSH_TRACE(2, ("hostbased-authentication (rhosts) refused for " \
                    "%.100: no home directory %.200s", \
                    ssh_user_name(user_data), ssh_user_dir(user_data)));
      return FALSE;
    }
  
  if (config->strict_modes && 
      ((st.st_uid != UID_ROOT && st.st_uid != ssh_user_uid(user_data)) ||
#ifdef ALLOW_GROUP_WRITEABILITY
       (st.st_mode & 002) != 0)
#else
       (st.st_mode & 022) != 0)
#endif
      )
    {
      ssh_log_event(config->log_facility, SSH_LOG_WARNING,
                    "hostbased-authentication (rhosts) refused for " \
                    "%.100s: bad ownership or modes for home directory.",
                    ssh_user_name(user_data));
      SSH_TRACE(2, ("hostbased-authentication (rhosts) refused for " \
                    "%.100s: bad ownership or modes for home directory.", \
                    ssh_user_name(user_data)));
      return FALSE;
    }
  
  /* Check all .rhosts files (currently .shosts and .rhosts). */
  for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
       rhosts_file_index++)
    {
      /* Check users .rhosts or .shosts. */
      snprintf(buf, sizeof(buf), "%.500s/%.100s", 
              ssh_user_dir(user_data), rhosts_files[rhosts_file_index]);
      if (ssh_userfile_stat(ssh_user_uid(user_data), buf, &st) < 0)
        continue; /* No such file. */

      /* Make sure that the file is either owned by the user or by root,
         and make sure it is not writable by anyone but the owner.  This is
         to help avoid novices accidentally allowing access to their account
         by anyone. */
      if (config->strict_modes &&
          ((st.st_uid != UID_ROOT && st.st_uid != ssh_user_uid(user_data)) ||
           (st.st_mode & 022) != 0))
        {
          ssh_log_event(config->log_facility, SSH_LOG_WARNING,
                        "hostbased-authentication (rhosts) refused for " \
                        "%.100s: bad modes for %.200s",
                        ssh_user_name(user_data), buf);
          SSH_TRACE(2, ("hostbased-authentication (rhosts) refused for " \
                        "%.100s: bad modes for %.200s", \
                        ssh_user_name(user_data), buf));
          continue;
        }

      /* Check if we have been configured to ignore .rhosts and .shosts 
         files.  If root, check ignore_root_rhosts first. */
      if ((ssh_user_uid(user_data) == UID_ROOT &&
           config->ignore_root_rhosts) ||
          (ssh_user_uid(user_data) != UID_ROOT &&
           config->ignore_rhosts))
        {
          SSH_TRACE(2, ("Server has been configured to ignore %.100s.", \
                        rhosts_files[rhosts_file_index]));
          continue;
        }

      /* Check if authentication is permitted by the file. */
      if (check_rhosts_file(ssh_user_uid(user_data), buf, hostname,
                            ipaddr, client_user, ssh_user_name(user_data),
                            server))
        {
          SSH_TRACE(2, ("Accepted by %.100s.", \
                        rhosts_files[rhosts_file_index]));
          return TRUE;
        }
    }

  /* Rhosts authentication denied. */
  SSH_TRACE(2, ("hostbased-authentication (rhosts) refused: client " \
                "user '%.100s', server user '%.100s', " \
                "client host '%.200s'.", \
                client_user, ssh_user_name(user_data), hostname));

  ssh_log_event(config->log_facility, SSH_LOG_WARNING,
                "hostbased-authentication (rhosts) refused: client " \
                "user '%.100s', server user '%.100s', " \
                "client host '%.200s'.", \
                client_user, ssh_user_name(user_data), hostname);

  return FALSE;
}