readconf.c 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409
  1. /* $OpenBSD: readconf.c,v 1.335 2020/08/27 02:11:09 djm Exp $ */
  2. /*
  3. * Author: Tatu Ylonen <ylo@cs.hut.fi>
  4. * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  5. * All rights reserved
  6. * Functions for reading the configuration files.
  7. *
  8. * As far as I am concerned, the code I have written for this software
  9. * can be used freely for any purpose. Any derived versions of this
  10. * software must be clearly marked as such, and if the derived work is
  11. * incompatible with the protocol description in the RFC file, it must be
  12. * called by a name other than "ssh" or "Secure Shell".
  13. */
  14. #include "includes.h"
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/socket.h>
  18. #include <sys/wait.h>
  19. #include <sys/un.h>
  20. #include <netinet/in.h>
  21. #include <netinet/in_systm.h>
  22. #include <netinet/ip.h>
  23. #include <arpa/inet.h>
  24. #include <ctype.h>
  25. #include <errno.h>
  26. #include <fcntl.h>
  27. #include <limits.h>
  28. #include <netdb.h>
  29. #ifdef HAVE_PATHS_H
  30. # include <paths.h>
  31. #endif
  32. #include <pwd.h>
  33. #include <signal.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdarg.h>
  37. #include <unistd.h>
  38. #ifdef USE_SYSTEM_GLOB
  39. # include <glob.h>
  40. #else
  41. # include "openbsd-compat/glob.h"
  42. #endif
  43. #ifdef HAVE_UTIL_H
  44. #include <util.h>
  45. #endif
  46. #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
  47. # include <vis.h>
  48. #endif
  49. #include "xmalloc.h"
  50. #include "ssh.h"
  51. #include "ssherr.h"
  52. #include "compat.h"
  53. #include "cipher.h"
  54. #include "pathnames.h"
  55. #include "log.h"
  56. #include "sshkey.h"
  57. #include "misc.h"
  58. #include "readconf.h"
  59. #include "match.h"
  60. #include "kex.h"
  61. #include "mac.h"
  62. #include "uidswap.h"
  63. #include "myproposal.h"
  64. #include "digest.h"
  65. #include "sshbuf.h"
  66. /* Format of the configuration file:
  67. # Configuration data is parsed as follows:
  68. # 1. command line options
  69. # 2. user-specific file
  70. # 3. system-wide file
  71. # Any configuration value is only changed the first time it is set.
  72. # Thus, host-specific definitions should be at the beginning of the
  73. # configuration file, and defaults at the end.
  74. # Host-specific declarations. These may override anything above. A single
  75. # host may match multiple declarations; these are processed in the order
  76. # that they are given in.
  77. Host *.ngs.fi ngs.fi
  78. User foo
  79. Host fake.com
  80. Hostname another.host.name.real.org
  81. User blaah
  82. Port 34289
  83. ForwardX11 no
  84. ForwardAgent no
  85. Host books.com
  86. RemoteForward 9999 shadows.cs.hut.fi:9999
  87. Ciphers 3des-cbc
  88. Host fascist.blob.com
  89. Port 23123
  90. User tylonen
  91. PasswordAuthentication no
  92. Host puukko.hut.fi
  93. User t35124p
  94. ProxyCommand ssh-proxy %h %p
  95. Host *.fr
  96. PublicKeyAuthentication no
  97. Host *.su
  98. Ciphers aes128-ctr
  99. PasswordAuthentication no
  100. Host vpn.fake.com
  101. Tunnel yes
  102. TunnelDevice 3
  103. # Defaults for various options
  104. Host *
  105. ForwardAgent no
  106. ForwardX11 no
  107. PasswordAuthentication yes
  108. StrictHostKeyChecking yes
  109. TcpKeepAlive no
  110. IdentityFile ~/.ssh/identity
  111. Port 22
  112. EscapeChar ~
  113. */
  114. static int read_config_file_depth(const char *filename, struct passwd *pw,
  115. const char *host, const char *original_host, Options *options,
  116. int flags, int *activep, int *want_final_pass, int depth);
  117. static int process_config_line_depth(Options *options, struct passwd *pw,
  118. const char *host, const char *original_host, char *line,
  119. const char *filename, int linenum, int *activep, int flags,
  120. int *want_final_pass, int depth);
  121. /* Keyword tokens. */
  122. typedef enum {
  123. oBadOption,
  124. oHost, oMatch, oInclude,
  125. oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
  126. oGatewayPorts, oExitOnForwardFailure,
  127. oPasswordAuthentication,
  128. oChallengeResponseAuthentication, oXAuthLocation,
  129. oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
  130. oPermitRemoteOpen,
  131. oCertificateFile, oAddKeysToAgent, oIdentityAgent,
  132. oUser, oEscapeChar, oProxyCommand,
  133. oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
  134. oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
  135. oTCPKeepAlive, oNumberOfPasswordPrompts,
  136. oLogFacility, oLogLevel, oCiphers, oMacs,
  137. oPubkeyAuthentication,
  138. oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
  139. oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
  140. oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
  141. oClearAllForwardings, oNoHostAuthenticationForLocalhost,
  142. oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
  143. oAddressFamily, oGssAuthentication, oGssDelegateCreds,
  144. oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
  145. oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
  146. oHashKnownHosts,
  147. oTunnel, oTunnelDevice,
  148. oLocalCommand, oPermitLocalCommand, oRemoteCommand,
  149. oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize,
  150. oNoneEnabled, oNoneMacEnabled, oNoneSwitch,
  151. oDisableMTAES,
  152. oVisualHostKey,
  153. oKexAlgorithms, oIPQoS, oRequestTTY, oNoShell, oStdinNull,
  154. oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
  155. oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
  156. oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
  157. oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
  158. oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
  159. oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
  160. oSecurityKeyProvider,
  161. oProtocolKeepAlives, oSetupTimeOut,
  162. oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
  163. } OpCodes;
  164. /* Textual representations of the tokens. */
  165. static struct {
  166. const char *name;
  167. OpCodes opcode;
  168. } keywords[] = {
  169. /* Deprecated options */
  170. { "protocol", oIgnore }, /* NB. silently ignored */
  171. { "cipher", oDeprecated },
  172. { "fallbacktorsh", oDeprecated },
  173. { "globalknownhostsfile2", oDeprecated },
  174. { "rhostsauthentication", oDeprecated },
  175. { "useblacklistedkeys", oDeprecated },
  176. { "userknownhostsfile2", oDeprecated },
  177. { "useroaming", oDeprecated },
  178. { "usersh", oDeprecated },
  179. { "useprivilegedport", oDeprecated },
  180. /* Unsupported options */
  181. { "afstokenpassing", oUnsupported },
  182. { "kerberosauthentication", oUnsupported },
  183. { "kerberostgtpassing", oUnsupported },
  184. { "rsaauthentication", oUnsupported },
  185. { "rhostsrsaauthentication", oUnsupported },
  186. { "compressionlevel", oUnsupported },
  187. /* Sometimes-unsupported options */
  188. #if defined(GSSAPI)
  189. { "gssapiauthentication", oGssAuthentication },
  190. { "gssapidelegatecredentials", oGssDelegateCreds },
  191. # else
  192. { "gssapiauthentication", oUnsupported },
  193. { "gssapidelegatecredentials", oUnsupported },
  194. #endif
  195. #ifdef ENABLE_PKCS11
  196. { "pkcs11provider", oPKCS11Provider },
  197. { "smartcarddevice", oPKCS11Provider },
  198. # else
  199. { "smartcarddevice", oUnsupported },
  200. { "pkcs11provider", oUnsupported },
  201. #endif
  202. { "forwardagent", oForwardAgent },
  203. { "forwardx11", oForwardX11 },
  204. { "forwardx11trusted", oForwardX11Trusted },
  205. { "forwardx11timeout", oForwardX11Timeout },
  206. { "exitonforwardfailure", oExitOnForwardFailure },
  207. { "xauthlocation", oXAuthLocation },
  208. { "gatewayports", oGatewayPorts },
  209. { "passwordauthentication", oPasswordAuthentication },
  210. { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
  211. { "kbdinteractivedevices", oKbdInteractiveDevices },
  212. { "pubkeyauthentication", oPubkeyAuthentication },
  213. { "dsaauthentication", oPubkeyAuthentication }, /* alias */
  214. { "hostbasedauthentication", oHostbasedAuthentication },
  215. { "challengeresponseauthentication", oChallengeResponseAuthentication },
  216. { "skeyauthentication", oUnsupported },
  217. { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
  218. { "identityfile", oIdentityFile },
  219. { "identityfile2", oIdentityFile }, /* obsolete */
  220. { "identitiesonly", oIdentitiesOnly },
  221. { "certificatefile", oCertificateFile },
  222. { "addkeystoagent", oAddKeysToAgent },
  223. { "identityagent", oIdentityAgent },
  224. { "hostname", oHostname },
  225. { "hostkeyalias", oHostKeyAlias },
  226. { "proxycommand", oProxyCommand },
  227. { "port", oPort },
  228. { "ciphers", oCiphers },
  229. { "macs", oMacs },
  230. { "remoteforward", oRemoteForward },
  231. { "localforward", oLocalForward },
  232. { "permitremoteopen", oPermitRemoteOpen },
  233. { "user", oUser },
  234. { "host", oHost },
  235. { "match", oMatch },
  236. { "escapechar", oEscapeChar },
  237. { "globalknownhostsfile", oGlobalKnownHostsFile },
  238. { "userknownhostsfile", oUserKnownHostsFile },
  239. { "connectionattempts", oConnectionAttempts },
  240. { "batchmode", oBatchMode },
  241. { "checkhostip", oCheckHostIP },
  242. { "stricthostkeychecking", oStrictHostKeyChecking },
  243. { "compression", oCompression },
  244. { "tcpkeepalive", oTCPKeepAlive },
  245. { "keepalive", oTCPKeepAlive }, /* obsolete */
  246. { "numberofpasswordprompts", oNumberOfPasswordPrompts },
  247. { "syslogfacility", oLogFacility },
  248. { "loglevel", oLogLevel },
  249. { "dynamicforward", oDynamicForward },
  250. { "preferredauthentications", oPreferredAuthentications },
  251. { "hostkeyalgorithms", oHostKeyAlgorithms },
  252. { "casignaturealgorithms", oCASignatureAlgorithms },
  253. { "bindaddress", oBindAddress },
  254. { "bindinterface", oBindInterface },
  255. { "clearallforwardings", oClearAllForwardings },
  256. { "enablesshkeysign", oEnableSSHKeysign },
  257. { "verifyhostkeydns", oVerifyHostKeyDNS },
  258. { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
  259. { "rekeylimit", oRekeyLimit },
  260. { "connecttimeout", oConnectTimeout },
  261. { "addressfamily", oAddressFamily },
  262. { "serveraliveinterval", oServerAliveInterval },
  263. { "serveralivecountmax", oServerAliveCountMax },
  264. { "sendenv", oSendEnv },
  265. { "setenv", oSetEnv },
  266. { "controlpath", oControlPath },
  267. { "controlmaster", oControlMaster },
  268. { "controlpersist", oControlPersist },
  269. { "hashknownhosts", oHashKnownHosts },
  270. { "include", oInclude },
  271. { "tunnel", oTunnel },
  272. { "tunneldevice", oTunnelDevice },
  273. { "localcommand", oLocalCommand },
  274. { "permitlocalcommand", oPermitLocalCommand },
  275. { "remotecommand", oRemoteCommand },
  276. { "visualhostkey", oVisualHostKey },
  277. { "kexalgorithms", oKexAlgorithms },
  278. { "ipqos", oIPQoS },
  279. { "requesttty", oRequestTTY },
  280. { "noshell", oNoShell },
  281. { "stdinnull", oStdinNull },
  282. { "forkafterauthentication", oForkAfterAuthentication },
  283. { "noneenabled", oNoneEnabled },
  284. { "nonemacenabled", oNoneMacEnabled },
  285. { "noneswitch", oNoneSwitch },
  286. { "disablemtaes", oDisableMTAES },
  287. { "proxyusefdpass", oProxyUseFdpass },
  288. { "canonicaldomains", oCanonicalDomains },
  289. { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
  290. { "canonicalizehostname", oCanonicalizeHostname },
  291. { "canonicalizemaxdots", oCanonicalizeMaxDots },
  292. { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
  293. { "streamlocalbindmask", oStreamLocalBindMask },
  294. { "streamlocalbindunlink", oStreamLocalBindUnlink },
  295. { "revokedhostkeys", oRevokedHostKeys },
  296. { "fingerprinthash", oFingerprintHash },
  297. { "updatehostkeys", oUpdateHostkeys },
  298. { "hostbasedalgorithms", oHostbasedAcceptedAlgorithms },
  299. { "hostbasedkeytypes", oHostbasedAcceptedAlgorithms }, /* obsolete */
  300. { "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms },
  301. { "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms }, /* obsolete */
  302. { "ignoreunknown", oIgnoreUnknown },
  303. { "proxyjump", oProxyJump },
  304. { "protocolkeepalives", oProtocolKeepAlives },
  305. { "setuptimeout", oSetupTimeOut },
  306. { "securitykeyprovider", oSecurityKeyProvider },
  307. { "tcprcvbufpoll", oTcpRcvBufPoll },
  308. { "tcprcvbuf", oTcpRcvBuf },
  309. { "hpndisabled", oHPNDisabled },
  310. { "hpnbuffersize", oHPNBufferSize },
  311. { NULL, oBadOption }
  312. };
  313. static const char *lookup_opcode_name(OpCodes code);
  314. const char *
  315. kex_default_pk_alg(void)
  316. {
  317. static char *pkalgs;
  318. if (pkalgs == NULL) {
  319. char *all_key;
  320. all_key = sshkey_alg_list(0, 0, 1, ',');
  321. pkalgs = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
  322. free(all_key);
  323. }
  324. return pkalgs;
  325. }
  326. char *
  327. ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
  328. const char *user)
  329. {
  330. struct ssh_digest_ctx *md;
  331. u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
  332. if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
  333. ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
  334. ssh_digest_update(md, host, strlen(host)) < 0 ||
  335. ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
  336. ssh_digest_update(md, user, strlen(user)) < 0 ||
  337. ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
  338. fatal("%s: mux digest failed", __func__);
  339. ssh_digest_free(md);
  340. return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
  341. }
  342. /*
  343. * Adds a local TCP/IP port forward to options. Never returns if there is an
  344. * error.
  345. */
  346. void
  347. add_local_forward(Options *options, const struct Forward *newfwd)
  348. {
  349. struct Forward *fwd;
  350. int i;
  351. /* Don't add duplicates */
  352. for (i = 0; i < options->num_local_forwards; i++) {
  353. if (forward_equals(newfwd, options->local_forwards + i))
  354. return;
  355. }
  356. options->local_forwards = xreallocarray(options->local_forwards,
  357. options->num_local_forwards + 1,
  358. sizeof(*options->local_forwards));
  359. fwd = &options->local_forwards[options->num_local_forwards++];
  360. fwd->listen_host = newfwd->listen_host;
  361. fwd->listen_port = newfwd->listen_port;
  362. fwd->listen_path = newfwd->listen_path;
  363. fwd->connect_host = newfwd->connect_host;
  364. fwd->connect_port = newfwd->connect_port;
  365. fwd->connect_path = newfwd->connect_path;
  366. }
  367. /*
  368. * Adds a remote TCP/IP port forward to options. Never returns if there is
  369. * an error.
  370. */
  371. void
  372. add_remote_forward(Options *options, const struct Forward *newfwd)
  373. {
  374. struct Forward *fwd;
  375. int i;
  376. /* Don't add duplicates */
  377. for (i = 0; i < options->num_remote_forwards; i++) {
  378. if (forward_equals(newfwd, options->remote_forwards + i))
  379. return;
  380. }
  381. options->remote_forwards = xreallocarray(options->remote_forwards,
  382. options->num_remote_forwards + 1,
  383. sizeof(*options->remote_forwards));
  384. fwd = &options->remote_forwards[options->num_remote_forwards++];
  385. fwd->listen_host = newfwd->listen_host;
  386. fwd->listen_port = newfwd->listen_port;
  387. fwd->listen_path = newfwd->listen_path;
  388. fwd->connect_host = newfwd->connect_host;
  389. fwd->connect_port = newfwd->connect_port;
  390. fwd->connect_path = newfwd->connect_path;
  391. fwd->handle = newfwd->handle;
  392. fwd->allocated_port = 0;
  393. }
  394. static void
  395. clear_forwardings(Options *options)
  396. {
  397. int i;
  398. for (i = 0; i < options->num_local_forwards; i++) {
  399. free(options->local_forwards[i].listen_host);
  400. free(options->local_forwards[i].listen_path);
  401. free(options->local_forwards[i].connect_host);
  402. free(options->local_forwards[i].connect_path);
  403. }
  404. if (options->num_local_forwards > 0) {
  405. free(options->local_forwards);
  406. options->local_forwards = NULL;
  407. }
  408. options->num_local_forwards = 0;
  409. for (i = 0; i < options->num_remote_forwards; i++) {
  410. free(options->remote_forwards[i].listen_host);
  411. free(options->remote_forwards[i].listen_path);
  412. free(options->remote_forwards[i].connect_host);
  413. free(options->remote_forwards[i].connect_path);
  414. }
  415. if (options->num_remote_forwards > 0) {
  416. free(options->remote_forwards);
  417. options->remote_forwards = NULL;
  418. }
  419. options->num_remote_forwards = 0;
  420. options->tun_open = SSH_TUNMODE_NO;
  421. }
  422. void
  423. add_certificate_file(Options *options, const char *path, int userprovided)
  424. {
  425. int i;
  426. if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
  427. fatal("Too many certificate files specified (max %d)",
  428. SSH_MAX_CERTIFICATE_FILES);
  429. /* Avoid registering duplicates */
  430. for (i = 0; i < options->num_certificate_files; i++) {
  431. if (options->certificate_file_userprovided[i] == userprovided &&
  432. strcmp(options->certificate_files[i], path) == 0) {
  433. debug2("%s: ignoring duplicate key %s", __func__, path);
  434. return;
  435. }
  436. }
  437. options->certificate_file_userprovided[options->num_certificate_files] =
  438. userprovided;
  439. options->certificate_files[options->num_certificate_files++] =
  440. xstrdup(path);
  441. }
  442. void
  443. add_identity_file(Options *options, const char *dir, const char *filename,
  444. int userprovided)
  445. {
  446. char *path;
  447. int i;
  448. if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
  449. fatal("Too many identity files specified (max %d)",
  450. SSH_MAX_IDENTITY_FILES);
  451. if (dir == NULL) /* no dir, filename is absolute */
  452. path = xstrdup(filename);
  453. else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
  454. fatal("Identity file path %s too long", path);
  455. /* Avoid registering duplicates */
  456. for (i = 0; i < options->num_identity_files; i++) {
  457. if (options->identity_file_userprovided[i] == userprovided &&
  458. strcmp(options->identity_files[i], path) == 0) {
  459. debug2("%s: ignoring duplicate key %s", __func__, path);
  460. free(path);
  461. return;
  462. }
  463. }
  464. options->identity_file_userprovided[options->num_identity_files] =
  465. userprovided;
  466. options->identity_files[options->num_identity_files++] = path;
  467. }
  468. int
  469. default_ssh_port(void)
  470. {
  471. static int port;
  472. struct servent *sp;
  473. if (port == 0) {
  474. sp = getservbyname(SSH_SERVICE_NAME, "tcp");
  475. port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
  476. }
  477. return port;
  478. }
  479. /*
  480. * Execute a command in a shell.
  481. * Return its exit status or -1 on abnormal exit.
  482. */
  483. static int
  484. execute_in_shell(const char *cmd)
  485. {
  486. char *shell;
  487. pid_t pid;
  488. int devnull, status;
  489. if ((shell = getenv("SHELL")) == NULL)
  490. shell = _PATH_BSHELL;
  491. if (access(shell, X_OK) == -1) {
  492. fatal("Shell \"%s\" is not executable: %s",
  493. shell, strerror(errno));
  494. }
  495. /* Need this to redirect subprocess stdin/out */
  496. if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
  497. fatal("open(/dev/null): %s", strerror(errno));
  498. debug("Executing command: '%.500s'", cmd);
  499. /* Fork and execute the command. */
  500. if ((pid = fork()) == 0) {
  501. char *argv[4];
  502. /* Redirect child stdin and stdout. Leave stderr */
  503. if (dup2(devnull, STDIN_FILENO) == -1)
  504. fatal("dup2: %s", strerror(errno));
  505. if (dup2(devnull, STDOUT_FILENO) == -1)
  506. fatal("dup2: %s", strerror(errno));
  507. if (devnull > STDERR_FILENO)
  508. close(devnull);
  509. closefrom(STDERR_FILENO + 1);
  510. argv[0] = shell;
  511. argv[1] = "-c";
  512. argv[2] = xstrdup(cmd);
  513. argv[3] = NULL;
  514. execv(argv[0], argv);
  515. error("Unable to execute '%.100s': %s", cmd, strerror(errno));
  516. /* Die with signal to make this error apparent to parent. */
  517. ssh_signal(SIGTERM, SIG_DFL);
  518. kill(getpid(), SIGTERM);
  519. _exit(1);
  520. }
  521. /* Parent. */
  522. if (pid == -1)
  523. fatal("%s: fork: %.100s", __func__, strerror(errno));
  524. close(devnull);
  525. while (waitpid(pid, &status, 0) == -1) {
  526. if (errno != EINTR && errno != EAGAIN)
  527. fatal("%s: waitpid: %s", __func__, strerror(errno));
  528. }
  529. if (!WIFEXITED(status)) {
  530. error("command '%.100s' exited abnormally", cmd);
  531. return -1;
  532. }
  533. debug3("command returned status %d", WEXITSTATUS(status));
  534. return WEXITSTATUS(status);
  535. }
  536. /*
  537. * Parse and execute a Match directive.
  538. */
  539. static int
  540. match_cfg_line(Options *options, char **condition, struct passwd *pw,
  541. const char *host_arg, const char *original_host, int final_pass,
  542. int *want_final_pass, const char *filename, int linenum)
  543. {
  544. char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
  545. const char *ruser;
  546. int r, port, this_result, result = 1, attributes = 0, negate;
  547. char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
  548. char uidstr[32];
  549. /*
  550. * Configuration is likely to be incomplete at this point so we
  551. * must be prepared to use default values.
  552. */
  553. port = options->port <= 0 ? default_ssh_port() : options->port;
  554. ruser = options->user == NULL ? pw->pw_name : options->user;
  555. if (final_pass) {
  556. host = xstrdup(options->hostname);
  557. } else if (options->hostname != NULL) {
  558. /* NB. Please keep in sync with ssh.c:main() */
  559. host = percent_expand(options->hostname,
  560. "h", host_arg, (char *)NULL);
  561. } else {
  562. host = xstrdup(host_arg);
  563. }
  564. debug2("checking match for '%s' host %s originally %s",
  565. cp, host, original_host);
  566. while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
  567. criteria = NULL;
  568. this_result = 1;
  569. if ((negate = attrib[0] == '!'))
  570. attrib++;
  571. /* criteria "all" and "canonical" have no argument */
  572. if (strcasecmp(attrib, "all") == 0) {
  573. if (attributes > 1 ||
  574. ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
  575. error("%.200s line %d: '%s' cannot be combined "
  576. "with other Match attributes",
  577. filename, linenum, oattrib);
  578. result = -1;
  579. goto out;
  580. }
  581. if (result)
  582. result = negate ? 0 : 1;
  583. goto out;
  584. }
  585. attributes++;
  586. if (strcasecmp(attrib, "canonical") == 0 ||
  587. strcasecmp(attrib, "final") == 0) {
  588. /*
  589. * If the config requests "Match final" then remember
  590. * this so we can perform a second pass later.
  591. */
  592. if (strcasecmp(attrib, "final") == 0 &&
  593. want_final_pass != NULL)
  594. *want_final_pass = 1;
  595. r = !!final_pass; /* force bitmask member to boolean */
  596. if (r == (negate ? 1 : 0))
  597. this_result = result = 0;
  598. debug3("%.200s line %d: %smatched '%s'",
  599. filename, linenum,
  600. this_result ? "" : "not ", oattrib);
  601. continue;
  602. }
  603. /* All other criteria require an argument */
  604. if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
  605. error("Missing Match criteria for %s", attrib);
  606. result = -1;
  607. goto out;
  608. }
  609. if (strcasecmp(attrib, "host") == 0) {
  610. criteria = xstrdup(host);
  611. r = match_hostname(host, arg) == 1;
  612. if (r == (negate ? 1 : 0))
  613. this_result = result = 0;
  614. } else if (strcasecmp(attrib, "originalhost") == 0) {
  615. criteria = xstrdup(original_host);
  616. r = match_hostname(original_host, arg) == 1;
  617. if (r == (negate ? 1 : 0))
  618. this_result = result = 0;
  619. } else if (strcasecmp(attrib, "user") == 0) {
  620. criteria = xstrdup(ruser);
  621. r = match_pattern_list(ruser, arg, 0) == 1;
  622. if (r == (negate ? 1 : 0))
  623. this_result = result = 0;
  624. } else if (strcasecmp(attrib, "localuser") == 0) {
  625. criteria = xstrdup(pw->pw_name);
  626. r = match_pattern_list(pw->pw_name, arg, 0) == 1;
  627. if (r == (negate ? 1 : 0))
  628. this_result = result = 0;
  629. } else if (strcasecmp(attrib, "exec") == 0) {
  630. char *conn_hash_hex, *keyalias;
  631. if (gethostname(thishost, sizeof(thishost)) == -1)
  632. fatal("gethostname: %s", strerror(errno));
  633. strlcpy(shorthost, thishost, sizeof(shorthost));
  634. shorthost[strcspn(thishost, ".")] = '\0';
  635. snprintf(portstr, sizeof(portstr), "%d", port);
  636. snprintf(uidstr, sizeof(uidstr), "%llu",
  637. (unsigned long long)pw->pw_uid);
  638. conn_hash_hex = ssh_connection_hash(thishost, host,
  639. portstr, ruser);
  640. keyalias = options->host_key_alias ?
  641. options->host_key_alias : host;
  642. cmd = percent_expand(arg,
  643. "C", conn_hash_hex,
  644. "L", shorthost,
  645. "d", pw->pw_dir,
  646. "h", host,
  647. "k", keyalias,
  648. "l", thishost,
  649. "n", original_host,
  650. "p", portstr,
  651. "r", ruser,
  652. "u", pw->pw_name,
  653. "i", uidstr,
  654. (char *)NULL);
  655. free(conn_hash_hex);
  656. if (result != 1) {
  657. /* skip execution if prior predicate failed */
  658. debug3("%.200s line %d: skipped exec "
  659. "\"%.100s\"", filename, linenum, cmd);
  660. free(cmd);
  661. continue;
  662. }
  663. r = execute_in_shell(cmd);
  664. if (r == -1) {
  665. fatal("%.200s line %d: match exec "
  666. "'%.100s' error", filename,
  667. linenum, cmd);
  668. }
  669. criteria = xstrdup(cmd);
  670. free(cmd);
  671. /* Force exit status to boolean */
  672. r = r == 0;
  673. if (r == (negate ? 1 : 0))
  674. this_result = result = 0;
  675. } else {
  676. error("Unsupported Match attribute %s", attrib);
  677. result = -1;
  678. goto out;
  679. }
  680. debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
  681. filename, linenum, this_result ? "": "not ",
  682. oattrib, criteria);
  683. free(criteria);
  684. }
  685. if (attributes == 0) {
  686. error("One or more attributes required for Match");
  687. result = -1;
  688. goto out;
  689. }
  690. out:
  691. if (result != -1)
  692. debug2("match %sfound", result ? "" : "not ");
  693. *condition = cp;
  694. free(host);
  695. return result;
  696. }
  697. /* Remove environment variable by pattern */
  698. static void
  699. rm_env(Options *options, const char *arg, const char *filename, int linenum)
  700. {
  701. int i, j, onum_send_env = options->num_send_env;
  702. char *cp;
  703. /* Remove an environment variable */
  704. for (i = 0; i < options->num_send_env; ) {
  705. cp = xstrdup(options->send_env[i]);
  706. if (!match_pattern(cp, arg + 1)) {
  707. free(cp);
  708. i++;
  709. continue;
  710. }
  711. debug3("%s line %d: removing environment %s",
  712. filename, linenum, cp);
  713. free(cp);
  714. free(options->send_env[i]);
  715. options->send_env[i] = NULL;
  716. for (j = i; j < options->num_send_env - 1; j++) {
  717. options->send_env[j] = options->send_env[j + 1];
  718. options->send_env[j + 1] = NULL;
  719. }
  720. options->num_send_env--;
  721. /* NB. don't increment i */
  722. }
  723. if (onum_send_env != options->num_send_env) {
  724. options->send_env = xrecallocarray(options->send_env,
  725. onum_send_env, options->num_send_env,
  726. sizeof(*options->send_env));
  727. }
  728. }
  729. /*
  730. * Returns the number of the token pointed to by cp or oBadOption.
  731. */
  732. static OpCodes
  733. parse_token(const char *cp, const char *filename, int linenum,
  734. const char *ignored_unknown)
  735. {
  736. int i;
  737. for (i = 0; keywords[i].name; i++)
  738. if (strcmp(cp, keywords[i].name) == 0)
  739. return keywords[i].opcode;
  740. if (ignored_unknown != NULL &&
  741. match_pattern_list(cp, ignored_unknown, 1) == 1)
  742. return oIgnoredUnknownOption;
  743. error("%s: line %d: Bad configuration option: %s",
  744. filename, linenum, cp);
  745. return oBadOption;
  746. }
  747. /* Multistate option parsing */
  748. struct multistate {
  749. char *key;
  750. int value;
  751. };
  752. static const struct multistate multistate_flag[] = {
  753. { "true", 1 },
  754. { "false", 0 },
  755. { "yes", 1 },
  756. { "no", 0 },
  757. { NULL, -1 }
  758. };
  759. static const struct multistate multistate_yesnoask[] = {
  760. { "true", 1 },
  761. { "false", 0 },
  762. { "yes", 1 },
  763. { "no", 0 },
  764. { "ask", 2 },
  765. { NULL, -1 }
  766. };
  767. static const struct multistate multistate_strict_hostkey[] = {
  768. { "true", SSH_STRICT_HOSTKEY_YES },
  769. { "false", SSH_STRICT_HOSTKEY_OFF },
  770. { "yes", SSH_STRICT_HOSTKEY_YES },
  771. { "no", SSH_STRICT_HOSTKEY_OFF },
  772. { "ask", SSH_STRICT_HOSTKEY_ASK },
  773. { "off", SSH_STRICT_HOSTKEY_OFF },
  774. { "accept-new", SSH_STRICT_HOSTKEY_NEW },
  775. { NULL, -1 }
  776. };
  777. static const struct multistate multistate_yesnoaskconfirm[] = {
  778. { "true", 1 },
  779. { "false", 0 },
  780. { "yes", 1 },
  781. { "no", 0 },
  782. { "ask", 2 },
  783. { "confirm", 3 },
  784. { NULL, -1 }
  785. };
  786. static const struct multistate multistate_addressfamily[] = {
  787. { "inet", AF_INET },
  788. { "inet6", AF_INET6 },
  789. { "any", AF_UNSPEC },
  790. { NULL, -1 }
  791. };
  792. static const struct multistate multistate_controlmaster[] = {
  793. { "true", SSHCTL_MASTER_YES },
  794. { "yes", SSHCTL_MASTER_YES },
  795. { "false", SSHCTL_MASTER_NO },
  796. { "no", SSHCTL_MASTER_NO },
  797. { "auto", SSHCTL_MASTER_AUTO },
  798. { "ask", SSHCTL_MASTER_ASK },
  799. { "autoask", SSHCTL_MASTER_AUTO_ASK },
  800. { NULL, -1 }
  801. };
  802. static const struct multistate multistate_tunnel[] = {
  803. { "ethernet", SSH_TUNMODE_ETHERNET },
  804. { "point-to-point", SSH_TUNMODE_POINTOPOINT },
  805. { "true", SSH_TUNMODE_DEFAULT },
  806. { "yes", SSH_TUNMODE_DEFAULT },
  807. { "false", SSH_TUNMODE_NO },
  808. { "no", SSH_TUNMODE_NO },
  809. { NULL, -1 }
  810. };
  811. static const struct multistate multistate_requesttty[] = {
  812. { "true", REQUEST_TTY_YES },
  813. { "yes", REQUEST_TTY_YES },
  814. { "false", REQUEST_TTY_NO },
  815. { "no", REQUEST_TTY_NO },
  816. { "force", REQUEST_TTY_FORCE },
  817. { "auto", REQUEST_TTY_AUTO },
  818. { NULL, -1 }
  819. };
  820. static const struct multistate multistate_canonicalizehostname[] = {
  821. { "true", SSH_CANONICALISE_YES },
  822. { "false", SSH_CANONICALISE_NO },
  823. { "yes", SSH_CANONICALISE_YES },
  824. { "no", SSH_CANONICALISE_NO },
  825. { "always", SSH_CANONICALISE_ALWAYS },
  826. { NULL, -1 }
  827. };
  828. static const struct multistate multistate_compression[] = {
  829. #ifdef WITH_ZLIB
  830. { "yes", COMP_ZLIB },
  831. #endif
  832. { "no", COMP_NONE },
  833. { NULL, -1 }
  834. };
  835. static int
  836. parse_multistate_value(const char *arg, const char *filename, int linenum,
  837. const struct multistate *multistate_ptr)
  838. {
  839. int i;
  840. if (!arg || *arg == '\0') {
  841. error("%s line %d: missing argument.", filename, linenum);
  842. return -1;
  843. }
  844. for (i = 0; multistate_ptr[i].key != NULL; i++) {
  845. if (strcasecmp(arg, multistate_ptr[i].key) == 0)
  846. return multistate_ptr[i].value;
  847. }
  848. return -1;
  849. }
  850. /*
  851. * Processes a single option line as used in the configuration files. This
  852. * only sets those values that have not already been set.
  853. */
  854. int
  855. process_config_line(Options *options, struct passwd *pw, const char *host,
  856. const char *original_host, char *line, const char *filename,
  857. int linenum, int *activep, int flags)
  858. {
  859. return process_config_line_depth(options, pw, host, original_host,
  860. line, filename, linenum, activep, flags, NULL, 0);
  861. }
  862. #define WHITESPACE " \t\r\n"
  863. static int
  864. process_config_line_depth(Options *options, struct passwd *pw, const char *host,
  865. const char *original_host, char *line, const char *filename,
  866. int linenum, int *activep, int flags, int *want_final_pass, int depth)
  867. {
  868. char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
  869. char **cpptr, ***cppptr, fwdarg[512];
  870. u_int i, *uintptr, uvalue, max_entries = 0;
  871. int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
  872. int remotefwd, dynamicfwd;
  873. LogLevel *log_level_ptr;
  874. SyslogFacility *log_facility_ptr;
  875. long long val64;
  876. size_t len;
  877. struct Forward fwd;
  878. const struct multistate *multistate_ptr;
  879. struct allowed_cname *cname;
  880. glob_t gl;
  881. const char *errstr;
  882. if (activep == NULL) { /* We are processing a command line directive */
  883. cmdline = 1;
  884. activep = &cmdline;
  885. }
  886. /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
  887. if ((len = strlen(line)) == 0)
  888. return 0;
  889. for (len--; len > 0; len--) {
  890. if (strchr(WHITESPACE "\f", line[len]) == NULL)
  891. break;
  892. line[len] = '\0';
  893. }
  894. s = line;
  895. /* Get the keyword. (Each line is supposed to begin with a keyword). */
  896. if ((keyword = strdelim(&s)) == NULL)
  897. return 0;
  898. /* Ignore leading whitespace. */
  899. if (*keyword == '\0')
  900. keyword = strdelim(&s);
  901. if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
  902. return 0;
  903. /* Match lowercase keyword */
  904. lowercase(keyword);
  905. opcode = parse_token(keyword, filename, linenum,
  906. options->ignored_unknown);
  907. switch (opcode) {
  908. case oBadOption:
  909. /* don't panic, but count bad options */
  910. return -1;
  911. case oIgnore:
  912. return 0;
  913. case oIgnoredUnknownOption:
  914. debug("%s line %d: Ignored unknown option \"%s\"",
  915. filename, linenum, keyword);
  916. return 0;
  917. case oConnectTimeout:
  918. intptr = &options->connection_timeout;
  919. parse_time:
  920. arg = strdelim(&s);
  921. if (!arg || *arg == '\0') {
  922. error("%s line %d: missing time value.",
  923. filename, linenum);
  924. return -1;
  925. }
  926. if (strcmp(arg, "none") == 0)
  927. value = -1;
  928. else if ((value = convtime(arg)) == -1) {
  929. error("%s line %d: invalid time value.",
  930. filename, linenum);
  931. return -1;
  932. }
  933. if (*activep && *intptr == -1)
  934. *intptr = value;
  935. break;
  936. case oForwardAgent:
  937. intptr = &options->forward_agent;
  938. arg = strdelim(&s);
  939. if (!arg || *arg == '\0') {
  940. error("%s line %d: missing argument.",
  941. filename, linenum);
  942. return -1;
  943. }
  944. value = -1;
  945. multistate_ptr = multistate_flag;
  946. for (i = 0; multistate_ptr[i].key != NULL; i++) {
  947. if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
  948. value = multistate_ptr[i].value;
  949. break;
  950. }
  951. }
  952. if (value != -1) {
  953. if (*activep && *intptr == -1)
  954. *intptr = value;
  955. break;
  956. }
  957. /* ForwardAgent wasn't 'yes' or 'no', assume a path */
  958. if (*activep && *intptr == -1)
  959. *intptr = 1;
  960. charptr = &options->forward_agent_sock_path;
  961. goto parse_agent_path;
  962. case oForwardX11:
  963. intptr = &options->forward_x11;
  964. parse_flag:
  965. multistate_ptr = multistate_flag;
  966. parse_multistate:
  967. arg = strdelim(&s);
  968. if ((value = parse_multistate_value(arg, filename, linenum,
  969. multistate_ptr)) == -1) {
  970. error("%s line %d: unsupported option \"%s\".",
  971. filename, linenum, arg);
  972. return -1;
  973. }
  974. if (*activep && *intptr == -1)
  975. *intptr = value;
  976. break;
  977. case oForwardX11Trusted:
  978. intptr = &options->forward_x11_trusted;
  979. goto parse_flag;
  980. case oForwardX11Timeout:
  981. intptr = &options->forward_x11_timeout;
  982. goto parse_time;
  983. case oGatewayPorts:
  984. intptr = &options->fwd_opts.gateway_ports;
  985. goto parse_flag;
  986. case oExitOnForwardFailure:
  987. intptr = &options->exit_on_forward_failure;
  988. goto parse_flag;
  989. case oPasswordAuthentication:
  990. intptr = &options->password_authentication;
  991. goto parse_flag;
  992. case oKbdInteractiveAuthentication:
  993. intptr = &options->kbd_interactive_authentication;
  994. goto parse_flag;
  995. case oKbdInteractiveDevices:
  996. charptr = &options->kbd_interactive_devices;
  997. goto parse_string;
  998. case oPubkeyAuthentication:
  999. intptr = &options->pubkey_authentication;
  1000. goto parse_flag;
  1001. case oHostbasedAuthentication:
  1002. intptr = &options->hostbased_authentication;
  1003. goto parse_flag;
  1004. case oChallengeResponseAuthentication:
  1005. intptr = &options->challenge_response_authentication;
  1006. goto parse_flag;
  1007. case oGssAuthentication:
  1008. intptr = &options->gss_authentication;
  1009. goto parse_flag;
  1010. case oGssDelegateCreds:
  1011. intptr = &options->gss_deleg_creds;
  1012. goto parse_flag;
  1013. case oBatchMode:
  1014. intptr = &options->batch_mode;
  1015. goto parse_flag;
  1016. case oCheckHostIP:
  1017. intptr = &options->check_host_ip;
  1018. goto parse_flag;
  1019. case oHPNDisabled:
  1020. intptr = &options->hpn_disabled;
  1021. goto parse_flag;
  1022. case oHPNBufferSize:
  1023. intptr = &options->hpn_buffer_size;
  1024. goto parse_int;
  1025. case oTcpRcvBufPoll:
  1026. intptr = &options->tcp_rcv_buf_poll;
  1027. goto parse_flag;
  1028. case oNoneEnabled:
  1029. intptr = &options->none_enabled;
  1030. goto parse_flag;
  1031. case oNoneMacEnabled:
  1032. intptr = &options->nonemac_enabled;
  1033. goto parse_flag;
  1034. case oDisableMTAES:
  1035. intptr = &options->disable_multithreaded;
  1036. goto parse_flag;
  1037. /*
  1038. * We check to see if the command comes from the command
  1039. * line or not. If it does then enable it otherwise fail.
  1040. * NONE should never be a default configuration.
  1041. */
  1042. case oNoneSwitch:
  1043. if (strcmp(filename, "command-line") == 0) {
  1044. intptr = &options->none_switch;
  1045. goto parse_flag;
  1046. } else {
  1047. error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
  1048. error("Continuing...");
  1049. debug("NoneSwitch directive found in %.200s.", filename);
  1050. return 0;
  1051. }
  1052. case oVerifyHostKeyDNS:
  1053. intptr = &options->verify_host_key_dns;
  1054. multistate_ptr = multistate_yesnoask;
  1055. goto parse_multistate;
  1056. case oStrictHostKeyChecking:
  1057. intptr = &options->strict_host_key_checking;
  1058. multistate_ptr = multistate_strict_hostkey;
  1059. goto parse_multistate;
  1060. case oCompression:
  1061. intptr = &options->compression;
  1062. multistate_ptr = multistate_compression;
  1063. goto parse_multistate;
  1064. case oTCPKeepAlive:
  1065. intptr = &options->tcp_keep_alive;
  1066. goto parse_flag;
  1067. case oNoHostAuthenticationForLocalhost:
  1068. intptr = &options->no_host_authentication_for_localhost;
  1069. goto parse_flag;
  1070. case oNumberOfPasswordPrompts:
  1071. intptr = &options->number_of_password_prompts;
  1072. goto parse_int;
  1073. case oRekeyLimit:
  1074. arg = strdelim(&s);
  1075. if (!arg || *arg == '\0') {
  1076. error("%.200s line %d: Missing argument.", filename,
  1077. linenum);
  1078. return -1;
  1079. }
  1080. if (strcmp(arg, "default") == 0) {
  1081. val64 = 0;
  1082. } else {
  1083. if (scan_scaled(arg, &val64) == -1) {
  1084. error("%.200s line %d: Bad number '%s': %s",
  1085. filename, linenum, arg, strerror(errno));
  1086. return -1;
  1087. }
  1088. if (val64 != 0 && val64 < 16) {
  1089. error("%.200s line %d: RekeyLimit too small",
  1090. filename, linenum);
  1091. return -1;
  1092. }
  1093. }
  1094. if (*activep && options->rekey_limit == -1)
  1095. options->rekey_limit = val64;
  1096. if (s != NULL) { /* optional rekey interval present */
  1097. if (strcmp(s, "none") == 0) {
  1098. (void)strdelim(&s); /* discard */
  1099. break;
  1100. }
  1101. intptr = &options->rekey_interval;
  1102. goto parse_time;
  1103. }
  1104. break;
  1105. case oIdentityFile:
  1106. arg = strdelim(&s);
  1107. if (!arg || *arg == '\0') {
  1108. error("%.200s line %d: Missing argument.",
  1109. filename, linenum);
  1110. return -1;
  1111. }
  1112. if (*activep) {
  1113. intptr = &options->num_identity_files;
  1114. if (*intptr >= SSH_MAX_IDENTITY_FILES) {
  1115. error("%.200s line %d: Too many identity files "
  1116. "specified (max %d).", filename, linenum,
  1117. SSH_MAX_IDENTITY_FILES);
  1118. return -1;
  1119. }
  1120. add_identity_file(options, NULL,
  1121. arg, flags & SSHCONF_USERCONF);
  1122. }
  1123. break;
  1124. case oCertificateFile:
  1125. arg = strdelim(&s);
  1126. if (!arg || *arg == '\0') {
  1127. error("%.200s line %d: Missing argument.",
  1128. filename, linenum);
  1129. return -1;
  1130. }
  1131. if (*activep) {
  1132. intptr = &options->num_certificate_files;
  1133. if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
  1134. error("%.200s line %d: Too many certificate "
  1135. "files specified (max %d).",
  1136. filename, linenum,
  1137. SSH_MAX_CERTIFICATE_FILES);
  1138. return -1;
  1139. }
  1140. add_certificate_file(options, arg,
  1141. flags & SSHCONF_USERCONF);
  1142. }
  1143. break;
  1144. case oXAuthLocation:
  1145. charptr=&options->xauth_location;
  1146. goto parse_string;
  1147. case oUser:
  1148. charptr = &options->user;
  1149. parse_string:
  1150. arg = strdelim(&s);
  1151. if (!arg || *arg == '\0') {
  1152. error("%.200s line %d: Missing argument.",
  1153. filename, linenum);
  1154. return -1;
  1155. }
  1156. if (*activep && *charptr == NULL)
  1157. *charptr = xstrdup(arg);
  1158. break;
  1159. case oGlobalKnownHostsFile:
  1160. cpptr = (char **)&options->system_hostfiles;
  1161. uintptr = &options->num_system_hostfiles;
  1162. max_entries = SSH_MAX_HOSTS_FILES;
  1163. parse_char_array:
  1164. if (*activep && *uintptr == 0) {
  1165. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1166. if ((*uintptr) >= max_entries) {
  1167. error("%s line %d: too many known "
  1168. "hosts files.", filename, linenum);
  1169. return -1;
  1170. }
  1171. cpptr[(*uintptr)++] = xstrdup(arg);
  1172. }
  1173. }
  1174. return 0;
  1175. case oUserKnownHostsFile:
  1176. cpptr = (char **)&options->user_hostfiles;
  1177. uintptr = &options->num_user_hostfiles;
  1178. max_entries = SSH_MAX_HOSTS_FILES;
  1179. goto parse_char_array;
  1180. case oHostname:
  1181. charptr = &options->hostname;
  1182. goto parse_string;
  1183. case oHostKeyAlias:
  1184. charptr = &options->host_key_alias;
  1185. goto parse_string;
  1186. case oPreferredAuthentications:
  1187. charptr = &options->preferred_authentications;
  1188. goto parse_string;
  1189. case oBindAddress:
  1190. charptr = &options->bind_address;
  1191. goto parse_string;
  1192. case oBindInterface:
  1193. charptr = &options->bind_interface;
  1194. goto parse_string;
  1195. case oPKCS11Provider:
  1196. charptr = &options->pkcs11_provider;
  1197. goto parse_string;
  1198. case oSecurityKeyProvider:
  1199. charptr = &options->sk_provider;
  1200. goto parse_string;
  1201. case oProxyCommand:
  1202. charptr = &options->proxy_command;
  1203. /* Ignore ProxyCommand if ProxyJump already specified */
  1204. if (options->jump_host != NULL)
  1205. charptr = &options->jump_host; /* Skip below */
  1206. parse_command:
  1207. if (s == NULL) {
  1208. error("%.200s line %d: Missing argument.",
  1209. filename, linenum);
  1210. return -1;
  1211. }
  1212. len = strspn(s, WHITESPACE "=");
  1213. if (*activep && *charptr == NULL)
  1214. *charptr = xstrdup(s + len);
  1215. return 0;
  1216. case oProxyJump:
  1217. if (s == NULL) {
  1218. error("%.200s line %d: Missing argument.",
  1219. filename, linenum);
  1220. return -1;
  1221. }
  1222. len = strspn(s, WHITESPACE "=");
  1223. if (parse_jump(s + len, options, *activep) == -1) {
  1224. error("%.200s line %d: Invalid ProxyJump \"%s\"",
  1225. filename, linenum, s + len);
  1226. return -1;
  1227. }
  1228. return 0;
  1229. case oPort:
  1230. arg = strdelim(&s);
  1231. if (!arg || *arg == '\0') {
  1232. error("%.200s line %d: Missing argument.",
  1233. filename, linenum);
  1234. return -1;
  1235. }
  1236. value = a2port(arg);
  1237. if (value <= 0) {
  1238. error("%.200s line %d: Bad port '%s'.",
  1239. filename, linenum, arg);
  1240. return -1;
  1241. }
  1242. if (*activep && options->port == -1)
  1243. options->port = value;
  1244. break;
  1245. case oConnectionAttempts:
  1246. intptr = &options->connection_attempts;
  1247. parse_int:
  1248. arg = strdelim(&s);
  1249. if ((errstr = atoi_err(arg, &value)) != NULL) {
  1250. error("%s line %d: integer value %s.",
  1251. filename, linenum, errstr);
  1252. return -1;
  1253. }
  1254. if (*activep && *intptr == -1)
  1255. *intptr = value;
  1256. break;
  1257. case oTcpRcvBuf:
  1258. intptr = &options->tcp_rcv_buf;
  1259. goto parse_int;
  1260. case oCiphers:
  1261. arg = strdelim(&s);
  1262. if (!arg || *arg == '\0') {
  1263. error("%.200s line %d: Missing argument.",
  1264. filename, linenum);
  1265. return -1;
  1266. }
  1267. if (*arg != '-' &&
  1268. !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
  1269. error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
  1270. filename, linenum, arg ? arg : "<NONE>");
  1271. return -1;
  1272. }
  1273. if (*activep && options->ciphers == NULL)
  1274. options->ciphers = xstrdup(arg);
  1275. break;
  1276. case oMacs:
  1277. arg = strdelim(&s);
  1278. if (!arg || *arg == '\0') {
  1279. error("%.200s line %d: Missing argument.",
  1280. filename, linenum);
  1281. return -1;
  1282. }
  1283. if (*arg != '-' &&
  1284. !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
  1285. error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
  1286. filename, linenum, arg ? arg : "<NONE>");
  1287. return -1;
  1288. }
  1289. if (*activep && options->macs == NULL)
  1290. options->macs = xstrdup(arg);
  1291. break;
  1292. case oKexAlgorithms:
  1293. arg = strdelim(&s);
  1294. if (!arg || *arg == '\0') {
  1295. error("%.200s line %d: Missing argument.",
  1296. filename, linenum);
  1297. return -1;
  1298. }
  1299. if (*arg != '-' &&
  1300. !kex_names_valid(*arg == '+' || *arg == '^' ?
  1301. arg + 1 : arg)) {
  1302. error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
  1303. filename, linenum, arg ? arg : "<NONE>");
  1304. return -1;
  1305. }
  1306. if (*activep && options->kex_algorithms == NULL)
  1307. options->kex_algorithms = xstrdup(arg);
  1308. break;
  1309. case oHostKeyAlgorithms:
  1310. charptr = &options->hostkeyalgorithms;
  1311. parse_pubkey_algos:
  1312. arg = strdelim(&s);
  1313. if (!arg || *arg == '\0') {
  1314. error("%.200s line %d: Missing argument.",
  1315. filename, linenum);
  1316. return -1;
  1317. }
  1318. if (*arg != '-' &&
  1319. !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
  1320. arg + 1 : arg, 1)) {
  1321. error("%s line %d: Bad key types '%s'.",
  1322. filename, linenum, arg ? arg : "<NONE>");
  1323. return -1;
  1324. }
  1325. if (*activep && *charptr == NULL)
  1326. *charptr = xstrdup(arg);
  1327. break;
  1328. case oCASignatureAlgorithms:
  1329. charptr = &options->ca_sign_algorithms;
  1330. goto parse_pubkey_algos;
  1331. case oLogLevel:
  1332. log_level_ptr = &options->log_level;
  1333. arg = strdelim(&s);
  1334. value = log_level_number(arg);
  1335. if (value == SYSLOG_LEVEL_NOT_SET) {
  1336. error("%.200s line %d: unsupported log level '%s'",
  1337. filename, linenum, arg ? arg : "<NONE>");
  1338. return -1;
  1339. }
  1340. if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
  1341. *log_level_ptr = (LogLevel) value;
  1342. break;
  1343. case oLogFacility:
  1344. log_facility_ptr = &options->log_facility;
  1345. arg = strdelim(&s);
  1346. value = log_facility_number(arg);
  1347. if (value == SYSLOG_FACILITY_NOT_SET) {
  1348. error("%.200s line %d: unsupported log facility '%s'",
  1349. filename, linenum, arg ? arg : "<NONE>");
  1350. return -1;
  1351. }
  1352. if (*log_facility_ptr == -1)
  1353. *log_facility_ptr = (SyslogFacility) value;
  1354. break;
  1355. case oLocalForward:
  1356. case oRemoteForward:
  1357. case oDynamicForward:
  1358. arg = strdelim(&s);
  1359. if (!arg || *arg == '\0') {
  1360. error("%.200s line %d: Missing argument.",
  1361. filename, linenum);
  1362. return -1;
  1363. }
  1364. remotefwd = (opcode == oRemoteForward);
  1365. dynamicfwd = (opcode == oDynamicForward);
  1366. if (!dynamicfwd) {
  1367. arg2 = strdelim(&s);
  1368. if (arg2 == NULL || *arg2 == '\0') {
  1369. if (remotefwd)
  1370. dynamicfwd = 1;
  1371. else {
  1372. error("%.200s line %d: Missing target "
  1373. "argument.", filename, linenum);
  1374. return -1;
  1375. }
  1376. } else {
  1377. /* construct a string for parse_forward */
  1378. snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
  1379. arg2);
  1380. }
  1381. }
  1382. if (dynamicfwd)
  1383. strlcpy(fwdarg, arg, sizeof(fwdarg));
  1384. if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
  1385. error("%.200s line %d: Bad forwarding specification.",
  1386. filename, linenum);
  1387. return -1;
  1388. }
  1389. if (*activep) {
  1390. if (remotefwd) {
  1391. add_remote_forward(options, &fwd);
  1392. } else {
  1393. add_local_forward(options, &fwd);
  1394. }
  1395. }
  1396. break;
  1397. case oPermitRemoteOpen:
  1398. uintptr = &options->num_permitted_remote_opens;
  1399. cppptr = &options->permitted_remote_opens;
  1400. arg = strdelim(&s);
  1401. if (!arg || *arg == '\0')
  1402. fatal("%s line %d: missing %s specification",
  1403. filename, linenum, lookup_opcode_name(opcode));
  1404. uvalue = *uintptr; /* modified later */
  1405. if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
  1406. if (*activep && uvalue == 0) {
  1407. *uintptr = 1;
  1408. *cppptr = xcalloc(1, sizeof(**cppptr));
  1409. (*cppptr)[0] = xstrdup(arg);
  1410. }
  1411. break;
  1412. }
  1413. for (; arg != NULL && *arg != '\0'; arg = strdelim(&s)) {
  1414. arg2 = xstrdup(arg);
  1415. ch = '\0';
  1416. p = hpdelim2(&arg, &ch);
  1417. if (p == NULL || ch == '/') {
  1418. fatal("%s line %d: missing host in %s",
  1419. filename, linenum,
  1420. lookup_opcode_name(opcode));
  1421. }
  1422. p = cleanhostname(p);
  1423. /*
  1424. * don't want to use permitopen_port to avoid
  1425. * dependency on channels.[ch] here.
  1426. */
  1427. if (arg == NULL ||
  1428. (strcmp(arg, "*") != 0 && a2port(arg) <= 0)) {
  1429. fatal("%s line %d: bad port number in %s",
  1430. filename, linenum,
  1431. lookup_opcode_name(opcode));
  1432. }
  1433. if (*activep && uvalue == 0) {
  1434. opt_array_append(filename, linenum,
  1435. lookup_opcode_name(opcode),
  1436. cppptr, uintptr, arg2);
  1437. }
  1438. free(arg2);
  1439. }
  1440. break;
  1441. case oClearAllForwardings:
  1442. intptr = &options->clear_forwardings;
  1443. goto parse_flag;
  1444. case oHost:
  1445. if (cmdline) {
  1446. error("Host directive not supported as a command-line "
  1447. "option");
  1448. return -1;
  1449. }
  1450. *activep = 0;
  1451. arg2 = NULL;
  1452. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1453. if ((flags & SSHCONF_NEVERMATCH) != 0)
  1454. break;
  1455. negated = *arg == '!';
  1456. if (negated)
  1457. arg++;
  1458. if (match_pattern(host, arg)) {
  1459. if (negated) {
  1460. debug("%.200s line %d: Skipping Host "
  1461. "block because of negated match "
  1462. "for %.100s", filename, linenum,
  1463. arg);
  1464. *activep = 0;
  1465. break;
  1466. }
  1467. if (!*activep)
  1468. arg2 = arg; /* logged below */
  1469. *activep = 1;
  1470. }
  1471. }
  1472. if (*activep)
  1473. debug("%.200s line %d: Applying options for %.100s",
  1474. filename, linenum, arg2);
  1475. /* Avoid garbage check below, as strdelim is done. */
  1476. return 0;
  1477. case oMatch:
  1478. if (cmdline) {
  1479. error("Host directive not supported as a command-line "
  1480. "option");
  1481. return -1;
  1482. }
  1483. value = match_cfg_line(options, &s, pw, host, original_host,
  1484. flags & SSHCONF_FINAL, want_final_pass,
  1485. filename, linenum);
  1486. if (value < 0) {
  1487. error("%.200s line %d: Bad Match condition", filename,
  1488. linenum);
  1489. return -1;
  1490. }
  1491. *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
  1492. break;
  1493. case oEscapeChar:
  1494. intptr = &options->escape_char;
  1495. arg = strdelim(&s);
  1496. if (!arg || *arg == '\0') {
  1497. error("%.200s line %d: Missing argument.",
  1498. filename, linenum);
  1499. return -1;
  1500. }
  1501. if (strcmp(arg, "none") == 0)
  1502. value = SSH_ESCAPECHAR_NONE;
  1503. else if (arg[1] == '\0')
  1504. value = (u_char) arg[0];
  1505. else if (arg[0] == '^' && arg[2] == 0 &&
  1506. (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
  1507. value = (u_char) arg[1] & 31;
  1508. else {
  1509. error("%.200s line %d: Bad escape character.",
  1510. filename, linenum);
  1511. value = 0; /* Avoid compiler warning. */
  1512. return -1;
  1513. }
  1514. if (*activep && *intptr == -1)
  1515. *intptr = value;
  1516. break;
  1517. case oAddressFamily:
  1518. intptr = &options->address_family;
  1519. multistate_ptr = multistate_addressfamily;
  1520. goto parse_multistate;
  1521. case oEnableSSHKeysign:
  1522. intptr = &options->enable_ssh_keysign;
  1523. goto parse_flag;
  1524. case oIdentitiesOnly:
  1525. intptr = &options->identities_only;
  1526. goto parse_flag;
  1527. case oServerAliveInterval:
  1528. case oProtocolKeepAlives: /* Debian-specific compatibility alias */
  1529. case oSetupTimeOut: /* Debian-specific compatibility alias */
  1530. intptr = &options->server_alive_interval;
  1531. goto parse_time;
  1532. case oServerAliveCountMax:
  1533. intptr = &options->server_alive_count_max;
  1534. goto parse_int;
  1535. case oSendEnv:
  1536. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1537. if (strchr(arg, '=') != NULL) {
  1538. error("%s line %d: Invalid environment name.",
  1539. filename, linenum);
  1540. return -1;
  1541. }
  1542. if (!*activep)
  1543. continue;
  1544. if (*arg == '-') {
  1545. /* Removing an env var */
  1546. rm_env(options, arg, filename, linenum);
  1547. continue;
  1548. } else {
  1549. /* Adding an env var */
  1550. if (options->num_send_env >= INT_MAX) {
  1551. error("%s line %d: too many send env.",
  1552. filename, linenum);
  1553. return -1;
  1554. }
  1555. options->send_env = xrecallocarray(
  1556. options->send_env, options->num_send_env,
  1557. options->num_send_env + 1,
  1558. sizeof(*options->send_env));
  1559. options->send_env[options->num_send_env++] =
  1560. xstrdup(arg);
  1561. }
  1562. }
  1563. break;
  1564. case oSetEnv:
  1565. value = options->num_setenv;
  1566. while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
  1567. if (strchr(arg, '=') == NULL) {
  1568. error("%s line %d: Invalid SetEnv.",
  1569. filename, linenum);
  1570. return -1;
  1571. }
  1572. if (!*activep || value != 0)
  1573. continue;
  1574. /* Adding a setenv var */
  1575. if (options->num_setenv >= INT_MAX) {
  1576. error("%s line %d: too many SetEnv.",
  1577. filename, linenum);
  1578. return -1;
  1579. }
  1580. options->setenv = xrecallocarray(
  1581. options->setenv, options->num_setenv,
  1582. options->num_setenv + 1, sizeof(*options->setenv));
  1583. options->setenv[options->num_setenv++] = xstrdup(arg);
  1584. }
  1585. break;
  1586. case oControlPath:
  1587. charptr = &options->control_path;
  1588. goto parse_string;
  1589. case oControlMaster:
  1590. intptr = &options->control_master;
  1591. multistate_ptr = multistate_controlmaster;
  1592. goto parse_multistate;
  1593. case oControlPersist:
  1594. /* no/false/yes/true, or a time spec */
  1595. intptr = &options->control_persist;
  1596. arg = strdelim(&s);
  1597. if (!arg || *arg == '\0') {
  1598. error("%.200s line %d: Missing ControlPersist"
  1599. " argument.", filename, linenum);
  1600. return -1;
  1601. }
  1602. value = 0;
  1603. value2 = 0; /* timeout */
  1604. if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
  1605. value = 0;
  1606. else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
  1607. value = 1;
  1608. else if ((value2 = convtime(arg)) >= 0)
  1609. value = 1;
  1610. else {
  1611. error("%.200s line %d: Bad ControlPersist argument.",
  1612. filename, linenum);
  1613. return -1;
  1614. }
  1615. if (*activep && *intptr == -1) {
  1616. *intptr = value;
  1617. options->control_persist_timeout = value2;
  1618. }
  1619. break;
  1620. case oHashKnownHosts:
  1621. intptr = &options->hash_known_hosts;
  1622. goto parse_flag;
  1623. case oTunnel:
  1624. intptr = &options->tun_open;
  1625. multistate_ptr = multistate_tunnel;
  1626. goto parse_multistate;
  1627. case oTunnelDevice:
  1628. arg = strdelim(&s);
  1629. if (!arg || *arg == '\0') {
  1630. error("%.200s line %d: Missing argument.",
  1631. filename, linenum);
  1632. return -1;
  1633. }
  1634. value = a2tun(arg, &value2);
  1635. if (value == SSH_TUNID_ERR) {
  1636. error("%.200s line %d: Bad tun device.",
  1637. filename, linenum);
  1638. return -1;
  1639. }
  1640. if (*activep) {
  1641. options->tun_local = value;
  1642. options->tun_remote = value2;
  1643. }
  1644. break;
  1645. case oLocalCommand:
  1646. charptr = &options->local_command;
  1647. goto parse_command;
  1648. case oPermitLocalCommand:
  1649. intptr = &options->permit_local_command;
  1650. goto parse_flag;
  1651. case oRemoteCommand:
  1652. charptr = &options->remote_command;
  1653. goto parse_command;
  1654. case oVisualHostKey:
  1655. intptr = &options->visual_host_key;
  1656. goto parse_flag;
  1657. case oInclude:
  1658. if (cmdline) {
  1659. error("Include directive not supported as a "
  1660. "command-line option");
  1661. return -1;
  1662. }
  1663. value = 0;
  1664. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1665. /*
  1666. * Ensure all paths are anchored. User configuration
  1667. * files may begin with '~/' but system configurations
  1668. * must not. If the path is relative, then treat it
  1669. * as living in ~/.ssh for user configurations or
  1670. * /etc/ssh for system ones.
  1671. */
  1672. if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {
  1673. error("%.200s line %d: bad include path %s.",
  1674. filename, linenum, arg);
  1675. return -1;
  1676. }
  1677. if (!path_absolute(arg) && *arg != '~') {
  1678. xasprintf(&arg2, "%s/%s",
  1679. (flags & SSHCONF_USERCONF) ?
  1680. "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
  1681. } else
  1682. arg2 = xstrdup(arg);
  1683. memset(&gl, 0, sizeof(gl));
  1684. r = glob(arg2, GLOB_TILDE, NULL, &gl);
  1685. if (r == GLOB_NOMATCH) {
  1686. debug("%.200s line %d: include %s matched no "
  1687. "files",filename, linenum, arg2);
  1688. free(arg2);
  1689. continue;
  1690. } else if (r != 0) {
  1691. error("%.200s line %d: glob failed for %s.",
  1692. filename, linenum, arg2);
  1693. return -1;
  1694. }
  1695. free(arg2);
  1696. oactive = *activep;
  1697. for (i = 0; i < gl.gl_pathc; i++) {
  1698. debug3("%.200s line %d: Including file %s "
  1699. "depth %d%s", filename, linenum,
  1700. gl.gl_pathv[i], depth,
  1701. oactive ? "" : " (parse only)");
  1702. r = read_config_file_depth(gl.gl_pathv[i],
  1703. pw, host, original_host, options,
  1704. flags | SSHCONF_CHECKPERM |
  1705. (oactive ? 0 : SSHCONF_NEVERMATCH),
  1706. activep, want_final_pass, depth + 1);
  1707. if (r != 1 && errno != ENOENT) {
  1708. error("Can't open user config file "
  1709. "%.100s: %.100s", gl.gl_pathv[i],
  1710. strerror(errno));
  1711. globfree(&gl);
  1712. return -1;
  1713. }
  1714. /*
  1715. * don't let Match in includes clobber the
  1716. * containing file's Match state.
  1717. */
  1718. *activep = oactive;
  1719. if (r != 1)
  1720. value = -1;
  1721. }
  1722. globfree(&gl);
  1723. }
  1724. if (value != 0)
  1725. return value;
  1726. break;
  1727. case oIPQoS:
  1728. arg = strdelim(&s);
  1729. if ((value = parse_ipqos(arg)) == -1) {
  1730. error("%s line %d: Bad IPQoS value: %s",
  1731. filename, linenum, arg);
  1732. return -1;
  1733. }
  1734. arg = strdelim(&s);
  1735. if (arg == NULL)
  1736. value2 = value;
  1737. else if ((value2 = parse_ipqos(arg)) == -1) {
  1738. error("%s line %d: Bad IPQoS value: %s",
  1739. filename, linenum, arg);
  1740. return -1;
  1741. }
  1742. if (*activep) {
  1743. options->ip_qos_interactive = value;
  1744. options->ip_qos_bulk = value2;
  1745. }
  1746. break;
  1747. case oRequestTTY:
  1748. intptr = &options->request_tty;
  1749. multistate_ptr = multistate_requesttty;
  1750. goto parse_multistate;
  1751. case oNoShell:
  1752. intptr = &options->no_shell;
  1753. goto parse_flag;
  1754. case oStdinNull:
  1755. intptr = &options->stdin_null;
  1756. goto parse_flag;
  1757. case oForkAfterAuthentication:
  1758. intptr = &options->fork_after_authentication;
  1759. goto parse_flag;
  1760. case oIgnoreUnknown:
  1761. charptr = &options->ignored_unknown;
  1762. goto parse_string;
  1763. case oProxyUseFdpass:
  1764. intptr = &options->proxy_use_fdpass;
  1765. goto parse_flag;
  1766. case oCanonicalDomains:
  1767. value = options->num_canonical_domains != 0;
  1768. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1769. if (!valid_domain(arg, 1, &errstr)) {
  1770. error("%s line %d: %s", filename, linenum,
  1771. errstr);
  1772. return -1;
  1773. }
  1774. if (!*activep || value)
  1775. continue;
  1776. if (options->num_canonical_domains >=
  1777. MAX_CANON_DOMAINS) {
  1778. error("%s line %d: too many hostname suffixes.",
  1779. filename, linenum);
  1780. return -1;
  1781. }
  1782. options->canonical_domains[
  1783. options->num_canonical_domains++] = xstrdup(arg);
  1784. }
  1785. break;
  1786. case oCanonicalizePermittedCNAMEs:
  1787. value = options->num_permitted_cnames != 0;
  1788. while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1789. /* Either '*' for everything or 'list:list' */
  1790. if (strcmp(arg, "*") == 0)
  1791. arg2 = arg;
  1792. else {
  1793. lowercase(arg);
  1794. if ((arg2 = strchr(arg, ':')) == NULL ||
  1795. arg2[1] == '\0') {
  1796. error("%s line %d: "
  1797. "Invalid permitted CNAME \"%s\"",
  1798. filename, linenum, arg);
  1799. return -1;
  1800. }
  1801. *arg2 = '\0';
  1802. arg2++;
  1803. }
  1804. if (!*activep || value)
  1805. continue;
  1806. if (options->num_permitted_cnames >=
  1807. MAX_CANON_DOMAINS) {
  1808. error("%s line %d: too many permitted CNAMEs.",
  1809. filename, linenum);
  1810. return -1;
  1811. }
  1812. cname = options->permitted_cnames +
  1813. options->num_permitted_cnames++;
  1814. cname->source_list = xstrdup(arg);
  1815. cname->target_list = xstrdup(arg2);
  1816. }
  1817. break;
  1818. case oCanonicalizeHostname:
  1819. intptr = &options->canonicalize_hostname;
  1820. multistate_ptr = multistate_canonicalizehostname;
  1821. goto parse_multistate;
  1822. case oCanonicalizeMaxDots:
  1823. intptr = &options->canonicalize_max_dots;
  1824. goto parse_int;
  1825. case oCanonicalizeFallbackLocal:
  1826. intptr = &options->canonicalize_fallback_local;
  1827. goto parse_flag;
  1828. case oStreamLocalBindMask:
  1829. arg = strdelim(&s);
  1830. if (!arg || *arg == '\0') {
  1831. error("%.200s line %d: Missing StreamLocalBindMask "
  1832. "argument.", filename, linenum);
  1833. return -1;
  1834. }
  1835. /* Parse mode in octal format */
  1836. value = strtol(arg, &endofnumber, 8);
  1837. if (arg == endofnumber || value < 0 || value > 0777) {
  1838. error("%.200s line %d: Bad mask.", filename, linenum);
  1839. return -1;
  1840. }
  1841. options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
  1842. break;
  1843. case oStreamLocalBindUnlink:
  1844. intptr = &options->fwd_opts.streamlocal_bind_unlink;
  1845. goto parse_flag;
  1846. case oRevokedHostKeys:
  1847. charptr = &options->revoked_host_keys;
  1848. goto parse_string;
  1849. case oFingerprintHash:
  1850. intptr = &options->fingerprint_hash;
  1851. arg = strdelim(&s);
  1852. if (!arg || *arg == '\0') {
  1853. error("%.200s line %d: Missing argument.",
  1854. filename, linenum);
  1855. return -1;
  1856. }
  1857. if ((value = ssh_digest_alg_by_name(arg)) == -1) {
  1858. error("%.200s line %d: Invalid hash algorithm \"%s\".",
  1859. filename, linenum, arg);
  1860. return -1;
  1861. }
  1862. if (*activep && *intptr == -1)
  1863. *intptr = value;
  1864. break;
  1865. case oUpdateHostkeys:
  1866. intptr = &options->update_hostkeys;
  1867. multistate_ptr = multistate_yesnoask;
  1868. goto parse_multistate;
  1869. case oHostbasedAcceptedAlgorithms:
  1870. charptr = &options->hostbased_accepted_algos;
  1871. goto parse_pubkey_algos;
  1872. case oPubkeyAcceptedAlgorithms:
  1873. charptr = &options->pubkey_accepted_algos;
  1874. goto parse_pubkey_algos;
  1875. case oAddKeysToAgent:
  1876. arg = strdelim(&s);
  1877. arg2 = strdelim(&s);
  1878. value = parse_multistate_value(arg, filename, linenum,
  1879. multistate_yesnoaskconfirm);
  1880. value2 = 0; /* unlimited lifespan by default */
  1881. if (value == 3 && arg2 != NULL) {
  1882. /* allow "AddKeysToAgent confirm 5m" */
  1883. if ((value2 = convtime(arg2)) == -1 ||
  1884. value2 > INT_MAX) {
  1885. error("%s line %d: invalid time value.",
  1886. filename, linenum);
  1887. return -1;
  1888. }
  1889. } else if (value == -1 && arg2 == NULL) {
  1890. if ((value2 = convtime(arg)) == -1 ||
  1891. value2 > INT_MAX) {
  1892. error("%s line %d: unsupported option",
  1893. filename, linenum);
  1894. return -1;
  1895. }
  1896. value = 1; /* yes */
  1897. } else if (value == -1 || arg2 != NULL) {
  1898. error("%s line %d: unsupported option",
  1899. filename, linenum);
  1900. return -1;
  1901. }
  1902. if (*activep && options->add_keys_to_agent == -1) {
  1903. options->add_keys_to_agent = value;
  1904. options->add_keys_to_agent_lifespan = value2;
  1905. }
  1906. break;
  1907. case oIdentityAgent:
  1908. charptr = &options->identity_agent;
  1909. arg = strdelim(&s);
  1910. if (!arg || *arg == '\0') {
  1911. error("%.200s line %d: Missing argument.",
  1912. filename, linenum);
  1913. return -1;
  1914. }
  1915. parse_agent_path:
  1916. /* Extra validation if the string represents an env var. */
  1917. if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {
  1918. error("%.200s line %d: Invalid environment expansion "
  1919. "%s.", filename, linenum, arg);
  1920. return -1;
  1921. }
  1922. free(arg2);
  1923. /* check for legacy environment format */
  1924. if (arg[0] == '$' && arg[1] != '{' &&
  1925. !valid_env_name(arg + 1)) {
  1926. error("%.200s line %d: Invalid environment name %s.",
  1927. filename, linenum, arg);
  1928. return -1;
  1929. }
  1930. if (*activep && *charptr == NULL)
  1931. *charptr = xstrdup(arg);
  1932. break;
  1933. case oDeprecated:
  1934. debug("%s line %d: Deprecated option \"%s\"",
  1935. filename, linenum, keyword);
  1936. return 0;
  1937. case oUnsupported:
  1938. error("%s line %d: Unsupported option \"%s\"",
  1939. filename, linenum, keyword);
  1940. return 0;
  1941. default:
  1942. error("%s line %d: Unimplemented opcode %d",
  1943. filename, linenum, opcode);
  1944. }
  1945. /* Check that there is no garbage at end of line. */
  1946. if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  1947. error("%.200s line %d: garbage at end of line; \"%.200s\".",
  1948. filename, linenum, arg);
  1949. return -1;
  1950. }
  1951. return 0;
  1952. }
  1953. /*
  1954. * Reads the config file and modifies the options accordingly. Options
  1955. * should already be initialized before this call. This never returns if
  1956. * there is an error. If the file does not exist, this returns 0.
  1957. */
  1958. int
  1959. read_config_file(const char *filename, struct passwd *pw, const char *host,
  1960. const char *original_host, Options *options, int flags,
  1961. int *want_final_pass)
  1962. {
  1963. int active = 1;
  1964. return read_config_file_depth(filename, pw, host, original_host,
  1965. options, flags, &active, want_final_pass, 0);
  1966. }
  1967. #define READCONF_MAX_DEPTH 16
  1968. static int
  1969. read_config_file_depth(const char *filename, struct passwd *pw,
  1970. const char *host, const char *original_host, Options *options,
  1971. int flags, int *activep, int *want_final_pass, int depth)
  1972. {
  1973. FILE *f;
  1974. char *cp, *line = NULL;
  1975. size_t linesize = 0;
  1976. int linenum;
  1977. int bad_options = 0;
  1978. if (depth < 0 || depth > READCONF_MAX_DEPTH)
  1979. fatal("Too many recursive configuration includes");
  1980. if ((f = fopen(filename, "r")) == NULL)
  1981. return 0;
  1982. if (flags & SSHCONF_CHECKPERM) {
  1983. struct stat sb;
  1984. if (fstat(fileno(f), &sb) == -1)
  1985. fatal("fstat %s: %s", filename, strerror(errno));
  1986. if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
  1987. (sb.st_mode & 022) != 0))
  1988. fatal("Bad owner or permissions on %s", filename);
  1989. }
  1990. debug("Reading configuration data %.200s", filename);
  1991. /*
  1992. * Mark that we are now processing the options. This flag is turned
  1993. * on/off by Host specifications.
  1994. */
  1995. linenum = 0;
  1996. while (getline(&line, &linesize, f) != -1) {
  1997. /* Update line number counter. */
  1998. linenum++;
  1999. /*
  2000. * Trim out comments and strip whitespace.
  2001. * NB - preserve newlines, they are needed to reproduce
  2002. * line numbers later for error messages.
  2003. */
  2004. if ((cp = strchr(line, '#')) != NULL)
  2005. *cp = '\0';
  2006. if (process_config_line_depth(options, pw, host, original_host,
  2007. line, filename, linenum, activep, flags, want_final_pass,
  2008. depth) != 0)
  2009. bad_options++;
  2010. }
  2011. free(line);
  2012. fclose(f);
  2013. if (bad_options > 0)
  2014. fatal("%s: terminating, %d bad configuration options",
  2015. filename, bad_options);
  2016. return 1;
  2017. }
  2018. /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
  2019. int
  2020. option_clear_or_none(const char *o)
  2021. {
  2022. return o == NULL || strcasecmp(o, "none") == 0;
  2023. }
  2024. /*
  2025. * Initializes options to special values that indicate that they have not yet
  2026. * been set. Read_config_file will only set options with this value. Options
  2027. * are processed in the following order: command line, user config file,
  2028. * system config file. Last, fill_default_options is called.
  2029. */
  2030. void
  2031. initialize_options(Options * options)
  2032. {
  2033. memset(options, 'X', sizeof(*options));
  2034. options->forward_agent = -1;
  2035. options->forward_agent_sock_path = NULL;
  2036. options->forward_x11 = -1;
  2037. options->forward_x11_trusted = -1;
  2038. options->forward_x11_timeout = -1;
  2039. options->stdio_forward_host = NULL;
  2040. options->stdio_forward_port = 0;
  2041. options->clear_forwardings = -1;
  2042. options->exit_on_forward_failure = -1;
  2043. options->xauth_location = NULL;
  2044. options->fwd_opts.gateway_ports = -1;
  2045. options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
  2046. options->fwd_opts.streamlocal_bind_unlink = -1;
  2047. options->pubkey_authentication = -1;
  2048. options->challenge_response_authentication = -1;
  2049. options->gss_authentication = -1;
  2050. options->gss_deleg_creds = -1;
  2051. options->password_authentication = -1;
  2052. options->kbd_interactive_authentication = -1;
  2053. options->kbd_interactive_devices = NULL;
  2054. options->hostbased_authentication = -1;
  2055. options->batch_mode = -1;
  2056. options->check_host_ip = -1;
  2057. options->strict_host_key_checking = -1;
  2058. options->compression = -1;
  2059. options->tcp_keep_alive = -1;
  2060. options->port = -1;
  2061. options->address_family = -1;
  2062. options->connection_attempts = -1;
  2063. options->connection_timeout = -1;
  2064. options->number_of_password_prompts = -1;
  2065. options->ciphers = NULL;
  2066. options->macs = NULL;
  2067. options->kex_algorithms = NULL;
  2068. options->hostkeyalgorithms = NULL;
  2069. options->ca_sign_algorithms = NULL;
  2070. options->num_identity_files = 0;
  2071. memset(options->identity_keys, 0, sizeof(options->identity_keys));
  2072. options->num_certificate_files = 0;
  2073. memset(options->certificates, 0, sizeof(options->certificates));
  2074. options->hostname = NULL;
  2075. options->host_key_alias = NULL;
  2076. options->proxy_command = NULL;
  2077. options->jump_user = NULL;
  2078. options->jump_host = NULL;
  2079. options->jump_port = -1;
  2080. options->jump_extra = NULL;
  2081. options->user = NULL;
  2082. options->escape_char = -1;
  2083. options->num_system_hostfiles = 0;
  2084. options->num_user_hostfiles = 0;
  2085. options->local_forwards = NULL;
  2086. options->num_local_forwards = 0;
  2087. options->remote_forwards = NULL;
  2088. options->num_remote_forwards = 0;
  2089. options->permitted_remote_opens = NULL;
  2090. options->num_permitted_remote_opens = 0;
  2091. options->log_facility = SYSLOG_FACILITY_NOT_SET;
  2092. options->log_level = SYSLOG_LEVEL_NOT_SET;
  2093. options->preferred_authentications = NULL;
  2094. options->bind_address = NULL;
  2095. options->bind_interface = NULL;
  2096. options->pkcs11_provider = NULL;
  2097. options->sk_provider = NULL;
  2098. options->enable_ssh_keysign = - 1;
  2099. options->no_host_authentication_for_localhost = - 1;
  2100. options->identities_only = - 1;
  2101. options->rekey_limit = - 1;
  2102. options->rekey_interval = -1;
  2103. options->verify_host_key_dns = -1;
  2104. options->server_alive_interval = -1;
  2105. options->server_alive_count_max = -1;
  2106. options->send_env = NULL;
  2107. options->num_send_env = 0;
  2108. options->setenv = NULL;
  2109. options->num_setenv = 0;
  2110. options->control_path = NULL;
  2111. options->control_master = -1;
  2112. options->control_persist = -1;
  2113. options->control_persist_timeout = 0;
  2114. options->hash_known_hosts = -1;
  2115. options->tun_open = -1;
  2116. options->tun_local = -1;
  2117. options->tun_remote = -1;
  2118. options->local_command = NULL;
  2119. options->permit_local_command = -1;
  2120. options->remote_command = NULL;
  2121. options->add_keys_to_agent = -1;
  2122. options->add_keys_to_agent_lifespan = -1;
  2123. options->identity_agent = NULL;
  2124. options->visual_host_key = -1;
  2125. options->ip_qos_interactive = -1;
  2126. options->ip_qos_bulk = -1;
  2127. options->request_tty = -1;
  2128. options->no_shell = -1;
  2129. options->stdin_null = -1;
  2130. options->fork_after_authentication = -1;
  2131. options->none_switch = -1;
  2132. options->none_enabled = -1;
  2133. options->nonemac_enabled = -1;
  2134. options->disable_multithreaded = -1;
  2135. options->hpn_disabled = -1;
  2136. options->hpn_buffer_size = -1;
  2137. options->tcp_rcv_buf_poll = -1;
  2138. options->tcp_rcv_buf = -1;
  2139. options->proxy_use_fdpass = -1;
  2140. options->ignored_unknown = NULL;
  2141. options->num_canonical_domains = 0;
  2142. options->num_permitted_cnames = 0;
  2143. options->canonicalize_max_dots = -1;
  2144. options->canonicalize_fallback_local = -1;
  2145. options->canonicalize_hostname = -1;
  2146. options->revoked_host_keys = NULL;
  2147. options->fingerprint_hash = -1;
  2148. options->update_hostkeys = -1;
  2149. options->hostbased_accepted_algos = NULL;
  2150. options->pubkey_accepted_algos = NULL;
  2151. }
  2152. /*
  2153. * A petite version of fill_default_options() that just fills the options
  2154. * needed for hostname canonicalization to proceed.
  2155. */
  2156. void
  2157. fill_default_options_for_canonicalization(Options *options)
  2158. {
  2159. if (options->canonicalize_max_dots == -1)
  2160. options->canonicalize_max_dots = 1;
  2161. if (options->canonicalize_fallback_local == -1)
  2162. options->canonicalize_fallback_local = 1;
  2163. if (options->canonicalize_hostname == -1)
  2164. options->canonicalize_hostname = SSH_CANONICALISE_NO;
  2165. }
  2166. /*
  2167. * Called after processing other sources of option data, this fills those
  2168. * options for which no value has been specified with their default values.
  2169. */
  2170. int
  2171. fill_default_options(Options * options)
  2172. {
  2173. char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
  2174. char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
  2175. int ret = 0, r;
  2176. if (options->forward_agent == -1)
  2177. options->forward_agent = 0;
  2178. if (options->forward_x11 == -1)
  2179. options->forward_x11 = 0;
  2180. if (options->forward_x11_trusted == -1)
  2181. options->forward_x11_trusted = 0;
  2182. if (options->forward_x11_timeout == -1)
  2183. options->forward_x11_timeout = 1200;
  2184. /*
  2185. * stdio forwarding (-W) changes the default for these but we defer
  2186. * setting the values so they can be overridden.
  2187. */
  2188. if (options->exit_on_forward_failure == -1)
  2189. options->exit_on_forward_failure =
  2190. options->stdio_forward_host != NULL ? 1 : 0;
  2191. if (options->clear_forwardings == -1)
  2192. options->clear_forwardings =
  2193. options->stdio_forward_host != NULL ? 1 : 0;
  2194. if (options->clear_forwardings == 1)
  2195. clear_forwardings(options);
  2196. if (options->xauth_location == NULL)
  2197. options->xauth_location = xstrdup(_PATH_XAUTH);
  2198. if (options->fwd_opts.gateway_ports == -1)
  2199. options->fwd_opts.gateway_ports = 0;
  2200. if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
  2201. options->fwd_opts.streamlocal_bind_mask = 0177;
  2202. if (options->fwd_opts.streamlocal_bind_unlink == -1)
  2203. options->fwd_opts.streamlocal_bind_unlink = 0;
  2204. if (options->pubkey_authentication == -1)
  2205. options->pubkey_authentication = 1;
  2206. if (options->challenge_response_authentication == -1)
  2207. options->challenge_response_authentication = 1;
  2208. if (options->gss_authentication == -1)
  2209. options->gss_authentication = 0;
  2210. if (options->gss_deleg_creds == -1)
  2211. options->gss_deleg_creds = 0;
  2212. if (options->password_authentication == -1)
  2213. options->password_authentication = 1;
  2214. if (options->kbd_interactive_authentication == -1)
  2215. options->kbd_interactive_authentication = 1;
  2216. if (options->hostbased_authentication == -1)
  2217. options->hostbased_authentication = 0;
  2218. if (options->batch_mode == -1)
  2219. options->batch_mode = 0;
  2220. if (options->check_host_ip == -1)
  2221. options->check_host_ip = 0;
  2222. if (options->strict_host_key_checking == -1)
  2223. options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
  2224. if (options->compression == -1)
  2225. options->compression = 0;
  2226. if (options->tcp_keep_alive == -1)
  2227. options->tcp_keep_alive = 1;
  2228. if (options->port == -1)
  2229. options->port = 0; /* Filled in ssh_connect. */
  2230. if (options->address_family == -1)
  2231. options->address_family = AF_UNSPEC;
  2232. if (options->connection_attempts == -1)
  2233. options->connection_attempts = 1;
  2234. if (options->number_of_password_prompts == -1)
  2235. options->number_of_password_prompts = 3;
  2236. /* options->hostkeyalgorithms, default set in myproposals.h */
  2237. if (options->add_keys_to_agent == -1) {
  2238. options->add_keys_to_agent = 0;
  2239. options->add_keys_to_agent_lifespan = 0;
  2240. }
  2241. if (options->num_identity_files == 0) {
  2242. add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
  2243. add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
  2244. #ifdef OPENSSL_HAS_ECC
  2245. add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
  2246. add_identity_file(options, "~/",
  2247. _PATH_SSH_CLIENT_ID_ECDSA_SK, 0);
  2248. #endif
  2249. add_identity_file(options, "~/",
  2250. _PATH_SSH_CLIENT_ID_ED25519, 0);
  2251. add_identity_file(options, "~/",
  2252. _PATH_SSH_CLIENT_ID_ED25519_SK, 0);
  2253. add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
  2254. }
  2255. if (options->escape_char == -1)
  2256. options->escape_char = '~';
  2257. if (options->num_system_hostfiles == 0) {
  2258. options->system_hostfiles[options->num_system_hostfiles++] =
  2259. xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
  2260. options->system_hostfiles[options->num_system_hostfiles++] =
  2261. xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
  2262. }
  2263. if (options->update_hostkeys == -1) {
  2264. if (options->verify_host_key_dns <= 0 &&
  2265. (options->num_user_hostfiles == 0 ||
  2266. (options->num_user_hostfiles == 1 && strcmp(options->
  2267. user_hostfiles[0], _PATH_SSH_USER_HOSTFILE) == 0)))
  2268. options->update_hostkeys = SSH_UPDATE_HOSTKEYS_YES;
  2269. else
  2270. options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO;
  2271. }
  2272. if (options->num_user_hostfiles == 0) {
  2273. options->user_hostfiles[options->num_user_hostfiles++] =
  2274. xstrdup(_PATH_SSH_USER_HOSTFILE);
  2275. options->user_hostfiles[options->num_user_hostfiles++] =
  2276. xstrdup(_PATH_SSH_USER_HOSTFILE2);
  2277. }
  2278. if (options->log_level == SYSLOG_LEVEL_NOT_SET)
  2279. options->log_level = SYSLOG_LEVEL_INFO;
  2280. if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
  2281. options->log_facility = SYSLOG_FACILITY_USER;
  2282. if (options->no_host_authentication_for_localhost == - 1)
  2283. options->no_host_authentication_for_localhost = 0;
  2284. if (options->identities_only == -1)
  2285. options->identities_only = 0;
  2286. if (options->enable_ssh_keysign == -1)
  2287. options->enable_ssh_keysign = 0;
  2288. if (options->rekey_limit == -1)
  2289. options->rekey_limit = 0;
  2290. if (options->rekey_interval == -1)
  2291. options->rekey_interval = 0;
  2292. if (options->verify_host_key_dns == -1)
  2293. options->verify_host_key_dns = 0;
  2294. if (options->server_alive_interval == -1) {
  2295. /* in batch mode, default is 5mins */
  2296. if (options->batch_mode == 1)
  2297. options->server_alive_interval = 300;
  2298. else
  2299. options->server_alive_interval = 0;
  2300. }
  2301. if (options->server_alive_count_max == -1)
  2302. options->server_alive_count_max = 3;
  2303. if (options->hpn_disabled == -1)
  2304. options->hpn_disabled = 0;
  2305. if (options->hpn_buffer_size > -1) {
  2306. /* if a user tries to set the size to 0 set it to 6MB */
  2307. if (options->hpn_buffer_size == 0)
  2308. options->hpn_buffer_size = 6 * 1024 * 1024;
  2309. /* limit the buffer to SSHBUF_SIZE_MAX (currently 256MB) */
  2310. if (options->hpn_buffer_size > (SSHBUF_SIZE_MAX / 1024)) {
  2311. options->hpn_buffer_size = SSHBUF_SIZE_MAX;
  2312. debug("User requested buffer larger than 256MB. Request reverted to 256MB");
  2313. } else
  2314. options->hpn_buffer_size *= 1024;
  2315. debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
  2316. }
  2317. if (options->tcp_rcv_buf == 0)
  2318. options->tcp_rcv_buf = 1;
  2319. if (options->tcp_rcv_buf > -1)
  2320. options->tcp_rcv_buf *=1024;
  2321. if (options->tcp_rcv_buf_poll == -1)
  2322. options->tcp_rcv_buf_poll = 1;
  2323. if (options->none_switch == -1)
  2324. options->none_switch = 0;
  2325. if (options->none_enabled == -1)
  2326. options->none_enabled = 0;
  2327. if (options->none_enabled == 0 && options->none_switch > 0) {
  2328. fprintf(stderr, "NoneEnabled must be enabled to use the None Switch option. None cipher disabled.\n");
  2329. options->none_enabled = 0;
  2330. }
  2331. if (options->nonemac_enabled == -1)
  2332. options->nonemac_enabled = 0;
  2333. if (options->nonemac_enabled > 0 && (options->none_enabled == 0 ||
  2334. options->none_switch == 0)) {
  2335. fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n");
  2336. options->nonemac_enabled = 0;
  2337. }
  2338. if (options->disable_multithreaded == -1)
  2339. options->disable_multithreaded = 0;
  2340. if (options->control_master == -1)
  2341. options->control_master = 0;
  2342. if (options->control_persist == -1) {
  2343. options->control_persist = 0;
  2344. options->control_persist_timeout = 0;
  2345. }
  2346. if (options->hash_known_hosts == -1)
  2347. options->hash_known_hosts = 0;
  2348. if (options->tun_open == -1)
  2349. options->tun_open = SSH_TUNMODE_NO;
  2350. if (options->tun_local == -1)
  2351. options->tun_local = SSH_TUNID_ANY;
  2352. if (options->tun_remote == -1)
  2353. options->tun_remote = SSH_TUNID_ANY;
  2354. if (options->permit_local_command == -1)
  2355. options->permit_local_command = 0;
  2356. if (options->visual_host_key == -1)
  2357. options->visual_host_key = 0;
  2358. if (options->ip_qos_interactive == -1)
  2359. options->ip_qos_interactive = IPTOS_LOWDELAY;
  2360. if (options->ip_qos_bulk == -1)
  2361. options->ip_qos_bulk = IPTOS_THROUGHPUT;
  2362. if (options->request_tty == -1)
  2363. options->request_tty = REQUEST_TTY_AUTO;
  2364. if (options->no_shell == -1)
  2365. options->no_shell = 0;
  2366. if (options->stdin_null == -1)
  2367. options->stdin_null = 0;
  2368. if (options->fork_after_authentication == -1)
  2369. options->fork_after_authentication = 0;
  2370. if (options->proxy_use_fdpass == -1)
  2371. options->proxy_use_fdpass = 0;
  2372. if (options->canonicalize_max_dots == -1)
  2373. options->canonicalize_max_dots = 1;
  2374. if (options->canonicalize_fallback_local == -1)
  2375. options->canonicalize_fallback_local = 1;
  2376. if (options->canonicalize_hostname == -1)
  2377. options->canonicalize_hostname = SSH_CANONICALISE_NO;
  2378. if (options->fingerprint_hash == -1)
  2379. options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
  2380. #ifdef ENABLE_SK_INTERNAL
  2381. if (options->sk_provider == NULL)
  2382. options->sk_provider = xstrdup("internal");
  2383. #else
  2384. if (options->sk_provider == NULL)
  2385. options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
  2386. #endif
  2387. /* Expand KEX name lists */
  2388. all_cipher = cipher_alg_list(',', 0);
  2389. all_mac = mac_alg_list(',');
  2390. all_kex = kex_alg_list(',');
  2391. all_key = sshkey_alg_list(0, 0, 1, ',');
  2392. all_sig = sshkey_alg_list(0, 1, 1, ',');
  2393. /* remove unsupported algos from default lists */
  2394. def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
  2395. def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
  2396. def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
  2397. def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
  2398. def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
  2399. #define ASSEMBLE(what, defaults, all) \
  2400. do { \
  2401. if ((r = kex_assemble_names(&options->what, \
  2402. defaults, all)) != 0) { \
  2403. error(r, "%s", #what); \
  2404. goto fail; \
  2405. } \
  2406. } while (0)
  2407. ASSEMBLE(ciphers, def_cipher, all_cipher);
  2408. ASSEMBLE(macs, def_mac, all_mac);
  2409. ASSEMBLE(kex_algorithms, def_kex, all_kex);
  2410. ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
  2411. ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
  2412. ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
  2413. #undef ASSEMBLE
  2414. #define CLEAR_ON_NONE(v) \
  2415. do { \
  2416. if (option_clear_or_none(v)) { \
  2417. free(v); \
  2418. v = NULL; \
  2419. } \
  2420. } while(0)
  2421. CLEAR_ON_NONE(options->local_command);
  2422. CLEAR_ON_NONE(options->remote_command);
  2423. CLEAR_ON_NONE(options->proxy_command);
  2424. CLEAR_ON_NONE(options->control_path);
  2425. CLEAR_ON_NONE(options->revoked_host_keys);
  2426. CLEAR_ON_NONE(options->pkcs11_provider);
  2427. CLEAR_ON_NONE(options->sk_provider);
  2428. if (options->jump_host != NULL &&
  2429. strcmp(options->jump_host, "none") == 0 &&
  2430. options->jump_port == 0 && options->jump_user == NULL) {
  2431. free(options->jump_host);
  2432. options->jump_host = NULL;
  2433. }
  2434. /* options->identity_agent distinguishes NULL from 'none' */
  2435. /* options->user will be set in the main program if appropriate */
  2436. /* options->hostname will be set in the main program if appropriate */
  2437. /* options->host_key_alias should not be set by default */
  2438. /* options->preferred_authentications will be set in ssh */
  2439. /* success */
  2440. ret = 0;
  2441. fail:
  2442. free(all_cipher);
  2443. free(all_mac);
  2444. free(all_kex);
  2445. free(all_key);
  2446. free(all_sig);
  2447. free(def_cipher);
  2448. free(def_mac);
  2449. free(def_kex);
  2450. free(def_key);
  2451. free(def_sig);
  2452. return ret;
  2453. }
  2454. void
  2455. free_options(Options *o)
  2456. {
  2457. int i;
  2458. if (o == NULL)
  2459. return;
  2460. #define FREE_ARRAY(type, n, a) \
  2461. do { \
  2462. type _i; \
  2463. for (_i = 0; _i < (n); _i++) \
  2464. free((a)[_i]); \
  2465. } while (0)
  2466. free(o->forward_agent_sock_path);
  2467. free(o->xauth_location);
  2468. //FREE_ARRAY(u_int, o->num_log_verbose, o->log_verbose);
  2469. //free(o->log_verbose);
  2470. free(o->ciphers);
  2471. free(o->macs);
  2472. free(o->hostkeyalgorithms);
  2473. free(o->kex_algorithms);
  2474. free(o->ca_sign_algorithms);
  2475. free(o->hostname);
  2476. free(o->host_key_alias);
  2477. free(o->proxy_command);
  2478. free(o->user);
  2479. FREE_ARRAY(u_int, o->num_system_hostfiles, o->system_hostfiles);
  2480. FREE_ARRAY(u_int, o->num_user_hostfiles, o->user_hostfiles);
  2481. free(o->preferred_authentications);
  2482. free(o->bind_address);
  2483. free(o->bind_interface);
  2484. free(o->pkcs11_provider);
  2485. free(o->sk_provider);
  2486. for (i = 0; i < o->num_identity_files; i++) {
  2487. free(o->identity_files[i]);
  2488. sshkey_free(o->identity_keys[i]);
  2489. }
  2490. for (i = 0; i < o->num_certificate_files; i++) {
  2491. free(o->certificate_files[i]);
  2492. sshkey_free(o->certificates[i]);
  2493. }
  2494. free(o->identity_agent);
  2495. for (i = 0; i < o->num_local_forwards; i++) {
  2496. free(o->local_forwards[i].listen_host);
  2497. free(o->local_forwards[i].listen_path);
  2498. free(o->local_forwards[i].connect_host);
  2499. free(o->local_forwards[i].connect_path);
  2500. }
  2501. free(o->local_forwards);
  2502. for (i = 0; i < o->num_remote_forwards; i++) {
  2503. free(o->remote_forwards[i].listen_host);
  2504. free(o->remote_forwards[i].listen_path);
  2505. free(o->remote_forwards[i].connect_host);
  2506. free(o->remote_forwards[i].connect_path);
  2507. }
  2508. free(o->remote_forwards);
  2509. free(o->stdio_forward_host);
  2510. FREE_ARRAY(int, o->num_send_env, o->send_env);
  2511. free(o->send_env);
  2512. FREE_ARRAY(int, o->num_setenv, o->setenv);
  2513. free(o->setenv);
  2514. free(o->control_path);
  2515. free(o->local_command);
  2516. free(o->remote_command);
  2517. FREE_ARRAY(int, o->num_canonical_domains, o->canonical_domains);
  2518. for (i = 0; i < o->num_permitted_cnames; i++) {
  2519. free(o->permitted_cnames[i].source_list);
  2520. free(o->permitted_cnames[i].target_list);
  2521. }
  2522. free(o->revoked_host_keys);
  2523. free(o->hostbased_accepted_algos);
  2524. free(o->pubkey_accepted_algos);
  2525. free(o->jump_user);
  2526. free(o->jump_host);
  2527. free(o->jump_extra);
  2528. free(o->ignored_unknown);
  2529. explicit_bzero(o, sizeof(*o));
  2530. #undef FREE_ARRAY
  2531. }
  2532. struct fwdarg {
  2533. char *arg;
  2534. int ispath;
  2535. };
  2536. /*
  2537. * parse_fwd_field
  2538. * parses the next field in a port forwarding specification.
  2539. * sets fwd to the parsed field and advances p past the colon
  2540. * or sets it to NULL at end of string.
  2541. * returns 0 on success, else non-zero.
  2542. */
  2543. static int
  2544. parse_fwd_field(char **p, struct fwdarg *fwd)
  2545. {
  2546. char *ep, *cp = *p;
  2547. int ispath = 0;
  2548. if (*cp == '\0') {
  2549. *p = NULL;
  2550. return -1; /* end of string */
  2551. }
  2552. /*
  2553. * A field escaped with square brackets is used literally.
  2554. * XXX - allow ']' to be escaped via backslash?
  2555. */
  2556. if (*cp == '[') {
  2557. /* find matching ']' */
  2558. for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
  2559. if (*ep == '/')
  2560. ispath = 1;
  2561. }
  2562. /* no matching ']' or not at end of field. */
  2563. if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
  2564. return -1;
  2565. /* NUL terminate the field and advance p past the colon */
  2566. *ep++ = '\0';
  2567. if (*ep != '\0')
  2568. *ep++ = '\0';
  2569. fwd->arg = cp + 1;
  2570. fwd->ispath = ispath;
  2571. *p = ep;
  2572. return 0;
  2573. }
  2574. for (cp = *p; *cp != '\0'; cp++) {
  2575. switch (*cp) {
  2576. case '\\':
  2577. memmove(cp, cp + 1, strlen(cp + 1) + 1);
  2578. if (*cp == '\0')
  2579. return -1;
  2580. break;
  2581. case '/':
  2582. ispath = 1;
  2583. break;
  2584. case ':':
  2585. *cp++ = '\0';
  2586. goto done;
  2587. }
  2588. }
  2589. done:
  2590. fwd->arg = *p;
  2591. fwd->ispath = ispath;
  2592. *p = cp;
  2593. return 0;
  2594. }
  2595. /*
  2596. * parse_forward
  2597. * parses a string containing a port forwarding specification of the form:
  2598. * dynamicfwd == 0
  2599. * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
  2600. * listenpath:connectpath
  2601. * dynamicfwd == 1
  2602. * [listenhost:]listenport
  2603. * returns number of arguments parsed or zero on error
  2604. */
  2605. int
  2606. parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
  2607. {
  2608. struct fwdarg fwdargs[4];
  2609. char *p, *cp;
  2610. int i, err;
  2611. memset(fwd, 0, sizeof(*fwd));
  2612. memset(fwdargs, 0, sizeof(fwdargs));
  2613. /*
  2614. * We expand environment variables before checking if we think they're
  2615. * paths so that if ${VAR} expands to a fully qualified path it is
  2616. * treated as a path.
  2617. */
  2618. cp = p = dollar_expand(&err, fwdspec);
  2619. if (p == NULL || err)
  2620. return 0;
  2621. /* skip leading spaces */
  2622. while (isspace((u_char)*cp))
  2623. cp++;
  2624. for (i = 0; i < 4; ++i) {
  2625. if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
  2626. break;
  2627. }
  2628. /* Check for trailing garbage */
  2629. if (cp != NULL && *cp != '\0') {
  2630. i = 0; /* failure */
  2631. }
  2632. switch (i) {
  2633. case 1:
  2634. if (fwdargs[0].ispath) {
  2635. fwd->listen_path = xstrdup(fwdargs[0].arg);
  2636. fwd->listen_port = PORT_STREAMLOCAL;
  2637. } else {
  2638. fwd->listen_host = NULL;
  2639. fwd->listen_port = a2port(fwdargs[0].arg);
  2640. }
  2641. fwd->connect_host = xstrdup("socks");
  2642. break;
  2643. case 2:
  2644. if (fwdargs[0].ispath && fwdargs[1].ispath) {
  2645. fwd->listen_path = xstrdup(fwdargs[0].arg);
  2646. fwd->listen_port = PORT_STREAMLOCAL;
  2647. fwd->connect_path = xstrdup(fwdargs[1].arg);
  2648. fwd->connect_port = PORT_STREAMLOCAL;
  2649. } else if (fwdargs[1].ispath) {
  2650. fwd->listen_host = NULL;
  2651. fwd->listen_port = a2port(fwdargs[0].arg);
  2652. fwd->connect_path = xstrdup(fwdargs[1].arg);
  2653. fwd->connect_port = PORT_STREAMLOCAL;
  2654. } else {
  2655. fwd->listen_host = xstrdup(fwdargs[0].arg);
  2656. fwd->listen_port = a2port(fwdargs[1].arg);
  2657. fwd->connect_host = xstrdup("socks");
  2658. }
  2659. break;
  2660. case 3:
  2661. if (fwdargs[0].ispath) {
  2662. fwd->listen_path = xstrdup(fwdargs[0].arg);
  2663. fwd->listen_port = PORT_STREAMLOCAL;
  2664. fwd->connect_host = xstrdup(fwdargs[1].arg);
  2665. fwd->connect_port = a2port(fwdargs[2].arg);
  2666. } else if (fwdargs[2].ispath) {
  2667. fwd->listen_host = xstrdup(fwdargs[0].arg);
  2668. fwd->listen_port = a2port(fwdargs[1].arg);
  2669. fwd->connect_path = xstrdup(fwdargs[2].arg);
  2670. fwd->connect_port = PORT_STREAMLOCAL;
  2671. } else {
  2672. fwd->listen_host = NULL;
  2673. fwd->listen_port = a2port(fwdargs[0].arg);
  2674. fwd->connect_host = xstrdup(fwdargs[1].arg);
  2675. fwd->connect_port = a2port(fwdargs[2].arg);
  2676. }
  2677. break;
  2678. case 4:
  2679. fwd->listen_host = xstrdup(fwdargs[0].arg);
  2680. fwd->listen_port = a2port(fwdargs[1].arg);
  2681. fwd->connect_host = xstrdup(fwdargs[2].arg);
  2682. fwd->connect_port = a2port(fwdargs[3].arg);
  2683. break;
  2684. default:
  2685. i = 0; /* failure */
  2686. }
  2687. free(p);
  2688. if (dynamicfwd) {
  2689. if (!(i == 1 || i == 2))
  2690. goto fail_free;
  2691. } else {
  2692. if (!(i == 3 || i == 4)) {
  2693. if (fwd->connect_path == NULL &&
  2694. fwd->listen_path == NULL)
  2695. goto fail_free;
  2696. }
  2697. if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
  2698. goto fail_free;
  2699. }
  2700. if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
  2701. (!remotefwd && fwd->listen_port == 0))
  2702. goto fail_free;
  2703. if (fwd->connect_host != NULL &&
  2704. strlen(fwd->connect_host) >= NI_MAXHOST)
  2705. goto fail_free;
  2706. /* XXX - if connecting to a remote socket, max sun len may not match this host */
  2707. if (fwd->connect_path != NULL &&
  2708. strlen(fwd->connect_path) >= PATH_MAX_SUN)
  2709. goto fail_free;
  2710. if (fwd->listen_host != NULL &&
  2711. strlen(fwd->listen_host) >= NI_MAXHOST)
  2712. goto fail_free;
  2713. if (fwd->listen_path != NULL &&
  2714. strlen(fwd->listen_path) >= PATH_MAX_SUN)
  2715. goto fail_free;
  2716. return (i);
  2717. fail_free:
  2718. free(fwd->connect_host);
  2719. fwd->connect_host = NULL;
  2720. free(fwd->connect_path);
  2721. fwd->connect_path = NULL;
  2722. free(fwd->listen_host);
  2723. fwd->listen_host = NULL;
  2724. free(fwd->listen_path);
  2725. fwd->listen_path = NULL;
  2726. return (0);
  2727. }
  2728. int
  2729. parse_jump(const char *s, Options *o, int active)
  2730. {
  2731. char *orig, *sdup, *cp;
  2732. char *host = NULL, *user = NULL;
  2733. int r, ret = -1, port = -1, first;
  2734. active &= o->proxy_command == NULL && o->jump_host == NULL;
  2735. orig = sdup = xstrdup(s);
  2736. first = active;
  2737. do {
  2738. if (strcasecmp(s, "none") == 0)
  2739. break;
  2740. if ((cp = strrchr(sdup, ',')) == NULL)
  2741. cp = sdup; /* last */
  2742. else
  2743. *cp++ = '\0';
  2744. if (first) {
  2745. /* First argument and configuration is active */
  2746. r = parse_ssh_uri(cp, &user, &host, &port);
  2747. if (r == -1 || (r == 1 &&
  2748. parse_user_host_port(cp, &user, &host, &port) != 0))
  2749. goto out;
  2750. } else {
  2751. /* Subsequent argument or inactive configuration */
  2752. r = parse_ssh_uri(cp, NULL, NULL, NULL);
  2753. if (r == -1 || (r == 1 &&
  2754. parse_user_host_port(cp, NULL, NULL, NULL) != 0))
  2755. goto out;
  2756. }
  2757. first = 0; /* only check syntax for subsequent hosts */
  2758. } while (cp != sdup);
  2759. /* success */
  2760. if (active) {
  2761. if (strcasecmp(s, "none") == 0) {
  2762. o->jump_host = xstrdup("none");
  2763. o->jump_port = 0;
  2764. } else {
  2765. o->jump_user = user;
  2766. o->jump_host = host;
  2767. o->jump_port = port;
  2768. o->proxy_command = xstrdup("none");
  2769. user = host = NULL;
  2770. if ((cp = strrchr(s, ',')) != NULL && cp != s) {
  2771. o->jump_extra = xstrdup(s);
  2772. o->jump_extra[cp - s] = '\0';
  2773. }
  2774. }
  2775. }
  2776. ret = 0;
  2777. out:
  2778. free(orig);
  2779. free(user);
  2780. free(host);
  2781. return ret;
  2782. }
  2783. int
  2784. parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
  2785. {
  2786. char *user = NULL, *host = NULL, *path = NULL;
  2787. int r, port;
  2788. r = parse_uri("ssh", uri, &user, &host, &port, &path);
  2789. if (r == 0 && path != NULL)
  2790. r = -1; /* path not allowed */
  2791. if (r == 0) {
  2792. if (userp != NULL) {
  2793. *userp = user;
  2794. user = NULL;
  2795. }
  2796. if (hostp != NULL) {
  2797. *hostp = host;
  2798. host = NULL;
  2799. }
  2800. if (portp != NULL)
  2801. *portp = port;
  2802. }
  2803. free(user);
  2804. free(host);
  2805. free(path);
  2806. return r;
  2807. }
  2808. /* XXX the following is a near-vebatim copy from servconf.c; refactor */
  2809. static const char *
  2810. fmt_multistate_int(int val, const struct multistate *m)
  2811. {
  2812. u_int i;
  2813. for (i = 0; m[i].key != NULL; i++) {
  2814. if (m[i].value == val)
  2815. return m[i].key;
  2816. }
  2817. return "UNKNOWN";
  2818. }
  2819. static const char *
  2820. fmt_intarg(OpCodes code, int val)
  2821. {
  2822. if (val == -1)
  2823. return "unset";
  2824. switch (code) {
  2825. case oAddressFamily:
  2826. return fmt_multistate_int(val, multistate_addressfamily);
  2827. case oVerifyHostKeyDNS:
  2828. case oUpdateHostkeys:
  2829. return fmt_multistate_int(val, multistate_yesnoask);
  2830. case oStrictHostKeyChecking:
  2831. return fmt_multistate_int(val, multistate_strict_hostkey);
  2832. case oControlMaster:
  2833. return fmt_multistate_int(val, multistate_controlmaster);
  2834. case oTunnel:
  2835. return fmt_multistate_int(val, multistate_tunnel);
  2836. case oRequestTTY:
  2837. return fmt_multistate_int(val, multistate_requesttty);
  2838. case oCanonicalizeHostname:
  2839. return fmt_multistate_int(val, multistate_canonicalizehostname);
  2840. case oAddKeysToAgent:
  2841. return fmt_multistate_int(val, multistate_yesnoaskconfirm);
  2842. case oFingerprintHash:
  2843. return ssh_digest_alg_name(val);
  2844. default:
  2845. switch (val) {
  2846. case 0:
  2847. return "no";
  2848. case 1:
  2849. return "yes";
  2850. default:
  2851. return "UNKNOWN";
  2852. }
  2853. }
  2854. }
  2855. static const char *
  2856. lookup_opcode_name(OpCodes code)
  2857. {
  2858. u_int i;
  2859. for (i = 0; keywords[i].name != NULL; i++)
  2860. if (keywords[i].opcode == code)
  2861. return(keywords[i].name);
  2862. return "UNKNOWN";
  2863. }
  2864. static void
  2865. dump_cfg_int(OpCodes code, int val)
  2866. {
  2867. printf("%s %d\n", lookup_opcode_name(code), val);
  2868. }
  2869. static void
  2870. dump_cfg_fmtint(OpCodes code, int val)
  2871. {
  2872. printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
  2873. }
  2874. static void
  2875. dump_cfg_string(OpCodes code, const char *val)
  2876. {
  2877. if (val == NULL)
  2878. return;
  2879. printf("%s %s\n", lookup_opcode_name(code), val);
  2880. }
  2881. static void
  2882. dump_cfg_strarray(OpCodes code, u_int count, char **vals)
  2883. {
  2884. u_int i;
  2885. for (i = 0; i < count; i++)
  2886. printf("%s %s\n", lookup_opcode_name(code), vals[i]);
  2887. }
  2888. static void
  2889. dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
  2890. {
  2891. u_int i;
  2892. printf("%s", lookup_opcode_name(code));
  2893. for (i = 0; i < count; i++)
  2894. printf(" %s", vals[i]);
  2895. printf("\n");
  2896. }
  2897. static void
  2898. dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
  2899. {
  2900. const struct Forward *fwd;
  2901. u_int i;
  2902. /* oDynamicForward */
  2903. for (i = 0; i < count; i++) {
  2904. fwd = &fwds[i];
  2905. if (code == oDynamicForward && fwd->connect_host != NULL &&
  2906. strcmp(fwd->connect_host, "socks") != 0)
  2907. continue;
  2908. if (code == oLocalForward && fwd->connect_host != NULL &&
  2909. strcmp(fwd->connect_host, "socks") == 0)
  2910. continue;
  2911. printf("%s", lookup_opcode_name(code));
  2912. if (fwd->listen_port == PORT_STREAMLOCAL)
  2913. printf(" %s", fwd->listen_path);
  2914. else if (fwd->listen_host == NULL)
  2915. printf(" %d", fwd->listen_port);
  2916. else {
  2917. printf(" [%s]:%d",
  2918. fwd->listen_host, fwd->listen_port);
  2919. }
  2920. if (code != oDynamicForward) {
  2921. if (fwd->connect_port == PORT_STREAMLOCAL)
  2922. printf(" %s", fwd->connect_path);
  2923. else if (fwd->connect_host == NULL)
  2924. printf(" %d", fwd->connect_port);
  2925. else {
  2926. printf(" [%s]:%d",
  2927. fwd->connect_host, fwd->connect_port);
  2928. }
  2929. }
  2930. printf("\n");
  2931. }
  2932. }
  2933. void
  2934. dump_client_config(Options *o, const char *host)
  2935. {
  2936. int i, r;
  2937. char buf[8], *all_key;
  2938. /*
  2939. * Expand HostKeyAlgorithms name lists. This isn't handled in
  2940. * fill_default_options() like the other algorithm lists because
  2941. * the host key algorithms are by default dynamically chosen based
  2942. * on the host's keys found in known_hosts.
  2943. */
  2944. all_key = sshkey_alg_list(0, 0, 1, ',');
  2945. if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
  2946. all_key)) != 0)
  2947. fatal("%s: expand HostKeyAlgorithms: %s", __func__, ssh_err(r));
  2948. free(all_key);
  2949. /* Most interesting options first: user, host, port */
  2950. dump_cfg_string(oUser, o->user);
  2951. dump_cfg_string(oHostname, host);
  2952. dump_cfg_int(oPort, o->port);
  2953. /* Flag options */
  2954. dump_cfg_fmtint(oAddressFamily, o->address_family);
  2955. dump_cfg_fmtint(oBatchMode, o->batch_mode);
  2956. dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
  2957. dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
  2958. dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
  2959. dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
  2960. dump_cfg_fmtint(oCompression, o->compression);
  2961. dump_cfg_fmtint(oControlMaster, o->control_master);
  2962. dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
  2963. dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
  2964. dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
  2965. dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
  2966. dump_cfg_fmtint(oForwardX11, o->forward_x11);
  2967. dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
  2968. dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
  2969. #ifdef GSSAPI
  2970. dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
  2971. dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
  2972. #endif /* GSSAPI */
  2973. dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
  2974. dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
  2975. dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
  2976. dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
  2977. dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
  2978. dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
  2979. dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
  2980. dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
  2981. dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
  2982. dump_cfg_fmtint(oRequestTTY, o->request_tty);
  2983. dump_cfg_fmtint(oNoShell, o->no_shell);
  2984. dump_cfg_fmtint(oStdinNull, o->stdin_null);
  2985. dump_cfg_fmtint(oForkAfterAuthentication, o->fork_after_authentication);
  2986. dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
  2987. dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
  2988. dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
  2989. dump_cfg_fmtint(oTunnel, o->tun_open);
  2990. dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
  2991. dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
  2992. dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
  2993. /* Integer options */
  2994. dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
  2995. dump_cfg_int(oConnectionAttempts, o->connection_attempts);
  2996. dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
  2997. dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
  2998. dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
  2999. dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
  3000. /* String options */
  3001. dump_cfg_string(oBindAddress, o->bind_address);
  3002. dump_cfg_string(oBindInterface, o->bind_interface);
  3003. dump_cfg_string(oCiphers, o->ciphers);
  3004. dump_cfg_string(oControlPath, o->control_path);
  3005. dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
  3006. dump_cfg_string(oHostKeyAlias, o->host_key_alias);
  3007. dump_cfg_string(oHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
  3008. dump_cfg_string(oIdentityAgent, o->identity_agent);
  3009. dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
  3010. dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
  3011. dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
  3012. dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
  3013. dump_cfg_string(oLocalCommand, o->local_command);
  3014. dump_cfg_string(oRemoteCommand, o->remote_command);
  3015. dump_cfg_string(oLogLevel, log_level_name(o->log_level));
  3016. dump_cfg_string(oMacs, o->macs);
  3017. #ifdef ENABLE_PKCS11
  3018. dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
  3019. #endif
  3020. dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
  3021. dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
  3022. dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
  3023. dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
  3024. dump_cfg_string(oXAuthLocation, o->xauth_location);
  3025. /* Forwards */
  3026. dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
  3027. dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
  3028. dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
  3029. /* String array options */
  3030. dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
  3031. dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
  3032. dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
  3033. dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
  3034. dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
  3035. dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
  3036. dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
  3037. /* Special cases */
  3038. /* PermitRemoteOpen */
  3039. if (o->num_permitted_remote_opens == 0)
  3040. printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen));
  3041. else
  3042. dump_cfg_strarray_oneline(oPermitRemoteOpen,
  3043. o->num_permitted_remote_opens, o->permitted_remote_opens);
  3044. /* AddKeysToAgent */
  3045. if (o->add_keys_to_agent_lifespan <= 0)
  3046. dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
  3047. else {
  3048. printf("addkeystoagent%s %d\n",
  3049. o->add_keys_to_agent == 3 ? " confirm" : "",
  3050. o->add_keys_to_agent_lifespan);
  3051. }
  3052. /* oForwardAgent */
  3053. if (o->forward_agent_sock_path == NULL)
  3054. dump_cfg_fmtint(oForwardAgent, o->forward_agent);
  3055. else
  3056. dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
  3057. /* oConnectTimeout */
  3058. if (o->connection_timeout == -1)
  3059. printf("connecttimeout none\n");
  3060. else
  3061. dump_cfg_int(oConnectTimeout, o->connection_timeout);
  3062. /* oTunnelDevice */
  3063. printf("tunneldevice");
  3064. if (o->tun_local == SSH_TUNID_ANY)
  3065. printf(" any");
  3066. else
  3067. printf(" %d", o->tun_local);
  3068. if (o->tun_remote == SSH_TUNID_ANY)
  3069. printf(":any");
  3070. else
  3071. printf(":%d", o->tun_remote);
  3072. printf("\n");
  3073. /* oCanonicalizePermittedCNAMEs */
  3074. if ( o->num_permitted_cnames > 0) {
  3075. printf("canonicalizePermittedcnames");
  3076. for (i = 0; i < o->num_permitted_cnames; i++) {
  3077. printf(" %s:%s", o->permitted_cnames[i].source_list,
  3078. o->permitted_cnames[i].target_list);
  3079. }
  3080. printf("\n");
  3081. }
  3082. /* oControlPersist */
  3083. if (o->control_persist == 0 || o->control_persist_timeout == 0)
  3084. dump_cfg_fmtint(oControlPersist, o->control_persist);
  3085. else
  3086. dump_cfg_int(oControlPersist, o->control_persist_timeout);
  3087. /* oEscapeChar */
  3088. if (o->escape_char == SSH_ESCAPECHAR_NONE)
  3089. printf("escapechar none\n");
  3090. else {
  3091. vis(buf, o->escape_char, VIS_WHITE, 0);
  3092. printf("escapechar %s\n", buf);
  3093. }
  3094. /* oIPQoS */
  3095. printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
  3096. printf("%s\n", iptos2str(o->ip_qos_bulk));
  3097. /* oRekeyLimit */
  3098. printf("rekeylimit %llu %d\n",
  3099. (unsigned long long)o->rekey_limit, o->rekey_interval);
  3100. /* oStreamLocalBindMask */
  3101. printf("streamlocalbindmask 0%o\n",
  3102. o->fwd_opts.streamlocal_bind_mask);
  3103. /* oLogFacility */
  3104. printf("syslogfacility %s\n", log_facility_name(o->log_facility));
  3105. /* oProxyCommand / oProxyJump */
  3106. if (o->jump_host == NULL)
  3107. dump_cfg_string(oProxyCommand, o->proxy_command);
  3108. else {
  3109. /* Check for numeric addresses */
  3110. i = strchr(o->jump_host, ':') != NULL ||
  3111. strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
  3112. snprintf(buf, sizeof(buf), "%d", o->jump_port);
  3113. printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
  3114. /* optional additional jump spec */
  3115. o->jump_extra == NULL ? "" : o->jump_extra,
  3116. o->jump_extra == NULL ? "" : ",",
  3117. /* optional user */
  3118. o->jump_user == NULL ? "" : o->jump_user,
  3119. o->jump_user == NULL ? "" : "@",
  3120. /* opening [ if hostname is numeric */
  3121. i ? "[" : "",
  3122. /* mandatory hostname */
  3123. o->jump_host,
  3124. /* closing ] if hostname is numeric */
  3125. i ? "]" : "",
  3126. /* optional port number */
  3127. o->jump_port <= 0 ? "" : ":",
  3128. o->jump_port <= 0 ? "" : buf);
  3129. }
  3130. }